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 <arpa/inet.h>
25#include <blackboard/net/ilist_content.h>
26#include <core/exceptions/software.h>
27#include <netcomm/fawkes/component_ids.h>
28#include <netcomm/utils/dynamic_buffer.h>
29#include <utils/time/time.h>
30
31#include <cstdlib>
32#include <cstring>
33
34namespace 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/** Message content constructor.
52 * This constructor is meant to be used with FawkesNetworkMessage::msgc().
53 * @param component_id component ID
54 * @param msg_id message ID
55 * @param payload message payload
56 * @param payload_size total payload size
57 */
59 unsigned int msg_id,
60 void * payload,
61 size_t payload_size)
62{
63 if (component_id != FAWKES_CID_BLACKBOARD) {
64 throw TypeMismatchException("BlackBoardInterfaceListContent: invalid component ID");
65 }
67 void * ilist_payload = (void *)((size_t)payload + sizeof(msg));
68 interface_list =
69 new DynamicBuffer(&(tmsg->interface_list), ilist_payload, payload_size - sizeof(msg));
70}
71
72/** Destructor. */
74{
75 delete interface_list;
76 if (_payload != NULL) {
77 free(_payload);
78 _payload = NULL;
79 _payload_size = 0;
80 }
81}
82
83/** Append interface info.
84 * @param type type of interface
85 * @param id ID of interface instance
86 * @param hash version hash of interface instance/type
87 * @param serial instance serial
88 * @param has_writer true if a writer exists, false otherwise
89 * @param num_readers number of readers
90 * @param timestamp interface timestamp (time of last write or data timestamp)
91 */
92void
94 const char * id,
95 const unsigned char *hash,
96 unsigned int serial,
97 bool has_writer,
98 unsigned int num_readers,
99 const fawkes::Time & timestamp)
100{
101 bb_iinfo_msg_t info;
102 memset(&info, 0, sizeof(info));
103 strncpy(info.type, type, INTERFACE_TYPE_SIZE_ - 1);
104 strncpy(info.id, id, INTERFACE_ID_SIZE_ - 1);
105 memcpy(info.hash, hash, INTERFACE_HASH_SIZE_);
106 info.serial = htonl(serial);
107 info.writer_readers = htonl(num_readers);
108 if (has_writer) {
109 info.writer_readers |= htonl(0x80000000);
110 } else {
111 info.writer_readers &= htonl(0x7FFFFFFF);
112 }
113 interface_list->append(&info, sizeof(info));
114 info.timestamp_sec = timestamp.get_sec();
115 info.timestamp_usec = timestamp.get_usec();
116}
117
118/** Append interface info.
119 * @param iinfo interface info
120 */
121void
123{
124 bb_iinfo_msg_t info;
125 memset(&info, 0, sizeof(info));
126 strncpy(info.type, iinfo.type(), INTERFACE_TYPE_SIZE_ - 1);
127 strncpy(info.id, iinfo.id(), INTERFACE_ID_SIZE_ - 1);
128 memcpy(info.hash, iinfo.hash(), INTERFACE_HASH_SIZE_);
129 info.serial = htonl(iinfo.serial());
130 info.writer_readers = htonl(iinfo.num_readers());
131 if (iinfo.has_writer()) {
132 info.writer_readers |= htonl(0x80000000);
133 } else {
134 info.writer_readers &= htonl(0x7FFFFFFF);
135 }
136 const Time *timestamp = iinfo.timestamp();
137 info.timestamp_sec = timestamp->get_sec();
138 info.timestamp_usec = timestamp->get_usec();
139
140 interface_list->append(&info, sizeof(info));
141}
142
143void
145{
146 _payload_size = sizeof(msg) + interface_list->buffer_size();
147 _payload = malloc(_payload_size);
148 copy_payload(0, &msg, sizeof(msg));
149 copy_payload(sizeof(msg), interface_list->buffer(), interface_list->buffer_size());
150}
151
152/** Reset iterator.
153 * For incoming messages only.
154 */
155void
157{
158 interface_list->reset_iterator();
159}
160
161/** Check if more list elements are available.
162 * For incoming messages only.
163 * @return true if there are more elements available, false otherwise.
164 */
165bool
167{
168 return interface_list->has_next();
169}
170
171/** Get next plugin from list.
172 * @param size upon return contains the size of the returned data element.
173 * @return next config entitiy from the list. The value is only of the type of
174 * the header. Check the message type and the size and cast the message to the correct
175 * entity.
176 */
179{
180 void *tmp = interface_list->next(size);
181 return (bb_iinfo_msg_t *)tmp;
182}
183
184} // end namespace fawkes
virtual ~BlackBoardInterfaceListContent()
Destructor.
bb_iinfo_msg_t * next(size_t *size)
Get next plugin from list.
bool has_next()
Check if more list elements are available.
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.
virtual void serialize()
Serialize message content.
Dynamically growing buffer.
size_t buffer_size()
Get buffer size.
void append(const void *data, size_t data_size)
Append data.
void reset_iterator()
Reset iterator.
bool has_next()
Check if another element is available.
void * next(size_t *size)
Get next buffer.
void * buffer()
Get pointer to buffer.
void copy_payload(size_t offset, const void *buf, size_t len)
Copy payload into payload buffer to a specified offset.
virtual size_t payload_size()
Return payload size.
void * _payload
Pointer to payload.
virtual void * payload()
Return pointer to payload.
Interface info.
bool has_writer() const
Check if there is a writer.
unsigned int serial() const
Get interface instance serial.
const char * type() const
Get interface type.
const char * id() const
Get interface ID.
const unsigned char * hash() const
Get interface version hash.
unsigned int num_readers() const
Get number of readers.
const Time * timestamp() const
Get interface timestamp.
A class for handling time.
Definition: time.h:93
long get_usec() const
Get microseconds.
Definition: time.h:127
long get_sec() const
Get seconds.
Definition: time.h:117
Fawkes library namespace.
Message for interface info.
Definition: messages.h:91
uint32_t writer_readers
combined writer reader information.
Definition: messages.h:97
char id[INTERFACE_ID_SIZE_]
interface instance ID
Definition: messages.h:93
unsigned char hash[INTERFACE_HASH_SIZE_]
interface version hash
Definition: messages.h:94
int64_t timestamp_usec
data or write timestamp, usec part
Definition: messages.h:103
int64_t timestamp_sec
data or write timestamp, sec part
Definition: messages.h:102
uint32_t serial
instance serial to uniquely identify this instance (big endian)
Definition: messages.h:95
char type[INTERFACE_TYPE_SIZE_]
interface type name
Definition: messages.h:92
Message to transport a list of interfaces.
Definition: messages.h:70
dynamic_list_t interface_list
dynamic buffer list with interface info
Definition: messages.h:71