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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ option(EXCEPTION_CATCHING
"Enable unhandled exception handling catching." OFF)
option(DEADLOCK_DETECTION
"Enable deadlock detection tooling." OFF)
option(DISABLE_USE_COMPLEMENTARY_CODE_SET
"Disable the complementary code set" OFF)

if(HIDE_NON_EXTERNAL_SYMBOLS)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
Expand Down Expand Up @@ -108,3 +110,8 @@ endif()
if(EXECUTABLE)
add_subdirectory(WPEFramework)
endif()

if(DISABLE_USE_COMPLEMENTARY_CODE_SET)
add_definitions(-D__DISABLE_USE_COMPLEMENTARY_CODE_SET__)
message(STATUS "complementary code set disabled")
endif()
24 changes: 24 additions & 0 deletions Source/WPEFramework/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,9 @@ namespace PluginHost {
, Observe()
#ifdef HIBERNATE_SUPPORT_ENABLED
, Hibernate()
#endif
#ifndef __DISABLE_USE_COMPLEMENTARY_CODE_SET__
, CustomCodeLibrary()
#endif
{
// No IdleTime
Expand Down Expand Up @@ -433,6 +436,9 @@ namespace PluginHost {
Add(_T("observe"), &Observe);
#ifdef HIBERNATE_SUPPORT_ENABLED
Add(_T("hibernate"), &Hibernate);
#endif
#ifndef __DISABLE_USE_COMPLEMENTARY_CODE_SET__
Add(_T("customcodelibrary"), &CustomCodeLibrary);
#endif
}
~JSONConfig() override = default;
Expand Down Expand Up @@ -477,6 +483,9 @@ namespace PluginHost {
Observables Observe;
#ifdef HIBERNATE_SUPPORT_ENABLED
HibernateConfig Hibernate;
#endif
#ifndef __DISABLE_USE_COMPLEMENTARY_CODE_SET__
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you verified by enabling the DISABLE_USE_COMPLEMENTARY_CODE_SET switch?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh @sivarajappan-siva I must admit I didn't test that myself (blush) :)
It is more a "safety" mechanism so we can disable less essential stuff.
Might you try and hit issues (already caused by my changes) just let me know and I will help

Core::JSON::String CustomCodeLibrary;
#endif
};

Expand Down Expand Up @@ -638,6 +647,9 @@ namespace PluginHost {
#ifdef HIBERNATE_SUPPORT_ENABLED
, _hibernateLocator()
#endif
#ifndef __DISABLE_USE_COMPLEMENTARY_CODE_SET__
, _customCodeLibrary()
#endif
{
JSONConfig config;

Expand All @@ -652,6 +664,9 @@ namespace PluginHost {
#endif
#ifdef HIBERNATE_SUPPORT_ENABLED
_hibernateLocator = config.Hibernate.Locator.Value();
#endif
#ifndef __DISABLE_USE_COMPLEMENTARY_CODE_SET__
_customCodeLibrary = config.CustomCodeLibrary.Value();
#endif
_volatilePath = Core::Directory::Normalize(config.VolatilePath.Value());
_persistentPath = Core::Directory::Normalize(config.PersistentPath.Value());
Expand Down Expand Up @@ -784,6 +799,12 @@ POP_WARNING()
inline const string& HibernateLocator() const {
return (_hibernateLocator);
}
#endif
#ifndef __DISABLE_USE_COMPLEMENTARY_CODE_SET__
inline const string& CustomCodeLibrary() const
{
return (_customCodeLibrary);
}
#endif
inline const string& VolatilePath() const
{
Expand Down Expand Up @@ -1069,6 +1090,9 @@ POP_WARNING()
std::vector<std::string> _linkerPluginPaths;
#ifdef HIBERNATE_SUPPORT_ENABLED
string _hibernateLocator;
#endif
#ifndef __DISABLE_USE_COMPLEMENTARY_CODE_SET__
string _customCodeLibrary;
#endif
};
}
Expand Down
76 changes: 76 additions & 0 deletions Source/WPEFramework/PluginHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,66 @@ POP_WARNING()
string _interface;
Core::AdapterObserver _observer;
};

#ifndef __DISABLE_USE_COMPLEMENTARY_CODE_SET__

class CustomCodeLibrary {
public:

CustomCodeLibrary(const CustomCodeLibrary&) = delete;
CustomCodeLibrary& operator=(const CustomCodeLibrary&) = delete;
CustomCodeLibrary(CustomCodeLibrary&&) = delete;
CustomCodeLibrary& operator=(CustomCodeLibrary&&) = delete;

CustomCodeLibrary()
: _customCodeLibrary()
, _customCodeToStringHandler(nullptr)
{
}
~CustomCodeLibrary()
{
ASSERT(_customCodeToStringHandler == nullptr);
ASSERT(_customCodeLibrary.IsLoaded() == false);
}

void Load(const string& libraryPath)
{
ASSERT(_customCodeToStringHandler == nullptr);
ASSERT(_customCodeLibrary.IsLoaded() == false);

_customCodeLibrary = Core::Library(libraryPath.c_str());
if (_customCodeLibrary.IsLoaded() == true) {
_customCodeToStringHandler = reinterpret_cast<Core::CustomCodeToStringHandler>(_customCodeLibrary.LoadFunction(CustomCodeToStringName));
if (_customCodeToStringHandler != nullptr) {
Core::SetCustomCodeToStringHandler(_customCodeToStringHandler);
} else {
SYSLOG(Logging::Error, (_T("Could not find CustomCodeToString function in Custom Error Code library")));
_customCodeLibrary = Core::Library();
}
} else {
SYSLOG(Logging::Error, (_T("Could not load Custom Error Code library")));
}
}

void Release()
{
if (_customCodeToStringHandler != nullptr) {
Core::SetCustomCodeToStringHandler(nullptr);
_customCodeToStringHandler = nullptr;
}
if (_customCodeLibrary.IsLoaded() == true) {
_customCodeLibrary = Core::Library();
}
}

private:
static constexpr const TCHAR* CustomCodeToStringName{ _T("CustomCodeToString") };

Core::Library _customCodeLibrary;
Core::CustomCodeToStringHandler _customCodeToStringHandler;
};

#endif

class ExitHandler : public Core::Thread {
private:
Expand Down Expand Up @@ -514,6 +574,10 @@ POP_WARNING()
fprintf(stdout, "Config file [%s] could not be opened.\n", options.configFile);
}
}

#ifndef __DISABLE_USE_COMPLEMENTARY_CODE_SET__
CustomCodeLibrary customcodelibraryhandler;
#endif

if (_config != nullptr) {

Expand Down Expand Up @@ -567,6 +631,14 @@ POP_WARNING()
postMortemPath.CreatePath();
}


#ifndef __DISABLE_USE_COMPLEMENTARY_CODE_SET__
if (_config->CustomCodeLibrary().empty() == false) {
customcodelibraryhandler.Load(_config->CustomCodeLibrary());
}
#endif


if (_config->MessagingCategoriesFile()) {

messagingSettings = Core::Directory::Normalize(Core::File::PathName(options.configFile)) + _config->MessagingCategories();
Expand Down Expand Up @@ -1018,6 +1090,10 @@ POP_WARNING()
fprintf(stderr, EXPAND_AND_QUOTE(APPLICATION_NAME) " shutting down due to a 'Q' press in the terminal. Regular shutdown\n");
fflush(stderr);
}

#ifndef __DISABLE_USE_COMPLEMENTARY_CODE_SET__
customcodelibraryhandler.Release();
#endif

ExitHandler::Destruct();
std::set_terminate(nullptr);
Expand Down
1 change: 1 addition & 0 deletions Source/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ set(PUBLIC_HEADERS
CallsignTLS.h
TokenizedStringList.h
MessageStore.h
ICustomErrorCode.h
)

target_compile_options (${TARGET} PRIVATE -Wno-psabi)
Expand Down
56 changes: 56 additions & 0 deletions Source/core/ICustomErrorCode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:
*
* Copyright 2025 Metrological
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*
This file contains the interface that a library can implement in case the "custom error codes" feature is used in Thunder and code to string conversion is desired
*/

#pragma once

#undef EXTERNAL

#if defined(WIN32) || defined(_WINDOWS) || defined(__CYGWIN__) || defined(_WIN64)
#define EXTERNAL __declspec(dllexport)
#else
#define EXTERNAL __attribute__((visibility("default")))
#endif

#ifndef TCHAR
#ifdef _UNICODE
#define TCHAR wchar_t
#else
#define TCHAR char
#endif
#endif

#ifdef __cplusplus
#include <cstdint>
extern "C" {
#else
#include <stdint.h>
#endif

// called from within Thunder to get the string representation for a custom code
// note parameter code is the pure (signed) Custom Code passed to Thunder. no additional bits set (so for signed numbers 32nd bit used as sign bit).
// in case no special string representation is needed return nullptr (NULL), in that case Thunder will convert the Custom Code to a generic message itself
EXTERNAL const TCHAR* CustomCodeToString(const int32_t code);

#ifdef __cplusplus
} // extern "C"
#endif
32 changes: 17 additions & 15 deletions Source/core/JSONRPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ namespace Core {

class EXTERNAL Message : public Core::JSON::Container {
public:
static constexpr int32_t ApplicationErrorCodeBase = -31000;
class Info : public Core::JSON::Container {
public:
Info()
Expand Down Expand Up @@ -125,23 +126,24 @@ namespace Core {
Text = _T("The service is in an Hibernated state!!!.");
break;
default:
if ((frameworkError & 0x80000000) == 0) {

// Heras solution to enable the possibility to override the json rpc errorcode and make it fall into
// the -32000 to -32099 range (as desired by some externally defined interfaces). The 1000 offset and -31000 base are chosen to on
// one hand keep the current Thunder error codes used in 4.4 backwards compatible (so the numbers as reported in
// json rpc will not change) while at the same time making sure that code used in dynamic json rpc override will behave
// as in Thunder 5 (so if the error code is changed to 1000 there it will result in a -32000 error code reported for json rpc)

if( frameworkError <= 999 ) {
Code = static_cast<int32_t>(frameworkError);
if ((frameworkError & COM_ERROR) != 0) {
Code = ApplicationErrorCodeBase - static_cast<int32_t>(frameworkError & 0x7FFFFFFF) - 500;
} else {
#ifndef __DISABLE_USE_COMPLEMENTARY_CODE_SET__
int32_t customcode = IsCustomCode(frameworkError);
if (customcode != 0) {
Code = (customcode == std::numeric_limits<int32_t>::min() ? 0 : customcode);
} else {
Code = -31000 - static_cast<int32_t>(frameworkError);
#endif
Code = ApplicationErrorCodeBase - static_cast<int32_t>(frameworkError);
#ifndef __DISABLE_USE_COMPLEMENTARY_CODE_SET__
}
} else {
Code = static_cast<int32_t>(frameworkError & 0x7FFFFFFF) + 500;
}
Text = Core::ErrorToString(frameworkError);
#endif
}

if (Text.IsSet() == false) {
Text = Core::ErrorToStringExtended(frameworkError);
}
break;
}
}
Expand Down
Loading