Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions SwitchBoard/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,21 @@ endif()

# This is a plugin so we need the Plugin configuration section.
find_package(${NAMESPACE}Plugins REQUIRED)
find_package(CompileSettingsDebug REQUIRED)
find_package(CompileSettingsDebug CONFIG REQUIRED)

add_library(${MODULE_NAME} SHARED
SwitchBoard.cpp
Module.cpp)

set_target_properties(${MODULE_NAME} PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED YES)
target_compile_options (${MODULE_NAME} PRIVATE -Wno-psabi)

target_link_libraries(${MODULE_NAME}
PRIVATE
${NAMESPACE}Plugins::${NAMESPACE}Plugins
CompileSettingsDebug::CompileSettingsDebug)
CompileSettingsDebug::CompileSettingsDebug
${NAMESPACE}Plugins::${NAMESPACE}Plugins)

# Library installation section
string(TOLOWER ${NAMESPACE} STORAGENAME)
Expand Down
133 changes: 65 additions & 68 deletions SwitchBoard/SwitchBoard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,13 @@ POP_WARNING()

if (_switches.size() == 0) {
_service->Unregister(&_sink);
_service->Release();
_service = nullptr;
_switches.clear();
}
else {
Exchange::JSwitchBoard::Register(*this, this);
}
}

Initialize();
Expand All @@ -115,6 +119,8 @@ POP_WARNING()
ASSERT(_service == service);
ASSERT(_switches.size() > 1);

Exchange::JSwitchBoard::Unregister(*this);

for (auto& index: _switches) {
index.second.Unregister(&_sink);
}
Expand All @@ -134,111 +140,100 @@ POP_WARNING()
return (string());
}

/* virtual */ void SwitchBoard::Inbound(Web::Request& request VARIABLE_IS_NOT_USED)
{
// No body required...
}

/* virtual */ Core::ProxyType<Web::Response> SwitchBoard::Process(const Web::Request& request)
Core::hresult SwitchBoard::Register(Exchange::ISwitchBoard::INotification* const notification)
{
Core::ProxyType<Web::Response> result(PluginHost::IFactories::Instance().Response());

TRACE(Trace::Information, (string(_T("Received request"))));
Core::hresult result = Core::ERROR_ALREADY_CONNECTED;

Core::TextSegmentIterator index(Core::TextFragment(
request.Path,
_skipURL,
request.Path.length() - _skipURL),
false,
'/');

// Always skip the first one, it is an empty part because we start with '/' if tehre are more parameters.
index.Next();

result->ErrorCode = Web::STATUS_BAD_REQUEST;
result->Message = string(_T("Dont understand what to do with this request"));
ASSERT(notification != nullptr);

// For now, whatever the URL, we will just, on a get, drop all info we have
if ( (request.Verb == Web::Request::HTTP_GET) && (index.Next() == false) ) {
_adminLock.Lock();

Core::ProxyType<Web::JSONBodyType<Config> > response(jsonBodySwitchFactory.Element());
auto it = std::find(_notificationClients.begin(), _notificationClients.end(), notification);
ASSERT(it == _notificationClients.end());

SwitchBoard::Iterator index(_switches);
Core::JSON::String element(true);
if (it == _notificationClients.end()) {
notification->AddRef();

while (index.Next() == true) {
element = index.Callsign();
response->Callsigns.Add(element);
}

if (_defaultCallsign != nullptr) {
response->Default = _defaultCallsign->Callsign();
}
_notificationClients.push_back(notification);

result->ErrorCode = Web::STATUS_OK;
result->Message = string(_T("OK"));
result->Body(Core::ProxyType<Web::IBody>(response));

} else if ( (request.Verb == Web::Request::HTTP_PUT) && (index.Next() == true) ) {
const string callSign(index.Current().Text());
uint32_t error = Activate(callSign);
if (error != Core::ERROR_NONE) {
result->ErrorCode = Web::STATUS_NOT_MODIFIED;
result->Message = string(_T("Switch did not succeed. Error: ")) +
Core::NumberType<uint32_t>(error).Text();
} else {
result->ErrorCode = Web::STATUS_OK;
result->Message = string(_T("OK"));
}
result = Core::ERROR_NONE;
}

_adminLock.Unlock();

return (result);
}

void SwitchBoard::Register(Exchange::ISwitchBoard::INotification* notification)
Core::hresult SwitchBoard::Unregister(const Exchange::ISwitchBoard::INotification* const notification)
{
Core::hresult result = Core::ERROR_ALREADY_RELEASED;

ASSERT(notification != nullptr);

_adminLock.Lock();

std::list<Exchange::ISwitchBoard::INotification*>::iterator index(std::find(_notificationClients.begin(), _notificationClients.end(), notification));
auto it = std::find(_notificationClients.cbegin(), _notificationClients.cend(), notification);
ASSERT(it != _notificationClients.end());

ASSERT(index == _notificationClients.end());
if (it != _notificationClients.end()) {
(*it)->Release();

if (index == _notificationClients.end()) {
_notificationClients.push_back(notification);
_notificationClients.erase(it);

result = Core::ERROR_NONE;
}

_adminLock.Unlock();

return (result);
}

void SwitchBoard::Unregister(Exchange::ISwitchBoard::INotification* notification)
Core::hresult SwitchBoard::Switches(Exchange::ISwitchBoard::IStringIterator*& switches) const
{
ASSERT(notification != nullptr);
std::vector<string> list;

_adminLock.Lock();
for (const auto& entry : _switches) {
list.push_back(entry.first);
}

std::list<Exchange::ISwitchBoard::INotification*>::iterator index(std::find(_notificationClients.begin(), _notificationClients.end(), notification));
using Implementation = RPC::IteratorType<RPC::IStringIterator>;
switches = Core::ServiceType<Implementation>::Create<RPC::IStringIterator>(list);

ASSERT(index != _notificationClients.end());
return (Core::ERROR_NONE);
}

Core::hresult SwitchBoard::Default(string& callsign) const
{
Core::hresult result = Core::ERROR_NONE;

if (index != _notificationClients.end()) {
_notificationClients.erase(index);
if (_defaultCallsign != nullptr) {
callsign = _defaultCallsign->Callsign();
}
else {
result = Core::ERROR_UNAVAILABLE;
}

_adminLock.Unlock();
return (result);
}

/* virtual */ bool SwitchBoard::IsActive(const string& callsign) const
/* virtual */ Core::hresult SwitchBoard::IsActive(const string& callsign, bool& active) const
{
Core::hresult result = Core::ERROR_NONE;
std::map<string, Entry>::const_iterator index(_switches.find(callsign));

return (index != _switches.end() ? index->second.IsActive() : false);
if (index != _switches.end()) {
active = index->second.IsActive();
}
else {
result = Core::ERROR_UNKNOWN_KEY;
}

return (result);
}

/* virtual */ uint32_t SwitchBoard::Activate(const string& callsign)
/* virtual */ Core::hresult SwitchBoard::Activate(const string& callsign)
{
uint32_t result = (_state == INACTIVE ? Core::ERROR_ILLEGAL_STATE : Core::ERROR_INPROGRESS);
Core::hresult result = (_state == INACTIVE ? Core::ERROR_ILLEGAL_STATE : Core::ERROR_INPROGRESS);

_adminLock.Lock();

Expand Down Expand Up @@ -283,9 +278,9 @@ POP_WARNING()
return (result);
}

/* virtual */ uint32_t SwitchBoard::Deactivate(const string& callsign)
/* virtual */ Core::hresult SwitchBoard::Deactivate(const string& callsign)
{
uint32_t result = (_state == INACTIVE ? Core::ERROR_ILLEGAL_STATE : Core::ERROR_INPROGRESS);
Core::hresult result = (_state == INACTIVE ? Core::ERROR_ILLEGAL_STATE : Core::ERROR_INPROGRESS);

_adminLock.Lock();

Expand Down Expand Up @@ -398,6 +393,8 @@ POP_WARNING()
(*index)->Activated(callsign);
index++;
}

Exchange::JSwitchBoard::Event::Activated(*this, callsign);
}
}

Expand Down
34 changes: 13 additions & 21 deletions SwitchBoard/SwitchBoard.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@

#include "Module.h"
#include <interfaces/ISwitchBoard.h>
#include <interfaces/json/JSwitchBoard.h>

namespace Thunder {
namespace Plugin {

class SwitchBoard : public PluginHost::IPlugin, PluginHost::IWeb, Exchange::ISwitchBoard {
class SwitchBoard : public Exchange::ISwitchBoard
, public PluginHost::IPlugin
, public PluginHost::JSONRPC {

public:
class Config : public Core::JSON::Container {
Expand Down Expand Up @@ -396,31 +399,20 @@ namespace Plugin {
// to this plugin. This Metadata can be used by the MetData plugin to publish this information to the ouside world.
string Information() const override;

// IWeb methods
// -------------------------------------------------------------------------------------------------------
// Whenever a request is received, it might carry some additional data in the body. This method allows
// the plugin to attach a deserializable data object (ref counted) to be loaded with any potential found
// in the body of the request.
void Inbound(Web::Request& request) override;
// ISwitchBoard interface
Core::hresult Register(Exchange::ISwitchBoard::INotification* const notification) override;
Core::hresult Unregister(const Exchange::ISwitchBoard::INotification* const notification) override;

// If everything is received correctly, the request is passed to us, on a thread from the thread pool, to
// do our thing and to return the result in the response object. Here the actual specific module work,
// based on a a request is handled.
Core::ProxyType<Web::Response> Process(const Web::Request& request) override;
Core::hresult Switches(Exchange::ISwitchBoard::IStringIterator*& switches) const override;
Core::hresult Default(string& callsign) const override;

// IUnknown methods
// -------------------------------------------------------------------------------------------------------

// ISwitchBoard interface
void Register(Exchange::ISwitchBoard::INotification* notification) override;
void Unregister(Exchange::ISwitchBoard::INotification* notification) override;
bool IsActive(const string& callsign) const override;
uint32_t Activate(const string& callsign) override;
uint32_t Deactivate(const string& callsign) override;
Core::hresult IsActive(const string& callsign, bool& active) const override;
Core::hresult Activate(const string& callsign) override;
Core::hresult Deactivate(const string& callsign) override;

BEGIN_INTERFACE_MAP(SwitchBoard)
INTERFACE_ENTRY(PluginHost::IPlugin)
INTERFACE_ENTRY(PluginHost::IWeb)
INTERFACE_ENTRY(PluginHost::IDispatcher)
INTERFACE_ENTRY(Exchange::ISwitchBoard)
END_INTERFACE_MAP

Expand Down
14 changes: 14 additions & 0 deletions SwitchBoard/SwitchBoardPlugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"$schema": "plugin.schema.json",
"info": {
"title": "Switch Board Plugin",
"callsign": "SwitchBoard",
"locator": "libThunderSwitchBoard.so",
"status": "production",
"description": "This plugin is configured to manage a group of plugins, within which only one plugin can be active",
"version": "1.0"
},
"interface": [
{ "$ref": "{cppinterfacedir}/ISwitchBoard.h" }
]
}
Loading
Loading