24#include <blackboard/exceptions.h>
25#include <blackboard/internal/instance_factory.h>
26#include <blackboard/internal/notifier.h>
27#include <blackboard/net/ilist_content.h>
28#include <blackboard/net/interface_proxy.h>
29#include <blackboard/net/messages.h>
30#include <blackboard/remote.h>
31#include <core/threading/mutex.h>
32#include <core/threading/mutex_locker.h>
33#include <core/threading/thread.h>
34#include <core/threading/wait_condition.h>
35#include <interface/interface_info.h>
36#include <netcomm/fawkes/client.h>
37#include <utils/time/time.h>
62 throw Exception(
"Cannot instantiate RemoteBlackBoard on unconnected client");
70 wait_mutex_ =
new Mutex();
73 inbound_thread_ = NULL;
96 throw Exception(
"Cannot instantiate RemoteBlackBoard on unconnected client");
101 mutex_ =
new Mutex();
104 wait_mutex_ =
new Mutex();
107 inbound_thread_ = NULL;
116 delete instance_factory_;
118 for (pit_ = proxies_.begin(); pit_ != proxies_.end(); ++pit_) {
138RemoteBlackBoard::reopen_interfaces()
141 ipit_ = invalid_proxies_.begin();
142 while (ipit_ != invalid_proxies_.end()) {
144 Interface *iface = (*ipit_)->interface();
147 ipit_ = invalid_proxies_.erase(ipit_);
148 }
catch (Exception &e) {
173RemoteBlackBoard::open_interface(
const char *type,
174 const char *identifier,
180 throw Exception(
"Cannot instantiate remote interface, connection is dead");
186 throw Exception(
"Cannot call open_interface() from inbound handler");
190 bb_iopen_msg_t *om = (bb_iopen_msg_t *)calloc(1,
sizeof(bb_iopen_msg_t));
191 strncpy(om->type, type, INTERFACE_TYPE_SIZE_ - 1);
192 strncpy(om->id, identifier, INTERFACE_ID_SIZE_ - 1);
193 memcpy(om->hash, iface->
hash(), INTERFACE_HASH_SIZE_);
195 FawkesNetworkMessage *omsg =
196 new FawkesNetworkMessage(FAWKES_CID_BLACKBOARD,
197 writer ? MSG_BB_OPEN_FOR_WRITING : MSG_BB_OPEN_FOR_READING,
199 sizeof(bb_iopen_msg_t));
205 && (!m_ || ((m_->
msgid() != MSG_BB_OPEN_SUCCESS) && (m_->
msgid() != MSG_BB_OPEN_FAILURE)))) {
215 throw Exception(
"Connection died while trying to open %s::%s", type, identifier);
218 if (m_->
msgid() == MSG_BB_OPEN_SUCCESS) {
220 BlackBoardInterfaceProxy *proxy =
221 new BlackBoardInterfaceProxy(fnc_, m_,
notifier_, iface, writer);
222 proxies_[proxy->serial()] = proxy;
223 }
else if (m_->
msgid() == MSG_BB_OPEN_FAILURE) {
224 bb_iopenfail_msg_t *fm = m_->
msg<bb_iopenfail_msg_t>();
225 unsigned int error = ntohl(fm->error_code);
229 throw BlackBoardWriterActiveException(identifier, type);
231 throw Exception(
"Hash mismatch for interface %s:%s", type, identifier);
233 throw Exception(
"Type %s unknown (%s::%s)", type, type, identifier);
235 throw BlackBoardWriterActiveException(identifier, type);
237 throw Exception(
"Could not open interface");
246RemoteBlackBoard::open_interface(
const char *type,
247 const char *identifier,
252 throw Exception(
"Cannot instantiate remote interface, connection is dead");
257 open_interface(type, identifier, owner, writer, iface);
258 }
catch (Exception &e) {
269 return open_interface(type, identifier, owner,
false);
275 return open_interface(type, identifier, owner,
true);
278std::list<Interface *>
280 const char *id_pattern,
283 std::list<Interface *> rv;
286 for (InterfaceInfoList::iterator i = infl->begin(); i != infl->end(); ++i) {
288 char type[INTERFACE_TYPE_SIZE_ + 1];
289 char id[INTERFACE_ID_SIZE_ + 1];
290 type[INTERFACE_TYPE_SIZE_] = 0;
291 id[INTERFACE_TYPE_SIZE_] = 0;
292 strncpy(type, i->type(), INTERFACE_TYPE_SIZE_);
293 strncpy(
id, i->id(), INTERFACE_ID_SIZE_);
295 if ((fnmatch(type_pattern, type, 0) == FNM_NOMATCH)
296 || (fnmatch(id_pattern,
id, 0) == FNM_NOMATCH)) {
305 for (std::list<Interface *>::iterator j = rv.begin(); j != rv.end(); ++j) {
321 if (interface == NULL)
326 if (proxies_.find(serial) != proxies_.end()) {
327 delete proxies_[serial];
328 proxies_.erase(serial);
349 throw Exception(
"Cannot call list_all() from inbound handler");
358 while (!m_ || (m_->
msgid() != MSG_BB_INTERFACE_LIST)) {
372 unsigned int num_readers = ntohl(ii->
writer_readers & htonl(0x7FFFFFFF));
379 std::list<std::string>(),
395 throw Exception(
"Cannot call list() from inbound handler");
402 strncpy(om->
type_pattern, type_pattern, INTERFACE_TYPE_SIZE_ - 1);
403 strncpy(om->
id_pattern, id_pattern, INTERFACE_ID_SIZE_ - 1);
410 while (!m_ || (m_->
msgid() != MSG_BB_INTERFACE_LIST)) {
424 unsigned int num_readers = ntohl(ii->
writer_readers & htonl(0x7FFFFFFF));
431 std::list<std::string>(),
458 if (m->cid() == FAWKES_CID_BLACKBOARD) {
459 unsigned int msgid = m->msgid();
461 if (msgid == MSG_BB_DATA_CHANGED || msgid == MSG_BB_DATA_REFRESHED) {
462 Uuid serial = ((
Uuid *)m->payload())[0];
463 if (proxies_.find(serial) != proxies_.end()) {
464 proxies_[serial]->process_data_refreshed(m);
466 }
else if (msgid == MSG_BB_INTERFACE_MESSAGE) {
467 Uuid serial = ((
Uuid *)m->payload())[0];
468 if (proxies_.find(serial) != proxies_.end()) {
469 proxies_[serial]->process_interface_message(m);
471 }
else if (msgid == MSG_BB_READER_ADDED) {
473 if (proxies_.find(esm->
serial) != proxies_.end()) {
476 }
else if (msgid == MSG_BB_READER_REMOVED) {
478 if (proxies_.find(esm->
serial) != proxies_.end()) {
481 }
else if (msgid == MSG_BB_WRITER_ADDED) {
483 if (proxies_.find(esm->
serial) != proxies_.end()) {
486 }
else if (msgid == MSG_BB_WRITER_REMOVED) {
488 if (proxies_.find(esm->
serial) != proxies_.end()) {
491 }
else if (msgid == MSG_BB_INTERFACE_CREATED) {
493 notifier_->notify_of_interface_created(em->
type, em->
id);
494 }
else if (msgid == MSG_BB_INTERFACE_DESTROYED) {
496 notifier_->notify_of_interface_destroyed(em->
type, em->
id);
501 wait_cond_->wake_all();
502 wait_mutex_->unlock();
510 inbound_thread_ = NULL;
519 for (pit_ = proxies_.begin(); pit_ != proxies_.end(); ++pit_) {
520 pit_->second->interface()->set_validity(
false);
521 invalid_proxies_.push_back(pit_->second);
525 wait_cond_->wake_all();
BlackBoard instance factory.
void delete_interface_instance(Interface *interface)
Destroy an interface instance.
Interface * new_interface_instance(const char *type, const char *identifier)
Creates a new interface instance.
BlackBoard interface list content.
bb_iinfo_msg_t * next(size_t *size)
Get next plugin from list.
bool has_next()
Check if more list elements are available.
BlackBoardNotifier * notifier_
Notifier for BB events.
Base class for exceptions in Fawkes.
Simple Fawkes network client.
void register_handler(FawkesNetworkClientHandler *handler, unsigned int component_id)
Register handler.
void connect()
Connect to remote.
void disconnect()
Disconnect socket.
void deregister_handler(unsigned int component_id)
Deregister handler.
bool connected() const noexcept
Check if connection is alive.
void enqueue(FawkesNetworkMessage *message)
Enqueue message to send.
Representation of a message that is sent over the network.
unsigned short int msgid() const
Get message type ID.
MT * msg() const
Get correctly casted payload.
MT * msgc() const
Get correctly parsed output.
Interface information list.
void append(const char *type, const char *id, const unsigned char *hash, unsigned int serial, bool has_writer, unsigned int num_readers, const std::list< std::string > &readers, const std::string &writer, const Time ×tamp)
Append an interface info.
Base class for all Fawkes BlackBoard interfaces.
void set_validity(bool valid)
Mark this interface invalid.
const char * type() const
Get type of interface.
bool is_writer() const
Check if this is a writing instance.
const unsigned char * hash() const
Get interface hash.
const char * id() const
Get identifier of interface.
Uuid serial() const
Get instance serial of interface.
const char * owner() const
Get owner of interface.
Mutex mutual exclusion lock.
void lock()
Lock this mutex.
void unlock()
Unlock the mutex.
void unref()
Decrement reference count and conditionally delete this instance.
virtual bool try_aliveness_restore() noexcept
Try to restore the aliveness of the BlackBoard instance.
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)
Open interface for reading.
virtual ~RemoteBlackBoard()
Destructor.
virtual InterfaceInfoList * list_all()
Get list of all currently existing interfaces.
virtual InterfaceInfoList * list(const char *type_pattern, const char *id_pattern)
Get list of interfaces matching type and ID patterns.
std::list< Interface * > open_multiple_for_reading(const char *interface_type, const char *id_pattern="*", const char *owner=NULL)
Open multiple interfaces for reading.
virtual void connection_died(unsigned int id) noexcept
Client connection died.
virtual void deregistered(unsigned int id) noexcept
We are no longer registered in Fawkes network client.
virtual Interface * open_for_writing(const char *interface_type, const char *identifier, const char *owner=NULL)
Open interface for writing.
virtual void connection_established(unsigned int id) noexcept
Client has established a connection.
virtual bool is_alive() const noexcept
Check if the BlackBoard is still alive.
virtual void close(Interface *interface)
Close interface.
virtual void inbound_received(FawkesNetworkMessage *msg, unsigned int id) noexcept
Called for incoming messages.
RemoteBlackBoard(FawkesNetworkClient *client)
Constructor.
const char * name() const
Get name of thread.
static Thread * current_thread()
Get the Thread instance of the currently running thread.
A class for handling time.
A convenience class for universally unique identifiers (UUIDs).
Wait until a given condition holds.
void wait()
Wait for the condition forever.
Fawkes library namespace.
@ BB_ERR_WRITER_EXISTS
You tried to open an interface for writing but there is already a writing instance for this interface...
@ BB_ERR_HASH_MISMATCH
The hashes of the interfaces do not match.
@ BB_ERR_UNKNOWN_TYPE
Requested interface type is unknown.
Message for interface events.
char type[INTERFACE_TYPE_SIZE_]
interface type name
char id[INTERFACE_ID_SIZE_]
interface instance ID
Message to identify an two interface instances.
Uuid event_serial
instance serial to unique identify instance that caused the event.
Uuid serial
instance serial to unique identify own instance
Message for interface info.
uint32_t writer_readers
combined writer reader information.
char id[INTERFACE_ID_SIZE_]
interface instance ID
unsigned char hash[INTERFACE_HASH_SIZE_]
interface version hash
int64_t timestamp_usec
data or write timestamp, usec part
int64_t timestamp_sec
data or write timestamp, sec part
uint32_t serial
instance serial to uniquely identify this instance (big endian)
char type[INTERFACE_TYPE_SIZE_]
interface type name
Message to request constrained interface list.
char type_pattern[INTERFACE_TYPE_SIZE_]
type pattern
char id_pattern[INTERFACE_ID_SIZE_]
ID pattern.
Message to identify an interface instance.
Uuid serial
instance serial to unique identify this instance