YARP
Yet Another Robot Platform
DeviceDriver.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * Copyright (C) 2006-2010 RobotCub Consortium
4  * All rights reserved.
5  *
6  * This software may be modified and distributed under the terms of the
7  * BSD-3-Clause license. See the accompanying LICENSE file for details.
8  */
9 
10 #include <cstdio>
11 #include <yarp/dev/DeviceDriver.h>
12 #include <yarp/os/Vocab.h>
13 #include <yarp/os/LogComponent.h>
14 #include <yarp/os/Value.h>
15 
16 using namespace yarp::dev;
17 using namespace yarp::os;
18 using namespace yarp::os::impl;
19 
20 namespace {
21  YARP_LOG_COMPONENT(DEVICERESPONDER, "yarp.dev.DeviceResponder")
22 }
23 
25  makeUsage();
26 }
27 
28 void DeviceResponder::addUsage(const char *txt, const char *explain) {
29  examples.addString(txt); //Value::makeList(txt));
30  explains.addString((explain!=nullptr)?explain:"");
31  details.add(Value::makeList(txt));
32  std::string more = std::string(" ") + ((explain != nullptr) ? explain : "");
33  details.addString(more.c_str());
34 }
35 
36 
37 void DeviceResponder::addUsage(const Bottle& bot, const char *explain) {
38  addUsage(bot.toString().c_str(),explain);
39 }
40 
41 
42 bool DeviceResponder::respond(const Bottle& command, Bottle& reply) {
43  switch (command.get(0).asVocab()) {
44  case yarp::os::createVocab('h','e','l','p'):
45  if (examples.size()>=1) {
46  reply.add(Value::makeVocab("many"));
47  if (command.get(1).toString()=="more") {
48  reply.append(details);
49  } else {
50  reply.append(examples);
51  }
52  return true;
53  } else {
54  reply.addString("no documentation available");
55  return false;
56  }
57  break;
58  default:
59  reply.addString("command not recognized");
60  return false;
61  }
62  return false;
63 }
64 
66 {
67  Bottle cmd;
68  Bottle response;
69  if (!cmd.read(connection)) {
70  return false;
71  }
72  yCTrace(DEVICERESPONDER, "Command received: %s", cmd.toString().c_str());
73  respond(cmd, response);
74  if (response.size() >= 1) {
75  ConnectionWriter* writer = connection.getWriter();
76  if (writer != nullptr) {
77  if (response.get(0).toString() == "many" && writer->isTextMode()) {
78  for (size_t i = 1; i < response.size(); i++) {
79  Value& v = response.get(i);
80  if (v.isList()) {
81  v.asList()->write(*writer);
82  } else {
83  Bottle b;
84  b.add(v);
85  b.write(*writer);
86  }
87  }
88  } else {
89  response.write(*writer);
90  }
91 
92  yCTrace(DEVICERESPONDER, "Response sent: %s", response.toString().c_str());
93  }
94  } else {
95  ConnectionWriter* writer = connection.getWriter();
96  if (writer != nullptr) {
97  response.clear();
98  response.addVocab(Vocab::encode("nak"));
99  response.write(*writer);
100  }
101  }
102  return true;
103 }
104 
105 
107  examples.clear();
108  explains.clear();
109  details.clear();
110  addUsage("[help]", "list usage");
111  addUsage("[help] [more]", "list usage with some comments");
112 }
virtual bool respond(const yarp::os::Bottle &command, yarp::os::Bottle &reply)
Respond to a message.
void addUsage(const char *txt, const char *explain=nullptr)
Add information about a message that the respond() method understands.
void makeUsage()
Regenerate usage information.
bool read(yarp::os::ConnectionReader &connection) override
Handler for reading messages from the network, and passing them on to the respond() method.
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:73
void add(const Value &value)
Add a Value to the bottle, at the end of the list.
Definition: Bottle.cpp:339
void append(const Bottle &alt)
Append the content of the given bottle to the current list.
Definition: Bottle.cpp:383
size_type size() const
Gets the number of elements in the bottle.
Definition: Bottle.cpp:254
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
Definition: Bottle.cpp:243
void addVocab(int x)
Places a vocabulary item in the bottle, at the end of the list.
Definition: Bottle.cpp:167
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition: Bottle.cpp:249
void clear()
Empties the bottle of any objects it contains.
Definition: Bottle.cpp:124
bool write(ConnectionWriter &writer) const override
Output a representation of the bottle to a network connection.
Definition: Bottle.cpp:233
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition: Bottle.cpp:173
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Definition: Bottle.cpp:214
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.
virtual bool isTextMode() const =0
Check if the connection is text mode.
A single value (typically within a Bottle).
Definition: Value.h:47
virtual bool isList() const
Checks if value is a list.
Definition: Value.cpp:165
virtual Bottle * asList() const
Get list value.
Definition: Value.cpp:243
std::string toString() const override
Return a standard text representation of the content of the object.
Definition: Value.cpp:359
virtual std::int32_t asVocab() const
Get vocabulary identifier as an integer.
Definition: Value.cpp:231
#define yCTrace(component,...)
Definition: LogComponent.h:88
#define YARP_LOG_COMPONENT(name,...)
Definition: LogComponent.h:80
An interface for the device drivers.
NetInt32 encode(const std::string &str)
Convert a string into a vocabulary identifier.
Definition: Vocab.cpp:14
The components from which ports and connections are built.
An interface to the operating system, including Port based communication.
constexpr yarp::conf::vocab32_t createVocab(char a, char b=0, char c=0, char d=0)
Definition: Vocab.h:22