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);
237 __interfaces.unlock();
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->writer_readers = htonl(interface->
num_readers());
336 osm->writer_readers |= htonl(0x80000000);
338 osm->writer_readers &= htonl(0x7FFFFFFF);
340 osm->data_size = htonl(interface->
datasize());
350 MSG_BB_OPEN_SUCCESS, payload,
357 "open success to %u, exception follows", clid);
364 BlackBoardNetworkHandler::send_openfailure(
unsigned int clid,
unsigned int error_code)
370 MSG_BB_OPEN_FAILURE, ofm,
376 "open failure to %u, exception follows", clid);
412 __client_interfaces.lock();
413 if ( __client_interfaces.find(clid) != __client_interfaces.end() ) {
415 for ( __ciit = __client_interfaces[clid].begin(); __ciit != __client_interfaces[clid].end(); ++__ciit) {
417 "%u (client disconnected)",
418 (*__ciit)->type(), (*__ciit)->id(), clid);
420 unsigned int serial = (*__ciit)->serial();
421 __serial_to_clid.erase(serial);
422 __interfaces.erase_locked(serial);
423 delete __listeners[serial];
424 __listeners.erase(serial);
425 __bb->
close(*__ciit);
427 __client_interfaces.erase(clid);
429 __client_interfaces.unlock();
void * payload() const
Get payload buffer.
unsigned char hash[__INTERFACE_HASH_SIZE]
interface version hash
char type[__INTERFACE_TYPE_SIZE]
interface type name
void clear()
Clear the queue.
unsigned int datasize() const
Get data size.
Base class for all messages passed through interfaces in Fawkes BlackBoard.
Requested interface type is unknown.
void unref()
Decrement reference count and conditionally delete this instance.
BlackBoardNetworkHandler(BlackBoard *blackboard, FawkesNetworkHub *hub)
Constructor.
static void log_debug(const char *component, const char *format,...)
Log debug message.
uint32_t serial
instance serial to unique identify this instance
Fawkes library namespace.
unsigned int clid() const
Get client ID.
Message to identify an interface on open.
Interface listener for network handler.
virtual void add_handler(FawkesNetworkHandler *handler)=0
Add a message handler.
virtual void loop()
Process all network messages that have been received.
Representation of a message that is sent over the network.
Thread class encapsulation of pthreads.
char msg_type[__INTERFACE_MESSAGE_TYPE_SIZE]
message type
Base class for all Fawkes BlackBoard interfaces.
Interface observer for blackboard network handler.
virtual InterfaceInfoList * list(const char *type_pattern, const char *id_pattern)=0
Get list of interfaces matching type and ID patterns.
You tried to open an interface for writing but there is already a writing instance for this interface...
uint32_t error_code
Error code.
virtual void client_disconnected(unsigned int clid)
Client disconnected.
const unsigned char * hash() const
Get interface hash.
static void log_error(const char *component, const char *format,...)
Log error message.
virtual void client_connected(unsigned int clid)
Client connected.
Interface information list.
void wakeup()
Wake up thread.
char id_pattern[__INTERFACE_ID_SIZE]
ID pattern.
Base class for exceptions in Fawkes.
unsigned short serial() const
Get instance serial of interface.
void read()
Read from BlackBoard into local copy.
virtual void send(FawkesNetworkMessage *msg)=0
Method to send a message to a specific client.
void set_from_chunk(const void *chunk)
Set from raw data chunk.
Interface open success The serial denotes a unique instance of an interface within the (remote) Black...
void ref()
Increment reference count.
The hashes of the interfaces do not match.
bool has_writer() const
Check if there is a writer for the interface.
uint32_t data_size
data for message
Network handler abstract base class.
static void log_warn(const char *component, const char *format,...)
Log warning message.
~BlackBoardNetworkHandler()
Destructor.
bool is_writer() const
Check if this is a writing instance.
void append_interface(const char *type, const char *id, const unsigned char *hash, unsigned int serial, bool has_writer, unsigned int num_readers, const fawkes::Time &time)
Append interface info.
void pop_locked()
Pop element from queue with lock protection.
uint32_t serial
interface instance serial
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
uint32_t serial
instance serial to unique identify this instance
virtual InterfaceInfoList * list_all()=0
Get list of all currently existing interfaces.
Thrown if no definition of interface or interface generator found.
void push_locked(const Type &x)
Push element to queue with lock protection.
char type_pattern[__INTERFACE_TYPE_SIZE]
type pattern
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for reading.
unsigned int datasize() const
Get size of data.
Message to request constrained interface list.
BlackBoard interface list content.
Message to identify an interface instance.
const void * datachunk() const
Get data chunk.
unsigned int num_readers() const
Get the number of readers.
virtual void remove_handler(FawkesNetworkHandler *handler)=0
Remove a message handler.
The BlackBoard abstract class.
Thrown if a writer is already active on an interface that writing has been requested for...
MT * msg() const
Get correctly casted payload.
void set_hops(unsigned int hops)
Set number of hops.
uint32_t data_size
size in bytes of the following data.
virtual Interface * open_for_writing(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for writing.
void set_id(unsigned int message_id)
Set message ID.
uint32_t hops
number of hops this message already passed
virtual void handle_network_message(FawkesNetworkMessage *msg)
Handle network message.
virtual void close(Interface *interface)=0
Close interface.
Message to send update data.