YARP
Yet Another Robot Platform
YarpNameSpace.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 
7 
9 #include <yarp/os/Log.h>
13 
14 #include <cstdio>
15 
16 using namespace yarp::os;
17 using namespace yarp::os::impl;
18 
19 #define HELPER(x) (*((NameClient*)((x)->system_resource)))
20 
21 namespace {
22 YARP_OS_LOG_COMPONENT(YARPNAMESPACE, "yarp.os.YarpNameSpace")
23 }
24 
26 {
27  system_resource = NameClient::create();
28  yAssert(system_resource != nullptr);
29  HELPER(this).setContact(contact);
30  this->contact = contact;
31 }
32 
34 {
35  if (system_resource != nullptr) {
36  delete &HELPER(this);
37  system_resource = nullptr;
38  }
39 }
40 
41 Contact YarpNameSpace::queryName(const std::string& name)
42 {
43  NameClient& nic = HELPER(this);
44  return nic.queryName(name);
45 }
46 
47 
48 Contact YarpNameSpace::registerName(const std::string& name)
49 {
50  return registerContact(Contact(name));
51 }
52 
54 {
55  NameClient& nic = HELPER(this);
56  yCDebug(YARPNAMESPACE, "Registering contact: %s", contact.toURI().c_str());
57  Contact address = nic.registerName(contact.getName(), contact);
58  yCDebug(YARPNAMESPACE, "Registered address: %s", address.toURI().c_str());
59 
60  if (address.isValid()) {
61  NestedContact nc;
62  nc.fromString(address.getRegName());
63  std::string cat = nc.getCategory();
64  if (!nc.getNestedName().empty()) {
65  //bool service = (cat.find("1") != std::string::npos);
66  bool publish = (cat.find('+') != std::string::npos);
67  bool subscribe = (cat.find('-') != std::string::npos);
68  ContactStyle style;
69  Contact c1(nc.getFullName());
70  Contact c2(std::string("topic:/") + nc.getNestedName());
71  if (subscribe) {
73  connectPortToTopic(c2, c1, style);
74  }
75  if (publish) {
77  connectPortToTopic(c1, c2, style);
78  }
79  }
80  }
81  return address;
82 }
83 
84 Contact YarpNameSpace::unregisterName(const std::string& name)
85 {
86  NestedContact nc;
87  nc.fromString(name);
88  std::string cat = nc.getCategory();
89  if (!nc.getNestedName().empty()) {
90  //bool service = (cat.find("1") != std::string::npos);
91  bool publish = (cat.find('+') != std::string::npos);
92  bool subscribe = (cat.find('-') != std::string::npos);
93  ContactStyle style;
94  Contact c1(nc.getFullName());
95  Contact c2(std::string("topic:/") + nc.getNestedName());
96  if (subscribe) {
97  disconnectPortFromTopic(c2, c1, style);
98  }
99  if (publish) {
100  disconnectPortFromTopic(c1, c2, style);
101  }
102  }
103  NameClient& nic = HELPER(this);
104  return nic.unregisterName(name);
105 }
106 
108 {
109  NameClient& nic = HELPER(this);
110  return nic.unregisterName(contact.getName());
111 }
112 
113 
114 bool YarpNameSpace::setProperty(const std::string& name, const std::string& key, const Value& value)
115 {
116  Bottle command;
117  command.addString("bot");
118  command.addString("set");
119  command.addString(name);
120  command.addString(key);
121  command.add(value);
122  Bottle reply;
123  NameClient& nic = HELPER(this);
124  nic.send(command, reply);
125  return reply.size() > 0;
126 }
127 
128 Value* YarpNameSpace::getProperty(const std::string& name, const std::string& key)
129 {
130  Bottle command;
131  command.addString("bot");
132  command.addString("get");
133  command.addString(name);
134  command.addString(key);
135  Bottle reply;
136  NameClient& nic = HELPER(this);
137  nic.send(command, reply);
138  return Value::makeValue(reply.toString());
139 }
140 
142  bool& scanNeeded,
143  bool& serverUsed)
144 {
145  NameConfig nc;
146  NameClient& nic = HELPER(this);
147  nic.setFakeMode(false);
148  nic.updateAddress();
149  nic.setScan();
150  if (useDetectedServer) {
151  nic.setSave();
152  }
153  nic.send("ping", false);
154  scanNeeded = nic.didScan();
155  serverUsed = nic.didSave();
156 
157  Contact c = nic.getAddress();
158  c.setName(nc.getNamespace());
159  //Contact c = nic.getAddress().toContact();
160  // if (scanNeeded) {
161  // Address addr = nic.getAddress();
162  // c.setSocket("tcp", addr.getName().c_str(), addr.getPort());
164  //c.setName(nc.getNamespace().c_str());
165  return c;
166 }
167 
168 
170  PortReader& reply,
171  const ContactStyle& style)
172 {
173  Contact srv = getNameServerContact();
174  std::string cmd0 = "NAME_SERVER";
175 
176  DummyConnector con0;
177  cmd.write(con0.getWriter());
178  Bottle in;
179  in.read(con0.getReader());
180  for (size_t i = 0; i < in.size(); i++) {
181  cmd0 += " ";
182  cmd0 += in.get(i).toString();
183  }
184  NameClient& nic = HELPER(this);
185  std::string result = nic.send(cmd0, true, style);
186  Bottle reply2;
187  reply2.addString(result.c_str());
188  DummyConnector con;
189  reply2.write(con.getWriter());
190  reply.read(con.getReader());
191  return !result.empty();
192 }
void cat(Vector &a, const Vector &b)
#define yAssert(x)
Definition: Log.h:294
#define HELPER(x)
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:74
void add(const Value &value)
Add a Value to the bottle, at the end of the list.
Definition: Bottle.cpp:336
size_type size() const
Gets the number of elements in the bottle.
Definition: Bottle.cpp:251
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
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
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Definition: Bottle.cpp:211
Preferences for how to communicate with a contact.
Definition: ContactStyle.h:24
PersistenceType persistenceType
Specify kind of persistence to use.
Definition: ContactStyle.h:81
Represents how to reach a part of a YARP network.
Definition: Contact.h:36
bool isValid() const
Checks if a Contact is tagged as valid.
Definition: Contact.cpp:298
std::string getName() const
Get the name associated with this Contact.
Definition: Contact.cpp:205
std::string getRegName() const
Get the name associated with this Contact.
Definition: Contact.cpp:217
std::string toURI(bool includeCarrier=true) const
Get a representation of the Contact as a URI.
Definition: Contact.cpp:313
void setName(const std::string &name)
Set the name associated with this Contact.
Definition: Contact.cpp:222
A dummy connection to test yarp::os::Portable implementations.
ConnectionWriter & getWriter()
Get the dummy ConnectionWriter loaded with whatever was written the ConnectionWriter since it was las...
ConnectionReader & getReader(ConnectionWriter *replyWriter=nullptr)
Get the dummy ConnectionReader loaded with whatever was written the ConnectionWriter since it was las...
A placeholder for rich contact information.
Definition: NestedContact.h:24
std::string getFullName() const
bool fromString(const std::string &nFullName)
std::string getNestedName() const
std::string getCategory() const
Interface implemented by all objects that can read themselves from the network, such as Bottle object...
Definition: PortReader.h:25
virtual bool read(ConnectionReader &reader)=0
Read this object from a network connection.
Interface implemented by all objects that can write themselves to the network, such as Bottle objects...
Definition: PortWriter.h:24
virtual bool write(ConnectionWriter &writer) const =0
Write this object to a network connection.
A single value (typically within a Bottle).
Definition: Value.h:45
static Value * makeValue(const std::string &txt)
Create a Value from a text description.
Definition: Value.cpp:456
std::string toString() const override
Return a standard text representation of the content of the object.
Definition: Value.cpp:356
Contact registerName(const std::string &name) override
Record contact information to tie to a port name.
virtual Value * getProperty(const std::string &name, const std::string &key) override
Get the value of a named key from a named port.
Contact unregisterName(const std::string &name) override
Disassociate contact information from a port name.
Contact unregisterContact(const Contact &contact) override
Disassociate contact information (should include a port name).
Contact registerContact(const Contact &contact) override
Record contact information (should include a port name).
virtual Contact detectNameServer(bool useDetectedServer, bool &scanNeeded, bool &serverUsed) override
Find a name server for this NameSpace, if applicable.
virtual bool setProperty(const std::string &name, const std::string &key, const Value &value) override
Associate a key/value pair with a named port.
Contact queryName(const std::string &name) override
Map from port name to contact information.
virtual bool writeToNameServer(PortWriter &cmd, PortReader &reply, const ContactStyle &style) override
Write a message to a name server for this NameSpace, if applicable.
YarpNameSpace(const Contact &contact)
Client for YARP name server.
Definition: NameClient.h:32
Contact unregisterName(const std::string &name)
Register disassociation of name from port.
Definition: NameClient.cpp:257
bool didScan()
Check whether the name client scanned for the address of the name server.
Definition: NameClient.cpp:442
static NameClient * create()
Definition: NameClient.cpp:131
bool didSave()
Check whether the name client saved the address of the name server.
Definition: NameClient.cpp:447
Contact getAddress()
The address of the name server.
Definition: NameClient.cpp:137
bool updateAddress()
Force the name client to reread the cached location of the name server.
Definition: NameClient.cpp:452
std::string send(const std::string &cmd, bool multi=true, const ContactStyle &style=ContactStyle())
Send a text message to the nameserver, and return the result.
Definition: NameClient.cpp:299
Contact queryName(const std::string &name)
Look up the address of a named port.
Definition: NameClient.cpp:143
void setFakeMode(bool fake=true)
For testing, the nameclient can be set to use a "fake" name server rather than communicating with an ...
Definition: NameClient.cpp:422
void setScan(bool allow=true)
Control whether the name client should scan for the name server if the cached connection information ...
Definition: NameClient.cpp:432
Contact registerName(const std::string &name)
Register a port with a given name.
Definition: NameClient.cpp:163
void setSave(bool allow=true)
Control whether the name client can save the address of the name server in a cache file.
Definition: NameClient.cpp:437
Small helper class to help deal with legacy YARP configuration files.
Definition: NameConfig.h:25
std::string getNamespace(bool refresh=false)
Definition: NameConfig.cpp:441
#define yCDebug(component,...)
Definition: LogComponent.h:109
#define YARP_OS_LOG_COMPONENT(name, name_string)
Definition: LogComponent.h:34
The components from which ports and connections are built.
An interface to the operating system, including Port based communication.