24 #include <config/memory.h>
25 #include <config/net_list_content.h>
26 #include <config/net_messages.h>
27 #include <config/netconf.h>
28 #include <core/threading/interruptible_barrier.h>
29 #include <core/threading/mutex.h>
30 #include <logging/liblogger.h>
31 #include <netcomm/fawkes/client.h>
32 #include <netcomm/fawkes/message.h>
33 #include <netcomm/utils/exceptions.h>
34 #include <utils/misc/string_conversions.h>
52 :
Exception(
"Could not enable mirroring: %s", msg)
77 mirror_timeout_sec_ = mirror_timeout_sec;
81 mirror_mode_before_connection_dead_ =
false;
82 mirror_init_waiting_ =
false;
90 e.
append(
"Failed to register for config manager component on network client");
103 delete mirror_init_barrier_;
146 bool rv = i->
valid();
190 return (
get_type(path) ==
"unsigned int");
208 return (
get_type(path) ==
"string");
218 NetworkConfiguration::send_get(
const char *path,
unsigned int msgid,
unsigned int expected_reply)
222 "client connection is not alive");
224 config_getval_msg_t *g = (config_getval_msg_t *)calloc(1,
sizeof(config_getval_msg_t));
225 strncpy(g->cp.path, path, CONFIG_MSG_PATH_LENGTH - 1);
226 FawkesNetworkMessage *omsg =
227 new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER, msgid, g,
sizeof(config_getval_msg_t));
232 throw NullPointerException(
"NetworkConfiguration::send_get: msg == NULL");
235 if (msg->
msgid() != expected_reply) {
236 unsigned int msg_msgid = msg->
msgid();
240 throw Exception(
"NetworkConfiguration::send_get: expected %u, but got %u",
249 if (strlen(path) > CONFIG_MSG_PATH_LENGTH) {
251 "Maximum length for path exceeded");
255 "client connection is not alive");
265 e.
append(
"NetworkConfiguration[mirroring]::get_float: exception in mirror database");
271 send_get(path, MSG_CONFIG_GET_FLOAT, MSG_CONFIG_FLOAT_VALUE);
277 throw Exception(
"NetworkConfiguration: received list of and not a single value");
285 e.
append(
"NetworkConfiguration::get_float: Fetching float failed");
303 if (strlen(path) >= CONFIG_MSG_PATH_LENGTH) {
305 "Maximum length for path exceeded");
309 "client connection is not alive");
319 e.
append(
"NetworkConfiguration[mirroring]::get_uint: exception in mirror database");
325 send_get(path, MSG_CONFIG_GET_UINT, MSG_CONFIG_UINT_VALUE);
331 throw Exception(
"NetworkConfiguration: received list of and not a single value");
339 e.
append(
"NetworkConfiguration::get_uint: Fetching unsigned int failed");
357 if (strlen(path) >= CONFIG_MSG_PATH_LENGTH) {
359 "Maximum length for path exceeded");
363 "client connection is not alive");
371 i = mirror_config->
get_int(path);
373 e.
append(
"NetworkConfiguration[mirroring]::get_int: exception in mirror database");
379 send_get(path, MSG_CONFIG_GET_INT, MSG_CONFIG_INT_VALUE);
385 throw Exception(
"NetworkConfiguration: received list of and not a single value");
393 e.
append(
"NetworkConfiguration::get_int: Fetching int failed");
411 if (strlen(path) >= CONFIG_MSG_PATH_LENGTH) {
413 "Maximum length for path exceeded");
417 "client connection is not alive");
427 e.
append(
"NetworkConfiguration[mirroring]::get_bool: exception in mirror database");
433 send_get(path, MSG_CONFIG_GET_BOOL, MSG_CONFIG_BOOL_VALUE);
439 throw Exception(
"NetworkConfiguration: received list of and not a single value");
447 e.
append(
"NetworkConfiguration::get_bool: Fetching bool failed");
465 if (strlen(path) >= CONFIG_MSG_PATH_LENGTH) {
467 "Maximum length for path exceeded");
471 "client connection is not alive");
481 e.
append(
"NetworkConfiguration[mirroring]::get_string: exception in mirror database");
487 send_get(path, MSG_CONFIG_GET_STRING, MSG_CONFIG_STRING_VALUE);
493 throw Exception(
"NetworkConfiguration: received list of and not a single value");
503 e.
append(
"NetworkConfiguration::get_string: Fetching string failed");
524 std::vector<unsigned int>
542 std::vector<std::string>
551 if (strlen(path) >= CONFIG_MSG_PATH_LENGTH) {
553 "Maximum length for path exceeded");
557 "client connection is not alive");
567 e.
append(
"NetworkConfiguration[mirroring]::get_comment: exception in mirror database");
573 send_get(path, MSG_CONFIG_GET_COMMENT, MSG_CONFIG_COMMENT_VALUE);
582 e.
append(
"NetworkConfiguration::get_comment: Fetching int failed");
600 if (strlen(path) >= CONFIG_MSG_PATH_LENGTH) {
602 "Maximum length for path exceeded");
606 "client connection is not alive");
616 e.
append(
"NetworkConfiguration[mirroring]::get_default_comment: "
617 "exception in mirror database");
623 send_get(path, MSG_CONFIG_GET_DEFAULT_COMMENT, MSG_CONFIG_COMMENT_VALUE);
632 e.
append(
"NetworkConfiguration::get_comment: Fetching int failed");
650 if (strlen(path) >= CONFIG_MSG_PATH_LENGTH) {
652 "Maximum length for path exceeded");
656 "client connection is not alive");
666 e.
append(
"NetworkConfiguration[mirroring]::get_float: exception in mirror database");
672 strncpy(g->
cp.
path, path, CONFIG_MSG_PATH_LENGTH - 1);
674 MSG_CONFIG_GET_VALUE,
696 NetworkConfiguration::set_value_internal(
unsigned int msg_type,
702 if (strlen(path) >= CONFIG_MSG_PATH_LENGTH) {
704 "Maximum length for path exceeded");
707 throw ConnectionDiedException(
"NetworkConfiguration: Cannot set value, "
708 "client connection is not alive");
712 size_t msg_size =
sizeof(config_descriptor_t) + data_size;
713 FawkesNetworkMessage *omsg =
714 new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER, msg_type, msg_size);
715 config_descriptor_t *cd = omsg->msgge<config_descriptor_t>();
716 strncpy(cd->path, path, CONFIG_MSG_PATH_LENGTH - 1);
717 cd->num_values = num_values;
719 void *mdata = ((
char *)omsg->payload() +
sizeof(config_descriptor_t));
720 memcpy(mdata, data, data_size);
723 if (!mirror_mode_ && (msg != NULL)) {
733 set_value_internal(MSG_CONFIG_SET_FLOAT, path, 0,
sizeof(
float), &f);
739 set_value_internal(MSG_CONFIG_SET_DEFAULT_FLOAT, path, 0,
sizeof(
float), &f);
745 set_value_internal(MSG_CONFIG_SET_UINT, path, 0,
sizeof(uint32_t), &uint);
751 set_value_internal(MSG_CONFIG_SET_DEFAULT_UINT, path, 0,
sizeof(uint32_t), &uint);
757 set_value_internal(MSG_CONFIG_SET_INT, path, 0,
sizeof(int32_t), &i);
763 set_value_internal(MSG_CONFIG_SET_DEFAULT_INT, path, 0,
sizeof(int32_t), &i);
769 int32_t bs[1] = {b ? 1 : 0};
770 set_value_internal(MSG_CONFIG_SET_BOOL, path, 0,
sizeof(int32_t), bs);
776 int32_t bs[1] = {b ? 1 : 0};
777 set_value_internal(MSG_CONFIG_SET_DEFAULT_BOOL, path, 0,
sizeof(int32_t), bs);
783 size_t s_length = strlen(s);
785 void * data = malloc(data_size);
786 memset(data, 0, data_size);
791 set_value_internal(MSG_CONFIG_SET_STRING, path, 0, data_size, data);
798 size_t s_length = strlen(s);
800 void * data = malloc(data_size);
801 memset(data, 0, data_size);
805 set_value_internal(MSG_CONFIG_SET_DEFAULT_STRING, path, 0, data_size, data);
878 NetworkConfiguration::erase_internal(
const char *path,
bool is_default)
880 if (strlen(path) >= CONFIG_MSG_PATH_LENGTH) {
882 "Maximum length for path exceeded");
885 throw ConnectionDiedException(
"NetworkConfiguration: Cannot set value, "
886 "client connection is not alive");
890 FawkesNetworkMessage * omsg =
new FawkesNetworkMessage(FAWKES_CID_CONFIGMANAGER,
891 MSG_CONFIG_ERASE_VALUE,
892 sizeof(config_erase_value_msg_t));
893 config_erase_value_msg_t *m = omsg->msg<config_erase_value_msg_t>();
895 strncpy(m->cp.path, path, CONFIG_MSG_PATH_LENGTH - 1);
897 if (!mirror_mode_ && (msg != NULL)) {
907 erase_internal(path,
false);
913 erase_internal(path,
true);
928 if (m->cid() == FAWKES_CID_CONFIGMANAGER) {
930 switch (m->msgid()) {
931 case MSG_CONFIG_LIST:
940 case MSG_CONFIG_FLOAT_VALUE: {
944 for (
volatile unsigned int j = 0; j < cle->
cp.
num_values; ++j) {
945 values[j] = msg_values[j];
947 mirror_config->set_floats(cle->
cp.
path, values);
950 mirror_config->set_default_float(cle->
cp.
path, *msg_values);
952 mirror_config->set_float(cle->
cp.
path, *msg_values);
957 case MSG_CONFIG_INT_VALUE: {
961 for (
volatile unsigned int j = 0; j < cle->
cp.
num_values; ++j) {
962 values[j] = msg_values[j];
964 mirror_config->set_ints(cle->
cp.
path, values);
967 mirror_config->set_default_int(cle->
cp.
path, *msg_values);
969 mirror_config->set_int(cle->
cp.
path, *msg_values);
974 case MSG_CONFIG_UINT_VALUE: {
975 uint32_t *msg_values =
979 for (
volatile unsigned int j = 0; j < cle->
cp.
num_values; ++j) {
980 values[j] = msg_values[j];
982 mirror_config->set_uints(cle->
cp.
path, values);
985 mirror_config->set_default_uint(cle->
cp.
path, *msg_values);
987 mirror_config->set_uint(cle->
cp.
path, *msg_values);
992 case MSG_CONFIG_BOOL_VALUE: {
996 for (
volatile unsigned int j = 0; j < cle->
cp.
num_values; ++j) {
997 values[j] = (msg_values[j] != 0);
999 mirror_config->set_bools(cle->
cp.
path, values);
1002 mirror_config->set_default_bool(cle->
cp.
path, (*msg_values != 0));
1004 mirror_config->set_bool(cle->
cp.
path, (*msg_values != 0));
1009 case MSG_CONFIG_STRING_VALUE: {
1012 std::vector<std::string> values(cle->
cp.
num_values,
"");
1013 for (
volatile unsigned int j = 0; j < cle->
cp.
num_values; ++j) {
1016 values[j] = std::string(msg_string, csv->
s_length);
1019 mirror_config->set_strings(cle->
cp.
path, values);
1024 mirror_config->set_default_string(cle->
cp.
path,
1025 std::string(msg_string, csv->
s_length).c_str());
1027 mirror_config->set_string(cle->
cp.
path,
1028 std::string(msg_string, csv->
s_length).c_str());
1033 case MSG_CONFIG_COMMENT_VALUE:
1043 for (ChangeHandlerMultimap::const_iterator j = _change_handlers.begin();
1044 j != _change_handlers.end();
1046 _ch_range = _change_handlers.equal_range((*j).first);
1047 for (ChangeHandlerMultimap::const_iterator i = _ch_range.first; i != _ch_range.second;
1049 mirror_config->add_change_handler((*i).second);
1053 if (mirror_init_waiting_) {
1054 mirror_init_barrier_->wait();
1058 case MSG_CONFIG_VALUE_ERASED:
1062 mirror_config->erase_default(em->
cp.
path);
1064 mirror_config->erase(em->
cp.
path);
1069 "[mirroring]::inboundReceived: erasing failed");
1073 case MSG_CONFIG_FLOAT_VALUE:
1078 std::vector<float> floats(cd->
num_values, 0.0);
1079 for (
unsigned int i = 0; i < cd->
num_values; ++i) {
1082 mirror_config->set_floats(cd->
path, floats);
1086 mirror_config->set_default_float(cd->
path, f);
1088 mirror_config->set_float(cd->
path, f);
1094 "[mirroring]::inboundReceived: invalid float received");
1098 case MSG_CONFIG_UINT_VALUE:
1103 std::vector<unsigned int> values(cd->
num_values, 0);
1104 for (
unsigned int i = 0; i < cd->
num_values; ++i) {
1107 mirror_config->set_uints(cd->
path, values);
1112 mirror_config->set_default_uint(cd->
path, u);
1114 mirror_config->set_uint(cd->
path, u);
1120 "[mirroring]::inboundReceived: invalid uint received");
1124 case MSG_CONFIG_INT_VALUE:
1130 for (
unsigned int i = 0; i < cd->
num_values; ++i) {
1133 mirror_config->set_ints(cd->
path, values);
1138 mirror_config->set_default_int(cd->
path, i);
1140 mirror_config->set_int(cd->
path, i);
1146 "[mirroring]::inboundReceived: invalid int received");
1150 case MSG_CONFIG_BOOL_VALUE:
1156 for (
unsigned int i = 0; i < cd->
num_values; ++i) {
1157 values[i] = (vs[i] != 0);
1159 mirror_config->set_bools(cd->
path, values);
1164 mirror_config->set_default_bool(cd->
path, (i != 0));
1166 mirror_config->set_bool(cd->
path, (i != 0));
1172 "[mirroring]::inboundReceived: invalid bool received");
1176 case MSG_CONFIG_STRING_VALUE:
1180 std::vector<std::string> values(cd->
num_values,
"");
1182 for (
unsigned int i = 0; i < cd->
num_values; ++i) {
1185 values[i] = std::string(msg_string, vs->
s_length);
1188 mirror_config->set_strings(cd->
path, values);
1194 std::string value = std::string(msg_string, sv->
s_length);
1196 mirror_config->set_default_string(cd->
path, value);
1198 mirror_config->set_string(cd->
path, value);
1204 "[mirroring]::inboundReceived: invalid string received");
1208 case MSG_CONFIG_COMMENT_VALUE:
1212 mirror_config->set_default_comment(cm->
cp.
path, cm->
s);
1214 mirror_config->set_comment(cm->
cp.
path, cm->
s);
1219 "[mirroring]::inboundReceived: invalid string received");
1234 mirror_mode_before_connection_dead_ = mirror_mode_;
1235 set_mirror_mode(
false);
1243 set_mirror_mode(mirror_mode_before_connection_dead_);
1272 if (!mirror_mode_) {
1279 mirror_init_waiting_ =
true;
1282 mirror_mode_ =
true;
1290 if (!mirror_init_barrier_->
wait(mirror_timeout_sec_, 0)) {
1292 mirror_init_waiting_ =
false;
1293 delete mirror_config;
1297 mirror_init_waiting_ =
false;
1302 mirror_mode_ =
false;
1311 delete mirror_config;
1345 throw Exception(
"NetworkConfiguration: Iterating only supported in mirror mode");
1362 throw Exception(
"NetworkConfiguration: Iterating only supported in mirror mode");
1379 throw Exception(
"NetworkConfiguration: Iterating only supported in mirror mode");
1387 return mirror_config->
search(path);
1389 throw Exception(
"NetworkConfiguration: Searching only supported in mirror mode");
1404 iterated_once =
false;
1416 iterated_once =
false;
1430 iterated_once =
false;
1433 if ((m->
cid() == FAWKES_CID_CONFIGMANAGER) && (m->
msgid() >= MSG_CONFIG_VALUE_BEGIN)
1434 && (m->
msgid() <= MSG_CONFIG_VALUE_END)
1440 _path = (
char *)malloc(CONFIG_MSG_PATH_LENGTH + 1);
1441 _path[CONFIG_MSG_PATH_LENGTH] = 0;
1443 strncpy(_path, cd->
path, CONFIG_MSG_PATH_LENGTH);
1463 if ((msg == NULL) || iterated_once) {
1466 iterated_once =
true;
1477 return ((i != NULL) || (msg != NULL));
1502 switch (msg->
msgid()) {
1503 case MSG_CONFIG_FLOAT_VALUE:
return "float";
1504 case MSG_CONFIG_UINT_VALUE:
return "unsigned int";
1505 case MSG_CONFIG_INT_VALUE:
return "int";
1506 case MSG_CONFIG_BOOL_VALUE:
return "bool";
1507 case MSG_CONFIG_STRING_VALUE:
return "string";
1522 return (msg->
msgid() == MSG_CONFIG_FLOAT_VALUE);
1524 return i->is_float();
1535 return (msg->
msgid() == MSG_CONFIG_UINT_VALUE);
1537 return i->is_float();
1548 return (msg->
msgid() == MSG_CONFIG_INT_VALUE);
1561 return (msg->
msgid() == MSG_CONFIG_BOOL_VALUE);
1563 return i->is_bool();
1574 return (msg->
msgid() == MSG_CONFIG_STRING_VALUE);
1576 return i->is_string();
1590 return i->is_list();
1604 return i->get_list_size();
1615 unsigned int msgid = msg->
msgid();
1617 case MSG_CONFIG_FLOAT_VALUE:
1618 case MSG_CONFIG_UINT_VALUE:
1619 case MSG_CONFIG_INT_VALUE:
1620 case MSG_CONFIG_BOOL_VALUE:
1621 case MSG_CONFIG_STRING_VALUE: {
1628 "iterator to value message");
1631 return i->is_default();
1642 if (msg->
msgid() == MSG_CONFIG_FLOAT_VALUE) {
1652 return i->get_float();
1663 if (msg->
msgid() == MSG_CONFIG_UINT_VALUE) {
1673 return i->get_int();
1684 if (msg->
msgid() == MSG_CONFIG_INT_VALUE) {
1694 return i->get_int();
1705 if (msg->
msgid() == MSG_CONFIG_BOOL_VALUE) {
1715 return i->get_bool();
1726 if (msg->
msgid() == MSG_CONFIG_STRING_VALUE) {
1735 return std::string(msg_string, sv->
s_length);
1738 "NetConfValueIterator::get_string: type mismatch, expected %u, got %u",
1739 MSG_CONFIG_STRING_VALUE,
1743 return i->get_string();
1754 if (msg->
msgid() == MSG_CONFIG_FLOAT_VALUE) {
1762 for (
unsigned int j = 0; j < cd->
num_values; ++j) {
1768 "NetConfValueIterator::get_string: type mismatch, expected %u, got %u",
1769 MSG_CONFIG_STRING_VALUE,
1773 return i->get_floats();
1777 std::vector<unsigned int>
1784 if (msg->
msgid() == MSG_CONFIG_UINT_VALUE) {
1790 std::vector<unsigned int> rv(cd->
num_values, 0);
1792 for (
unsigned int j = 0; j < cd->
num_values; ++j) {
1798 "NetConfValueIterator::get_string: type mismatch, expected %u, got %u",
1799 MSG_CONFIG_STRING_VALUE,
1803 return i->get_uints();
1814 if (msg->
msgid() == MSG_CONFIG_INT_VALUE) {
1822 for (
unsigned int j = 0; j < cd->
num_values; ++j) {
1828 "NetConfValueIterator::get_string: type mismatch, expected %u, got %u",
1829 MSG_CONFIG_STRING_VALUE,
1833 return i->get_ints();
1844 if (msg->
msgid() == MSG_CONFIG_INT_VALUE) {
1852 for (
unsigned int j = 0; j < cd->
num_values; ++j) {
1853 rv[j] = (data[j] != 0);
1858 "NetConfValueIterator::get_string: type mismatch, expected %u, got %u",
1859 MSG_CONFIG_STRING_VALUE,
1863 return i->get_bools();
1867 std::vector<std::string>
1874 if (msg->
msgid() == MSG_CONFIG_STRING_VALUE) {
1879 std::vector<std::string> rv(cd->
num_values,
"");
1882 for (
unsigned int j = 0; j < cd->
num_values; ++j) {
1885 rv[j] = std::string(msg_string, sv->
s_length);
1891 "NetConfValueIterator::get_string: type mismatch, expected %u, got %u",
1892 MSG_CONFIG_STRING_VALUE,
1896 return i->get_strings();
1906 "invalid iterator");
1908 if (msg->
msgid() == MSG_CONFIG_STRING_VALUE) {
1910 }
else if (msg->
msgid() == MSG_CONFIG_BOOL_VALUE) {
1911 return get_bool() ?
"true" :
"false";
1912 }
else if (msg->
msgid() == MSG_CONFIG_INT_VALUE) {
1914 }
else if (msg->
msgid() == MSG_CONFIG_UINT_VALUE) {
1916 }
else if (msg->
msgid() == MSG_CONFIG_FLOAT_VALUE) {
1919 throw Exception(
"NetConfValueIterator::get_as_string: unknown type");
1922 return i->get_as_string();
1933 if (msg->
msgid() == MSG_CONFIG_COMMENT_VALUE) {
1940 return i->get_comment();