24 #include <interface/interface.h>
26 #include <interface/mediators/interface_mediator.h>
27 #include <interface/mediators/message_mediator.h>
28 #include <core/threading/refc_rwlock.h>
29 #include <core/threading/mutex.h>
30 #include <core/exceptions/system.h>
31 #include <utils/time/clock.h>
32 #include <utils/time/time.h>
33 #include <utils/misc/strndup.h>
58 :
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.", id, type)
92 :
Exception(
"Message of type '%s' cannot be enqueued in interface of type '%s'",
93 message->type(), interface->type())
110 :
Exception(
"The interface %s (instance serial %u) is invalid. You cannot call %s anymore.",
111 interface->uid(), interface->serial(), method)
233 __write_access =
false;
236 __next_message_id = 0;
238 __fieldinfo_list = NULL;
239 __messageinfo_list = NULL;
241 __timestamp =
new Time(0, 0);
242 __local_read_timestamp =
new Time(0, 0);
243 __auto_timestamping =
true;
245 memset(__hash, 0, __INTERFACE_HASH_SIZE);
246 memset(__hash_printable, 0, __INTERFACE_HASH_SIZE * 2 + 1);
255 __data_mutex =
new Mutex();
262 if ( __rwlock) __rwlock->
unref();
264 delete __message_queue;
265 if (__buffers) free(__buffers);
269 __fieldinfo_list = __fieldinfo_list->
next;
271 finfol = __fieldinfo_list;
276 __messageinfo_list = __messageinfo_list->
next;
278 minfol = __messageinfo_list;
281 delete __local_read_timestamp;
291 const unsigned char *
304 return __hash_printable;
314 memcpy(__hash, ihash, __INTERFACE_HASH_SIZE);
315 for (
size_t s = 0; s < __INTERFACE_HASH_SIZE; ++s) {
316 snprintf(&__hash_printable[s*2], 3,
"%02X", __hash[s]);
333 size_t length,
void *value,
const char *enumtype)
341 newinfo->
name = name;
343 newinfo->
value = value;
344 newinfo->
next = NULL;
346 if ( infol == NULL ) {
348 __fieldinfo_list = newinfo;
351 while ( infol->
next != NULL ) {
354 infol->
next = newinfo;
375 newinfo->
next = NULL;
377 if ( infol == NULL ) {
379 __messageinfo_list = newinfo;
382 while ( infol->
next != NULL ) {
385 infol->
next = newinfo;
394 std::list<const char *>
397 std::list<const char *> types;
400 while ( cur != NULL ) {
401 types.push_back(cur->
type);
416 return __INTERFACE_HASH_SIZE;
437 return __write_access;
475 __data_mutex->
lock();
478 *__local_read_timestamp = *__timestamp;
497 if ( ! __write_access ) {
502 __data_mutex->
lock();
505 if (__auto_timestamping) __timestamp->
stamp();
506 long sec = 0, usec = 0;
541 Interface::set_type_id(
const char *type,
const char *
id)
543 __type[__INTERFACE_TYPE_SIZE] = 0;
544 __id[__INTERFACE_ID_SIZE] = 0;
545 __uid[__INTERFACE_UID_SIZE] = 0;
546 strncpy(__type, type, __INTERFACE_TYPE_SIZE);
547 strncpy(__id,
id, __INTERFACE_ID_SIZE);
548 snprintf(__uid, __INTERFACE_UID_SIZE,
"%s::%s", type,
id);
556 Interface::set_instance_serial(
unsigned short instance_serial)
558 __instance_serial = instance_serial;
567 Interface::set_mediators(InterfaceMediator *iface_mediator,
568 MessageMediator *msg_mediator)
570 __interface_mediator = iface_mediator;
571 __message_mediator = msg_mediator;
581 Interface::set_memory(
unsigned int serial,
void *real_ptr,
void *data_ptr)
584 __mem_real_ptr = real_ptr;
594 Interface::set_readwrite(
bool write_access, RefCountRWLock *rwlock)
596 __write_access = write_access;
615 return ( (strncmp(__type, comp.__type,
sizeof(__type)) == 0) &&
616 (strncmp(__id, comp.__id,
sizeof(__id)) == 0) );
627 return (strncmp(this->__type, interface_type,
sizeof(this->__type)) == 0);
672 return __instance_serial;
704 if (__auto_timestamping)
throw Exception(
"Auto timestamping enabled, cannot "
705 "set explicit timestamp");
706 if (!__write_access)
throw Exception(
"Timestamp can only be set on writing "
712 __timestamp->
stamp();
735 __auto_timestamping = enabled;
750 return (*__timestamp != __local_read_timestamp);
832 if ( __write_access ) {
837 message->set_interface(
this);
838 message->
set_id(next_msg_id());
840 __message_mediator->
transmit(message);
841 unsigned int msgid = message->
id();
871 if ( __write_access ) {
874 if ( message == NULL ) {
880 mcopy->set_interface(
this);
881 mcopy->
set_id(next_msg_id());
882 __message_mediator->
transmit(mcopy);
883 unsigned int msgid = mcopy->
id();
901 Interface::msgq_append(
Message *message)
903 if ( ! __write_access ) {
905 "reading instance of an interface (append).");
908 __message_queue->
append(message);
925 if ( ! __write_access ) {
927 "reading instance of an interface (remove msg).");
930 return __message_queue->
remove(message);
942 if ( ! __write_access ) {
944 "reading instance of an interface (remove id).");
947 return __message_queue->
remove(message_id);
958 if ( ! __write_access ) {
960 "reading instance of an interface (size).");
963 return __message_queue->
size();
974 if ( ! __write_access ) {
976 "reading instance of an interface (empty).");
979 return __message_queue->
empty();
990 if ( ! __write_access ) {
992 "reading instance of an interface (flush).");
995 __message_queue->
flush();
1008 if ( ! __write_access ) {
1010 "reading instance of an interface (lock).");
1013 __message_queue->
lock();
1028 if ( ! __write_access ) {
1030 "Cannot work on message queue on "
1031 "reading instance of an interface "
1032 "(msgq_try_lock).");
1035 return __message_queue->
try_lock();
1046 if ( ! __write_access ) {
1048 "reading instance of an interface (unlock).");
1051 __message_queue->
unlock();
1066 if ( ! __write_access ) {
1068 "reading instance of an interface (begin).");
1071 return __message_queue->
begin();
1087 if ( ! __write_access ) {
1089 "Cannot work on message queue on "
1090 "reading instance of an interface (end).");
1093 return __message_queue->
end();
1106 if ( ! __write_access ) {
1108 "reading instance of an interface (first).");
1111 return __message_queue->
first();
1120 if ( ! __write_access ) {
1122 "reading instance of an interface (pop).");
1125 __message_queue->
pop();
1155 return __num_fields;
1168 __data_mutex->
lock();
1169 if (num_buffers == 0) {
1170 if (__buffers != NULL) {
1176 void *tmp = realloc(__buffers, num_buffers *
data_size);
1179 throw Exception(errno,
"Resizing buffers for interface %s failed", __uid);
1195 return __num_buffers;
1205 if (buffer >= __num_buffers) {
1207 buffer, 0, __num_buffers);
1212 __data_mutex->
lock();
1214 void *buf = (
char *)__buffers + buffer *
data_size;
1234 if (buffer >= __num_buffers) {
1236 buffer, 0, __num_buffers);
1240 __data_mutex->
lock();
1241 void *buf = (
char *)__buffers + buffer *
data_size;
1254 if (buffer >= __num_buffers) {
1256 buffer, 0, __num_buffers);
1259 __data_mutex->
lock();
1260 void *buf = (
char *)__buffers + buffer *
data_size;
1275 if (buffer >= __num_buffers) {
1277 buffer, 0, __num_buffers);
1280 __data_mutex->
lock();
1281 void *buf = (
char *)__buffers + buffer *
data_size;
1303 #define xstr(s) str(s)
1304 if ((ec = regcomp(&re,
1305 "^([a-zA-Z0-9]{1," xstr(__INTERFACE_TYPE_SIZE)
"})::"
1306 "([a-zA-Z0-9 _\\.-]{1," xstr(__INTERFACE_ID_SIZE)
"})$",
1307 REG_EXTENDED)) != 0) {
1309 regerror(ec, &re, errbuf, 1024);
1310 throw Exception(
"Failed to created regular expression to parse UID (%s)",
1313 regmatch_t matches[3];
1314 if (regexec(&re, uid, 3, matches, 0) != 0) {
1316 throw Exception(
"Failed to match UID %s, format error.", uid);
1319 *type = strndup(&(uid[matches[1].rm_so]), matches[1].rm_eo - matches[1].rm_so);
1320 *
id = strndup(&(uid[matches[2].rm_so]), matches[2].rm_eo - matches[2].rm_so);