1
0
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:
Ralf Ramsauer 2015-05-13 14:20:12 +00:00
parent b369bdbb70
commit 1b1ffe54f3
5 changed files with 75 additions and 117 deletions

View File

@ -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)

View File

@ -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"

View File

@ -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()),

View File

@ -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();

174
main.cpp
View File

@ -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)
{
if (!ec)
{
const string payload(_data, length);
const auto rc = logic->parseRequest(payload);
boost::asio::write(_socket, boost::asio::buffer(to_string(rc) + "\n"));
}
});
} }
handle = open(fifoLocation.c_str(), O_RDWR | O_NONBLOCK); private:
if (handle == -1)
{
fprintf(stderr, "Unable to open Fifo");
goto out;
}
if (fchown(handle, 0, 1001) != 0) tcp::socket _socket;
{ static constexpr int _maxLen = { 2048 };
fprintf(stderr, "Fifo chown failed"); char _data[_maxLen];
close(handle); };
handle = -1;
goto out;
}
out: class server
return handle;
}
int closeFifo(int handle)
{ {
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)
{
do_accept();
}
private:
void do_accept()
{ {
close(handle);
_acceptor.async_accept(_socket,
[this](boost::system::error_code ec)
{
if (!ec)
{
std::make_shared<session>(std::move(_socket))->start();
}
do_accept();
});
} }
l(LogLevel::debug, "Removing Fifo file"); tcp::acceptor _acceptor;
if (unlink(FIFO_LOCATION) != 0) tcp::socket _socket;
{ };
l(LogLevel::error, "Unable to delete Fifo file");
retval = -1;
goto out;
}
retval = 0;
out:
return retval;
}
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");