Leosac  0.8.0
Open Source Access Control
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 }
Leosac::Module::SysFsGpio::SysFsGpioModule::process_config
void process_config(const boost::property_tree::ptree &cfg)
Process the configuration, preparing configured GPIO pin.
Definition: SysFsGpioModule.cpp:68
Leosac::Module::BaseModule
Base class for module implementation.
Definition: BaseModule.hpp:110
Leosac::Tools::compute_timeout
int compute_timeout(InputIterator begin, InputIterator end)
Compute the time until the next timeout from a collection of time point.
Definition: timeout.hpp:39
zmqpp
Definition: CoreUtils.hpp:27
Leosac::Module::SysFsGpio::SysFsGpioModule::run
virtual void run() override
This is the main loop of the module.
Definition: SysFsGpioModule.cpp:138
Leosac::Module::SysFsGpio::SysFsGpioModule::general_cfg_
SysFsGpioConfig * general_cfg_
General configuration for module.
Definition: SysFsGpioModule.hpp:104
Leosac::Hardware::GPIO::Direction::Out
@ Out
Leosac::Hardware::DeviceClass::GPIO
@ GPIO
timeout.hpp
Leosac::Module::SysFsGpio::SysFsGpioModule::publish_on_bus
void publish_on_bus(zmqpp::message &msg)
Write the message eon the bus.
Definition: SysFsGpioModule.cpp:122
INFO
@ INFO
Definition: log.hpp:34
SysFsGpioConfig.hpp
Leosac::Module::SysFsGpio::SysFsGpioPin::InterruptMode::Both
@ Both
Leosac::Module::SysFsGpio::SysFsGpioModule::process_general_config
void process_general_config()
General configuration (file paths, etc).
Definition: SysFsGpioModule.cpp:127
Leosac::Module::SysFsGpio::SysFsGpioPin::InterruptMode::Rising
@ Rising
Leosac::Colorize::underline
std::string underline(const T &in)
Definition: Colorize.hpp:64
Leosac::Module::SysFsGpio::SysFsGpioConfig
Internal configuration helper for sysfsgpio module.
Definition: SysFsGpioConfig.hpp:40
unixfs.hpp
unix filesystem helper functions
Leosac::Module::SysFsGpio::SysFsGpioPin::InterruptMode::None
@ None
Leosac::Module::SysFsGpio::SysFsGpioModule::general_config
const SysFsGpioConfig & general_config() const
Retrieve a reference to the config object.
Definition: SysFsGpioModule.cpp:133
kernel.hpp
Leosac::Module::BaseModule::config_
boost::property_tree::ptree config_
The configuration tree passed to the start_module function.
Definition: BaseModule.hpp:193
Leosac::Module::SysFsGpio::SysFsGpioModule::~SysFsGpioModule
~SysFsGpioModule()
Definition: SysFsGpioModule.cpp:115
Leosac::Module::BaseModule::reactor_
zmqpp::reactor reactor_
The reactor object we poll() on in the main loop.
Definition: BaseModule.hpp:214
Leosac::Module::BaseModule::utils_
CoreUtilsPtr utils_
Pointer to the core utils, which gives access to scheduler and others.
Definition: BaseModule.hpp:198
Leosac::Module::SysFsGpio
Namespace for the module that implements GPIO support using the Linux Kernel sysfs interface.
Definition: SysFsGpioConfig.hpp:32
Leosac::Hardware::GPIO::Direction
Direction
Definition: GPIO.hpp:44
Leosac::Colorize::green
std::string green(const T &in)
Definition: Colorize.hpp:82
Leosac::Module::SysFsGpio::SysFsGpioPin::InterruptMode
InterruptMode
Definition: SysFSGPIOPin.hpp:46
Leosac::Module::BaseModule::is_running_
bool is_running_
Boolean indicating whether the main loop should run or not.
Definition: BaseModule.hpp:203
SysFsGpioModule.hpp
Leosac::Tools::UnixFs
Definition: unixfs.hpp:39
Leosac::Module::SysFsGpio::SysFsGpioModule::bus_push_
zmqpp::socket bus_push_
Socket to write the bus.
Definition: SysFsGpioModule.hpp:94
Leosac::Module::SysFsGpio::SysFsGpioPin::InterruptMode::Falling
@ Falling
Leosac::Hardware::GPIO::Direction::In
@ In
log.hpp
Leosac::Module::SysFsGpio::SysFsGpioModule::SysFsGpioModule
SysFsGpioModule(zmqpp::context &ctx, zmqpp::socket *module_manager_pipe, const boost::property_tree::ptree &config, CoreUtilsPtr utils)
Definition: SysFsGpioModule.cpp:37
Leosac::Module::SysFsGpio::SysFsGpioModule::export_gpio
void export_gpio(int gpio_no)
Write to "gpio_export_path" so the kernel export the socket to sysfs.
Definition: SysFsGpioModule.cpp:110
Leosac::Module::BaseModule::ctx_
zmqpp::context & ctx_
A reference to the ZeroMQ context in case you need it to create additional socket.
Definition: BaseModule.hpp:183
Leosac::CoreUtilsPtr
std::shared_ptr< CoreUtils > CoreUtilsPtr
Definition: LeosacFwd.hpp:35
Leosac::Module::SysFsGpio::SysFsGpioPin
This is a implementation class.
Definition: SysFSGPIOPin.hpp:41
Leosac::Module::SysFsGpio::SysFsGpioConfig::export_path
const std::string & export_path() const
Returns the absolute path to the "export" sysfs file.
Definition: SysFsGpioConfig.cpp:63
Leosac::Module::SysFsGpio::SysFsGpioModule::gpios_
std::vector< SysFsGpioPin * > gpios_
Vector of underlying pin object.
Definition: SysFsGpioModule.hpp:99