Fawkes API  Fawkes Development Version
gossip_thread.cpp
1 
2 /***************************************************************************
3  * gossip_thread.cpp - Robot Group Communication Plugin
4  *
5  * Created: Fri Feb 28 11:11:20 2014
6  * Copyright 2006-2014 Tim Niemueller [www.niemueller.de]
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Library General Public License for more details.
18  *
19  * Read the full text in the LICENSE.GPL file in the doc directory.
20  */
21 
22 #include "gossip_thread.h"
23 
24 #include <plugins/gossip/gossip/gossip_group_manager.h>
25 
26 #include <set>
27 
28 using namespace fawkes;
29 
30 #define CFG_PREFIX "/gossip/"
31 
32 /** @class GossipThread "clips-protobuf-thread.h"
33  * Robot Group Communication.
34  * @author Tim Niemueller
35  */
36 
37 /** Constructor. */
39 : Thread("GossipThread", Thread::OPMODE_WAITFORWAKEUP), AspectProviderAspect(&gossip_aspect_inifin_)
40 {
41 }
42 
43 /** Destructor. */
45 {
46 }
47 
48 void
50 {
51  cfg_service_name_ = config->get_string(CFG_PREFIX "name");
52 
53  // gather static group configurations
54  std::map<std::string, GossipGroupConfiguration> groups;
55  std::set<std::string> ignored_groups;
56 
57  std::string prefix = CFG_PREFIX "groups/";
58 
59  std::shared_ptr<Configuration::ValueIterator> i(config->search(prefix.c_str()));
60  while (i->next()) {
61  std::string cfg_name = std::string(i->path()).substr(prefix.length());
62  cfg_name = cfg_name.substr(0, cfg_name.find("/"));
63 
64  if ((groups.find(cfg_name) == groups.end())
65  && (ignored_groups.find(cfg_name) == ignored_groups.end())) {
66  std::string cfg_prefix = prefix + cfg_name + "/";
67 
68  bool active = true;
69  try {
70  active = config->get_bool((cfg_prefix + "active").c_str());
71  } catch (Exception &e) {
72  } // ignored, assume enabled
73 
74  try {
75  if (active) {
76  std::string addr = config->get_string((cfg_prefix + "broadcast-address").c_str());
77 
78  if (config->exists((cfg_prefix + "broadcast-send-port").c_str())
79  && config->exists((cfg_prefix + "broadcast-recv-port").c_str())) {
80  unsigned int send_port = config->get_uint((cfg_prefix + "broadcast-send-port").c_str());
81  unsigned int recv_port = config->get_uint((cfg_prefix + "broadcast-recv-port").c_str());
82 
83  if (send_port > 0xFFFF) {
84  throw Exception("Port number too high: %u > %u", send_port, 0xFFFF);
85  }
86  if (recv_port > 0xFFFF) {
87  throw Exception("Port number too high: %u > %u", recv_port, 0xFFFF);
88  }
89  groups[cfg_name] = GossipGroupConfiguration(cfg_name, addr, send_port, recv_port);
90 
91  } else {
92  unsigned int port = config->get_uint((cfg_prefix + "broadcast-port").c_str());
93 
94  if (port > 0xFFFF) {
95  throw Exception("Port number too high: %u > %u", port, 0xFFFF);
96  }
97 
98  groups[cfg_name] = GossipGroupConfiguration(cfg_name, addr, port);
99  }
100 
101  try {
102  groups[cfg_name].crypto_key =
103  config->get_string((cfg_prefix + "encryption-key").c_str());
104  try {
105  groups[cfg_name].crypto_cipher =
106  config->get_string((cfg_prefix + "encryption-cipher").c_str());
107  } catch (Exception &e) {
108  // ignore, use default
109  groups[cfg_name].crypto_cipher = "aes-128-ecb";
110  }
111  logger->log_debug(name(),
112  "Setup encryption of type %s for group '%s'",
113  groups[cfg_name].crypto_cipher.c_str(),
114  cfg_name.c_str());
115  } catch (Exception &e) {
116  } // ignored, no encryption
117 
118  } else {
119  //printf("Ignoring laser config %s\n", cfg_name.c_str());
120  ignored_groups.insert(cfg_name);
121  }
122  } catch (Exception &e) {
123  throw;
124  }
125  }
126  }
127 
128  group_mgr_ = std::shared_ptr<GossipGroupManager>(
129  new GossipGroupManager(cfg_service_name_, service_publisher, groups));
130  gossip_aspect_inifin_.set_manager(group_mgr_.get());
131 }
132 
133 void
135 {
136  gossip_aspect_inifin_.set_manager(NULL);
137  group_mgr_.reset();
138 }
139 
140 void
142 {
143 }
virtual void loop()
Code to execute in the thread.
virtual void init()
Initialize the thread.
ServicePublisher * service_publisher
Service publisher to publish services on the network.
Definition: network.h:46
Fawkes library namespace.
virtual bool get_bool(const char *path)=0
Get value from configuration which is of type bool.
virtual ValueIterator * search(const char *path)=0
Iterator with search results.
virtual bool next()=0
Check if there is another element and advance to this if possible.
Thread class encapsulation of pthreads.
Definition: thread.h:45
Logger * logger
This is the Logger member used to access the logger.
Definition: logging.h:41
Group configuration for initial groups.
Base class for exceptions in Fawkes.
Definition: exception.h:35
virtual ~GossipThread()
Destructor.
Abstract class for a Gossip group manager.
const char * name() const
Get name of thread.
Definition: thread.h:100
virtual void finalize()
Finalize the thread.
virtual const char * path() const =0
Path of value.
Thread aspect provide a new aspect.
virtual void log_debug(const char *component, const char *format,...)=0
Log debug message.
virtual bool exists(const char *path)=0
Check if a given value exists.
GossipThread()
Constructor.
virtual unsigned int get_uint(const char *path)=0
Get value from configuration which is of type unsigned int.
Configuration * config
This is the Configuration member used to access the configuration.
Definition: configurable.h:41
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
void set_manager(GossipGroupManager *gossip_group_mgr)
Set gossip group manger.