restored OUtputPinController
This commit is contained in:
23
FlippR-Driver/networking/CMakeLists.txt
Normal file
23
FlippR-Driver/networking/CMakeLists.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
cmake_minimum_required(VERSION 3.6.2)
|
||||
project(flippR_driver_networking)
|
||||
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/${OUTPUT_PATH}/cli)
|
||||
set(SOURCES
|
||||
input/SocketHandler.cpp
|
||||
output/OutputRequestHandler.cpp
|
||||
output/OutputRequestHandlerFactory.cpp
|
||||
)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE FlippR-Driver)
|
||||
|
||||
####################### POCO ##############################
|
||||
find_package(Poco REQUIRED COMPONENTS Foundation Net JSON )
|
||||
|
||||
if(NOT Poco_FOUND)
|
||||
message(FATAL_ERROR, "Could not find libPoco")
|
||||
endif()
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC Poco::Foundation Poco::Net Poco::JSON)
|
||||
59
FlippR-Driver/networking/input/SocketHandler.cpp
Normal file
59
FlippR-Driver/networking/input/SocketHandler.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* SocketConnection.cpp
|
||||
*
|
||||
* Created on: Jun 13, 2018
|
||||
* Author: Andreas Schneider, Johannes Wendel, Jonas Zeunert
|
||||
*/
|
||||
|
||||
#include "SocketHandler.h"
|
||||
|
||||
|
||||
using Poco::Net::StreamSocket;
|
||||
using Poco::Net::TCPServerConnection;
|
||||
using flippR_driver::input::InputDriver;
|
||||
using flippR_driver::input::detail::EventHandler;
|
||||
using flippR_driver::input::Event;
|
||||
|
||||
namespace flippR_driver
|
||||
{
|
||||
namespace utility
|
||||
{
|
||||
namespace networking
|
||||
{
|
||||
namespace input
|
||||
{
|
||||
|
||||
SocketHandler::SocketHandler(StreamSocket streamSocket, std::shared_ptr<InputDriver> inputDriver) :
|
||||
TCPServerConnection(streamSocket),
|
||||
EventHandler(inputDriver)
|
||||
{
|
||||
}
|
||||
|
||||
void SocketHandler::run()
|
||||
{
|
||||
StreamSocket& streamSocket = socket();
|
||||
|
||||
while(true)
|
||||
{
|
||||
Event event = this->queue->pop();
|
||||
|
||||
if(event.name == "END")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::string str = event.getJsonString();
|
||||
|
||||
streamSocket.sendBytes(str.c_str(), str.length());
|
||||
}
|
||||
}
|
||||
|
||||
void SocketHandler::handle(Event &event)
|
||||
{
|
||||
this->queue->push(event);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
44
FlippR-Driver/networking/input/SocketHandler.h
Normal file
44
FlippR-Driver/networking/input/SocketHandler.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* SocketConnection.h
|
||||
*
|
||||
* Created on: Jun 13, 2018
|
||||
* Author: Andreas Schneider, Johannes Wendel, Jonas Zeunert
|
||||
*/
|
||||
|
||||
#ifndef FLIPPR_CODE_INPUTSOCKETCONNECTION_H
|
||||
#define FLIPPR_CODE_INPUTSOCKETCONNECTION_H
|
||||
|
||||
|
||||
#include <Poco/Net/TCPServerConnection.h>
|
||||
|
||||
#include "utility/IBlockingQueue.h"
|
||||
#include "input/InputDriver.h"
|
||||
#include "input/detail/EventHandler.h"
|
||||
#include "input/Event.h"
|
||||
|
||||
namespace flippR_driver
|
||||
{
|
||||
namespace utility
|
||||
{
|
||||
namespace networking
|
||||
{
|
||||
namespace input
|
||||
{
|
||||
class SocketHandler : public Poco::Net::TCPServerConnection, flippR_driver::input::detail::EventHandler
|
||||
{
|
||||
public:
|
||||
SocketHandler(Poco::Net::StreamSocket streamSocket, std::shared_ptr<flippR_driver::input::InputDriver> input_driver);
|
||||
|
||||
void run() override;
|
||||
void handle(flippR_driver::input::Event &event) override;
|
||||
|
||||
private:
|
||||
flippR_driver::utility::IBlockingQueue<flippR_driver::input::Event>* queue;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif //FLIPPR_CODE_INPUTSOCKETCONNECTION_H
|
||||
21
FlippR-Driver/networking/output/OutputHTTPServer.cpp
Normal file
21
FlippR-Driver/networking/output/OutputHTTPServer.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Created by rhetenor on 4/15/19.
|
||||
//
|
||||
|
||||
#include <Poco/Net/HTTPServerParams.h>
|
||||
|
||||
#include "OutputHTTPServer.h"
|
||||
#include "OutputRequestHandlerFactory.h"
|
||||
|
||||
namespace flippR_driver
|
||||
{
|
||||
namespace utility
|
||||
{
|
||||
using namespace Poco::Net;
|
||||
|
||||
OutputHTTPServer::OutputHTTPServer(std::shared_ptr<output::OutputDriver> output_driver, Socket &socket) :
|
||||
HTTPServer(new OutputRequestHandlerFactory(output_driver), socket, new HTTPServerParams())
|
||||
{}
|
||||
|
||||
}
|
||||
}
|
||||
28
FlippR-Driver/networking/output/OutputHTTPServer.h
Normal file
28
FlippR-Driver/networking/output/OutputHTTPServer.h
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Created by rhetenor on 4/15/19.
|
||||
//
|
||||
|
||||
#ifndef FLIPPR_CODE_OUTPUTHTTPSERVER_H
|
||||
#define FLIPPR_CODE_OUTPUTHTTPSERVER_H
|
||||
|
||||
#include <Poco/Net/HTTPServer.h>
|
||||
#include <Poco/Net/Socket.h>
|
||||
|
||||
#include "output/OutputDriver.h"
|
||||
|
||||
namespace flippR_driver
|
||||
{
|
||||
namespace utility
|
||||
{
|
||||
|
||||
class OutputHTTPServer : public Poco::Net::HTTPServer
|
||||
{
|
||||
public:
|
||||
explicit OutputHTTPServer(std::shared_ptr<output::OutputDriver> output_driver, Poco::Net::Socket &socket);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif //FLIPPR_CODE_OUTPUTHTTPSERVER_H
|
||||
260
FlippR-Driver/networking/output/OutputRequestHandler.cpp
Normal file
260
FlippR-Driver/networking/output/OutputRequestHandler.cpp
Normal file
@@ -0,0 +1,260 @@
|
||||
//
|
||||
// Created by rhetenor on 3/6/19.
|
||||
//
|
||||
|
||||
|
||||
#include <Poco/Net/HTTPServerResponse.h>
|
||||
#include <Poco/Net/HTTPServerRequest.h>
|
||||
#include <Poco/Exception.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "OutputRequestHandler.h"
|
||||
|
||||
namespace flippR_driver
|
||||
{
|
||||
namespace utility
|
||||
{
|
||||
using namespace Poco;
|
||||
using namespace Poco::Net;
|
||||
|
||||
OutputRequestHandler::OutputRequestHandler(std::shared_ptr<output::OutputDriver> output_driver) :
|
||||
output_driver(output_driver)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Handles a REST request with a URI form of:
|
||||
*
|
||||
* address/{item_type}/[item_name]/[action]/[score]
|
||||
*
|
||||
* Where
|
||||
* {item_type} is either solenoids, lamps, sounds, displays, or one of the two special events: activate and deactivate
|
||||
* [item_name] is the string name of an item (optional if you want to get the list of all available items)
|
||||
* [action] is the particular action for the item:
|
||||
* Solenoids: trigger
|
||||
* lamps: activate, deactivate, status
|
||||
* sounds: play
|
||||
* displays: write_score (for this is the additional optional attribute [score]
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
void OutputRequestHandler::handleRequest(HTTPServerRequest &request,
|
||||
HTTPServerResponse &response)
|
||||
{
|
||||
auto path_segments = getPathSegments(URI(request.getURI()));
|
||||
|
||||
// fill up vector
|
||||
for(int i = path_segments.size(); i < 4; i++)
|
||||
{
|
||||
path_segments.emplace_back("");
|
||||
}
|
||||
|
||||
std::string item_type = path_segments.at(0);
|
||||
std::string item_name = path_segments.at(1);
|
||||
std::string action = path_segments.at(2);
|
||||
std::string score = path_segments.at(3);
|
||||
|
||||
if(item_type == "deactivate")
|
||||
{
|
||||
this->output_driver->deactivate_displays();
|
||||
this->output_driver->deactivate_all_lamps();
|
||||
return;
|
||||
}
|
||||
|
||||
if(item_type == "activate")
|
||||
{
|
||||
this->output_driver->activate_displays();
|
||||
return;
|
||||
}
|
||||
|
||||
response.setContentType("text/json");
|
||||
response.setStatus(HTTPServerResponse::HTTP_OK);
|
||||
|
||||
try
|
||||
{
|
||||
boost::optional<Poco::JSON::Object> json_response = parseRequest(item_type, item_name, action, score);
|
||||
if(json_response)
|
||||
{
|
||||
std::ostream& ostr = response.send();
|
||||
json_response->stringify(ostr);
|
||||
}
|
||||
}
|
||||
catch(const NotFoundException &e)
|
||||
{
|
||||
response.setStatusAndReason(HTTPServerResponse::HTTP_NOT_FOUND, e.displayText());
|
||||
}
|
||||
catch(const Poco::InvalidArgumentException &e)
|
||||
{
|
||||
response.setStatusAndReason(HTTPServerResponse::HTTP_BAD_REQUEST, e.displayText());
|
||||
}
|
||||
}
|
||||
|
||||
boost::optional<Poco::JSON::Object> OutputRequestHandler::parseRequest(const std::string& item_type, const std::string& item_name, const std::string& action, const std::string& score)
|
||||
{
|
||||
if(item_type == "solenoids")
|
||||
{
|
||||
return parseSolenoid(item_name, action);
|
||||
}
|
||||
else if(item_type == "lamps")
|
||||
{
|
||||
return parseLamp(item_name, action);
|
||||
}
|
||||
else if(item_type == "sounds")
|
||||
{
|
||||
return parseSound(item_name, action);
|
||||
}
|
||||
else if(item_type == "displays")
|
||||
{
|
||||
return parseDisplay(item_name, action, score);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Poco::NotFoundException("No item type called " + item_type);
|
||||
}
|
||||
}
|
||||
|
||||
boost::optional<Poco::JSON::Object> OutputRequestHandler::parseSolenoid(const std::string& item_name, const std::string& action)
|
||||
{
|
||||
if(item_name == "")
|
||||
{
|
||||
Poco::JSON::Object response;
|
||||
response.set("solenoids", this->output_driver->get_solenoids());
|
||||
return response;
|
||||
}
|
||||
|
||||
auto opt_solenoid = this->output_driver->get_solenoid(item_name);
|
||||
|
||||
if(!opt_solenoid)
|
||||
{
|
||||
throw new Poco::NotFoundException("No solenoid with name \"" + item_name + "\"!");
|
||||
}
|
||||
|
||||
auto solenoid = opt_solenoid->get();
|
||||
|
||||
if(action == "trigger")
|
||||
{
|
||||
solenoid->trigger();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Poco::NotFoundException("No action with name \"" + action + "\" on solenoids!");
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
boost::optional<Poco::JSON::Object> OutputRequestHandler::parseLamp(const std::string& item_name, const std::string& action)
|
||||
{
|
||||
if(item_name == "")
|
||||
{
|
||||
Poco::JSON::Object response;
|
||||
response.set("lamps", this->output_driver->get_lamps());
|
||||
return response;
|
||||
}
|
||||
|
||||
auto opt_lamp = this->output_driver->get_lamp(item_name);
|
||||
|
||||
if(!opt_lamp)
|
||||
{
|
||||
throw new Poco::NotFoundException("No lamp with name \"" + item_name + "\"!");
|
||||
}
|
||||
|
||||
auto lamp = opt_lamp->get();
|
||||
|
||||
if(action == "activate")
|
||||
{
|
||||
lamp->activate();
|
||||
}
|
||||
else if(action == "deactivate")
|
||||
{
|
||||
lamp->deactivate();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Poco::NotFoundException("No action with name \"" + action + "\" on lamps!");
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
boost::optional<Poco::JSON::Object> OutputRequestHandler::parseSound(const std::string& item_name, const std::string& action)
|
||||
{
|
||||
if(item_name == "")
|
||||
{
|
||||
Poco::JSON::Object response;
|
||||
response.set("sounds", this->output_driver->get_sounds());
|
||||
return response;
|
||||
}
|
||||
|
||||
auto opt_sound = this->output_driver->get_sound(item_name);
|
||||
|
||||
if(!opt_sound)
|
||||
{
|
||||
throw new Poco::NotFoundException("No sound with name \"" + item_name + "\"!");
|
||||
}
|
||||
|
||||
auto sound = opt_sound->get();
|
||||
|
||||
if(action == "play")
|
||||
{
|
||||
sound->play();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Poco::NotFoundException("No action with name \"" + action + "\" on sounds!");
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
boost::optional<Poco::JSON::Object> OutputRequestHandler::parseDisplay(const std::string& item_name, const std::string& action, const std::string& score)
|
||||
{
|
||||
if(item_name == "")
|
||||
{
|
||||
Poco::JSON::Object response;
|
||||
response.set("displays", this->output_driver->get_displays());
|
||||
return response;
|
||||
}
|
||||
|
||||
uint8_t display_number = std::stoi(item_name);
|
||||
auto opt_display = this->output_driver->get_display(display_number);
|
||||
|
||||
if(!opt_display)
|
||||
{
|
||||
throw new Poco::NotFoundException("No display with number \"" + item_name + "\"!");
|
||||
}
|
||||
|
||||
auto display = opt_display->get();
|
||||
|
||||
|
||||
if(action == "write_score")
|
||||
{
|
||||
try
|
||||
{
|
||||
unsigned int numerical_score = std::stoi(score);
|
||||
display->write_score(numerical_score);
|
||||
}
|
||||
catch(std::invalid_argument &e)
|
||||
{
|
||||
throw new Poco::InvalidArgumentException("Could not convert " + score + " to a number!\n" + e.what());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Poco::NotFoundException("No Action with name \"" + action + "\" on sounds!");
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::string> OutputRequestHandler::getPathSegments(Poco::URI uri)
|
||||
{
|
||||
std::vector<std::string> path_segments;
|
||||
uri.getPathSegments(path_segments);
|
||||
return path_segments;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
48
FlippR-Driver/networking/output/OutputRequestHandler.h
Normal file
48
FlippR-Driver/networking/output/OutputRequestHandler.h
Normal file
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// Created by rhetenor on 3/6/19.
|
||||
//
|
||||
|
||||
#ifndef FLIPPR_CODE_OUTPUTREQUESTHANDLER_H
|
||||
#define FLIPPR_CODE_OUTPUTREQUESTHANDLER_H
|
||||
|
||||
#include <Poco/Net/HTTPRequestHandler.h>
|
||||
#include <Poco/URI.h>
|
||||
#include <Poco/JSON/JSON.h>
|
||||
#include <memory>
|
||||
#include <boost/optional.hpp>
|
||||
#include <Poco/JSON/Object.h>
|
||||
|
||||
#include "output/OutputDriver.h"
|
||||
|
||||
namespace flippR_driver
|
||||
{
|
||||
namespace utility
|
||||
{
|
||||
|
||||
class OutputRequestHandler : public Poco::Net::HTTPRequestHandler
|
||||
{
|
||||
public:
|
||||
OutputRequestHandler(std::shared_ptr<output::OutputDriver> output_driver);
|
||||
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &request, Poco::Net::HTTPServerResponse &response) override;
|
||||
|
||||
private:
|
||||
boost::optional<Poco::JSON::Object> parseRequest(const std::string& item_type, const std::string& item_name, const std::string& action, const std::string& score = 0);
|
||||
|
||||
boost::optional<Poco::JSON::Object> parseSolenoid(const std::string& item_name, const std::string& action);
|
||||
boost::optional<Poco::JSON::Object> parseLamp(const std::string& item_name, const std::string& action);
|
||||
boost::optional<Poco::JSON::Object> parseSound(const std::string& item_name, const std::string& action);
|
||||
boost::optional<Poco::JSON::Object> parseDisplay(const std::string& item_name, const std::string& action, const std::string& score);
|
||||
|
||||
std::vector<std::string> getPathSegments(Poco::URI uri);
|
||||
|
||||
private:
|
||||
std::shared_ptr<output::OutputDriver> output_driver;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //FLIPPR_CODE_OUTPUTREQUESTHANDLER_H
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by rhetenor on 4/15/19.
|
||||
//
|
||||
|
||||
#include "OutputRequestHandlerFactory.h"
|
||||
#include "OutputRequestHandler.h"
|
||||
|
||||
namespace flippR_driver
|
||||
{
|
||||
namespace utility
|
||||
{
|
||||
using namespace Poco::Net;
|
||||
|
||||
OutputRequestHandlerFactory::OutputRequestHandlerFactory(std::shared_ptr<output::OutputDriver> output_driver) :
|
||||
output_driver(output_driver)
|
||||
{}
|
||||
|
||||
HTTPRequestHandler *OutputRequestHandlerFactory::createRequestHandler(const HTTPServerRequest &request)
|
||||
{
|
||||
return new OutputRequestHandler(this->output_driver);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// Created by rhetenor on 4/15/19.
|
||||
//
|
||||
|
||||
#ifndef FLIPPR_CODE_OUTPUTREQUESTHANDLERFACTORY_H
|
||||
#define FLIPPR_CODE_OUTPUTREQUESTHANDLERFACTORY_H
|
||||
|
||||
#include <Poco/Net/HTTPRequestHandlerFactory.h>
|
||||
#include <memory>
|
||||
|
||||
#include "output/OutputDriver.h"
|
||||
|
||||
namespace flippR_driver
|
||||
{
|
||||
namespace utility
|
||||
{
|
||||
|
||||
class OutputRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory
|
||||
{
|
||||
public:
|
||||
explicit OutputRequestHandlerFactory(std::shared_ptr<output::OutputDriver> output_driver);
|
||||
Poco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<output::OutputDriver> output_driver;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif //FLIPPR_CODE_OUTPUTREQUESTHANDLERFACTORY_H
|
||||
Reference in New Issue
Block a user