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);
154 }
catch (Exception &e) {
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");
196 bb_iopen_msg_t *om = (bb_iopen_msg_t *)calloc(1,
sizeof(bb_iopen_msg_t));
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);
201 FawkesNetworkMessage *omsg =
new FawkesNetworkMessage(FAWKES_CID_BLACKBOARD,
202 writer ? MSG_BB_OPEN_FOR_WRITING : MSG_BB_OPEN_FOR_READING,
203 om,
sizeof(bb_iopen_msg_t));
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 ) {
227 BlackBoardInterfaceProxy *proxy =
new BlackBoardInterfaceProxy(__fnc, __m,
__notifier,
229 __proxies[proxy->serial()] = proxy;
230 }
else if ( __m->
msgid() == MSG_BB_OPEN_FAILURE ) {
231 bb_iopenfail_msg_t *fm = __m->
msg<bb_iopenfail_msg_t>();
232 unsigned int error = ntohl(fm->errno);
236 throw BlackBoardWriterActiveException(identifier, type);
238 throw Exception(
"Hash mismatch for interface %s:%s", type, identifier);
240 throw Exception(
"Type %s unknown (%s::%s)", type, type, identifier);
242 throw BlackBoardWriterActiveException(identifier, type);
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);
262 }
catch (Exception &e) {
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) {
498 __notifier->notify_of_interface_created(em->
type, em->
id);
499 }
else if (msgid == MSG_BB_INTERFACE_DESTROYED) {
501 __notifier->notify_of_interface_destroyed(em->
type, em->
id);
503 __wait_mutex->lock();
506 __wait_cond->wake_all();
507 __wait_mutex->unlock();
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);
531 __wait_cond->wake_all();