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),
40  AspectProviderAspect(&gossip_aspect_inifin_)
41 {
42 }
43 
44 
45 /** Destructor. */
47 {
48 }
49 
50 
51 void
53 {
54  cfg_service_name_ = config->get_string(CFG_PREFIX"name");
55 
56  // gather static group configurations
57  std::map<std::string, GossipGroupConfiguration> groups;
58  std::set<std::string> ignored_groups;
59 
60  std::string prefix = CFG_PREFIX"groups/";
61 
62  std::shared_ptr<Configuration::ValueIterator> i(config->search(prefix.c_str()));
63  while (i->next()) {
64  std::string cfg_name = std::string(i->path()).substr(prefix.length());
65  cfg_name = cfg_name.substr(0, cfg_name.find("/"));
66 
67  if ( (groups.find(cfg_name) == groups.end()) &&
68  (ignored_groups.find(cfg_name) == ignored_groups.end()) ) {
69 
70  std::string cfg_prefix = prefix + cfg_name + "/";
71 
72  bool active = true;
73  try {
74  active = config->get_bool((cfg_prefix + "active").c_str());
75  } catch (Exception &e) {} // ignored, assume enabled
76 
77  try {
78  if (active) {
79  std::string addr = config->get_string((cfg_prefix + "broadcast-address").c_str());
80 
81  if (config->exists((cfg_prefix + "broadcast-send-port").c_str()) &&
82  config->exists((cfg_prefix + "broadcast-recv-port").c_str()) )
83  {
84  unsigned int send_port =
85  config->get_uint((cfg_prefix + "broadcast-send-port").c_str());
86  unsigned int recv_port =
87  config->get_uint((cfg_prefix + "broadcast-recv-port").c_str());
88 
89  if (send_port > 0xFFFF) {
90  throw Exception("Port number too high: %u > %u", send_port, 0xFFFF);
91  }
92  if (recv_port > 0xFFFF) {
93  throw Exception("Port number too high: %u > %u", recv_port, 0xFFFF);
94  }
95  groups[cfg_name] = GossipGroupConfiguration(cfg_name, addr, send_port, recv_port);
96 
97  } else {
98  unsigned int port = config->get_uint((cfg_prefix + "broadcast-port").c_str());
99 
100  if (port > 0xFFFF) {
101  throw Exception("Port number too high: %u > %u", port, 0xFFFF);
102  }
103 
104  groups[cfg_name] = GossipGroupConfiguration(cfg_name, addr, port);
105  }
106 
107  try {
108  groups[cfg_name].crypto_key =
109  config->get_string((cfg_prefix + "encryption-key").c_str());
110  try {
111  groups[cfg_name].crypto_cipher =
112  config->get_string((cfg_prefix + "encryption-cipher").c_str());
113  } catch (Exception &e) {
114  // ignore, use default
115  groups[cfg_name].crypto_cipher = "aes-128-ecb";
116  }
117  logger->log_debug(name(), "Setup encryption of type %s for group '%s'",
118  groups[cfg_name].crypto_cipher.c_str(), cfg_name.c_str());
119  } catch (Exception &e) {} // ignored, no encryption
120 
121  } else {
122  //printf("Ignoring laser config %s\n", cfg_name.c_str());
123  ignored_groups.insert(cfg_name);
124  }
125  } catch(Exception &e) {
126  throw;
127  }
128  }
129  }
130 
131  group_mgr_ =
132  std::shared_ptr<GossipGroupManager>(new GossipGroupManager(cfg_service_name_,
134  groups));
135  gossip_aspect_inifin_.set_manager(group_mgr_.get());
136 }
137 
138 
139 void
141 {
142  gossip_aspect_inifin_.set_manager(NULL);
143  group_mgr_.reset();
144 }
145 
146 
147 void
149 {
150 }
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:49
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.
Thread class encapsulation of pthreads.
Definition: thread.h:42
Logger * logger
This is the Logger member used to access the logger.
Definition: logging.h:44
Group configuration for initial groups.
Base class for exceptions in Fawkes.
Definition: exception.h:36
virtual ~GossipThread()
Destructor.
Abstract class for a Gossip group manager.
const char * name() const
Get name of thread.
Definition: thread.h:95
virtual void finalize()
Finalize the thread.
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:44
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.