97 lines
2.1 KiB
C++
97 lines
2.1 KiB
C++
#pragma once
|
|
|
|
#include <array>
|
|
#include <cstdint>
|
|
|
|
#include "VaultConfig.h"
|
|
|
|
enum class SubmitResult : uint8_t {
|
|
DigitAccepted,
|
|
CorrectCode,
|
|
WrongCode,
|
|
LockedOut,
|
|
InvalidDigit
|
|
};
|
|
|
|
class VaultState {
|
|
public:
|
|
VaultState() : _code(DEFAULT_CODE), _entry{}, _entryLength(0), _failedAttempts(0), _lockoutUntilMs(0) {
|
|
}
|
|
|
|
void setCode(const std::array<uint8_t, CODE_LENGTH> &code) {
|
|
_code = code;
|
|
}
|
|
|
|
const std::array<uint8_t, CODE_LENGTH> &code() const {
|
|
return _code;
|
|
}
|
|
|
|
SubmitResult pushDigit(uint8_t digit, uint32_t nowMs) {
|
|
if (isLockedOut(nowMs)) {
|
|
return SubmitResult::LockedOut;
|
|
}
|
|
if (digit < DIGIT_MIN || digit > DIGIT_MAX) {
|
|
return SubmitResult::InvalidDigit;
|
|
}
|
|
if (_entryLength < CODE_LENGTH) {
|
|
_entry[_entryLength++] = digit;
|
|
}
|
|
|
|
if (_entryLength < CODE_LENGTH) {
|
|
return SubmitResult::DigitAccepted;
|
|
}
|
|
|
|
const bool ok = (_entry == _code);
|
|
clearEntry();
|
|
|
|
if (ok) {
|
|
_failedAttempts = 0;
|
|
return SubmitResult::CorrectCode;
|
|
}
|
|
|
|
++_failedAttempts;
|
|
if (_failedAttempts >= MAX_FAILED_ATTEMPTS) {
|
|
_failedAttempts = 0;
|
|
_lockoutUntilMs = nowMs + LOCKOUT_MS;
|
|
}
|
|
return SubmitResult::WrongCode;
|
|
}
|
|
|
|
bool isLockedOut(uint32_t nowMs) const {
|
|
return nowMs < _lockoutUntilMs;
|
|
}
|
|
|
|
uint32_t lockoutRemainingMs(uint32_t nowMs) const {
|
|
if (!isLockedOut(nowMs)) {
|
|
return 0;
|
|
}
|
|
return _lockoutUntilMs - nowMs;
|
|
}
|
|
|
|
void clearEntry() {
|
|
_entry.fill(0);
|
|
_entryLength = 0;
|
|
}
|
|
|
|
std::size_t enteredLength() const {
|
|
return _entryLength;
|
|
}
|
|
|
|
uint8_t failedAttempts() const {
|
|
return _failedAttempts;
|
|
}
|
|
|
|
void resetLockout() {
|
|
_lockoutUntilMs = 0;
|
|
_failedAttempts = 0;
|
|
clearEntry();
|
|
}
|
|
|
|
private:
|
|
std::array<uint8_t, CODE_LENGTH> _code;
|
|
std::array<uint8_t, CODE_LENGTH> _entry;
|
|
std::size_t _entryLength;
|
|
uint8_t _failedAttempts;
|
|
uint32_t _lockoutUntilMs;
|
|
};
|