Skip to content

Commit

Permalink
Move network code into self-contained class
Browse files Browse the repository at this point in the history
  • Loading branch information
evan1026 committed Oct 28, 2022
1 parent fd8f14a commit 6e39f68
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 57 deletions.
8 changes: 4 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ CPMAddPackage("gh:nlohmann/json@${JSON_VERSION}")
CPMAddPackage("gh:evan1026/blink1-lib@${BLINK1_LIB_VERSION}")
CPMAddPackage("gh:jarro2783/cxxopts@${CXXOPTS_VERSION}")
CPMAddPackage("gh:google/googletest@${GOOGLE_TEST_VERSION}#release-${GOOGLE_TEST_VERSION}")

install_boost_library_recursively("asio" ${BOOST_VERSION})
CPMAddPackage("gh:boostorg/boost@${BOOST_VERSION}#boost-${BOOST_VERSION}")

set(GTEST_LIBRARIES gtest gtest_main gmock gmock_main)

Expand All @@ -52,6 +51,7 @@ set(EXECUTABLE_NAME "blink1-control")
set(SOURCES
${SOURCE_DIR}/config/ConfigParser.cpp
${SOURCE_DIR}/config/PatternCommand.cpp
${SOURCE_DIR}/network/NetworkManager.cpp
)

set(EXECUTABLE_SOURCES
Expand All @@ -60,7 +60,7 @@ set(EXECUTABLE_SOURCES
)

add_executable(${EXECUTABLE_NAME} ${EXECUTABLE_SOURCES})
target_link_libraries(${EXECUTABLE_NAME} nlohmann_json Boost::asio cxxopts)
target_link_libraries(${EXECUTABLE_NAME} nlohmann_json Boost::asio Boost::thread cxxopts)

set(WARNINGS "-Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wunused -Woverloaded-virtual -Wpedantic -Wconversion -Wsign-conversion")
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
Expand Down Expand Up @@ -113,7 +113,7 @@ set(TEST_SOURCES
enable_testing()

add_executable(${TEST_EXECUTABLE_NAME} ${TEST_SOURCES} ${SOURCES})
target_link_libraries(${TEST_EXECUTABLE_NAME} ${GTEST_LIBRARIES} blink1-testing nlohmann_json)
target_link_libraries(${TEST_EXECUTABLE_NAME} ${GTEST_LIBRARIES} blink1-testing nlohmann_json Boost::asio Boost::thread)
set_property(TARGET ${TEST_EXECUTABLE_NAME} PROPERTY CXX_STANDARD 20)

include(GoogleTest)
Expand Down
29 changes: 0 additions & 29 deletions cmake/cpm_utilities.cmake
Original file line number Diff line number Diff line change
@@ -1,32 +1,3 @@
function(install_boost_library_recursively library_name boost_version)
CPMAddPackage(
NAME boost-${library_name}
VERSION ${boost_version}
GIT_TAG boost-${boost_version}
GITHUB_REPOSITORY "boostorg/${library_name}"
EXCLUDE_FROM_ALL yes
)

set(PROCESSED_BOOST_LIBRARIES "${PROCESSED_BOOST_LIBRARIES};${library_name}" CACHE INTERNAL "")

set_target_properties(boost_${library_name} PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:boost_${library_name},INTERFACE_INCLUDE_DIRECTORIES>)
get_target_property(libs Boost::${library_name} INTERFACE_LINK_LIBRARIES)

while (libs)

list(GET libs 0 first_library)
string(REPLACE "::" ";" library_name_parts ${first_library})
list(GET library_name_parts 1 child_library_name)

install_boost_library_recursively(${child_library_name} ${boost_version})

list(REMOVE_AT libs 0)

endwhile()
endfunction()



function(install_cpm CPM_DOWNLOAD_VERSION)
if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
Expand Down
19 changes: 19 additions & 0 deletions include/network.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @file network.hpp
* @brief Header file for blink1_control::network
*
* Including this file will give access to all classes within blink1_control::network
*/
#pragma once

#include "network/NetworkManager.hpp"

namespace blink1_control {

/**
* Classes related to network connections
*/
namespace network {

}
}
64 changes: 64 additions & 0 deletions include/network/NetworkManager.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* @file NetworkManager.hpp
* @brief Header file for blink1_control::network::NetworkManager.
*/

#pragma once

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wshorten-64-to-32"
#pragma GCC diagnostic ignored "-Wshadow"
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#pragma GCC diagnostic pop

namespace blink1_control::network {

/**
* This class creates and maintains network connections.
*/
class NetworkManager {

std::shared_ptr<boost::asio::io_context> ioc;
boost::asio::local::stream_protocol::endpoint endpoint;
boost::asio::local::stream_protocol::acceptor acceptor;
std::unique_ptr<boost::thread> ioThread;

void acceptHandler(const boost::system::error_code& error, boost::asio::local::stream_protocol::socket peer);

void startAccept();

public:

/**
* Constructor.
*
* @param socketPath The path to bind the socket to.
*/
NetworkManager(std::string_view socketPath);

/**
* Destructor.
*/
~NetworkManager();

NetworkManager(const NetworkManager& other) = delete;
NetworkManager(NetworkManager&& other) = delete;
NetworkManager& operator=(const NetworkManager& other) = delete;
NetworkManager& operator=(NetworkManager&& other) = delete;

/**
* Starts the network I/O service.
*/
void start();

/**
* Stops the network I/O service.
*/
void stop();

};

}
41 changes: 17 additions & 24 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
#include <iostream>
#include <nlohmann/json.hpp>
#include <span>
#include <boost/asio.hpp>

#include "blink-lib.hpp"
#include "config.hpp"
#include "network.hpp"

#ifdef USE_BLINK1_TESTING_LIBRARY
#include "Blink1TestingLibrary.hpp"
Expand Down Expand Up @@ -69,25 +69,25 @@ void runPatterns(std::optional<blink1_control::config::Config> config) {
while (LOOPING) {
for (auto it = config->patternConfigs.begin(); it != config->patternConfigs.end() && LOOPING; ++it) {
PatternConfig& pattern = *it->second;
std::cout << "Playing " << pattern.name << "\n";
// std::cout << "Playing " << pattern.name << "\n";

std::cout << " Playing before pattern\n";
// std::cout << " Playing before pattern\n";
for (auto& patternLine : pattern.before) {
std::cout << " Playing " << *patternLine << "\n";
// std::cout << " Playing " << *patternLine << "\n";
patternLine->execute(blinkDevice);
}

for (int i = 0; i < pattern.repeat && LOOPING; ++i) {
std::cout << " Playing iteration " << i << "/" << pattern.repeat << "\n";
// std::cout << " Playing iteration " << i << "/" << pattern.repeat << "\n";
for (auto& patternLine : pattern.pattern) {
std::cout << " Playing " << *patternLine << "\n";
// std::cout << " Playing " << *patternLine << "\n";
patternLine->execute(blinkDevice);
}
}

std::cout << " Playing after pattern\n";
// std::cout << " Playing after pattern\n";
for (auto& patternLine : pattern.after) {
std::cout << " Playing " << *patternLine << "\n";
// std::cout << " Playing " << *patternLine << "\n";
patternLine->execute(blinkDevice);
}
}
Expand All @@ -98,9 +98,6 @@ void cleanSocketFile() {
std::filesystem::remove("./blink1-control.sock");
}

namespace ba = boost::asio;
namespace bal = boost::asio::local;

int main(int argc, const char* argv[]) {

signal(SIGINT, signalCallbackHandler);
Expand All @@ -113,20 +110,16 @@ int main(int argc, const char* argv[]) {

std::atexit(cleanSocketFile);

ba::io_context ioc;
bal::stream_protocol::endpoint ep("./blink1-control.sock");
bal::stream_protocol::acceptor acceptor(ioc, ep);
bal::stream_protocol::socket socket(ioc);

while (LOOPING) {
bal::stream_protocol::iostream clientIos;
acceptor.accept(clientIos.socket());
blink1_control::network::NetworkManager networkManager(config->socketPath);

std::string data;
clientIos << "Hello, World!\n";
std::getline(clientIos, data);
std::cout << data << "\n";
}
std::cout << "Starting\n";
networkManager.start();
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Stopping\n";
networkManager.stop();
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Starting\n";
networkManager.start();

runPatterns(config);
}
67 changes: 67 additions & 0 deletions src/network/NetworkManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "network/NetworkManager.hpp"

#include <iostream>

namespace b = boost;
namespace ba = boost::asio;
namespace bal = boost::asio::local;

static void runIo(std::shared_ptr<ba::io_context> ioContext) {
ba::io_service::work work(*ioContext);
std::cout << "Starting I/O service\n";
ioContext->run();
std::cout << "I/O service finished\n";
}

namespace blink1_control::network {

NetworkManager::NetworkManager(std::string_view socketPath) :
ioc(std::make_shared<ba::io_context>()),
endpoint(socketPath),
acceptor(*ioc, endpoint),
ioThread(nullptr)
{}

NetworkManager::~NetworkManager() {
stop();
}

void NetworkManager::start() {
ioc->restart();
acceptor.listen();
startAccept();
ioThread = std::make_unique<boost::thread>(std::bind_front(&runIo, this->ioc));
}

void NetworkManager::stop() {
acceptor.cancel();
ioc->stop();
}

void NetworkManager::startAccept() {
acceptor.async_accept(std::bind_front(&NetworkManager::acceptHandler, this));
}

void NetworkManager::acceptHandler(const b::system::error_code& error, bal::stream_protocol::socket peer) {
if (error) {

if (error.value() != b::system::errc::operation_canceled) {
std::cout << "Error accepting connection: " << error.what() << "\n";
}

return;
}

std::cout << "Got connection\n";
bal::stream_protocol::iostream clientIos(std::move(peer));
std::string data;
std::cout << "Outbound: \"Hello, World!\"\n";
clientIos << "Hello, World!\n";
std::getline(clientIos, data);
std::cout << "Inbound: " << data << "\n";
std::cout << "Closing connection\n";

startAccept();
}

}

0 comments on commit 6e39f68

Please sign in to comment.