Fawkes API  Fawkes Development Version
ilist_content.cpp
1 
2 /***************************************************************************
3  * net_ilist_content.cpp - BlackBoard network: interface list content
4  *
5  * Created: Mon Mar 03 12:04:51 2008
6  * Copyright 2006-2008 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <blackboard/net/ilist_content.h>
25 
26 #include <netcomm/utils/dynamic_buffer.h>
27 #include <netcomm/fawkes/component_ids.h>
28 #include <core/exceptions/software.h>
29 #include <utils/time/time.h>
30 #include <cstdlib>
31 #include <cstring>
32 #include <arpa/inet.h>
33 
34 namespace fawkes {
35 
36 /** @class BlackBoardInterfaceListContent <blackboard/net/ilist_content.h>
37  * BlackBoard interface list content.
38  * A complex dynamic message with an arbitrary number of interfaces. Uses
39  * DynamicBuffer for the internal list of plugins and thus the buffer is
40  * limited to 4 GB in total.
41  *
42  * @author Tim Niemueller
43  */
44 
45 /** Constructor. */
47 {
48  interface_list = new DynamicBuffer(&(msg.interface_list));
49 }
50 
51 
52 /** Message content constructor.
53  * This constructor is meant to be used with FawkesNetworkMessage::msgc().
54  * @param component_id component ID
55  * @param msg_id message ID
56  * @param payload message payload
57  * @param payload_size total payload size
58  */
60  unsigned int msg_id,
61  void *payload,
62  size_t payload_size)
63 {
64  if ( component_id != FAWKES_CID_BLACKBOARD ) {
65  throw TypeMismatchException("BlackBoardInterfaceListContent: invalid component ID");
66  }
67  bb_ilist_msg_t *tmsg = (bb_ilist_msg_t *)payload;
68  void *ilist_payload = (void *)((size_t)payload + sizeof(msg));
69  interface_list = new DynamicBuffer(&(tmsg->interface_list), ilist_payload,
70  payload_size - sizeof(msg));
71 }
72 
73 
74 /** Destructor. */
76 {
77  delete interface_list;
78  if (_payload != NULL) {
79  free(_payload);
80  _payload = NULL;
81  _payload_size = 0;
82  }
83 }
84 
85 
86 
87 /** Append interface info.
88  * @param type type of interface
89  * @param id ID of interface instance
90  * @param hash version hash of interface instance/type
91  * @param serial instance serial
92  * @param has_writer true if a writer exists, false otherwise
93  * @param num_readers number of readers
94  * @param timestamp interface timestamp (time of last write or data timestamp)
95  */
96 void
97 BlackBoardInterfaceListContent::append_interface(const char *type, const char *id,
98  const unsigned char *hash,
99  unsigned int serial,
100  bool has_writer, unsigned int num_readers,
101  const fawkes::Time &timestamp)
102 {
103  bb_iinfo_msg_t info;
104  memset(&info, 0, sizeof(info));
105  strncpy(info.type, type, __INTERFACE_TYPE_SIZE);
106  strncpy(info.id, id, __INTERFACE_ID_SIZE);
107  memcpy(info.hash, hash, __INTERFACE_HASH_SIZE);
108  info.serial = htonl(serial);
109  info.writer_readers = htonl(num_readers);
110  if (has_writer) {
111  info.writer_readers |= htonl(0x80000000);
112  } else {
113  info.writer_readers &= htonl(0x7FFFFFFF);
114  }
115  interface_list->append(&info, sizeof(info));
116  info.timestamp_sec = timestamp.get_sec();
117  info.timestamp_usec = timestamp.get_usec();
118 }
119 
120 
121 /** Append interface info.
122  * @param iinfo interface info
123  */
124 void
126 {
127  bb_iinfo_msg_t info;
128  memset(&info, 0, sizeof(info));
129  strncpy(info.type, iinfo.type(), __INTERFACE_TYPE_SIZE);
130  strncpy(info.id, iinfo.id(), __INTERFACE_ID_SIZE);
131  memcpy(info.hash, iinfo.hash(), __INTERFACE_HASH_SIZE);
132  info.serial = htonl(iinfo.serial());
133  info.writer_readers = htonl(iinfo.num_readers());
134  if (iinfo.has_writer()) {
135  info.writer_readers |= htonl(0x80000000);
136  } else {
137  info.writer_readers &= htonl(0x7FFFFFFF);
138  }
139  const Time *timestamp = iinfo.timestamp();
140  info.timestamp_sec = timestamp->get_sec();
141  info.timestamp_usec = timestamp->get_usec();
142 
143  interface_list->append(&info, sizeof(info));
144 }
145 
146 
147 void
149 {
150  _payload_size = sizeof(msg) + interface_list->buffer_size();
151  _payload = malloc(_payload_size);
152  copy_payload(0, &msg, sizeof(msg));
153  copy_payload(sizeof(msg), interface_list->buffer(), interface_list->buffer_size());
154 }
155 
156 
157 /** Reset iterator.
158  * For incoming messages only.
159  */
160 void
162 {
163  interface_list->reset_iterator();
164 }
165 
166 
167 /** Check if more list elements are available.
168  * For incoming messages only.
169  * @return true if there are more elements available, false otherwise.
170  */
171 bool
173 {
174  return interface_list->has_next();
175 }
176 
177 
178 /** Get next plugin from list.
179  * @param size upon return contains the size of the returned data element.
180  * @return next config entitiy from the list. The value is only of the type of
181  * the header. Check the message type and the size and cast the message to the correct
182  * entity.
183  */
186 {
187  void *tmp = interface_list->next(size);
188  return (bb_iinfo_msg_t *)tmp;
189 }
190 
191 } // end namespace fawkes
void * _payload
Pointer to payload.
uint32_t serial
instance serial to uniquely identify this instance (big endian)
Definition: messages.h:90
const char * type() const
Get interface type.
bool has_next()
Check if more list elements are available.
int64_t timestamp_sec
data or write timestamp, sec part
Definition: messages.h:97
Fawkes library namespace.
const char * id() const
Get interface ID.
int64_t timestamp_usec
data or write timestamp, usec part
Definition: messages.h:98
void * buffer()
Get pointer to buffer.
bb_iinfo_msg_t * next(size_t *size)
Get next plugin from list.
A class for handling time.
Definition: time.h:91
Message to transport a list of interfaces.
Definition: messages.h:67
Message for interface info.
Definition: messages.h:86
bool has_next()
Check if another element is available.
size_t buffer_size()
Get buffer size.
const unsigned char * hash() const
Get interface version hash.
const Time * timestamp() const
Get interface timestamp.
char id[__INTERFACE_ID_SIZE]
interface instance ID
Definition: messages.h:88
bool has_writer() const
Check if there is a writer.
uint32_t writer_readers
combined writer reader information.
Definition: messages.h:92
char type[__INTERFACE_TYPE_SIZE]
interface type name
Definition: messages.h:87
unsigned char hash[__INTERFACE_HASH_SIZE]
interface version hash
Definition: messages.h:89
unsigned int serial() const
Get interface instance serial.
virtual void * payload()
Return pointer to payload.
unsigned int num_readers() const
Get number of readers.
dynamic_list_t interface_list
dynamic buffer list with interface info
Definition: messages.h:68
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.
long get_sec() const
Get seconds.
Definition: time.h:110
void copy_payload(size_t offset, const void *buf, size_t len)
Copy payload into payload buffer to a specified offset.
Dynamically growing buffer.
long get_usec() const
Get microseconds.
Definition: time.h:112
virtual size_t payload_size()
Return payload size.
void reset_iterator()
Reset iterator.
virtual ~BlackBoardInterfaceListContent()
Destructor.
void append(const void *data, size_t data_size)
Append data.
void * next(size_t *size)
Get next buffer.
virtual void serialize()
Serialize message content.
Interface info.