diff --git a/Src/Common/MWR/C3/Interfaces/Channels/UncShareFile.cpp b/Src/Common/MWR/C3/Interfaces/Channels/UncShareFile.cpp index 7dcca9b..867fede 100644 --- a/Src/Common/MWR/C3/Interfaces/Channels/UncShareFile.cpp +++ b/Src/Common/MWR/C3/Interfaces/Channels/UncShareFile.cpp @@ -83,7 +83,6 @@ size_t MWR::C3::Interfaces::Channels::UncShareFile::OnSendToChannel(ByteView dat } std::filesystem::rename(tmpFilePath, filePath); - Log({ OBF("OnSend() called for UncShareFile carrying ") + std::to_string(data.size()) + OBF(" bytes"), LogMessage::Severity::DebugInformation }); return data.size(); } catch (std::exception& exception) diff --git a/Src/Common/MWR/C3/Internals/AutomaticRegistrator.h b/Src/Common/MWR/C3/Internals/AutomaticRegistrator.h index 3da229b..0d73dce 100644 --- a/Src/Common/MWR/C3/Internals/AutomaticRegistrator.h +++ b/Src/Common/MWR/C3/Internals/AutomaticRegistrator.h @@ -6,7 +6,6 @@ namespace MWR::C3 { - /// Template class handling registration of Interface before main function. /// @tparam Iface. Interface to be registered. template @@ -43,21 +42,7 @@ namespace MWR::C3 template <> static std::string GetCapability() { - return R"_( -{ - "create": - { - "arguments": - [ - { - "type": "binary", - "description": "Blob of data that will be provided to Channel constructor.", - "name": "arguments" - } - ] - }, - "commands": [] -})_"; + return "{}"; } template <> @@ -104,128 +89,131 @@ namespace MWR::C3 constexpr HashT Register::s_InterfaceHash = Hash::Fnv1aType(); #pragma warning( pop ) - /// Specialization of Registration mechanism for Channel type Interface. - template - class Channel : public Register + namespace Interfaces { - public: - constexpr static std::chrono::milliseconds s_MinUpdateFrequency = 30ms; - constexpr static std::chrono::milliseconds s_MaxUpdateFrequency = 30ms; - - /// Constructor setting default update frequency for channel - Channel() + /// Specialization of Registration mechanism for Channel type Interface. + template + class Channel : public Register { - static_assert(Iface::s_MinUpdateFrequency >= 30ms && Iface::s_MinUpdateFrequency <= Iface::s_MaxUpdateFrequency, "The frequency is set incorrectly"); - m_MinUpdateFrequency = Iface::s_MinUpdateFrequency; - m_MaxUpdateFrequency = Iface::s_MaxUpdateFrequency; - } + public: + constexpr static std::chrono::milliseconds s_MinUpdateFrequency = 30ms; + constexpr static std::chrono::milliseconds s_MaxUpdateFrequency = 30ms; - /// Callback that is periodically called for every Device to update itself. - /// This is point where dynamic polymorphisms is replaced by static one with recognition of returned value. - /// Types using Channel CRTP should implement MWR::ByteVector OnReceiveFromChannel(), or std::vector OnReceiveFromChannel() - /// @return std::vector that contains all packets retrieved from Channel. - std::vector OnReceiveFromChannelInternal() override final - { - static_assert(CanRecive<>::value, "OnReceiveFromChannel is not implemented"); - static_assert(std::is_same_v, ByteVector> || std::is_same_v, std::vector>, "OnReceiveFromChannel should return ByteVector or std::vector"); - return ReceiveWrapper(); - } + /// Constructor setting default update frequency for channel + Channel() + { + static_assert(Iface::s_MinUpdateFrequency >= 30ms && Iface::s_MinUpdateFrequency <= Iface::s_MaxUpdateFrequency, "The frequency is set incorrectly"); + m_MinUpdateFrequency = Iface::s_MinUpdateFrequency; + m_MaxUpdateFrequency = Iface::s_MaxUpdateFrequency; + } - /// Called every time Relay wants to send a packet through this Channel Device. - /// This is point where dynamic polymorphisms is replaced by static one. - /// Types using Channel CRTP should implement size_t OnSendToChannel(ByteView). - /// @param blob buffer containing data to send. - size_t OnSendToChannelInternal(ByteView packet) override final - { - static_assert(CanSend::value, "OnSendToChannel is not implemented"); - auto self = static_cast(this); - return self->OnSendToChannel(packet); - } + /// Callback that is periodically called for every Device to update itself. + /// This is point where dynamic polymorphisms is replaced by static one with recognition of returned value. + /// Types using Channel CRTP should implement MWR::ByteVector OnReceiveFromChannel(), or std::vector OnReceiveFromChannel() + /// @return std::vector that contains all packets retrieved from Channel. + std::vector OnReceiveFromChannelInternal() override final + { + static_assert(CanRecive<>::value, "OnReceiveFromChannel is not implemented"); + static_assert(std::is_same_v, ByteVector> || std::is_same_v, std::vector>, "OnReceiveFromChannel should return ByteVector or std::vector"); + return ReceiveWrapper(); + } - private: - /// Alias to get result of OnReceiveFromChannel call. - /// Use in form ReceiveReturnType to obtain type. - /// Can fail if function is not implemented. - template - using ReceiveReturnType = decltype(std::declval().OnReceiveFromChannel(std::declval()...)); + /// Called every time Relay wants to send a packet through this Channel Device. + /// This is point where dynamic polymorphisms is replaced by static one. + /// Types using Channel CRTP should implement size_t OnSendToChannel(ByteView). + /// @param blob buffer containing data to send. + size_t OnSendToChannelInternal(ByteView packet) override final + { + static_assert(CanSend::value, "OnSendToChannel is not implemented"); + auto self = static_cast(this); + return self->OnSendToChannel(packet); + } - /// Alias to test if OnReceiveFromChannel is implemented. - /// Use in form CanRecive::value to obtain bool value with information. - template - using CanRecive = MWR::Utils::CanApply; + private: + /// Alias to get result of OnReceiveFromChannel call. + /// Use in form ReceiveReturnType to obtain type. + /// Can fail if function is not implemented. + template + using ReceiveReturnType = decltype(std::declval().OnReceiveFromChannel(std::declval()...)); - /// Alias to get result of OnSendToChannel call. - /// Use in form SendReturnType to obtain type. - /// Can fail if function is not implemented. - template - using SendReturnType = decltype(std::declval().OnSendToChannel(std::declval()...)); + /// Alias to test if OnReceiveFromChannel is implemented. + /// Use in form CanRecive::value to obtain bool value with information. + template + using CanRecive = MWR::Utils::CanApply; - /// Alias to test if OnSendToChannel is implemented. - /// Use in form CanSend::value to obtain bool value with information. - template - using CanSend = MWR::Utils::CanApply; + /// Alias to get result of OnSendToChannel call. + /// Use in form SendReturnType to obtain type. + /// Can fail if function is not implemented. + template + using SendReturnType = decltype(std::declval().OnSendToChannel(std::declval()...)); - /// Virtual OnSendToChannelInternal cannot be templated. - /// This function will be available for call if OnReceiveFromChannel returns ByteVector. - /// @returns std::vector one packet pushed on collection if it is not empty.. - template - std::enable_if_t, ByteVector>, std::vector> ReceiveWrapper() - { - auto self = static_cast(this); - std::vector ret; - if (auto packet = self->OnReceiveFromChannel(); !packet.empty()) - ret.push_back(std::move(packet)); + /// Alias to test if OnSendToChannel is implemented. + /// Use in form CanSend::value to obtain bool value with information. + template + using CanSend = MWR::Utils::CanApply; - return ret; - } + /// Virtual OnSendToChannelInternal cannot be templated. + /// This function will be available for call if OnReceiveFromChannel returns ByteVector. + /// @returns std::vector one packet pushed on collection if it is not empty.. + template + std::enable_if_t, ByteVector>, std::vector> ReceiveWrapper() + { + auto self = static_cast(this); + std::vector ret; + if (auto packet = self->OnReceiveFromChannel(); !packet.empty()) + ret.push_back(std::move(packet)); - /// Virtual OnSendToChannelInternal cannot be templated. - /// This function will be available for call if OnReceiveFromChannel returns std::vector. - /// @returns std::vector many packets that are not empty. - template - std::enable_if_t, std::vector>, std::vector> ReceiveWrapper() - { - auto self = static_cast(this); - auto ret = self->OnReceiveFromChannel(); - static_cast(std::remove_if(ret.begin(), ret.end(), [](auto&& e) { return e.empty(); })); - return ret; - } - }; + return ret; + } + + /// Virtual OnSendToChannelInternal cannot be templated. + /// This function will be available for call if OnReceiveFromChannel returns std::vector. + /// @returns std::vector many packets that are not empty. + template + std::enable_if_t, std::vector>, std::vector> ReceiveWrapper() + { + auto self = static_cast(this); + auto ret = self->OnReceiveFromChannel(); + static_cast(std::remove_if(ret.begin(), ret.end(), [](auto&& e) { return e.empty(); })); + return ret; + } + }; #ifdef C3_IS_GATEWAY - /// Specialization of Registration mechanism for Connector type Interface. - template - class Connector : public Register - { - public: - // connector in fact does not need those values. They are here to satisfy template requirements. - constexpr static std::chrono::milliseconds s_MinUpdateFrequency = 0ms; - constexpr static std::chrono::milliseconds s_MaxUpdateFrequency = 0ms; - }; + /// Specialization of Registration mechanism for Connector type Interface. + template + class Connector : public Register + { + public: + // connector in fact does not need those values. They are here to satisfy template requirements. + constexpr static std::chrono::milliseconds s_MinUpdateFrequency = 0ms; + constexpr static std::chrono::milliseconds s_MaxUpdateFrequency = 0ms; + }; #else - /// Don't register the connectors in node builds - template - class Connector : public AbstractConnector - { - }; + /// Don't register the connectors in node builds + template + class Connector : public AbstractConnector + { + }; #endif C3_IS_GATEWAY #pragma warning( push ) #pragma warning( disable : 4307) - /// Specialization of Registration mechanism for Peripheral type Interface. - template - class Peripheral : public Register()> - { - public: - constexpr static std::chrono::milliseconds s_MinUpdateFrequency = 30ms; - constexpr static std::chrono::milliseconds s_MaxUpdateFrequency = 30ms; - - Peripheral() + /// Specialization of Registration mechanism for Peripheral type Interface. + template + class Peripheral : public Register()> { - static_assert(Iface::s_MinUpdateFrequency >= 30ms && Iface::s_MinUpdateFrequency <= Iface::s_MaxUpdateFrequency, "The frequency is set incorrectly"); - m_MinUpdateFrequency = Iface::s_MinUpdateFrequency; - m_MaxUpdateFrequency = Iface::s_MaxUpdateFrequency; - } - }; + public: + constexpr static std::chrono::milliseconds s_MinUpdateFrequency = 30ms; + constexpr static std::chrono::milliseconds s_MaxUpdateFrequency = 30ms; + + Peripheral() + { + static_assert(Iface::s_MinUpdateFrequency >= 30ms && Iface::s_MinUpdateFrequency <= Iface::s_MaxUpdateFrequency, "The frequency is set incorrectly"); + m_MinUpdateFrequency = Iface::s_MinUpdateFrequency; + m_MaxUpdateFrequency = Iface::s_MaxUpdateFrequency; + } + }; #pragma warning( pop ) + } } diff --git a/Src/Common/MWR/C3/Internals/InterfaceFactory.cpp b/Src/Common/MWR/C3/Internals/InterfaceFactory.cpp index f6e0542..08906f8 100644 --- a/Src/Common/MWR/C3/Internals/InterfaceFactory.cpp +++ b/Src/Common/MWR/C3/Internals/InterfaceFactory.cpp @@ -23,9 +23,6 @@ std::string MWR::C3::InterfaceFactory::GetCapability() { json entry; entry["type"] = e.first; - if (e.second.m_Capability.empty() || e.second.m_Name.empty()) - continue; - entry["name"] = e.second.m_Name; auto pin = json::parse(e.second.m_Capability); for (const auto& j : pin.items()) diff --git a/Src/Core/Profiler.cpp b/Src/Core/Profiler.cpp index eeffabe..f2e1402 100644 --- a/Src/Core/Profiler.cpp +++ b/Src/Core/Profiler.cpp @@ -117,7 +117,7 @@ MWR::ByteVector MWR::C3::Core::Profiler::TranslateArguments(json const& argument if (!argument.is_array()) translate(argument); else - for (auto subargument : argument) + for (auto const subargument : argument) translate(subargument); } @@ -821,6 +821,20 @@ json MWR::C3::Core::Profiler::Gateway::GetCapability() // Construct the InitialPacket. json initialPacket = json::parse(gateway->m_InterfaceFactory.GetCapability()); + for (auto& interface : initialPacket["channels"]) + if (!interface.contains("create")) + interface["create"] = json::parse(R"( + { + "arguments" : + [ + { + "type": "binary", + "description": "Blob of data that will be provided to Channel constructor.", + "name": "arguments" + } + ] + })"); + // Create method in interface is constructor. It must be a relay/gateway command. // initialPacket is copied to original to prevent iterator invalidation. // last 256 commands will be reserved for common commands. @@ -829,14 +843,13 @@ json MWR::C3::Core::Profiler::Gateway::GetCapability() auto idToErase = 0; std::vector>> buffer; buffer.resize(prefix.size()); - for (auto&& e : oryginal[interfaceType]) + for (auto&& element : oryginal[interfaceType]) { try { for (auto i = 0u; i < prefix.size(); ++i) { - - auto arguments = e.at("create").at("arguments"); + auto arguments = element.at("create").at("arguments"); if (i) // NegotiationChannel command { if (arguments.empty() || arguments[0].size() != 2) @@ -846,7 +859,7 @@ json MWR::C3::Core::Profiler::Gateway::GetCapability() } for (auto&& relayType : relayTypes) - buffer[i][relayType].push_back(json{ {"name", prefix[i] + e["name"].get()}, {"arguments", arguments}, {"id", id} }); + buffer[i][relayType].push_back(json{ {"name", prefix[i] + element["name"].get()}, {"arguments", arguments}, {"id", id} }); m_CreateCommands.push_back({ id, initialPacket[interfaceType][idToErase]["type"].get(), isDevice, !!i }); // store command id and hash. --id; @@ -856,7 +869,7 @@ json MWR::C3::Core::Profiler::Gateway::GetCapability() initialPacket[interfaceType][idToErase].erase("create"); initialPacket[interfaceType][idToErase]["commands"].push_back(json{ {"name", isDevice ? "Close" : "TurnOff"}, {"id", static_cast>(NodeRelay::Command::Close) }, {"arguments", json::array()} }); if (isDevice) - initialPacket[interfaceType][idToErase]["commands"].push_back(json{ {"name", "UpdateDelayJitter"}, {"description", "Set delay between receiving function calls."}, {"id", static_cast>(NodeRelay::Command::UpdateJitter) }, + initialPacket[interfaceType][idToErase]["commands"].push_back(json{ {"name", "Set UpdateDelayJitter"}, {"description", "Set delay between receiving function calls."}, {"id", static_cast>(NodeRelay::Command::UpdateJitter) }, {"arguments", { {{"type", "float"}, {"name", "Min"}, {"description", "Minimal delay in seconds"}, {"min", 0.03}}, {{"type", "float"}, {"name", "Max"}, {"description", "Maximal delay in seconds. "}, {"min", 0.03}}