Leosac  0.8.0
Open Source Access Control
Autodetect.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 "Autodetect.hpp"
22 #include <tools/log.hpp>
23 
24 using namespace Leosac::Module::Wiegand;
25 using namespace Leosac::Module::Wiegand::Strategy;
26 
27 Autodetect::Autodetect(WiegandReaderImpl *reader, std::chrono::milliseconds delay,
28  char pin_key_end, bool nowait)
29  : WiegandStrategy(reader)
30  , delay_(delay)
31  , reading_pin_(false)
32  , reading_card_(true)
33  , ready_(false)
34  , pin_key_end_(pin_key_end)
35  , nowait_(nowait)
36 {
37  time_card_read_ = std::chrono::system_clock::now();
38  last_pin_read_ = std::chrono::system_clock::now();
40  std::unique_ptr<CardReading>(new SimpleWiegandStrategy(reader));
41 }
42 
44 {
45  using namespace std::chrono;
46 
47  // When finishing reading a PIN code we mark as ready.
48  // This is because we have a choice between: PIN / Card / Card + PIN, so if PIN
49  // is presents,
50  // it is always last.
51 
52  if (reader_->counter() == 4 || reader_->counter() == 8)
53  {
54  reading_pin_ = true;
55  if (!read_pin_strategy_)
57  read_pin_strategy_->set_reader(reader_);
58  DEBUG("This is likely a PIN code");
59 
60  read_pin_strategy_->timeout();
61  last_pin_read_ = system_clock::now();
62  if (read_pin_strategy_->completed())
63  {
64  DEBUG("Read PIN = " << read_pin_strategy_->get_pin());
65  ready_ = true;
66  reading_pin_ = false;
68  }
69  }
70  else if (reader_->counter())
71  {
72  read_card_strategy_->timeout();
73  DEBUG("DOING SOME CARD READING");
74  time_card_read_ = system_clock::now();
75  if (read_card_strategy_->completed())
76  {
77  DEBUG("Read CARD = " << read_card_strategy_->get_card_id());
79  }
80  }
81  else
82  {
83  check_timeout();
84  }
85 }
86 
88 {
89  using namespace std::chrono;
90 
91  // Nothing was read, this is an inactivity timeout() tick.
92  // We do 2 things here: If we were reading a PIN code, check timeout and finish
93  // if timeout
94  // Check inactivity timeout for card + pin, to timeout and send a Card only
95  // credentials.
96 
97  auto elapsed_ms =
98  duration_cast<milliseconds>(system_clock::now() - time_card_read_);
99  auto elapsed_ms_pin =
100  duration_cast<milliseconds>(system_clock::now() - last_pin_read_);
101 
102  if (reading_pin_)
103  {
104  if (elapsed_ms_pin > delay_)
105  {
106  read_pin_strategy_->timeout();
107  DEBUG("PIN READING TIMEOUT");
108  if (read_pin_strategy_->completed())
109  {
110  DEBUG("Read PIN = " << read_pin_strategy_->get_pin());
111  ready_ = true;
112  reading_pin_ = false;
113  reader_->read_reset();
114  }
115  }
116  }
117  // 2 sec of total inactivity and we valid card.
118  if ((elapsed_ms > delay_ && elapsed_ms_pin > delay_) || nowait_)
119  {
120  if (read_card_strategy_->completed() && read_card_strategy_->get_nb_bits())
121  {
122  // mark as ready since no pin were typed after swiping the card
123  // for delay_ milliseconds.
124  ready_ = true;
125  }
126  }
127 }
128 
130 {
131  return ready_;
132 }
133 
134 void Autodetect::signal(zmqpp::socket &sock)
135 {
136  bool with_card = read_card_strategy_->get_nb_bits();
137  bool with_pin = read_pin_strategy_ && read_pin_strategy_->get_pin().length();
138 
139  zmqpp::message msg;
140  msg << ("S_" + reader_->name());
141  if (with_card && with_pin)
143  else if (with_card)
145  else if (with_pin)
147 
148  if (with_card)
149  msg << read_card_strategy_->get_card_id()
150  << read_card_strategy_->get_nb_bits();
151  if (with_pin)
152  msg << read_pin_strategy_->get_pin();
153 
154  sock.send(msg);
155  reset();
156 }
157 
159 {
161  read_card_strategy_->set_reader(new_ptr);
162  if (read_pin_strategy_)
163  read_pin_strategy_->set_reader(new_ptr);
164 }
165 
167 {
168  ready_ = false;
169  reading_card_ = true;
170  reader_->read_reset();
171  read_card_strategy_->reset();
172 
173  // we hard-reset the pin strategy so we can instantiate a new one
174  // next time. We can then switch between 4 or 8 bits mode without problem.
175  read_pin_strategy_ = nullptr;
176 }
177 
179 {
180  assert(bits == 4 || bits == 8);
181  if (bits == 4)
182  {
183  return std::unique_ptr<PinReading>(
185  }
186  else if (bits == 8)
187  {
188  return std::unique_ptr<PinReading>(
190  }
191  return nullptr;
192 }
Autodetect.hpp
Leosac::Module::Wiegand::Strategy::Autodetect::nowait_
bool nowait_
Definition: Autodetect.hpp:103
Leosac::Module::Wiegand::WiegandReaderImpl
An implementation class that represents a Wiegand Reader.
Definition: WiegandReaderImpl.hpp:41
Leosac::Module::Wiegand::Strategy::Autodetect::Autodetect
Autodetect(WiegandReaderImpl *reader, std::chrono::milliseconds delay, char pin_key_end, bool nowait)
Create a strategy that read whatever it can and tries its best to determine what is was that it read.
Definition: Autodetect.cpp:27
DEBUG
@ DEBUG
Definition: log.hpp:35
Leosac::Auth::SourceType::WIEGAND_PIN
@ WIEGAND_PIN
Message formatting when using a simple PIN code.
Leosac::Module::Wiegand::Strategy::Autodetect::signal
virtual void signal(zmqpp::socket &sock) override
Tells the strategy implementation to send a message to the application containing the received creden...
Definition: Autodetect.cpp:134
Leosac::Auth::SourceType::WIEGAND_CARD_PIN
@ WIEGAND_CARD_PIN
When reading both a card an a PIN code.
Leosac::Module::Wiegand::Strategy::Autodetect::reading_pin_
bool reading_pin_
Definition: Autodetect.hpp:98
Leosac::Module::Wiegand::Strategy::Autodetect::time_card_read_
TimePoint time_card_read_
Definition: Autodetect.hpp:95
Leosac::Module::Wiegand::Strategy::Autodetect::ready_
bool ready_
Definition: Autodetect.hpp:100
Leosac::Module::Wiegand::Strategy::Autodetect::reading_card_
bool reading_card_
Definition: Autodetect.hpp:99
WiegandReaderImpl.hpp
Leosac::Module::Wiegand::Strategy::WiegandStrategy::set_reader
virtual void set_reader(WiegandReaderImpl *new_ptr)
Update the pointer that points back to the associated reader.
Definition: WiegandStrategy.hpp:99
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::Strategy::Autodetect::set_reader
virtual void set_reader(WiegandReaderImpl *new_ptr) override
Update the pointer that points back to the associated reader.
Definition: Autodetect.cpp:158
Leosac::Module::Wiegand::WiegandReaderImpl::counter
int counter() const
Returns the number of bits read.
Definition: WiegandReaderImpl.cpp:203
Leosac::Module::Wiegand::Strategy::Autodetect::read_pin_strategy_
PinReadingUPtr read_pin_strategy_
Definition: Autodetect.hpp:91
Leosac::Module::Wiegand::Strategy::Autodetect::pin_key_end_
char pin_key_end_
Definition: Autodetect.hpp:102
Leosac::Module::Wiegand::Strategy::Autodetect::delay_
std::chrono::milliseconds delay_
Definition: Autodetect.hpp:93
Leosac::Module::Wiegand::Strategy::Autodetect::build_strategy
PinReadingUPtr build_strategy(int bits)
Dynamically instanciate a new strategy based on the number of bits available.
Definition: Autodetect.cpp:178
Leosac::Module::Wiegand::Strategy::WiegandStrategy
The multiple modes available to wiegand reader are implemented through the strategy pattern.
Definition: WiegandStrategy.hpp:50
Leosac::Module::Wiegand::Strategy
Definition: Autodetect.hpp:31
Leosac::Module::Wiegand::Strategy::Autodetect::timeout
virtual void timeout() override
This is called when the module detect a timeout.
Definition: Autodetect.cpp:43
Leosac::Module::Wiegand::Strategy::Autodetect::last_pin_read_
TimePoint last_pin_read_
Definition: Autodetect.hpp:96
Leosac::Module::Wiegand::Strategy::PinReadingUPtr
std::unique_ptr< PinReading > PinReadingUPtr
Definition: StrategiesFwd.hpp:33
Leosac::Module::Wiegand::Strategy::Autodetect::completed
virtual bool completed() const override
Did the strategy gather needed data? If this function returns true, that means that the strategy impl...
Definition: Autodetect.cpp:129
Leosac::Module::Wiegand::Strategy::Autodetect::read_card_strategy_
CardReadingUPtr read_card_strategy_
Definition: Autodetect.hpp:90
Leosac::Module::Wiegand::Strategy::SimpleWiegandStrategy
Implementation of a wiegand card only strategy.
Definition: SimpleWiegandStrategy.hpp:35
log.hpp
Leosac::Module::Wiegand
Provide support for Wiegand devices.
Definition: Autodetect.hpp:29
Leosac::Module::Wiegand::Strategy::Autodetect::reset
void reset() override
Reset self.
Definition: Autodetect.cpp:166
Leosac::Module::Wiegand::Strategy::Autodetect::check_timeout
void check_timeout()
Called when timeout() was called but nothing was read.
Definition: Autodetect.cpp:87
Leosac::Module::Wiegand::Strategy::WiegandStrategy::reader_
WiegandReaderImpl * reader_
Definition: WiegandStrategy.hpp:110
Leosac::Module::Wiegand::Strategy::WiegandPinNBitsOnly
Strategy for ready PIN only.
Definition: WiegandPinNBitsOnly.hpp:38
Leosac::Module::Wiegand::WiegandReaderImpl::name
const std::string & name() const
Returns the name of this reader.
Definition: WiegandReaderImpl.cpp:208
Leosac::Auth::SourceType::SIMPLE_WIEGAND
@ SIMPLE_WIEGAND
This define message formatting for data source SIMPLE_WIEGAND.