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),
53 FawkesNetworkHandler(FAWKES_CID_CONFIGMANAGER),
54 ConfigurationChangeHandler(
"")
61 config_->add_change_handler(
this);
62 hub_->add_handler(
this);
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()) {
238 FawkesNetworkMessage *msg = inbound_queue_.front();
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);
279 config_value_erased_msg_t *r =
280 prepare_msg<config_value_erased_msg_t>(path, (m->
cp.
is_default == 1));
281 hub_->
send(msg->clid(),
282 FAWKES_CID_CONFIGMANAGER,
283 MSG_CONFIG_VALUE_ERASED,
285 sizeof(config_value_erased_msg_t));
287 }
catch (Exception &e) {
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)) {
295 if (msg->payload_size() !=
sizeof(config_getval_msg_t)) {
297 "CONFIG_GET_FLOAT: invalid payload size "
298 "(received %zu instead of %zu bytes",
300 sizeof(config_getval_msg_t));
302 config_getval_msg_t *m = (config_getval_msg_t *)msg->payload();
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:
315 Configuration::ValueIterator *i = config_->
get_value(path);
317 send_value(msg->clid(), i);
319 send_inv_value(msg->clid(), path);
322 }
catch (ConfigurationException &e) {
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];
335 if (msg->payload_size() <
sizeof(config_descriptor_t)) {
337 "inbound set: payload is too small"
338 "(%zu is less than %zu bytes",
340 sizeof(config_descriptor_t));
341 send_inv_value(msg->clid(),
"?");
343 config_descriptor_t *cd = (config_descriptor_t *)msg->payload();
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:
351 float *vs = (
float *)((
char *)msg->payload() +
sizeof(config_descriptor_t));
352 if (cd->num_values > 0) {
353 std::vector<float> values(cd->num_values);
354 for (
unsigned int i = 0; i < cd->num_values; ++i) {
359 if (msg->msgid() == MSG_CONFIG_SET_FLOAT) {
366 }
catch (Exception &e) {
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:
378 uint32_t *vs = (uint32_t *)((
char *)msg->payload() +
sizeof(config_descriptor_t));
379 if (cd->num_values > 0) {
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) {
393 }
catch (Exception &e) {
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:
405 int32_t *vs = (int32_t *)((
char *)msg->payload() +
sizeof(config_descriptor_t));
406 if (cd->num_values > 0) {
407 std::vector<int> values(cd->num_values);
408 for (
unsigned int i = 0; i < cd->num_values; ++i) {
413 if (msg->msgid() == MSG_CONFIG_SET_INT) {
420 }
catch (Exception &e) {
421 send_inv_value(msg->clid(), path);
427 case MSG_CONFIG_SET_BOOL:
428 case MSG_CONFIG_SET_DEFAULT_BOOL:
430 int32_t *vs = (int32_t *)((
char *)msg->payload() +
sizeof(config_descriptor_t));
431 if (cd->num_values > 0) {
432 std::vector<bool> values(cd->num_values);
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));
445 }
catch (Exception &e) {
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:
457 char *tmp = ((
char *)msg->payload() +
sizeof(config_descriptor_t));
459 if (cd->num_values > 0) {
460 std::vector<std::string> values(cd->num_values);
461 for (
unsigned int i = 0; i < cd->num_values; ++i) {
462 config_string_value_t *sv = (config_string_value_t *)tmp;
463 char * msg_string = tmp +
sizeof(config_string_value_t);
464 tmp +=
sizeof(config_string_value_t) + sv->s_length + 1;
465 values[i] = std::string(msg_string, sv->s_length);
469 config_string_value_t *sv = (config_string_value_t *)tmp;
470 char * msg_string = tmp +
sizeof(config_string_value_t);
471 std::string value = std::string(msg_string, sv->s_length);
472 if (msg->msgid() == MSG_CONFIG_SET_INT) {
479 }
catch (Exception &e) {
480 send_inv_value(msg->clid(), path);
482 "set string: Value %s could not be set",
492 Configuration::ValueIterator *i = config_->
get_value(path);
494 send_value(msg->clid(), i);
496 send_inv_value(msg->clid(), path);
499 }
catch (ConfigurationException &e) {
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 "