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->has_writer = interface->
has_writer() ? 1 : 0;
335 osm->num_readers = htonl(interface->
num_readers());
336 osm->data_size = htonl(interface->
datasize());
346 MSG_BB_OPEN_SUCCESS, payload,
353 "open success to %u, exception follows", clid);
360 BlackBoardNetworkHandler::send_openfailure(
unsigned int clid,
unsigned int error_code)
366 MSG_BB_OPEN_FAILURE, ofm,
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);
418 __interfaces.erase_locked(serial);
419 delete __listeners[serial];
420 __listeners.erase(serial);
421 __bb->
close(*__ciit);
423 __client_interfaces.erase(clid);
425 __client_interfaces.unlock();
unsigned char hash[__INTERFACE_HASH_SIZE]
interface version hash
char type[__INTERFACE_TYPE_SIZE]
interface type name
void clear()
Clear the queue.
Base class for all messages passed through interfaces in Fawkes BlackBoard.
unsigned short serial() const
Get instance serial of interface.
Requested interface type is unknown.
void unref()
Decrement reference count and conditionally delete this instance.
unsigned int num_readers() const
Get the number of readers.
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.
Message to identify an interface on open.
void * payload() const
Get payload buffer.
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.
const unsigned char * hash() const
Get interface hash.
Representation of a message that is sent over the network.
unsigned short int msgid() const
Get message type ID.
unsigned int datasize() const
Get size of data.
Thread class encapsulation of pthreads.
char msg_type[__INTERFACE_MESSAGE_TYPE_SIZE]
message type
Base class for all Fawkes BlackBoard interfaces.
virtual Interface * open_for_writing(const char *interface_type, const char *identifier)=0
Open interface for writing.
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.
bool has_writer() const
Check if there is a writer for the interface.
virtual void client_disconnected(unsigned int clid)
Client disconnected.
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.
unsigned int datasize() const
Get data size.
void wakeup()
Wake up thread.
char id_pattern[__INTERFACE_ID_SIZE]
ID pattern.
Base class for exceptions in Fawkes.
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 append_interface(const char *type, const char *id, const unsigned char *hash, unsigned int serial, bool has_writer, unsigned int num_readers)
Append interface info.
void ref()
Increment reference count.
The hashes of the interfaces do not match.
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.
void pop_locked()
Pop element from queue with lock protection.
uint32_t serial
interface instance serial
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
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)=0
Open interface for reading.
Message to request constrained interface list.
BlackBoard interface list content.
Message to identify an interface instance.
bool is_writer() const
Check if this is a writing instance.
const void * datachunk() const
Get data chunk.
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...
void set_hops(unsigned int hops)
Set number of hops.
uint32_t data_size
size in bytes of the following data.
void set_id(unsigned int message_id)
Set message ID.
unsigned int clid() const
Get client 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.