Leosac  0.8.0
Open Source Access Control
WiegandReaderImpl.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 "WiegandReaderImpl.hpp"
22 #include "tools/log.hpp"
23 #include <core/auth/Auth.hpp>
24 #include <iomanip>
25 
26 using namespace Leosac::Module::Wiegand;
27 using namespace Leosac::Module::Wiegand::Strategy;
28 using namespace Leosac::Hardware;
29 using namespace Leosac::Auth;
30 
32  const std::string &reader_name,
33  const std::string &data_high_pin,
34  const std::string &data_low_pin,
35  const std::string &green_led_name,
36  const std::string &buzzer_name,
37  std::unique_ptr<WiegandStrategy> strategy)
38  : bus_sub_(ctx, zmqpp::socket_type::sub)
39  , sock_(ctx, zmqpp::socket_type::rep)
40  , bus_push_(ctx, zmqpp::socket_type::push)
41  , counter_(0)
42  , name_(reader_name)
43  , green_led_(nullptr)
44  , buzzer_(nullptr)
45  , strategy_(std::move(strategy))
46 {
47  bus_sub_.connect("inproc://zmq-bus-pub");
48  bus_push_.connect("inproc://zmq-bus-pull");
49 
50  sock_.bind("inproc://" + name_);
51 
52  topic_high_ = "S_INT:" + data_high_pin;
53  topic_low_ = "S_INT:" + data_low_pin;
54 
55  bus_sub_.subscribe(topic_high_);
56  bus_sub_.subscribe(topic_low_);
57 
58  std::fill(buffer_.begin(), buffer_.end(), 0);
59 
60  if (!green_led_name.empty())
61  green_led_ = std::make_unique<FLED>(ctx, green_led_name);
62 
63  if (!buzzer_name.empty())
64  buzzer_ = std::make_unique<FBuzzer>(ctx, buzzer_name);
65 }
66 
68 {
69 }
70 
72  : bus_sub_(std::move(o.bus_sub_))
73  , sock_(std::move(o.sock_))
74  , bus_push_(std::move(o.bus_push_))
75  , name_(std::move(o.name_))
76  , strategy_(std::move(o.strategy_))
77 {
78  topic_high_ = o.topic_high_;
79  topic_low_ = o.topic_low_;
80 
81  buffer_ = o.buffer_;
82  counter_ = o.counter_;
83 
84  green_led_ = std::move(o.green_led_);
85  buzzer_ = std::move(o.buzzer_);
86 
87  // when we are moved, we must update our strategy's pointer back to the "new" us.
88  strategy_->set_reader(this);
89 }
90 
92 {
93  std::string msg;
94  bus_sub_.receive(msg);
95 
96  if (counter_ < 128)
97  {
98  if (msg == topic_high_)
99  {
100  buffer_[counter_ / 8] |= (1 << (7 - counter_ % 8));
101  }
102  else if (msg == topic_low_)
103  {
104  // set the bit to 0. it doesn't cost much
105  // and is safer in case the buffer wasn't fully filled with 0.
106  buffer_[counter_ / 8] &= ~(1 << (7 - counter_ % 8));
107  }
108  counter_++;
109  }
110  else
111  {
112  WARN("Received too many interrupt. Resetting current counter.");
113  counter_ = 0;
114  }
115 }
116 
118 {
119  assert(strategy_);
120  strategy_->timeout();
121 
122  if (strategy_->completed())
123  {
124  // if we gathered all the data we need, send
125  // and authentication attempt by signaling the application.
126  strategy_->signal(bus_push_);
127  strategy_->reset();
128  }
129 }
130 
132 {
133  zmqpp::message msg;
134  std::string str;
135  sock_.receive(msg);
136 
137  msg >> str;
138  assert(str == "GREEN_LED" || str == "BEEP" || str == "BEEP_ON" ||
139  str == "BEEP_OFF");
140  if (str == "GREEN_LED")
141  {
142  msg.pop_front();
143  if (!green_led_)
144  {
145  sock_.send("KO");
146  return;
147  }
148  // forward the request to the led.
149  green_led_->backend().send(msg);
150  green_led_->backend().receive(str);
151  assert(str == "OK" || str == "KO");
152  sock_.send(str == "OK" ? "OK" : "KO");
153  }
154  else if (str == "BEEP")
155  {
156  assert(msg.parts() == 2);
157  int64_t duration;
158  msg >> duration;
159  if (!buzzer_)
160  {
161  sock_.send("KO");
162  return;
163  }
164  bool ret = buzzer_->turnOn(std::chrono::milliseconds(duration));
165  ASSERT_LOG(ret, "Turning the buzzer ON failed.");
166  sock_.send("OK");
167  }
168  else if (str == "BEEP_ON")
169  {
170  if (!buzzer_)
171  {
172  sock_.send("KO");
173  return;
174  }
175  bool ret = buzzer_->turnOn();
176  ASSERT_LOG(ret, "Turning the buzzer ON failed.");
177  sock_.send("OK");
178  }
179  else if (str == "BEEP_OFF")
180  {
181  if (!buzzer_)
182  {
183  sock_.send("KO");
184  return;
185  }
186  bool ret = buzzer_->turnOff();
187  ASSERT_LOG(ret, "Turning the buzzer OFF failed.");
188  sock_.send("OK");
189  }
190 }
191 
193 {
194  counter_ = 0;
195  std::fill(buffer_.begin(), buffer_.end(), 0);
196 }
197 
198 const unsigned char *WiegandReaderImpl::buffer() const
199 {
200  return &buffer_[0];
201 }
202 
204 {
205  return counter_;
206 }
207 
208 std::string const &WiegandReaderImpl::name() const
209 {
210  return name_;
211 }
Leosac::Module::Wiegand::WiegandReaderImpl::handle_request
void handle_request()
Someone sent a request.
Definition: WiegandReaderImpl.cpp:131
Leosac::Auth
Holds classes relevant to the Authentication and Authorization subsystem.
Definition: AccessPoint.hpp:27
Leosac::Module::Wiegand::WiegandReaderImpl::buzzer_
std::unique_ptr< Hardware::FBuzzer > buzzer_
Facade to the buzzer object.
Definition: WiegandReaderImpl.hpp:161
Leosac::Module::Wiegand::WiegandReaderImpl::counter_
int counter_
Count the number of bits received from GPIOs.
Definition: WiegandReaderImpl.hpp:146
Leosac::Module::Wiegand::WiegandReaderImpl::topic_low_
std::string topic_low_
ZMQ topic-string to interrupt on LOW gpio (low gpio's name)
Definition: WiegandReaderImpl.hpp:136
WARN
@ WARN
Definition: log.hpp:33
zmqpp
Definition: CoreUtils.hpp:27
Leosac::Module::Wiegand::WiegandReaderImpl
An implementation class that represents a Wiegand Reader.
Definition: WiegandReaderImpl.hpp:41
Auth.hpp
ASSERT_LOG
#define ASSERT_LOG(cond, msg)
Definition: log.hpp:190
Leosac::Module::Wiegand::WiegandReaderImpl::handle_bus_msg
void handle_bus_msg()
Something happened on the bus.
Definition: WiegandReaderImpl.cpp:91
Leosac::Module::Wiegand::WiegandReaderImpl::timeout
void timeout()
Timeout (no more data burst to handle).
Definition: WiegandReaderImpl.cpp:117
WiegandStrategy.hpp
WiegandReaderImpl.hpp
Leosac::Module::Wiegand::WiegandReaderImpl::strategy_
std::unique_ptr< Strategy::WiegandStrategy > strategy_
Concrete implementation of the reader mode.
Definition: WiegandReaderImpl.hpp:166
Leosac::Module::Wiegand::WiegandReaderImpl::sock_
zmqpp::socket sock_
REP socket to receive command on.
Definition: WiegandReaderImpl.hpp:76
Leosac::Module::Wiegand::WiegandReaderImpl::bus_push_
zmqpp::socket bus_push_
Socket to write to the message bus.
Definition: WiegandReaderImpl.hpp:126
Leosac::Module::Wiegand::WiegandReaderImpl::read_reset
void read_reset()
Reset the "read state" of the reader, effectively cleaning the wiegand-bit-buffer and resetting the c...
Definition: WiegandReaderImpl.cpp:192
Leosac::Module::Wiegand::WiegandReaderImpl::counter
int counter() const
Returns the number of bits read.
Definition: WiegandReaderImpl.cpp:203
Leosac::Module::Wiegand::Strategy
Definition: Autodetect.hpp:31
Leosac::Module::Wiegand::WiegandReaderImpl::buffer
const unsigned char * buffer() const
Return a pointer to internal buffer memory.
Definition: WiegandReaderImpl.cpp:198
log.hpp
Leosac::Module::Wiegand
Provide support for Wiegand devices.
Definition: Autodetect.hpp:29
Leosac::Module::Wiegand::WiegandReaderImpl::topic_high_
std::string topic_high_
ZMQ topic-string for interrupt on HIGH gpio (high gpio's name)
Definition: WiegandReaderImpl.hpp:131
Leosac::Module::Wiegand::WiegandReaderImpl::buffer_
std::array< uint8_t, 16 > buffer_
Buffer to store incoming bits from high and low gpios.
Definition: WiegandReaderImpl.hpp:141
Leosac::Module::Wiegand::WiegandReaderImpl::WiegandReaderImpl
WiegandReaderImpl(zmqpp::context &ctx, const std::string &reader_name, const std::string &data_high_pin, const std::string &data_low_pin, const std::string &green_led_name, const std::string &buzzer_name, std::unique_ptr< Strategy::WiegandStrategy > strategy)
Create a new implementation of a Wiegand Reader.
Definition: WiegandReaderImpl.cpp:31
Leosac::Module::Wiegand::WiegandReaderImpl::~WiegandReaderImpl
~WiegandReaderImpl()
Definition: WiegandReaderImpl.cpp:67
Leosac::Hardware
Provides facade classes to hardware device implementation.
Definition: Buzzer.cpp:25
Leosac::Module::Wiegand::WiegandReaderImpl::bus_sub_
zmqpp::socket bus_sub_
Socket that allows the reader to listen to the application BUS.
Definition: WiegandReaderImpl.hpp:71
Leosac::Module::Wiegand::WiegandReaderImpl::name
const std::string & name() const
Returns the name of this reader.
Definition: WiegandReaderImpl.cpp:208
Leosac::Module::Wiegand::WiegandReaderImpl::name_
std::string name_
Name of the device (defined in configuration)
Definition: WiegandReaderImpl.hpp:151
Leosac::Module::Wiegand::WiegandReaderImpl::green_led_
std::unique_ptr< Hardware::FLED > green_led_
Facade to control the reader green led.
Definition: WiegandReaderImpl.hpp:156