diff --git a/Source/WPEFramework/Controller.cpp b/Source/WPEFramework/Controller.cpp index b866145213..343afa83d5 100644 --- a/Source/WPEFramework/Controller.cpp +++ b/Source/WPEFramework/Controller.cpp @@ -20,16 +20,16 @@ #include "Controller.h" #include "SystemInfo.h" -#include "JsonData_SystemManagement.h" -#include "JsonData_LifeTime.h" -#include "JsonData_Discovery.h" -#include "JsonData_Metadata.h" +#include +#include +#include +#include -#include "JDiscovery.h" -#include "JConfiguration.h" -#include "JSystemManagement.h" -#include "JLifeTime.h" -#include "JMetadata.h" +#include +#include +#include +#include +#include namespace WPEFramework { @@ -380,17 +380,15 @@ namespace Plugin { Core::ProxyType> response(jsonBodyMetaDataFactory.Element()); // No more parameters, flush it all.. - _pluginServer->Dispatcher().GetMetaData(response->Channels); - _pluginServer->Services().GetMetaData(response->Channels); - _pluginServer->Services().GetMetaData(response->Plugins); + _pluginServer->Metadata(response->Channels); + _pluginServer->Metadata(response->Plugins); WorkerPoolMetaData(response->Process); result->Body(Core::ProxyType(response)); } else if (index.Current() == _T("Links")) { Core::ProxyType> response(jsonBodyMetaDataFactory.Element()); - _pluginServer->Dispatcher().GetMetaData(response->Channels); - _pluginServer->Services().GetMetaData(response->Channels); + _pluginServer->Metadata(response->Channels); result->Body(Core::ProxyType(response)); } else if (index.Current() == _T("Plugins")) { @@ -685,7 +683,7 @@ namespace Plugin { void Controller::StartupResume(const string& callsign, PluginHost::IShell* plugin) { if (_resumes.size() > 0) { - std::list::iterator index(_resumes.begin()); + Resumes::iterator index(_resumes.begin()); ASSERT(_service != nullptr); @@ -794,11 +792,7 @@ namespace Plugin { } } - uint32_t Controller::Validate(const string& token, const string& method, const string& paramaters) const /* override */ { - return(PluginHost::JSONRPC::Validate(token, Core::JSONRPC::Message::Method(method), paramaters)); - } - - uint32_t Controller::Invoke(const uint32_t channelId, const uint32_t id, const string& token, const string& method, const string& parameters, string& response /* @out */) /* override */ + Core::hresult Controller::Invoke(const uint32_t channelId, const uint32_t id, const string& token, const string& method, const string& parameters, string& response /* @out */) /* override */ { Core::hresult result = Core::ERROR_BAD_REQUEST; string callsign(Core::JSONRPC::Message::Callsign(method)); @@ -821,16 +815,11 @@ namespace Plugin { else { ASSERT(service.IsValid()); - PluginHost::IDispatcher* dispatcher = reinterpret_cast(service->QueryInterface(PluginHost::IDispatcher::ID)); + PluginHost::IDispatcher* dispatcher = service->QueryInterface(); if (dispatcher != nullptr) { - PluginHost::ILocalDispatcher* localDispatcher = dispatcher->Local(); + result = dispatcher->Invoke(channelId, id, token, method, parameters, response); - ASSERT(localDispatcher != nullptr); - - if (localDispatcher != nullptr) { - result = localDispatcher->Invoke(channelId, id, token, Core::JSONRPC::Message::VersionedFullMethod(method), parameters, response); - } dispatcher->Release(); } } @@ -845,9 +834,9 @@ namespace Plugin { _adminLock.Lock(); // Make sure a sink is not registered multiple times. - ASSERT(std::find(_observers.begin(), _observers.end(), notification) == _observers.end()); + ASSERT(std::find(_lifeTimeObservers.begin(), _lifeTimeObservers.end(), notification) == _lifeTimeObservers.end()); - _observers.push_back(notification); + _lifeTimeObservers.push_back(notification); notification->AddRef(); _adminLock.Unlock(); @@ -859,14 +848,14 @@ namespace Plugin { { _adminLock.Lock(); - std::list::iterator index(std::find(_observers.begin(), _observers.end(), notification)); + LifeTimeNotifiers::iterator index(std::find(_lifeTimeObservers.begin(), _lifeTimeObservers.end(), notification)); // Make sure you do not unregister something you did not register !!! - ASSERT(index != _observers.end()); + ASSERT(index != _lifeTimeObservers.end()); - if (index != _observers.end()) { + if (index != _lifeTimeObservers.end()) { (*index)->Release(); - _observers.erase(index); + _lifeTimeObservers.erase(index); } _adminLock.Unlock(); @@ -874,6 +863,20 @@ namespace Plugin { return (Core::ERROR_NONE); } + Core::hresult Controller::Register(Exchange::Controller::IShells::INotification* notification) + { + _pluginServer->Services().Register(notification); + + return (Core::ERROR_NONE); + } + + Core::hresult Controller::Unregister(Exchange::Controller::IShells::INotification* notification) + { + _pluginServer->Services().Unregister(notification); + + return (Core::ERROR_NONE); + } + Core::hresult Controller::Activate(const string& callsign) { Core::hresult result = Core::ERROR_NONE; @@ -1022,8 +1025,13 @@ namespace Plugin { Core::hresult Controller::Clone(const string& callsign, const string& newcallsign, string& response) { Core::hresult result = Clone(callsign, newcallsign); + if (result == Core::ERROR_NONE) { - response = newcallsign; + PluginHost::IShell* shell = reinterpret_cast(_pluginServer->Services().QueryInterfaceByCallsign(PluginHost::IShell::ID, newcallsign)); + + if (shell != nullptr) { + response = newcallsign; + } } return result; } @@ -1196,8 +1204,7 @@ namespace Plugin { ASSERT(_pluginServer != nullptr); - _pluginServer->Dispatcher().GetMetaData(meta); - _pluginServer->Services().GetMetaData(meta); + _pluginServer->Metadata(meta); if (meta.Length() > 0) { std::list links; @@ -1388,9 +1395,9 @@ namespace Plugin { { _adminLock.Lock(); - std::list::const_iterator index = _observers.begin(); + LifeTimeNotifiers::const_iterator index = _lifeTimeObservers.begin(); - while(index != _observers.end()) { + while(index != _lifeTimeObservers.end()) { (*index)->StateChange(callsign, state, reason); index++; } diff --git a/Source/WPEFramework/Controller.h b/Source/WPEFramework/Controller.h index 1e6a4827c0..334895e2fc 100644 --- a/Source/WPEFramework/Controller.h +++ b/Source/WPEFramework/Controller.h @@ -39,44 +39,13 @@ namespace Plugin { , public Exchange::Controller::IDiscovery , public Exchange::Controller::ISystemManagement , public Exchange::Controller::IMetadata - , public Exchange::Controller::ILifeTime { - public: - class SubsystemsData : public Core::JSON::Container { - public: - SubsystemsData() - : Core::JSON::Container() - { - Init(); - } - - SubsystemsData(const SubsystemsData& other) - : Core::JSON::Container() - , Subsystem(other.Subsystem) - , Active(other.Active) - { - Init(); - } - - SubsystemsData& operator=(const SubsystemsData& rhs) - { - Subsystem = rhs.Subsystem; - Active = rhs.Active; - return (*this); - } - - private: - void Init() - { - Add(_T("subsystem"), &Subsystem); - Add(_T("active"), &Active); - } - - public: - Core::JSON::EnumType Subsystem; - Core::JSON::Boolean Active; - }; - + , public Exchange::Controller::ILifeTime + , public Exchange::Controller::IShells { private: + using Resumes = std::vector; + using ExternalSubSystems = std::vector; + using LifeTimeNotifiers = std::vector; + class Sink : public PluginHost::IPlugin::INotification , public PluginHost::ISubSystem::INotification { @@ -149,6 +118,40 @@ namespace Plugin { // PUT -> URL //Deactivate/ // DELETE -> URL //Plugin/ public: + class SubsystemsData : public Core::JSON::Container { + public: + SubsystemsData() + : Core::JSON::Container() + { + Init(); + } + + SubsystemsData(const SubsystemsData& other) + : Core::JSON::Container() + , Subsystem(other.Subsystem) + , Active(other.Active) + { + Init(); + } + + SubsystemsData& operator=(const SubsystemsData& rhs) + { + Subsystem = rhs.Subsystem; + Active = rhs.Active; + return (*this); + } + + private: + void Init() + { + Add(_T("subsystem"), &Subsystem); + Add(_T("active"), &Active); + } + + public: + Core::JSON::EnumType Subsystem; + Core::JSON::Boolean Active; + }; class Config : public Core::JSON::Container { private: Config(const Config&) = delete; @@ -216,7 +219,7 @@ namespace Plugin { , _resumes() , _lastReported() , _externalSubsystems() - , _observers() + , _lifeTimeObservers() { } POP_WARNING() @@ -354,6 +357,10 @@ namespace Plugin { Core::hresult Subsystems(IMetadata::Data::ISubsystemsIterator*& subsystems) const override; Core::hresult Version(IMetadata::Data::Version& version) const override; + // Pushing notifications to interested sinks + Core::hresult Register(Exchange::Controller::IShells::INotification* sink) override; + Core::hresult Unregister(Exchange::Controller::IShells::INotification* sink) override; + // IUnknown methods // ------------------------------------------------------------------------------------------------------- BEGIN_INTERFACE_MAP(Controller) @@ -366,12 +373,12 @@ namespace Plugin { INTERFACE_ENTRY(Exchange::Controller::ISystemManagement) INTERFACE_ENTRY(Exchange::Controller::IMetadata) INTERFACE_ENTRY(Exchange::Controller::ILifeTime) + INTERFACE_ENTRY(Exchange::Controller::IShells) END_INTERFACE_MAP private: // ILocalDispatcher methods // ------------------------------------------------------------------------------------------------------- - uint32_t Validate(const string& token, const string& method, const string& paramaters) const override; uint32_t Invoke(const uint32_t channelId, const uint32_t id, const string& token, const string& method, const string& parameters, string& response /* @out */) override; inline Core::ProxyType FromIdentifier(const string& callsign) const @@ -405,11 +412,12 @@ namespace Plugin { PluginHost::IShell* _service; Probe* _probe; Core::Sink _systemInfoReport; - std::list _resumes; + Resumes _resumes; uint32_t _lastReported; - std::vector _externalSubsystems; - std::list _observers; + ExternalSubSystems _externalSubsystems; + LifeTimeNotifiers _lifeTimeObservers; }; + POP_WARNING() } } diff --git a/Source/WPEFramework/ExampleConfigWindows.json b/Source/WPEFramework/ExampleConfigWindows.json index 87f6ea47a6..fcd271a553 100644 --- a/Source/WPEFramework/ExampleConfigWindows.json +++ b/Source/WPEFramework/ExampleConfigWindows.json @@ -128,7 +128,7 @@ "classname": "BridgeLink", "autostart": false, "configuration": { - "source": "192.168.1.102:62000", + "source": "192.168.11.24:62000", "retries": 255, "interval": 10 } diff --git a/Source/WPEFramework/PluginHost.cpp b/Source/WPEFramework/PluginHost.cpp index 407f4b4aa0..e696aa3d60 100644 --- a/Source/WPEFramework/PluginHost.cpp +++ b/Source/WPEFramework/PluginHost.cpp @@ -742,8 +742,7 @@ POP_WARNING() } case 'C': { Core::JSON::ArrayType metaData; - _dispatcher->Dispatcher().GetMetaData(metaData); - _dispatcher->Services().GetMetaData(metaData); + _dispatcher->Metadata(metaData); Core::JSON::ArrayType::Iterator index(metaData.Elements()); printf("\nChannels:\n"); diff --git a/Source/WPEFramework/PluginServer.cpp b/Source/WPEFramework/PluginServer.cpp index 1ca42e842e..0dea56d3fe 100644 --- a/Source/WPEFramework/PluginServer.cpp +++ b/Source/WPEFramework/PluginServer.cpp @@ -51,8 +51,11 @@ ENUM_CONVERSION_BEGIN(PluginHost::InputHandler::type) ENUM_CONVERSION_END(PluginHost::InputHandler::type) -namespace PluginHost -{ +namespace PluginHost { + // + // STATIC declarations + // ----------------------------------------------------------------------------------------------------------------------------------- + /* static */ Core::ProxyType Server::Channel::_missingCallsign(Core::ProxyType::Create()); /* static */ Core::ProxyType Server::Channel::_incorrectVersion(Core::ProxyType::Create()); /* static */ Core::ProxyType Server::Channel::WebRequestJob::_missingResponse(Core::ProxyType::Create()); @@ -177,6 +180,9 @@ namespace PluginHost return (result); } + // + // class Server::WorkerPoolImplementation + // ----------------------------------------------------------------------------------------------------------------------------------- void Server::WorkerPoolImplementation::Dispatcher::Dispatch(Core::IDispatch* job) /* override */ { #if defined(__CORE_EXCEPTION_CATCHING__) || defined(__CORE_WARNING_REPORTING__) string callsign(_T("Callsign Unknown")); @@ -299,23 +305,23 @@ namespace PluginHost return (result); } - /* virtual */ void* Server::Service::QueryInterfaceByCallsign(const uint32_t id, const string& name) + void* Server::Service::QueryInterfaceByCallsign(const uint32_t id, const string& name) /* override */ { return (_administrator.QueryInterfaceByCallsign(id, name)); } - /* virtual */ void Server::Service::Register(IPlugin::INotification * sink) + void Server::Service::Register(IPlugin::INotification * sink) /* override */ { _administrator.Register(sink); } - /* virtual */ void Server::Service::Unregister(IPlugin::INotification * sink) + void Server::Service::Unregister(IPlugin::INotification * sink) /* override */ { _administrator.Unregister(sink); } // Methods to stop/start/update the service. - /* virtual */ Core::hresult Server::Service::Activate(const PluginHost::IShell::reason why) + Core::hresult Server::Service::Activate(const PluginHost::IShell::reason why) /* override */ { Core::hresult result = Core::ERROR_NONE; @@ -460,7 +466,7 @@ namespace PluginHost return (result); } - uint32_t Server::Service::Resume(const reason why) { + uint32_t Server::Service::Resume(const reason why) /* override */ { uint32_t result = Core::ERROR_NONE; Lock(); @@ -496,7 +502,7 @@ namespace PluginHost return (result); } - /* virtual */ Core::hresult Server::Service::Deactivate(const reason why) + Core::hresult Server::Service::Deactivate(const reason why) /* override */ { Core::hresult result = Core::ERROR_NONE; @@ -638,7 +644,7 @@ namespace PluginHost return (result); } - /* virtual */ Core::hresult Server::Service::Unavailable(const reason why) { + Core::hresult Server::Service::Unavailable(const reason why) /* override */ { Core::hresult result = Core::ERROR_NONE; Lock(); @@ -840,17 +846,17 @@ namespace PluginHost } #endif - /* virtual */ uint32_t Server::Service::Submit(const uint32_t id, const Core::ProxyType& response) + uint32_t Server::Service::Submit(const uint32_t id, const Core::ProxyType& response) /* override */ { return (_administrator.Submit(id, response)); } - /* virtual */ ISubSystem* Server::Service::SubSystems() + ISubSystem* Server::Service::SubSystems() /* override */ { return (_administrator.SubSystemsInterface(this)); } - /* virtual */ void Server::Service::Notify(const string& message) + void Server::Service::Notify(const string& message) /* override */ { const ForwardMessage forwarder(PluginHost::Service::Callsign(), message); @@ -862,6 +868,73 @@ namespace PluginHost _administrator.Notification(forwarder); } + // + // class Server::ServiceMap + // ----------------------------------------------------------------------------------------------------------------------------------- + void Server::ServiceMap::Open(std::vector& externallyControlled) { + // Load the metadata for the subsystem information.. + for (auto service : _services) + { + service.second->LoadMetadata(); + for (const PluginHost::ISubSystem::subsystem& entry : service.second->SubSystemControl()) { + Core::EnumerateType name(entry); + if (std::find(externallyControlled.begin(), externallyControlled.end(), entry) != externallyControlled.end()) { + SYSLOG(Logging::Startup, (Core::Format(_T("Subsystem [%s] controlled by multiple plugins. Second: [%s]. Configuration error!!!"), name.Data(), service.second->Callsign().c_str()))); + } + else if (entry >= PluginHost::ISubSystem::END_LIST) { + SYSLOG(Logging::Startup, (Core::Format(_T("Subsystem [%s] can not be used as a control value in [%s]!!!"), name.Data(), service.second->Callsign().c_str()))); + } + else { + SYSLOG(Logging::Startup, (Core::Format(_T("Subsytem [%s] controlled by plugin [%s]"), name.Data(), service.second->Callsign().c_str()))); + externallyControlled.emplace_back(entry); + } + } + } + } + + void Server::ServiceMap::Close() + { + _adminLock.Lock(); + + // First, move them all to deactivated except Controller + Core::ProxyType controller(_server.Controller()); + + TRACE_L1("Destructing %d plugins", static_cast(_services.size())); + + while (_services.empty() == false) { + + auto index = _services.begin(); + + Core::ProxyType service(index->second); + + ASSERT(service.IsValid()); + + if (index->first.c_str() != controller->Callsign()) { + _adminLock.Unlock(); + + index->second->Deactivate(PluginHost::IShell::SHUTDOWN); + + _adminLock.Lock(); + } + + _services.erase(index); + } + + _adminLock.Unlock(); + + // Now deactivate controller plugin, once other plugins are deactivated + controller->Deactivate(PluginHost::IShell::SHUTDOWN); + + TRACE_L1("Pending notifiers are %zu", _notifiers.size()); + for (VARIABLE_IS_NOT_USED auto notifier : _notifiers) { + TRACE_L1(" --> %s", Core::ClassNameOnly(typeid(*notifier).name()).Text().c_str()); + } + + _processAdministrator.Close(Core::infinite); + + _processAdministrator.Destroy(); + } + uint32_t Server::ServiceMap::FromLocator(const string& identifier, Core::ProxyType& service, bool& serviceCall) { uint32_t result = Core::ERROR_BAD_REQUEST; @@ -916,6 +989,40 @@ namespace PluginHost return (result); } + void Server::ServiceMap::Startup() { + + // sort plugins based on StartupOrder from configuration + std::vector> configured_services; + + for (auto service : _services) { + configured_services.emplace_back(service.second); + } + + std::sort(configured_services.begin(), configured_services.end(), + [](const Core::ProxyType& lhs, const Core::ProxyType& rhs) + { + return lhs->StartupOrder() < rhs->StartupOrder(); + }); + + for (auto service : configured_services) + { + if (service->State() != PluginHost::Service::state::UNAVAILABLE) { + if (service->Startup() == PluginHost::IShell::startup::ACTIVATED) { + SYSLOG(Logging::Startup, (_T("Activating plugin [%s]:[%s]"), + service->ClassName().c_str(), service->Callsign().c_str())); + service->Activate(PluginHost::IShell::STARTUP); + } + else { + SYSLOG(Logging::Startup, (_T("Activation of plugin [%s]:[%s] delayed, autostart is false"), + service->ClassName().c_str(), service->Callsign().c_str())); + } + } + } + } + + // + // class Server::Channel + // ----------------------------------------------------------------------------------------------------------------------------------- Server::Channel::Channel(const SOCKET& connector, const Core::NodeId& remoteId, Core::SocketServerType* parent) : PluginHost::Channel(connector, remoteId) , _parent(static_cast(*parent).Parent()) @@ -944,11 +1051,13 @@ namespace PluginHost Close(0); } -PUSH_WARNING(DISABLE_WARNING_THIS_IN_MEMBER_INITIALIZER_LIST) - + // + // class Server + // ----------------------------------------------------------------------------------------------------------------------------------- + PUSH_WARNING(DISABLE_WARNING_THIS_IN_MEMBER_INITIALIZER_LIST) Server::Server(Config& configuration, const bool background) : _dispatcher(configuration.StackSize()) - , _connections(*this, configuration.Binder(), configuration.IdleTime()) + , _connections(*this, configuration.Binder()) , _config(configuration) , _services(*this) , _controller() @@ -987,11 +1096,11 @@ PUSH_WARNING(DISABLE_WARNING_THIS_IN_MEMBER_INITIALIZER_LIST) metaDataConfig.Configuration = entry.Configuration; } else { // Let's raise an error, this is a bit strange, again, the controller is initialized !!! -#ifndef __WINDOWS__ + #ifndef __WINDOWS__ if (background == true) { syslog(LOG_NOTICE, "Configuration error. Controller is defined mutiple times [%s].\n", entry.Callsign.Value().c_str()); } else -#endif + #endif { fprintf(stdout, "Configuration error. Controller is defined mutiple times [%s].\n", entry.Callsign.Value().c_str()); } @@ -1022,14 +1131,13 @@ PUSH_WARNING(DISABLE_WARNING_THIS_IN_MEMBER_INITIALIZER_LIST) // Add the controller as a service to the services. _controller = _services.Insert(metaDataConfig, Service::mode::CONFIGURED); -#ifdef PROCESSCONTAINERS_ENABLED + #ifdef PROCESSCONTAINERS_ENABLED // turn on ProcessContainer logging ProcessContainers::IContainerAdministrator& admin = ProcessContainers::IContainerAdministrator::Instance(); admin.Logging(_config.VolatilePath(), configuration.ProcessContainersLogging()); -#endif + #endif } - -POP_WARNING() + POP_WARNING() Server::~Server() { @@ -1065,26 +1173,7 @@ POP_WARNING() _config.Security(securityProvider); std::vector externallyControlled; - ServiceMap::Iterator iterator(_services.Services()); - - // Load the metadata for the subsystem information.. - while (iterator.Next() == true) - { - iterator->LoadMetadata(); - for (const PluginHost::ISubSystem::subsystem& entry : iterator->SubSystemControl()) { - Core::EnumerateType name(entry); - if (std::find(externallyControlled.begin(), externallyControlled.end(), entry) != externallyControlled.end()) { - SYSLOG(Logging::Startup, (Core::Format(_T("Subsystem [%s] controlled by multiple plugins. Second: [%s]. Configuration error!!!"), name.Data(), iterator->Callsign().c_str()))); - } - else if (entry >= PluginHost::ISubSystem::END_LIST) { - SYSLOG(Logging::Startup, (Core::Format(_T("Subsystem [%s] can not be used as a control value in [%s]!!!"), name.Data(), iterator->Callsign().c_str()))); - } - else { - SYSLOG(Logging::Startup, (Core::Format(_T("Subsytem [%s] controlled by plugin [%s]"), name.Data(), iterator->Callsign().c_str()))); - externallyControlled.emplace_back(entry); - } - } - } + _services.Open(externallyControlled); _controller->Activate(PluginHost::IShell::STARTUP); @@ -1105,36 +1194,9 @@ POP_WARNING() securityProvider->Release(); _dispatcher.Run(); - Dispatcher().Open(MAX_EXTERNAL_WAITS); - - // Right we have the shells for all possible services registered, time to activate what is needed :-) - iterator.Reset(0); - - // sort plugins based on StartupOrder from configuration - std::vector> configured_services; - while (iterator.Next()) - configured_services.push_back(*iterator); - - std::sort(configured_services.begin(), configured_services.end(), - [](const Core::ProxyType& lhs, const Core::ProxyType&rhs) - { - return lhs->StartupOrder() < rhs->StartupOrder(); - }); + _connections.Open(MAX_EXTERNAL_WAITS, _config.IdleTime()); - for (auto service : configured_services) - { - if (service->State() != PluginHost::Service::state::UNAVAILABLE) { - if (service->Startup() == PluginHost::IShell::startup::ACTIVATED) { - SYSLOG(Logging::Startup, (_T("Activating plugin [%s]:[%s]"), - service->ClassName().c_str(), service->Callsign().c_str())); - service->Activate(PluginHost::IShell::STARTUP); - } - else { - SYSLOG(Logging::Startup, (_T("Activation of plugin [%s]:[%s] delayed, autostart is false"), - service->ClassName().c_str(), service->Callsign().c_str())); - } - } - } + _services.Startup(); } void Server::Close() @@ -1143,7 +1205,7 @@ POP_WARNING() destructor->AddRef(); _connections.Close(100); destructor->Stopped(); - _services.Destroy(); + _services.Close(); _dispatcher.Stop(); destructor->Release(); _inputHandler.Deinitialize(); diff --git a/Source/WPEFramework/PluginServer.h b/Source/WPEFramework/PluginServer.h index d3f9188e92..dfeb210946 100644 --- a/Source/WPEFramework/PluginServer.h +++ b/Source/WPEFramework/PluginServer.h @@ -369,561 +369,6 @@ namespace PluginHost { std::string _text; }; - class CompositPlugin : public PluginHost::ICompositPlugin::INotification { - public: - static constexpr TCHAR RemotePluginDelimiter = '/'; - - private: - class ShellProxy : public PluginHost::IShell { - public: - ShellProxy() = delete; - ShellProxy(ShellProxy&&) = delete; - ShellProxy(const ShellProxy&) = delete; - ShellProxy& operator= (const ShellProxy&) = delete; - - ShellProxy(PluginHost::IShell* real, const string callsign, const string& hostPlugin) - : _adminLock() - , _shell(real) - , _callsign(hostPlugin + RemotePluginDelimiter + callsign) { - _shell->AddRef(); - } - ~ShellProxy() override { - _adminLock.Lock(); - if (_shell != nullptr) { - _shell->Release(); - _shell = nullptr; - } - _adminLock.Unlock(); - } - - public: - bool IsActive() const { - return (_shell != nullptr); - } - void EnableWebServer(const string& URLPath, const string& fileSystemPath) override { - PluginHost::IShell* source = Source(); - if (source != nullptr) { - source->EnableWebServer(URLPath, fileSystemPath); - source->Release(); - } - } - void DisableWebServer() override { - PluginHost::IShell* source = Source(); - if (source != nullptr) { - source->DisableWebServer(); - source->Release(); - } - } - //! Model: Returns a Human Readable name for the platform it is running on. - string Model() const override { - string result; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->Model(); - source->Release(); - } - return (result); - } - //! Background: If enabled, the PluginHost is running in daemon mode - bool Background() const override { - bool result = true; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->Background(); - source->Release(); - } - return (result); - } - //! Accessor: Identifier that can be used for Core:NodeId to connect to the webbridge. - string Accessor() const override { - string result; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->Accessor(); - source->Release(); - } - return (result); - } - //! WebPrefix: First part of the pathname in the HTTP request to select the webbridge components. - string WebPrefix() const override { - string result; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->WebPrefix(); - source->Release(); - } - return (result); - } - //! Locator: The name of the binary (so) that holds the given ClassName code. - string Locator() const override { - string result; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->Locator(); - source->Release(); - } - return (result); - } - //! ClassName: Name of the class to be instantiated for this IShell - string ClassName() const override { - string result; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->ClassName(); - source->Release(); - } - return (result); - } - //! Versions: Returns a JSON Array of versions (JSONRPC interfaces) supported by this plugin. - string Versions() const override { - string result; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->Versions(); - source->Release(); - } - return (result); - } - //! Callsign: Instantiation name of this specific plugin. It is the name given in the config for the classname. - string Callsign() const override { - return (_callsign); - } - //! PersistentPath: // - string PersistentPath() const override { - string result; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->PersistentPath(); - source->Release(); - } - return (result); - } - //! VolatilePath: // - string VolatilePath() const override { - string result; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->VolatilePath(); - source->Release(); - } - return (result); - } - //! DataPath: // - string DataPath() const override { - string result; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->DataPath(); - source->Release(); - } - return (result); - } - //! ProxyStubPath: / - string ProxyStubPath() const override { - string result; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->ProxyStubPath(); - source->Release(); - } - return (result); - } - //! SystemPath: / - string SystemPath() const override { - string result; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->SystemPath(); - source->Release(); - } - return (result); - } - //! SystemPath: /Plugins/ - string PluginPath() const override { - string result; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->PluginPath(); - source->Release(); - } - return (result); - } - //! SystemPath: / - string SystemRootPath() const override { - string result; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->SystemRootPath(); - source->Release(); - } - return (result); - } - //! SystemRootPath: Set / - uint32_t SystemRootPath(const string& systemRootPath) override { - uint32_t result = Core::ERROR_UNAVAILABLE; - PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->SystemRootPath(systemRootPath); - source->Release(); - } - return (result); - } - //! Startup: / - PluginHost::IShell::startup Startup() const override { - PluginHost::IShell::startup result = PluginHost::IShell::startup::UNAVAILABLE; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->Startup(); - source->Release(); - } - return (result); - } - //! Startup: Set/ - uint32_t Startup(const startup value) override { - uint32_t result = Core::ERROR_UNAVAILABLE; - PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->Startup(value); - source->Release(); - } - return (result); - } - //! Substituted Config value - string Substitute(const string& input) const override { - string result; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->Substitute(input); - source->Release(); - } - return (result); - } - bool Resumed() const override { - bool result = true; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->Resumed(); - source->Release(); - } - return (result); - } - uint32_t Resumed(const bool value) override { - uint32_t result = Core::ERROR_UNAVAILABLE; - PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->Resumed(value); - source->Release(); - } - return (result); - } - string HashKey() const override { - string result; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->HashKey(); - source->Release(); - } - return (result); - } - string ConfigLine() const override { - string result; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->SystemRootPath(); - source->Release(); - } - return (result); - } - uint32_t ConfigLine(const string& config) override { - uint32_t result = Core::ERROR_UNAVAILABLE; - PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->ConfigLine(config); - source->Release(); - } - return (result); - } - //! Return whether the given version is supported by this IShell instance. - bool IsSupported(const uint8_t version) const override { - bool result = true; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->IsSupported(version); - source->Release(); - } - return (result); - } - // Get access to the SubSystems and their corrresponding information. Information can be set or get to see what the - // status of the sub systems is. - PluginHost::ISubSystem* SubSystems() override { - PluginHost::ISubSystem* result = nullptr; - PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->SubSystems(); - source->Release(); - } - return (result); - } - // Notify all subscribers of this service with the given string. - // It is expected to be JSON formatted strings as it is assumed that this is for reaching websockets clients living in - // the web world that have build in functionality to parse JSON structs. - void Notify(const string& message) override { - PluginHost::IShell* source = Source(); - if (source != nullptr) { - source->Notify(message); - source->Release(); - } - } - // Allow access to the Shells, configured for the different Plugins found in the configuration. - // Calling the QueryInterfaceByCallsign with an empty callsign will query for interfaces located - // on the controller. - void Register(IPlugin::INotification* sink) override { - PluginHost::IShell* source = Source(); - if (source != nullptr) { - source->Register(sink); - source->Release(); - } - } - void Unregister(IPlugin::INotification* sink) override { - PluginHost::IShell* source = Source(); - if (source != nullptr) { - source->Unregister(sink); - source->Release(); - } - } - state State() const override { - state result = state::DEACTIVATED; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->State(); - source->Release(); - } - return (result); - } - void* /* @interface:id */ QueryInterfaceByCallsign(const uint32_t id, const string& name) override { - void* result = nullptr; - PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->QueryInterfaceByCallsign(id, name); - source->Release(); - } - return (result); - } - // Methods to Activate/Deactivate and Unavailable the aggregated Plugin to this shell. - // NOTE: These are Blocking calls!!!!! - uint32_t Activate(const reason why) override { - uint32_t result = Core::ERROR_UNAVAILABLE; - PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->Activate(why); - source->Release(); - } - return (result); - } - uint32_t Deactivate(const reason why) override { - uint32_t result = Core::ERROR_UNAVAILABLE; - PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->Deactivate(why); - source->Release(); - } - return (result); - } - uint32_t Unavailable(const reason why) override { - uint32_t result = Core::ERROR_UNAVAILABLE; - PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->Unavailable(why); - source->Release(); - } - return (result); - } - uint32_t Hibernate(const uint32_t timeout) override { - uint32_t result = Core::ERROR_UNAVAILABLE; - PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->Hibernate(timeout); - source->Release(); - } - return (result); - } - reason Reason() const override { - reason result = reason::FAILURE; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->Reason(); - source->Release(); - } - return (result); - } - Core::hresult Metadata(string& info /* @out */) const { - Core::hresult result = Core::ERROR_UNAVAILABLE; - const PluginHost::IShell* source = Source(); - if (source != nullptr) { - result = source->Metadata(info); - source->Release(); - } - return (result); - } - - // Method to access, in the main process space, the channel factory to submit JSON objects to be send. - // This method will return a error if it is NOT in the main process. - /* @stubgen:stub */ - uint32_t Submit(const uint32_t Id VARIABLE_IS_NOT_USED, const Core::ProxyType& response VARIABLE_IS_NOT_USED) override { - return (Core::ERROR_NOT_SUPPORTED); - } - - // Method to access, in the main space, a COM factory to instantiate objects out-of-process. - // This method will return a nullptr if it is NOT in the main process. - /* @stubgen:stub */ - ICOMLink* COMLink() override { - return (nullptr); - } - - BEGIN_INTERFACE_MAP(ShellProxy) - INTERFACE_ENTRY(PluginHost::IShell) - END_INTERFACE_MAP - - private: - PluginHost::IShell* Source() { - _adminLock.Lock(); - PluginHost::IShell* result = _shell; - if (result != nullptr) { - result->AddRef(); - } - _adminLock.Unlock(); - return (result); - } - const PluginHost::IShell* Source() const { - _adminLock.Lock(); - const PluginHost::IShell* result = _shell; - if (result != nullptr) { - result->AddRef(); - } - _adminLock.Unlock(); - return (result); - } - - private: - mutable Core::CriticalSection _adminLock; - PluginHost::IShell* _shell; - const string _callsign; - }; - using CompositPlugins = std::unordered_map; - - public: - CompositPlugin(ServiceMap& parent, const string& linkPlugin) - : _parent(parent) - , _adminLock() - , _linkPlugin(linkPlugin) - , _plugins() { - } - ~CompositPlugin() override { - ASSERT(_plugins.empty() == true); - } - - public: - const string& Callsign() const { - return (_linkPlugin); - } - template - void Visit(ACTION&& action) { - _adminLock.Lock(); - for (std::pair& entry : _plugins) { - action(entry.first, entry.second); - } - _adminLock.Unlock(); - } - template - void Visit(ACTION&& action) const { - _adminLock.Lock(); - for (const std::pair& entry : _plugins) { - action(entry.first, entry.second); - } - _adminLock.Unlock(); - } - void* QueryInterfaceByCallsign(const uint32_t id, const string& name) { - void* result = nullptr; - - _adminLock.Lock(); - CompositPlugins::iterator index(_plugins.find(name)); - if (index != _plugins.end()) { - result = index->second->QueryInterfaceByCallsign(id, name); - } - _adminLock.Unlock(); - - return (result); - } - template - INTERFACE* QueryInterfaceByCallsign(const string& name) { - return (reinterpret_cast(QueryInterfaceByCallsign(INTERFACE::ID, name))); - } - uint32_t Activated(const string& callsign, PluginHost::IShell* plugin) override { - ShellProxy* entry = nullptr; - _adminLock.Lock(); - CompositPlugins::iterator index(_plugins.find(callsign)); - if (index == _plugins.end()) { - Core::ProxyType object = Core::ProxyType::Create(plugin, callsign, _linkPlugin); - entry = object.operator->(); - entry->AddRef(); - TRACE(Activity, (_T("Activated composit plugin [%s]"), entry->Callsign().c_str())); - _plugins.emplace(std::piecewise_construct, - std::make_tuple(callsign), - std::make_tuple(entry)); - } - _adminLock.Unlock(); - - if (entry != nullptr) { - _parent.Activated(entry->Callsign(), entry); - } - - return (Core::ERROR_NONE); - } - uint32_t Deactivated(const string& callsign, PluginHost::IShell* plugin VARIABLE_IS_NOT_USED) override { - ShellProxy* entry = nullptr; - - _adminLock.Lock(); - CompositPlugins::iterator index(_plugins.find(callsign)); - if (index != _plugins.end()) { - entry = index->second; - _plugins.erase(index); - } - _adminLock.Unlock(); - - if (entry != nullptr) { - _parent.Deactivated(entry->Callsign(), entry); - TRACE(Activity, (_T("Deactivated composit plugin [%s]"), entry->Callsign().c_str())); - entry->Release(); - } - - return (Core::ERROR_NONE); - } - void Clear() { - std::vector entries; - - _adminLock.Lock(); - for (auto& entry : _plugins) { - entries.push_back(entry.second); - } - _plugins.clear(); - _adminLock.Unlock(); - - for (auto& element : entries) { - _parent.Deactivated(element->Callsign(), element); - element->Release(); - } - } - - BEGIN_INTERFACE_MAP(RemoteLink) - INTERFACE_ENTRY(PluginHost::ICompositPlugin::INotification) - END_INTERFACE_MAP - - private: - ServiceMap& _parent; - mutable Core::CriticalSection _adminLock; - const string _linkPlugin; - CompositPlugins _plugins; - }; class Service : public IShell::ICOMLink, public PluginHost::Service { public: enum mode { @@ -1309,19 +754,6 @@ namespace PluginHost { _extended->Detach(channel); } } - inline void Configuration(const string& config) - { - PluginHost::Service::ConfigLine(config); - } - string Configuration() const - { - - Lock(); - string result(PluginHost::Service::ConfigLine()); - Unlock(); - - return (result); - } bool Update(const Plugin::Config& config) { bool succeeded = false; @@ -1468,103 +900,33 @@ namespace PluginHost { IncrementProcessedRequests(); #endif Core::InterlockedIncrement(_activity); - uint32_t result; - string method(message.Designator.Value()); - - if (message.Id.IsSet() == true) { - response = Core::ProxyType(IFactories::Instance().JSONRPC()); - response->JSONRPC = Core::JSONRPC::Message::DefaultVersion; - response->Id = message.Id.Value(); - } + string output; + uint32_t result = _jsonrpc->Invoke(channelId, message.Id.Value(), token, message.Designator.Value(), message.Parameters.Value(), output); - if ((message.Designator.IsSet() == false) || (method.empty())) { - if (response.IsValid() == false) { - response = Core::ProxyType(IFactories::Instance().JSONRPC()); - response->Id.Null(true); - } + if ( (result != static_cast(~0)) && ( (message.Id.IsSet()) || (result != Core::ERROR_NONE) ) ) { - response->Error.SetError(Core::ERROR_PARSE_FAILURE); - response->Error.Text = _T("Parsing of the method failed"); - } - else if ((result = _jsonrpc->Validate(token, method, message.Parameters.Value())) == Core::ERROR_PRIVILIGED_REQUEST) { - if (response.IsValid() == true) { - response->Error.SetError(Core::ERROR_PRIVILIGED_REQUEST); - response->Error.Text = _T("method invokation not allowed."); + response = IFactories::Instance().JSONRPC(); + + if (message.Id.IsSet()) { + response->Id = message.Id.Value(); } - } - else if (result == Core::ERROR_UNAVAILABLE) { - if (response.IsValid() == true) { - response->Error.SetError(Core::ERROR_PRIVILIGED_REQUEST); - response->Error.Text = _T("method invokation is deferred, Currently not allowed."); - } - } - else if (result != Core::ERROR_NONE) { - if (response.IsValid() == true) { - response->Error.SetError(Core::ERROR_PRIVILIGED_REQUEST); - response->Error.Text = _T("method invokation could not be validated."); - } - } - else { - string output; - result = _jsonrpc->Invoke(channelId, message.Id.Value(), token, method, message.Parameters.Value(), output); - if (result == Core::ERROR_PARSE_FAILURE) { - if (response.IsValid() == false) { - response = Core::ProxyType(IFactories::Instance().JSONRPC()); - response->Id.Null(true); + if (result == Core::ERROR_NONE) { + if (output.empty() == true) { + response->Result.Null(true);; + } + else { + response->Result = output; } - - response->Error.SetError(Core::ERROR_PARSE_FAILURE); - response->Error.Text = _T("Parsing of the parameters failed"); } - else if (response.IsValid() == true) { - switch (result) { - case Core::ERROR_NONE: - if (output.empty() == true) { - response->Result.Null(true); - } - else { - response->Result = output; - } - break; - case Core::ERROR_INVALID_RANGE: - response->Error.SetError(Core::ERROR_INVALID_RANGE); - response->Error.Text = _T("Requested version is not supported."); - break; - case Core::ERROR_INCORRECT_URL: - response->Error.SetError(Core::ERROR_INVALID_DESIGNATOR); - response->Error.Text = _T("Dessignator is invalid."); - break; - case Core::ERROR_BAD_REQUEST: - response->Error.SetError(Core::ERROR_UNKNOWN_KEY); - response->Error.Text = _T("Unknown method."); - break; - case Core::ERROR_FAILED_REGISTERED: - response->Error.SetError(Core::ERROR_UNKNOWN_KEY); - response->Error.Text = _T("Registration already done!!!."); - break; - case Core::ERROR_FAILED_UNREGISTERED: - response->Error.SetError(Core::ERROR_UNKNOWN_KEY); - response->Error.Text = _T("Unregister was already done!!!."); - break; - case Core::ERROR_HIBERNATED: - response->Error.SetError(Core::ERROR_HIBERNATED); - response->Error.Text = _T("The service is in an Hibernated state!!!."); - break; - case Core::ERROR_ILLEGAL_STATE: - response->Error.SetError(Core::ERROR_ILLEGAL_STATE); - response->Error.Text = _T("The service is in an illegal state!!!."); - break; - case static_cast(~0): - response.Release(); - break; - default: - response->Error.Code = result; - response->Error.Text = Core::ErrorToString(result); - break; + else { + response->Error.SetError(result); + if (output.empty() == false) { + response->Error.Text = output; } } } + Core::InterlockedDecrement(_activity); } @@ -2212,16 +1574,16 @@ namespace PluginHost { if (current->second.IsSet() == true) { if (current->second.Configuration.IsSet() == true) { - (*index)->Configuration(current->second.Configuration.Value()); + index->ConfigLine(current->second.Configuration.Value()); } if (current->second.SystemRootPath.IsSet() == true) { - (*index)->SystemRootPath(current->second.SystemRootPath.Value()); + index->SystemRootPath(current->second.SystemRootPath.Value()); } if (current->second.Startup.IsSet() == true) { - (*index)->Startup(current->second.Startup.Value()); + index->Startup(current->second.Startup.Value()); } if (current->second.Resumed.IsSet() == true) { - (*index)->Resumed(current->second.Resumed.Value()); + index->Resumed(current->second.Resumed.Value()); } } } @@ -2258,16 +1620,16 @@ namespace PluginHost { // ServiceMap should *NOT* change runtime... ASSERT(current != _callsigns.end()); - string config((*index)->Configuration()); + string config(index->ConfigLine()); if (config.empty() == true) { current->second.Configuration = _T("{}"); } else { current->second.Configuration = config; } - current->second.SystemRootPath = (index)->SystemRootPath(); - current->second.Startup = (index)->Startup(); - current->second.Resumed = (index)->Resumed(); + current->second.SystemRootPath = index->SystemRootPath(); + current->second.Startup = index->Startup(); + current->second.Resumed = index->Resumed(); } // Persist the currently set information @@ -2297,11 +1659,230 @@ namespace PluginHost { public: using ServiceContainer = std::map>; using Notifiers = std::vector; - using Iterator = Core::IteratorMapType, const string&>; using RemoteInstantiators = std::unordered_map; - using CompositPlugins = std::list< Core::Sink >; + using ShellNotifiers = std::vector< Exchange::Controller::IShells::INotification*>; + + class Iterator { + public: + using Shells = std::unordered_map >; + + Iterator() + : _container() + , _index() + , _position(0) { + } + Iterator(const ServiceContainer& services, Shells&& composits) + : _container(composits) + , _index() + , _position(0) { + for (auto entry : services) { + _container.emplace(std::piecewise_construct, + std::make_tuple(entry.first), + std::make_tuple(Core::ProxyType(entry.second))); + } + } + Iterator(Iterator&& move) + : _container(std::move(move._container)) + , _index() + , _position(0) { + } + Iterator(const Iterator& copy) + : _container(copy._container) + , _index() + , _position(0) { + } + ~Iterator() = default; + + Iterator& operator= (Iterator&& move) { + _container = std::move(move._container); + _index = std::move(move._index); + _position = move._position; + + return (*this); + } + Iterator& operator= (const Iterator& copy) { + _container = copy._container; + _position = copy._position; + if (_position > 0) { + _index = _container.begin(); + uint32_t steps = _position - 1; + while ((steps != 0) && (_index != _container.end())) { + _index++; + steps--; + } + } + return (*this); + } + + public: + bool IsValid() const { + return ((_position > 0) && (_index != _container.end())); + } + void Reset() { + _position = 0; + } + bool Next() { + if (_position == 0) { + _position = 1; + _index = _container.begin(); + } + else if (_index != _container.end()) { + _position++; + _index++; + } + return (_index != _container.end()); + } + const Core::ProxyType& Current() { + ASSERT(IsValid()); + return (_index->second); + } + uint32_t Count() const { + return (static_cast(_container.size())); + } + const Core::ProxyType& operator->() + { + ASSERT(IsValid()); + + return (_index->second); + } + + Core::ProxyType operator->() const + { + ASSERT(IsValid()); + + return (Core::ProxyType(_index->second)); + } + + private: + Shells _container; + Shells::iterator _index; + uint32_t _position; + }; private: + class CompositPlugin : public PluginHost::ICompositPlugin::ICallback { + private: + using CompositPlugins = std::unordered_map; + + public: + CompositPlugin(ServiceMap& parent, const string& linkPlugin) + : _parent(parent) + , _adminLock() + , _linkPlugin(linkPlugin) + , _plugins() { + } + ~CompositPlugin() override { + ASSERT(_plugins.empty() == true); + } + + public: + bool IsEmpty() const { + return (_plugins.empty()); + } + const string& Callsign() const { + return (_linkPlugin); + } + template + void Visit(ACTION&& action) { + _adminLock.Lock(); + for (std::pair& entry : _plugins) { + action(_linkPlugin + PluginHost::ICompositPlugin::Delimiter + entry.first, entry.second); + } + _adminLock.Unlock(); + } + template + void Visit(ACTION&& action) const { + _adminLock.Lock(); + for (const std::pair& entry : _plugins) { + action(_linkPlugin + PluginHost::ICompositPlugin::Delimiter + entry.first, entry.second); + } + _adminLock.Unlock(); + } + Core::ProxyType Source(const string& name) { + Core::ProxyType result; + + _adminLock.Lock(); + CompositPlugins::iterator index(_plugins.find(name)); + if (index != _plugins.end()) { + result = Core::ProxyType(static_cast(*(index->second)), *(index->second)); + } + _adminLock.Unlock(); + + return (result); + } + void Created(const string& callsign, IShell* plugin) override { + _adminLock.Lock(); + + CompositPlugins::iterator index(_plugins.find(callsign)); + + ASSERT(index == _plugins.end()); + + bool report = (index == _plugins.end()); + + if (report == true) { + _plugins.emplace(std::piecewise_construct, + std::make_tuple(callsign), + std::make_tuple(plugin)); + TRACE(Activity, (_T("LinkPlugin [%s], added composit plugin [%s]"), _linkPlugin.c_str(), callsign.c_str())); + } + _adminLock.Unlock(); + + if (report == true) { + _parent.Created(_linkPlugin + PluginHost::ICompositPlugin::Delimiter + callsign, plugin); + } + } + void Destroy(const string& callsign, IShell* plugin) override { + _adminLock.Lock(); + + CompositPlugins::iterator index(_plugins.find(callsign)); + + ASSERT(index != _plugins.end()); + + bool report = (index != _plugins.end()); + + if (report == true) { + _plugins.erase(index); + TRACE(Activity, (_T("LinkPlugin [%s], removed composit plugin [%s]"), _linkPlugin.c_str(), callsign.c_str())); + } + _adminLock.Unlock(); + + if (report == true) { + _parent.Destroy(_linkPlugin + PluginHost::ICompositPlugin::Delimiter + callsign, plugin); + } + } + void Activated(const string& callsign, PluginHost::IShell* plugin) override { + ASSERT(_plugins.find(callsign) != _plugins.end()); + ASSERT(plugin != nullptr); + _parent.Activated(_linkPlugin + PluginHost::ICompositPlugin::Delimiter + callsign, plugin); + } + void Deactivated(const string& callsign, PluginHost::IShell* plugin) override { + ASSERT(_plugins.find(callsign) != _plugins.end()); + ASSERT(plugin != nullptr); + _parent.Deactivated(_linkPlugin + PluginHost::ICompositPlugin::Delimiter + callsign, plugin); + } + void Unavailable(const string& callsign, PluginHost::IShell* plugin) override { + ASSERT(_plugins.find(callsign) != _plugins.end()); + ASSERT(plugin != nullptr); + _parent.Unavailable(_linkPlugin + PluginHost::ICompositPlugin::Delimiter + callsign, plugin); + } + void Copy(Iterator::Shells& list) { + for (const std::pair& entry : _plugins) { + list.emplace(std::piecewise_construct, + std::forward_as_tuple(_linkPlugin + PluginHost::ICompositPlugin::Delimiter + entry.first), + std::forward_as_tuple(*static_cast(entry.second), *static_cast(entry.second))); + } + } + + BEGIN_INTERFACE_MAP(RemoteLink) + INTERFACE_ENTRY(PluginHost::ICompositPlugin::ICallback) + END_INTERFACE_MAP + + private: + ServiceMap& _parent; + mutable Core::CriticalSection _adminLock; + const string _linkPlugin; + CompositPlugins _plugins; + }; class CommunicatorServer : public RPC::Communicator { private: using Observers = std::vector; @@ -2942,6 +2523,8 @@ POP_WARNING() string _observerPath; }; + using CompositPlugins = std::list< Core::Sink >; + public: ServiceMap() = delete; ServiceMap(const ServiceMap&) = delete; @@ -2998,7 +2581,7 @@ POP_WARNING() _authenticationHandler = reinterpret_cast(QueryInterfaceByCallsign(IAuthenticate::ID, _subSystems.SecurityCallsign())); } else { // Remove the security from all the channels. - _server.Dispatcher().SecurityRevoke(Configuration().Security()); + _server.SecurityRevoke(Configuration().Security()); } } @@ -3021,7 +2604,13 @@ POP_WARNING() } inline uint32_t Submit(const uint32_t id, const Core::ProxyType& response) { - return (_server.Dispatcher().Submit(id, response)); + Core::ProxyType entry(_server.Connection(id)); + + if (entry.IsValid() == true) { + entry->Submit(response); + return (Core::ERROR_NONE); + } + return (Core::ERROR_UNAVAILABLE); } inline SystemInfo& SubSystemInfo() { @@ -3052,44 +2641,44 @@ POP_WARNING() _notificationLock.Unlock(); } - void Activated(const string& callsign, PluginHost::IShell* entry) + void Deinitialized(const string& callsign, PluginHost::IShell* entry) { _notificationLock.Lock(); Notifiers::iterator index(_notifiers.begin()); while (index != _notifiers.end()) { - (*index)->Activated(callsign, entry); + PluginHost::IPlugin::ILifeTime* lifetime = (*index)->QueryInterface(); + if (lifetime != nullptr) { + lifetime->Deinitialized(callsign, entry); + lifetime->Release(); + } index++; } _notificationLock.Unlock(); } - void Deactivated(const string& callsign, PluginHost::IShell* entry) + void Activated(const string& callsign, PluginHost::IShell* entry) { _notificationLock.Lock(); Notifiers::iterator index(_notifiers.begin()); while (index != _notifiers.end()) { - (*index)->Deactivated(callsign, entry); + (*index)->Activated(callsign, entry); index++; } _notificationLock.Unlock(); } - void Deinitialized(const string& callsign, PluginHost::IShell* entry) + void Deactivated(const string& callsign, PluginHost::IShell* entry) { _notificationLock.Lock(); Notifiers::iterator index(_notifiers.begin()); while (index != _notifiers.end()) { - PluginHost::IPlugin::ILifeTime* lifetime = (*index)->QueryInterface(); - if (lifetime != nullptr) { - lifetime->Deinitialized(callsign, entry); - lifetime->Release(); - } + (*index)->Deactivated(callsign, entry); index++; } @@ -3108,6 +2697,21 @@ POP_WARNING() _notificationLock.Unlock(); } + void Created(const string& callsign, PluginHost::IShell* entry) { + _notificationLock.Lock(); + for (auto observer : _shellObservers) { + observer->Created(callsign, entry); + } + _notificationLock.Unlock(); + } + void Destroy(const string& callsign, PluginHost::IShell* entry) { + _notificationLock.Lock(); + for (auto observer : _shellObservers) { + observer->Destroy(callsign, entry); + } + _notificationLock.Unlock(); + + } void Register(PluginHost::IPlugin::INotification* sink) { _notificationLock.Lock(); @@ -3196,6 +2800,42 @@ POP_WARNING() { _processAdministrator.Unregister(sink); } + void Register(Exchange::Controller::IShells::INotification* sink) { + _notificationLock.Lock(); + + // Make sure a sink is not registered multiple times. + ASSERT(std::find(_shellObservers.begin(), _shellObservers.end(), sink) == _shellObservers.end()); + + _shellObservers.push_back(sink); + sink->AddRef(); + + for (auto entry : _services) { + sink->Created(entry.first, entry.second.operator->()); + } + for (Core::Sink& entry : _compositPlugins) { + entry.Visit([&](const string& callsign, IShell* proxy) { + sink->Created(callsign, proxy); + }); + } + + _notificationLock.Unlock(); + } + void Unregister(Exchange::Controller::IShells::INotification* sink) { + _notificationLock.Lock(); + + ShellNotifiers::iterator index(std::find(_shellObservers.begin(), _shellObservers.end(), sink)); + + // Make sure you do not unregister something you did not register !!! + ASSERT(index != _shellObservers.end()); + + if (index != _shellObservers.end()) { + (*index)->Release(); + _shellObservers.erase(index); + } + + _notificationLock.Unlock(); + } + RPC::IRemoteConnection* RemoteConnection(const uint32_t connectionId) { return (connectionId != 0 ? _processAdministrator.Connection(connectionId) : nullptr); @@ -3242,7 +2882,7 @@ POP_WARNING() if ((original.IsValid() == true) && (_services.find(newCallsign) == _services.end())) { // Copy original configuration Plugin::Config newConfiguration; - newConfiguration.FromString(original->Configuration()); + newConfiguration.FromString(original->ConfigLine()); newConfiguration.Callsign = newCallsign; Core::ProxyType clone = Core::ProxyType::Create(Configuration(), newConfiguration, *this, Service::mode::CLONED, _engine); @@ -3281,7 +2921,11 @@ POP_WARNING() } inline Iterator Services() { - return (Iterator(_services)); + Iterator::Shells composits; + for (Core::Sink& entry : _compositPlugins) { + entry.Copy(composits); + } + return (Iterator(_services, std::move(composits))); } inline void Notification(const ForwardMessage& message) { @@ -3351,7 +2995,7 @@ POP_WARNING() uint32_t result = Core::ERROR_UNAVAILABLE; size_t pos; - if ((pos = callSign.find_first_of(CompositPlugin::RemotePluginDelimiter)) != string::npos) { + if ((pos = callSign.find_first_of(PluginHost::ICompositPlugin::Delimiter)) != string::npos) { // This is a Composit plugin identifier.. string linkingPin = callSign.substr(0, pos); _adminLock.Lock(); @@ -3359,14 +3003,14 @@ POP_WARNING() while ((index != _compositPlugins.end()) && (index->Callsign() != linkingPin)) { index++; } - if (index != _compositPlugins.end()) { - IShell* found = index->QueryInterfaceByCallsign(callSign.substr(pos + 1)); - if (found != nullptr) { - service = Core::ProxyType(static_cast(*found), *found); - } + if (index != _compositPlugins.end()) { + service = index->Source(callSign.substr(pos + 1)); } + _adminLock.Unlock(); + + result = (service.IsValid() == false ? Core::ERROR_UNKNOWN_KEY : Core::ERROR_NONE); } else { _adminLock.Lock(); @@ -3403,11 +3047,6 @@ POP_WARNING() return (result); } - - uint32_t FromLocator(const string& identifier, Core::ProxyType& service, bool& serviceCall); - - void Destroy(); - inline const PluginHost::Config& Configuration() const { return _server.Configuration(); @@ -3416,7 +3055,7 @@ POP_WARNING() _adminLock.Lock(); // Seems this is a plugin that can be a composition of more plugins.. _compositPlugins.emplace_back(*this, callsign); - composit->Register(&_compositPlugins.back()); + composit->Callback(&_compositPlugins.back()); _adminLock.Unlock(); } void RemoveComposit(const string& callsign, ICompositPlugin* composit) { @@ -3428,13 +3067,28 @@ POP_WARNING() } if (index != _compositPlugins.end()) { - index->Clear(); - composit->Unregister(&(*index)); + composit->Callback(nullptr); + ASSERT(index->IsEmpty() == true); _compositPlugins.erase(index); } _adminLock.Unlock(); } + void Evaluate() + { + _adminLock.Lock(); + + ServiceContainer::iterator index(_services.begin()); + + RecursiveNotification(index); + } + + uint32_t FromLocator(const string& identifier, Core::ProxyType& service, bool& serviceCall); + + void Open(std::vector& externallyControlled); + void Startup(); + void Close(); + void Destroy(); private: void Dangling(const Core::IUnknown* source, const uint32_t interfaceId) { @@ -3558,16 +3212,6 @@ POP_WARNING() return (_server.WorkerPool()); } - public: - void Evaluate() - { - _adminLock.Lock(); - - ServiceContainer::iterator index(_services.begin()); - - RecursiveNotification(index); - } - private: Server& _server; mutable Core::CriticalSection _adminLock; @@ -3581,6 +3225,7 @@ POP_WARNING() IAuthenticate* _authenticationHandler; ConfigObserver _configObserver; CompositPlugins _compositPlugins; + ShellNotifiers _shellObservers; }; // Connection handler is the listening socket and keeps track of all open @@ -3591,7 +3236,9 @@ POP_WARNING() public: class Job : public Core::IDispatch { public: + Job(Job&&) = delete; Job(const Job&) = delete; + Job& operator=(Job&&) = delete; Job& operator=(const Job&) = delete; Job() @@ -3612,7 +3259,11 @@ POP_WARNING() void Close() { TRACE(Activity, (_T("HTTP Request with direct close on [%d]"), _ID)); - _server->Dispatcher().Suspend(_ID); + ASSERT(_server != nullptr); + Core::ProxyType channel(_server->Connection(_ID)); + if (channel.IsValid() == true) { + channel->Close(0); + } } bool HasService() const { @@ -3673,24 +3324,43 @@ POP_WARNING() void Submit(PACKAGE package) { ASSERT(_server != nullptr); - _server->Dispatcher().Submit(_ID, package); + Core::ProxyType channel(_server->Connection(_ID)); + if (channel.IsValid() == true) { + channel->Submit(package); + } } void RequestClose() { ASSERT(_server != nullptr); - _server->Dispatcher().RequestClose(_ID); + Core::ProxyType channel (_server->Connection(_ID)); + if (channel.IsValid() == true) { + channel->RequestClose(); + } } string Callsign() const { ASSERT(_service.IsValid() == true); return _service->Callsign(); } + void Completed() { + ASSERT(_ID != static_cast(~0)); + ASSERT(_server != nullptr); + Core::ProxyType channel(_server->Connection(_ID)); + if (channel.IsValid() == true) { + channel->Pop(); + } + Clear(); + } private: uint32_t _ID; Server* _server; Core::ProxyType _service; }; + + private: class WebRequestJob : public Job { public: + WebRequestJob(WebRequestJob&&) = delete; WebRequestJob(const WebRequestJob&) = delete; + WebRequestJob& operator=(WebRequestJob&&) = delete; WebRequestJob& operator=(const WebRequestJob&) = delete; WebRequestJob() @@ -3837,8 +3507,7 @@ POP_WARNING() // We are done, clear all info _request.Release(); - Job::Clear(); - + Job::Completed(); } string Identifier() const override { string identifier; @@ -3862,7 +3531,9 @@ POP_WARNING() }; class JSONElementJob : public Job { public: + JSONElementJob(JSONElementJob&&) = delete; JSONElementJob(const JSONElementJob&) = delete; + JSONElementJob& operator=(JSONElementJob&&) = delete; JSONElementJob& operator=(const JSONElementJob&) = delete; JSONElementJob() @@ -3940,7 +3611,7 @@ POP_WARNING() _element.Release(); } - Job::Clear(); + Job::Completed(); } string Identifier() const override { if (_jsonrpc == true) { @@ -3961,17 +3632,13 @@ POP_WARNING() }; class TextJob : public Job { public: + TextJob(TextJob&&) = delete; TextJob(const TextJob&) = delete; + TextJob& operator=(TextJob&&) = delete; TextJob& operator=(const TextJob&) = delete; - TextJob() - : Job() - , _text() - { - } - ~TextJob() override - { - } + TextJob() = default; + ~TextJob() override = default; public: void Set(const uint32_t id, Server* server, Core::ProxyType& service, const string& text) @@ -3991,7 +3658,7 @@ POP_WARNING() _text.clear(); } - Job::Clear(); + Job::Completed(); } string Identifier() const override { return(_T("PluginServer::Channel::TextJob::") + Callsign()); @@ -4001,9 +3668,13 @@ POP_WARNING() string _text; }; + using Jobs = std::vector< Core::ProxyType >; + public: Channel() = delete; + Channel(Channel&& copy) = delete; Channel(const Channel& copy) = delete; + Channel& operator=(Channel&&) = delete; Channel& operator=(const Channel&) = delete; Channel(const SOCKET& connector, const Core::NodeId& remoteId, Core::SocketServerType* parent); @@ -4071,6 +3742,25 @@ POP_WARNING() inline void RequestClose() { _requestClose = true; } + inline void Push(Core::ProxyType&& job) { + _adminLock.Lock(); + if (_jobs.empty()) { + _parent.Submit(Core::ProxyType(job)); + } + _jobs.emplace(_jobs.begin(), job); + _adminLock.Unlock(); + } + inline void Pop() { + _adminLock.Lock(); + ASSERT(_jobs.empty() == false); + if (_jobs.empty() == false) { + _jobs.pop_back(); + if (_jobs.empty() == false) { + _parent.Submit(_jobs.back()); + } + } + _adminLock.Unlock(); + } private: bool Allowed(const string& pathParameter, const string& queryParameters) @@ -4244,7 +3934,7 @@ POP_WARNING() if (job.IsValid() == true) { Core::ProxyType baseRequest(request); job->Set(Id(), &_parent, service, baseRequest, _security->Token(), !request->ServiceCall()); - _parent.Submit(Core::ProxyType(job)); + Push(Core::ProxyType(job)); } } break; @@ -4321,7 +4011,7 @@ POP_WARNING() if ((_service.IsValid() == true) && (job.IsValid() == true)) { job->Set(Id(), &_parent, _service, element, _security->Token(), ((State() & Channel::JSONRPC) != 0)); - _parent.Submit(Core::ProxyType(job)); + Push(Core::ProxyType(job)); } } } @@ -4339,7 +4029,7 @@ POP_WARNING() if ((_service.IsValid() == true) && (job.IsValid() == true)) { job->Set(Id(), &_parent, _service, value); - _parent.Submit(Core::ProxyType(job)); + Push(Core::ProxyType(job)); } } @@ -4384,8 +4074,6 @@ POP_WARNING() } State(CLOSED, false); - _parent.Closed(Id()); - _parent.Dispatcher().TriggerCleanup(); } else if (IsUpgrading() == true) { @@ -4433,7 +4121,6 @@ POP_WARNING() SetId(id); } - private: inline string SelectSupportedProtocol(const Web::ProtocolsArray& protocols) { for (const auto& protocol : protocols) { @@ -4460,9 +4147,11 @@ POP_WARNING() } Server& _parent; + Core::CriticalSection _adminLock; PluginHost::ISecurity* _security; Core::ProxyType _service; bool _requestClose; + Jobs _jobs; // Factories for creating jobs that can be placed on the PluginHost Worker pool. static Core::ProxyPoolType _webJobs; @@ -4491,34 +4180,29 @@ POP_WARNING() ChannelMap& operator=(const ChannelMap&) = delete; PUSH_WARNING(DISABLE_WARNING_THIS_IN_MEMBER_INITIALIZER_LIST) - ChannelMap(Server& parent, const Core::NodeId& listeningNode, const uint16_t connectionCheckTimer) + ChannelMap(Server& parent, const Core::NodeId& listeningNode) : Core::SocketServerType(listeningNode) , _parent(parent) - , _connectionCheckTimer(connectionCheckTimer * 1000) + , _connectionCheckTimer(0) , _job(*this) { - if (connectionCheckTimer != 0) { - Core::Time NextTick = Core::Time::Now(); - - NextTick.Add(_connectionCheckTimer); - - Core::ProxyType job(_job.Submit()); - if (job.IsValid() == true) { - _parent.Schedule(NextTick.Ticks(), job); - } - } } POP_WARNING() - ~ChannelMap() - { - Core::ProxyType job(_job.Revoke()); - if (job.IsValid() == true) { - _parent.Revoke(job); - _job.Revoked(); + ~ChannelMap() = default; + + public: + uint32_t Open(const uint32_t waitTime, const uint16_t connectionCheckTimer) { + _connectionCheckTimer = connectionCheckTimer * 1000; + if (connectionCheckTimer != 0) { + _job.Reschedule(Core::Time::Now().Add(_connectionCheckTimer).Ticks()); } + return(BaseClass::Open(waitTime)); + } + uint32_t Close(const uint32_t waitTime) { + _job.Revoke(); // Start by closing the server thread.. - Close(100); + BaseClass::Close(waitTime); // Kill all open connections, we are shutting down !!! BaseClass::Iterator index(BaseClass::Clients()); @@ -4526,14 +4210,14 @@ POP_WARNING() while (index.Next() == true) { // Oops nothing hapened for a long time, kill the connection // give it 100ms to actually close, if not do it forcefully !! - index.Client()->Close(100); + index.Client()->Close(waitTime); } // Cleanup the closed sockets we created.. - Cleanup(); - } + ValidateConnections(); - public: + return (Core::ERROR_NONE); + } void SecurityRevoke(ISecurity* fallback) { BaseClass::Lock(); @@ -4554,20 +4238,13 @@ POP_WARNING() { return (Core::SocketServerType::Count()); } - inline void RequestClose(const uint32_t id) { - Core::ProxyType client(BaseClass::Client(id)); - - if (client.IsValid() == true) { - client->RequestClose(); - } + inline Core::ProxyType Connection(const uint32_t id) { + return(BaseClass::Client(id)); } - void TriggerCleanup() + void Cleanup() { if (_connectionCheckTimer == 0) { - Core::ProxyType job(_job.Reschedule(Core::Time::Now())); - if (job.IsValid() == true) { - _parent.Submit(job); - } + _job.Submit(); } } void GetMetaData(Core::JSON::ArrayType& metaData) const; @@ -4582,8 +4259,10 @@ POP_WARNING() { TRACE(Activity, (string(_T("Cleanup job running..\n")))); - // First clear all shit from last time.. - Cleanup(); + // Next Clean all Id's from JSONRPC nolonger available + // + // First check and clear, closed connections + ValidateConnections(); if (_connectionCheckTimer != 0) { // Now suspend those that have no activity. @@ -4608,11 +4287,22 @@ POP_WARNING() _job.Reschedule(NextTick); } } + void ValidateConnections() { + BaseClass::Iterator index(BaseClass::Clients()); + + while (index.Next() == true) { + if (index.Client()->IsOpen() == false) { + TRACE(Activity, (_T("Client closed, that is reported closed"), index.Client()->Id())); + _parent.Services().Closed(index.Client()->Id()); + } + } + BaseClass::Cleanup(); + } private: Server& _parent; - const uint32_t _connectionCheckTimer; - Core::ThreadPool::JobType _job; + uint32_t _connectionCheckTimer; + Core::WorkerPool::JobType _job; }; public: @@ -4630,9 +4320,17 @@ POP_WARNING() inline void Statistics(uint32_t& requests, uint32_t& responses, uint32_t& fileBodies, uint32_t& jsonrpc) const { _factoriesImplementation.Statistics(requests, responses, fileBodies, jsonrpc); } - inline ChannelMap& Dispatcher() + inline void SecurityRevoke(PluginHost::ISecurity* security) { - return (_connections); + return (_connections.SecurityRevoke(security)); + } + inline void Cleanup() + { + return (_connections.Cleanup()); + } + inline Core::ProxyType Connection(const uint32_t id) + { + return (_connections.Connection(id)); } inline void DumpMetadata() { PostMortemData data; @@ -4666,13 +4364,21 @@ POP_WARNING() { return (_services); } - inline void Metadata(PluginHost::MetaData::Version& data) + inline void Metadata(PluginHost::MetaData::Version& data) const { data.Major = PluginHost::Major; data.Minor = PluginHost::Minor; data.Patch = PluginHost::Patch; data.Hash = string(Core::System::ModuleBuildRef()); } + inline void Metadata(Core::JSON::ArrayType& data) const + { + _connections.GetMetaData(data); + _services.GetMetaData(data); + } + inline void Metadata(Core::JSON::ArrayType& data) const { + _services.GetMetaData(data); + } inline Server::WorkerPoolImplementation& WorkerPool() { return (_dispatcher); @@ -4728,9 +4434,6 @@ POP_WARNING() { return (_config.Security()); } - void Closed(const uint32_t id) { - _services.Closed(id); - } private: Core::NodeId _accessor; diff --git a/Source/WPEFramework/bridge.vcxproj b/Source/WPEFramework/bridge.vcxproj index c1ca8feaf8..1d25f550b0 100755 --- a/Source/WPEFramework/bridge.vcxproj +++ b/Source/WPEFramework/bridge.vcxproj @@ -122,7 +122,7 @@ __CORE_MESSAGING__;_CRT_SECURE_NO_WARNINGS;_WINDOWS;THREADPOOL_COUNT=4;HOSTING_COMPROCESS=comprocess.exe;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true pch.h - $(FrameworkPath)plugins\generated\json;$(FrameworkPath)plugins;$(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib + $(FrameworkPath)plugins;$(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib true @@ -146,7 +146,7 @@ __CORE_MESSAGING__;_CRT_SECURE_NO_WARNINGS;_WINDOWS;THREADPOOL_COUNT=4;HOSTING_COMPROCESS=comprocess.exe;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true pch.h - $(FrameworkPath)plugins\generated\json;$(FrameworkPath)plugins;$(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib + $(FrameworkPath)plugins;$(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib true @@ -168,7 +168,7 @@ __CORE_MESSAGING__;_CRT_SECURE_NO_WARNINGS;_WINDOWS;THREADPOOL_COUNT=4;HOSTING_COMPROCESS=comprocess.exe;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true pch.h - $(FrameworkPath)plugins\generated\json;$(FrameworkPath)plugins;$(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib + $(FrameworkPath)plugins;$(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib true @@ -192,7 +192,7 @@ __CORE_MESSAGING__;_CRT_SECURE_NO_WARNINGS;_WINDOWS;THREADPOOL_COUNT=4;HOSTING_COMPROCESS=comprocess.exe;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true pch.h - $(FrameworkPath)plugins\generated\json;$(FrameworkPath)plugins;$(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib + $(FrameworkPath)plugins;$(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib true diff --git a/Source/WPEProcess/comprocess.vcxproj b/Source/WPEProcess/comprocess.vcxproj index c59a0d16d9..48bf85fe34 100755 --- a/Source/WPEProcess/comprocess.vcxproj +++ b/Source/WPEProcess/comprocess.vcxproj @@ -110,7 +110,7 @@ __CORE_MESSAGING__;_CRT_SECURE_NO_WARNINGS;_WINDOWS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true pch.h - $(FrameworkPath);$(FrameworkPath)plugins\generated\json;$(WindowsPath);$(WindowsPath)zlib + $(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib true @@ -131,7 +131,7 @@ __CORE_MESSAGING__;_CRT_SECURE_NO_WARNINGS;_WINDOWS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true pch.h - $(FrameworkPath);$(FrameworkPath)plugins\generated\json;$(WindowsPath);$(WindowsPath)zlib + $(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib true @@ -150,7 +150,7 @@ __CORE_MESSAGING__;_CRT_SECURE_NO_WARNINGS;_WINDOWS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true pch.h - $(FrameworkPath);$(FrameworkPath)plugins\generated\json;$(WindowsPath);$(WindowsPath)zlib + $(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib true @@ -171,7 +171,7 @@ __CORE_MESSAGING__;_CRT_SECURE_NO_WARNINGS;_WINDOWS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true pch.h - $(FrameworkPath);$(FrameworkPath)plugins\generated\json;$(WindowsPath);$(WindowsPath)zlib + $(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib true diff --git a/Source/com/IUnknown.h b/Source/com/IUnknown.h index eba5c07d6d..e083ba22a2 100644 --- a/Source/com/IUnknown.h +++ b/Source/com/IUnknown.h @@ -300,6 +300,11 @@ namespace ProxyStub { // Oops something failed on the communication. Report it. TRACE_L1("IPC method invocation failed for 0x%X, error: %d", message->Parameters().InterfaceId(), result); } + else if (message->Response().Length() == 0) { + // Oops something failed on the communication. Report it. + TRACE_L1("Response empty for [%d]/[%d]. Is this the closing of the connection????", message->Parameters().InterfaceId(), message->Parameters().MethodId()); + result = COM_ERROR; + } return (result); } diff --git a/Source/com/Ids.h b/Source/com/Ids.h index fbbe6ef3d8..f89cba69ee 100644 --- a/Source/com/Ids.h +++ b/Source/com/Ids.h @@ -25,63 +25,66 @@ namespace WPEFramework { namespace RPC { enum IDS { - ID_OFFSET_INTERNAL = (Core::IUnknown::ID_OFFSET_INTERNAL), + ID_OFFSET_INTERNAL = (Core::IUnknown::ID_OFFSET_INTERNAL), - ID_COMCONNECTION = (ID_OFFSET_INTERNAL + 0x0001), - ID_COMCONNECTION_NOTIFICATION = (ID_OFFSET_INTERNAL + 0x0002), - ID_TRACEITERATOR = (ID_OFFSET_INTERNAL + 0x0003), - ID_TRACECONTROLLER = (ID_OFFSET_INTERNAL + 0x0004), - ID_STRINGITERATOR = (ID_OFFSET_INTERNAL + 0x0005), - ID_VALUEITERATOR = (ID_OFFSET_INTERNAL + 0x0006), - ID_MONITORABLE_PROCESS = (ID_OFFSET_INTERNAL + 0x0007), - ID_CONTROLLER_CONFIGURATION = (ID_OFFSET_INTERNAL + 0x0008), - ID_CONTROLLER_DISCOVERY = (ID_OFFSET_INTERNAL + 0x0009), + ID_COMCONNECTION = (ID_OFFSET_INTERNAL + 0x0001), + ID_COMCONNECTION_NOTIFICATION = (ID_OFFSET_INTERNAL + 0x0002), + ID_TRACEITERATOR = (ID_OFFSET_INTERNAL + 0x0003), + ID_TRACECONTROLLER = (ID_OFFSET_INTERNAL + 0x0004), + ID_STRINGITERATOR = (ID_OFFSET_INTERNAL + 0x0005), + ID_VALUEITERATOR = (ID_OFFSET_INTERNAL + 0x0006), + ID_MONITORABLE_PROCESS = (ID_OFFSET_INTERNAL + 0x0007), + ID_CONTROLLER_CONFIGURATION = (ID_OFFSET_INTERNAL + 0x0008), + ID_CONTROLLER_DISCOVERY = (ID_OFFSET_INTERNAL + 0x0009), ID_CONTROLLER_DISCOVERY_DISCOVERYRESULTS_ITERATOR = (ID_OFFSET_INTERNAL + 0x000A), - ID_CONTROLLER_SYSTEMINFO = (ID_OFFSET_INTERNAL + 0x000B), - ID_CONTROLLER_LIFETIME = (ID_OFFSET_INTERNAL + 0x000C), - ID_CONTROLLER_LIFETIME_NOTIFICATION = (ID_OFFSET_INTERNAL + 0x000D), - ID_CONTROLLER_METADATA = (ID_OFFSET_INTERNAL + 0x000E), - ID_CONTROLLER_METADATA_SERVICES_ITERATOR = (ID_OFFSET_INTERNAL + 0x000F), - ID_CONTROLLER_METADATA_LINKS_ITERATOR = (ID_OFFSET_INTERNAL + 0x0010), - ID_CONTROLLER_METADATA_PROXIES_ITERATOR = (ID_OFFSET_INTERNAL + 0x0011), - ID_CONTROLLER_METADATA_THREADS_ITERATOR = (ID_OFFSET_INTERNAL + 0x0012), + ID_CONTROLLER_SYSTEMINFO = (ID_OFFSET_INTERNAL + 0x000B), + ID_CONTROLLER_LIFETIME = (ID_OFFSET_INTERNAL + 0x000C), + ID_CONTROLLER_LIFETIME_NOTIFICATION = (ID_OFFSET_INTERNAL + 0x000D), + ID_CONTROLLER_METADATA = (ID_OFFSET_INTERNAL + 0x000E), + ID_CONTROLLER_METADATA_SERVICES_ITERATOR = (ID_OFFSET_INTERNAL + 0x000F), + ID_CONTROLLER_METADATA_LINKS_ITERATOR = (ID_OFFSET_INTERNAL + 0x0010), + ID_CONTROLLER_METADATA_PROXIES_ITERATOR = (ID_OFFSET_INTERNAL + 0x0011), + ID_CONTROLLER_METADATA_THREADS_ITERATOR = (ID_OFFSET_INTERNAL + 0x0012), ID_CONTROLLER_METADATA_SUBSYSTEMS_ITERATOR = (ID_OFFSET_INTERNAL + 0x0013), - ID_CONTROLLER_METADATA_CALLSTACK_ITERATOR = (ID_OFFSET_INTERNAL + 0x0014), - ID_CONTROLLER_SYSTEM_MANAGEMENT = (ID_OFFSET_INTERNAL + 0x0015), + ID_CONTROLLER_METADATA_CALLSTACK_ITERATOR = (ID_OFFSET_INTERNAL + 0x0014), + ID_CONTROLLER_SYSTEM_MANAGEMENT = (ID_OFFSET_INTERNAL + 0x0015), + ID_CONTROLLER_SHELLS = (ID_OFFSET_INTERNAL + 0x0017), + ID_CONTROLLER_SHELLS_NOTIFICATION = (ID_OFFSET_INTERNAL + 0x0018), - ID_CONTROLLER = (ID_OFFSET_INTERNAL + 0x0020), - ID_PLUGIN = (ID_OFFSET_INTERNAL + 0x0021), - ID_PLUGIN_NOTIFICATION = (ID_OFFSET_INTERNAL + 0x0022), - ID_PLUGINEXTENDED = (ID_OFFSET_INTERNAL + 0x0023), - ID_WEB = (ID_OFFSET_INTERNAL + 0x0024), - ID_WEBSOCKET = (ID_OFFSET_INTERNAL + 0x0025), - ID_DISPATCHER = (ID_OFFSET_INTERNAL + 0x0026), - ID_TEXTSOCKET = (ID_OFFSET_INTERNAL + 0x0027), - ID_CHANNEL = (ID_OFFSET_INTERNAL + 0x0028), - ID_SECURITY = (ID_OFFSET_INTERNAL + 0x0029), - ID_AUTHENTICATE = (ID_OFFSET_INTERNAL + 0x002A), - ID_PLUGIN_LIFETIME = (ID_OFFSET_INTERNAL + 0x002B), - ID_COMPOSIT_PLUGIN = (ID_OFFSET_INTERNAL + 0x002C), - ID_COMPOSIT_PLUGIN_NOTIFICATION = (ID_OFFSET_INTERNAL + 0x002D), - ID_DISPATCHER_CALLBACK = (ID_OFFSET_INTERNAL + 0x002E), - - ID_SHELL = (ID_OFFSET_INTERNAL + 0x0030), - ID_STATECONTROL = (ID_OFFSET_INTERNAL + 0x0031), - ID_STATECONTROL_NOTIFICATION = (ID_OFFSET_INTERNAL + 0x0032), - ID_SUBSYSTEM = (ID_OFFSET_INTERNAL + 0x0033), - ID_SUBSYSTEM_NOTIFICATION = (ID_OFFSET_INTERNAL + 0x0034), - ID_SUBSYSTEM_INTERNET = (ID_OFFSET_INTERNAL + 0x0035), - ID_SUBSYSTEM_LOCATION = (ID_OFFSET_INTERNAL + 0x0036), - ID_SUBSYSTEM_IDENTIFIER = (ID_OFFSET_INTERNAL + 0x0037), - ID_SUBSYSTEM_TIME = (ID_OFFSET_INTERNAL + 0x0038), - ID_SUBSYSTEM_SECURITY = (ID_OFFSET_INTERNAL + 0x0039), - ID_SUBSYSTEM_PROVISIONING = (ID_OFFSET_INTERNAL + 0x003A), - ID_SUBSYSTEM_DECRYPTION = (ID_OFFSET_INTERNAL + 0x003B), - ID_REMOTE_INSTANTIATION = (ID_OFFSET_INTERNAL + 0x003C), - ID_COMREQUEST_NOTIFICATION = (ID_OFFSET_INTERNAL + 0x003D), - ID_SYSTEM_METADATA = (ID_OFFSET_INTERNAL + 0x003E), - - ID_EXTERNAL_INTERFACE_OFFSET = (ID_OFFSET_INTERNAL + 0x0040) + // Plugin module + ID_PLUGIN = (ID_OFFSET_INTERNAL + 0x0021), + ID_CONTROLLER = (ID_OFFSET_INTERNAL + 0x0020), + ID_PLUGIN_NOTIFICATION = (ID_OFFSET_INTERNAL + 0x0022), + ID_PLUGINEXTENDED = (ID_OFFSET_INTERNAL + 0x0023), + ID_WEB = (ID_OFFSET_INTERNAL + 0x0024), + ID_WEBSOCKET = (ID_OFFSET_INTERNAL + 0x0025), + ID_DISPATCHER = (ID_OFFSET_INTERNAL + 0x0026), + ID_TEXTSOCKET = (ID_OFFSET_INTERNAL + 0x0027), + ID_CHANNEL = (ID_OFFSET_INTERNAL + 0x0028), + ID_SECURITY = (ID_OFFSET_INTERNAL + 0x0029), + ID_AUTHENTICATE = (ID_OFFSET_INTERNAL + 0x002A), + ID_PLUGIN_LIFETIME = (ID_OFFSET_INTERNAL + 0x002B), + ID_COMPOSIT_PLUGIN = (ID_OFFSET_INTERNAL + 0x002C), + ID_COMPOSIT_PLUGIN_CALLBACK = (ID_OFFSET_INTERNAL + 0x002D), + ID_DISPATCHER_CALLBACK = (ID_OFFSET_INTERNAL + 0x002E), + + ID_SHELL = (ID_OFFSET_INTERNAL + 0x0030), + ID_STATECONTROL = (ID_OFFSET_INTERNAL + 0x0031), + ID_STATECONTROL_NOTIFICATION = (ID_OFFSET_INTERNAL + 0x0032), + ID_SUBSYSTEM = (ID_OFFSET_INTERNAL + 0x0033), + ID_SUBSYSTEM_NOTIFICATION = (ID_OFFSET_INTERNAL + 0x0034), + ID_SUBSYSTEM_INTERNET = (ID_OFFSET_INTERNAL + 0x0035), + ID_SUBSYSTEM_LOCATION = (ID_OFFSET_INTERNAL + 0x0036), + ID_SUBSYSTEM_IDENTIFIER = (ID_OFFSET_INTERNAL + 0x0037), + ID_SUBSYSTEM_TIME = (ID_OFFSET_INTERNAL + 0x0038), + ID_SUBSYSTEM_SECURITY = (ID_OFFSET_INTERNAL + 0x0039), + ID_SUBSYSTEM_PROVISIONING = (ID_OFFSET_INTERNAL + 0x003A), + ID_SUBSYSTEM_DECRYPTION = (ID_OFFSET_INTERNAL + 0x003B), + ID_REMOTE_INSTANTIATION = (ID_OFFSET_INTERNAL + 0x003C), + ID_COMREQUEST_NOTIFICATION = (ID_OFFSET_INTERNAL + 0x003D), + ID_SYSTEM_METADATA = (ID_OFFSET_INTERNAL + 0x003E), + + ID_EXTERNAL_INTERFACE_OFFSET = (ID_OFFSET_INTERNAL + 0x0040) }; } } diff --git a/Source/core/JSONRPC.h b/Source/core/JSONRPC.h index 157db055e5..aadc4600bc 100644 --- a/Source/core/JSONRPC.h +++ b/Source/core/JSONRPC.h @@ -82,27 +82,63 @@ namespace Core { switch (frameworkError) { case Core::ERROR_BAD_REQUEST: Code = -32603; // Internal Error + Text = _T("Unknown method."); break; case Core::ERROR_INVALID_DESIGNATOR: + Text = _T("Invalid Request."); Code = -32600; // Invalid request break; case Core::ERROR_INVALID_SIGNATURE: Code = -32602; // Invalid parameters + Text = _T("Invalid Parameters."); break; case Core::ERROR_UNKNOWN_KEY: + Text = _T("Method not found."); Code = -32601; // Method not found break; case Core::ERROR_PRIVILIGED_REQUEST: Code = -32604; // Priviliged + Text = _T("method invocation not allowed."); + break; + case Core::ERROR_PRIVILIGED_DEFERRED: + Code = -32604; + Text = _T("method invokation is deferred, Currently not allowed."); break; case Core::ERROR_TIMEDOUT: Code = -32000; // Server defined, now mapped to Timed out + Text = _T("Call timed out."); break; case Core::ERROR_PARSE_FAILURE: Code = -32700; // Parse error + Text = _T("Parsing of the parameters failed"); + break; + case Core::ERROR_INVALID_RANGE: + Code = Core::ERROR_INVALID_RANGE; + Text = _T("Requested version is not supported."); + break; + case Core::ERROR_INCORRECT_URL: + Code = Core::ERROR_INCORRECT_URL; + Text = _T("Designator is invalid."); + break; + case Core::ERROR_ILLEGAL_STATE: + Code = Core::ERROR_ILLEGAL_STATE; + Text = _T("The service is in an illegal state!!!."); + break; + case Core::ERROR_FAILED_REGISTERED: + Code = Core::ERROR_FAILED_REGISTERED; + Text = _T("Registration already done!!!."); + break; + case Core::ERROR_FAILED_UNREGISTERED: + Code = Core::ERROR_FAILED_UNREGISTERED; + Text = _T("Unregister was already done!!!."); + break; + case Core::ERROR_HIBERNATED: + Code = Core::ERROR_HIBERNATED; + Text = _T("The service is in an Hibernated state!!!."); break; default: Code = static_cast(frameworkError); + Text = _T("Non specific error!!!."); break; } } diff --git a/Source/core/Portability.h b/Source/core/Portability.h index e972f4d603..f742c66936 100644 --- a/Source/core/Portability.h +++ b/Source/core/Portability.h @@ -341,6 +341,7 @@ typedef std::string string; #undef max #undef ERROR_NOT_SUPPORTED #undef ERROR_HIBERNATED +#undef ERROR_INVALID_PARAMETER //#if _MSC_VER >= 1600 //const std::basic_string::size_type std::basic_string::npos = (std::basic_string::size_type) - 1; @@ -887,7 +888,13 @@ namespace Core { ERROR_CODE(ERROR_INPROC, 47) \ ERROR_CODE(ERROR_FAILED_REGISTERED, 48) \ ERROR_CODE(ERROR_FAILED_UNREGISTERED, 49) \ - ERROR_CODE(ERROR_PARSE_FAILURE, 50) + ERROR_CODE(ERROR_PARSE_FAILURE, 50) \ + ERROR_CODE(ERROR_PRIVILIGED_DEFERRED, 51) \ + ERROR_CODE(ERROR_INVALID_ENVELOPPE, 52) \ + ERROR_CODE(ERROR_UNKNOWN_METHOD, 53) \ + ERROR_CODE(ERROR_INVALID_PARAMETER, 54) \ + ERROR_CODE(ERROR_INTERNAL_JSONRPC, 55) \ + ERROR_CODE(ERROR_PARSING_ENVELOPPE, 56) #define ERROR_CODE(CODE, VALUE) CODE = VALUE, diff --git a/Source/core/SocketServer.h b/Source/core/SocketServer.h index 613b4b21f0..be1a4df024 100644 --- a/Source/core/SocketServer.h +++ b/Source/core/SocketServer.h @@ -225,19 +225,6 @@ namespace Core { return (result); } - inline void Suspend(const uint32_t ID) - { - _lock.Lock(); - - typename ClientMap::iterator index = _clients.find(ID); - - if (index != _clients.end()) { - // Oke connection still exists, send the message.. - index->second->Close(0); - } - - _lock.Unlock(); - } inline void CloseClients(const uint32_t waiTime) { _lock.Lock(); diff --git a/Source/core/TextStreamRedirectType.h b/Source/core/TextStreamRedirectType.h index 965b582c0d..9649d34e29 100644 --- a/Source/core/TextStreamRedirectType.h +++ b/Source/core/TextStreamRedirectType.h @@ -165,8 +165,7 @@ namespace Core { ResourceMonitor& operator= (const ResourceMonitor&) = delete; static ResourceMonitor& Instance() { - static ResourceMonitor instance; - return (instance); + return (Core::SingletonType::Instance()); } ~ResourceMonitor() override { Core::Thread::Stop(); diff --git a/Source/plugins/CMakeLists.txt b/Source/plugins/CMakeLists.txt index 87df02631e..ae90628827 100644 --- a/Source/plugins/CMakeLists.txt +++ b/Source/plugins/CMakeLists.txt @@ -29,10 +29,10 @@ ProxyStubGenerator(NAMESPACE "WPEFramework::PluginHost" INPUT "${CMAKE_CURRENT_S ProxyStubGenerator(NAMESPACE "WPEFramework::PluginHost" INPUT "${CMAKE_CURRENT_SOURCE_DIR}/ISubSystem.h" OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/generated") ProxyStubGenerator(NAMESPACE "WPEFramework::PluginHost" INPUT "${CMAKE_CURRENT_SOURCE_DIR}/IDispatcher.h" OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/generated") -JsonGenerator(CODE NAMESPACE WPEFramework::Exchange::Controller INPUT ${CMAKE_CURRENT_SOURCE_DIR}/IController.h OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/generated/jsonrpc" INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/.." NO_INCLUDES) +JsonGenerator(CODE NAMESPACE WPEFramework::Exchange::Controller INPUT ${CMAKE_CURRENT_SOURCE_DIR}/IController.h OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/json" INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/.." NO_INCLUDES) -file(GLOB JSON_ENUM_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/generated/jsonrpc/JsonEnum_*.cpp") -file(GLOB JSON_DATA_HEADERS "${CMAKE_CURRENT_BINARY_DIR}/generated/jsonrpc/JsonData_*.h") +file(GLOB JSON_ENUM_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/json/JsonEnum_*.cpp") +file(GLOB JSON_DATA_HEADERS "${CMAKE_CURRENT_BINARY_DIR}/json/JsonData_*.h") add_library(${TARGET} SHARED Channel.cpp @@ -113,9 +113,8 @@ target_link_libraries(${TARGET_PROXYSTUBS} target_include_directories( ${TARGET} PUBLIC $ - $ + $ $ - $ ) target_include_directories( ${TARGET_PROXYSTUBS} diff --git a/Source/plugins/IController.h b/Source/plugins/IController.h index 8b119eaff5..ed7117e312 100644 --- a/Source/plugins/IController.h +++ b/Source/plugins/IController.h @@ -30,6 +30,7 @@ namespace WPEFramework { namespace Exchange { + namespace Controller { /* @json */ @@ -129,6 +130,23 @@ namespace Controller { virtual Core::hresult Resume(const string& callsign) = 0; }; + struct EXTERNAL IShells : virtual public Core::IUnknown { + enum { ID = RPC::ID_CONTROLLER_SHELLS }; + + struct EXTERNAL INotification : virtual public Core::IUnknown { + enum { ID = RPC::ID_CONTROLLER_SHELLS_NOTIFICATION }; + + // @brief Notifies the creation of a Shell (Startup or Clone) + virtual void Created(const string& callsign, PluginHost::IShell* plugin /* @in */) = 0; + // @brief Notifies the destruction of a shell (Destroy) + virtual void Destroy(const string& callsign, PluginHost::IShell* plugin /* @in */) = 0; + }; + + // Pushing notifications to interested sinks + virtual Core::hresult Register(INotification* sink) = 0; + virtual Core::hresult Unregister(INotification* sink) = 0; + }; + /* @json */ struct EXTERNAL IMetadata : virtual public Core::IUnknown { diff --git a/Source/plugins/IDispatcher.h b/Source/plugins/IDispatcher.h index 05a9fa1c5f..db629ec0be 100644 --- a/Source/plugins/IDispatcher.h +++ b/Source/plugins/IDispatcher.h @@ -29,28 +29,26 @@ namespace WPEFramework { struct EXTERNAL ILocalDispatcher; struct EXTERNAL IDispatcher : public virtual Core::IUnknown { - virtual ~IDispatcher() override = default; + ~IDispatcher() override = default; enum { ID = RPC::ID_DISPATCHER }; struct EXTERNAL ICallback : public virtual Core::IUnknown { - virtual ~ICallback() override = default; + ~ICallback() override = default; enum { ID = RPC::ID_DISPATCHER_CALLBACK }; - virtual Core::hresult Event(const string& event, const string& parameters /* @restrict:(4M-1) */) = 0; - virtual Core::hresult Error(const uint32_t channel, const uint32_t id, const uint32_t code, const string& message) = 0; - virtual Core::hresult Response(const uint32_t channel, const uint32_t id, const string& response /* @restrict:(4M-1) */) = 0; - - virtual Core::hresult Subscribe(const uint32_t channel, const string& event, const string& designator) = 0; - virtual Core::hresult Unsubscribe(const uint32_t channel, const string& event, const string& designator) = 0; + virtual Core::hresult Event(const string& event, const string& designator, const string& parameters /* @restrict:(4M-1) */) = 0; }; - virtual Core::hresult Validate(const string& token, const string& method, const string& paramaters /* @restrict:(4M-1) */) const = 0; - virtual Core::hresult Invoke(ICallback* callback, const uint32_t channelId, const uint32_t id, const string& token, const string& method, const string& parameters /* @restrict:(4M-1) */, string& response /* @restrict:(4M-1) @out */) = 0; - virtual Core::hresult Revoke(ICallback* callback) = 0; + virtual uint32_t Invoke(const uint32_t channelid, const uint32_t id, const string& token, const string& method, const string& parameters, string& response /* @out */) = 0; + + virtual Core::hresult Subscribe(ICallback* callback, const string& event, const string& designator) = 0; + virtual Core::hresult Unsubscribe(ICallback* callback, const string& event, const string& designator) = 0; - // If we need to activate this locally, we can get access to the base.. + // If this is a local instance of this interface, we get access to the IShell + // of this service which in turn allows access to the channels and thus the + // possibility to return responses on the right JSONRPC channels. /* @stubgen:stub */ virtual ILocalDispatcher* Local() = 0; }; diff --git a/Source/plugins/IPlugin.h b/Source/plugins/IPlugin.h index 8be4cd86c1..bc918b0cb6 100644 --- a/Source/plugins/IPlugin.h +++ b/Source/plugins/IPlugin.h @@ -116,19 +116,24 @@ namespace PluginHost { struct EXTERNAL ICompositPlugin : public virtual Core::IUnknown { enum { ID = RPC::ID_COMPOSIT_PLUGIN }; - struct EXTERNAL INotification : public virtual Core::IUnknown { - enum { ID = RPC::ID_COMPOSIT_PLUGIN_NOTIFICATION }; + struct EXTERNAL ICallback : public virtual Core::IUnknown { + enum { ID = RPC::ID_COMPOSIT_PLUGIN_CALLBACK }; - ~INotification() override = default; + ~ICallback() override = default; + + virtual void Created(const string& callsign, IShell* plugin) = 0; + virtual void Destroy(const string& callsign, IShell* plugin) = 0; - virtual uint32_t Activated(const string& callsign, IShell* plugin) = 0; - virtual uint32_t Deactivated(const string& callsign, IShell* plugin) = 0; + virtual void Activated(const string& callsign, IShell* plugin) = 0; + virtual void Deactivated(const string& callsign, IShell* plugin) = 0; + virtual void Unavailable(const string& callsign, IShell* plugin) = 0; }; ~ICompositPlugin() override = default; - virtual uint32_t Register(INotification*) = 0; - virtual uint32_t Unregister(INotification*) = 0; + static constexpr TCHAR Delimiter = '/'; + + virtual uint32_t Callback(ICallback*) = 0; }; /* @stubgen:omit */ diff --git a/Source/plugins/JSONRPC.h b/Source/plugins/JSONRPC.h index e8891b46ea..3c017560be 100644 --- a/Source/plugins/JSONRPC.h +++ b/Source/plugins/JSONRPC.h @@ -30,61 +30,126 @@ namespace WPEFramework { namespace PluginHost { struct EXTERNAL ILocalDispatcher : public IDispatcher { - virtual ~ILocalDispatcher() override = default; - - virtual uint32_t Invoke(const uint32_t channelId, const uint32_t id, const string& token, const string& method, const string& parameters, string& response) = 0; + virtual ~ILocalDispatcher() = default; virtual void Activate(IShell* service) = 0; virtual void Deactivate() = 0; virtual void Dropped(const uint32_t channelId) = 0; + virtual void Dropped(const IDispatcher::ICallback* callback) = 0; }; - class EXTERNAL JSONRPC : public ILocalDispatcher, public IDispatcher::ICallback { + class EXTERNAL JSONRPC : public ILocalDispatcher { private: class Observer { private: - using Destination = std::pair; + class Destination { + public: + Destination() = delete; + Destination(uint32_t channelId, const string& designator) + : _callback(nullptr) + , _channelId(channelId) + , _designator(designator) { + } + Destination(IDispatcher::ICallback* callback, const string& designator) + : _callback(callback) + , _channelId(~0) + , _designator(designator) { + if (_callback != nullptr) { + _callback->AddRef(); + } + } + Destination(Destination&& move) noexcept + : _callback(move._callback) + , _channelId(move._channelId) + , _designator(move._designator) { + move._callback = nullptr; + } + Destination(const Destination& copy) + : _callback(copy._callback) + , _channelId(copy._channelId) + , _designator(copy._designator) { + if (_callback != nullptr) { + _callback->AddRef(); + } + } + ~Destination() { + if (_callback != nullptr) { + _callback->Release(); + } + } + + Destination& operator= (Destination&& move) noexcept + { + if (_callback != nullptr) { + _callback->Release(); + } + _callback = move._callback; + _channelId = move._channelId; + _designator = move._designator; + move._callback = nullptr; + return (*this); + } + Destination& operator= (const Destination& copy) + { + if (_callback != nullptr) { + _callback->Release(); + } + _callback = copy._callback; + _channelId = copy._channelId; + _designator = copy._designator; + if (_callback != nullptr) { + _callback->AddRef(); + } + return (*this); + } + + public: + inline IDispatcher::ICallback* Callback() { + return (_callback); + } + inline uint32_t ChannelId() const { + return (_channelId); + } + inline const string& Designator() const { + return (_designator); + } + + private: + IDispatcher::ICallback* _callback; + uint32_t _channelId; + string _designator; + }; using Destinations = std::vector; - using Remotes = std::vector; public: - Observer& operator= (const Observer& copy) = delete; + Observer& operator= (Observer&&) = delete; + Observer& operator= (const Observer&) = delete; Observer() - : _callbacks() - , _designators() { + : _designators() { } Observer(Observer&& move) noexcept - : _callbacks(move._callbacks) - , _designators(move._designators) { + : _designators(move._designators) { } Observer(const Observer& copy) - : _callbacks(copy._callbacks) - , _designators(copy._designators) { - for (IDispatcher::ICallback*& callback : _callbacks) { - callback->AddRef(); - } - } - ~Observer() { - for (IDispatcher::ICallback*& callback : _callbacks) { - callback->Release(); - } + : _designators(copy._designators) { } + ~Observer() = default; public: bool IsEmpty() const { - return ( (_designators.empty()) && (_callbacks.empty()) ); + return ( _designators.empty() ); } - uint32_t Subscribe(const uint32_t id, const string& event) { + uint32_t Subscribe(const uint32_t id, const string& designator) { uint32_t result = Core::ERROR_NONE; Destinations::iterator index(_designators.begin()); - while ((index != _designators.end()) && ((index->first != id) || (index->second != event))) { + while ((index != _designators.end()) && ((index->ChannelId() != id) || (index->Designator() != designator))) { index++; } if (index == _designators.end()) { - _designators.emplace_back(Destination(id, event)); + _designators.emplace_back(id, designator); } else { result = Core::ERROR_DUPLICATE_KEY; @@ -92,11 +157,11 @@ namespace PluginHost { return (result); } - uint32_t Unsubscribe(const uint32_t id, const string& event) { + uint32_t Unsubscribe(const uint32_t id, const string& designator) { uint32_t result = Core::ERROR_NONE; Destinations::iterator index(_designators.begin()); - while ((index != _designators.end()) && ((index->first != id) || (index->second != event))) { + while ((index != _designators.end()) && ((index->ChannelId() != id) || (index->Designator() != designator))) { index++; } @@ -109,30 +174,55 @@ namespace PluginHost { return (result); } - void Subscribe(IDispatcher::ICallback* callback) { - Remotes::iterator index = std::find(_callbacks.begin(), _callbacks.end(), callback); + uint32_t Subscribe(IDispatcher::ICallback* callback, const string& designator) { + uint32_t result = Core::ERROR_NONE; - ASSERT(index == _callbacks.end()); + Destinations::iterator index(_designators.begin()); + while ((index != _designators.end()) && ((index->Designator() != designator) || (index->Callback() == callback))) { + index++; + } - if (index == _callbacks.end()) { - callback->AddRef(); - _callbacks.emplace_back(callback); + if (index == _designators.end()) { + _designators.emplace_back(callback, designator); + } + else { + result = Core::ERROR_DUPLICATE_KEY; } + + return (result); } - void Unsubscribe(const IDispatcher::ICallback* callback) { - Remotes::iterator index = std::find(_callbacks.begin(), _callbacks.end(), callback); + uint32_t Unsubscribe(IDispatcher::ICallback* callback, const string& designator) { + uint32_t result = Core::ERROR_NONE; - ASSERT(index != _callbacks.end()); + Destinations::iterator index(_designators.begin()); + while ((index != _designators.end()) && ((index->Designator() != designator) || (index->Callback() == callback))) { + index++; + } - if (index != _callbacks.end()) { - (*index)->Release(); - _callbacks.erase(index); + if (index != _designators.end()) { + _designators.erase(index); + } + else { + result = Core::ERROR_BAD_REQUEST; + } + + return (result); + } + void Dropped(const IDispatcher::ICallback* callback) { + Destinations::iterator index = _designators.begin(); + while (index != _designators.end()) { + if (index->Callback() == callback) { + index = _designators.erase(index); + } + else { + index++; + } } } void Dropped(const uint32_t channelId) { Destinations::iterator index = _designators.begin(); while (index != _designators.end()) { - if (index->first == channelId) { + if ( (index->ChannelId() == channelId) && (index->Callback() == nullptr) ) { index = _designators.erase(index); } else { @@ -141,18 +231,19 @@ namespace PluginHost { } } void Event(JSONRPC& parent, const string event, const string& parameter, const std::function& sendifmethod) { - for (const Destination& entry : _designators) { - if (!sendifmethod || sendifmethod(entry.second)) { - parent.Notify(entry.first, entry.second + '.' + event, parameter); + for (Destination& entry : _designators) { + if (!sendifmethod || sendifmethod(entry.Designator())) { + if (entry.Callback() == nullptr) { + parent.Notify(entry.ChannelId(), entry.Designator() + '.' + event, parameter); + } + else { + entry.Callback()->Event(event, entry.Designator(), parameter); + } } } - for (IDispatcher::ICallback*& callback : _callbacks) { - callback->Event(event, parameter); - } } private: - Remotes _callbacks; Destinations _designators; }; @@ -245,6 +336,7 @@ namespace PluginHost { DEFERRED = 3 }; + typedef std::function TokenCheckFunction; JSONRPC(const JSONRPC&) = delete; @@ -423,130 +515,128 @@ namespace PluginHost { parameters.ToString(subject); return InternalNotify(event, subject, std::move(method)); } - - // - // Methods to send responses to inbound invokaction methods (a-synchronous callbacks) - // ------------------------------------------------------------------------------------------------------------------------------ - template - uint32_t Response(const Core::JSONRPC::Context& channel, const JSONOBJECT& parameters) - { - string subject; - parameters.ToString(subject); - return (Response(channel, subject)); + void Response(const uint32_t channelId, const Core::ProxyType& message) { + _service->Submit(channelId, message); } - uint32_t Response(const Core::JSONRPC::Context& context, const string& result) - { - Core::ProxyType message = IFactories::Instance().JSONRPC(); - - ASSERT(_service != nullptr); - message->Result = result; - message->Id = context.Sequence(); - message->JSONRPC = Core::JSONRPC::Message::DefaultVersion; + // Inherited via IDispatcher + // --------------------------------------------------------------------------------- + uint32_t Invoke(const uint32_t channelId, const uint32_t id, const string& token, const string& method, const string& parameters, string& response) override { + uint32_t result = Core::ERROR_PARSE_FAILURE; - return (_service->Submit(context.ChannelId(), Core::ProxyType(message))); - } - uint32_t Response(const Core::JSONRPC::Context& channel, const Core::JSONRPC::Error& result) - { - Core::ProxyType message = IFactories::Instance().JSONRPC(); + if (method.empty() == false) { - ASSERT(_service != nullptr); + ASSERT(Core::JSONRPC::Message::Callsign(method).empty() || (Core::JSONRPC::Message::Callsign(method) == _callsign)); - message->Error = result; - message->Id = channel.Sequence(); - message->JSONRPC = Core::JSONRPC::Message::DefaultVersion; + result = Core::ERROR_NONE; - return (_service->Submit(channel.ChannelId(), Core::ProxyType(message))); - } - - // Inherited via IDispatcher - // --------------------------------------------------------------------------------- - Core::hresult Validate(const string& token, const string& method, const string& parameters) const override { - classification result; - if (_validate != nullptr) { - result = _validate(token, method, parameters); - if (result == classification::INVALID) { - return (Core::ERROR_PRIVILIGED_REQUEST); - } - else if (result == classification::DEFERRED) { - return (Core::ERROR_UNAVAILABLE); + if (_validate != nullptr) { + classification validation = _validate(token, method, parameters); + if (validation == classification::INVALID) { + result = Core::ERROR_PRIVILIGED_REQUEST; + } + else if (validation == classification::DEFERRED) { + result = Core::ERROR_PRIVILIGED_DEFERRED; + } } - } - return (Core::ERROR_NONE); - } - Core::hresult Invoke(IDispatcher::ICallback*, const uint32_t channelId, const uint32_t id, const string& token, const string& method, const string& parameters, string& response) override { - uint32_t result(Core::ERROR_BAD_REQUEST); - Core::JSONRPC::Handler* handler(Handler(method)); - string realMethod(Core::JSONRPC::Message::Method(method)); - if (handler == nullptr) { - result = Core::ERROR_INVALID_RANGE; - } - else if (realMethod == _T("exists")) { - result = Core::ERROR_NONE; - if (handler->Exists(parameters) == Core::ERROR_NONE) { - response = _T("1"); - } - else { - response = _T("0"); + if (result == Core::ERROR_NONE) { + + // Seems we are on the right handler.. + // now see if someone supports this version + string realMethod(Core::JSONRPC::Message::Method(method)); + + if (realMethod == _T("exists")) { + if (Handler(parameters) == nullptr) { + response = _T("0"); + } + else { + response = _T("1"); + } + } + if (realMethod == _T("register")) { + Registration info; info.FromString(parameters); + + result = Subscribe(channelId, info.Event.Value(), info.Callsign.Value()); + if (result == Core::ERROR_NONE) { + response = _T("0"); + } + else { + result = Core::ERROR_FAILED_REGISTERED; + } + } + else if (realMethod == _T("unregister")) { + Registration info; info.FromString(parameters); + + result = Unsubscribe(channelId, info.Event.Value(), info.Callsign.Value()); + if (result == Core::ERROR_NONE) { + response = _T("0"); + } + else { + result = Core::ERROR_FAILED_UNREGISTERED; + } + } + else { + Core::JSONRPC::Handler* handler(Handler(realMethod)); + + if (handler == nullptr) { + result = Core::ERROR_INCORRECT_URL; + } + else { + Core::JSONRPC::Context context(channelId, id, token); + result = handler->Invoke(context, realMethod, parameters, response); + } + } } } - else if (handler->Exists(realMethod) == Core::ERROR_NONE) { - Core::JSONRPC::Context context(channelId, id, token); - result = handler->Invoke(context, Core::JSONRPC::Message::FullMethod(method), parameters, response); - } + return (result); } - Core::hresult Revoke(IDispatcher::ICallback* callback) override { - // See if we re using this callback, we need to abort its use.. - for (std::pair& entry : _observers) { - entry.second.Unsubscribe(callback); + Core::hresult Subscribe(ICallback* callback, const string& eventId, const string& designator) override + { + uint32_t result; + + _adminLock.Lock(); + + ObserverMap::iterator index = _observers.find(eventId); + + if (index == _observers.end()) { + index = _observers.emplace(std::piecewise_construct, + std::forward_as_tuple(eventId), + std::forward_as_tuple()).first; } - return (Core::ERROR_NONE); - } - ILocalDispatcher* Local() override { - return (this); - } - // Inherited via ILocalDispatcher - // --------------------------------------------------------------------------------- - uint32_t Invoke(const uint32_t channelId, const uint32_t id, const string& token, const string& method, const string& parameters, string& response) override { - uint32_t result = Core::ERROR_INCORRECT_URL; + result = index->second.Subscribe(callback, designator); + + _adminLock.Unlock(); - ASSERT(Core::JSONRPC::Message::Callsign(method).empty() || (Core::JSONRPC::Message::Callsign(method) == _callsign)); + return (result); + } + Core::hresult Unsubscribe(ICallback* callback, const string& eventId, const string& designator) override + { + uint32_t result = Core::ERROR_UNKNOWN_KEY; - // Seems we are on the right handler.. - // now see if someone supports this version - string realMethod(Core::JSONRPC::Message::Method(method)); + _adminLock.Lock(); - if (realMethod == _T("register")) { - Registration info; info.FromString(parameters); + ObserverMap::iterator index = _observers.find(eventId); - result = Subscribe(this, channelId, info.Event.Value(), info.Callsign.Value()); - if (result == Core::ERROR_NONE) { - response = _T("0"); - } - else { - result = Core::ERROR_FAILED_REGISTERED; - } - } - else if (realMethod == _T("unregister")) { - Registration info; info.FromString(parameters); + if (index != _observers.end()) { + result = index->second.Unsubscribe(callback, designator); - result = Unsubscribe(this, channelId, info.Event.Value(), info.Callsign.Value()); - if (result == Core::ERROR_NONE) { - response = _T("0"); - } - else { - result = Core::ERROR_FAILED_UNREGISTERED; + if ((result == Core::ERROR_NONE) && (index->second.IsEmpty() == true)) { + _observers.erase(index); } } - else { - result = Invoke(this, channelId, id, token, method, parameters, response); - } + _adminLock.Unlock(); return (result); } + ILocalDispatcher* Local() override { + return (this); + } + + // Inherited via ILocalDispatcher + // --------------------------------------------------------------------------------- void Activate(IShell* service) override { ASSERT(_service == nullptr); @@ -584,79 +674,33 @@ namespace PluginHost { index++; } } - - _adminLock.Unlock(); } - - // Inherited via IDispatcher::ICallback - // --------------------------------------------------------------------------------- - Core::hresult Event(const string& eventId, const string& parameters) override { + Core::hresult Event(const string& eventId, const string& parameters) { return (InternalNotify(eventId, parameters)); } - Core::hresult Error(const uint32_t channel, const uint32_t id, const uint32_t code, const string& errorText) override { - Core::ProxyType message = IFactories::Instance().JSONRPC(); - - ASSERT(_service != nullptr); - - message->Error.Text = errorText; - message->Error.Code = code; - message->Id = id; - message->JSONRPC = Core::JSONRPC::Message::DefaultVersion; - - return (_service->Submit(channel, Core::ProxyType(message))); - } - Core::hresult Response(const uint32_t channel, const uint32_t id, const string& response) override { - Core::ProxyType message = IFactories::Instance().JSONRPC(); - - ASSERT(_service != nullptr); - - message->Result = response; - message->Id = id; - message->JSONRPC = Core::JSONRPC::Message::DefaultVersion; - - return (_service->Submit(channel, Core::ProxyType(message))); - } - Core::hresult Subscribe(const uint32_t channel, const string& eventId, const string& designator) override - { - uint32_t result; + // Inherited via IDispatcher::ICallback + // --------------------------------------------------------------------------------- + void Dropped(const IDispatcher::ICallback* callback) { _adminLock.Lock(); - ObserverMap::iterator index = _observers.find(eventId); - - if (index == _observers.end()) { - index = _observers.emplace(std::piecewise_construct, - std::forward_as_tuple(eventId), - std::forward_as_tuple()).first; - } - - result = index->second.Subscribe(channel, designator); - - _adminLock.Unlock(); - - return (result); - } - Core::hresult Unsubscribe(const uint32_t channel, const string& eventId, const string& designator) override - { - uint32_t result = Core::ERROR_UNKNOWN_KEY; - - _adminLock.Lock(); + ObserverMap::iterator index = _observers.begin(); - ObserverMap::iterator index = _observers.find(eventId); + while (index != _observers.end()) { - if (index != _observers.end()) { - result = index->second.Unsubscribe(channel, designator); + index->second.Dropped(callback); - if ((result == Core::ERROR_NONE) && (index->second.IsEmpty() == true)) { - _observers.erase(index); + if (index->second.IsEmpty() == true) { + index = _observers.erase(index); + } + else { + index++; } } _adminLock.Unlock(); - - return (result); } - + protected: uint32_t RegisterMethod(const uint8_t version, const string& methodName) { _adminLock.Lock(); @@ -694,59 +738,47 @@ namespace PluginHost { return (index == _handlers.end() ? nullptr : &(*index)); } - private: - uint32_t Subscribe(IDispatcher::ICallback* callback, const uint32_t channelId, const string& event, const string& designator) { - uint32_t result = Core::ERROR_UNKNOWN_KEY; + uint32_t Subscribe(const uint32_t channelId, const string& eventId, const string& designator) + { + uint32_t result; - // This is to make sure that the actuall location (there weher the channels really end) are - // aware of distributing the event. - if (callback->Subscribe(channelId, event, designator) == Core::ERROR_NONE) { + _adminLock.Lock(); - if (callback != this) { - // Oops the real location is somewhere else. Register this event also for callbacks - // to be forwarded to that actual location - _adminLock.Lock(); + ObserverMap::iterator index = _observers.find(eventId); - ObserverMap::iterator index = _observers.find(event); + if (index == _observers.end()) { + index = _observers.emplace(std::piecewise_construct, + std::forward_as_tuple(eventId), + std::forward_as_tuple()).first; + } - if (index == _observers.end()) { - index = _observers.emplace(std::piecewise_construct, - std::forward_as_tuple(event), - std::forward_as_tuple()).first; - } + result = index->second.Subscribe(channelId, designator); - index->second.Subscribe(callback); + _adminLock.Unlock(); - _adminLock.Unlock(); - } - result = Core::ERROR_NONE; - } return (result); } - uint32_t Unsubscribe(IDispatcher::ICallback* callback, const uint32_t channelId, const string& event, const string& designator) { + uint32_t Unsubscribe(const uint32_t channelId, const string& eventId, const string& designator) + { uint32_t result = Core::ERROR_UNKNOWN_KEY; - if (callback->Unsubscribe(channelId, event, designator) == Core::ERROR_NONE) { - - if (callback != this) { - // Oops the real location was somewhere else. Unregister this event also for callbacks - // to be forwarded to that actual location - _adminLock.Lock(); + _adminLock.Lock(); - ObserverMap::iterator index = _observers.find(event); + ObserverMap::iterator index = _observers.find(eventId); - if (index != _observers.end()) { - index->second.Unsubscribe(callback); + if (index != _observers.end()) { + result = index->second.Unsubscribe(channelId, designator); - if ((result == Core::ERROR_NONE) && (index->second.IsEmpty() == true)) { - _observers.erase(index); - } - } + if ((result == Core::ERROR_NONE) && (index->second.IsEmpty() == true)) { + _observers.erase(index); } - result = Core::ERROR_NONE; } + _adminLock.Unlock(); + return (result); } + + private: uint32_t InternalNotify(const string& event, const string& parameters, const std::function& sendifmethod = std::function()) const { uint32_t result = Core::ERROR_UNKNOWN_KEY; @@ -846,7 +878,7 @@ namespace PluginHost { } public: - Core::hresult Subscribe(const uint32_t channel, const string& eventId, const string& designator) override + uint32_t Subscribe(const uint32_t channel, const string& eventId, const string& designator) { const Core::hresult result = JSONRPC::Subscribe(channel, eventId, designator); @@ -856,8 +888,7 @@ namespace PluginHost { return (result); } - - Core::hresult Unsubscribe(const uint32_t channel, const string& eventId, const string& designator) override + uint32_t Unsubscribe(const uint32_t channel, const string& eventId, const string& designator) { const Core::hresult result = JSONRPC::Unsubscribe(channel, eventId, designator); diff --git a/Source/plugins/MetaData.h b/Source/plugins/MetaData.h index 0e86d52ea3..3646e209be 100644 --- a/Source/plugins/MetaData.h +++ b/Source/plugins/MetaData.h @@ -24,9 +24,8 @@ #include "Configuration.h" #include "IController.h" -#include "JsonData_Metadata.h" -#include "JsonData_Discovery.h" - +#include +#include namespace WPEFramework { namespace PluginHost { diff --git a/Source/plugins/plugins.vcxproj b/Source/plugins/plugins.vcxproj index c968489781..c3b293245b 100755 --- a/Source/plugins/plugins.vcxproj +++ b/Source/plugins/plugins.vcxproj @@ -20,8 +20,11 @@ - - + + + + + @@ -36,8 +39,30 @@ - - + + false + true + false + true + false + true + false + true + $(Projectdir)/json/JConfiguration.h + $(Projectdir)/json/JConfiguration.h + $(Projectdir)/json/JConfiguration.h + $(Projectdir)/json/JConfiguration.h + ClInclude + ClInclude + ClInclude + ClInclude + + + $(ProjectDir)json/JDispatcher.h + $(ProjectDir)json/JDispatcher.h + $(ProjectDir)json/JDispatcher.h + $(ProjectDir)json/JDispatcher.h + @@ -138,7 +163,7 @@ true __CORE_MESSAGING__;_CRT_SECURE_NO_WARNINGS;NDEBUG;PLUGINS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true - .;$(FrameworkPath)plugins\generated\json;$(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib + .;$(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib true @@ -150,8 +175,26 @@ $(IntDir)$(TargetName).pdb - python "$(ToolPath)\JsonGenerator\JsonGenerator.py" -I "$(FrameworkPath)\" --no-includes --keep-empty -c --namespace WPEFramework::Exchange::Controller -o "$(ProjectDir)generated\json" "$(ProjectDir)IController.h" --force + + + + + + + + + + + + python "$(ToolPath)\JsonGenerator\JsonGenerator.py" -I "$(FrameworkPath)\" --no-includes --keep-empty -c --namespace WPEFramework::Exchange::Controller -o "$(ProjectDir)/json" "%(FullPath)" --force + + + JSON Generated Code + $(ProjectDir)json/JSystemManagement.h + ClCompile + true + @@ -161,7 +204,7 @@ true __CORE_MESSAGING__;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;PLUGINS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true - .;$(FrameworkPath)plugins\generated\json;$(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib + .;$(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib true @@ -171,8 +214,26 @@ $(IntDir)$(TargetName).pdb - python "$(ToolPath)\JsonGenerator\JsonGenerator.py" -I "$(FrameworkPath)\" --no-includes --keep-empty -c --namespace WPEFramework::Exchange::Controller -o "$(ProjectDir)generated\json" "$(ProjectDir)IController.h" --force + + + + + + + + + + + + python "$(ToolPath)\JsonGenerator\JsonGenerator.py" -I "$(FrameworkPath)\" --no-includes --keep-empty -c --namespace WPEFramework::Exchange::Controller -o "$(ProjectDir)/json" "%(FullPath)" --force + + + JSON Generated Code + $(ProjectDir)json/JSystemManagement.h + ClCompile + true + @@ -182,7 +243,7 @@ true __CORE_MESSAGING__;_CRT_SECURE_NO_WARNINGS;_DEBUG;PLUGINS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true - .;$(FrameworkPath)plugins\generated\json;$(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib + .;$(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib true @@ -192,8 +253,26 @@ $(IntDir)$(TargetName).pdb - python "$(ToolPath)\JsonGenerator\JsonGenerator.py" -I "$(FrameworkPath)\" --no-includes --keep-empty -c --namespace WPEFramework::Exchange::Controller -o "$(ProjectDir)generated\json" "$(ProjectDir)IController.h" --force + + + + + + + + + + + + python "$(ToolPath)\JsonGenerator\JsonGenerator.py" -I "$(FrameworkPath)\" --no-includes --keep-empty -c --namespace WPEFramework::Exchange::Controller -o "$(ProjectDir)/json" "%(FullPath)" --force + + + JSON Generated Code + $(ProjectDir)json/JSystemManagement.h + ClCompile + true + @@ -205,7 +284,7 @@ true __CORE_MESSAGING__;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;PLUGINS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true - .;$(FrameworkPath)plugins\generated\json;$(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib + .;$(FrameworkPath);$(WindowsPath);$(WindowsPath)zlib true @@ -217,8 +296,26 @@ $(IntDir)$(TargetName).pdb - python "$(ToolPath)\JsonGenerator\JsonGenerator.py" -I "$(FrameworkPath)\" --no-includes --keep-empty -c --namespace WPEFramework::Exchange::Controller -o "$(ProjectDir)generated\json" "$(ProjectDir)IController.h" --force + + + + + + + + + + + + python "$(ToolPath)\JsonGenerator\JsonGenerator.py" -I "$(FrameworkPath)\" --no-includes --keep-empty -c --namespace WPEFramework::Exchange::Controller -o "$(ProjectDir)/json" "%(FullPath)" --force + + + JSON Generated Code + $(ProjectDir)json/JSystemManagement.h + ClCompile + true + diff --git a/Source/plugins/plugins.vcxproj.filters b/Source/plugins/plugins.vcxproj.filters index f7742fa329..42a8f63598 100755 --- a/Source/plugins/plugins.vcxproj.filters +++ b/Source/plugins/plugins.vcxproj.filters @@ -31,11 +31,20 @@ Source Files - - Source Files\generated + + Generated Files - - Source Files\generated + + Generated Files + + + Generated Files + + + Generated Files + + + Generated Files @@ -93,9 +102,6 @@ Interface Files - - Interface Files - @@ -107,11 +113,16 @@ {4ca8a196-74dd-4e20-98ef-051e5a446b67} - + {2ef8c592-a7e4-4c2e-9d00-d54599022486} + + + Interface Files + + \ No newline at end of file diff --git a/Source/plugins/proxystubs.vcxproj b/Source/plugins/proxystubs.vcxproj index 700891e350..88ec38211f 100644 --- a/Source/plugins/proxystubs.vcxproj +++ b/Source/plugins/proxystubs.vcxproj @@ -19,15 +19,17 @@ - - - - - - + - + + + + + + + + 15.0 @@ -128,7 +130,7 @@ $(IntDir)$(TargetName).pdb - python "$(ToolPath)\ProxyStubGenerator\StubGenerator.py" --namespace WPEFramework::PluginHost --outdir "$(ProjectDir)generated" "$(ProjectDir)IPlugin.h" "$(ProjectDir)IShell.h" "$(ProjectDir)IControllerDeprecated.h" "$(ProjectDir)IController.h" "$(ProjectDir)IStateControl.h" "$(ProjectDir)ISubSystem.h" "$(ProjectDir)IDispatcher.h" -I "$(ProjectDir)\.." + python "$(ToolPath)\ProxyStubGenerator\StubGenerator.py" --namespace WPEFramework --outdir "$(SolutionDir)..\artifacts\generated\$(ProjectName)" "$(ProjectDir)IPlugin.h" "$(ProjectDir)IShell.h" "$(ProjectDir)IControllerDeprecated.h" "$(ProjectDir)IController.h" "$(ProjectDir)IStateControl.h" "$(ProjectDir)ISubSystem.h" "$(ProjectDir)IDispatcher.h" -I "$(ProjectDir)\.." @@ -152,7 +154,7 @@ $(IntDir)$(TargetName).pdb - python "$(ToolPath)\ProxyStubGenerator\StubGenerator.py" --namespace WPEFramework::PluginHost --outdir "$(ProjectDir)generated" "$(ProjectDir)IPlugin.h" "$(ProjectDir)IShell.h" "$(ProjectDir)IControllerDeprecated.h" "$(ProjectDir)IController.h" "$(ProjectDir)IStateControl.h" "$(ProjectDir)ISubSystem.h" "$(ProjectDir)IDispatcher.h" -I "$(ProjectDir)\.." + python "$(ToolPath)\ProxyStubGenerator\StubGenerator.py" --namespace WPEFramework --outdir "$(SolutionDir)..\artifacts\generated\$(ProjectName)" "$(ProjectDir)IPlugin.h" "$(ProjectDir)IShell.h" "$(ProjectDir)IControllerDeprecated.h" "$(ProjectDir)IController.h" "$(ProjectDir)IStateControl.h" "$(ProjectDir)ISubSystem.h" "$(ProjectDir)IDispatcher.h" -I "$(ProjectDir)\.." @@ -176,7 +178,7 @@ $(IntDir)$(TargetName).pdb - python "$(ToolPath)\ProxyStubGenerator\StubGenerator.py" --namespace WPEFramework::PluginHost --outdir "$(ProjectDir)generated" "$(ProjectDir)IPlugin.h" "$(ProjectDir)IShell.h" "$(ProjectDir)IControllerDeprecated.h" "$(ProjectDir)IController.h" "$(ProjectDir)IStateControl.h" "$(ProjectDir)ISubSystem.h" "$(ProjectDir)IDispatcher.h" -I "$(ProjectDir)\.." + python "$(ToolPath)\ProxyStubGenerator\StubGenerator.py" --namespace WPEFramework --outdir "$(SolutionDir)..\artifacts\generated\$(ProjectName)" "$(ProjectDir)IPlugin.h" "$(ProjectDir)IShell.h" "$(ProjectDir)IControllerDeprecated.h" "$(ProjectDir)IController.h" "$(ProjectDir)IStateControl.h" "$(ProjectDir)ISubSystem.h" "$(ProjectDir)IDispatcher.h" -I "$(ProjectDir)\.." @@ -204,7 +206,7 @@ $(IntDir)$(TargetName).pdb - python "$(ToolPath)\ProxyStubGenerator\StubGenerator.py" --namespace WPEFramework::PluginHost --outdir "$(ProjectDir)generated" "$(ProjectDir)IPlugin.h" "$(ProjectDir)IShell.h" "$(ProjectDir)IControllerDeprecated.h" "$(ProjectDir)IController.h" "$(ProjectDir)IStateControl.h" "$(ProjectDir)ISubSystem.h" "$(ProjectDir)IDispatcher.h" -I "$(ProjectDir)\.." + python "$(ToolPath)\ProxyStubGenerator\StubGenerator.py" --namespace WPEFramework --outdir "$(SolutionDir)..\artifacts\generated\$(ProjectName)" "$(ProjectDir)IPlugin.h" "$(ProjectDir)IShell.h" "$(ProjectDir)IControllerDeprecated.h" "$(ProjectDir)IController.h" "$(ProjectDir)IStateControl.h" "$(ProjectDir)ISubSystem.h" "$(ProjectDir)IDispatcher.h" -I "$(ProjectDir)\.." diff --git a/Source/plugins/proxystubs.vcxproj.filters b/Source/plugins/proxystubs.vcxproj.filters index 3cc36e0490..362e38ba22 100644 --- a/Source/plugins/proxystubs.vcxproj.filters +++ b/Source/plugins/proxystubs.vcxproj.filters @@ -1,31 +1,37 @@  - + + {09855975-a4b7-44e1-a4f4-f9fc631e2d98} + + + + + + + Generated Files - + Generated Files - + Generated Files - + Generated Files - + Generated Files - + + Generated Files + + + Generated Files + + Generated Files - - - - {09855975-a4b7-44e1-a4f4-f9fc631e2d98} - - - - \ No newline at end of file