Fawkes API
Fawkes Development Version
|
23 #include <core/exceptions/system.h>
24 #include <core/threading/mutex.h>
25 #include <core/threading/mutex_locker.h>
26 #include <core/threading/refc_rwlock.h>
27 #include <interface/interface.h>
28 #include <interface/mediators/interface_mediator.h>
29 #include <interface/mediators/message_mediator.h>
30 #include <utils/misc/strndup.h>
31 #include <utils/time/clock.h>
32 #include <utils/time/time.h>
57 :
Exception(
"This interface instance '%s' of type '%s' is not opened for writing. %s",
75 :
Exception(
"This interface instance '%s' of type '%s' IS opened for writing, but "
76 "messages can only be enqueued on reading interfaces.",
94 :
Exception(
"Message of type '%s' cannot be enqueued in interface of type '%s'",
111 :
Exception(
"The interface %s (instance serial %u) is invalid. You cannot call %s anymore.",
235 write_access_ =
false;
238 next_message_id_ = 0;
240 fieldinfo_list_ = NULL;
241 messageinfo_list_ = NULL;
243 timestamp_ =
new Time(0, 0);
244 local_read_timestamp_ =
new Time(0, 0);
245 auto_timestamping_ =
true;
246 owner_ = strdup(
"?");
248 memset(hash_, 0, INTERFACE_HASH_SIZE_);
249 memset(hash_printable_, 0, INTERFACE_HASH_SIZE_ * 2 + 1);
258 data_mutex_ =
new Mutex();
267 delete message_queue_;
273 fieldinfo_list_ = fieldinfo_list_->
next;
275 finfol = fieldinfo_list_;
280 messageinfo_list_ = messageinfo_list_->
next;
282 minfol = messageinfo_list_;
285 delete local_read_timestamp_;
297 const unsigned char *
309 return hash_printable_;
318 memcpy(hash_, ihash, INTERFACE_HASH_SIZE_);
319 for (
size_t s = 0; s < INTERFACE_HASH_SIZE_; ++s) {
320 snprintf(&hash_printable_[s * 2], 3,
"%02X", hash_[s]);
340 const char * enumtype,
348 newinfo->
name = name;
350 newinfo->
value = value;
352 newinfo->
next = NULL;
356 fieldinfo_list_ = newinfo;
359 while (infol->
next != NULL) {
362 infol->
next = newinfo;
382 newinfo->
next = NULL;
386 messageinfo_list_ = newinfo;
389 while (infol->
next != NULL) {
392 infol->
next = newinfo;
400 std::list<const char *>
403 std::list<const char *> types;
406 while (cur != NULL) {
407 types.push_back(cur->
type);
421 return INTERFACE_HASH_SIZE_;
440 return write_access_;
478 *local_read_timestamp_ = *timestamp_;
496 if (!write_access_) {
502 bool do_notify =
false;
505 if (auto_timestamping_)
507 long sec = 0, usec = 0;
542 Interface::set_type_id(
const char *type,
const char *
id)
544 strncpy(type_,
type, INTERFACE_TYPE_SIZE_);
545 strncpy(id_,
id, INTERFACE_ID_SIZE_);
546 snprintf(uid_, INTERFACE_UID_SIZE_ + 1,
"%s::%s", type_, id_);
549 type_[INTERFACE_TYPE_SIZE_] = 0;
550 id_[INTERFACE_ID_SIZE_] = 0;
551 uid_[INTERFACE_UID_SIZE_] = 0;
558 Interface::set_instance_serial(
unsigned short instance_serial)
560 instance_serial_ = instance_serial;
568 Interface::set_mediators(InterfaceMediator *iface_mediator, MessageMediator *msg_mediator)
570 interface_mediator_ = iface_mediator;
571 message_mediator_ = msg_mediator;
580 Interface::set_memory(
unsigned int serial,
void *real_ptr,
void *data_ptr)
583 mem_real_ptr_ = real_ptr;
592 Interface::set_readwrite(
bool write_access, RefCountRWLock *rwlock)
594 write_access_ = write_access;
602 Interface::set_owner(
const char *owner)
608 owner_ = strdup(
owner);
625 return ((strncmp(type_, comp.type_,
sizeof(type_)) == 0)
626 && (strncmp(id_, comp.id_,
sizeof(id_)) == 0));
636 return (strncmp(this->type_, interface_type,
sizeof(this->type_)) == 0);
688 return instance_serial_;
717 if (auto_timestamping_)
718 throw Exception(
"Auto timestamping enabled, cannot "
719 "set explicit timestamp");
721 throw Exception(
"Timestamp can only be set on writing "
748 auto_timestamping_ = enabled;
785 return (*timestamp_ != local_read_timestamp_);
857 return interface_mediator_->
writer(
this);
863 std::list<std::string>
866 return interface_mediator_->
readers(
this);
889 message->set_interface(
this);
890 message->
set_id(next_msg_id());
892 message_mediator_->
transmit(message);
893 unsigned int msgid = message->
id();
925 if (message == NULL) {
931 mcopy->set_interface(
this);
932 mcopy->
set_id(next_msg_id());
934 unsigned int msgid = mcopy->
id();
955 if (!write_access_) {
958 "Cannot work on message queue on "
959 "reading instance of an interface (append).");
963 message_queue_->
append(message);
979 if (!write_access_) {
982 "Cannot work on message queue on "
983 "reading instance of an interface (remove msg).");
986 return message_queue_->
remove(message);
997 if (!write_access_) {
1000 "Cannot work on message queue on "
1001 "reading instance of an interface (remove id).");
1004 return message_queue_->
remove(message_id);
1014 if (!write_access_) {
1017 "Cannot work on message queue on "
1018 "reading instance of an interface (size).");
1021 return message_queue_->
size();
1031 if (!write_access_) {
1034 "Cannot work on message queue on "
1035 "reading instance of an interface (empty).");
1038 return message_queue_->
empty();
1048 if (!write_access_) {
1051 "Cannot work on message queue on "
1052 "reading instance of an interface (flush).");
1055 message_queue_->
flush();
1067 if (!write_access_) {
1070 "Cannot work on message queue on "
1071 "reading instance of an interface (lock).");
1074 message_queue_->
lock();
1088 if (!write_access_) {
1091 "Cannot work on message queue on "
1092 "reading instance of an interface "
1093 "(msgq_try_lock).");
1106 if (!write_access_) {
1109 "Cannot work on message queue on "
1110 "reading instance of an interface (unlock).");
1113 message_queue_->
unlock();
1128 if (!write_access_) {
1131 "Cannot work on message queue on "
1132 "reading instance of an interface (begin).");
1135 return message_queue_->
begin();
1150 if (!write_access_) {
1153 "Cannot work on message queue on "
1154 "reading instance of an interface (end).");
1157 return message_queue_->
end();
1169 if (!write_access_) {
1172 "Cannot work on message queue on "
1173 "reading instance of an interface (first).");
1175 return message_queue_->
first();
1184 if (!write_access_) {
1187 "Cannot work on message queue on "
1188 "reading instance of an interface (pop).");
1191 message_queue_->
pop();
1230 data_mutex_->
lock();
1232 if (buffers_ != NULL) {
1241 throw Exception(errno,
"Resizing buffers for interface %s failed", uid_);
1256 return num_buffers_;
1265 if (buffer >= num_buffers_) {
1270 data_mutex_->
lock();
1272 void *buf = (
char *)buffers_ + buffer *
data_size;
1291 if (buffer >= num_buffers_) {
1295 data_mutex_->
lock();
1296 void *buf = (
char *)buffers_ + buffer *
data_size;
1307 if (buffer >= num_buffers_) {
1311 data_mutex_->
lock();
1312 void *buf = (
char *)buffers_ + buffer *
data_size;
1314 *local_read_timestamp_ = *timestamp_;
1329 if (buffer >= num_buffers_) {
1333 data_mutex_->
lock();
1334 void *buf = (
char *)buffers_ + buffer *
data_size;
1348 if (buffer >= num_buffers_) {
1353 void * buf = (
char *)buffers_ + buffer *
data_size;
1366 if (buffer >= num_buffers_) {
1374 void * buf = (
char *)buffers_ + buffer *
data_size;
1393 #define xstr(s) str(s)
1394 if ((ec = regcomp(&re,
1395 "^([a-zA-Z0-9]{1," xstr(INTERFACE_TYPE_SIZE_)
"})::"
1396 "([a-zA-Z0-9 _/\\.-]{1," xstr(
1397 INTERFACE_ID_SIZE_)
"})$",
1401 regerror(ec, &re, errbuf, 1024);
1402 throw Exception(
"Failed to created regular expression to parse UID (%s)", errbuf);
1404 regmatch_t matches[3];
1405 if (regexec(&re,
uid, 3, matches, 0) != 0) {
1407 throw Exception(
"Failed to match UID %s, format error.",
uid);
1410 type.assign(&(
uid[matches[1].rm_so]), matches[1].rm_eo - matches[1].rm_so);
1411 id.assign(&(
uid[matches[2].rm_so]), matches[2].rm_eo - matches[2].rm_so);
void lock()
Lock this mutex.
bool empty() const
Check if message queue is empty.
std::list< const char * > get_message_types()
Obtain a list of textual representations of the message types available for this interface.
void unref()
Decrement reference count and conditionally delete this instance.
void * data_ptr
Pointer to local memory storage.
const void * datachunk() const
Get data chunk.
This exception is thrown if a message has been queued in the interface which is not recognized by the...
void set_validity(bool valid)
Mark this interface invalid.
MessageQueue::MessageIterator msgq_end()
Get end iterator for message queue.
const char * type
the type of the message
void msgq_pop()
Erase first message from queue.
void set_time(const timeval *tv)
Sets the time.
bool msgq_empty()
Check if queue is empty.
interface_fieldinfo_t * next
next field, NULL if last
bool try_lock()
Try to lock message queue.
interface_messageinfo_t * next
the next field, NULL if last
InterfaceFieldIterator fields_end()
Invalid iterator.
Message queue used in interfaces.
void flush()
Delete all messages from queue.
int compare_buffers(unsigned int buffer)
Compare buffer to private memory.
Mutex mutual exclusion lock.
const Time * timestamp() const
Get timestamp of last write.
interface_fieldtype_t
Interface field type.
bool is_writer() const
Check if this is a writing instance.
Base class for all messages passed through interfaces in Fawkes BlackBoard.
const char * hash_printable() const
Get printable interface hash.
void read()
Read from BlackBoard into local copy.
void set_id(unsigned int message_id)
Set message ID.
Timestamp data, must be present and first entries for each interface data structs!...
const unsigned char * hash() const
Get interface hash.
void read_from_buffer(unsigned int buffer)
Copy data from buffer to private memory.
void lock()
Lock message queue.
virtual bool message_valid(const Message *message) const =0
Check if the message is valid and can be enqueued.
void pop()
Erase first message from queue.
void unlock()
Unlock message queue.
const char * type() const
Get type of interface.
InterfaceInvalidException(const Interface *interface, const char *method)
Constructor.
void msgq_remove(Message *message)
Remove message from queue.
void add_fieldinfo(interface_fieldtype_t type, const char *name, size_t length, void *value, const char *enumtype=0, const interface_enum_map_t *enum_map=0)
Add an entry to the field info list.
void set_clock(Clock *clock)
Set clock to use for timestamping.
InterfaceInvalidMessageException(const Interface *interface, const Message *message)
Constructor.
int64_t timestamp_sec
time in seconds since Unix epoch
const char * id() const
Get identifier of interface.
void unlock()
Unlock the mutex.
interface_data_ts_t * data_ts
Pointer to data casted to timestamp struct.
unsigned int mem_serial() const
Get memory serial of interface.
int64_t timestamp_usec
additional time microseconds
void set_timestamp(const Time *t=NULL)
Set timestamp.
void lock_for_read()
Aquire a reader lock.
void mark_data_changed()
Mark data as changed.
unsigned int size() const
Get number of messages in queue.
InterfaceWriteDeniedException(const char *type, const char *id, const char *msg)
Constructor.
MessageIterator end()
Get iterator to element beyond end of message queue list.
bool data_changed
Indicator if data has changed.
Interface field iterator.
std::string writer() const
Get owner name of writing interface instance.
void ref()
Increment reference count.
void msgq_lock()
Lock message queue.
Fawkes library namespace.
const char * enumtype
text representation of enum type
Time buffer_timestamp(unsigned int buffer)
Get time of a buffer.
bool changed() const
Check if data has been changed.
void set_hash(unsigned char *ihash)
Set hash.
std::list< std::string > readers() const
Get owner names of reading interface instances.
Interface field info list.
void append(Message *msg)
Append message to queue.
MessageQueue::MessageIterator msgq_begin()
Get start iterator for message queue.
void remove(const Message *msg)
Remove message from queue.
void lock_for_write()
Aquire a writer lock.
void msgq_append(Message *message)
Enqueue message.
unsigned int msgq_enqueue_copy(Message *message)
Enqueue copy of message at end of queue.
Base class for all Fawkes BlackBoard interfaces.
void resize_buffers(unsigned int num_buffers)
Resize buffer array.
bool has_writer() const
Check if there is a writer for the interface.
void set_clock(Clock *clock)
Set clock for this instance.
Message * first()
Get first message from queue.
void msgq_unlock()
Unlock message queue.
unsigned int num_buffers() const
Get number of buffers.
const interface_enum_map_t * enum_map
Map of possible enum values.
static void parse_uid(const char *uid, std::string &type, std::string &id)
Parse UID to type and ID strings.
This exception is thrown if a write has been attempted on a read-only interface.
std::map< int, std::string > interface_enum_map_t
Map of enum integer to string values.
void unlock()
Release the lock.
const char * uid() const
Get unique identifier of interface.
const char * name
Name of this field.
unsigned int num_readers() const
Get the number of readers.
InterfaceFieldIterator fields()
Get iterator over all fields of this interface instance.
A class for handling time.
const char * owner() const
Get owner of interface.
void set_auto_timestamping(bool enabled)
Enable or disable automated timestamping.
unsigned int data_size
Minimal data size to hold data storage.
size_t length
Length of field (array, string)
unsigned short serial() const
Get instance serial of interface.
unsigned int msgq_size()
Get size of message queue.
unsigned int num_fields()
Get the number of fields in the interface.
virtual Message * clone() const
Clone this message.
unsigned int id() const
Get message ID.
static Clock * instance()
Clock initializer.
Time & stamp()
Set this time to the current time.
virtual ~Interface()
Destructor.
void copy_private_to_buffer(unsigned int buffer)
Copy data from private memory to buffer.
void msgq_flush()
Flush all messages.
unsigned int datasize() const
Get data size.
A NULL pointer was supplied where not allowed.
This exception is thrown if a write has been attempted on a read-only interface.
unsigned int msgq_enqueue(Message *message)
Enqueue message at end of queue.
bool oftype(const char *interface_type) const
Check if interface is of given type.
void set_from_chunk(void *chunk)
Set from a raw data chunk.
void get_timestamp(long &sec, long &usec) const
Get time stamp.
InterfaceMessageEnqueueException(const char *type, const char *id)
Constructor.
Message * msgq_first()
Get the first message from the message queue.
void add_messageinfo(const char *name)
Add an entry to the message info list.
void write()
Write from local copy into BlackBoard memory.
interface_fieldtype_t type
type of this field
size_t hash_size() const
Get size of interface hash.
This exception is thrown if an interface is invalid and it is attempted to call read()/write().
bool is_valid() const
Check validity of interface.
void copy_shared_to_buffer(unsigned int buffer)
Copy data from private memory to buffer.
MessageIterator begin()
Get iterator to first element in message queue.
This is supposed to be the central clock in Fawkes.
bool msgq_try_lock()
Try to lock message queue.
bool operator==(Interface &comp) const
Check equality of two interfaces.
void * value
Current value of this field.
Base class for exceptions in Fawkes.