Leosac  0.8.0
Open Source Access Control
WiegandPinNBitsOnly.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 "WiegandPinNBitsOnly.hpp"
22 #include <tools/log.hpp>
23 
24 using namespace Leosac::Module::Wiegand;
25 using namespace Leosac::Module::Wiegand::Strategy;
26 
27 template <unsigned int NbBits>
29  WiegandReaderImpl *reader, std::chrono::milliseconds pin_timeout,
30  char pin_end_key)
31  : PinReading(reader)
32  , pin_timeout_(pin_timeout)
33  , pin_end_key_(pin_end_key)
34  , ready_(false)
35 {
36  last_update_ = std::chrono::system_clock::now();
37 }
38 
39 template <unsigned int NbBits>
41 {
42  // If we receive 4 bits per key, the
43  // data looks like this:
44  // buffer[0] = 0101 ...
45  // ^^^^ key pressed.
46  // For 8 bits mode, it looks like this:
47  // buffer[0] = 1010 0101
48  // ~bits^^^^ ^^^^ key value
49  // If this example, the key pressed is '5'.
50  DEBUG("Buffer value = " << (unsigned int)input);
51  unsigned int n = 0;
52  for (int i = 0; i < 4; ++i)
53  {
54  bool v = ((input >> (7 - i)) & 0x01);
55  if (NbBits == 8)
56  v = !v;
57  n |= v << (3 - i);
58  }
59  // this deduced from manual testing. Value for '#' and '*'.
60  // 10 -> *
61  // 11 -> #
62  if (n == 10)
63  return '*';
64  else if (n == 11)
65  return '#';
66  else
67  return std::to_string(n).at(0);
68 }
69 
70 template <unsigned int NbBits>
72 {
73  static_assert(NbBits == 4 || NbBits == 8,
74  "Must either be 4 or 8 bits per key pressed");
75  using namespace std::chrono;
76  auto elapsed_ms =
77  duration_cast<milliseconds>(system_clock::now() - last_update_);
78 
79  if (!reader_->counter())
80  {
81  if (elapsed_ms > pin_timeout_)
82  end_of_input();
83  return;
84  }
85 
86  if (reader_->counter() != NbBits)
87  {
88  WARN("Expected number of bits invalid. ("
89  << reader_->counter() << " but we expected " << NbBits << ")");
90  reset();
91  return;
92  }
93 
94  last_update_ = system_clock::now();
95  char c = extract_from_raw(reader_->buffer()[0]);
96  if (c == pin_end_key_)
97  {
98  end_of_input();
99  }
100  else
101  inputs_ += c;
102  reader_->read_reset();
103 }
104 
105 template <unsigned int NbBits>
107 {
108  if (inputs_.length())
109  ready_ = true;
110  else
111  ready_ = false;
112 }
113 
114 template <unsigned int NbBits>
116 {
117  return ready_;
118 }
119 
120 template <unsigned int NbBits>
121 void WiegandPinNBitsOnly<NbBits>::signal(zmqpp::socket &sock)
122 {
123  assert(ready_);
124  assert(inputs_.length());
125  DEBUG("Sending PIN Code: " << inputs_);
126  zmqpp::message msg;
127  msg << ("S_" + reader_->name()) << Leosac::Auth::SourceType::WIEGAND_PIN
128  << inputs_;
129  sock.send(msg);
130  reset();
131 }
132 
133 template <unsigned int NbBits>
134 const std::string &WiegandPinNBitsOnly<NbBits>::get_pin() const
135 {
136  return inputs_;
137 }
138 
139 template <unsigned int NbBits>
141 {
142  reader_->read_reset();
143  ready_ = false;
144  inputs_ = "";
145  last_update_ = std::chrono::system_clock::now();
146 }
147 
148 namespace Leosac
149 {
150 namespace Module
151 {
152 namespace Wiegand
153 {
154 namespace Strategy
155 {
156 template class WiegandPinNBitsOnly<4>;
157 template class WiegandPinNBitsOnly<8>;
158 }
159 }
160 }
161 }
Leosac::Module::Wiegand::Strategy::WiegandPinNBitsOnly::extract_from_raw
char extract_from_raw(uint8_t input) const
Extract the character that was pressed from raw data.
Definition: WiegandPinNBitsOnly.cpp:40
WiegandPinNBitsOnly.hpp
WARN
@ WARN
Definition: log.hpp:33
Leosac::Module::Wiegand::Strategy::WiegandPinNBitsOnly::WiegandPinNBitsOnly
WiegandPinNBitsOnly(WiegandReaderImpl *reader, std::chrono::milliseconds pin_timeout, char pin_end_key)
Create a strategy that read N bits-per-key PIN code.
Definition: WiegandPinNBitsOnly.cpp:28
Leosac::Module::Wiegand::WiegandReaderImpl
An implementation class that represents a Wiegand Reader.
Definition: WiegandReaderImpl.hpp:41
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::PinReading
Interface for a strategy that read a PIN code.
Definition: PinReading.hpp:37
Leosac::Module::Wiegand::Strategy::WiegandPinNBitsOnly::timeout
virtual void timeout() override
This is called when the module detect a timeout.
Definition: WiegandPinNBitsOnly.cpp:71
WiegandReaderImpl.hpp
Leosac::Module::Wiegand::Strategy::WiegandPinNBitsOnly::reset
virtual void reset() override
Reset the strategy, meaning that the next time timeout() is called the behavior should be the same th...
Definition: WiegandPinNBitsOnly.cpp:140
Leosac
This is the header file for a generated source file, GitSHA1.cpp.
Definition: APIStatusCode.hpp:22
Leosac::Module::Wiegand::Strategy::WiegandPinNBitsOnly::get_pin
virtual const std::string & get_pin() const override
Retrieve the pin code that was read from the reader.
Definition: WiegandPinNBitsOnly.cpp:134
Leosac::Module::Wiegand::Strategy
Definition: Autodetect.hpp:31
Leosac::Module::Wiegand::Strategy::WiegandPinNBitsOnly::end_of_input
void end_of_input()
Timeout or pin_end_key read.
Definition: WiegandPinNBitsOnly.cpp:106
Leosac::Module::Wiegand::Strategy::WiegandPinNBitsOnly::completed
virtual bool completed() const override
Did the strategy gather needed data? If this function returns true, that means that the strategy impl...
Definition: WiegandPinNBitsOnly.cpp:115
log.hpp
Leosac::Module::Wiegand
Provide support for Wiegand devices.
Definition: Autodetect.hpp:29
Leosac::Module::Wiegand::Strategy::WiegandPinNBitsOnly
Strategy for ready PIN only.
Definition: WiegandPinNBitsOnly.hpp:38
Leosac::Module::Wiegand::Strategy::WiegandPinNBitsOnly::last_update_
TimePoint last_update_
Definition: WiegandPinNBitsOnly.hpp:81
Leosac::Module::Wiegand::Strategy::WiegandPinNBitsOnly::signal
virtual void signal(zmqpp::socket &sock) override
Tells the strategy implementation to send a message to the application containing the received creden...
Definition: WiegandPinNBitsOnly.cpp:121