24 #include <config/net_handler.h>
25 #include <config/net_messages.h>
26 #include <config/net_list_content.h>
27 #include <logging/liblogger.h>
29 #include <netcomm/fawkes/component_ids.h>
30 #include <netcomm/fawkes/hub.h>
31 #include <config/config.h>
54 :
Thread(
"ConfigNetworkHandler",
Thread::OPMODE_WAITFORWAKEUP),
74 __inbound_queue.
clear();
83 ConfigNetworkHandler::send_inv_value(
unsigned int clid,
const char *path)
95 ConfigNetworkHandler::send_value(
unsigned int clid, Configuration::ValueIterator *i)
97 if ( i->is_float() ) {
99 config_float_value_msg_t *r = prepare_msg<config_float_value_msg_t>(i->path(), i->is_default());
100 r->f = i->get_float();
101 __hub->
send(clid, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_FLOAT_VALUE, r,
sizeof(config_float_value_msg_t));
102 }
catch (Exception &e) {
104 "send_value: Value %s could not be sent",
108 }
else if ( i->is_uint() ) {
110 config_uint_value_msg_t *r = prepare_msg<config_uint_value_msg_t>(i->path(), i->is_default());
111 r->u = i->get_uint();
112 __hub->
send(clid, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_UINT_VALUE, r,
sizeof(config_uint_value_msg_t));
113 }
catch (Exception &e) {
115 "send_value: Value %s could not be sent",
119 }
else if ( i->is_int() ) {
121 config_int_value_msg_t *r = prepare_msg<config_int_value_msg_t>(i->path(), i->is_default());
123 __hub->
send(clid, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_INT_VALUE, r,
sizeof(config_int_value_msg_t));
124 }
catch (Exception &e) {
126 "send_value: Value %s could not be sent",
130 }
else if ( i->is_bool() ) {
132 config_bool_value_msg_t *r = prepare_msg<config_bool_value_msg_t>(i->path(), i->is_default());
133 r->b = (i->get_bool() ? 1 : 0);
134 __hub->
send(clid, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_BOOL_VALUE, r,
sizeof(config_bool_value_msg_t));
135 }
catch (Exception &e) {
137 "send_value: Value %s could not be sent",
141 }
else if ( i->is_string() ) {
143 size_t sl =
sizeof(config_string_value_msg_t) + i->get_string().length();
144 config_string_value_msg_t *m = (config_string_value_msg_t *)calloc(1, sl);
145 strncpy(m->cp.path, i->path(), CONFIG_MSG_PATH_LENGTH);
146 m->cp.is_default = i->is_default() ? 1 : 0;
147 m->s_length = i->get_string().length();
148 strcpy(m->s, i->get_string().c_str());
149 __hub->
send(clid, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_STRING_VALUE, m, sl);
150 }
catch (Exception &e) {
152 "send_value: Value %s could not be sent",
164 while ( ! __inbound_queue.empty() ) {
169 if (msg->
msgid() == MSG_CONFIG_SUBSCRIBE) {
172 __subscribers.sort();
173 __subscribers.unique();
178 while ( i->
next() ) {
183 while ( i->
next() ) {
187 __hub->
send(msg->
clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_LIST, content);
190 }
else if (msg->
msgid() == MSG_CONFIG_ERASE_VALUE) {
193 char path[CONFIG_MSG_PATH_LENGTH + 1];
194 path[CONFIG_MSG_PATH_LENGTH] = 0;
195 strncpy(path, m->
cp.
path, CONFIG_MSG_PATH_LENGTH);
200 __config->
erase(path);
204 __hub->
send(msg->
clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_VALUE_ERASED,
208 send_inv_value(msg->
clid(),
"?");
209 e.
append(
"Failed to erase value");
214 }
else if ( (msg->
msgid() >= MSG_CONFIG_GET_BEGIN) &&
215 (msg->
msgid() <= MSG_CONFIG_GET_END) ) {
219 "CONFIG_GET_FLOAT: invalid payload size "
220 "(received %zu instead of %zu bytes",
224 char path[CONFIG_MSG_PATH_LENGTH + 1];
225 path[CONFIG_MSG_PATH_LENGTH] = 0;
226 strncpy(path, m->
cp.
path, CONFIG_MSG_PATH_LENGTH);
228 switch (msg->
msgid()) {
229 case MSG_CONFIG_GET_FLOAT:
235 __hub->
send(msg->
clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_FLOAT_VALUE,
238 send_inv_value(msg->
clid(), path);
240 "get float: Value %s could not be found", path);
245 case MSG_CONFIG_GET_UINT:
247 unsigned int u = __config->
get_uint(path);
251 __hub->
send(msg->
clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_UINT_VALUE,
254 send_inv_value(msg->
clid(), path);
256 "get uint: Value %s could not be found", path);
261 case MSG_CONFIG_GET_INT:
263 int i = __config->
get_int(path);
267 __hub->
send(msg->
clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_INT_VALUE,
270 send_inv_value(msg->
clid(), path);
272 "get int: Value %s could not be found", path);
277 case MSG_CONFIG_GET_BOOL:
283 __hub->
send(msg->
clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_BOOL_VALUE,
286 send_inv_value(msg->
clid(), path);
288 "get bool: Value %s could not be found", path);
293 case MSG_CONFIG_GET_STRING:
298 strcpy(r->
s, s.c_str());
299 __hub->
send(msg->
clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_STRING_VALUE,
302 send_inv_value(msg->
clid(), path);
304 "get string: Value %s could not be found", path);
309 case MSG_CONFIG_GET_VALUE:
313 send_value(msg->
clid(), i);
315 send_inv_value(msg->
clid(), path);
320 "get value: Value %s could not be found", path);
327 }
else if ( (msg->
msgid() >= MSG_CONFIG_SET_BEGIN) &&
328 (msg->
msgid() <= MSG_CONFIG_SET_END) ) {
330 char path[CONFIG_MSG_PATH_LENGTH + 1];
333 "inbound set: payload is too small"
334 "(%zu is less than %zu bytes",
336 send_inv_value(msg->
clid(),
"?");
339 path[CONFIG_MSG_PATH_LENGTH] = 0;
340 strncpy(path, d->
path, CONFIG_MSG_PATH_LENGTH);
342 switch (msg->
msgid()) {
343 case MSG_CONFIG_SET_FLOAT:
344 case MSG_CONFIG_SET_DEFAULT_FLOAT:
347 if ( msg->
msgid() == MSG_CONFIG_SET_FLOAT ) {
355 __hub->
send(msg->
clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_FLOAT_VALUE,
358 send_inv_value(msg->
clid(), path);
360 "set float: Value %s could not be set", path);
365 case MSG_CONFIG_SET_UINT:
366 case MSG_CONFIG_SET_DEFAULT_UINT:
369 if ( msg->
msgid() == MSG_CONFIG_SET_UINT ) {
374 unsigned int u = __config->
get_uint(path);
377 __hub->
send(msg->
clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_UINT_VALUE,
380 send_inv_value(msg->
clid(), path);
382 "set uint: Value %s could not be set", path);
387 case MSG_CONFIG_SET_INT:
388 case MSG_CONFIG_SET_DEFAULT_INT:
391 if ( msg->
msgid() == MSG_CONFIG_SET_INT ) {
396 int i = __config->
get_int(path);
399 __hub->
send(msg->
clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_INT_VALUE,
402 send_inv_value(msg->
clid(), path);
404 "set int: Value %s could not be set", path);
409 case MSG_CONFIG_SET_BOOL:
410 case MSG_CONFIG_SET_DEFAULT_BOOL:
413 if ( msg->
msgid() == MSG_CONFIG_SET_BOOL ) {
421 __hub->
send(msg->
clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_BOOL_VALUE,
424 send_inv_value(msg->
clid(), path);
426 "set bool: Value %s could not be set", path);
431 case MSG_CONFIG_SET_STRING:
432 case MSG_CONFIG_SET_DEFAULT_STRING:
435 if ( msg->
msgid() == MSG_CONFIG_SET_STRING ) {
441 size_t s_length = s.length();
443 strcpy(r->
s, s.c_str());
444 __hub->
send(msg->
clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_STRING_VALUE,
447 send_inv_value(msg->
clid(), path);
449 "set string: Value %s could not be set", path);
454 case MSG_CONFIG_SET_COMMENT:
455 case MSG_CONFIG_SET_DEFAULT_COMMENT:
459 if ( msg->
msgid() == MSG_CONFIG_SET_COMMENT ) {
466 size_t s_length = s.length();
467 config_comment_msg_t *r = prepare_string_msg<config_comment_msg_t>(path, (msg->
msgid() == MSG_CONFIG_SET_DEFAULT_COMMENT), s_length);
468 strcpy(r->
s, s.c_str());
469 __hub->
send(msg->
clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_COMMENT_VALUE,
472 send_inv_value(msg->
clid(), path);
474 "set comment: Value %s could not be set", path);
520 __subscribers.
lock();
521 if (find(__subscribers.begin(), __subscribers.end(), clid) != __subscribers.end()) {
523 "Client %u disconnected without closing the config, removing from list of subscribers",
525 __subscribers.remove(clid);
544 const char *path = v->
path();
547 __subscribers.
lock();
548 for (__sit = __subscribers.begin(); __sit != __subscribers.end(); ++__sit) {
552 size_t s_length = value.length();
554 prepare_string_msg<config_string_value_msg_t>(path, is_default,
556 strcpy(r->
s, value.c_str());
557 __hub->
send(*__sit, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_STRING_VALUE,
562 prepare_msg<config_bool_value_msg_t>(path, is_default);
563 r->
b = (value ? 1 : 0);
564 __hub->
send(*__sit, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_BOOL_VALUE,
569 prepare_msg<config_int_value_msg_t>(path, is_default);
571 __hub->
send(*__sit, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_INT_VALUE,
576 prepare_msg<config_uint_value_msg_t>(path, is_default);
578 __hub->
send(*__sit, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_UINT_VALUE,
583 prepare_msg<config_float_value_msg_t>(path, is_default);
585 __hub->
send(*__sit, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_FLOAT_VALUE,
591 "config_value_changed: Value for %s could not be sent "
592 "to client %u", path, *__sit);
603 const char *path = v->
path();
606 __subscribers.
lock();
607 for (__sit = __subscribers.begin(); __sit != __subscribers.end(); ++__sit) {
609 size_t s_length = comment.length();
611 prepare_string_msg<config_comment_msg_t>(path, is_default, s_length);
612 strcpy(r->
s, comment.c_str());
614 __hub->
send(*__sit, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_COMMENT_VALUE,
618 "config_comment_changed[string]: Value for %s could "
619 "not be sent to client %u", path, *__sit);
630 __subscribers.
lock();
631 for (__sit = __subscribers.begin(); __sit != __subscribers.end(); ++__sit) {
634 prepare_msg<config_value_erased_msg_t>(path,
false);
635 __hub->
send(*__sit, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_VALUE_ERASED,
639 "configValueErased: Value for %s could not be sent "
640 "to client %u", path, *__sit);
virtual bool is_float() const =0
Check if current value is a float.
virtual std::string get_default_comment(const char *path)=0
Get comment of value at given path.
uint32_t is_default
1 if value is a default value, 0 otherwise, only for get response
void clear()
Clear the queue.
virtual void set_default_float(const char *path, float f)=0
Set new default value in configuration of type float.
virtual void set_default_int(const char *path, int i)=0
Set new default value in configuration of type int.
void unref()
Decrement reference count and conditionally delete this instance.
void append(Configuration::ValueIterator *i)
Append from iterator.
virtual void set_default_comment(const char *path, const char *comment)=0
Set new default comment for existing default configuration value.
virtual bool is_bool() const =0
Check if current value is a bool.
virtual bool is_default(const char *path)=0
Check if a value was read from the default config.
Fawkes library namespace.
virtual bool get_bool(const char *path)=0
Get value from configuration which is of type bool.
virtual void config_value_changed(const Configuration::ValueIterator *v)
Called whenever a watched value has changed.
virtual void unlock() const
Unlock list.
void * payload() const
Get payload buffer.
config_descriptor_t cp
value descriptor
~ConfigNetworkHandler()
Destructor.
virtual void add_handler(FawkesNetworkHandler *handler)=0
Add a message handler.
Interface for configuration change handling.
char path[CONFIG_MSG_PATH_LENGTH]
path to config value.
virtual void handle_network_message(FawkesNetworkMessage *msg)
Handle network message.
virtual std::string get_string() const =0
Get string value.
virtual void config_value_erased(const char *path)
Called whenever a value has been erased from the config.
Representation of a message that is sent over the network.
virtual bool is_string() const =0
Check if current value is a string.
virtual bool is_uint() const =0
Check if current value is a unsigned int.
unsigned short int msgid() const
Get message type ID.
virtual bool next()=0
Check if there is another element and advance to this if possible.
virtual void set_int(const char *path, int i)=0
Set new value in configuration of type int.
virtual float get_float() const =0
Get float value.
Thread class encapsulation of pthreads.
virtual void lock() const
Lock list.
virtual ValueIterator * iterator_hostspecific()=0
Iterator for all host-specific values.
virtual const char * path() const =0
Path of value.
virtual int get_int(const char *path)=0
Get value from configuration which is of type int.
void push_back_locked(const Type &x)
Push element to list at back with lock protection.
virtual void set_bool(const char *path, bool b)=0
Set new value in configuration of type bool.
virtual void set_float(const char *path, float f)=0
Set new value in configuration of type float.
virtual void loop()
Process all network messages that have been received.
virtual unsigned int get_uint() const =0
Get unsigned int value.
size_t payload_size() const
Get payload size.
ConfigNetworkHandler(Configuration *config, FawkesNetworkHub *hub)
Constructor.
char s[2]
string value, 0-terminated
MT * msgge() const
Get correctly casted payload.
void wakeup()
Wake up thread.
virtual void erase_default(const char *path)=0
Erase the given default value from the configuration.
virtual void erase(const char *path)=0
Erase the given value from the configuration.
virtual void set_default_bool(const char *path, bool b)=0
Set new default value in configuration of type bool.
Base class for exceptions in Fawkes.
virtual void send(FawkesNetworkMessage *msg)=0
Method to send a message to a specific client.
virtual void set_default_uint(const char *path, unsigned int uint)=0
Set new default value in configuration of type unsigned int.
virtual bool is_int() const =0
Check if current value is a int.
virtual std::string get_comment() const =0
Get comment of value.
virtual void rem_change_handler(ConfigurationChangeHandler *h)
Remove a configuration change handler.
void ref()
Increment reference count.
Unsigned int value message.
virtual bool get_bool() const =0
Get bool value.
Network handler abstract base class.
Generic configuration exception.
static void log_warn(const char *component, const char *format,...)
Log warning message.
virtual void client_disconnected(unsigned int clid)
Client disconnected.
void cancel()
Cancel a thread.
void pop_locked()
Pop element from queue with lock protection.
virtual void unlock()=0
Unlock the config.
virtual ValueIterator * iterator_default()=0
Iterator for all default values.
virtual void client_connected(unsigned int clid)
Client connected.
MT * msg() const
Get correctly casted payload.
Invalid value request message.
virtual ValueIterator * get_value(const char *path)=0
Get value from configuration.
void push_locked(const Type &x)
Push element to queue with lock protection.
Iterator interface to iterate over config values.
void join()
Join the thread.
virtual void add_change_handler(ConfigurationChangeHandler *h)
Add a configuration change handler.
config_descriptor_t cp
value descriptor
virtual unsigned int get_uint(const char *path)=0
Get value from configuration which is of type unsigned int.
virtual void set_default_string(const char *path, std::string &s)=0
Set new default value in configuration of type string.
virtual void config_comment_changed(const Configuration::ValueIterator *v)
Called whenever a comment of a watched value has changed.
virtual std::string get_comment(const char *path)=0
Get comment of value at given path.
Interface for configuration handling.
virtual void set_comment(const char *path, const char *comment)=0
Set new comment for existing value.
virtual float get_float(const char *path)=0
Get value from configuration which is of type float.
virtual bool is_default() const =0
Check if current value was read from the default config.
virtual void set_uint(const char *path, unsigned int uint)=0
Set new value in configuration of type unsigned int.
virtual void set_string(const char *path, std::string &s)=0
Set new value in configuration of type string.
void append(const char *format,...)
Append messages to the message list.
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
virtual void lock()=0
Lock the config.
unsigned int clid() const
Get client ID.
virtual void config_tag_changed(const char *new_location)
Tag changed.
void start(bool wait=true)
Call this method to start the thread.
virtual int get_int() const =0
Get int value.