Fawkes API  Fawkes Development Version
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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 <cstdlib>
30 #include <cstring>
31 
32 namespace fawkes {
33 
34 /** @class BlackBoardInterfaceListContent <blackboard/net/ilist_content.h>
35  * BlackBoard interface list content.
36  * A complex dynamic message with an arbitrary number of interfaces. Uses
37  * DynamicBuffer for the internal list of plugins and thus the buffer is
38  * limited to 4 GB in total.
39  *
40  * @author Tim Niemueller
41  */
42 
43 /** Constructor. */
45 {
46  interface_list = new DynamicBuffer(&(msg.interface_list));
47 }
48 
49 
50 /** Message content constructor.
51  * This constructor is meant to be used with FawkesNetworkMessage::msgc().
52  * @param component_id component ID
53  * @param msg_id message ID
54  * @param payload message payload
55  * @param payload_size total payload size
56  */
58  unsigned int msg_id,
59  void *payload,
60  size_t payload_size)
61 {
62  if ( component_id != FAWKES_CID_BLACKBOARD ) {
63  throw TypeMismatchException("BlackBoardInterfaceListContent: invalid component ID");
64  }
65  bb_ilist_msg_t *tmsg = (bb_ilist_msg_t *)payload;
66  void *ilist_payload = (void *)((size_t)payload + sizeof(msg));
67  interface_list = new DynamicBuffer(&(tmsg->interface_list), ilist_payload,
68  payload_size - sizeof(msg));
69 }
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 
84 
85 /** Append interface info.
86  * @param type type of interface
87  * @param id ID of interface instance
88  * @param hash version hash of interface instance/type
89  * @param serial instance serial
90  * @param has_writer true if a writer exists, false otherwise
91  * @param num_readers number of readers
92  */
93 void
94 BlackBoardInterfaceListContent::append_interface(const char *type, const char *id,
95  const unsigned char *hash,
96  unsigned int serial,
97  bool has_writer, unsigned int num_readers)
98 {
99  bb_iinfo_msg_t info;
100  memset(&info, 0, sizeof(info));
101  strncpy(info.type, type, __INTERFACE_TYPE_SIZE);
102  strncpy(info.id, id, __INTERFACE_ID_SIZE);
103  memcpy(info.hash, hash, __INTERFACE_HASH_SIZE);
104  interface_list->append(&info, sizeof(info));
105  info.serial = serial;
106  info.has_writer = has_writer ? 1 : 0;
107  info.num_readers = num_readers;
108 }
109 
110 
111 /** Append interface info.
112  * @param iinfo interface info
113  */
114 void
116 {
117  bb_iinfo_msg_t info;
118  memset(&info, 0, sizeof(info));
119  strncpy(info.type, iinfo.type(), __INTERFACE_TYPE_SIZE);
120  strncpy(info.id, iinfo.id(), __INTERFACE_ID_SIZE);
121  memcpy(info.hash, iinfo.hash(), __INTERFACE_HASH_SIZE);
122  info.serial = iinfo.serial();
123  info.has_writer = iinfo.has_writer() ? 1 : 0;
124  info.num_readers = iinfo.num_readers();
125  interface_list->append(&info, sizeof(info));
126 }
127 
128 
129 void
131 {
132  _payload_size = sizeof(msg) + interface_list->buffer_size();
133  _payload = malloc(_payload_size);
134  copy_payload(0, &msg, sizeof(msg));
135  copy_payload(sizeof(msg), interface_list->buffer(), interface_list->buffer_size());
136 }
137 
138 
139 /** Reset iterator.
140  * For incoming messages only.
141  */
142 void
144 {
145  interface_list->reset_iterator();
146 }
147 
148 
149 /** Check if more list elements are available.
150  * For incoming messages only.
151  * @return true if there are more elements available, false otherwise.
152  */
153 bool
155 {
156  return interface_list->has_next();
157 }
158 
159 
160 /** Get next plugin from list.
161  * @param size upon return contains the size of the returned data element.
162  * @return next config entitiy from the list. The value is only of the type of
163  * the header. Check the message type and the size and cast the message to the correct
164  * entity.
165  */
168 {
169  void *tmp = interface_list->next(size);
170  return (bb_iinfo_msg_t *)tmp;
171 }
172 
173 } // end namespace fawkes