Leosac  0.8.0
Open Source Access Control
BaseModule.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014-2016 Leosac
3 
4  This file is part of Leosac.
5 
6  Leosac is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Affero General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Leosac is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Affero General Public License for more details.
15 
16  You should have received a copy of the GNU Affero General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "BaseModule.hpp"
21 #include "core/CoreUtils.hpp"
24 #include "tools/log.hpp"
25 #include <boost/archive/text_oarchive.hpp>
26 #include <boost/property_tree/ptree_serialization.hpp>
27 #include <signal.h>
28 
29 using namespace Leosac::Module;
30 using namespace Leosac::Tools;
31 
32 BaseModule::BaseModule(zmqpp::context &ctx, zmqpp::socket *pipe,
33  boost::property_tree::ptree const &cfg, CoreUtilsPtr utils)
34  : ctx_(ctx)
35  , pipe_(*pipe)
36  , config_(cfg)
37  , utils_(utils)
38  , is_running_(true)
39  , control_(ctx, zmqpp::socket_type::rep)
40 {
41  name_ = cfg.get<std::string>("name");
42  control_.bind("inproc://module-" + name_);
43 
44  reactor_.add(control_, std::bind(&BaseModule::handle_control, this));
45  reactor_.add(pipe_, std::bind(&BaseModule::handle_pipe, this));
46 }
47 
49 {
50  while (is_running_)
51  {
52  reactor_.poll();
53  }
54 }
55 
57 {
58  zmqpp::message msg;
59  zmqpp::signal sig;
60  pipe_.receive(msg);
61 
62  assert(msg.is_signal());
63  msg >> sig;
64  if (sig == zmqpp::signal::stop)
65  is_running_ = false;
66  else
67  {
68  ERROR(
69  "Module receive a message on its pipe that wasn't a signal. Aborting.");
70  assert(0);
71  throw std::runtime_error(
72  "Module receive a message on its pipe that wasn't a signal. Aborting.");
73  }
74 }
75 
77  zmqpp::message *out_msg) const
78 {
79  assert(out_msg);
81  {
82  std::ostringstream oss;
83  boost::archive::text_oarchive archive(oss);
84  boost::property_tree::save(archive, config_, 1);
85  out_msg->add(oss.str());
86  }
87  else
88  {
89  out_msg->add(propertyTreeToXml(config_));
90  }
91  try
92  {
93  dump_additional_config(out_msg);
94  }
95  catch (std::exception &e)
96  {
97  ERROR("Problem while dumping config: " << e.what());
98  }
99 }
100 
102 {
103  zmqpp::message msg;
104  std::string frame1;
105 
106  control_.receive(msg);
107  msg >> frame1;
108  if (frame1 == "DUMP_CONFIG")
109  {
110  zmqpp::message response;
111 
112  assert(msg.remaining() == 1);
114  msg >> format;
115  DEBUG("Module " << name_ << " is dumping config!");
116  dump_config(format, &response);
117  control_.send(response);
118  }
119  else
120  {
121  ERROR("Module received invalid request (" << frame1 << "). Aborting.");
122  assert(0);
123  throw std::runtime_error("Invalid request for module.");
124  }
125 }
126 
127 void BaseModule::dump_additional_config(zmqpp::message *) const
128 {
129 }
130 
131 void BaseModule::config_check(const std::string &obj_name)
132 {
133  if (utils_->config_checker().has_object(obj_name))
134  return;
135 
136  std::string prefix = "Configuration Error (module " + name_ + ") ";
137  ERROR(prefix << "Object " << obj_name << " cannot be found.");
138 
139  if (utils_->is_strict())
140  raise(SIGABRT); // BOOM
141 }
142 
143 void BaseModule::config_check(const std::string &obj_name,
145 {
146  bool res = utils_->config_checker().has_object(obj_name, type);
147 
148  if (res)
149  return;
150 
151  std::string prefix = "Configuration Error (module " + name_ + ") ";
152 
153  switch (type)
154  {
156  ERROR(prefix << "GPIO " << obj_name << " doesn't exist.");
157  break;
159  ERROR(prefix << "LED " << obj_name << " doesn't exist.");
160  break;
162  ERROR(prefix << "BUZZER " << obj_name << " doesn't exists.");
163  break;
165  ERROR(prefix << "READER " << obj_name << " doesn't exists.");
166  break;
168  ERROR(prefix << "EXTERNAL SERVER " << obj_name << " doesn't exists.");
169  break;
170  default:
171  ASSERT_LOG(false, prefix << "Missing case in switch: value "
172  << static_cast<int>(type) << " Need code fix.");
173  raise(SIGABRT);
174  break;
175  }
176  if (utils_->is_strict())
177  raise(SIGABRT); // lets suicide.
178 }
Leosac::Module::BaseModule::BaseModule
BaseModule(zmqpp::context &ctx, zmqpp::socket *pipe, const boost::property_tree::ptree &cfg, CoreUtilsPtr utils)
Constructor of BaseModule.
Definition: BaseModule.cpp:32
Leosac::Hardware::DeviceClass::RFID_READER
@ RFID_READER
Leosac::Module::BaseModule::pipe_
zmqpp::socket & pipe_
A reference to the pair socket that link back to the module manager.
Definition: BaseModule.hpp:188
Leosac::Hardware::DeviceClass
DeviceClass
An enumeration describing the class of the device.
Definition: HardwareFwd.hpp:42
zmqpp
Definition: CoreUtils.hpp:27
Leosac::Module::BaseModule::config_check
void config_check(const std::string &obj_name, Leosac::Hardware::DeviceClass type)
An helper that checks configuration the existence of some objects.
Definition: BaseModule.cpp:143
ERROR
@ ERROR
Definition: log.hpp:32
DEBUG
@ DEBUG
Definition: log.hpp:35
ASSERT_LOG
#define ASSERT_LOG(cond, msg)
Definition: log.hpp:190
Leosac::Hardware::DeviceClass::GPIO
@ GPIO
Leosac::Hardware::DeviceClass::BUZZER
@ BUZZER
BaseModule.hpp
Leosac::ConfigManager::ConfigFormat
ConfigFormat
This enum is used internally, when core request module configuration.
Definition: ConfigManager.hpp:118
Leosac::Module
All modules that provides features to Leosac shall be in this namespace.
Leosac::ConfigManager::ConfigFormat::BOOST_ARCHIVE
@ BOOST_ARCHIVE
Leosac::Module::BaseModule::config_
boost::property_tree::ptree config_
The configuration tree passed to the start_module function.
Definition: BaseModule.hpp:193
Leosac::Module::BaseModule::handle_pipe
virtual void handle_pipe()
The base class register the pipe_ socket to its reactor_ so that this function is called when the pip...
Definition: BaseModule.cpp:56
Leosac::Module::BaseModule::reactor_
zmqpp::reactor reactor_
The reactor object we poll() on in the main loop.
Definition: BaseModule.hpp:214
Leosac::Module::BaseModule::handle_control
virtual void handle_control()
Handle called when a message on the module's control socket arrives.
Definition: BaseModule.cpp:101
Leosac::Module::BaseModule::utils_
CoreUtilsPtr utils_
Pointer to the core utils, which gives access to scheduler and others.
Definition: BaseModule.hpp:198
Leosac::Hardware::DeviceClass::EXTERNAL_SERVER
@ EXTERNAL_SERVER
Leosac::Module::BaseModule::is_running_
bool is_running_
Boolean indicating whether the main loop should run or not.
Definition: BaseModule.hpp:203
XmlPropertyTree.hpp
Leosac::Module::BaseModule::dump_additional_config
virtual void dump_additional_config(zmqpp::message *out) const
Dump additional configuration (for example module specific config file).
Definition: BaseModule.cpp:127
Leosac::Module::BaseModule::run
virtual void run()
This is the main loop of the module.
Definition: BaseModule.cpp:48
Leosac::Colorize::detail::format
std::string format(const std::string &escape_code, const T &in)
Return a string containing the escape code, a string representation of T and the clear escape string.
Definition: Colorize.hpp:49
log.hpp
CoreUtils.hpp
Leosac::Tools::propertyTreeToXml
std::string propertyTreeToXml(const boost::property_tree::ptree &tree)
Convert a property tree to an xml formatted string.
Definition: XmlPropertyTree.cpp:67
Leosac::Module::BaseModule::control_
zmqpp::socket control_
Control REP socket.
Definition: BaseModule.hpp:208
Leosac::Module::BaseModule::name_
std::string name_
Definition: BaseModule.hpp:216
Leosac::CoreUtilsPtr
std::shared_ptr< CoreUtils > CoreUtilsPtr
Definition: LeosacFwd.hpp:35
ConfigManager.hpp
Leosac::Hardware::DeviceClass::LED
@ LED
Leosac::Tools
Definition: DatabaseLogSink.hpp:27
Leosac::Module::BaseModule::dump_config
void dump_config(ConfigManager::ConfigFormat fmt, zmqpp::message *out_msg) const
Fills a message with the module's configuration information.
Definition: BaseModule.cpp:76