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