Merge branch 'Decouple' into 'master'

Decouple

See merge request C3/C3!141
dependabot/npm_and_yarn/Src/WebController/UI/websocket-extensions-0.1.4
Grzegorz Rychlik 2019-10-31 15:53:29 +00:00
commit 08c3087aa7
8 changed files with 69 additions and 51 deletions

View File

@ -35,6 +35,18 @@ namespace MWR::C3
}
};
enum class Command : std::uint16_t
{
AddDevice = 0,
Close = static_cast<std::uint16_t>(-1), // for relays and interfaces last 256 commands are reserved for general commands.
UpdateJitter = static_cast<std::uint16_t>(-2),
CreateRoute = static_cast<std::uint16_t>(-3),
RemoveRoute = static_cast<std::uint16_t>(-4),
SetGRC = static_cast<std::uint16_t>(-5),
Ping = static_cast<std::uint16_t>(-6),
ClearNetwork = static_cast<std::uint16_t>(-7),
};
namespace Utils
{
/// Gate/Node Relay starters logger callback prototype.
@ -70,6 +82,9 @@ namespace MWR::C3
/// Detaches the Device.
virtual void Detach() = 0;
/// Notify the relay that this bridge should be closed
virtual void Close() = 0;
/// Callback periodically fired by Relay for Device to update it's state. Might be called from a separate thread. Device should perform all necessary actions and leave as soon as possible.
virtual void OnReceive() = 0;
@ -124,6 +139,9 @@ namespace MWR::C3
/// Detaches the Connector.
virtual void Detach() = 0;
/// Notify the gateway to turn off the connector
virtual void TurnOff() = 0;
/// Called whenever Connector wants to send a Command to its Peripheral Binder.
/// @param binderId Identifier of Peripheral who sends the Command.
/// @param command full Command with arguments.

View File

@ -1,9 +1,5 @@
#include "StdAfx.h"
#include "Interface.h"
#include "Core/DeviceBridge.h" // TODO it would be great to remove core dependency. PTAL Close method
#include "Core/ConnectorBridge.h"
#include "Core/Relay.h"
#include "Core/GateRelay.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void MWR::C3::AbstractPeripheral::OnReceive()
@ -55,9 +51,9 @@ MWR::ByteVector MWR::C3::Device::OnRunCommand(ByteView command)
{
switch (command.Read<uint16_t>())
{
case static_cast<uint16_t>(MWR::C3::Core::Relay::Command::Close):
case static_cast<uint16_t>(MWR::C3::Command::Close):
return Close(), ByteVector{};
case static_cast<uint16_t>(MWR::C3::Core::Relay::Command::UpdateJitter) :
case static_cast<uint16_t>(MWR::C3::Command::UpdateJitter) :
{
auto [minVal, maxVal] = command.Read<float, float>();
return SetUpdateDelay(MWR::Utils::ToMilliseconds(minVal), MWR::Utils::ToMilliseconds(maxVal)), ByteVector{};
@ -80,17 +76,13 @@ MWR::ByteVector MWR::C3::AbstractConnector::OnRunCommand(ByteView command)
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void MWR::C3::Device::Close() // Closing mechanism was not originaly ment for device itself. It must call relay methods to remove itself. New mechanism that does not need to know relay must be introduced.
void MWR::C3::Device::Close()
{
auto bridge = std::static_pointer_cast<Core::DeviceBridge>(GetBridge());
auto relay = std::static_pointer_cast<Core::Relay>(bridge->GetRelay());
relay->DetachDevice(bridge->GetDid());
GetBridge()->Close();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void MWR::C3::AbstractConnector::TurnOff()
{
auto bridge = std::static_pointer_cast<Core::ConnectorBridge>(GetBridge());
auto gateway = std::static_pointer_cast<Core::GateRelay>(bridge->GetGateRelay());
gateway->TurnOffConnector(bridge->GetNameHash());
GetBridge()->TurnOff();
}

View File

@ -23,6 +23,13 @@ void MWR::C3::Core::ConnectorBridge::Detach()
m_IsAlive = false;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void MWR::C3::Core::ConnectorBridge::TurnOff()
{
auto gateway = GetGateRelay();
gateway->TurnOffConnector(GetNameHash());
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void MWR::C3::Core::ConnectorBridge::PostCommandToBinder(ByteView binderId, ByteView command)
{

View File

@ -30,6 +30,9 @@ namespace MWR::C3::Core
/// Detaches the Connector.
void Detach() override;
/// Notify the gateway to turn off the connector
void TurnOff() override;
/// Called whenever Connector wants to send a Command to its Peripheral Binder.
/// @param binderId Identifier of Peripheral who sends the Command.
/// @param command full Command with arguments.

View File

@ -31,6 +31,13 @@ void MWR::C3::Core::DeviceBridge::Detach()
m_IsAlive = false;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void MWR::C3::Core::DeviceBridge::Close()
{
auto relay = GetRelay();
relay->DetachDevice(GetDid());
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void MWR::C3::Core::DeviceBridge::OnReceive()
{

View File

@ -36,6 +36,9 @@ namespace MWR::C3::Core
/// Detaches the Device.
void Detach() override;
/// Notify the relay that this bridge should be closed
void Close() override;
/// Callback periodically fired by Relay for Device to update it's state. Might be called from a separate thread. Device should perform all necessary actions and leave as soon as possible.
void OnReceive() override;

View File

@ -522,9 +522,9 @@ void MWR::C3::Core::Profiler::Agent::ParseAndRunCommand(json const& jCommandElem
if (commandId > static_cast<std::uint16_t>(-256))
{
// generic interface commands
switch (static_cast<MWR::C3::Core::Relay::Command>(commandId))
switch (static_cast<MWR::C3::Command>(commandId))
{
case MWR::C3::Core::Relay::Command::Close:
case MWR::C3::Command::Close:
finalizer = [&]()
{
if (deviceIsChannel)
@ -553,7 +553,7 @@ void MWR::C3::Core::Profiler::Agent::ParseAndRunCommand(json const& jCommandElem
}
};
break;
case MWR::C3::Core::Relay::Command::UpdateJitter:
case MWR::C3::Command::UpdateJitter:
finalizer = [this, deviceId, deviceIsChannel, commandReadView]() mutable
{
Device* device = deviceIsChannel ? m_Channels.Find(*deviceId) : m_Peripherals.Find(*deviceId);
@ -609,9 +609,9 @@ void MWR::C3::Core::Profiler::Agent::RunCommand(ByteView commandWithArguments)
throw std::runtime_error("Failed to find route to agent id = " + m_Id.ToString());
std::function<void()> finalizer = []() {};
switch (static_cast<NodeRelay::Command>(commandId))
switch (static_cast<Command>(commandId))
{
case NodeRelay::Command::Close:
case Command::Close:
{
finalizer = [&]()
{
@ -637,7 +637,7 @@ void MWR::C3::Core::Profiler::Agent::RunCommand(ByteView commandWithArguments)
};
break;
}
case NodeRelay::Command::CreateRoute:
case Command::CreateRoute:
{
finalizer = [this, commandReadView]() mutable
{
@ -646,7 +646,7 @@ void MWR::C3::Core::Profiler::Agent::RunCommand(ByteView commandWithArguments)
};
break;
}
case NodeRelay::Command::RemoveRoute:
case Command::RemoveRoute:
{
finalizer = [this, commandReadView]() mutable
{
@ -654,7 +654,7 @@ void MWR::C3::Core::Profiler::Agent::RunCommand(ByteView commandWithArguments)
};
break;
}
case NodeRelay::Command::SetGRC:
case Command::SetGRC:
{
finalizer = [this, commandReadView]() mutable
{
@ -667,7 +667,7 @@ void MWR::C3::Core::Profiler::Agent::RunCommand(ByteView commandWithArguments)
};
break;
}
case NodeRelay::Command::Ping:
case Command::Ping:
break;
default:
throw std::runtime_error("Profiler received an unknown command for agent id: " + m_Id.ToString());
@ -713,7 +713,7 @@ void MWR::C3::Core::Profiler::Agent::PerformCreateCommand(json const& jCommandEl
// it is a create command
DeviceId newDeviceId = ++m_LastDeviceId;
ByteVector repacked;
repacked.Concat(static_cast<std::underlying_type_t<NodeRelay::Command>>(NodeRelay::Command::AddDevice), newDeviceId.ToByteVector(), command->m_IsNegotiableChannel, command->m_Hash);
repacked.Concat(static_cast<std::underlying_type_t<Command>>(Command::AddDevice), newDeviceId.ToByteVector(), command->m_IsNegotiableChannel, command->m_Hash);
if (auto binder = profiler->GetBinderTo(command->m_Hash); binder && command->m_IsDevice) // peripheral, check if payload is needed.
{
auto connector = profiler->m_Gateway->m_Gateway.lock()->GetConnector(binder);
@ -804,9 +804,9 @@ void MWR::C3::Core::Profiler::Gateway::ParseAndRunCommand(json const& jCommandEl
if (auto device = gateway->FindDevice(MWR::Utils::SafeCast<DeviceId::UnderlyingIntegerType>(id)); device)
{
auto localView = commandReadView;
switch (MWR::C3::Core::Relay::Command(localView.Read<std::uint16_t>()))
switch (MWR::C3::Command(localView.Read<std::uint16_t>()))
{
case MWR::C3::Core::Relay::Command::UpdateJitter:
case MWR::C3::Command::UpdateJitter:
{
Device* profilerElement = m_Channels.Find(device->GetDid());
if (!profilerElement)
@ -819,7 +819,7 @@ void MWR::C3::Core::Profiler::Gateway::ParseAndRunCommand(json const& jCommandEl
profilerElement->m_Jitter.second = MWR::Utils::ToMilliseconds(localView.Read<float>());
break;
}
case MWR::C3::Core::Relay::Command::Close:
case MWR::C3::Command::Close:
{
auto profilerElement = m_Peripherals.Find(device->GetDid());
if (!profilerElement)
@ -926,9 +926,9 @@ json MWR::C3::Core::Profiler::Gateway::GetCapability()
// modify initial Packet with extra entries.
initialPacket[interfaceType][idToErase].erase("create");
initialPacket[interfaceType][idToErase]["commands"].push_back(json{ {"name", isDevice ? "Close" : "TurnOff"}, {"id", static_cast<std::underlying_type_t<NodeRelay::Command>>(NodeRelay::Command::Close) }, {"arguments", json::array()} });
initialPacket[interfaceType][idToErase]["commands"].push_back(json{ {"name", isDevice ? "Close" : "TurnOff"}, {"id", static_cast<std::underlying_type_t<Command>>(Command::Close) }, {"arguments", json::array()} });
if (isDevice)
initialPacket[interfaceType][idToErase]["commands"].push_back(json{ {"name", "Set UpdateDelayJitter"}, {"description", "Set delay between receiving function calls."}, {"id", static_cast<std::underlying_type_t<NodeRelay::Command>>(NodeRelay::Command::UpdateJitter) },
initialPacket[interfaceType][idToErase]["commands"].push_back(json{ {"name", "Set UpdateDelayJitter"}, {"description", "Set delay between receiving function calls."}, {"id", static_cast<std::underlying_type_t<Command>>(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}}
@ -961,25 +961,25 @@ json MWR::C3::Core::Profiler::Gateway::GetCapability()
for (auto&& relayType : relayTypes)
initialPacket[relayType]["commands"].push_back(newCommand);
};
addRelayCommand({ "gateway", "relay" }, json{ {"name", "Close"}, {"id", static_cast<std::underlying_type_t<NodeRelay::Command>>(NodeRelay::Command::Close) }, {"arguments", json::array()} });
addRelayCommand({ "gateway", "relay" }, json{ {"name", "Close"}, {"id", static_cast<std::underlying_type_t<Command>>(Command::Close) }, {"arguments", json::array()} });
addRelayCommand({ "gateway", "relay" }, json{ {"name", "CreateRoute"}, {"id", static_cast<std::underlying_type_t<NodeRelay::Command>>(NodeRelay::Command::CreateRoute) }, {"arguments", {
addRelayCommand({ "gateway", "relay" }, json{ {"name", "CreateRoute"}, {"id", static_cast<std::underlying_type_t<Command>>(Command::CreateRoute) }, {"arguments", {
{{"type", "string"}, {"name", "RouteID"}, {"description", "Id of route in string form."}, {"min", 1}},
{{"type", "string"}, {"name", "DeviceId"}, {"description", "Id of device in string form."}, {"min", 1}},
{{"type", "boolean"}, {"name", "Neighbor"}, {"description", "Informs if relay is direct neighbor."}, {"defaultValue", true}}
}} });
addRelayCommand({ "gateway", "relay" }, json{ {"name", "RemoveRoute"}, {"id", static_cast<std::underlying_type_t<NodeRelay::Command>>(NodeRelay::Command::RemoveRoute) }, {"arguments", {
addRelayCommand({ "gateway", "relay" }, json{ {"name", "RemoveRoute"}, {"id", static_cast<std::underlying_type_t<Command>>(Command::RemoveRoute) }, {"arguments", {
{{"type", "string"}, {"name", "RouteID"}, {"description", "Id of route in string form."}, {"min", 1}}
}} });
addRelayCommand({ "relay" }, json{ {"name", "SetGatewayReturnChannel"}, {"id", static_cast<std::underlying_type_t<NodeRelay::Command>>(NodeRelay::Command::SetGRC) }, {"arguments", {
addRelayCommand({ "relay" }, json{ {"name", "SetGatewayReturnChannel"}, {"id", static_cast<std::underlying_type_t<Command>>(Command::SetGRC) }, {"arguments", {
{{"type", "string"}, {"name", "DeviceID"}, {"description", "Id of device in string form."}, {"min", 1}}
}} });
addRelayCommand({ "relay" }, json{ {"name", "Ping"}, {"id", static_cast<std::underlying_type_t<NodeRelay::Command>>(NodeRelay::Command::Ping) }, {"arguments", json::array() } });
addRelayCommand({ "relay" }, json{ {"name", "Ping"}, {"id", static_cast<std::underlying_type_t<Command>>(Command::Ping) }, {"arguments", json::array() } });
addRelayCommand({ "gateway" }, json{ {"name", "ClearNetwork"}, {"id", static_cast<std::underlying_type_t<NodeRelay::Command>>(NodeRelay::Command::ClearNetwork) }, {"arguments", {
addRelayCommand({ "gateway" }, json{ {"name", "ClearNetwork"}, {"id", static_cast<std::underlying_type_t<Command>>(Command::ClearNetwork) }, {"arguments", {
{{"type", "boolean"}, {"name", "Are you sure?"}, {"description", "Confirm clearing the network. All network state will be lost, this can not be undone."}, {"default", false}}
}} });
@ -1006,25 +1006,25 @@ void MWR::C3::Core::Profiler::Gateway::RunCommand(ByteView commandWithArguments)
if (!pin)
return;
switch (static_cast<GateRelay::Command>(commandWithArguments.Read<std::underlying_type_t<GateRelay::Command>>()))
switch (static_cast<Command>(commandWithArguments.Read<std::underlying_type_t<Command>>()))
{
case GateRelay::Command::Close:
case Command::Close:
pin->Close();
break;
case GateRelay::Command::CreateRoute:
case Command::CreateRoute:
{
pin->CreateRoute(commandWithArguments);
auto [ridStr, didStr, isNbr] = commandWithArguments.Read<std::string_view, std::string_view, bool>();
ReAddRoute(ridStr, didStr, isNbr);
break;
}
case GateRelay::Command::RemoveRoute:
case Command::RemoveRoute:
{
pin->RemoveRoute(commandWithArguments);
ReRemoveRoute(commandWithArguments.Read<std::string_view>());
break;
}
case GateRelay::Command::ClearNetwork:
case Command::ClearNetwork:
{
// Clear real gateway
pin->Reset();

View File

@ -8,18 +8,6 @@ namespace MWR::C3::Core
/// Last base layer class for both Relay types.
struct Relay : Distributor, MWR::C3::Relay
{
enum class Command : std::uint16_t
{
AddDevice = 0,
Close = static_cast<std::uint16_t>(-1), // for relays and interfaces last 256 commands are reserved for general commands.
UpdateJitter = static_cast<std::uint16_t>(-2),
CreateRoute = static_cast<std::uint16_t>(-3),
RemoveRoute = static_cast<std::uint16_t>(-4),
SetGRC = static_cast<std::uint16_t>(-5),
Ping = static_cast<std::uint16_t>(-6),
ClearNetwork = static_cast<std::uint16_t>(-7),
};
/// Called whenever an attached Binder Peripheral wants to send a Command to its Connector Binder.
/// @param command full Command with arguments.
/// @param sender Interface that is sending the Command.