Leosac  0.7.0
OpenSourceAccessControl
SysFsGpioModule.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 "SysFsGpioModule.hpp"
21 #include "SysFsGpioConfig.hpp"
22 #include "core/kernel.hpp"
23 #include "tools/log.hpp"
24 #include "tools/timeout.hpp"
25 #include "tools/unixfs.hpp"
26 #include <boost/iterator/transform_iterator.hpp>
27 #include <boost/property_tree/ptree.hpp>
28 #include <memory>
29 #include <zmqpp/context.hpp>
30 #include <zmqpp/message.hpp>
31 
32 
33 using namespace Leosac::Module::SysFsGpio;
35 
36 
38  zmqpp::socket *module_manager_pipe,
39  const boost::property_tree::ptree &config,
40  CoreUtilsPtr utils)
41  : BaseModule(ctx, module_manager_pipe, config, utils)
42  , bus_push_(ctx_, zmqpp::socket_type::push)
43  , general_cfg_(nullptr)
44 {
45  bus_push_.connect("inproc://zmq-bus-pull");
46  process_config(config);
47 
48  for (auto &gpio : gpios_)
49  {
50  gpio->register_sockets(&reactor_);
51  }
52 }
53 
54 static SysFsGpioPin::InterruptMode gpio_interrupt_from_string(const std::string &str)
55 {
56  if (str == "none")
58  else if (str == "both")
60  else if (str == "falling")
62  else if (str == "rising")
64  else
66 }
67 
68 void SysFsGpioModule::process_config(const boost::property_tree::ptree &cfg)
69 {
70  boost::property_tree::ptree module_config = cfg.get_child("module_config");
71 
73 
74  for (auto &node : module_config.get_child("gpios"))
75  {
76  boost::property_tree::ptree gpio_cfg = node.second;
77  SysFsGpioPin::Direction direction;
78  SysFsGpioPin::InterruptMode interrupt_mode;
79  std::string gpio_name;
80  std::string gpio_direction;
81  std::string gpio_interrupt;
82  int gpio_no;
83  bool gpio_initial_value;
84 
85  gpio_name = gpio_cfg.get_child("name").data();
86  gpio_no = std::stoi(gpio_cfg.get_child("no").data());
87  gpio_direction = gpio_cfg.get_child("direction").data();
88  gpio_interrupt = gpio_cfg.get<std::string>("interrupt_mode", "none");
89  gpio_initial_value = gpio_cfg.get<bool>("value", false);
90 
91  using namespace Colorize;
92  INFO("Creating GPIO " << green(underline(gpio_name)) << ", with no "
93  << green(underline(gpio_no)) << ". direction = "
94  << green(underline(gpio_direction)));
95 
96  export_gpio(gpio_no);
97  interrupt_mode = gpio_interrupt_from_string(gpio_interrupt);
98 
99  direction = (gpio_direction == "in" ? SysFsGpioPin::Direction::In
101  gpios_.push_back(new SysFsGpioPin(ctx_, gpio_name, gpio_no, direction,
102  interrupt_mode, gpio_initial_value,
103  *this));
104 
105  utils_->config_checker().register_object(gpio_name,
107  }
108 }
109 
111 {
112  UnixFs::writeSysFsValue(general_cfg_->export_path(), gpio_no);
113 }
114 
116 {
117  for (auto gpio : gpios_)
118  delete gpio;
119  delete general_cfg_;
120 }
121 
122 void SysFsGpioModule::publish_on_bus(zmqpp::message &msg)
123 {
124  bus_push_.send(msg);
125 }
126 
128 {
129  assert(general_cfg_ == nullptr);
130  general_cfg_ = new SysFsGpioConfig(config_.get_child("module_config"));
131 }
132 
134 {
135  return *general_cfg_;
136 }
137 
139 {
140  while (is_running_)
141  {
142  auto itr_transform =
143  [](const SysFsGpioPin *p) -> std::chrono::system_clock::time_point {
144  return p->next_update();
145  };
146 
147  auto timeout = Tools::compute_timeout(
148  boost::make_transform_iterator(gpios_.begin(), itr_transform),
149  boost::make_transform_iterator(gpios_.end(), itr_transform));
150  reactor_.poll(timeout);
151  for (auto &gpio_pin : gpios_)
152  {
153  if (gpio_pin->next_update() < std::chrono::system_clock::now())
154  gpio_pin->update();
155  }
156  }
157 }
void process_config(const boost::property_tree::ptree &cfg)
Process the configuration, preparing configured GPIO pin.
zmqpp::socket bus_push_
Socket to write the bus.
Definition: log.hpp:37
int compute_timeout(InputIterator begin, InputIterator end)
Compute the time until the next timeout from a collection of time point.
Definition: timeout.hpp:39
CoreUtilsPtr utils_
Pointer to the core utils, which gives access to scheduler and others.
Definition: BaseModule.hpp:198
SysFsGpioConfig * general_cfg_
General configuration for module.
std::string underline(const T &in)
Definition: Colorize.hpp:64
SysFsGpioModule(zmqpp::context &ctx, zmqpp::socket *module_manager_pipe, const boost::property_tree::ptree &config, CoreUtilsPtr utils)
bool is_running_
Boolean indicating whether the main loop should run or not.
Definition: BaseModule.hpp:203
void publish_on_bus(zmqpp::message &msg)
Write the message eon the bus.
std::string green(const T &in)
Definition: Colorize.hpp:82
unix filesystem helper functions
Base class for module implementation.
Definition: BaseModule.hpp:110
zmqpp::context & ctx_
A reference to the ZeroMQ context in case you need it to create additional socket.
Definition: BaseModule.hpp:183
const std::string & export_path() const
Returns the absolute path to the "export" sysfs file.
Internal configuration helper for sysfsgpio module.
zmqpp::reactor reactor_
The reactor object we poll() on in the main loop.
Definition: BaseModule.hpp:214
This is a implementation class.
Namespace for the module that implements GPIO support using the Linux Kernel sysfs interface...
std::vector< SysFsGpioPin * > gpios_
Vector of underlying pin object.
std::shared_ptr< CoreUtils > CoreUtilsPtr
Definition: LeosacFwd.hpp:35
const SysFsGpioConfig & general_config() const
Retrieve a reference to the config object.
boost::property_tree::ptree config_
The configuration tree passed to the start_module function.
Definition: BaseModule.hpp:193
void export_gpio(int gpio_no)
Write to "gpio_export_path" so the kernel export the socket to sysfs.
virtual void run() override
This is the main loop of the module.
void process_general_config()
General configuration (file paths, etc).