mirror of
https://github.com/binary-kitchen/doorlockd
synced 2024-12-22 18:34:25 +01:00
Exchanged FIFO by TCP socket
This commit is contained in:
parent
b369bdbb70
commit
1b1ffe54f3
@ -18,7 +18,9 @@ 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)
|
find_package(Boost 1.55.0 COMPONENTS program_options system REQUIRED)
|
||||||
|
|
||||||
|
find_package (Threads)
|
||||||
|
|
||||||
set(SRCS
|
set(SRCS
|
||||||
main.cpp
|
main.cpp
|
||||||
@ -34,7 +36,7 @@ epaper/bsp.c
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_executable(doorlockd ${SRCS})
|
add_executable(doorlockd ${SRCS})
|
||||||
target_link_libraries(doorlockd wiringPi jsoncpp ldap ${Boost_LIBRARIES})
|
target_link_libraries(doorlockd wiringPi jsoncpp ldap ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
|
||||||
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)
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#define DEFAULT_LOG_LEVEL LogLevel::info
|
#define DEFAULT_LOG_LEVEL LogLevel::info
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define DEFAULT_PORT 5555
|
||||||
|
|
||||||
#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"
|
||||||
|
|
||||||
|
@ -19,12 +19,6 @@ 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(const chrono::seconds tokenTimeout)
|
|
||||||
{
|
|
||||||
static Logic l(tokenTimeout);
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logic::Logic(const chrono::seconds tokenTimeout) :
|
Logic::Logic(const chrono::seconds tokenTimeout) :
|
||||||
_logger(Logger::get()),
|
_logger(Logger::get()),
|
||||||
_door(Door::get()),
|
_door(Door::get()),
|
||||||
|
4
logic.h
4
logic.h
@ -16,7 +16,7 @@ class Logic
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static Logic &get(const std::chrono::seconds tokenTimeout);
|
Logic(const std::chrono::seconds tokenTimeout);
|
||||||
~Logic();
|
~Logic();
|
||||||
|
|
||||||
enum Response {
|
enum Response {
|
||||||
@ -37,8 +37,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Logic(const std::chrono::seconds tokenTimeout);
|
|
||||||
|
|
||||||
Response _lock();
|
Response _lock();
|
||||||
Response _unlock();
|
Response _unlock();
|
||||||
|
|
||||||
|
164
main.cpp
164
main.cpp
@ -1,13 +1,11 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "logic.h"
|
#include "logic.h"
|
||||||
@ -15,77 +13,84 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
using boost::asio::ip::tcp;
|
||||||
|
|
||||||
const static Logger &l = Logger::get();
|
const static Logger &l = Logger::get();
|
||||||
|
|
||||||
int createFifo(const string &fifoLocation)
|
static unique_ptr<Logic> logic = nullptr;
|
||||||
|
|
||||||
|
class session
|
||||||
|
: public std::enable_shared_from_this<session>
|
||||||
{
|
{
|
||||||
int handle = -1;
|
|
||||||
l(LogLevel::debug, "Creating Fifo file");
|
public:
|
||||||
if (access(fifoLocation.c_str(), F_OK) == 0)
|
|
||||||
|
session(tcp::socket socket)
|
||||||
|
: _socket(std::move(socket))
|
||||||
{
|
{
|
||||||
l(LogLevel::warning, "Fifo file aready existing, trying to delete");
|
|
||||||
if (unlink(fifoLocation.c_str()) != 0)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Unable to delete Fifo file");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
umask(0);
|
void start()
|
||||||
|
|
||||||
if (mkfifo(fifoLocation.c_str(), 0770) != 0)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Unable to create Fifo");
|
auto self(shared_from_this());
|
||||||
goto out;
|
_socket.async_read_some(boost::asio::buffer(_data, _maxLen),
|
||||||
}
|
[this, self](boost::system::error_code ec, std::size_t length)
|
||||||
|
|
||||||
handle = open(fifoLocation.c_str(), O_RDWR | O_NONBLOCK);
|
|
||||||
if (handle == -1)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Unable to open Fifo");
|
if (!ec)
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fchown(handle, 0, 1001) != 0)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Fifo chown failed");
|
const string payload(_data, length);
|
||||||
close(handle);
|
const auto rc = logic->parseRequest(payload);
|
||||||
handle = -1;
|
boost::asio::write(_socket, boost::asio::buffer(to_string(rc) + "\n"));
|
||||||
goto out;
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
private:
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
int closeFifo(int handle)
|
tcp::socket _socket;
|
||||||
|
static constexpr int _maxLen = { 2048 };
|
||||||
|
char _data[_maxLen];
|
||||||
|
};
|
||||||
|
|
||||||
|
class server
|
||||||
{
|
{
|
||||||
int retval = -1;
|
|
||||||
|
|
||||||
if (handle != -1)
|
public:
|
||||||
|
|
||||||
|
server(boost::asio::io_service& io_service, short port)
|
||||||
|
: _acceptor(io_service, tcp::endpoint(tcp::v4(), port)),
|
||||||
|
_socket(io_service)
|
||||||
{
|
{
|
||||||
close(handle);
|
do_accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
l(LogLevel::debug, "Removing Fifo file");
|
private:
|
||||||
if (unlink(FIFO_LOCATION) != 0)
|
|
||||||
|
void do_accept()
|
||||||
{
|
{
|
||||||
l(LogLevel::error, "Unable to delete Fifo file");
|
|
||||||
retval = -1;
|
_acceptor.async_accept(_socket,
|
||||||
goto out;
|
[this](boost::system::error_code ec)
|
||||||
|
{
|
||||||
|
if (!ec)
|
||||||
|
{
|
||||||
|
std::make_shared<session>(std::move(_socket))->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = 0;
|
do_accept();
|
||||||
|
});
|
||||||
|
|
||||||
out:
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tcp::acceptor _acceptor;
|
||||||
|
tcp::socket _socket;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
int fifoHandle = -1;
|
short port;
|
||||||
std::chrono::seconds tokenTimeout;
|
std::chrono::seconds tokenTimeout;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -93,7 +98,8 @@ int main(int argc, char** argv)
|
|||||||
po::options_description desc("usage: doorlockd");
|
po::options_description desc("usage: doorlockd");
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", "print help")
|
("help,h", "print help")
|
||||||
("tokentimeout,t", po::value<unsigned int>(&timeout)->required(), "tokentimeout in seconds");
|
("tokentimeout,t", po::value<unsigned int>(&timeout)->required(), "tokentimeout in seconds")
|
||||||
|
("port,p", po::value<short>(&port)->default_value(DEFAULT_PORT), "Port");
|
||||||
|
|
||||||
po::variables_map vm;
|
po::variables_map vm;
|
||||||
po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
|
po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
|
||||||
@ -115,56 +121,14 @@ int main(int argc, char** argv)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logic = unique_ptr<Logic>(new Logic(tokenTimeout));
|
||||||
|
|
||||||
l(LogLevel::notice, "Starting doorlockd");
|
l(LogLevel::notice, "Starting doorlockd");
|
||||||
|
|
||||||
fifoHandle = createFifo(FIFO_LOCATION);
|
|
||||||
if (fifoHandle == -1)
|
|
||||||
{
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Logic &logic = Logic::get(tokenTimeout);
|
boost::asio::io_service io_service;
|
||||||
fd_set set;
|
server s(io_service, port);
|
||||||
|
io_service.run();
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
FD_ZERO(&set);
|
|
||||||
FD_SET(fifoHandle, &set);
|
|
||||||
|
|
||||||
int i = select(fifoHandle+1, &set, nullptr, nullptr, nullptr);
|
|
||||||
if (i == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
} else if (i == -1) {
|
|
||||||
throw "Fifo select() failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!FD_ISSET(fifoHandle, &set))
|
|
||||||
{
|
|
||||||
l(LogLevel::warning, "select(): Not my fd");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
string payload;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
constexpr int BUFSIZE = 2;
|
|
||||||
char tmp[BUFSIZE];
|
|
||||||
i = read(fifoHandle, tmp, BUFSIZE);
|
|
||||||
if (i > 0) {
|
|
||||||
payload += string(tmp, i);
|
|
||||||
} else {
|
|
||||||
if (errno == EWOULDBLOCK)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
throw "read() fifo failed";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto rc = logic.parseRequest(payload);
|
|
||||||
}
|
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
}
|
}
|
||||||
@ -173,13 +137,11 @@ int main(int argc, char** argv)
|
|||||||
str << "FATAL ERROR: " << ex;
|
str << "FATAL ERROR: " << ex;
|
||||||
l(str, LogLevel::error);
|
l(str, LogLevel::error);
|
||||||
retval = -1;
|
retval = -1;
|
||||||
goto out1;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
||||||
out1:
|
|
||||||
retval = closeFifo(fifoHandle);
|
|
||||||
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