Compare commits

..

No commits in common. "6d57da3402c61b43c7000eb8da0b0746f7a09a55" and "0b216e2e83c04c4c07b351e821872628fefa1754" have entirely different histories.

8 changed files with 87 additions and 201 deletions

View File

@ -30,9 +30,8 @@
+ Settings pos + Settings pos
+ WifiSSID - terminator 0x00 - Pos.: 0-31 (00 - 1F) + WifiSSID - terminator 0x00 - Pos.: 0-31 (00 - 1F)
+ WifiPassword - terminator 0x00 - Pos.: 32-63 (20 - 3F) + WifiPassword - terminator 0x00 - Pos.: 32-63 (20 - 3F)
+ Device IP - 40-43 uint32 + Device IP - 40-43
+ Subnet 44 - 47 + Subnet 44 - 47
+ Gateway 48 - 4B + Gateway 48 - 4B
+ Mode 0 - station; 1 - client 4C uint8 + Flags:
+ AuthError Timeout (secs) 4D + Mode 0 - station; 1 - client 4C
+ OpenLock hold (secs) 4E

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,5 @@
#include "Config.h" #include "Config.h"
#define CONFIG_SIZE 0x4C
Config::Config() Config::Config()
{ {
if (!LittleFS.begin()) if (!LittleFS.begin())
@ -16,14 +16,19 @@ Config::~Config()
bool Config::loadBin() bool Config::loadBin()
{ {
File config_file = LittleFS.open("/settings", "r"); File config_file = LittleFS.open("/settings", "r");
//if (buffer == nullptr) // Allocate only once if(buffer==nullptr)
// buffer = (uint8_t *)malloc(CONFIG_SIZE); buffer = (uint8_t*) malloc(CONFIG_SIZE);
if (config_file.available()) if (config_file.available())
{ {
config_file.read(buffer, CONFIG_SIZE); config_file.read(buffer, CONFIG_SIZE);
buffer[OFFSET_SSID + 0x1F] = 0x00; // ensure ssid and password are terminated with a null character SSID = (char*) buffer;
buffer[OFFSET_PASS + 0x1F] = 0x00; buffer[0x1F] = 0x00;
buffer[0x3F] = 0x00;
PASS = (char*)(buffer + 0x20);
ip = (uint32_t *)(buffer + 0x40);
subnet = (uint32_t *)(buffer + 0x44);
gw = (uint32_t *)(buffer + 0x48);
mode = (uint8_t *)(buffer + 0x4C);
} }
config_file.close(); config_file.close();
return true; return true;
@ -37,12 +42,10 @@ bool Config::saveBin()
config_file.close(); config_file.close();
return true; return true;
} }
bool Config::setSSID(const char *ssid) bool Config::setSSID(const char *ssid){
{
size_t offset = 0; size_t offset = 0;
bool copy = true; bool copy = true;
for (int i = 0; i < 31; i++) for(int i=0; i<31;i++){
{
if(ssid[i]==0x00) if(ssid[i]==0x00)
copy = false; copy = false;
buffer[offset+i] = copy?ssid[i]:0x00; buffer[offset+i] = copy?ssid[i]:0x00;
@ -50,12 +53,10 @@ bool Config::setSSID(const char *ssid)
buffer[offset+31] = '\n'; buffer[offset+31] = '\n';
return true; return true;
} }
bool Config::setPASS(const char *pass) bool Config::setPASS(const char *pass){
{
size_t offset = 0x20; size_t offset = 0x20;
bool copy = true; bool copy = true;
for (int i = 0; i < 31; i++) for(int i=0; i<31;i++){
{
if(pass[i]==0x00) if(pass[i]==0x00)
copy = false; copy = false;
buffer[offset+i] = copy?pass[i]:0x00; buffer[offset+i] = copy?pass[i]:0x00;
@ -63,11 +64,9 @@ bool Config::setPASS(const char *pass)
buffer[offset+31] = '\n'; buffer[offset+31] = '\n';
return true; return true;
} }
void Config::print() void Config::print(){
{
Serial.print("BufferHEX "); Serial.print("BufferHEX ");
for (int i = 0; i < CONFIG_SIZE; i++) for(int i=0; i<CONFIG_SIZE;i++){
{
Serial.print(i,HEX); Serial.print(i,HEX);
Serial.print(">"); Serial.print(">");
Serial.print(buffer[i],HEX); Serial.print(buffer[i],HEX);
@ -78,27 +77,30 @@ void Config::print()
Serial.print("PASS: "); Serial.print("PASS: ");
Serial.println(PASS); Serial.println(PASS);
Serial.print("IP"); Serial.print("IP");
Serial.print(*((uint8_t *)&ip), DEC); Serial.print((uint8_t) *ip, DEC);
Serial.print("."); Serial.print(".");
Serial.print(* (((uint8_t *)&ip + 1)), DEC); Serial.print((uint8_t)*((uint8_t*)ip+1), DEC);
Serial.print("."); Serial.print(".");
Serial.print(* ((uint8_t *)&ip + 2), DEC); Serial.print((uint8_t) *((uint8_t*)ip+2), DEC);
Serial.print("."); Serial.print(".");
Serial.println( * ((uint8_t *)&ip + 3), DEC); Serial.println((uint8_t) *((uint8_t*)ip+3), DEC);
Serial.print("GW"); Serial.print("GW");
Serial.print( * ((uint8_t *)&gw), DEC); Serial.print((uint8_t) *((uint8_t*)gw), DEC);
Serial.print("."); Serial.print(".");
Serial.print( * ((uint8_t *)&gw + 1), DEC); Serial.print((uint8_t) *((uint8_t*)gw+1), DEC);
Serial.print("."); Serial.print(".");
Serial.print( * ((uint8_t *)&gw + 2), DEC); Serial.print((uint8_t) *((uint8_t*)gw+2), DEC);
Serial.print("."); Serial.print(".");
Serial.println( * ((uint8_t *)&gw + 3), DEC); Serial.println((uint8_t) *((uint8_t*)gw+3), DEC);
Serial.print("SUBNET"); Serial.print("SUBNET");
Serial.print( * ((uint8_t *)&subnet), DEC); Serial.print((uint8_t)*((uint8_t*)subnet), DEC);
Serial.print("."); Serial.print(".");
Serial.print( * ((uint8_t *)&subnet + 1), DEC); Serial.print((uint8_t)*((uint8_t*)subnet+1), DEC);
Serial.print("."); Serial.print(".");
Serial.print( * ((uint8_t *)&subnet + 2), DEC); Serial.print((uint8_t)*((uint8_t*)subnet+2), DEC);
Serial.print("."); Serial.print(".");
Serial.println( * ((uint8_t *)&subnet + 3), DEC); Serial.println((uint8_t)*((uint8_t*)subnet+3), DEC);
} }

View File

@ -1,32 +1,20 @@
#pragma once #pragma once
#include "LittleFS.h" #include "LittleFS.h"
#include "ArduinoJson.h" #include "ArduinoJson.h"
#define CONFIG_SIZE 0x4E
#define OFFSET_SSID 0x00
#define OFFSET_PASS 0x20
#define OFFSET_IP 0x40
#define OFFSET_SUBNET 0x44
#define OFFSET_GW 0x48
#define OFFSET_MODE 0x4C
#define OFFSET_FAIL_TIMEOUT 0x4D
#define OFFSET_HOLD_TIME 0x4E
class Config class Config
{ {
private: private:
uint8_t *buffer = (uint8_t *)malloc(CONFIG_SIZE); uint8_t *buffer = nullptr;
public: public:
Config(); Config();
~Config(); ~Config();
const char *SSID = (char *)(buffer + OFFSET_SSID); const char *SSID;
const char *PASS = (char *)(buffer + OFFSET_PASS); const char *PASS;
uint32_t &ip = *((uint32_t*)(buffer+OFFSET_IP)); uint8_t *mode;
uint32_t &subnet = *((uint32_t*)(buffer+OFFSET_SUBNET)); uint32_t *ip;
uint32_t &gw = *((uint32_t*)(buffer+OFFSET_GW)); uint32_t *subnet;
uint8_t &mode = *(buffer + OFFSET_MODE); uint32_t *gw;
uint8_t &fail_timeout = *(buffer+OFFSET_FAIL_TIMEOUT);
uint8_t &hold_time = *(buffer+OFFSET_HOLD_TIME);
bool loadConfig(); bool loadConfig();
bool loadBin(); bool loadBin();
bool saveBin(); bool saveBin();

View File

@ -10,28 +10,10 @@ WebConsole::~WebConsole()
_server->close(); _server->close();
delete (_server); delete (_server);
} }
bool WebConsole::init(Config *config, userdb::UserDb *userdb) bool WebConsole::init(userdb::UserDb *userdb)
{ {
_server = new ESP8266WebServer(80);
this->userdb = userdb; this->userdb = userdb;
this->_config = config;
this->userdb = userdb;
// Wifi Setup
this->_dnsServer = new DNSServer;
WiFi.mode(WIFI_AP);
Serial.print("\t1. Network config... ");
Serial.println(WiFi.softAPConfig(_config->ip, _config->gw, _config->subnet) ? "Ready" : "Failed!");
Serial.print("\t2. DNS config... ");
Serial.println(_dnsServer->start(53, "*", _config->ip) ? "Ready" : "Failed!");
Serial.print("\t3 AP setup <SSID:\"" + String(_config->SSID) + "\"...");
if (strlen(_config->PASS) > 0)
Serial.println(WiFi.softAP(_config->SSID, _config->PASS) ? "Ready" : "Failed!");
else
Serial.println(WiFi.softAP(_config->SSID) ? "Ready" : "Failed!");
WiFi.hostname("Doorlock");
Serial.println("Please connect via http://" +WiFi.softAPIP().toString()+"/");
// Webserver Setup
this->_server = new ESP8266WebServer(80);
const char *headerkeys[] = {"Authentification"}; const char *headerkeys[] = {"Authentification"};
size_t headerkeyssize = sizeof(headerkeys) / sizeof(char *); size_t headerkeyssize = sizeof(headerkeys) / sizeof(char *);
_server->collectHeaders(headerkeys, headerkeyssize); _server->collectHeaders(headerkeys, headerkeyssize);
@ -46,6 +28,7 @@ bool WebConsole::init(Config *config, userdb::UserDb *userdb)
_server->on(UriBraces("/api/user/{}"), HTTPMethod::HTTP_PUT, std::bind(&WebConsole::_createUser, this)); _server->on(UriBraces("/api/user/{}"), HTTPMethod::HTTP_PUT, std::bind(&WebConsole::_createUser, this));
_server->on(UriBraces("/api/user/{}"), HTTPMethod::HTTP_POST, std::bind(&WebConsole::_updateUser, this)); _server->on(UriBraces("/api/user/{}"), HTTPMethod::HTTP_POST, std::bind(&WebConsole::_updateUser, this));
_server->on(UriBraces("/api/config/{}"), std::bind(&WebConsole::_deleteUser, this)); _server->on(UriBraces("/api/config/{}"), std::bind(&WebConsole::_deleteUser, this));
//_server->on("/bypin",std::bind(&WebConsole::_findPin,this));
_server->serveStatic("/", LittleFS, "/s/"); _server->serveStatic("/", LittleFS, "/s/");
_server->onNotFound(std::bind(&WebConsole::_handleUnknown, this)); _server->onNotFound(std::bind(&WebConsole::_handleUnknown, this));
return true; return true;
@ -56,11 +39,9 @@ void WebConsole::attachRfid(Rfid *rfid)
} }
void WebConsole::serve() void WebConsole::serve()
{ {
_dnsServer->processNextRequest();
if (catch_rfid) if (catch_rfid)
{ {
if (millis() - catch_rfid_millis > 2000) if (millis() - catch_rfid_millis > 2000){
{
catch_rfid = 0; catch_rfid = 0;
} }
else if (catch_rfid > 1 && rfid != nullptr && rfid->available()) else if (catch_rfid > 1 && rfid != nullptr && rfid->available())
@ -73,8 +54,7 @@ void WebConsole::serve()
} }
uint8_t WebConsole::isInterceptingRfid() uint8_t WebConsole::isInterceptingRfid()
{ {
if (catch_rfid == 3) if(catch_rfid==3){
{
catch_rfid=2; catch_rfid=2;
return 3; return 3;
} }
@ -128,102 +108,6 @@ void WebConsole::_auth()
else else
_server->send(404, "text/plain", "unknown action"); _server->send(404, "text/plain", "unknown action");
} }
void WebConsole::_settings()
{
_sendCORS();
String action = _server->arg("action");
if (action.equals("update"))
{
uint8_t error = 0b00000000;
uint8_t sucess = 0b00000000;
if (_server->hasArg("SSID"))
{
_config->setSSID(_server->arg("SSID").c_str());
int length = strlen(_config->SSID);
if (length == 0 || length > 31)
error |= 0b00000001;
else
sucess |= 0b00000001;
}
if (_server->hasArg("PASS"))
{
_config->setSSID(_server->arg("PASS").c_str());
int length = strlen(_config->SSID);
if (length == 0 || length > 31)
error |= 0b00000010;
else
sucess |= 0b00000010;
}
if (_server->hasArg("IP"))
{
IPAddress temp;
if (temp.fromString(_server->arg("IP")))
{
_config->ip = temp.v4();
sucess |= 0b00000100;
}
else
error |= 0b00000100;
}
if (_server->hasArg("SUBNET"))
{
IPAddress temp;
if (temp.fromString(_server->arg("SUBNET")))
{
_config->subnet = temp.v4();
sucess |= 0b00001000;
}
else
error |= 0b00001000;
}
if (_server->hasArg("GW"))
{
IPAddress temp;
if (temp.fromString(_server->arg("GW")))
{
_config->gw = temp.v4();
sucess |= 0b00010000;
}
else
error |= 0b00010000;
}
if (_server->hasArg("MODE"))
{
_config->mode = _server->arg("MODE").toInt();
if (_config->mode >= 0 && _config->mode <= 1)
sucess |= 0b00100000;
else
error |= 0b00100000;
}
if (_server->hasArg("FAIL_TIMEOUT"))
{
_config->fail_timeout = _server->arg("FAIL_TIMEOUT").toInt();
if (_config->fail_timeout >= 0 && _config->fail_timeout <= 250)
sucess |= 0b01000000;
else
error |= 0b01000000;
}
if (_server->hasArg("HOLD_TIME"))
{
_config->hold_time = _server->arg("HOLD_TIME").toInt();
if (_config->hold_time > 0 && _config->hold_time <= 250)
sucess |= 0b10000000;
else
error |= 0b10000000;
}
if (error == 0 && sucess > 0)
{ // Save
_config->saveBin();
_server->send(200, "text/json", "{\"status\":\"ok\", \"sucess\":\"" + String(sucess) + "\"}");
}
else if (error > 0)
{ // Rollback
_config->loadBin();
_server->send(200, "text/json", "{\"status\":\"failed\", \"sucess\":\"" + String(sucess) + "\", \"error\":\"" + String(error) + "\"}");
}
}
}
void WebConsole::_sendCORS() void WebConsole::_sendCORS()
{ {
_server->sendHeader("Access-Control-Allow-Origin", "*"); _server->sendHeader("Access-Control-Allow-Origin", "*");

View File

@ -1,6 +1,4 @@
#pragma once #pragma once
#include <ESP8266mDNS.h>
#include <DNSServer.h>
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <ESP8266WebServer.h> #include <ESP8266WebServer.h>
#include <uri/UriBraces.h> #include <uri/UriBraces.h>
@ -9,7 +7,6 @@
#include "ArduinoJson.h" #include "ArduinoJson.h"
#include "UserDb.h" #include "UserDb.h"
#include "Rfid.h" #include "Rfid.h"
#include "Config.h"
#include "AdminAuth.h" #include "AdminAuth.h"
#include "Interface.h" #include "Interface.h"
namespace webconsole namespace webconsole
@ -22,14 +19,13 @@ namespace webconsole
WebConsole(); WebConsole();
~WebConsole(); ~WebConsole();
bool init(Config *config, userdb::UserDb *userdb); bool init(userdb::UserDb *userdb);
void attachRfid(Rfid *rfid); void attachRfid(Rfid *rfid);
void serve(); void serve();
uint8_t isInterceptingRfid(); uint8_t isInterceptingRfid();
private: private:
void _sendCORS(); void _sendCORS();
void _settings();
void _auth(); void _auth();
bool _isAuth(); bool _isAuth();
void _handleUnknown(); void _handleUnknown();
@ -51,8 +47,6 @@ namespace webconsole
_server->send(200, "text/plain", "printed to serial"); _server->send(200, "text/plain", "printed to serial");
f.close(); f.close();
} }
Config *_config;
DNSServer *_dnsServer;
ESP8266WebServer *_server; ESP8266WebServer *_server;
userdb::UserDb *userdb = nullptr; userdb::UserDb *userdb = nullptr;
unsigned long catch_rfid_millis = 0; unsigned long catch_rfid_millis = 0;

View File

@ -8,7 +8,8 @@
#include "WebConsole.h" #include "WebConsole.h"
#include "UserDb.h" #include "UserDb.h"
#include "Config.h" #include "Config.h"
#include <ESP8266mDNS.h>
#include <DNSServer.h>
// File config // File config
Config config; Config config;
userdb::UserDb userdatabase("userdb.csv"); userdb::UserDb userdatabase("userdb.csv");
@ -20,25 +21,44 @@ Rfid rfid;
#define PIN_WIRE_SCL D4 #define PIN_WIRE_SCL D4
Keyboard keyboard(200); Keyboard keyboard(200);
Interface iface; Interface iface;
// Wifi control
IPAddress local_IP(192, 168, 4, 22);
IPAddress gateway(0, 0, 0, 0);
IPAddress subnet(255, 255, 255, 0);
IPAddress dns(192, 168, 178, 1);
DNSServer dnsServer;
void setup() void setup()
{ {
//config.loadConfig();
config.loadBin(); config.loadBin();
Serial.begin(115200); Serial.begin(115200);
Serial.println("Starting System..."); Serial.println("Starting System");
Serial.print("\t1. Network config ->");
WiFi.mode(WIFI_AP);
Serial.println(WiFi.softAPConfig(*config.ip, *config.gw, *config.subnet) ? "Ready" : "Failed!");
Serial.print("\t2 AP setup " + String(config.SSID) + " -> ");
if (strlen(config.PASS) > 0)
Serial.println(WiFi.softAP(config.SSID, config.PASS) ? "Ready" : "Failed!");
else
Serial.println(WiFi.softAP(config.SSID) ? "Ready" : "Failed!");
WiFi.hostname("Doorlock");
dnsServer.start(53, "*", local_IP); // DNS spoofing (Only HTTP)
delay(150);
#ifdef DEBUG #ifdef DEBUG
userdatabase.print_to_serial(); userdatabase.print_to_serial();
#endif #endif
web.init(&config, &userdatabase); web.init(&userdatabase);
keyboard.begin(&Wire); keyboard.begin(&Wire);
rfid.begin(); rfid.begin();
web.attachRfid(&rfid); web.attachRfid(&rfid);
iface.begin(&keyboard); iface.begin(&keyboard);
config.print();
} }
void loop() void loop()
{ {
dnsServer.processNextRequest();
rfid.scan(); rfid.scan();
web.serve(); web.serve();
keyboard.scanAsync(); keyboard.scanAsync();
@ -49,7 +69,6 @@ void loop()
iface.showMessage("WebUI connected", "RFID Found", 1000); iface.showMessage("WebUI connected", "RFID Found", 1000);
else if (iface.pinAvailable() && iface.getState() != Interface::GREET) else if (iface.pinAvailable() && iface.getState() != Interface::GREET)
{ {
unsigned long delta = millis(); unsigned long delta = millis();
login_user = userdatabase.user_by_pin(iface.getPin()); login_user = userdatabase.user_by_pin(iface.getPin());
Serial.println("Query duration: " + String(millis() - delta)); Serial.println("Query duration: " + String(millis() - delta));