mirror of
https://github.com/binary-kitchen/doorlockd
synced 2024-12-22 10:24:26 +01:00
Added program options
This commit is contained in:
parent
409a31ddf2
commit
b369bdbb70
@ -10,13 +10,15 @@ configure_file (
|
|||||||
"${PROJECT_BINARY_DIR}/config.h"
|
"${PROJECT_BINARY_DIR}/config.h"
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories("${PROJECT_BINARY_DIR}")
|
include_directories(${PROJECT_BINARY_DIR})
|
||||||
|
include_directories(${Boost_INCLUDE_DIRS})
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -ggdb -Wall -pedantic -Weffc++ -Wextra")
|
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -ggdb -Wall -pedantic -Weffc++ -Wextra")
|
||||||
set(CMAKE_CXX_FLAGS "-O2 -Wall -pedantic -Wextra -Weffc++")
|
set(CMAKE_CXX_FLAGS "-O2 -Wall -pedantic -Wextra -Weffc++")
|
||||||
set(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb -Wall -pedantic -Wextra")
|
set(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb -Wall -pedantic -Wextra")
|
||||||
set(CMAKE_C_FLAGS "-O2 -Wall -pedantic -Wextra")
|
set(CMAKE_C_FLAGS "-O2 -Wall -pedantic -Wextra")
|
||||||
|
|
||||||
|
find_package(Boost 1.55.0 COMPONENTS program_options REQUIRED)
|
||||||
|
|
||||||
set(SRCS
|
set(SRCS
|
||||||
main.cpp
|
main.cpp
|
||||||
@ -32,7 +34,7 @@ epaper/bsp.c
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_executable(doorlockd ${SRCS})
|
add_executable(doorlockd ${SRCS})
|
||||||
target_link_libraries(doorlockd wiringPi jsoncpp ldap)
|
target_link_libraries(doorlockd wiringPi jsoncpp ldap ${Boost_LIBRARIES})
|
||||||
|
|
||||||
install(TARGETS doorlockd DESTINATION sbin)
|
install(TARGETS doorlockd DESTINATION sbin)
|
||||||
install(FILES img/template.png DESTINATION share/doorlockd)
|
install(FILES img/template.png DESTINATION share/doorlockd)
|
||||||
|
1
config.h.in
Normal file → Executable file
1
config.h.in
Normal file → Executable file
@ -9,7 +9,6 @@
|
|||||||
#define DEFAULT_LOG_LEVEL LogLevel::info
|
#define DEFAULT_LOG_LEVEL LogLevel::info
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TOKEN_TIMEOUT 60
|
|
||||||
#define LOCKPAGE_PREFIX "https://lock.binary.kitchen/"
|
#define LOCKPAGE_PREFIX "https://lock.binary.kitchen/"
|
||||||
#define FIFO_LOCATION "/var/run/doorlockd/doorlockd"
|
#define FIFO_LOCATION "/var/run/doorlockd/doorlockd"
|
||||||
|
|
||||||
|
41
logic.cpp
Normal file → Executable file
41
logic.cpp
Normal file → Executable file
@ -1,5 +1,4 @@
|
|||||||
#include <stdio.h>
|
#include <chrono>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
@ -7,6 +6,8 @@
|
|||||||
#define LDAP_DEPRECATED 1
|
#define LDAP_DEPRECATED 1
|
||||||
#include <ldap.h>
|
#include <ldap.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "logic.h"
|
#include "logic.h"
|
||||||
|
|
||||||
@ -18,27 +19,47 @@ const string Logic::_ldapServer = LDAP_SERVER;
|
|||||||
const string Logic::_bindDN = BINDDN;
|
const string Logic::_bindDN = BINDDN;
|
||||||
const string Logic::_allowedIpPrefix = ALLOWEDIPPREFIX;
|
const string Logic::_allowedIpPrefix = ALLOWEDIPPREFIX;
|
||||||
|
|
||||||
Logic &Logic::get()
|
Logic &Logic::get(const chrono::seconds tokenTimeout)
|
||||||
{
|
{
|
||||||
static Logic l;
|
static Logic l(tokenTimeout);
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logic::Logic() :
|
Logic::Logic(const chrono::seconds tokenTimeout) :
|
||||||
_logger(Logger::get()),
|
_logger(Logger::get()),
|
||||||
_door(Door::get()),
|
_door(Door::get()),
|
||||||
_epaper(Epaper::get())
|
_epaper(Epaper::get()),
|
||||||
|
_tokenTimeout(tokenTimeout)
|
||||||
{
|
{
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
createNewToken(false);
|
_createNewToken(false);
|
||||||
|
|
||||||
|
_tokenUpdater = thread([this] () {
|
||||||
|
while (_run)
|
||||||
|
{
|
||||||
|
unique_lock<mutex> l(_mutex);
|
||||||
|
_c.wait_for(l, _tokenTimeout);
|
||||||
|
if (_run == false)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
_createNewToken(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Logic::~Logic()
|
Logic::~Logic()
|
||||||
{
|
{
|
||||||
|
_run = false;
|
||||||
|
_c.notify_one();
|
||||||
|
_tokenUpdater.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
Logic::Response Logic::parseRequest(const string &str)
|
Logic::Response Logic::parseRequest(const string &str)
|
||||||
{
|
{
|
||||||
|
unique_lock<mutex> l(_mutex);
|
||||||
|
|
||||||
_logger("Parsing request...");
|
_logger("Parsing request...");
|
||||||
Json::Reader reader;
|
Json::Reader reader;
|
||||||
Json::Value root;
|
Json::Value root;
|
||||||
@ -123,7 +144,7 @@ Logic::Response Logic::_lock()
|
|||||||
|
|
||||||
_door.lock();
|
_door.lock();
|
||||||
_state = LOCKED;
|
_state = LOCKED;
|
||||||
createNewToken(false);
|
_createNewToken(false);
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
@ -138,7 +159,7 @@ Logic::Response Logic::_unlock()
|
|||||||
|
|
||||||
_door.unlock();
|
_door.unlock();
|
||||||
_state = UNLOCKED;
|
_state = UNLOCKED;
|
||||||
createNewToken(false);
|
_createNewToken(false);
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
@ -213,7 +234,7 @@ out2:
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logic::createNewToken(const bool stillValid)
|
void Logic::_createNewToken(const bool stillValid)
|
||||||
{
|
{
|
||||||
_prevToken = _curToken;
|
_prevToken = _curToken;
|
||||||
_prevValid = stillValid;
|
_prevValid = stillValid;
|
||||||
|
16
logic.h
Normal file → Executable file
16
logic.h
Normal file → Executable file
@ -3,7 +3,9 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <thread>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "epaper.h"
|
#include "epaper.h"
|
||||||
@ -14,7 +16,7 @@ class Logic
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static Logic &get();
|
static Logic &get(const std::chrono::seconds tokenTimeout);
|
||||||
~Logic();
|
~Logic();
|
||||||
|
|
||||||
enum Response {
|
enum Response {
|
||||||
@ -32,11 +34,10 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
Response parseRequest(const std::string &str);
|
Response parseRequest(const std::string &str);
|
||||||
void createNewToken(const bool stillValid);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Logic();
|
Logic(const std::chrono::seconds tokenTimeout);
|
||||||
|
|
||||||
Response _lock();
|
Response _lock();
|
||||||
Response _unlock();
|
Response _unlock();
|
||||||
@ -45,6 +46,7 @@ private:
|
|||||||
Response _checkLDAP(const std::string &user, const std::string &password);
|
Response _checkLDAP(const std::string &user, const std::string &password);
|
||||||
bool _checkIP(const std::string &ip);
|
bool _checkIP(const std::string &ip);
|
||||||
|
|
||||||
|
void _createNewToken(const bool stillValid);
|
||||||
|
|
||||||
const Logger &_logger;
|
const Logger &_logger;
|
||||||
Door &_door;
|
Door &_door;
|
||||||
@ -56,13 +58,17 @@ private:
|
|||||||
bool _prevValid = { false };
|
bool _prevValid = { false };
|
||||||
Token _prevToken = { 0x0000000000000000 };
|
Token _prevToken = { 0x0000000000000000 };
|
||||||
|
|
||||||
|
const std::chrono::seconds _tokenTimeout;
|
||||||
|
|
||||||
const static std::string _lockPagePrefix;
|
const static std::string _lockPagePrefix;
|
||||||
const static std::string _bindDN;
|
const static std::string _bindDN;
|
||||||
const static std::string _ldapServer;
|
const static std::string _ldapServer;
|
||||||
const static std::string _allowedIpPrefix;
|
const static std::string _allowedIpPrefix;
|
||||||
|
|
||||||
static constexpr int _tokenTimeout = TOKEN_TIMEOUT;
|
std::thread _tokenUpdater = {};
|
||||||
|
std::condition_variable _c = {};
|
||||||
|
std::mutex _mutex = {};
|
||||||
|
bool _run = true;
|
||||||
|
|
||||||
enum {LOCKED, UNLOCKED} _state = { LOCKED };
|
enum {LOCKED, UNLOCKED} _state = { LOCKED };
|
||||||
};
|
};
|
||||||
|
121
main.cpp
Normal file → Executable file
121
main.cpp
Normal file → Executable file
@ -2,6 +2,8 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -12,21 +14,18 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
const static Logger &l = Logger::get();
|
const static Logger &l = Logger::get();
|
||||||
|
|
||||||
int main(void)
|
int createFifo(const string &fifoLocation)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int handle = -1;
|
||||||
|
|
||||||
l(LogLevel::notice, "Starting doorlockd");
|
|
||||||
|
|
||||||
int fifoHandle = -1;
|
|
||||||
|
|
||||||
l(LogLevel::debug, "Creating Fifo file");
|
l(LogLevel::debug, "Creating Fifo file");
|
||||||
if (access(FIFO_LOCATION, F_OK) == 0)
|
if (access(fifoLocation.c_str(), F_OK) == 0)
|
||||||
{
|
{
|
||||||
l(LogLevel::warning, "Fifo file aready existing, trying to delete");
|
l(LogLevel::warning, "Fifo file aready existing, trying to delete");
|
||||||
if (unlink(FIFO_LOCATION) != 0)
|
if (unlink(fifoLocation.c_str()) != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Unable to delete Fifo file");
|
fprintf(stderr, "Unable to delete Fifo file");
|
||||||
goto out;
|
goto out;
|
||||||
@ -35,42 +34,107 @@ int main(void)
|
|||||||
|
|
||||||
umask(0);
|
umask(0);
|
||||||
|
|
||||||
if (mkfifo(FIFO_LOCATION, 0770) != 0)
|
if (mkfifo(fifoLocation.c_str(), 0770) != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Unable to create Fifo");
|
fprintf(stderr, "Unable to create Fifo");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
fifoHandle = open(FIFO_LOCATION, O_RDWR | O_NONBLOCK);
|
handle = open(fifoLocation.c_str(), O_RDWR | O_NONBLOCK);
|
||||||
if (fifoHandle == -1)
|
if (handle == -1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Unable to open Fifo");
|
fprintf(stderr, "Unable to open Fifo");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fchown(fifoHandle, 0, 1001) != 0)
|
if (fchown(handle, 0, 1001) != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Fifo chown failed");
|
fprintf(stderr, "Fifo chown failed");
|
||||||
goto out1;
|
close(handle);
|
||||||
|
handle = -1;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
int closeFifo(int handle)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
|
||||||
|
if (handle != -1)
|
||||||
|
{
|
||||||
|
close(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
l(LogLevel::debug, "Removing Fifo file");
|
||||||
|
if (unlink(FIFO_LOCATION) != 0)
|
||||||
|
{
|
||||||
|
l(LogLevel::error, "Unable to delete Fifo file");
|
||||||
|
retval = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
int fifoHandle = -1;
|
||||||
|
std::chrono::seconds tokenTimeout;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Logic &logic = Logic::get();
|
unsigned int timeout;
|
||||||
struct timeval tv;
|
po::options_description desc("usage: doorlockd");
|
||||||
|
desc.add_options()
|
||||||
|
("help,h", "print help")
|
||||||
|
("tokentimeout,t", po::value<unsigned int>(&timeout)->required(), "tokentimeout in seconds");
|
||||||
|
|
||||||
|
po::variables_map vm;
|
||||||
|
po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
|
||||||
|
|
||||||
|
if (vm.count("help"))
|
||||||
|
{
|
||||||
|
std::cout << desc << std::endl;
|
||||||
|
retval = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
po::notify(vm);
|
||||||
|
|
||||||
|
tokenTimeout = std::chrono::seconds(timeout>3 ? timeout-3 : timeout); // Epaper refresh takes ~3 seconds
|
||||||
|
}
|
||||||
|
catch(const std::exception &e)
|
||||||
|
{
|
||||||
|
std::cerr << "Error: " << e.what() << "\n";
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
l(LogLevel::notice, "Starting doorlockd");
|
||||||
|
|
||||||
|
fifoHandle = createFifo(FIFO_LOCATION);
|
||||||
|
if (fifoHandle == -1)
|
||||||
|
{
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Logic &logic = Logic::get(tokenTimeout);
|
||||||
fd_set set;
|
fd_set set;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
FD_ZERO(&set);
|
FD_ZERO(&set);
|
||||||
FD_SET(fifoHandle, &set);
|
FD_SET(fifoHandle, &set);
|
||||||
tv.tv_sec = TOKEN_TIMEOUT;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
|
|
||||||
int i = select(fifoHandle+1, &set, nullptr, nullptr, &tv);
|
int i = select(fifoHandle+1, &set, nullptr, nullptr, nullptr);
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
logic.createNewToken(true);
|
|
||||||
continue;
|
continue;
|
||||||
} else if (i == -1) {
|
} else if (i == -1) {
|
||||||
throw "Fifo select() failed";
|
throw "Fifo select() failed";
|
||||||
@ -99,7 +163,7 @@ int main(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc = logic.parseRequest(payload);
|
const auto rc = logic.parseRequest(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
@ -109,20 +173,13 @@ int main(void)
|
|||||||
str << "FATAL ERROR: " << ex;
|
str << "FATAL ERROR: " << ex;
|
||||||
l(str, LogLevel::error);
|
l(str, LogLevel::error);
|
||||||
retval = -1;
|
retval = -1;
|
||||||
|
goto out1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retval = 0;
|
||||||
|
|
||||||
out1:
|
out1:
|
||||||
if (fifoHandle != -1)
|
retval = closeFifo(fifoHandle);
|
||||||
{
|
|
||||||
close(fifoHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
l(LogLevel::debug, "Removing Fifo file");
|
|
||||||
if (unlink(FIFO_LOCATION) != 0)
|
|
||||||
{
|
|
||||||
throw("Unable to delete Fifo file");
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
Door::get().lock();
|
Door::get().lock();
|
||||||
l(LogLevel::notice, "Doorlockd stopped");
|
l(LogLevel::notice, "Doorlockd stopped");
|
||||||
|
Loading…
Reference in New Issue
Block a user