24 #include <blackboard/net/handler.h>
25 #include <blackboard/net/messages.h>
26 #include <blackboard/net/ilist_content.h>
27 #include <blackboard/blackboard.h>
28 #include <blackboard/exceptions.h>
29 #include <blackboard/net/interface_listener.h>
30 #include <blackboard/net/interface_observer.h>
32 #include <interface/interface.h>
33 #include <interface/interface_info.h>
35 #include <logging/liblogger.h>
36 #include <netcomm/fawkes/component_ids.h>
37 #include <netcomm/fawkes/hub.h>
41 #include <arpa/inet.h>
59 :
Thread(
"BlackBoardNetworkHandler",
Thread::OPMODE_WAITFORWAKEUP),
75 __inbound_queue.
clear();
77 for (__lit = __listeners.begin(); __lit != __listeners.end(); ++__lit) {
80 for (__iit = __interfaces.begin(); __iit != __interfaces.end(); ++__iit) {
81 __bb->
close(__iit->second);
90 while ( ! __inbound_queue.empty() ) {
94 unsigned int clid = msg->
clid();
96 switch (msg->
msgid()) {
102 for (InterfaceInfoList::iterator i = infl->begin(); i != infl->end(); ++i) {
107 __nhub->
send(clid, FAWKES_CID_BLACKBOARD, MSG_BB_INTERFACE_LIST, ilist);
110 "list to %u, exception follows", clid);
124 char type_pattern[__INTERFACE_TYPE_SIZE + 1];
125 char id_pattern[__INTERFACE_ID_SIZE + 1];
126 type_pattern[__INTERFACE_TYPE_SIZE] = 0;
127 id_pattern[__INTERFACE_ID_SIZE] = 0;
128 strncpy(type_pattern, lrm->
type_pattern, __INTERFACE_TYPE_SIZE);
129 strncpy(id_pattern, lrm->
id_pattern, __INTERFACE_ID_SIZE);
132 for (InterfaceInfoList::iterator i = infl->begin(); i != infl->end(); ++i)
138 __nhub->
send(clid, FAWKES_CID_BLACKBOARD, MSG_BB_INTERFACE_LIST, ilist);
141 "interface list to %u, exception follows", clid);
148 case MSG_BB_OPEN_FOR_READING:
149 case MSG_BB_OPEN_FOR_WRITING:
153 char type[__INTERFACE_TYPE_SIZE + 1];
154 char id[__INTERFACE_ID_SIZE + 1];
155 type[__INTERFACE_TYPE_SIZE] = 0;
156 id[__INTERFACE_ID_SIZE] = 0;
157 strncpy(type, om->
type, __INTERFACE_TYPE_SIZE);
158 strncpy(
id, om->
id, __INTERFACE_ID_SIZE);
165 if ( msg->
msgid() == MSG_BB_OPEN_FOR_READING ) {
170 if ( memcmp(iface->
hash(), om->
hash, __INTERFACE_HASH_SIZE) != 0 ) {
172 "hash mismatch", type,
id);
175 __interfaces[iface->
serial()] = iface;
176 __client_interfaces[clid].push_back(iface);
177 __serial_to_clid[iface->
serial()] = clid;
182 send_opensuccess(clid, iface);
186 "interface class not found", type,
id);
190 "writer already exists", type,
id);
209 unsigned int sm_serial = ntohl(sm->
serial);
210 if ( __interfaces.find(sm_serial) != __interfaces.end() ) {
212 __client_interfaces.
lock();
213 if ( __client_interfaces.find(clid) != __client_interfaces.end()) {
215 for ( __ciit = __client_interfaces[clid].begin(); __ciit != __client_interfaces[clid].end(); ++__ciit) {
216 if ( (*__ciit)->serial() == sm_serial ) {
218 __serial_to_clid.erase(sm_serial);
219 __client_interfaces[clid].erase(__ciit);
220 if ( __client_interfaces[clid].empty() ) {
221 __client_interfaces.erase(clid);
227 __client_interfaces.
unlock();
232 clid, __interfaces[sm_serial]->uid());
233 delete __listeners[sm_serial];
234 __listeners.erase(sm_serial);
235 __bb->
close(__interfaces[sm_serial]);
236 __interfaces.erase(sm_serial);
240 "interface with serial %u, but opened by other client",
245 "interface with serial %u which has not been opened",
255 case MSG_BB_DATA_CHANGED:
257 void *payload = msg->
payload();
259 unsigned int dm_serial = ntohl(dm->
serial);
260 if ( __interfaces.find(dm_serial) != __interfaces.end() ) {
262 if ( ntohl(dm->
data_size) != __interfaces[dm_serial]->datasize() ) {
264 "expected %zu, but got %zu, ignoring.",
265 __interfaces[dm_serial]->datasize(), ntohl(dm->
data_size));
267 __interfaces[dm_serial]->set_from_chunk((
char *)payload +
sizeof(
bb_idata_msg_t));
268 __interfaces[dm_serial]->write();
272 "serial %u not found, ignoring.", dm_serial);
277 case MSG_BB_INTERFACE_MESSAGE:
279 void *payload = msg->
payload();
281 unsigned int mm_serial = ntohl(mm->
serial);
282 if ( __interfaces.find(mm_serial) != __interfaces.end() ) {
284 if ( ! __interfaces[mm_serial]->is_writer() ) {
292 "expected %zu, but got %zu, ignoring.",
297 __interfaces[mm_serial]->msgq_enqueue(ifm);
302 "interface message, ignoring.");
307 "notification, but for a writing instance, ignoring.");
311 "serial %u not found, ignoring.", mm_serial);
318 "received", msg->
msgid());
329 BlackBoardNetworkHandler::send_opensuccess(
unsigned int clid,
Interface *interface)
334 osm->has_writer = interface->
has_writer() ? 1 : 0;
335 osm->num_readers = htonl(interface->
num_readers());
336 osm->data_size = htonl(interface->
datasize());
342 memcpy((
char *)payload +
sizeof(bb_iopensucc_msg_t),
345 FawkesNetworkMessage *omsg =
new FawkesNetworkMessage(clid, FAWKES_CID_BLACKBOARD,
346 MSG_BB_OPEN_SUCCESS, payload,
347 sizeof(bb_iopensucc_msg_t) +
351 }
catch (Exception &e) {
353 "open success to %u, exception follows", clid);
360 BlackBoardNetworkHandler::send_openfailure(
unsigned int clid,
unsigned int errno)
362 bb_iopenfail_msg_t *ofm = (bb_iopenfail_msg_t *)malloc(
sizeof(bb_iopenfail_msg_t));
363 ofm->errno = htonl(errno);
365 FawkesNetworkMessage *omsg =
new FawkesNetworkMessage(clid, FAWKES_CID_BLACKBOARD,
366 MSG_BB_OPEN_FAILURE, ofm,
367 sizeof(bb_iopenfail_msg_t));
370 }
catch (Exception &e) {
372 "open failure to %u, exception follows", clid);
408 __client_interfaces.
lock();
409 if ( __client_interfaces.find(clid) != __client_interfaces.end() ) {
411 for ( __ciit = __client_interfaces[clid].begin(); __ciit != __client_interfaces[clid].end(); ++__ciit) {
413 "%u (client disconnected)",
414 (*__ciit)->type(), (*__ciit)->id(), clid);
416 unsigned int serial = (*__ciit)->serial();
417 __serial_to_clid.erase(serial);
419 delete __listeners[serial];
420 __listeners.erase(serial);
421 __bb->
close(*__ciit);
423 __client_interfaces.erase(clid);
425 __client_interfaces.
unlock();