YARP
Yet Another Robot Platform
RobotDescriptionServer.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 
8 #include <yarp/os/Log.h>
9 #include <yarp/os/LogComponent.h>
10 #include <yarp/os/LogStream.h>
11 #include <mutex>
12 
15 using namespace yarp::dev;
16 using namespace yarp::os;
17 using namespace yarp::sig;
18 
19 namespace {
20 YARP_LOG_COMPONENT(ROBOTDESCRIPTIONSERVER, "yarp.device.robotDescriptionServer")
21 }
22 
23 //------------------------------------------------------------------------------------------------------------------------------
24 
26 {
27  m_local_name.clear();
28  m_local_name = config.find("local").asString();
29 
30  if (m_local_name == "")
31  {
32  yCError(ROBOTDESCRIPTIONSERVER, "open(): Invalid local name");
33  return false;
34  }
35 
36  std::string local_rpc = m_local_name;
37  local_rpc += "/rpc";
38 
39  if (!m_rpc_port.open(local_rpc))
40  {
41  yCError(ROBOTDESCRIPTIONSERVER, "open(): Could not open rpc port %s, check network", local_rpc.c_str());
42  return false;
43  }
44 
45  m_rpc_port.setReader(*this);
46  return true;
47 }
48 
50 {
51  std::lock_guard<std::mutex> guard(m_external_mutex);
52  for (int i = 0; i < p.size(); i++)
53  {
54  yCTrace(ROBOTDESCRIPTIONSERVER) << p[i]->poly->getOptions().toString();
55  yCTrace(ROBOTDESCRIPTIONSERVER) << p[i]->poly->getValue("device").toString();
56  yCTrace(ROBOTDESCRIPTIONSERVER) << p[i]->poly->getValue("name").toString();
58  dev.device_name = p[i]->poly->getValue("name").toString();
59  dev.device_type = p[i]->poly->getValue("device").toString();
60  if (this->add_device(dev) == false)
61  {
62  yCError(ROBOTDESCRIPTIONSERVER) << "attachAll(): Something strange happened here";
63  //return false;
64  }
65  }
66  return true;
67 }
68 
70 {
71  std::lock_guard<std::mutex> guard(m_external_mutex);
72  m_robot_devices.clear();
73  return true;
74 }
75 
77 {
78  m_rpc_port.close();
79  return true;
80 }
81 
82 bool RobotDescriptionServer::add_device(DeviceDescription dev)
83 {
84  std::lock_guard<std::mutex> guard(m_internal_mutex);
85  for (auto& m_robot_device : m_robot_devices)
86  {
87  if (dev.device_name == m_robot_device.device_name)
88  {
89  yCWarning(ROBOTDESCRIPTIONSERVER) << "add_device(): Device" << dev.device_name << "already exists, skipping";
90  return false;
91  }
92  }
93  m_robot_devices.push_back(dev);
94  return true;
95 }
96 
97 bool RobotDescriptionServer::remove_device(DeviceDescription dev)
98 {
99  std::lock_guard<std::mutex> guard(m_internal_mutex);
100  for (auto it = m_robot_devices.begin(); it != m_robot_devices.end(); it++)
101  {
102  if (dev.device_name == it->device_name)
103  {
104  m_robot_devices.erase(it);
105  return true;
106  }
107  }
108  return false;
109 }
110 
112 {
113  std::lock_guard<std::mutex> guard(m_external_mutex);
114  yarp::os::Bottle in;
115  yarp::os::Bottle out;
116  bool ret;
117  int code;
118 
119  bool ok = in.read(connection);
120  if (!ok) {
121  return false;
122  }
123 
124  // parse in, prepare out
125  code = in.get(0).asVocab32();
126  ret = false;
127 
128  if (code == VOCAB_IROBOT_DESCRIPTION)
129  {
130  int macro_cmd = in.get(1).asVocab32();
131  if (macro_cmd == VOCAB_IROBOT_GET)
132  {
133  int cmd = in.get(2).asVocab32();
134  if (cmd == VOCAB_IROBOT_ALL)
135  {
136  out.addVocab32(VOCAB_OK);
137  Bottle& l = out.addList();
138  for (auto& m_robot_device : m_robot_devices)
139  {
140  l.addString(m_robot_device.device_name);
141  l.addString(m_robot_device.device_type);
142  }
143  ret = true;
144  }
145  else if (cmd == VOCAB_IROBOT_BY_TYPE)
146  {
147  std::string type = in.get(3).asString();
148  out.addVocab32(VOCAB_OK);
149  Bottle& l = out.addList();
150  for (auto& m_robot_device : m_robot_devices)
151  {
152  if (m_robot_device.device_type == type)
153  {
154  l.addString(m_robot_device.device_name);
155  l.addString(m_robot_device.device_type);
156  }
157  }
158  ret = true;
159  }
160  else
161  {
162  ret = false;
163  yCError(ROBOTDESCRIPTIONSERVER, "Invalid vocab received");
164  }
165 
166  }
167  else if (macro_cmd == VOCAB_IROBOT_DELETE)
168  {
169  int cmd = in.get(2).asVocab32();
170  if (cmd == VOCAB_IROBOT_DEVICE)
171  {
172  std::string name = in.get(3).asString();
173  DeviceDescription dev;
174  dev.device_name = name;
175  bool b_rem = this->remove_device(dev);
176  if (b_rem == false)
177  {
178  yCError(ROBOTDESCRIPTIONSERVER) << "remove_device failed";
179  }
180  else
181  {
182  out.addVocab32(VOCAB_OK);
183  ret = true;
184  }
185  }
186  else
187  {
188  ret = false;
189  yCError(ROBOTDESCRIPTIONSERVER, "Invalid vocab received");
190  }
191  }
192  else if (macro_cmd == VOCAB_IROBOT_SET)
193  {
194  int cmd = in.get(2).asVocab32();
195  if (cmd == VOCAB_IROBOT_DEVICE)
196  {
197  DeviceDescription desc;
198  desc.device_name = in.get(3).asString();
199  desc.device_type = in.get(4).asString();
200  bool b_add = this->add_device(desc);
201  if (b_add == false)
202  {
203  yCError(ROBOTDESCRIPTIONSERVER) << "add_device failed";
204  }
205  else
206  {
207  out.addVocab32(VOCAB_OK);
208  ret = true;
209  }
210  }
211  else
212  {
213  ret = false;
214  yCError(ROBOTDESCRIPTIONSERVER, "Invalid vocab received");
215  }
216  }
217  else
218  {
219  ret = false;
220  yCError(ROBOTDESCRIPTIONSERVER, "Invalid vocab received");
221  }
222  }
223  else
224  {
225  ret = false;
226  yCError(ROBOTDESCRIPTIONSERVER, "Invalid vocab received");
227  }
228 
229  if (!ret)
230  {
231  out.clear();
233  }
234 
235  yarp::os::ConnectionWriter *returnToSender = connection.getWriter();
236 
237  if (returnToSender != nullptr)
238  {
239  out.write(*returnToSender);
240  }
241 
242  return true;
243 }
constexpr yarp::conf::vocab32_t VOCAB_OK
Definition: GenericVocabs.h:15
constexpr yarp::conf::vocab32_t VOCAB_FAILED
Definition: GenericVocabs.h:16
constexpr yarp::conf::vocab32_t VOCAB_IROBOT_SET
constexpr yarp::conf::vocab32_t VOCAB_IROBOT_DEVICE
constexpr yarp::conf::vocab32_t VOCAB_IROBOT_DELETE
constexpr yarp::conf::vocab32_t VOCAB_IROBOT_DESCRIPTION
constexpr yarp::conf::vocab32_t VOCAB_IROBOT_BY_TYPE
constexpr yarp::conf::vocab32_t VOCAB_IROBOT_ALL
constexpr yarp::conf::vocab32_t VOCAB_IROBOT_GET
bool ret
bool read(yarp::os::ConnectionReader &connection) override
Read this object from a network connection.
bool detachAll() override
Detach the object (you must have first called attach).
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
bool attachAll(const yarp::dev::PolyDriverList &l) override
Attach to a list of objects.
bool close() override
Close the DeviceDriver.
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:74
void addVocab32(yarp::conf::vocab32_t x)
Places a vocabulary item in the bottle, at the end of the list.
Definition: Bottle.cpp:164
Bottle & addList()
Places an empty nested list in the bottle, at the end of the list.
Definition: Bottle.cpp:182
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
Definition: Bottle.cpp:240
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
bool write(ConnectionWriter &writer) const override
Output a representation of the bottle to a network connection.
Definition: Bottle.cpp:230
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition: Bottle.cpp:170
An interface for reading from a network connection.
virtual ConnectionWriter * getWriter()=0
Gets a way to reply to the message, if possible.
An interface for writing to a network connection.
A base class for nested structures that can be searched.
Definition: Searchable.h:66
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
virtual yarp::conf::vocab32_t asVocab32() const
Get vocabulary identifier as an integer.
Definition: Value.cpp:228
virtual std::string asString() const
Get string value.
Definition: Value.cpp:234
#define yCError(component,...)
Definition: LogComponent.h:154
#define yCTrace(component,...)
Definition: LogComponent.h:85
#define yCWarning(component,...)
Definition: LogComponent.h:143
#define YARP_LOG_COMPONENT(name,...)
Definition: LogComponent.h:77
An interface for the device drivers.
An interface to the operating system, including Port based communication.
Signal processing.
Definition: Image.h:22