24 #include <blackboard/remote.h> 25 #include <blackboard/exceptions.h> 26 #include <blackboard/net/messages.h> 27 #include <blackboard/net/ilist_content.h> 28 #include <blackboard/net/interface_proxy.h> 29 #include <blackboard/internal/notifier.h> 30 #include <blackboard/internal/instance_factory.h> 32 #include <interface/interface_info.h> 34 #include <core/threading/thread.h> 35 #include <core/threading/mutex.h> 36 #include <core/threading/mutex_locker.h> 37 #include <core/threading/wait_condition.h> 38 #include <netcomm/fawkes/client.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,
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,
bool writer)
256 throw Exception(
"Cannot instantiate remote interface, connection is dead");
261 open_interface(type, identifier, writer, iface);
274 return open_interface(type, identifier,
false);
281 return open_interface(type, identifier,
true);
285 std::list<Interface *>
287 const char *id_pattern)
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)) {
398 if (__inbound_thread != NULL &&
401 throw Exception(
"Cannot call list() from inbound handler");
409 strncpy(om->
type_pattern, type_pattern, __INTERFACE_TYPE_SIZE);
410 strncpy(om->
id_pattern, id_pattern, __INTERFACE_ID_SIZE);
417 __wait_mutex->
lock();
420 (__m->
msgid() != MSG_BB_INTERFACE_LIST)) {
457 unsigned int id)
throw()
463 if ( m->cid() == FAWKES_CID_BLACKBOARD ) {
464 unsigned int msgid = m->msgid();
466 if ( msgid == MSG_BB_DATA_CHANGED ) {
467 unsigned int serial = ntohl(((
unsigned int *)m->payload())[0]);
468 if ( __proxies.find(serial) != __proxies.end() ) {
469 __proxies[serial]->process_data_changed(m);
471 }
else if (msgid == MSG_BB_INTERFACE_MESSAGE) {
472 unsigned int serial = ntohl(((
unsigned int *)m->payload())[0]);
473 if ( __proxies.find(serial) != __proxies.end() ) {
474 __proxies[serial]->process_interface_message(m);
476 }
else if (msgid == MSG_BB_READER_ADDED) {
478 if ( __proxies.find(ntohl(esm->
serial)) != __proxies.end() ) {
481 }
else if (msgid == MSG_BB_READER_REMOVED) {
483 if ( __proxies.find(ntohl(esm->
serial)) != __proxies.end() ) {
486 }
else if (msgid == MSG_BB_WRITER_ADDED) {
488 if ( __proxies.find(ntohl(esm->
serial)) != __proxies.end() ) {
491 }
else if (msgid == MSG_BB_WRITER_REMOVED) {
493 if ( __proxies.find(ntohl(esm->
serial)) != __proxies.end() ) {
496 }
else if (msgid == MSG_BB_INTERFACE_CREATED) {
499 }
else if (msgid == MSG_BB_INTERFACE_DESTROYED) {
503 __wait_mutex->
lock();
515 __inbound_thread = NULL;
525 for (__pit = __proxies.begin(); __pit != __proxies.end(); ++__pit) {
526 __pit->second->interface()->set_validity(
false);
527 __invalid_proxies.push_back(__pit->second);
unsigned char hash[__INTERFACE_HASH_SIZE]
interface version hash
uint32_t serial
instance serial to unique identify this instance
Interface * new_interface_instance(const char *type, const char *identifier)
Creates a new interface instance.
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.
unsigned short serial() const
Get instance serial of interface.
Requested interface type is unknown.
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
uint32_t num_readers
number of currently existing readers
Message to identify an two interface instances.
Fawkes library namespace.
void unlock()
Unlock the mutex.
Message to identify an interface on open.
virtual bool is_alive() const
Check if the BlackBoard is still alive.
void wake_all()
Wake up all waiting threads.
void disconnect()
Disconnect socket.
uint32_t has_writer
1 if the interface currently has a writer, 0 otherwise
void register_handler(FawkesNetworkClientHandler *handler, unsigned int component_id)
Register handler.
unsigned int serial() const
Get instance serial of interface.
void enqueue(FawkesNetworkMessage *message)
Enqueue message to send.
const unsigned char * hash() const
Get interface hash.
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.
unsigned short int msgid() const
Get message type ID.
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.
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 char * id() const
Get identifier of interface.
Interface information list.
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.
virtual ~RemoteBlackBoard()
Destructor.
uint32_t serial
instance serial to unique identify own instance
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.
bool connected() const
Check if connection is alive.
BlackBoardNotifier * __notifier
Notifier for BB events.
virtual void connection_died(unsigned int id)
Client connection died.
void wait()
Wait for the condition forever.
const char * name() const
Get name of thread.
MT * msgc() const
Get correctly parsed output.
virtual Interface * open_for_reading(const char *interface_type, const char *identifier)
Open interface for reading.
MT * msg() const
Get correctly casted payload.
char id[__INTERFACE_ID_SIZE]
interface instance 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 append(const char *type, const char *id, const unsigned char *hash, unsigned int serial, bool has_writer, unsigned int num_readers)
Append an interface info.
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 is_writer() const
Check if this is a writing instance.
Thrown if a writer is already active on an interface that writing has been requested for...
Mutex mutual exclusion lock.
std::list< Interface * > open_multiple_for_reading(const char *interface_type, const char *id_pattern="*")
Open multiple interfaces for reading.
char id[__INTERFACE_ID_SIZE]
interface instance ID
const char * type() const
Get type of interface.
virtual Interface * open_for_writing(const char *interface_type, const char *identifier)
Open interface for writing.
Message to send update data.