23 #include <blackboard/remote.h> 24 #include <blackboard/exceptions.h> 25 #include <blackboard/net/messages.h> 26 #include <blackboard/net/ilist_content.h> 27 #include <blackboard/net/interface_proxy.h> 28 #include <blackboard/internal/notifier.h> 29 #include <blackboard/internal/instance_factory.h> 31 #include <interface/interface_info.h> 33 #include <core/threading/thread.h> 34 #include <core/threading/mutex.h> 35 #include <core/threading/mutex_locker.h> 36 #include <core/threading/wait_condition.h> 37 #include <netcomm/fawkes/client.h> 38 #include <utils/time/time.h> 43 #include <arpa/inet.h> 64 throw Exception(
"Cannot instantiate RemoteBlackBoard on unconnected client");
69 __mutex =
new Mutex();
72 __wait_mutex =
new Mutex();
75 __inbound_thread = NULL;
99 throw Exception(
"Cannot instantiate RemoteBlackBoard on unconnected client");
104 __mutex =
new Mutex();
107 __wait_mutex =
new Mutex();
110 __inbound_thread = NULL;
120 delete __instance_factory;
122 for ( __pit = __proxies.begin(); __pit != __proxies.end(); ++__pit) {
123 delete __pit->second;
144 RemoteBlackBoard::reopen_interfaces()
147 __ipit = __invalid_proxies.begin();
148 while ( __ipit != __invalid_proxies.end() ) {
150 Interface *iface = (*__ipit)->interface();
153 __ipit = __invalid_proxies.erase(__ipit);
180 RemoteBlackBoard::open_interface(
const char *type,
const char *identifier,
const char *owner,
184 throw Exception(
"Cannot instantiate remote interface, connection is dead");
188 if (__inbound_thread != NULL &&
192 throw Exception(
"Cannot call open_interface() from inbound handler");
197 strncpy(om->
type, type, __INTERFACE_TYPE_SIZE);
198 strncpy(om->
id, identifier, __INTERFACE_ID_SIZE);
199 memcpy(om->
hash, iface->
hash(), __INTERFACE_HASH_SIZE);
202 writer ? MSG_BB_OPEN_FOR_WRITING : MSG_BB_OPEN_FOR_READING,
205 __wait_mutex->
lock();
209 ((__m->
msgid() != MSG_BB_OPEN_SUCCESS) &&
210 (__m->
msgid() != MSG_BB_OPEN_FAILURE))))
221 throw Exception(
"Connection died while trying to open %s::%s",
225 if ( __m->
msgid() == MSG_BB_OPEN_SUCCESS ) {
229 __proxies[proxy->
serial()] = proxy;
230 }
else if ( __m->
msgid() == MSG_BB_OPEN_FAILURE ) {
238 throw Exception(
"Hash mismatch for interface %s:%s", type, identifier);
240 throw Exception(
"Type %s unknown (%s::%s)", type, type, identifier);
244 throw Exception(
"Could not open interface");
253 RemoteBlackBoard::open_interface(
const char *type,
const char *identifier,
const char *owner,
bool writer)
256 throw Exception(
"Cannot instantiate remote interface, connection is dead");
261 open_interface(type, identifier, owner, writer, iface);
274 return open_interface(type, identifier, owner,
false);
281 return open_interface(type, identifier, owner,
true);
285 std::list<Interface *>
287 const char *id_pattern,
const char *owner)
289 std::list<Interface *> rv;
292 for (InterfaceInfoList::iterator i = infl->begin(); i != infl->end(); ++i) {
294 char type[__INTERFACE_TYPE_SIZE + 1];
295 char id[__INTERFACE_ID_SIZE + 1];
296 type[__INTERFACE_TYPE_SIZE] = 0;
297 id[__INTERFACE_TYPE_SIZE] = 0;
298 strncpy(type, i->type(), __INTERFACE_TYPE_SIZE);
299 strncpy(
id, i->id(), __INTERFACE_ID_SIZE);
301 if ((fnmatch(type_pattern, type, 0) == FNM_NOMATCH) ||
302 (fnmatch(id_pattern,
id, 0) == FNM_NOMATCH) ) {
311 for (std::list<Interface *>::iterator j = rv.begin(); j != rv.end(); ++j) {
328 if ( interface == NULL )
return;
330 unsigned int serial = interface->
serial();
332 if ( __proxies.find(serial) != __proxies.end() ) {
333 delete __proxies[serial];
334 __proxies.erase(serial);
356 if (__inbound_thread != NULL &&
359 throw Exception(
"Cannot call list_all() from inbound handler");
367 __wait_mutex->
lock();
370 (__m->
msgid() != MSG_BB_INTERFACE_LIST)) {
384 unsigned int num_readers = ntohl(ii->
writer_readers & htonl(0x7FFFFFFF));
386 has_writer, num_readers, std::list<std::string>(), std::string(),
401 if (__inbound_thread != NULL &&
404 throw Exception(
"Cannot call list() from inbound handler");
412 strncpy(om->
type_pattern, type_pattern, __INTERFACE_TYPE_SIZE);
413 strncpy(om->
id_pattern, id_pattern, __INTERFACE_ID_SIZE);
420 __wait_mutex->
lock();
423 (__m->
msgid() != MSG_BB_INTERFACE_LIST)) {
438 unsigned int num_readers = ntohl(ii->
writer_readers & htonl(0x7FFFFFFF));
440 has_writer, num_readers, std::list<std::string>(), std::string(),
463 unsigned int id)
throw()
469 if ( m->cid() == FAWKES_CID_BLACKBOARD ) {
470 unsigned int msgid = m->msgid();
472 if ( msgid == MSG_BB_DATA_CHANGED ) {
473 unsigned int serial = ntohl(((
unsigned int *)m->payload())[0]);
474 if ( __proxies.find(serial) != __proxies.end() ) {
475 __proxies[serial]->process_data_changed(m);
477 }
else if (msgid == MSG_BB_INTERFACE_MESSAGE) {
478 unsigned int serial = ntohl(((
unsigned int *)m->payload())[0]);
479 if ( __proxies.find(serial) != __proxies.end() ) {
480 __proxies[serial]->process_interface_message(m);
482 }
else if (msgid == MSG_BB_READER_ADDED) {
484 if ( __proxies.find(ntohl(esm->
serial)) != __proxies.end() ) {
487 }
else if (msgid == MSG_BB_READER_REMOVED) {
489 if ( __proxies.find(ntohl(esm->
serial)) != __proxies.end() ) {
492 }
else if (msgid == MSG_BB_WRITER_ADDED) {
494 if ( __proxies.find(ntohl(esm->
serial)) != __proxies.end() ) {
497 }
else if (msgid == MSG_BB_WRITER_REMOVED) {
499 if ( __proxies.find(ntohl(esm->
serial)) != __proxies.end() ) {
502 }
else if (msgid == MSG_BB_INTERFACE_CREATED) {
505 }
else if (msgid == MSG_BB_INTERFACE_DESTROYED) {
509 __wait_mutex->
lock();
521 __inbound_thread = NULL;
531 for (__pit = __proxies.begin(); __pit != __proxies.end(); ++__pit) {
532 __pit->second->interface()->set_validity(
false);
533 __invalid_proxies.push_back(__pit->second);
unsigned char hash[__INTERFACE_HASH_SIZE]
interface version hash
uint32_t serial
instance serial to uniquely identify this instance (big endian)
Interface * new_interface_instance(const char *type, const char *identifier)
Creates a new interface instance.
const char * owner() const
Get owner of interface.
bool has_next()
Check if more list elements are available.
BlackBoard instance factory.
char type[__INTERFACE_TYPE_SIZE]
interface type name
Wait until a given condition holds.
Requested interface type is unknown.
virtual Interface * open_for_writing(const char *interface_type, const char *identifier, const char *owner=NULL)
Open interface for writing.
Simple Fawkes network client.
void unref()
Decrement reference count and conditionally delete this instance.
void notify_of_interface_created(const char *type, const char *id)
Notify that an interface has been created.
char type[__INTERFACE_TYPE_SIZE]
interface type name
Message to identify an two interface instances.
int64_t timestamp_sec
data or write timestamp, sec part
Fawkes library namespace.
void unlock()
Unlock the mutex.
Message to identify an interface on open.
void wake_all()
Wake up all waiting threads.
void disconnect()
Disconnect socket.
int64_t timestamp_usec
data or write timestamp, usec part
const char * id() const
Get identifier of interface.
void register_handler(FawkesNetworkClientHandler *handler, unsigned int component_id)
Register handler.
void enqueue(FawkesNetworkMessage *message)
Enqueue message to send.
unsigned int serial() const
Get instance serial of interface.
Representation of a message that is sent over the network.
void connect()
Connect to remote.
bb_iinfo_msg_t * next(size_t *size)
Get next plugin from list.
A class for handling time.
virtual void deregistered(unsigned int id)
We are no longer registered in Fawkes network client.
virtual void connection_established(unsigned int id)
Client has established a connection.
MT * msgc() const
Get correctly parsed output.
Base class for all Fawkes BlackBoard interfaces.
Message for interface info.
You tried to open an interface for writing but there is already a writing instance for this interface...
uint32_t error_code
Error code.
uint32_t event_serial
instance serial to unique identify instance that caused the event.
virtual InterfaceInfoList * list(const char *type_pattern, const char *id_pattern)
Get list of interfaces matching type and ID patterns.
const unsigned char * hash() const
Get interface hash.
Interface information list.
const char * type() const
Get type of interface.
char id[__INTERFACE_ID_SIZE]
interface instance ID
virtual void close(Interface *interface)
Close interface.
char id_pattern[__INTERFACE_ID_SIZE]
ID pattern.
Base class for exceptions in Fawkes.
unsigned short serial() const
Get instance serial of interface.
virtual ~RemoteBlackBoard()
Destructor.
uint32_t serial
instance serial to unique identify own instance
uint32_t writer_readers
combined writer reader information.
void delete_interface_instance(Interface *interface)
Destroy an interface instance.
char type[__INTERFACE_TYPE_SIZE]
interface type name
virtual bool try_aliveness_restore()
Try to restore the aliveness of the BlackBoard instance.
Interface proxy for remote BlackBoard.
virtual void inbound_received(FawkesNetworkMessage *msg, unsigned int id)
Called for incoming messages.
void notify_of_interface_destroyed(const char *type, const char *id)
Notify that an interface has been destroyed.
void ref()
Increment reference count.
unsigned char hash[__INTERFACE_HASH_SIZE]
interface version hash
The hashes of the interfaces do not match.
static Thread * current_thread()
Get the Thread instance of the currently running thread.
const char * name() const
Get name of thread.
BlackBoardNotifier * __notifier
Notifier for BB events.
virtual void connection_died(unsigned int id)
Client connection died.
void wait()
Wait for the condition forever.
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.
bool is_writer() const
Check if this is a writing instance.
char id[__INTERFACE_ID_SIZE]
interface instance ID
unsigned short int msgid() const
Get message type ID.
uint32_t serial
instance serial to unique identify this instance
RemoteBlackBoard(FawkesNetworkClient *client)
Constructor.
char type_pattern[__INTERFACE_TYPE_SIZE]
type pattern
virtual InterfaceInfoList * list_all()
Get list of all currently existing interfaces.
void deregister_handler(unsigned int component_id)
Deregister handler.
Message for interface events.
void set_validity(bool valid)
Mark this interface invalid.
Message to request constrained interface list.
BlackBoard interface list content.
Message to identify an interface instance.
void lock()
Lock this mutex.
bool connected() const
Check if connection is alive.
Thrown if a writer is already active on an interface that writing has been requested for...
MT * msg() const
Get correctly casted payload.
Mutex mutual exclusion lock.
char id[__INTERFACE_ID_SIZE]
interface instance ID
virtual bool is_alive() const
Check if the BlackBoard is still alive.
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)
Open interface for reading.
std::list< Interface * > open_multiple_for_reading(const char *interface_type, const char *id_pattern="*", const char *owner=NULL)
Open multiple interfaces for reading.
Message to send update data.