24 #include <config/config.h>
25 #include <config/net_handler.h>
26 #include <config/net_list_content.h>
27 #include <config/net_messages.h>
28 #include <logging/liblogger.h>
29 #include <netcomm/fawkes/component_ids.h>
30 #include <netcomm/fawkes/hub.h>
52 :
Thread(
"ConfigNetworkHandler",
Thread::OPMODE_WAITFORWAKEUP),
72 inbound_queue_.
clear();
80 ConfigNetworkHandler::send_inv_value(
unsigned int clid,
const char *path)
91 ConfigNetworkHandler::send_value(
unsigned int clid,
const Configuration::ValueIterator *i)
96 uint16_t num_values = i->is_list() ? i->get_list_size() : 0;
98 void * m = prepare_value_msg<uint32_t>(
99 i->path(), i->is_default(), i->is_list(), num_values, data_size, (
void **)&values);
101 std::vector<unsigned int> c_values = i->get_uints();
102 for (uint16_t j = 0; j < num_values; ++j)
103 values[j] = c_values[j];
105 values[0] = i->get_uint();
107 hub_->
send(clid, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_UINT_VALUE, m, data_size);
108 }
catch (Exception &e) {
110 "send_value: Value %s could not be sent",
114 }
else if (i->is_int()) {
117 int16_t num_values = i->is_list() ? i->get_list_size() : 0;
118 size_t data_size = 0;
119 void * m = prepare_value_msg<int32_t>(
120 i->path(), i->is_default(), i->is_list(), num_values, data_size, (
void **)&values);
122 std::vector<int> c_values = i->get_ints();
123 for (uint16_t j = 0; j < num_values; ++j)
124 values[j] = c_values[j];
126 values[0] = i->get_int();
128 hub_->
send(clid, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_INT_VALUE, m, data_size);
129 }
catch (Exception &e) {
131 "send_value: Value %s could not be sent",
135 }
else if (i->is_bool()) {
138 int16_t num_values = i->is_list() ? i->get_list_size() : 0;
139 size_t data_size = 0;
140 void * m = prepare_value_msg<int32_t>(
141 i->path(), i->is_default(), i->is_list(), num_values, data_size, (
void **)&values);
143 std::vector<bool> c_values = i->get_bools();
144 for (uint16_t j = 0; j < num_values; ++j)
145 values[j] = (c_values[j] ? 1 : 0);
147 values[0] = i->get_bool() ? 1 : 0;
149 hub_->
send(clid, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_BOOL_VALUE, m, data_size);
150 }
catch (Exception &e) {
152 "send_value: Value %s could not be sent",
156 }
else if (i->is_float()) {
159 uint16_t num_values = i->is_list() ? i->get_list_size() : 0;
160 size_t data_size = 0;
161 void * m = prepare_value_msg<float>(
162 i->path(), i->is_default(), i->is_list(), num_values, data_size, (
void **)&values);
164 std::vector<float> c_values = i->get_floats();
165 for (uint16_t j = 0; j < num_values; ++j)
166 values[j] = c_values[j];
168 values[0] = i->get_float();
170 hub_->
send(clid, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_FLOAT_VALUE, m, data_size);
171 }
catch (Exception &e) {
173 "send_value: Value %s could not be sent",
177 }
else if (i->is_string()) {
180 std::vector<std::string> s = i->get_strings();
181 size_t data_size =
sizeof(config_descriptor_t);
183 for (
unsigned int j = 0; j < s.size(); ++j) {
184 data_size +=
sizeof(config_string_value_t) + s[j].length() + 1;
186 void *m = calloc(1, data_size);
188 config_descriptor_t *cd = (config_descriptor_t *)m;
189 strncpy(cd->path, i->path(), CONFIG_MSG_PATH_LENGTH - 1);
190 cd->is_default = i->is_default();
191 cd->num_values = s.size();
193 char *tmp = ((
char *)m +
sizeof(config_descriptor_t));
194 for (
unsigned int j = 0; j < s.size(); ++j) {
195 config_string_value_t *sv = (config_string_value_t *)tmp;
196 char * msg_string = tmp +
sizeof(config_string_value_t);
197 sv->s_length = s[j].length();
198 strcpy(msg_string, s[j].c_str());
199 tmp +=
sizeof(config_string_value_t) + sv->s_length + 1;
202 hub_->
send(clid, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_STRING_VALUE, m, data_size);
204 std::string s = i->get_string();
206 sizeof(config_descriptor_t) +
sizeof(config_string_value_t) + s.length() + 1;
207 void * m = calloc(1, data_size);
208 config_descriptor_t *cd = (config_descriptor_t *)m;
209 strncpy(cd->path, i->path(), CONFIG_MSG_PATH_LENGTH - 1);
210 cd->is_default = i->is_default();
213 config_string_value_t *sv =
214 (config_string_value_t *)((
char *)m +
sizeof(config_descriptor_t));
215 char *msg_string = (
char *)sv +
sizeof(config_string_value_t);
217 sv->s_length = s.length();
218 strcpy(msg_string, s.c_str());
220 hub_->
send(clid, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_STRING_VALUE, m, data_size);
222 }
catch (Exception &e) {
224 "send_value: Value %s could not be sent",
229 LibLogger::log_warn(
"ConfigNetworkHandler",
"send_value: unknown type of value %s", i->path());
237 while (!inbound_queue_.empty()) {
242 if (msg->
msgid() == MSG_CONFIG_SUBSCRIBE) {
245 subscribers_.unique();
263 hub_->
send(msg->
clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_LIST, content);
266 }
else if (msg->
msgid() == MSG_CONFIG_ERASE_VALUE) {
269 char path[CONFIG_MSG_PATH_LENGTH];
270 path[CONFIG_MSG_PATH_LENGTH - 1] = 0;
271 memcpy(path, m->
cp.
path, CONFIG_MSG_PATH_LENGTH);
276 config_->
erase(path);
280 prepare_msg<config_value_erased_msg_t>(path, (m->
cp.
is_default == 1));
282 FAWKES_CID_CONFIGMANAGER,
283 MSG_CONFIG_VALUE_ERASED,
288 send_inv_value(msg->
clid(),
"?");
289 e.
append(
"Failed to erase value");
294 }
else if ((msg->
msgid() >= MSG_CONFIG_GET_BEGIN) && (msg->
msgid() <= MSG_CONFIG_GET_END)) {
297 "CONFIG_GET_FLOAT: invalid payload size "
298 "(received %zu instead of %zu bytes",
303 char path[CONFIG_MSG_PATH_LENGTH + 1];
304 path[CONFIG_MSG_PATH_LENGTH] = 0;
305 strncpy(path, m->
cp.
path, CONFIG_MSG_PATH_LENGTH);
307 switch (msg->
msgid()) {
308 case MSG_CONFIG_GET_FLOAT:
309 case MSG_CONFIG_GET_UINT:
310 case MSG_CONFIG_GET_INT:
311 case MSG_CONFIG_GET_BOOL:
312 case MSG_CONFIG_GET_STRING:
313 case MSG_CONFIG_GET_VALUE:
317 send_value(msg->
clid(), i);
319 send_inv_value(msg->
clid(), path);
324 "get value: Value %s could not be found",
331 }
else if ((msg->
msgid() >= MSG_CONFIG_SET_BEGIN) && (msg->
msgid() <= MSG_CONFIG_SET_END)) {
332 bool success =
false;
334 char path[CONFIG_MSG_PATH_LENGTH + 1];
337 "inbound set: payload is too small"
338 "(%zu is less than %zu bytes",
341 send_inv_value(msg->
clid(),
"?");
344 path[CONFIG_MSG_PATH_LENGTH] = 0;
345 strncpy(path, cd->
path, CONFIG_MSG_PATH_LENGTH);
347 switch (msg->
msgid()) {
348 case MSG_CONFIG_SET_FLOAT:
349 case MSG_CONFIG_SET_DEFAULT_FLOAT:
354 for (
unsigned int i = 0; i < cd->
num_values; ++i) {
359 if (msg->
msgid() == MSG_CONFIG_SET_FLOAT) {
367 send_inv_value(msg->
clid(), path);
369 "set float: Value %s could not be set",
375 case MSG_CONFIG_SET_UINT:
376 case MSG_CONFIG_SET_DEFAULT_UINT:
380 std::vector<unsigned int> values(cd->
num_values);
381 for (
unsigned int i = 0; i < cd->
num_values; ++i) {
386 if (msg->
msgid() == MSG_CONFIG_SET_UINT) {
394 send_inv_value(msg->
clid(), path);
396 "set uint: Value %s could not be set",
402 case MSG_CONFIG_SET_INT:
403 case MSG_CONFIG_SET_DEFAULT_INT:
408 for (
unsigned int i = 0; i < cd->
num_values; ++i) {
413 if (msg->
msgid() == MSG_CONFIG_SET_INT) {
421 send_inv_value(msg->
clid(), path);
427 case MSG_CONFIG_SET_BOOL:
428 case MSG_CONFIG_SET_DEFAULT_BOOL:
433 for (
unsigned int i = 0; i < cd->
num_values; ++i) {
434 values[i] = (vs[i] != 0);
438 if (msg->
msgid() == MSG_CONFIG_SET_INT) {
439 config_->
set_bool(path, (*vs != 0));
446 send_inv_value(msg->
clid(), path);
448 "set bool: Value %s could not be set",
454 case MSG_CONFIG_SET_STRING:
455 case MSG_CONFIG_SET_DEFAULT_STRING:
460 std::vector<std::string> values(cd->
num_values);
461 for (
unsigned int i = 0; i < cd->
num_values; ++i) {
465 values[i] = std::string(msg_string, sv->
s_length);
471 std::string value = std::string(msg_string, sv->
s_length);
472 if (msg->
msgid() == MSG_CONFIG_SET_INT) {
480 send_inv_value(msg->
clid(), path);
482 "set string: Value %s could not be set",
494 send_value(msg->
clid(), i);
496 send_inv_value(msg->
clid(), path);
501 "get value: Value %s could not be found",
542 if (find(subscribers_.begin(), subscribers_.end(), clid) != subscribers_.end()) {
544 "ConfigNetworkHandler",
545 "Client %u disconnected without closing the config, removing from list of subscribers",
547 subscribers_.remove(clid);
564 const char *path = v->
path();
567 for (sit_ = subscribers_.begin(); sit_ != subscribers_.end(); ++sit_) {
569 send_value(*sit_, v);
572 "config_value_changed: Value for %s could not be sent "
591 for (sit_ = subscribers_.begin(); sit_ != subscribers_.end(); ++sit_) {
595 FAWKES_CID_CONFIGMANAGER,
596 MSG_CONFIG_VALUE_ERASED,
601 "configValueErased: Value for %s could not be sent "