Fawkes API  Fawkes Development Version
interface.h
1 
2 /***************************************************************************
3  * interface.h - BlackBoard Interface
4  *
5  * Created: Mon Oct 09 18:34:11 2006
6  * Copyright 2006-2015 Tim Niemueller [www.niemueller.de]
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version. A runtime exception applies to
13  * this software (see LICENSE.GPL_WRE file mentioned below for details).
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
21  */
22 
23 #ifndef _INTERFACE_H_
24 #define _INTERFACE_H_
25 
26 #include <core/exception.h>
27 #include <interface/message.h>
28 #include <interface/message_queue.h>
29 
30 #include <cstddef>
31 #include <list>
32 #include <stdint.h>
33 
34 #define INTERFACE_TYPE_SIZE_ 48
35 #define INTERFACE_ID_SIZE_ 64
36 // We use MD5 as interface hash
37 #define INTERFACE_HASH_SIZE_ 16
38 // UID is: type :: id
39 #define INTERFACE_UID_SIZE_ INTERFACE_TYPE_SIZE_ + 2 + INTERFACE_ID_SIZE_
40 
41 namespace fawkes {
42 
43 class RefCountRWLock;
44 class InterfaceMediator;
45 class MessageMediator;
46 class Time;
47 class Clock;
48 class Mutex;
49 class BlackBoardInterfaceManager;
50 class BlackBoardInstanceFactory;
51 class BlackBoardMessageManager;
52 class BlackBoardInterfaceProxy;
53 
55 {
56 public:
57  InterfaceWriteDeniedException(const char *type, const char *id, const char *msg);
58 };
59 
61 {
62 public:
63  InterfaceMessageEnqueueException(const char *type, const char *id);
64 };
65 
67 {
68 public:
69  InterfaceInvalidMessageException(const Interface *interface, const Message *message);
70 };
71 
73 {
74 public:
75  InterfaceInvalidException(const Interface *interface, const char *method);
76 };
77 
78 class Interface
79 {
84 
85 public:
86  virtual ~Interface();
87 
88  bool oftype(const char *interface_type) const;
89  const void * datachunk() const;
90  unsigned int datasize() const;
91  const char * type() const;
92  const char * id() const;
93  const char * uid() const;
94  unsigned short serial() const;
95  unsigned int mem_serial() const;
96  bool operator==(Interface &comp) const;
97  const unsigned char *hash() const;
98  size_t hash_size() const;
99  const char * hash_printable() const;
100  bool is_writer() const;
101  void set_validity(bool valid);
102  bool is_valid() const;
103  const char * owner() const;
104 
105  void set_from_chunk(void *chunk);
106 
107  virtual Message * create_message(const char *type) const = 0;
108  virtual void copy_values(const Interface *interface) = 0;
109  virtual const char *enum_tostring(const char *enumtype, int val) const = 0;
110 
111  void resize_buffers(unsigned int num_buffers);
112  unsigned int num_buffers() const;
113  void copy_shared_to_buffer(unsigned int buffer);
114  void copy_private_to_buffer(unsigned int buffer);
115  void read_from_buffer(unsigned int buffer);
116  int compare_buffers(unsigned int buffer);
117  Time buffer_timestamp(unsigned int buffer);
118  void buffer_timestamp(unsigned int buffer, Time *timestamp);
119 
120  void read();
121  void write();
122 
123  bool has_writer() const;
124  unsigned int num_readers() const;
125  std::string writer() const;
126  std::list<std::string> readers() const;
127 
128  bool changed() const;
129  const Time *timestamp() const;
130  void set_auto_timestamping(bool enabled);
131  void set_timestamp(const Time *t = NULL);
132  void set_clock(Clock *clock);
133  void mark_data_changed();
134 
135  std::list<const char *> get_message_types();
136 
137  unsigned int msgq_enqueue(Message *message);
138  unsigned int msgq_enqueue_copy(Message *message);
139  void msgq_remove(Message *message);
140  void msgq_remove(unsigned int message_id);
141  unsigned int msgq_size();
142  void msgq_flush();
143  void msgq_lock();
144  bool msgq_try_lock();
145  void msgq_unlock();
146  void msgq_pop();
147  Message * msgq_first();
148  bool msgq_empty();
149  void msgq_append(Message *message);
150 
151  /** Check if first message has desired type.
152  * @return true, if message has desired type, false otherwise
153  */
154  template <class MessageType>
155  bool msgq_first_is();
156 
157  /** Get first message casted to the desired type.
158  * @return message casted to desired type
159  * @exception TypeMismatchException thrown if message is not of desired type
160  */
161  template <class MessageType>
162  MessageType *msgq_first();
163 
164  /** Get first message casted to the desired type.
165  * @param msg reference to pointer to message of desired type, upon successful
166  * return points to the message.
167  * @return message casted to desired type (same as msg parameter)
168  * @exception TypeMismatchException thrown if message is not of desired type
169  */
170  template <class MessageType>
171  MessageType *msgq_first(MessageType *&msg);
172 
173  /** Get first message casted to the desired type without exceptions.
174  * This method allows to combine a call to msgq_first_is() and msgq_first()
175  * into a single call.
176  * @param msg reference to pointer to message of desired type, upon successful
177  * return points to the message.
178  * @return pointer to message if it is of the desired type, 0 otherwise
179  */
180  template <class MessageType>
181  MessageType *msgq_first_safe(MessageType *&msg) throw();
182 
185 
186  /* Introspection */
187 
188  /** Message info list */
190  {
191  const char * type; /**< the type of the message */
192  interface_messageinfo_t *next; /**< the next field, NULL if last */
193  };
194 
195  /** Timestamp data, must be present and first entries for each interface
196  * data structs! This leans on timeval struct. */
197  typedef struct
198  {
199  int64_t timestamp_sec; /**< time in seconds since Unix epoch */
200  int64_t timestamp_usec; /**< additional time microseconds */
202 
205 
206  unsigned int num_fields();
207 
208  /* Convenience */
209  static void parse_uid(const char *uid, std::string &type, std::string &id);
210 
211 protected:
212  Interface();
213  virtual bool message_valid(const Message *message) const = 0;
214 
215  void set_hash(unsigned char *ihash);
217  const char * name,
218  size_t length,
219  void * value,
220  const char * enumtype = 0,
221  const interface_enum_map_t *enum_map = 0);
222  void add_messageinfo(const char *name);
223 
224  void * data_ptr;
225  unsigned int data_size;
227 
229 
230 private:
231  void set_type_id(const char *type, const char *id);
232  void set_instance_serial(unsigned short instance_serial);
233  void set_mediators(InterfaceMediator *iface_mediator, MessageMediator *msg_mediator);
234  void set_memory(unsigned int serial, void *real_ptr, void *data_ptr);
235  void set_readwrite(bool write_access, RefCountRWLock *rwlock);
236  void set_owner(const char *owner);
237 
238  inline unsigned int
239  next_msg_id()
240  {
241  return (instance_serial_ << 16) | ++next_message_id_;
242  }
243 
244  char type_[INTERFACE_TYPE_SIZE_ + 1];
245  char id_[INTERFACE_ID_SIZE_ + 1];
246  char uid_[INTERFACE_UID_SIZE_ + 1];
247  unsigned char hash_[INTERFACE_HASH_SIZE_];
248  char hash_printable_[INTERFACE_HASH_SIZE_ * 2 + 1];
249  char * owner_;
250 
251  unsigned short instance_serial_;
252  bool valid_;
253 
254  void * mem_data_ptr_;
255  void * mem_real_ptr_;
256  unsigned int mem_serial_;
257  bool write_access_;
258 
259  void * buffers_;
260  unsigned int num_buffers_;
261 
262  Mutex * data_mutex_;
263  RefCountRWLock *rwlock_;
264 
265  InterfaceMediator *interface_mediator_;
266  MessageMediator * message_mediator_;
267  MessageQueue * message_queue_;
268  unsigned short next_message_id_;
269 
270  interface_fieldinfo_t * fieldinfo_list_;
271  interface_messageinfo_t *messageinfo_list_;
272 
273  unsigned int num_fields_;
274 
275  Clock *clock_;
276  Time * timestamp_;
277  Time * local_read_timestamp_;
278  bool auto_timestamping_;
279 };
280 
281 template <class MessageType>
282 MessageType *
284 {
285  MessageType *m = dynamic_cast<MessageType *>(message_queue_->first());
286  if (m) {
287  return m;
288  } else {
289  throw TypeMismatchException("Message is not of desired type");
290  }
291 }
292 
293 template <class MessageType>
294 MessageType *
295 Interface::msgq_first(MessageType *&msg)
296 {
297  msg = this->msgq_first<MessageType>();
298  return msg;
299 }
300 
301 template <class MessageType>
302 MessageType *
303 Interface::msgq_first_safe(MessageType *&msg) throw()
304 {
305  msg = dynamic_cast<MessageType *>(message_queue_->first());
306  return msg;
307 }
308 
309 /** Check if first message has desired type.
310  * @return true, if message has desired type, false otherwise
311  */
312 template <class MessageType>
313 bool
315 {
316  return (dynamic_cast<MessageType *>(message_queue_->first()) != 0);
317 }
318 
319 /** Interface destructor function for the shared library.
320  * Do not use directly. Use EXPORT_INTERFACE macro.
321  * @param interface Interface to destroy
322  */
323 typedef void (*InterfaceDestroyFunc)(Interface *interface);
324 
325 /** Interface generator function for the shared library
326  * Do not use directly. Use EXPORT_INTERFACE macro.
327  */
328 typedef Interface *(*InterfaceFactoryFunc)(void);
329 
330 /** Friend for interface generator function. */
331 #define INTERFACE_MGMT_FRIENDS(interface_class) \
332  friend Interface *private_new##interface_class(); \
333  friend void private_delete##interface_class(interface_class *interface);
334 
335 /** Interface generator function for this plugin.
336  * @return an instance of the desired interface
337  */
338 #define INTERFACE_GENERATOR(interface_class) \
339  Interface *private_new##interface_class() \
340  { \
341  return new interface_class(); \
342  }
343 
344 /** Interface delete function for this plugin.
345  * @return an instance of the desired interface
346  */
347 #define INTERFACE_DELETER(interface_class) \
348  void private_delete##interface_class(interface_class *interface) \
349  { \
350  delete interface; \
351  }
352 
353 /** Interface factory function.
354  * @return an instance of the desired interface
355  */
356 #define INTERFACE_FACTORY(interface_class) \
357  extern "C" Interface *interface_factory() \
358  { \
359  return private_new##interface_class(); \
360  }
361 
362 /** Interface destruction function.
363  * @param interface The interface that is to be destroyed.
364  */
365 #define INTERFACE_DESTROY(interface_class) \
366  extern "C" void interface_destroy(interface_class *interface) \
367  { \
368  private_delete##interface_class(interface); \
369  }
370 
371 /** Export interface.
372  * This will create appropriate interface factory and destroy functions.
373  */
374 #define EXPORT_INTERFACE(interface_class) \
375  INTERFACE_GENERATOR(interface_class) \
376  INTERFACE_DELETER(interface_class) \
377  INTERFACE_FACTORY(interface_class) \
378  INTERFACE_DESTROY(interface_class)
379 
380 } // end namespace fawkes
381 
382 #endif
fawkes::Interface::get_message_types
std::list< const char * > get_message_types()
Obtain a list of textual representations of the message types available for this interface.
Definition: interface.cpp:406
fawkes::Interface::data_ptr
void * data_ptr
Definition: interface.h:224
fawkes::Interface::datachunk
const void * datachunk() const
Get data chunk.
Definition: interface.cpp:434
fawkes::InterfaceInvalidMessageException
Definition: interface.h:66
fawkes::Interface::set_validity
void set_validity(bool valid)
Mark this interface invalid.
Definition: interface.cpp:456
fawkes::Interface::msgq_end
MessageQueue::MessageIterator msgq_end()
Get end iterator for message queue.
Definition: interface.cpp:1150
fawkes::Interface::msgq_first_is
bool msgq_first_is()
Check if first message has desired type.
Definition: interface.h:314
fawkes::Interface::interface_messageinfo_t::type
const char * type
the type of the message
Definition: interface.h:191
fawkes::Interface::interface_messageinfo_t
Message info list.
Definition: interface.h:189
fawkes::Interface::msgq_pop
void msgq_pop()
Erase first message from queue.
Definition: interface.cpp:1184
fawkes::Interface::msgq_empty
bool msgq_empty()
Check if queue is empty.
Definition: interface.cpp:1031
fawkes::Interface::interface_messageinfo_t::next
interface_messageinfo_t * next
the next field, NULL if last
Definition: interface.h:192
fawkes::Interface::fields_end
InterfaceFieldIterator fields_end()
Invalid iterator.
Definition: interface.cpp:1209
fawkes::MessageQueue
Definition: message_queue.h:47
fawkes::Interface::compare_buffers
int compare_buffers(unsigned int buffer)
Compare buffer to private memory.
Definition: interface.cpp:1329
fawkes::Mutex
Definition: mutex.h:38
fawkes::Interface::create_message
virtual Message * create_message(const char *type) const =0
fawkes::Interface::timestamp
const Time * timestamp() const
Get timestamp of last write.
Definition: interface.cpp:707
fawkes::RefCountRWLock
Definition: refc_rwlock.h:38
fawkes::interface_fieldtype_t
interface_fieldtype_t
Interface field type.
Definition: types.h:43
fawkes::Interface::msgq_first_safe
MessageType * msgq_first_safe(MessageType *&msg)
Get first message casted to the desired type without exceptions.
Definition: interface.h:303
fawkes::Interface::is_writer
bool is_writer() const
Check if this is a writing instance.
Definition: interface.cpp:443
fawkes::Message
Definition: message.h:41
fawkes::Interface::hash_printable
const char * hash_printable() const
Get printable interface hash.
Definition: interface.cpp:312
fawkes::Interface::read
void read()
Read from BlackBoard into local copy.
Definition: interface.cpp:477
fawkes::Interface::interface_data_ts_t
Timestamp data, must be present and first entries for each interface data structs!...
Definition: interface.h:197
fawkes::Interface::hash
const unsigned char * hash() const
Get interface hash.
Definition: interface.cpp:303
fawkes::MessageMediator
Message mediator interface.
Definition: message_mediator.h:43
fawkes::Interface::read_from_buffer
void read_from_buffer(unsigned int buffer)
Copy data from buffer to private memory.
Definition: interface.cpp:1307
fawkes::Interface::message_valid
virtual bool message_valid(const Message *message) const =0
fawkes::Interface::type
const char * type() const
Get type of interface.
Definition: interface.cpp:645
fawkes::InterfaceInvalidException::InterfaceInvalidException
InterfaceInvalidException(const Interface *interface, const char *method)
Constructor.
Definition: interface.cpp:115
fawkes::Interface::msgq_remove
void msgq_remove(Message *message)
Remove message from queue.
Definition: interface.cpp:979
fawkes::Interface::add_fieldinfo
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.
Definition: interface.cpp:341
fawkes::Interface::set_clock
void set_clock(Clock *clock)
Set clock to use for timestamping.
Definition: interface.cpp:738
fawkes::InterfaceInvalidMessageException::InterfaceInvalidMessageException
InterfaceInvalidMessageException(const Interface *interface, const Message *message)
Constructor.
Definition: interface.cpp:97
fawkes::Interface::interface_data_ts_t::timestamp_sec
int64_t timestamp_sec
time in seconds since Unix epoch
Definition: interface.h:199
fawkes::Interface::id
const char * id() const
Get identifier of interface.
Definition: interface.cpp:654
fawkes::Interface::data_ts
interface_data_ts_t * data_ts
Definition: interface.h:228
fawkes::Interface::mem_serial
unsigned int mem_serial() const
Get memory serial of interface.
Definition: interface.cpp:697
fawkes::BlackBoardInterfaceProxy
Definition: interface_proxy.h:46
fawkes::Interface::interface_data_ts_t::timestamp_usec
int64_t timestamp_usec
additional time microseconds
Definition: interface.h:200
fawkes::Interface::set_timestamp
void set_timestamp(const Time *t=NULL)
Set timestamp.
Definition: interface.cpp:717
fawkes::BlackBoardInterfaceManager
Definition: interface_manager.h:51
fawkes::Interface::mark_data_changed
void mark_data_changed()
Mark data as changed.
Definition: interface.cpp:760
fawkes::InterfaceWriteDeniedException::InterfaceWriteDeniedException
InterfaceWriteDeniedException(const char *type, const char *id, const char *msg)
Constructor.
Definition: interface.cpp:59
fawkes::InterfaceMediator
Interface mediator interface.
Definition: interface_mediator.h:45
fawkes::TypeMismatchException
Definition: software.h:49
fawkes::Interface::data_changed
bool data_changed
Definition: interface.h:226
fawkes::InterfaceFieldIterator
Definition: field_iterator.h:38
fawkes::InterfaceDestroyFunc
void(* InterfaceDestroyFunc)(Interface *interface)
Interface destructor function for the shared library.
Definition: interface.h:323
fawkes::Interface::writer
std::string writer() const
Get owner name of writing interface instance.
Definition: interface.cpp:857
fawkes::Interface::Interface
Interface()
Constructor.
Definition: interface.cpp:238
fawkes::Interface::msgq_lock
void msgq_lock()
Lock message queue.
Definition: interface.cpp:1067
fawkes
fawkes::Interface::buffer_timestamp
Time buffer_timestamp(unsigned int buffer)
Get time of a buffer.
Definition: interface.cpp:1348
fawkes::Interface::changed
bool changed() const
Check if data has been changed.
Definition: interface.cpp:782
fawkes::Interface::set_hash
void set_hash(unsigned char *ihash)
Set hash.
Definition: interface.cpp:321
fawkes::Interface::readers
std::list< std::string > readers() const
Get owner names of reading interface instances.
Definition: interface.cpp:866
fawkes::interface_fieldinfo_t
Interface field info list.
Definition: types.h:64
fawkes::MessageQueue::MessageIterator
Definition: message_queue.h:64
fawkes::Interface::msgq_begin
MessageQueue::MessageIterator msgq_begin()
Get start iterator for message queue.
Definition: interface.cpp:1128
fawkes::Interface::msgq_append
void msgq_append(Message *message)
Enqueue message.
Definition: interface.cpp:955
fawkes::Interface::msgq_enqueue_copy
unsigned int msgq_enqueue_copy(Message *message)
Enqueue copy of message at end of queue.
Definition: interface.cpp:922
fawkes::Interface
Definition: interface.h:78
fawkes::Interface::resize_buffers
void resize_buffers(unsigned int num_buffers)
Resize buffer array.
Definition: interface.cpp:1230
fawkes::Interface::has_writer
bool has_writer() const
Check if there is a writer for the interface.
Definition: interface.cpp:819
fawkes::MessageQueue::first
Message * first()
Get first message from queue.
Definition: message_queue.cpp:290
fawkes::Interface::msgq_unlock
void msgq_unlock()
Unlock message queue.
Definition: interface.cpp:1106
fawkes::Interface::num_buffers
unsigned int num_buffers() const
Get number of buffers.
Definition: interface.cpp:1256
fawkes::Interface::parse_uid
static void parse_uid(const char *uid, std::string &type, std::string &id)
Parse UID to type and ID strings.
Definition: interface.cpp:1389
fawkes::InterfaceWriteDeniedException
Definition: interface.h:54
fawkes::BlackBoardMessageManager
Definition: message_manager.h:42
fawkes::interface_enum_map_t
std::map< int, std::string > interface_enum_map_t
Map of enum integer to string values.
Definition: types.h:61
fawkes::Interface::uid
const char * uid() const
Get unique identifier of interface.
Definition: interface.cpp:679
fawkes::Interface::num_readers
unsigned int num_readers() const
Get the number of readers.
Definition: interface.cpp:847
fawkes::Interface::copy_values
virtual void copy_values(const Interface *interface)=0
fawkes::Interface::fields
InterfaceFieldIterator fields()
Get iterator over all fields of this interface instance.
Definition: interface.cpp:1200
fawkes::Time
Definition: time.h:98
fawkes::Interface::owner
const char * owner() const
Get owner of interface.
Definition: interface.cpp:665
fawkes::Interface::set_auto_timestamping
void set_auto_timestamping(bool enabled)
Enable or disable automated timestamping.
Definition: interface.cpp:748
fawkes::Interface::data_size
unsigned int data_size
Definition: interface.h:225
fawkes::BlackBoardInstanceFactory
Definition: instance_factory.h:39
fawkes::Interface::serial
unsigned short serial() const
Get instance serial of interface.
Definition: interface.cpp:688
fawkes::Interface::msgq_size
unsigned int msgq_size()
Get size of message queue.
Definition: interface.cpp:1014
fawkes::Interface::num_fields
unsigned int num_fields()
Get the number of fields in the interface.
Definition: interface.cpp:1218
fawkes::Interface::~Interface
virtual ~Interface()
Destructor.
Definition: interface.cpp:267
fawkes::Interface::copy_private_to_buffer
void copy_private_to_buffer(unsigned int buffer)
Copy data from private memory to buffer.
Definition: interface.cpp:1291
fawkes::Interface::enum_tostring
virtual const char * enum_tostring(const char *enumtype, int val) const =0
fawkes::Interface::msgq_flush
void msgq_flush()
Flush all messages.
Definition: interface.cpp:1048
fawkes::Interface::datasize
unsigned int datasize() const
Get data size.
Definition: interface.cpp:533
fawkes::InterfaceMessageEnqueueException
Definition: interface.h:60
fawkes::Interface::msgq_enqueue
unsigned int msgq_enqueue(Message *message)
Enqueue message at end of queue.
Definition: interface.cpp:884
fawkes::Interface::oftype
bool oftype(const char *interface_type) const
Check if interface is of given type.
Definition: interface.cpp:636
fawkes::Interface::set_from_chunk
void set_from_chunk(void *chunk)
Set from a raw data chunk.
Definition: interface.cpp:802
fawkes::InterfaceMessageEnqueueException::InterfaceMessageEnqueueException
InterfaceMessageEnqueueException(const char *type, const char *id)
Constructor.
Definition: interface.cpp:79
fawkes::Interface::msgq_first
Message * msgq_first()
Get the first message from the message queue.
Definition: interface.cpp:1169
fawkes::Interface::add_messageinfo
void add_messageinfo(const char *name)
Add an entry to the message info list.
Definition: interface.cpp:380
fawkes::Interface::write
void write()
Write from local copy into BlackBoard memory.
Definition: interface.cpp:499
fawkes::Interface::hash_size
size_t hash_size() const
Get size of interface hash.
Definition: interface.cpp:424
fawkes::InterfaceInvalidException
Definition: interface.h:72
fawkes::Interface::is_valid
bool is_valid() const
Check validity of interface.
Definition: interface.cpp:467
fawkes::Interface::copy_shared_to_buffer
void copy_shared_to_buffer(unsigned int buffer)
Copy data from private memory to buffer.
Definition: interface.cpp:1265
fawkes::Clock
Definition: clock.h:41
fawkes::Interface::msgq_try_lock
bool msgq_try_lock()
Try to lock message queue.
Definition: interface.cpp:1088
fawkes::Interface::operator==
bool operator==(Interface &comp) const
Check equality of two interfaces.
Definition: interface.cpp:625
fawkes::Exception
Definition: exception.h:41