Initial commit
This commit is contained in:
commit
af6dcf2629
|
@ -0,0 +1,5 @@
|
|||
*.config
|
||||
*.creator
|
||||
*.creator.*
|
||||
*.files
|
||||
*.includes
|
|
@ -0,0 +1,52 @@
|
|||
#include "ArduinoGpio.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
ArduinoGpio::ArduinoGpio(int pin, bool initialValue, IGpio::Mode initialMode):
|
||||
pin(pin)
|
||||
{
|
||||
/* There is no protection to prevent from creation of multiple instances
|
||||
* of single pin, as Arduino does not support C++ exceptions.
|
||||
* Only one parent object may own instance of a pin.
|
||||
*/
|
||||
write(initialValue);
|
||||
setMode((initialMode));
|
||||
}
|
||||
|
||||
ArduinoGpio::~ArduinoGpio()
|
||||
{
|
||||
setMode(Mode::Input);
|
||||
write(false);
|
||||
}
|
||||
|
||||
bool ArduinoGpio::read()
|
||||
{
|
||||
return (digitalRead(pin) != 0);
|
||||
}
|
||||
|
||||
void ArduinoGpio::write(bool newValue)
|
||||
{
|
||||
digitalWrite(pin, newValue ? HIGH : LOW);
|
||||
}
|
||||
|
||||
IGpio::Mode ArduinoGpio::getMode()
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
|
||||
void ArduinoGpio::setMode(IGpio::Mode newMode)
|
||||
{
|
||||
mode = newMode;
|
||||
pinMode(pin, toAdruinoMode(newMode));
|
||||
}
|
||||
|
||||
int ArduinoGpio::toAdruinoMode(IGpio::Mode mode)
|
||||
{
|
||||
switch(mode) {
|
||||
case Mode::Input:
|
||||
return INPUT;
|
||||
case Mode::InputPullup:
|
||||
return INPUT_PULLUP;
|
||||
case Mode::Output:
|
||||
return OUTPUT;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef ARDUINOGPIO_H
|
||||
#define ARDUINOGPIO_H
|
||||
|
||||
#include "IGpio.h"
|
||||
|
||||
class ArduinoGpio : public IGpio
|
||||
{
|
||||
public:
|
||||
ArduinoGpio(int pin, bool initialValue, Mode initialMode);
|
||||
virtual ~ArduinoGpio();
|
||||
virtual bool read();
|
||||
virtual void write(bool newValue);
|
||||
virtual Mode getMode();
|
||||
virtual void setMode(Mode newMode);
|
||||
|
||||
private:
|
||||
int pin;
|
||||
Mode mode;
|
||||
int toAdruinoMode(Mode mode);
|
||||
};
|
||||
|
||||
#endif // ARDUINOGPIO_H
|
|
@ -0,0 +1,63 @@
|
|||
#include "ArduinoSerialLogger.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
ArduinoSerialLogger::ArduinoSerialLogger(Serial_ &hardwareSerial):
|
||||
hardwareSerial(hardwareSerial)
|
||||
{
|
||||
hardwareSerial.begin(DEBUG_CONSOLE_BAUD);
|
||||
}
|
||||
|
||||
ArduinoSerialLogger::~ArduinoSerialLogger()
|
||||
{
|
||||
hardwareSerial.end();
|
||||
}
|
||||
|
||||
void ArduinoSerialLogger::debug(const char *format, ...) const
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
formatLog("DBG/", format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void ArduinoSerialLogger::info(const char *format, ...) const
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
formatLog("INF/", format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void ArduinoSerialLogger::warning(const char *format, ...) const
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
formatLog("WRN/", format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void ArduinoSerialLogger::error(const char *format, ...) const
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
formatLog("ERR/", format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void ArduinoSerialLogger::flush() const
|
||||
{
|
||||
hardwareSerial.flush();
|
||||
}
|
||||
|
||||
void ArduinoSerialLogger::formatLog(const char *level, const char *format, va_list args) const
|
||||
{
|
||||
char newFormat[128];
|
||||
/* This is the least crappy solution I came up with at 23:40 after a beer.
|
||||
* sstream is not available on this platform.
|
||||
* CAN YOU SPOT THE BUG? */
|
||||
snprintf(newFormat, sizeof(newFormat), "%s%s\n", level, format);
|
||||
|
||||
char buffer[256];
|
||||
vsnprintf(buffer, sizeof(buffer), newFormat, args);
|
||||
hardwareSerial.print(buffer);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef ARDUINOSERIALLOGGER_H
|
||||
#define ARDUINOSERIALLOGGER_H
|
||||
|
||||
#include "ILogger.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
#define Serial_ HardwareSerial
|
||||
class ArduinoSerialLogger : public ILogger
|
||||
{
|
||||
public:
|
||||
explicit ArduinoSerialLogger(Serial_& hardwareSerial);
|
||||
virtual ~ArduinoSerialLogger();
|
||||
|
||||
virtual void debug(const char *format, ...) const;
|
||||
virtual void info(const char *format, ...) const;
|
||||
virtual void warning(const char* format, ...) const;
|
||||
virtual void error(const char* format, ...) const;
|
||||
|
||||
virtual void flush() const;
|
||||
|
||||
private:
|
||||
enum {
|
||||
DEBUG_CONSOLE_BAUD = 9600
|
||||
};
|
||||
|
||||
void formatLog(const char* level, const char* format, va_list args) const;
|
||||
|
||||
Serial_& hardwareSerial;
|
||||
};
|
||||
|
||||
#endif // ARDUINOSERIALLOGGER_H
|
|
@ -0,0 +1,29 @@
|
|||
#include "DoorLock.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
DoorLock::DoorLock(IGpio &gpio, DoorLock::ActiveState activeState, DoorLock::TMilliseconds openTime):
|
||||
gpio(gpio),
|
||||
activeState(activeState),
|
||||
openTime(openTime)
|
||||
{
|
||||
deactivate();
|
||||
gpio.setMode(IGpio::Mode::Output);
|
||||
}
|
||||
|
||||
void DoorLock::open()
|
||||
{
|
||||
activate();
|
||||
delay(openTime);
|
||||
deactivate();
|
||||
}
|
||||
|
||||
void DoorLock::activate()
|
||||
{
|
||||
gpio.write(activeState == ActiveState::High);
|
||||
}
|
||||
|
||||
void DoorLock::deactivate()
|
||||
{
|
||||
gpio.write(activeState != ActiveState::High);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef DOORLOCK_H
|
||||
#define DOORLOCK_H
|
||||
|
||||
#include "IGpio.h"
|
||||
|
||||
class DoorLock
|
||||
{
|
||||
public:
|
||||
enum class ActiveState {
|
||||
Low,
|
||||
High,
|
||||
};
|
||||
typedef int TMilliseconds;
|
||||
|
||||
DoorLock(IGpio& gpio, ActiveState activeState, TMilliseconds openTime);
|
||||
void open();
|
||||
|
||||
private:
|
||||
void activate();
|
||||
void deactivate();
|
||||
|
||||
IGpio& gpio;
|
||||
ActiveState activeState;
|
||||
TMilliseconds openTime;
|
||||
};
|
||||
|
||||
#endif // DOORLOCK_H
|
|
@ -0,0 +1,61 @@
|
|||
#include "DoorLockController.h"
|
||||
|
||||
DoorLockController::DoorLockController() :
|
||||
logger(Serial),
|
||||
greenLedGpio(LED_GREEN_PIN, false, IGpio::Mode::Output),
|
||||
redLedGpio(LED_RED_PIN, false, IGpio::Mode::Output),
|
||||
doorLockGpio(DOOR_PIN, false, IGpio::Mode::Output),
|
||||
statusLed(redLedGpio, greenLedGpio),
|
||||
doorLock(doorLockGpio, DoorLock::ActiveState::Low, DOOR_OPEN_TIME_MS),
|
||||
nfcAuthenticator(NFC_SLAVE_SELECT_PIN, NFC_RESET_PIN, logger),
|
||||
oneWireAuthenticator(ONEWIRE_PIN, logger),
|
||||
authenticators{&nfcAuthenticator, &oneWireAuthenticator},
|
||||
unauthorizedAccess(false),
|
||||
heartbeatCounter(0)
|
||||
{
|
||||
logger.info("Ready. Waiting for keys.");
|
||||
}
|
||||
|
||||
void DoorLockController::heartbeat()
|
||||
{
|
||||
heartbeatCounter = (heartbeatCounter == BLINK_INTERVAL_CYCLES - 1) ? 0 : heartbeatCounter+1;
|
||||
if(heartbeatCounter == 0)
|
||||
statusLed.setState(unauthorizedAccess ? DualColorLed::State::Red : DualColorLed::State::Green);
|
||||
}
|
||||
|
||||
void DoorLockController::checkForKeys()
|
||||
{
|
||||
for(IAuthenticator* authenticator : authenticators) {
|
||||
Key key = authenticator->getKey();
|
||||
if(!key.isValid())
|
||||
continue;
|
||||
|
||||
if(keyDatabase.contains(key))
|
||||
{
|
||||
statusLed.setState(DualColorLed::State::Green);
|
||||
logger.info("Access granted.");
|
||||
unauthorizedAccess = false;
|
||||
doorLock.open();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
statusLed.setState(DualColorLed::State::Red);
|
||||
logger.error("ACCESS DENIED!");
|
||||
unauthorizedAccess = true;
|
||||
delay(DOOR_OPEN_TIME_MS);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoorLockController::run()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
heartbeat();
|
||||
checkForKeys();
|
||||
statusLed.setState(DualColorLed::State::Off);
|
||||
delay(POLLING_INTERVAL_MS);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef CDOORLOCKCONTROLLER_H
|
||||
#define CDOORLOCKCONTROLLER_H
|
||||
|
||||
#include "ArduinoGpio.h"
|
||||
#include "ArduinoSerialLogger.h"
|
||||
|
||||
#include "DoorLock.h"
|
||||
#include "NfcAuthenticator.h"
|
||||
#include "OneWireAuthenticator.h"
|
||||
#include "HardcodedKeyStorage.h"
|
||||
#include "DualColorLed.h"
|
||||
|
||||
class DoorLockController
|
||||
{
|
||||
public:
|
||||
DoorLockController();
|
||||
void run();
|
||||
|
||||
private:
|
||||
enum {
|
||||
NFC_SLAVE_SELECT_PIN = 10,
|
||||
NFC_RESET_PIN = 9,
|
||||
ONEWIRE_PIN = 8,
|
||||
DOOR_PIN = 4,
|
||||
LED_RED_PIN = 3,
|
||||
LED_GREEN_PIN = 2,
|
||||
DOOR_OPEN_TIME_MS = 3000,
|
||||
NUM_AUTHENTICATORS=2,
|
||||
POLLING_INTERVAL_MS = 250,
|
||||
BLINK_INTERVAL_CYCLES = 20
|
||||
};
|
||||
|
||||
void heartbeat();
|
||||
void checkForKeys();
|
||||
|
||||
ArduinoSerialLogger logger;
|
||||
ArduinoGpio greenLedGpio, redLedGpio, doorLockGpio;
|
||||
|
||||
DualColorLed statusLed;
|
||||
DoorLock doorLock;
|
||||
NfcAuthenticator nfcAuthenticator;
|
||||
OneWireAuthenticator oneWireAuthenticator;
|
||||
IAuthenticator* authenticators[NUM_AUTHENTICATORS];
|
||||
HardcodedKeyStorage keyDatabase;
|
||||
|
||||
bool unauthorizedAccess;
|
||||
short heartbeatCounter;
|
||||
};
|
||||
|
||||
#endif // CDOORLOCKCONTROLLER_H
|
|
@ -0,0 +1,37 @@
|
|||
#include "DualColorLed.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
DualColorLed::DualColorLed(IGpio& redGpio, IGpio& greenGpio):
|
||||
redGpio(redGpio),
|
||||
greenGpio(greenGpio),
|
||||
currentState(State::Off)
|
||||
{
|
||||
redGpio.write(false);
|
||||
greenGpio.write(false);
|
||||
redGpio.setMode(IGpio::Mode::Output);
|
||||
greenGpio.setMode(IGpio::Mode::Output);
|
||||
}
|
||||
|
||||
void DualColorLed::setState(DualColorLed::State newState)
|
||||
{
|
||||
if(currentState == newState)
|
||||
return;
|
||||
|
||||
currentState = newState;
|
||||
|
||||
switch(newState) {
|
||||
case State::Off:
|
||||
redGpio.write(false);
|
||||
greenGpio.write(false);
|
||||
return;
|
||||
case State::Red:
|
||||
redGpio.write(true);
|
||||
greenGpio.write(false);
|
||||
return;
|
||||
case State::Green:
|
||||
redGpio.write(false);
|
||||
greenGpio.write(true);
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef DUALCOLORLED_H
|
||||
#define DUALCOLORLED_H
|
||||
|
||||
#include "IGpio.h"
|
||||
|
||||
class DualColorLed
|
||||
{
|
||||
public:
|
||||
enum class State {
|
||||
Off,
|
||||
Red,
|
||||
Green
|
||||
};
|
||||
DualColorLed(IGpio& redGpio, IGpio& greenGpio);
|
||||
|
||||
void setState(State newState);
|
||||
|
||||
private:
|
||||
IGpio& redGpio;
|
||||
IGpio& greenGpio;
|
||||
State currentState;
|
||||
};
|
||||
|
||||
#endif // DUALCOLORLED_H
|
|
@ -0,0 +1,36 @@
|
|||
#include "HardcodedKeyStorage.h"
|
||||
|
||||
HardcodedKeyStorage::HardcodedKeyStorage():
|
||||
keyTable( {
|
||||
MifareClassicKey((const uint8_t[]) { 0x01, 0x02, 0x03, 0x04 }), // SAMPLE. DO NOT USE!
|
||||
})
|
||||
{}
|
||||
|
||||
HardcodedKeyStorage::~HardcodedKeyStorage() {}
|
||||
|
||||
bool HardcodedKeyStorage::contains(const Key& inputKey)
|
||||
{
|
||||
if(!inputKey.isValid())
|
||||
return false;
|
||||
|
||||
for(const Key& keyFromTable: keyTable)
|
||||
{
|
||||
if(inputKey == keyFromTable)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HardcodedKeyStorage::insert(const Key &existingKey, const Key &newKey)
|
||||
{
|
||||
(void) existingKey;
|
||||
(void) newKey;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HardcodedKeyStorage::remove(const Key &key)
|
||||
{
|
||||
(void) key;
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef HARDCODEDKEYSTORAGE_H
|
||||
#define HARDCODEDKEYSTORAGE_H
|
||||
|
||||
#include "IKeyStorage.h"
|
||||
|
||||
class HardcodedKeyStorage: public IKeyStorage
|
||||
{
|
||||
public:
|
||||
HardcodedKeyStorage();
|
||||
|
||||
virtual ~HardcodedKeyStorage();
|
||||
virtual bool contains(const Key &inputKey);
|
||||
virtual bool insert(const Key &existingKey, const Key &newKey);
|
||||
virtual bool remove(const Key &key);
|
||||
|
||||
private:
|
||||
enum {
|
||||
NUMBER_OF_ENTRIES = 1,
|
||||
};
|
||||
|
||||
Key keyTable[NUMBER_OF_ENTRIES];
|
||||
};
|
||||
|
||||
#endif // HARDCODEDKEYSTORAGE_H
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef IAUTHENTICATOR_H
|
||||
#define IAUTHENTICATOR_H
|
||||
|
||||
#include "Key.h"
|
||||
|
||||
class IAuthenticator
|
||||
{
|
||||
public:
|
||||
virtual ~IAuthenticator() {};
|
||||
|
||||
virtual Key getKey() = 0;
|
||||
};
|
||||
|
||||
#endif // IAUTHENTICATOR_H
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef IGPIO_H
|
||||
#define IGPIO_H
|
||||
|
||||
class IGpio
|
||||
{
|
||||
public:
|
||||
enum class Mode {
|
||||
Input,
|
||||
InputPullup,
|
||||
Output,
|
||||
};
|
||||
|
||||
virtual ~IGpio() {}
|
||||
virtual bool read() = 0;
|
||||
virtual void write(bool value) = 0;
|
||||
virtual Mode getMode() = 0;
|
||||
virtual void setMode(Mode mode) = 0;
|
||||
};
|
||||
|
||||
#endif // IGPIO_H
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef IKEYSTORAGE_H
|
||||
#define IKEYSTORAGE_H
|
||||
|
||||
#include "Key.h"
|
||||
|
||||
class IKeyStorage
|
||||
{
|
||||
public:
|
||||
virtual ~IKeyStorage() {}
|
||||
|
||||
virtual bool contains(const Key& key) = 0;
|
||||
virtual bool insert(const Key& existingKey, const Key& newKey) = 0;
|
||||
virtual bool remove(const Key& key) = 0;
|
||||
};
|
||||
|
||||
#endif // IKEYSTORAGE_H
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef ILOGGER_H
|
||||
#define ILOGGER_H
|
||||
|
||||
class ILogger
|
||||
{
|
||||
public:
|
||||
virtual ~ILogger() {}
|
||||
|
||||
virtual void debug(const char *format, ...) const = 0;
|
||||
virtual void info(const char *format, ...) const = 0;
|
||||
virtual void warning(const char* format, ...) const = 0;
|
||||
virtual void error(const char* format, ...) const = 0;
|
||||
|
||||
virtual void flush() const;
|
||||
};
|
||||
|
||||
#endif // ILOGGER_H
|
|
@ -0,0 +1,48 @@
|
|||
#include "Key.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
Key::Key() :
|
||||
type(KeyType::Invalid),
|
||||
size(0),
|
||||
value()
|
||||
{
|
||||
}
|
||||
|
||||
Key::Key(KeyType type, size_t size, const void *data):
|
||||
type(type),
|
||||
size(size),
|
||||
value()
|
||||
{
|
||||
memcpy(value, data, size);
|
||||
}
|
||||
|
||||
bool Key::isValid() const
|
||||
{
|
||||
return type != KeyType::Invalid;
|
||||
}
|
||||
|
||||
bool Key::operator==(const Key &rhs) const
|
||||
{
|
||||
if(type == KeyType::Invalid)
|
||||
return type == rhs.type;
|
||||
|
||||
return type == rhs.type && size == rhs.size && isBufferEqual(value, rhs.value, size);
|
||||
}
|
||||
|
||||
bool Key::isBufferEqual(const unsigned char *lhs, const unsigned char *rhs, size_t size) const
|
||||
{
|
||||
unsigned char maskOfDifferences = 0;
|
||||
|
||||
/** This comparison by design checks whole buffers to harden timing attacks */
|
||||
for(size_t i = 0; i < size; ++i)
|
||||
maskOfDifferences |= lhs[i] ^ rhs[i];
|
||||
|
||||
return (maskOfDifferences == 0);
|
||||
}
|
||||
|
||||
DallasIButtonKey::DallasIButtonKey(const uint8_t uid[]):
|
||||
Key(KeyType::iButton, UID_SIZE, uid) {}
|
||||
|
||||
MifareClassicKey::MifareClassicKey(const uint8_t nuid[]):
|
||||
Key(KeyType::MifareClassic, NUID_SIZE, nuid) {}
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef KEY_H
|
||||
#define KEY_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
class Key {
|
||||
public:
|
||||
enum {
|
||||
MAX_KEY_SIZE = 8
|
||||
};
|
||||
|
||||
enum class KeyType
|
||||
{
|
||||
Invalid = 0,
|
||||
MifareClassic = 1,
|
||||
iButton = 2,
|
||||
};
|
||||
|
||||
Key();
|
||||
|
||||
bool isValid() const;
|
||||
bool operator==(const Key& rhs) const;
|
||||
|
||||
protected:
|
||||
Key(KeyType type, size_t size, const void* data);
|
||||
|
||||
private:
|
||||
bool isBufferEqual(const unsigned char *lhs, const unsigned char* rhs, size_t size) const;
|
||||
|
||||
KeyType type;
|
||||
size_t size;
|
||||
unsigned char value[MAX_KEY_SIZE];
|
||||
};
|
||||
|
||||
class DallasIButtonKey: public Key {
|
||||
public:
|
||||
enum {UID_SIZE = 8};
|
||||
explicit DallasIButtonKey(const uint8_t uid[UID_SIZE]);
|
||||
};
|
||||
|
||||
class MifareClassicKey: public Key {
|
||||
public:
|
||||
enum {NUID_SIZE = 4};
|
||||
explicit MifareClassicKey(const uint8_t nuid[NUID_SIZE]);
|
||||
};
|
||||
|
||||
#endif // KEY_H
|
|
@ -0,0 +1,54 @@
|
|||
#include "NfcAuthenticator.h"
|
||||
|
||||
#include "ILogger.h"
|
||||
#include <SPI.h>
|
||||
|
||||
NfcAuthenticator::NfcAuthenticator(int nfcSlaveSelectPin, int nfcResetPin, const ILogger &logger):
|
||||
rfid(nfcSlaveSelectPin, nfcResetPin),
|
||||
logger(logger)
|
||||
{
|
||||
SPI.begin();
|
||||
rfid.PCD_Init();
|
||||
}
|
||||
|
||||
NfcAuthenticator::~NfcAuthenticator()
|
||||
{}
|
||||
|
||||
Key NfcAuthenticator::getKey()
|
||||
{
|
||||
if(!initializeCard())
|
||||
return Key();
|
||||
|
||||
uint8_t *nuid = rfid.uid.uidByte;
|
||||
logger.debug("Mifare Classic tag detected, NUID: %02hhX %02hhX %02hhX %02hhX", nuid[0], nuid[1], nuid[2], nuid[3]);
|
||||
|
||||
releaseCard();
|
||||
|
||||
return MifareClassicKey(rfid.uid.uidByte);
|
||||
}
|
||||
|
||||
bool NfcAuthenticator::initializeCard()
|
||||
{
|
||||
if (!rfid.PICC_IsNewCardPresent())
|
||||
return false;
|
||||
|
||||
if (!rfid.PICC_ReadCardSerial())
|
||||
return false;
|
||||
|
||||
auto piccType = rfid.PICC_GetType(rfid.uid.sak);
|
||||
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
|
||||
piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
|
||||
piccType != MFRC522::PICC_TYPE_MIFARE_4K)
|
||||
{
|
||||
logger.warning("Invalid Mifare tag type: %s", rfid.PICC_GetTypeName(piccType));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NfcAuthenticator::releaseCard()
|
||||
{
|
||||
rfid.PICC_HaltA();
|
||||
rfid.PCD_StopCrypto1();
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef NFCAUTHENTICATOR_H
|
||||
#define NFCAUTHENTICATOR_H
|
||||
|
||||
#include "IAuthenticator.h"
|
||||
|
||||
#include <MFRC522.h>
|
||||
|
||||
class ILogger;
|
||||
|
||||
class NfcAuthenticator: public IAuthenticator
|
||||
{
|
||||
public:
|
||||
NfcAuthenticator(int nfcSlaveSelectPin, int nfcResetPin, const ILogger& logger);
|
||||
virtual ~NfcAuthenticator();
|
||||
virtual Key getKey();
|
||||
|
||||
|
||||
private:
|
||||
bool initializeCard();
|
||||
void releaseCard();
|
||||
MFRC522 rfid;
|
||||
const ILogger& logger;
|
||||
};
|
||||
|
||||
#endif // NFCAUTHENTICATOR_H
|
|
@ -0,0 +1,27 @@
|
|||
#include "OneWireAuthenticator.h"
|
||||
|
||||
#include "ILogger.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
OneWireAuthenticator::OneWireAuthenticator(int interfacePin, const ILogger& logger):
|
||||
oneWire(interfacePin),
|
||||
logger(logger)
|
||||
{
|
||||
pinMode(interfacePin, INPUT_PULLUP);
|
||||
}
|
||||
|
||||
Key OneWireAuthenticator::getKey()
|
||||
{
|
||||
uint8_t key[ONEWIRE_KEY_SIZE];
|
||||
|
||||
if (!oneWire.search(key)) {
|
||||
oneWire.reset_search();
|
||||
return Key();
|
||||
}
|
||||
|
||||
logger.debug("1-Wire device detected, S/N: %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX",
|
||||
key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]);
|
||||
|
||||
oneWire.reset();
|
||||
return DallasIButtonKey(key);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef ONEWIREAUTHENTICATOR_H
|
||||
#define ONEWIREAUTHENTICATOR_H
|
||||
|
||||
#include "IAuthenticator.h"
|
||||
|
||||
#include <OneWire.h>
|
||||
|
||||
class ILogger;
|
||||
|
||||
class OneWireAuthenticator: public IAuthenticator
|
||||
{
|
||||
public:
|
||||
OneWireAuthenticator(int interfacePin, const ILogger& logger);
|
||||
virtual Key getKey();
|
||||
private:
|
||||
enum {
|
||||
ONEWIRE_KEY_SIZE = 8,
|
||||
};
|
||||
|
||||
OneWire oneWire;
|
||||
const ILogger& logger;
|
||||
};
|
||||
|
||||
#endif // ONEWIREAUTHENTICATOR_H
|
|
@ -0,0 +1,8 @@
|
|||
#include "DoorLockController.h"
|
||||
|
||||
void setup() {}
|
||||
|
||||
void loop()
|
||||
{
|
||||
DoorLockController().run();
|
||||
}
|
Reference in New Issue