diff --git a/Src/ChannelLinter/ChannelLinter.cpp b/Src/ChannelLinter/ChannelLinter.cpp index 0ff7e07..996cc59 100644 --- a/Src/ChannelLinter/ChannelLinter.cpp +++ b/Src/ChannelLinter/ChannelLinter.cpp @@ -1,99 +1,89 @@ -#include "StdAfx.h" +#include "stdafx.h" +#include "ChannelLinter.h" + #include "Core/Profiler.h" namespace MWR::C3::Linter { - /// @throws std::runtime_error if channel with given name was not registered - auto const& GetChannelInfo(std::string_view channelName) + namespace { - return InterfaceFactory::Instance().Find(channelName)->second; - } - - /// template to avoid typing the whole name - template - auto GetChannelCapability(T const& channelInfo) - { - try + /// @throws std::runtime_error if channel with given name was not registered + auto const& GetChannelInfo(std::string_view channelName) { - auto ret = json::parse(channelInfo.m_Capability); - C3::Core::Profiler::Gateway::EnsureCreateExists(ret); - C3::Core::Profiler::Gateway::AddBuildInCommands(ret, true); - return ret; + return InterfaceFactory::Instance().Find(channelName)->second; } - catch (json::parse_error& e) + + /// template to avoid typing the whole name + template + auto GetChannelCapability(T const& channelInfo) { - throw std::runtime_error("Failed to parse channel's capability json. "s + e.what()); + try + { + auto ret = json::parse(channelInfo.m_Capability); + C3::Core::Profiler::Gateway::EnsureCreateExists(ret); + C3::Core::Profiler::Gateway::AddBuildInCommands(ret, true); + return ret; + } + catch (json::parse_error & e) + { + throw std::runtime_error("Failed to parse channel's capability json. "s + e.what()); + } + } + + /// template to avoid typing the whole name + template + auto MakeDevice(MWR::json const& createParams, const T& chInfo) + { + auto blob = MWR::C3::Core::Profiler::TranslateArguments(createParams); + auto channelBridge = std::make_shared(chInfo.m_Builder(blob)); + channelBridge->OnAttach(); + return channelBridge; } } - /// template to avoid typing the whole name - template - auto MakeDevice(MWR::json const& createParams, const T& chInfo) + void ChannelLinter::Process() { - auto blob = MWR::C3::Core::Profiler::TranslateArguments(createParams); - auto channelBridge = std::make_shared(chInfo.m_Builder(blob)); - channelBridge->OnAttach(); - return channelBridge; + // select channel + auto const& chInfo = C3::Linter::GetChannelInfo(m_Config.m_ChannelName); + + // read create and prompt for arguments + auto capability = C3::Linter::GetChannelCapability(chInfo); + + std::cout << "Create channel 1" << std::endl; + C3::Linter::Form form(capability.at("/create/arguments"_json_pointer)); + auto createParams = form.FillForm(m_Config.m_ChannelArguments); + auto channel = C3::Linter::MakeDevice(createParams, chInfo); + + if (m_Config.m_TestChannelIO) + { + std::cout << "Create channel 2" << std::endl; + auto const& ch2Args = m_Config.m_ComplementaryChannelArguments ? *m_Config.m_ComplementaryChannelArguments : form.GetComplementaryArgs(m_Config.m_ChannelArguments); + json createParams2 = form.FillForm(ch2Args); + auto ch2 = C3::Linter::MakeDevice(createParams2, chInfo); + + // test write and read + auto data = ByteVector(ByteView(MWR::Utils::GenerateRandomString(64))); + channel->GetDevice()->OnSendToChannelInternal(data); + auto rcv = std::static_pointer_cast(ch2->GetDevice())->OnReceiveFromChannelInternal(); + if (data != rcv.at(0)) + throw std::exception("data sent and received mismatch"); + } + + if (m_Config.m_Command) + { + auto& commandParams = *m_Config.m_Command; + auto commandIdL = std::stoi(commandParams.at(0)); + auto commandId = static_cast(commandIdL); + + auto& commands = capability.at("commands"); + auto commandIt = std::find_if(begin(commands), end(commands), [commandId](auto const& c) { return c.contains("id") && c["id"].get() == commandId; }); + if (commandIt == end(commands)) + throw std::runtime_error("Failed to find a command with id: " + std::to_string(commandId)); + + C3::Linter::Form commandForm(commandIt->at("arguments")); + auto args = commandForm.FillForm({ begin(commandParams) + 1, end(commandParams) }); // +1 to omit command ID + auto x = ByteVector{}.Concat(commandId, C3::Core::Profiler::TranslateArguments(args)); + channel->RunCommand(x); + } } } - -/// Entry point of the application. -/// @param argc number of program arguments. -/// @param argv vector of program arguments. -int main(DWORD argc, char* argv[]) -try -{ - using namespace MWR; - - std::cout << "Custom Command and Control - Channel linter. BUILD: " << C3_BUILD_VERSION << std::endl; - C3::Linter::AppConfig context(argc, argv); - auto const& config = context.GetConfig(); - - // select channel - auto const& chInfo = C3::Linter::GetChannelInfo(config.m_ChannelName); - - // read create and prompt for arguments - auto capability = C3::Linter::GetChannelCapability(chInfo); - - std::cout << "Create channel 1" << std::endl; - C3::Linter::Form form(capability.at("/create/arguments"_json_pointer)); - auto createParams = form.FillForm(config.m_ChannelArguments); - auto channel = C3::Linter::MakeDevice(createParams, chInfo); - - if (config.m_TestChannelIO) - { - std::cout << "Create channel 2" << std::endl; - auto const& ch2Args = config.m_ComplementaryChannelArguments ? *config.m_ComplementaryChannelArguments : form.GetComplementaryArgs(config.m_ChannelArguments); - json createParams2 = form.FillForm(ch2Args); - auto ch2 = C3::Linter::MakeDevice(createParams2, chInfo); - - // test write and read - auto data = ByteVector(ByteView(MWR::Utils::GenerateRandomString(64))); - channel->GetDevice()->OnSendToChannelInternal(data); - auto rcv = std::static_pointer_cast(ch2->GetDevice())->OnReceiveFromChannelInternal(); - if (data != rcv.at(0)) - throw std::exception("data sent and received mismatch"); - } - - if (config.m_Command) - { - auto& commandParams = *config.m_Command; - auto commandIdL = std::stoi(commandParams.at(0)); - auto commandId = static_cast(commandIdL); - - auto& commands = capability.at("commands"); - auto commandIt = std::find_if(begin(commands), end(commands), [commandId](auto const& c) { return c.contains("id") && c["id"].get() == commandId;}); - if (commandIt == end(commands)) - throw std::runtime_error("Failed to find a command with id: " + std::to_string(commandId)); - - C3::Linter::Form commandForm(commandIt->at("arguments")); - auto args = commandForm.FillForm({begin(commandParams) + 1, end(commandParams) }); // +1 to omit command ID - auto x = ByteVector{}.Concat(commandId, C3::Core::Profiler::TranslateArguments(args)); - channel->RunCommand(x); - } -} -catch (std::exception & e) -{ - std::cerr << e.what() << std::endl; - return 1; -} diff --git a/Src/ChannelLinter/ChannelLinter.h b/Src/ChannelLinter/ChannelLinter.h new file mode 100644 index 0000000..4407961 --- /dev/null +++ b/Src/ChannelLinter/ChannelLinter.h @@ -0,0 +1,15 @@ +#pragma once + +namespace MWR::C3::Linter +{ + class ChannelLinter + { + public: + ChannelLinter(AppConfig::Config const& config) : m_Config(config) {} + void Process(); + + private: + AppConfig::Config const& m_Config; + }; +} + diff --git a/Src/ChannelLinter/ChannelLinter.vcxproj b/Src/ChannelLinter/ChannelLinter.vcxproj index 274d974..2f181e7 100644 --- a/Src/ChannelLinter/ChannelLinter.vcxproj +++ b/Src/ChannelLinter/ChannelLinter.vcxproj @@ -296,6 +296,7 @@ + @@ -305,6 +306,7 @@ + diff --git a/Src/ChannelLinter/ChannelLinter.vcxproj.filters b/Src/ChannelLinter/ChannelLinter.vcxproj.filters index 7723948..3943586 100644 --- a/Src/ChannelLinter/ChannelLinter.vcxproj.filters +++ b/Src/ChannelLinter/ChannelLinter.vcxproj.filters @@ -4,12 +4,13 @@ - + + @@ -18,5 +19,6 @@ + \ No newline at end of file diff --git a/Src/ChannelLinter/ChannelLinterMain.cpp b/Src/ChannelLinter/ChannelLinterMain.cpp new file mode 100644 index 0000000..4f03b5f --- /dev/null +++ b/Src/ChannelLinter/ChannelLinterMain.cpp @@ -0,0 +1,21 @@ +#include "StdAfx.h" + + +/// Entry point of the application. +/// @param argc number of program arguments. +/// @param argv vector of program arguments. +int main(DWORD argc, char* argv[]) +try +{ + using namespace MWR; + + std::cout << "Custom Command and Control - Channel linter. BUILD: " << C3_BUILD_VERSION << std::endl; + C3::Linter::AppConfig context(argc, argv); + auto const& config = context.GetConfig(); + C3::Linter::ChannelLinter(config).Process(); +} +catch (std::exception & e) +{ + std::cerr << e.what() << std::endl; + return 1; +} diff --git a/Src/ChannelLinter/StdAfx.h b/Src/ChannelLinter/StdAfx.h index 798ec71..4ac3e38 100644 --- a/Src/ChannelLinter/StdAfx.h +++ b/Src/ChannelLinter/StdAfx.h @@ -23,3 +23,4 @@ using json = nlohmann::json; #include "FormElement.hpp" #include "Form.h" #include "MockDeviceBridge.h" +#include "ChannelLinter.h"