FIXED: configuration's set_default_comment() tried to set non-default comment.
[fawkes.git] / src / libs / config / net_handler.cpp
1
2 /***************************************************************************
3  *  net_handler.cpp - Fawkes configuration network handler
4  *
5  *  Generated: Sat Jan 06 22:55:03 2007
6  *  Copyright  2006-2007  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 <config/net_handler.h>
25 #include <config/net_messages.h>
26 #include <config/net_list_content.h>
27 #include <utils/logging/liblogger.h>
28
29 #include <netcomm/fawkes/component_ids.h>
30 #include <netcomm/fawkes/hub.h>
31 #include <config/config.h>
32
33 #include <algorithm>
34 #include <cstring>
35
36 namespace fawkes {
37
38 /** @class ConfigNetworkHandler <config/net_handler.h>
39  * Fawkes Configuration Network Handler.
40  * It provides access to a given config via the network.
41  * This is mainly used to allow modification of config values over the network.
42  *
43  * @author Tim Niemueller
44  */
45
46 /** Constructor.
47  * @param config configuration, loaded and ready to be used for getting and
48  * setting values
49  * @param hub Fawkes network hub to use for receiving and sending network
50  * messages
51  */
52 ConfigNetworkHandler::ConfigNetworkHandler(Configuration *config,
53                                          FawkesNetworkHub *hub)
54   : Thread("ConfigNetworkHandler", Thread::OPMODE_WAITFORWAKEUP),
55     FawkesNetworkHandler(FAWKES_CID_CONFIGMANAGER),
56     ConfigurationChangeHandler()
57 {
58   __config = config;
59   __hub    = hub;
60
61   start();
62
63   __config->add_change_handler(this);
64   __hub->add_handler( this );
65 }
66
67
68 /** Destructor. */
69 ConfigNetworkHandler::~ConfigNetworkHandler()
70 {
71   cancel();
72   join();
73   __config->rem_change_handler(this);
74   __inbound_queue.clear();
75 }
76
77
78 /** Send invalid value message.
79  * @param clid client ID
80  * @param path path
81  */
82 void
83 ConfigNetworkHandler::send_inv_value(unsigned int clid, const char *path)
84 {
85   config_invval_msg_t *r = prepare_msg<config_invval_msg_t>(path, false);
86   __hub->send(clid, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_INV_VALUE, r, sizeof(config_invval_msg_t));
87 }
88
89
90 /** Send value.
91  * @param clid client ID
92  * @param i value
93  */
94 void
95 ConfigNetworkHandler::send_value(unsigned int clid, Configuration::ValueIterator *i)
96 {
97   if ( i->is_float() ) {
98     try {
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) {
103       LibLogger::log_warn("ConfigNetworkHandler",
104                           "send_value: Value %s could not be sent",
105                           i->path());
106       LibLogger::log_warn("ConfigNetworkHandler", e);
107     }
108   } else if ( i->is_uint() ) {
109     try {
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) {
114       LibLogger::log_warn("ConfigNetworkHandler",
115                           "send_value: Value %s could not be sent",
116                           i->path());
117       LibLogger::log_warn("ConfigNetworkHandler", e);
118     }
119   } else if ( i->is_int() ) {
120     try {
121       config_int_value_msg_t *r = prepare_msg<config_int_value_msg_t>(i->path(), i->is_default());
122       r->i = i->get_int();
123       __hub->send(clid, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_INT_VALUE, r, sizeof(config_int_value_msg_t));
124     } catch (Exception &e) {
125       LibLogger::log_warn("ConfigNetworkHandler",
126                           "send_value: Value %s could not be sent",
127                           i->path());
128       LibLogger::log_warn("ConfigNetworkHandler", e);
129     }
130   } else if ( i->is_bool() ) {
131     try {
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) {
136       LibLogger::log_warn("ConfigNetworkHandler",
137                           "send_value: Value %s could not be sent",
138                           i->path());
139       LibLogger::log_warn("ConfigNetworkHandler", e);
140     }
141   } else if ( i->is_string() ) {
142     try {
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) {
151       LibLogger::log_warn("ConfigNetworkHandler",
152                           "send_value: Value %s could not be sent",
153                           i->path());
154       LibLogger::log_warn("ConfigNetworkHandler", e);
155     }
156   }
157 }
158
159
160 /** Process all network messages that have been received. */
161 void
162 ConfigNetworkHandler::loop()
163 {
164   while ( ! __inbound_queue.empty() ) {
165     FawkesNetworkMessage *msg = __inbound_queue.front();
166
167     // printf("Received message of type %u\n", msg->msgid());
168
169     if (msg->msgid() == MSG_CONFIG_SUBSCRIBE) {
170
171       __subscribers.push_back_locked(msg->clid());
172       __subscribers.sort();
173       __subscribers.unique();
174
175       __config->lock();
176       ConfigListContent *content = new ConfigListContent();
177       Configuration::ValueIterator *i = __config->iterator_default();
178       while ( i->next() ) {
179         content->append(i);
180       }
181       delete i;
182       i = __config->iterator_hostspecific();
183       while ( i->next() ) {
184         content->append(i);
185       }
186       delete i;
187       __hub->send(msg->clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_LIST, content);
188       __config->unlock();
189
190     } else if (msg->msgid() == MSG_CONFIG_ERASE_VALUE) {
191       try {
192         config_erase_value_msg_t *m = msg->msg<config_erase_value_msg_t>();
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);
196
197         if ( m->cp.is_default == 1 ) {
198           __config->erase_default(path);
199         } else {
200           __config->erase(path);
201         }
202
203         config_value_erased_msg_t *r = prepare_msg<config_value_erased_msg_t>(path, (m->cp.is_default == 1));
204         __hub->send(msg->clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_VALUE_ERASED,
205                     r, sizeof(config_value_erased_msg_t));
206
207       } catch (Exception &e) {
208         send_inv_value(msg->clid(), "?");
209         e.append("Failed to erase value");
210         LibLogger::log_warn("ConfigNetworkHandler", "Failed to erase value");
211         LibLogger::log_warn("ConfigNetworkHandler", e);
212       }
213
214     } else if ( (msg->msgid() >= MSG_CONFIG_GET_BEGIN) &&
215          (msg->msgid() <= MSG_CONFIG_GET_END) ) {
216
217       if ( msg->payload_size() != sizeof(config_getval_msg_t) ) {
218         LibLogger::log_warn("ConfigNetworkHandler",
219                             "CONFIG_GET_FLOAT: invalid payload size "
220                             "(received %zu instead of %zu bytes",
221                             msg->payload_size(), sizeof(config_getval_msg_t));
222       } else {
223         config_getval_msg_t *m = (config_getval_msg_t *)msg->payload();
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);
227
228         switch (msg->msgid()) {
229         case MSG_CONFIG_GET_FLOAT:
230           try {
231             float f = __config->get_float(path);
232             bool  d = __config->is_default(path);
233             config_float_value_msg_t *r = prepare_msg<config_float_value_msg_t>(path, d);
234             r->f = f;
235             __hub->send(msg->clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_FLOAT_VALUE,
236                       r, sizeof(config_float_value_msg_t));
237           } catch (Exception &e) {
238             send_inv_value(msg->clid(), path);
239             LibLogger::log_warn("ConfigNetworkHandler",
240                                 "get float: Value %s could not be found", path);
241             LibLogger::log_warn("ConfigNetworkHandler", e);
242           }
243           break;
244
245         case MSG_CONFIG_GET_UINT:
246           try {
247             unsigned int u = __config->get_uint(path);
248             bool  d = __config->is_default(path);
249             config_uint_value_msg_t *r = prepare_msg<config_uint_value_msg_t>(path, d);
250             r->u = u;
251             __hub->send(msg->clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_UINT_VALUE,
252                       r, sizeof(config_uint_value_msg_t));
253           } catch (Exception &e) {
254             send_inv_value(msg->clid(), path);
255             LibLogger::log_warn("ConfigNetworkHandler",
256                                 "get uint: Value %s could not be found", path);
257             LibLogger::log_warn("ConfigNetworkHandler", e);
258           }
259           break;
260
261         case MSG_CONFIG_GET_INT:
262           try {
263             int i = __config->get_int(path);
264             bool  d = __config->is_default(path);
265             config_int_value_msg_t *r = prepare_msg<config_int_value_msg_t>(path, d);
266             r->i = i;
267             __hub->send(msg->clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_INT_VALUE,
268                       r, sizeof(config_int_value_msg_t));
269           } catch (Exception &e) {
270             send_inv_value(msg->clid(), path);
271             LibLogger::log_warn("ConfigNetworkHandler",
272                                 "get int: Value %s could not be found", path);
273             LibLogger::log_warn("ConfigNetworkHandler", e);
274           }
275           break;
276
277         case MSG_CONFIG_GET_BOOL:
278           try {
279             bool b = __config->get_bool(path);
280             bool d = __config->is_default(path);
281             config_bool_value_msg_t *r = prepare_msg<config_bool_value_msg_t>(path, d);
282             r->b = b;
283             __hub->send(msg->clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_BOOL_VALUE,
284                       r, sizeof(config_bool_value_msg_t));
285           } catch (Exception &e) {
286             send_inv_value(msg->clid(), path);
287             LibLogger::log_warn("ConfigNetworkHandler",
288                                 "get bool: Value %s could not be found", path);
289             LibLogger::log_warn("ConfigNetworkHandler", e);
290           }
291           break;
292
293         case MSG_CONFIG_GET_STRING:
294           try {
295             std::string s = __config->get_string(path);
296             bool  d = __config->is_default(path);
297             config_string_value_msg_t *r = prepare_string_msg<config_string_value_msg_t>(path, d, s.length());
298             strcpy(r->s, s.c_str());
299             __hub->send(msg->clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_STRING_VALUE,
300                       r, sizeof(config_string_value_msg_t));
301           } catch (Exception &e) {
302             send_inv_value(msg->clid(), path);
303             LibLogger::log_warn("ConfigNetworkHandler",
304                                 "get string: Value %s could not be found", path);
305             LibLogger::log_warn("ConfigNetworkHandler", e);
306           }
307           break;
308
309         case MSG_CONFIG_GET_VALUE:
310           try {
311             Configuration::ValueIterator *i = __config->get_value(path);
312             if ( i->next() ) {
313               send_value(msg->clid(), i);
314             } else {
315               send_inv_value(msg->clid(), path);
316             }
317             delete i;
318           } catch (ConfigurationException &e) {
319             LibLogger::log_warn("ConfigNetworkHandler",
320                                 "get value: Value %s could not be found", path);
321             LibLogger::log_warn("ConfigNetworkHandler", e);
322           }
323           break;
324
325         }
326       }
327     } else if ( (msg->msgid() >= MSG_CONFIG_SET_BEGIN) &&
328                 (msg->msgid() <= MSG_CONFIG_SET_END) ) {
329       
330       char path[CONFIG_MSG_PATH_LENGTH + 1];
331       if ( msg->payload_size() < sizeof(config_descriptor_t)) {
332         LibLogger::log_warn("ConfigNetworkHandler",
333                             "inbound set: payload is too small"
334                             "(%zu is less than %zu bytes",
335                             msg->payload_size(), sizeof(config_descriptor_t));
336         send_inv_value(msg->clid(), "?");
337       } else {
338         config_descriptor_t *d = (config_descriptor_t *)msg->payload();
339         path[CONFIG_MSG_PATH_LENGTH] = 0;
340         strncpy(path, d->path, CONFIG_MSG_PATH_LENGTH);
341
342         switch (msg->msgid()) {
343         case MSG_CONFIG_SET_FLOAT:
344         case MSG_CONFIG_SET_DEFAULT_FLOAT:
345           try {
346             config_float_value_msg_t *m = msg->msg<config_float_value_msg_t>();
347             if ( msg->msgid() == MSG_CONFIG_SET_FLOAT ) {
348               __config->set_float(path, m->f);
349             } else {
350               __config->set_default_float(path, m->f);
351             }
352             float f = __config->get_float(path);
353             config_float_value_msg_t *r = prepare_msg<config_float_value_msg_t>(path, (msg->msgid() == MSG_CONFIG_SET_DEFAULT_FLOAT));
354             r->f = f;
355             __hub->send(msg->clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_FLOAT_VALUE,
356                       r, sizeof(config_float_value_msg_t));
357           } catch (Exception &e) {
358             send_inv_value(msg->clid(), path);
359             LibLogger::log_warn("ConfigNetworkHandler",
360                                 "set float: Value %s could not be set", path);
361             LibLogger::log_warn("ConfigNetworkHandler", e);
362           }
363           break;
364         
365         case MSG_CONFIG_SET_UINT:
366         case MSG_CONFIG_SET_DEFAULT_UINT:
367           try {
368             config_uint_value_msg_t *m = msg->msg<config_uint_value_msg_t>();
369             if ( msg->msgid() == MSG_CONFIG_SET_UINT ) {
370               __config->set_uint(path, m->u);
371             } else {
372               __config->set_default_uint(path, m->u);
373             }
374             unsigned int u = __config->get_uint(path);
375             config_uint_value_msg_t *r = prepare_msg<config_uint_value_msg_t>(path, (msg->msgid() == MSG_CONFIG_SET_DEFAULT_UINT));
376             r->u = u;
377             __hub->send(msg->clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_UINT_VALUE,
378                       r, sizeof(config_uint_value_msg_t));
379           } catch (Exception &e) {
380             send_inv_value(msg->clid(), path);
381             LibLogger::log_warn("ConfigNetworkHandler",
382                                 "set uint: Value %s could not be set", path);
383             LibLogger::log_warn("ConfigNetworkHandler", e);
384           }
385           break;
386         
387         case MSG_CONFIG_SET_INT:
388         case MSG_CONFIG_SET_DEFAULT_INT:
389           try {
390             config_int_value_msg_t *m = msg->msg<config_int_value_msg_t>();
391             if ( msg->msgid() == MSG_CONFIG_SET_INT ) {
392               __config->set_int(path, m->i);
393             } else {
394               __config->set_default_int(path, m->i);
395             }
396             int i = __config->get_int(path);
397             config_int_value_msg_t *r = prepare_msg<config_int_value_msg_t>(path, (msg->msgid() == MSG_CONFIG_SET_DEFAULT_INT));
398             r->i = i;
399             __hub->send(msg->clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_INT_VALUE,
400                       r, sizeof(config_int_value_msg_t));
401           } catch (Exception &e) {
402             send_inv_value(msg->clid(), path);
403             LibLogger::log_warn("ConfigNetworkHandler",
404                                 "set int: Value %s could not be set", path);
405             LibLogger::log_warn("ConfigNetworkHandler", e);
406           }
407           break;
408         
409         case MSG_CONFIG_SET_BOOL:
410         case MSG_CONFIG_SET_DEFAULT_BOOL:
411           try {
412             config_bool_value_msg_t *m = msg->msg<config_bool_value_msg_t>();
413             if ( msg->msgid() == MSG_CONFIG_SET_BOOL ) {
414               __config->set_bool(path, (m->b != 0));
415             } else {
416               __config->set_default_bool(path, (m->b != 0));
417             }
418             bool b = __config->get_bool(path);
419             config_bool_value_msg_t *r = prepare_msg<config_bool_value_msg_t>(path, (msg->msgid() == MSG_CONFIG_SET_DEFAULT_BOOL));
420             r->b = (b ? 1 : 0);
421             __hub->send(msg->clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_BOOL_VALUE,
422                       r, sizeof(config_bool_value_msg_t));
423           } catch (Exception &e) {
424             send_inv_value(msg->clid(), path);
425             LibLogger::log_warn("ConfigNetworkHandler",
426                                 "set bool: Value %s could not be set", path);
427             LibLogger::log_warn("ConfigNetworkHandler", e);
428           }
429           break;
430         
431         case MSG_CONFIG_SET_STRING:
432         case MSG_CONFIG_SET_DEFAULT_STRING:
433           try {
434             config_string_value_msg_t *m = msg->msgge<config_string_value_msg_t>();
435             if ( msg->msgid() == MSG_CONFIG_SET_STRING ) {
436               __config->set_string(path, m->s);
437             } else {
438               __config->set_default_string(path, m->s);
439             }
440             std::string s = __config->get_string(path);
441             size_t s_length = s.length();
442             config_string_value_msg_t *r = prepare_string_msg<config_string_value_msg_t>(path, (msg->msgid() == MSG_CONFIG_SET_DEFAULT_STRING), s_length);
443             strcpy(r->s, s.c_str());
444             __hub->send(msg->clid(), FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_STRING_VALUE,
445                       r, sizeof(config_string_value_msg_t) + s_length);
446           } catch (Exception &e) {
447             send_inv_value(msg->clid(), path);
448             LibLogger::log_warn("ConfigNetworkHandler",
449                                 "set string: Value %s could not be set", path);
450             LibLogger::log_warn("ConfigNetworkHandler", e);
451           }
452           break;
453
454         case MSG_CONFIG_SET_COMMENT:
455         case MSG_CONFIG_SET_DEFAULT_COMMENT:
456           try {
457             config_comment_msg_t *m = msg->msgge<config_comment_msg_t>();
458             std::string s = "";
459             if ( msg->msgid() == MSG_CONFIG_SET_COMMENT ) {
460               __config->set_comment(path, m->s);
461               s = __config->get_comment(path);
462             } else {
463               __config->set_default_comment(path, m->s);
464               s = __config->get_default_comment(path);
465             }
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,
470                         r, sizeof(config_comment_msg_t) + s_length);
471           } catch (Exception &e) {
472             send_inv_value(msg->clid(), path);
473             LibLogger::log_warn("ConfigNetworkHandler",
474                                 "set comment: Value %s could not be set", path);
475             LibLogger::log_warn("ConfigNetworkHandler", e);
476           }
477           break;
478         
479         }
480       }
481     }
482
483
484     msg->unref();
485     __inbound_queue.pop_locked();
486   }
487 }
488
489
490 /** Handle network message.
491  * The message is put into the inbound queue and processed in processAfterLoop().
492  * @param msg message
493  */
494 void
495 ConfigNetworkHandler::handle_network_message(FawkesNetworkMessage *msg)
496 {
497   msg->ref();
498   __inbound_queue.push_locked(msg);
499   wakeup();
500 }
501
502
503 /** Client connected.
504  * Ignored.
505  * @param clid client ID
506  */
507 void
508 ConfigNetworkHandler::client_connected(unsigned int clid)
509 {
510 }
511
512
513 /** Client disconnected.
514  * If the client was a subscriber it is removed.
515  * @param clid client ID
516  */
517 void
518 ConfigNetworkHandler::client_disconnected(unsigned int clid)
519 {
520   __subscribers.lock();
521   if (find(__subscribers.begin(), __subscribers.end(), clid) != __subscribers.end()) {
522     LibLogger::log_warn("ConfigNetworkHandler",
523                         "Client %u disconnected without closing the config, removing from list of subscribers",
524                         clid);
525     __subscribers.remove(clid);
526   }
527   __subscribers.unlock();
528 }
529
530
531 /** Tag changed.
532  * Ignored.
533  * @param new_tag new tag
534  */
535 void
536 ConfigNetworkHandler::config_tag_changed(const char *new_tag)
537 {
538 }
539
540
541 void
542 ConfigNetworkHandler::config_value_changed(const char *path, bool is_default, int value)
543 {
544   __subscribers.lock();
545   for (__sit = __subscribers.begin(); __sit != __subscribers.end(); ++__sit) {
546     try {
547       config_int_value_msg_t *r = prepare_msg<config_int_value_msg_t>(path, is_default);
548       r->i = value;
549       __hub->send(*__sit, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_INT_VALUE,
550                   r, sizeof(config_int_value_msg_t));
551     } catch (Exception &e) {
552       LibLogger::log_warn("ConfigNetworkHandler",
553                           "config_value_changed[int]: Value for %s could not be sent "
554                           "to client %u", path, *__sit);
555       LibLogger::log_warn("ConfigNetworkHandler", e);
556     }
557   }
558   __subscribers.unlock();
559 }
560
561
562 void
563 ConfigNetworkHandler::config_value_changed(const char *path, bool is_default, unsigned int value)
564 {
565   __subscribers.lock();
566   for (__sit = __subscribers.begin(); __sit != __subscribers.end(); ++__sit) {
567     try {
568       config_uint_value_msg_t *r = prepare_msg<config_uint_value_msg_t>(path, is_default);
569       r->u = value;
570       __hub->send(*__sit, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_UINT_VALUE,
571                   r, sizeof(config_uint_value_msg_t));
572     } catch (Exception &e) {
573       LibLogger::log_warn("ConfigNetworkHandler",
574                           "config_value_changed[uint]: Value for %s could not be sent "
575                           "to client %u", path, *__sit);
576       LibLogger::log_warn("ConfigNetworkHandler", e);
577     }
578   }
579   __subscribers.unlock();
580 }
581
582
583 void
584 ConfigNetworkHandler::config_value_changed(const char *path, bool is_default, float value)
585 {
586   __subscribers.lock();
587   for (__sit = __subscribers.begin(); __sit != __subscribers.end(); ++__sit) {
588     try {
589       config_float_value_msg_t *r = prepare_msg<config_float_value_msg_t>(path, is_default);
590       r->f = value;
591       __hub->send(*__sit, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_FLOAT_VALUE,
592                   r, sizeof(config_float_value_msg_t));
593     } catch (Exception &e) {
594       LibLogger::log_warn("ConfigNetworkHandler",
595                           "config_value_changed[float]: Value for %s could not be sent "
596                           "to client %u", path, *__sit);
597       LibLogger::log_warn("ConfigNetworkHandler", e);
598     }
599   }
600   __subscribers.unlock();
601 }
602
603
604 void
605 ConfigNetworkHandler::config_value_changed(const char *path, bool is_default, bool value)
606 {
607   __subscribers.lock();
608   for (__sit = __subscribers.begin(); __sit != __subscribers.end(); ++__sit) {
609     try {
610       config_bool_value_msg_t *r = prepare_msg<config_bool_value_msg_t>(path, is_default);
611       r->b = (value ? 1 : 0);
612       __hub->send(*__sit, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_BOOL_VALUE,
613                   r, sizeof(config_bool_value_msg_t));
614     } catch (Exception &e) {
615       LibLogger::log_warn("ConfigNetworkHandler",
616                           "config_value_changed[bool]: Value for %s could not be sent "
617                           "to client %u", path, *__sit);
618       LibLogger::log_warn("ConfigNetworkHandler", e);
619     }
620   }
621   __subscribers.unlock();
622 }
623
624
625 void
626 ConfigNetworkHandler::config_value_changed(const char *path, bool is_default, const char *value)
627 {
628   __subscribers.lock();
629   for (__sit = __subscribers.begin(); __sit != __subscribers.end(); ++__sit) {
630     try {
631       size_t s_length = strlen(value);
632       config_string_value_msg_t *r = prepare_string_msg<config_string_value_msg_t>(path, is_default, s_length);
633       strcpy(r->s, value);
634       __hub->send(*__sit, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_STRING_VALUE,
635                   r, sizeof(config_string_value_msg_t) + s_length);
636     } catch (Exception &e) {
637       LibLogger::log_warn("ConfigNetworkHandler",
638                           "config_value_changed[string]: Value for %s could not be sent "
639                           "to client %u", path, *__sit);
640       LibLogger::log_warn("ConfigNetworkHandler", e);
641     }
642   }
643   __subscribers.unlock();
644 }
645
646
647 void
648 ConfigNetworkHandler::config_comment_changed(const char *path, bool is_default, const char *comment)
649 {
650   __subscribers.lock();
651   for (__sit = __subscribers.begin(); __sit != __subscribers.end(); ++__sit) {
652     try {
653       size_t s_length = strlen(comment);
654       config_comment_msg_t *r = prepare_string_msg<config_comment_msg_t>(path, is_default, s_length);
655       strcpy(r->s, comment);
656
657       __hub->send(*__sit, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_COMMENT_VALUE,
658                   r, sizeof(config_comment_msg_t) + s_length);
659     } catch (Exception &e) {
660       LibLogger::log_warn("ConfigNetworkHandler",
661                           "config_value_changed[string]: Value for %s could not be sent "
662                           "to client %u", path, *__sit);
663       LibLogger::log_warn("ConfigNetworkHandler", e);
664     }
665   }
666   __subscribers.unlock();
667 }
668
669
670 void
671 ConfigNetworkHandler::config_value_erased(const char *path, bool is_default)
672 {
673   __subscribers.lock();
674   for (__sit = __subscribers.begin(); __sit != __subscribers.end(); ++__sit) {
675     try {
676       config_value_erased_msg_t *r = prepare_msg<config_value_erased_msg_t>(path, is_default);
677       __hub->send(*__sit, FAWKES_CID_CONFIGMANAGER, MSG_CONFIG_VALUE_ERASED,
678                 r, sizeof(config_value_erased_msg_t));
679     } catch (Exception &e) {
680       LibLogger::log_warn("ConfigNetworkHandler",
681                           "configValueErased: Value for %s could not be sent "
682                           "to client %u", path, *__sit);
683     }
684   }
685   __subscribers.unlock();
686 }
687
688 } // end namespace fawkes