YARP
Yet Another Robot Platform
PortMonitor.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 <yarp/os/Log.h>
10 #include <string>
11 #include <yarp/os/ResourceFinder.h>
13 #include <yarp/os/Route.h>
14 #include <yarp/os/Contactable.h>
15 #include <yarp/os/LogStream.h>
16 #include <yarp/os/Network.h>
17 
18 #include "PortMonitor.h"
19 #include "MonitorLogComponent.h"
20 
21 
22 
23 using namespace yarp::os;
24 
25 
30 // Read connection settings.
32 {
34 
35  portName = proto.getRoute().getToName();
36  sourceName = proto.getRoute().getFromName();
37  group = getPeers().add(portName,this);
38  if (!group) {
39  yCError(PORTMONITORCARRIER) << "Cannot find group";
40  return false;
41  }
42 
43  Property options;
44  options.fromString(proto.getSenderSpecifier());
45  options.put("source", sourceName);
46  options.put("destination", portName);
47  options.put("sender_side",
48  (proto.getContactable()->getName() == sourceName) ? 1 : 0);
49  options.put("receiver_side",
50  (proto.getContactable()->getName() == portName) ? 1 : 0);
51  options.put("carrier", proto.getRoute().getCarrierName());
52  return configureFromProperty(options);
53 }
54 
56 {
58 
59  delete binder;
60  binder = nullptr;
61 
62  std::string script = options.check("type", Value("lua")).asString();
63  std::string filename = options.check("file", Value("modifier")).asString();
64  std::string constraint = options.check("constraint", Value("")).asString();
65  // context is used to find the script files
66  std::string context = options.check("context", Value("")).asString();
67 
68  // check which monitor should be used
69  if((binder = MonitorBinding::create(script.c_str())) == nullptr)
70  {
71  yCError(PORTMONITORCARRIER, R"(Currently only 'lua' script and 'dll' object is supported by portmonitor)");
72  return false;
73  }
74 
75  // set the acceptance constraint
76  binder->setAcceptConstraint(constraint.c_str());
77 
78  std::string strFile = filename;
79 
80  if(script != "dll")
81  {
83  rf.setDefaultContext(context);
84  rf.configure(0, nullptr);
85  strFile = rf.findFile(filename);
86  if(strFile.empty()) {
87  strFile = rf.findFile(filename+".lua");
88  }
89  }
90 
91  // provide some useful information for the monitor object
92  // which can be accessed in the create() callback.
93  Property info;
94  info.clear();
95  info.put("filename", strFile);
96  info.put("type", script);
97  info.put("source", options.find("source").asString());
98  info.put("destination", options.find("destination").asString());
99  info.put("sender_side", options.find("sender_side").asInt32());
100  info.put("receiver_side",options.find("receiver_side").asInt32());
101  info.put("carrier", options.find("carrier").asString());
102 
104  bReady = binder->load(info);
106  return bReady;
107 }
108 
110 {
112 
113  if(!bReady) {
114  return;
115  }
117  binder->setParams(params);
119 }
120 
122 {
124 
125  if(!bReady) {
126  return;
127  }
129  binder->getParams(params);
131 }
132 
133 
135 {
137 
138  if(!bReady) {
139  return reader;
140  }
141 
142  // When we are here,
143  // the incoming data should be accessed using localReader.
144  // The reader passed to this function is infact empty.
145  // first check if we need to call the update callback
146  if(!binder->hasUpdate()) {
147  localReader->setParentConnectionReader(&reader);
148  return *localReader;
149  }
150 
152  yarp::os::Things thing;
153  thing.setConnectionReader(*localReader);
154  yarp::os::Things& result = binder->updateData(thing);
156  con.reset();
157  if(result.write(con.getWriter())) {
158  auto& cReader = con.getReader(reader.getWriter());
159  cReader.setParentConnectionReader(&reader);
160  if (result.getPortReader() != nullptr) {
161  cReader.getWriter()->setReplyHandler(*result.getPortReader());
162  }
163  return cReader;
164  }
165  return *localReader;
166 }
167 
169 {
171 
172  if(!bReady) {
173  return false;
174  }
175 
176  bool result = false;
177  localReader = &reader;
178  // If no accept callback avoid calling the binder
179  if(binder->hasAccept())
180  {
182  Things thing;
183  // set the reference connection reader
184  thing.setConnectionReader(reader);
185  result = binder->acceptData(thing);
187  if(!result) {
188  return false;
189  }
190 
191  // When data is read here using the reader passed to this functions,
192  // then it won't be available for modifyIncomingData(). Thus, we write
193  // it to a dummy connection and pass it to the modifyOutgoingData() using
194  // localReader.
195  // localReader points to a connection reader which contains
196  // either the original or modified data.
197  if(thing.hasBeenRead()) {
198  con.reset();
199  if(thing.write(con.getWriter())) {
200  localReader = &con.getReader(reader.getWriter());
201  }
202  }
203  }
204 
205  if(group!=nullptr) {
206  getPeers().lock();
207  result = group->acceptIncomingData(this);
208  getPeers().unlock();
209  }
210  return result;
211 }
212 
213 
215 {
217 
218  if(!bReady) {
219  return writer;
220  }
221 
222  // If no update callback avoid calling it
223  if(!binder->hasUpdate()) {
224  return writer;
225  }
226 
228  thing.reset();
229  thing.setPortWriter(const_cast<yarp::os::PortWriter*>(&writer));
230  yarp::os::Things& result = binder->updateData(thing);
232  return *result.getPortWriter();
233 }
234 
236 {
238 
239  if(!bReady) {
240  return false;
241  }
242 
243  // If no accept callback avoid calling it
244  if(!binder->hasAccept()) {
245  return true;
246  }
247 
249  yarp::os::Things thing;
250  thing.setPortWriter(const_cast<yarp::os::PortWriter*>(&writer));
251  bool result = binder->acceptData(thing);
253  return result;
254 }
255 
257 {
259 
260  if(!bReady) {
261  return reader;
262  }
263 
264  // If no updateReply callback avoid calling it
265  if(!binder->hasUpdateReply()) {
266  return reader;
267  }
268 
270  thing.reset();
271  thing.setPortReader(&reader);
272  yarp::os::Things& result = binder->updateReply(thing);
274  return *result.getPortReader();
275 }
276 
281 ElectionOf<PortMonitorGroup> *PortMonitor::peers = nullptr;
282 
283 // Make a singleton manager for finding peer carriers.
284 ElectionOf<PortMonitorGroup>& PortMonitor::getPeers()
285 {
287 
289  if (peers==nullptr) {
290  peers = new ElectionOf<PortMonitorGroup>;
293  } else {
295  }
296  return *peers;
297 }
298 
299 // Decide whether data should be accepted, for real.
301 {
303 
304  //bool accept = true;
305  for (auto& it : peerSet)
306  {
307  PortMonitor *peer = it.first;
308  if(peer != source)
309  {
310  peer->lock();
311  // TODO: check whether we should return false if
312  // the peer monitor object is not ready!
313  if(peer->getBinder()) {
314  peer->getBinder()->peerTrigged();
315  }
316  peer->unlock();
317  }
318  }
319  return source->getBinder()->canAccept();
320 }
LogStream.h
yarp::os::Things::getPortWriter
yarp::os::PortWriter * getPortWriter()
Definition: Things.cpp:34
yarp::os::Property::put
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
Definition: Property.cpp:998
yarp::os::Things::hasBeenRead
bool hasBeenRead()
Definition: Things.cpp:78
Network.h
yarp::os::Route::getCarrierName
const std::string & getCarrierName() const
Get the carrier type of the route.
Definition: Route.cpp:126
yarp::os::ConnectionReader::setParentConnectionReader
virtual void setParentConnectionReader(ConnectionReader *parentConnectionReader)
Set ConnectionReader to be used for reading the envelope.
Definition: ConnectionReader.cpp:23
MonitorBinding::canAccept
virtual bool canAccept()=0
MonitorBinding::peerTrigged
virtual bool peerTrigged()=0
yarp::os::NetworkBase::lock
static void lock()
Call wait() on a global mutual-exclusion semaphore allocated by YARP.
Definition: Network.cpp:1462
yarp::os::Property::fromString
void fromString(const std::string &txt, bool wipe=true)
Interprets a string as a list of properties.
Definition: Property.cpp:1046
PortMonitor::modifyReply
yarp::os::PortReader & modifyReply(yarp::os::PortReader &reader) override
Modify reply payload data, if appropriate.
Definition: PortMonitor.cpp:256
yarp::os::Things::setConnectionReader
bool setConnectionReader(yarp::os::ConnectionReader &reader)
set a reference to a ConnectionReader
Definition: Things.cpp:49
PortMonitor
Allow to monitor and modify port data from Lua script Under development.
Definition: PortMonitor.h:54
PortMonitor::acceptIncomingData
bool acceptIncomingData(yarp::os::ConnectionReader &reader) override
Determine whether incoming data should be accepted.
Definition: PortMonitor.cpp:168
yarp::os::Things
Base class for generic things.
Definition: Things.h:22
yarp::os::Property::find
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
Definition: Property.cpp:1034
yarp::os::Things::write
bool write(yarp::os::ConnectionWriter &connection)
Definition: Things.cpp:57
yarp::os::PortWriter
Interface implemented by all objects that can write themselves to the network, such as Bottle objects...
Definition: PortWriter.h:27
MonitorLogComponent.h
PortMonitor::getBinder
MonitorBinding * getBinder()
Definition: PortMonitor.h:108
PortMonitor::unlock
void unlock() const
Definition: PortMonitor.h:106
Log.h
yarp::os::ResourceFinder::findFile
std::string findFile(const std::string &name)
Find the full path to a file.
Definition: ResourceFinder.cpp:847
yarp::os::Things::setPortWriter
void setPortWriter(yarp::os::PortWriter *writer)
Set the reference to a PortWriter object.
Definition: Things.cpp:29
yarp::os::ConnectionState::getRoute
virtual const Route & getRoute() const =0
Get the route associated with this connection.
yarp::os::ResourceFinder::setDefaultContext
bool setDefaultContext(const std::string &contextName)
Sets the context for the current ResourceFinder object.
Definition: ResourceFinder.h:91
yarp::os::ResourceFinder::configure
bool configure(int argc, char *argv[], bool skipFirstArgument=true)
Sets up the ResourceFinder.
Definition: ResourceFinder.cpp:803
Route.h
yarp::os::PortReader
Interface implemented by all objects that can read themselves from the network, such as Bottle object...
Definition: PortReader.h:28
ConnectionState.h
PortMonitor::acceptOutgoingData
bool acceptOutgoingData(const yarp::os::PortWriter &writer) override
Determine whether outgoing data should be accepted.
Definition: PortMonitor.cpp:235
PortMonitor::configure
bool configure(yarp::os::ConnectionState &proto) override
Class PortMonitor.
Definition: PortMonitor.cpp:31
yarp::os::Value::asString
virtual std::string asString() const
Get string value.
Definition: Value.cpp:237
PortMonitor::getCarrierParams
void getCarrierParams(yarp::os::Property &params) const override
Get carrier configuration and deliver it by port administrative commands.
Definition: PortMonitor.cpp:121
PortMonitor::lock
void lock() const
Definition: PortMonitor.h:105
yarp::os::Property::check
bool check(const std::string &key) const override
Check if there exists a property of the given name.
Definition: Property.cpp:1024
yarp::os::ConnectionReader::getWriter
virtual ConnectionWriter * getWriter()=0
Gets a way to reply to the message, if possible.
yarp::os::Contactable::getName
virtual std::string getName() const
Get name of port.
Definition: Contactable.cpp:17
PortMonitor::modifyIncomingData
yarp::os::ConnectionReader & modifyIncomingData(yarp::os::ConnectionReader &reader) override
Modify incoming payload data, if appropriate.
Definition: PortMonitor.cpp:134
yarp::os::Property::clear
void clear()
Remove all associations.
Definition: Property.cpp:1040
yCAssert
#define yCAssert(component, x)
Definition: LogComponent.h:172
yarp::os::ElectionOf< PortMonitorGroup >
PortMonitor.h
yarp::os::ConnectionReader
An interface for reading from a network connection.
Definition: ConnectionReader.h:40
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::ConnectionState::getSenderSpecifier
virtual std::string getSenderSpecifier() const =0
Extract a name for the sender, if the connection type supports that.
yarp::os::Value::asInt32
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition: Value.cpp:207
MonitorBinding::create
static MonitorBinding * create(const char *script_type)
factory method
Definition: MonitorBinding.cpp:28
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
PortMonitorGroup::acceptIncomingData
virtual bool acceptIncomingData(PortMonitor *source)
Definition: PortMonitor.cpp:300
yarp::os::NetworkBase::unlock
static void unlock()
Call post() on a global mutual-exclusion semaphore allocated by YARP.
Definition: Network.cpp:1467
PORTMONITORCARRIER
const yarp::os::LogComponent & PORTMONITORCARRIER()
Definition: MonitorLogComponent.cpp:16
yarp::os::Route::getToName
const std::string & getToName() const
Get the destination of the route.
Definition: Route.cpp:106
PortMonitor::setCarrierParams
void setCarrierParams(const yarp::os::Property &params) override
Configure carrier from port administrative commands.
Definition: PortMonitor.cpp:109
yCTrace
#define yCTrace(component,...)
Definition: LogComponent.h:88
yarp::os::ConnectionState::getContactable
virtual Contactable * getContactable() const =0
Get the port associated with the connection.
yarp::os::Value
A single value (typically within a Bottle).
Definition: Value.h:47
yarp::os::Route::getFromName
const std::string & getFromName() const
Get the source of the route.
Definition: Route.cpp:96
PortMonitor::configureFromProperty
bool configureFromProperty(yarp::os::Property &options) override
Definition: PortMonitor.cpp:55
PortMonitor::modifyOutgoingData
const yarp::os::PortWriter & modifyOutgoingData(const yarp::os::PortWriter &writer) override
Modify outgoing payload data, if appropriate.
Definition: PortMonitor.cpp:214
yarp::os::Things::getPortReader
yarp::os::PortReader * getPortReader()
Definition: Things.cpp:44
ResourceFinder.h
yarp::os::Property
A class for storing options and configuration information.
Definition: Property.h:37
Contactable.h
yarp::os::ResourceFinder
Helper class for finding config files and other external resources.
Definition: ResourceFinder.h:33