From f2abafb1a37c6a538e97c7863fe7e2e28fa00c1d Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Tue, 21 May 2024 13:34:58 +0300 Subject: [PATCH 001/198] [github,workflows] Add static analysis action Signed-off-by: Mykhailo Lohvynenko --- .github/workflows/static_analysis.yaml | 24 ++++++++++++++++++++++++ suppressions.txt | 2 ++ 2 files changed, 26 insertions(+) create mode 100644 .github/workflows/static_analysis.yaml create mode 100644 suppressions.txt diff --git a/.github/workflows/static_analysis.yaml b/.github/workflows/static_analysis.yaml new file mode 100644 index 00000000..b06ed081 --- /dev/null +++ b/.github/workflows/static_analysis.yaml @@ -0,0 +1,24 @@ +name: Static analysis +on: + push: + branches: + - main + + pull_request: + branches: + - develop + - feature_* + +jobs: + cpp-check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Prepare + run: | + sudo apt install cppcheck -y + + - name: Run cppcheck + run: | + cppcheck --enable=all --inline-suppr -I src --std=c++17 --error-exitcode=1 \ + --suppressions-list=./suppressions.txt src diff --git a/suppressions.txt b/suppressions.txt new file mode 100644 index 00000000..17da75d1 --- /dev/null +++ b/suppressions.txt @@ -0,0 +1,2 @@ +missingIncludeSystem +useStlAlgorithm From c3d541dddfbe5bb95fb9380973f9c5d9e5142b6d Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Tue, 21 May 2024 13:35:27 +0300 Subject: [PATCH 002/198] [cppcheck] Add inline suppressions Signed-off-by: Mykhailo Lohvynenko --- src/communication/communication.cpp | 2 ++ src/communication/tlschannel.cpp | 1 + src/domains/domd/domd_cfg_h3ulcb.c | 1 + src/domains/domd/domd_cfg_salvator_xs.c | 1 + src/domains/domd/domd_cfg_spider.c | 1 + src/domains/domu/domu_cfg.c | 1 + src/downloader/downloader.cpp | 1 + src/main.cpp | 2 ++ src/monitoring/resourceusageprovider.cpp | 6 ++++-- src/ocispec/ocispec.cpp | 6 ++++++ src/runner/runner.cpp | 2 ++ src/storage/storage.cpp | 13 +++++++++++++ 12 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/communication/communication.cpp b/src/communication/communication.cpp index fb05b26e..1d0e44ae 100644 --- a/src/communication/communication.cpp +++ b/src/communication/communication.cpp @@ -135,6 +135,7 @@ void Communication::ClockUnsynced() mCondVar.NotifyOne(); } +// cppcheck-suppress unusedFunction aos::Error Communication::Subscribes(aos::ConnectionSubscriberItf& subscriber) { aos::LockGuard lock(mMutex); @@ -147,6 +148,7 @@ aos::Error Communication::Subscribes(aos::ConnectionSubscriberItf& subscriber) return aos::ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction void Communication::Unsubscribes(aos::ConnectionSubscriberItf& subscriber) { aos::LockGuard lock(mMutex); diff --git a/src/communication/tlschannel.cpp b/src/communication/tlschannel.cpp index 06781a12..7ccad299 100644 --- a/src/communication/tlschannel.cpp +++ b/src/communication/tlschannel.cpp @@ -185,6 +185,7 @@ aos::Error TLSChannel::SetupSSLConfig(const aos::String& certType) extern unsigned char __aos_root_ca_start[]; extern unsigned char __aos_root_ca_end[]; + // cppcheck-suppress comparePointers auto ret = mbedtls_x509_crt_parse(&mCACert, __aos_root_ca_start, __aos_root_ca_end - __aos_root_ca_start); if (ret != 0) { return AOS_ERROR_WRAP(ret); diff --git a/src/domains/domd/domd_cfg_h3ulcb.c b/src/domains/domd/domd_cfg_h3ulcb.c index 2da43de8..1919fe23 100644 --- a/src/domains/domd/domd_cfg_h3ulcb.c +++ b/src/domains/domd/domd_cfg_h3ulcb.c @@ -473,6 +473,7 @@ static int load_ipl_image(uint8_t* buf, size_t bufsize, uint64_t image_load_offs static ssize_t get_ipl_image_size(void* image_info, uint64_t* size) { ARG_UNUSED(image_info); + // cppcheck-suppress comparePointers *size = __img_ipl_end - __img_ipl_start; return 0; } diff --git a/src/domains/domd/domd_cfg_salvator_xs.c b/src/domains/domd/domd_cfg_salvator_xs.c index 9027249c..a3311eeb 100644 --- a/src/domains/domd/domd_cfg_salvator_xs.c +++ b/src/domains/domd/domd_cfg_salvator_xs.c @@ -495,6 +495,7 @@ static int load_ipl_image(uint8_t* buf, size_t bufsize, uint64_t image_load_offs static ssize_t get_ipl_image_size(void* image_info, uint64_t* size) { ARG_UNUSED(image_info); + // cppcheck-suppress comparePointers *size = __img_ipl_end - __img_ipl_start; return 0; } diff --git a/src/domains/domd/domd_cfg_spider.c b/src/domains/domd/domd_cfg_spider.c index 2537dd90..36acc26e 100644 --- a/src/domains/domd/domd_cfg_spider.c +++ b/src/domains/domd/domd_cfg_spider.c @@ -276,6 +276,7 @@ static int load_ipl_image(uint8_t* buf, size_t bufsize, uint64_t image_load_offs static ssize_t get_ipl_image_size(void* image_info, uint64_t* size) { ARG_UNUSED(image_info); + // cppcheck-suppress comparePointers *size = __img_ipl_end - __img_ipl_start; return 0; } diff --git a/src/domains/domu/domu_cfg.c b/src/domains/domu/domu_cfg.c index 8d64c6a9..6963eae1 100644 --- a/src/domains/domu/domu_cfg.c +++ b/src/domains/domu/domu_cfg.c @@ -30,6 +30,7 @@ static int load_domu_image(uint8_t* buf, size_t bufsize, uint64_t image_load_off static ssize_t get_domu_image_size(void* image_info, uint64_t* size) { ARG_UNUSED(image_info); + // cppcheck-suppress comparePointers *size = __img_domu_end - __img_domu_start; return 0; } diff --git a/src/downloader/downloader.cpp b/src/downloader/downloader.cpp index e0fde970..f086a55b 100644 --- a/src/downloader/downloader.cpp +++ b/src/downloader/downloader.cpp @@ -34,6 +34,7 @@ aos::Error Downloader::Init(DownloadRequesterItf& downloadRequester) return aos::ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction aos::Error Downloader::Download(const aos::String& url, const aos::String& path, aos::DownloadContent contentType) { aos::UniqueLock lock(mMutex); diff --git a/src/main.cpp b/src/main.cpp index 4fdf197f..03d9795b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,6 +13,8 @@ #include "app/app.hpp" #include "logger/logger.hpp" + +// cppcheck-suppress missingInclude #include "version.hpp" #if !defined(CONFIG_NATIVE_APPLICATION) diff --git a/src/monitoring/resourceusageprovider.cpp b/src/monitoring/resourceusageprovider.cpp index c25f5c96..b992a96c 100644 --- a/src/monitoring/resourceusageprovider.cpp +++ b/src/monitoring/resourceusageprovider.cpp @@ -68,6 +68,7 @@ aos::Error ResourceUsageProvider::GetNodeInfo(aos::monitoring::NodeInfo& nodeInf return aos::ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction aos::Error ResourceUsageProvider::GetNodeMonitoringData( const aos::String& nodeID, aos::monitoring::MonitoringData& monitoringData) { @@ -93,8 +94,8 @@ aos::Error ResourceUsageProvider::GetNodeMonitoringData( monitoringData.mCPU = ((cpuTimeDiff_ns / 10.0) / us_elapsed); } - LOG_DBG() << "Get node monitoring data: " - << "RAM(K): " << (monitoringData.mRAM / 1024) << ", CPU: " << monitoringData.mCPU; + LOG_DBG() << "Get node monitoring data: RAM(K): " << (monitoringData.mRAM / 1024) + << ", CPU: " << monitoringData.mCPU; mPrevNodeCPUTime = domain.cpu_ns; mPrevTime = curTime; @@ -116,6 +117,7 @@ aos::Error ResourceUsageProvider::GetNodeMonitoringData( return aos::ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction aos::Error ResourceUsageProvider::GetInstanceMonitoringData( const aos::String& instanceID, aos::monitoring::MonitoringData& monitoringData) { diff --git a/src/ocispec/ocispec.cpp b/src/ocispec/ocispec.cpp index b89bc5ca..6ffe1fc4 100644 --- a/src/ocispec/ocispec.cpp +++ b/src/ocispec/ocispec.cpp @@ -89,6 +89,7 @@ static const struct json_obj_descr RuntimeSpecDescr[] = { * Public **********************************************************************************************************************/ +// cppcheck-suppress unusedFunction aos::Error OCISpec::LoadImageManifest(const aos::String& path, aos::oci::ImageManifest& manifest) { aos::LockGuard lock(mMutex); @@ -182,6 +183,7 @@ aos::Error OCISpec::LoadImageManifest(const aos::String& path, aos::oci::ImageMa return aos::ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction aos::Error OCISpec::SaveImageManifest(const aos::String& path, const aos::oci::ImageManifest& manifest) { aos::LockGuard lock(mMutex); @@ -261,6 +263,7 @@ aos::Error OCISpec::SaveImageManifest(const aos::String& path, const aos::oci::I return aos::ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction aos::Error OCISpec::LoadImageSpec(const aos::String& path, aos::oci::ImageSpec& imageSpec) { aos::LockGuard lock(mMutex); @@ -305,6 +308,7 @@ aos::Error OCISpec::LoadImageSpec(const aos::String& path, aos::oci::ImageSpec& return aos::ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction aos::Error OCISpec::SaveImageSpec(const aos::String& path, const aos::oci::ImageSpec& imageSpec) { aos::LockGuard lock(mMutex); @@ -360,6 +364,7 @@ aos::Error OCISpec::SaveImageSpec(const aos::String& path, const aos::oci::Image return aos::ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction aos::Error OCISpec::LoadRuntimeSpec(const aos::String& path, aos::oci::RuntimeSpec& runtimeSpec) { aos::LockGuard lock(mMutex); @@ -470,6 +475,7 @@ aos::Error OCISpec::LoadRuntimeSpec(const aos::String& path, aos::oci::RuntimeSp return aos::ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction aos::Error OCISpec::SaveRuntimeSpec(const aos::String& path, const aos::oci::RuntimeSpec& runtimeSpec) { aos::LockGuard lock(mMutex); diff --git a/src/runner/runner.cpp b/src/runner/runner.cpp index e3418cf1..26a6563c 100644 --- a/src/runner/runner.cpp +++ b/src/runner/runner.cpp @@ -25,6 +25,7 @@ aos::Error Runner::Init(RunStatusReceiverItf& statusReceiver) return aos::ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction RunStatus Runner::StartInstance(const aos::String& instanceID, const aos::String& runtimeDir) { RunStatus runStatus {instanceID, aos::InstanceRunStateEnum::eActive, aos::ErrorEnum::eNone}; @@ -38,6 +39,7 @@ RunStatus Runner::StartInstance(const aos::String& instanceID, const aos::String return runStatus; } +// cppcheck-suppress unusedFunction aos::Error Runner::StopInstance(const aos::String& instanceID) { auto ret = xrun_kill(instanceID.CStr()); diff --git a/src/storage/storage.cpp b/src/storage/storage.cpp index 70aa1a21..8d7b41fb 100644 --- a/src/storage/storage.cpp +++ b/src/storage/storage.cpp @@ -44,6 +44,7 @@ aos::Error Storage::Init() return aos::ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction aos::Error Storage::AddInstance(const aos::InstanceInfo& instance) { aos::LockGuard lock(mMutex); @@ -58,6 +59,7 @@ aos::Error Storage::AddInstance(const aos::InstanceInfo& instance) }); } +// cppcheck-suppress unusedFunction aos::Error Storage::UpdateInstance(const aos::InstanceInfo& instance) { aos::LockGuard lock(mMutex); @@ -75,6 +77,7 @@ aos::Error Storage::UpdateInstance(const aos::InstanceInfo& instance) return aos::ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction aos::Error Storage::RemoveInstance(const aos::InstanceIdent& instanceIdent) { aos::LockGuard lock(mMutex); @@ -90,6 +93,7 @@ aos::Error Storage::RemoveInstance(const aos::InstanceIdent& instanceIdent) return aos::ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction aos::Error Storage::GetAllInstances(aos::Array& instances) { aos::LockGuard lock(mMutex); @@ -110,6 +114,7 @@ aos::Error Storage::GetAllInstances(aos::Array& instances) return err; } +// cppcheck-suppress unusedFunction aos::Error Storage::AddService(const aos::sm::servicemanager::ServiceData& service) { aos::LockGuard lock(mMutex); @@ -124,6 +129,7 @@ aos::Error Storage::AddService(const aos::sm::servicemanager::ServiceData& servi }); } +// cppcheck-suppress unusedFunction aos::Error Storage::UpdateService(const aos::sm::servicemanager::ServiceData& service) { aos::LockGuard lock(mMutex); @@ -147,6 +153,7 @@ aos::Error Storage::RemoveService(const aos::String& serviceID, uint64_t aosVers }); } +// cppcheck-suppress unusedFunction aos::Error Storage::GetAllServices(aos::Array& services) { aos::LockGuard lock(mMutex); @@ -167,6 +174,7 @@ aos::Error Storage::GetAllServices(aos::Array Storage::GetService(const aos::String& serviceID) { aos::LockGuard lock(mMutex); @@ -187,6 +195,7 @@ aos::RetWithError Storage::GetService(cons return aos::RetWithError(*retServiceData); } +// cppcheck-suppress unusedFunction aos::Error Storage::AddCertInfo(const aos::String& certType, const aos::iam::certhandler::CertInfo& certInfo) { aos::LockGuard lock(mMutex); @@ -205,6 +214,7 @@ aos::Error Storage::AddCertInfo(const aos::String& certType, const aos::iam::cer }); } +// cppcheck-suppress unusedFunction aos::Error Storage::RemoveCertInfo(const aos::String& certType, const aos::String& certURL) { aos::LockGuard lock(mMutex); @@ -215,6 +225,7 @@ aos::Error Storage::RemoveCertInfo(const aos::String& certType, const aos::Strin [&certType, &certURL](const CertInfo& data) { return data.mCertType == certType && data.mCertURL == certURL; }); } +// cppcheck-suppress unusedFunction aos::Error Storage::RemoveAllCertsInfo(const aos::String& certType) { aos::LockGuard lock(mMutex); @@ -229,6 +240,7 @@ aos::Error Storage::RemoveAllCertsInfo(const aos::String& certType) return aos::ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction aos::Error Storage::GetCertsInfo(const aos::String& certType, aos::Array& certsInfo) { aos::LockGuard lock(mMutex); @@ -251,6 +263,7 @@ aos::Error Storage::GetCertsInfo(const aos::String& certType, aos::Array& issuer, const aos::Array& serial, aos::iam::certhandler::CertInfo& cert) { From c788d80a131660ec27a4282f52189b4ea3825eeb Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Tue, 14 May 2024 17:59:11 +0300 Subject: [PATCH 003/198] [common] Replace cVendorVersionLen with cVersionLen Signed-off-by: Mykhailo Lohvynenko --- src/communication/cmclient.cpp | 4 ++-- src/storage/storage.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/communication/cmclient.cpp b/src/communication/cmclient.cpp index 2126bdc0..55af996f 100644 --- a/src/communication/cmclient.cpp +++ b/src/communication/cmclient.cpp @@ -301,7 +301,7 @@ aos::Error CMClient::ProcessGetUnitConfigStatus(Channel channel, uint64_t reques outgoingMessage->which_SMOutgoingMessage = servicemanager_v3_SMOutgoingMessages_unit_config_status_tag; pbConfigStatus = servicemanager_v3_UnitConfigStatus_init_default; - aos::StaticString version; + aos::StaticString version; auto err = mResourceManager->GetUnitConfigInfo(version); if (!err.IsNone()) { @@ -338,7 +338,7 @@ aos::Error CMClient::ProcessCheckUnitConfig( ErrorToPB(err, pbConfigStatus.error); } - aos::StaticString version; + aos::StaticString version; PBToString(pbUnitConfig.vendor_version, version); StringToPB(version, pbConfigStatus.vendor_version); diff --git a/src/storage/storage.hpp b/src/storage/storage.hpp index 41a5d49d..d9bfebe4 100644 --- a/src/storage/storage.hpp +++ b/src/storage/storage.hpp @@ -192,7 +192,7 @@ class Storage : public aos::sm::launcher::StorageItf, struct VersionInfo { uint64_t mAosVersion; - char mVendorVersion[aos::cVendorVersionLen + 1]; + char mVendorVersion[aos::cVersionLen + 1]; char mDescription[aos::cDescriptionLen + 1]; /** From 6c95ec3cfed6e442888e5607d69abaea28b4c442 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Wed, 5 Jun 2024 14:22:02 +0300 Subject: [PATCH 004/198] [west.yaml] Switch to develop repos Signed-off-by: Mykhailo Lohvynenko --- west.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/west.yml b/west.yml index e0ff7087..b6563425 100644 --- a/west.yml +++ b/west.yml @@ -24,40 +24,40 @@ manifest: projects: - name: zephyr remote: xen-troops - revision: "zephyr/v3.6.0/xt-v2.0.0" + revision: "zephyr-v3.6.0-xt" west-commands: scripts/west-commands.yml - name: aos_core_lib_cpp remote: aosedge - revision: "v0.3.3" + revision: "develop" - name: aos_core_api remote: aosedge - revision: "v7.3.3" + revision: "develop" - name: zephyr-xenlib remote: xen-troops - revision: "v2.1.1" + revision: "main" - name: zephyr-optee-client remote: xen-troops - revision: "v0.0.1" + revision: "master" - name: littlefs remote: zephyrproject-rtos - revision: "408c16a909dd6cf128874a76f21c793798c9e423" + revision: "zephyr" path: modules/fs/littlefs groups: - fs - name: nanopb remote: zephyrproject-rtos - revision: "65cbefb4695bc7af1cb733ced99618afb3586b20" + revision: "zephyr" path: modules/lib/nanopb - name: mbedtls remote: zephyrproject-rtos - revision: "3217c450180fd5e817601c6f479116de69e57461" + revision: "zephyr" path: modules/crypto/mbedtls groups: - crypto From 3c4a47ca0995e20f045d1e47caf5c8116b76a487 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 6 Jun 2024 12:43:15 +0300 Subject: [PATCH 005/198] [ci] Fix protobuf issue with latest zephyr CI update Signed-off-by: Oleksandr Grytsov --- .github/workflows/build_test.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_test.yaml b/.github/workflows/build_test.yaml index 36e6b56d..94d2b710 100644 --- a/.github/workflows/build_test.yaml +++ b/.github/workflows/build_test.yaml @@ -37,6 +37,7 @@ jobs: - name: Initialize run: | sudo apt update + pip install --upgrade protobuf==4.25.3 ln -ns /opt/protoc/include/google /usr/local/include west init -l ./ west update From 20d508b4ae7e05cec286d135d5097b41d1499420 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Thu, 18 Apr 2024 17:54:42 +0300 Subject: [PATCH 006/198] [resourcemanager] Implement and use aos_core_lib resource manager Signed-off-by: Mykhailo Lohvynenko --- src/app/app.cpp | 6 + src/app/app.hpp | 54 ++++--- src/communication/cmclient.cpp | 9 +- src/communication/cmclient.hpp | 15 +- src/communication/communication.cpp | 4 +- src/communication/communication.hpp | 5 +- src/resourcemanager/log.hpp | 8 +- src/resourcemanager/resourcemanager.cpp | 149 +++++++++++++----- src/resourcemanager/resourcemanager.hpp | 127 +++++++++------ tests/communication/src/cmclient.cpp | 5 +- .../src/stubs/resourcemanagerstub.hpp | 70 ++++++-- tests/resourcemanager/CMakeLists.txt | 33 ++++ tests/resourcemanager/Kconfig | 16 ++ tests/resourcemanager/prj.conf | 9 ++ tests/resourcemanager/src/main.cpp | 68 ++++++++ tests/resourcemanager/testcase.yaml | 6 + 16 files changed, 443 insertions(+), 141 deletions(-) create mode 100644 tests/resourcemanager/CMakeLists.txt create mode 100644 tests/resourcemanager/Kconfig create mode 100644 tests/resourcemanager/prj.conf create mode 100644 tests/resourcemanager/src/main.cpp create mode 100644 tests/resourcemanager/testcase.yaml diff --git a/src/app/app.cpp b/src/app/app.cpp index 80705617..ead0f8d4 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -149,6 +149,12 @@ aos::Error App::InitCommunication() return err; } + if (!(err = mResourceManager.Init( + mResourceManagerJSONProvider, mHostDeviceManager, mHostGroupManager, cNodeType, cUnitConfigFile)) + .IsNone()) { + return err; + } + if (!(err = mCommunication.Init(mOpenVChannel, mSecureTLSChannel, mLauncher, mCertHandler, mResourceManager, mResourceMonitor, mDownloader, mClockSync, mProvisioning)) .IsNone()) { diff --git a/src/app/app.hpp b/src/app/app.hpp index e7d11f44..cdb7dd0b 100644 --- a/src/app/app.hpp +++ b/src/app/app.hpp @@ -24,6 +24,7 @@ #include "monitoring/resourceusageprovider.hpp" #include "ocispec/ocispec.hpp" #include "provisioning/provisioning.hpp" +#include "resourcemanager/resourcemanager.hpp" #include "runner/runner.hpp" #include "storage/storage.hpp" @@ -49,34 +50,39 @@ class App : private aos::NonCopyable { static constexpr auto cPKCS11ModuleLibrary = AOS_CONFIG_CRYPTOUTILS_DEFAULT_PKCS11_LIB; static constexpr auto cPKCS11ModuleTokenLabel = "aoscore"; static constexpr auto cPKCS11ModulePinFile = CONFIG_AOS_PKCS11_MODULE_PIN_FILE; + static constexpr auto cNodeType = CONFIG_AOS_NODE_TYPE; + static constexpr auto cUnitConfigFile = CONFIG_AOS_UNIT_CONFIG_FILE; aos::Error InitCertHandler(); aos::Error InitCommunication(); - static App sApp; - aos::monitoring::ResourceMonitor mResourceMonitor; - aos::sm::launcher::Launcher mLauncher; - aos::sm::servicemanager::ServiceManager mServiceManager; - aos::iam::certhandler::CertModule mIAMCertModule; - aos::iam::certhandler::PKCS11Module mIAMHSMModule; - aos::iam::certhandler::CertModule mSMCertModule; - aos::iam::certhandler::PKCS11Module mSMHSMModule; - aos::iam::certhandler::CertHandler mCertHandler; - aos::crypto::MbedTLSCryptoProvider mCryptoProvider; - aos::cryptoutils::CertLoader mCertLoader; - aos::pkcs11::PKCS11Manager mPKCS11Manager; - ClockSync mClockSync; - Communication mCommunication; - VChannel mOpenVChannel; - VChannel mSecureVChannel; - TLSChannel mSecureTLSChannel; - Downloader mDownloader; - OCISpec mJsonOciSpec; - ResourceManager mResourceManager; - ResourceUsageProvider mResourceUsageProvider; - Runner mRunner; - Storage mStorage; - Provisioning mProvisioning; + static App sApp; + aos::monitoring::ResourceMonitor mResourceMonitor; + aos::sm::launcher::Launcher mLauncher; + aos::sm::servicemanager::ServiceManager mServiceManager; + aos::iam::certhandler::CertModule mIAMCertModule; + aos::iam::certhandler::PKCS11Module mIAMHSMModule; + aos::iam::certhandler::CertModule mSMCertModule; + aos::iam::certhandler::PKCS11Module mSMHSMModule; + aos::iam::certhandler::CertHandler mCertHandler; + aos::crypto::MbedTLSCryptoProvider mCryptoProvider; + aos::cryptoutils::CertLoader mCertLoader; + aos::pkcs11::PKCS11Manager mPKCS11Manager; + ClockSync mClockSync; + Communication mCommunication; + VChannel mOpenVChannel; + VChannel mSecureVChannel; + TLSChannel mSecureTLSChannel; + Downloader mDownloader; + OCISpec mJsonOciSpec; + ResourceManagerJSONProvider mResourceManagerJSONProvider; + HostDeviceManager mHostDeviceManager; + HostGroupManager mHostGroupManager; + aos::sm::resourcemanager::ResourceManager mResourceManager; + ResourceUsageProvider mResourceUsageProvider; + Runner mRunner; + Storage mStorage; + Provisioning mProvisioning; }; #endif diff --git a/src/communication/cmclient.cpp b/src/communication/cmclient.cpp index 55af996f..3c01a6a0 100644 --- a/src/communication/cmclient.cpp +++ b/src/communication/cmclient.cpp @@ -55,9 +55,9 @@ static void MonitoringDataToPB( * Public **********************************************************************************************************************/ -aos::Error CMClient::Init(aos::sm::launcher::LauncherItf& launcher, ResourceManagerItf& resourceManager, - aos::monitoring::ResourceMonitorItf& resourceMonitor, DownloadReceiverItf& downloader, ClockSyncItf& clockSync, - MessageSenderItf& messageSender) +aos::Error CMClient::Init(aos::sm::launcher::LauncherItf& launcher, + aos::sm::resourcemanager::ResourceManagerItf& resourceManager, aos::monitoring::ResourceMonitorItf& resourceMonitor, + DownloadReceiverItf& downloader, ClockSyncItf& clockSync, MessageSenderItf& messageSender) { LOG_DBG() << "Initialize CM client"; @@ -301,9 +301,10 @@ aos::Error CMClient::ProcessGetUnitConfigStatus(Channel channel, uint64_t reques outgoingMessage->which_SMOutgoingMessage = servicemanager_v3_SMOutgoingMessages_unit_config_status_tag; pbConfigStatus = servicemanager_v3_UnitConfigStatus_init_default; + aos::Error err; aos::StaticString version; - auto err = mResourceManager->GetUnitConfigInfo(version); + aos::Tie(version, err) = mResourceManager->GetVersion(); if (!err.IsNone()) { err = AOS_ERROR_WRAP(err); ErrorToPB(err, pbConfigStatus.error); diff --git a/src/communication/cmclient.hpp b/src/communication/cmclient.hpp index a9e186ca..3004f7a5 100644 --- a/src/communication/cmclient.hpp +++ b/src/communication/cmclient.hpp @@ -10,12 +10,12 @@ #include #include +#include #include #include "clocksync/clocksync.hpp" #include "downloader/downloader.hpp" -#include "resourcemanager/resourcemanager.hpp" #include "messagehandler.hpp" @@ -46,7 +46,8 @@ class CMClient : public MessageHandler + #include "communication.hpp" #include "log.hpp" @@ -51,7 +53,7 @@ Communication::~Communication() aos::Error Communication::Init(CommChannelItf& openChannel, CommChannelItf& secureChannel, aos::sm::launcher::LauncherItf& launcher, aos::iam::certhandler::CertHandlerItf& certHandler, - ResourceManagerItf& resourceManager, aos::monitoring::ResourceMonitorItf& resourceMonitor, + aos::sm::resourcemanager::ResourceManagerItf& resourceManager, aos::monitoring::ResourceMonitorItf& resourceMonitor, DownloadReceiverItf& downloader, ClockSyncItf& clockSync, ProvisioningItf& provisioning) { LOG_DBG() << "Initialize communication"; diff --git a/src/communication/communication.hpp b/src/communication/communication.hpp index 0ed83e44..a526d672 100644 --- a/src/communication/communication.hpp +++ b/src/communication/communication.hpp @@ -44,8 +44,9 @@ class Communication : public aos::sm::launcher::InstanceStatusReceiverItf, */ aos::Error Init(CommChannelItf& openChannel, CommChannelItf& secureChannel, aos::sm::launcher::LauncherItf& launcher, aos::iam::certhandler::CertHandlerItf& certHandler, - ResourceManagerItf& resourceManager, aos::monitoring::ResourceMonitorItf& resourceMonitor, - DownloadReceiverItf& downloader, ClockSyncItf& clockSync, ProvisioningItf& provisioning); + aos::sm::resourcemanager::ResourceManagerItf& resourceManager, + aos::monitoring::ResourceMonitorItf& resourceMonitor, DownloadReceiverItf& downloader, ClockSyncItf& clockSync, + ProvisioningItf& provisioning); /** * Destructor. diff --git a/src/resourcemanager/log.hpp b/src/resourcemanager/log.hpp index e0cd031c..3a2ae615 100644 --- a/src/resourcemanager/log.hpp +++ b/src/resourcemanager/log.hpp @@ -10,9 +10,9 @@ #include "logger/logger.hpp" -#define LOG_DBG() LOG_MODULE_DBG(static_cast(Logger::Module::eResourceMgr)) -#define LOG_INF() LOG_MODULE_INF(static_cast(Logger::Module::eResourceMgr)) -#define LOG_WRN() LOG_MODULE_WRN(static_cast(Logger::Module::eResourceMgr)) -#define LOG_ERR() LOG_MODULE_ERR(static_cast(Logger::Module::eResourceMgr)) +#define LOG_DBG() LOG_MODULE_DBG(aos::LogModuleEnum::eSMResourceManager) +#define LOG_INF() LOG_MODULE_INF(aos::LogModuleEnum::eSMResourceManager) +#define LOG_WRN() LOG_MODULE_WRN(aos::LogModuleEnum::eSMResourceManager) +#define LOG_ERR() LOG_MODULE_ERR(aos::LogModuleEnum::eSMResourceManager) #endif diff --git a/src/resourcemanager/resourcemanager.cpp b/src/resourcemanager/resourcemanager.cpp index 7ea1c61a..2c834f80 100644 --- a/src/resourcemanager/resourcemanager.cpp +++ b/src/resourcemanager/resourcemanager.cpp @@ -5,67 +5,144 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - -#include -#include +#include #include "log.hpp" #include "resourcemanager.hpp" +/*********************************************************************************************************************** + * Static + **********************************************************************************************************************/ + +static const struct json_obj_descr cUnitConfigDescr[] = { + JSON_OBJ_DESCR_PRIM(UnitConfig, vendorVersion, JSON_TOK_STRING), + JSON_OBJ_DESCR_PRIM(UnitConfig, nodeType, JSON_TOK_STRING), + JSON_OBJ_DESCR_PRIM(UnitConfig, priority, JSON_TOK_NUMBER), +}; + +/*********************************************************************************************************************** + * ResourceManagerJSONProvider + **********************************************************************************************************************/ /*********************************************************************************************************************** * Public **********************************************************************************************************************/ -aos::Error ResourceManager::GetUnitConfigInfo(aos::String& version) const +// cppcheck-suppress unusedFunction +aos::Error ResourceManagerJSONProvider::DumpUnitConfig( + const aos::sm::resourcemanager::UnitConfig& nodeUnitConfig, aos::String& json) const { - aos::Error err = aos::ErrorEnum::eNone; + aos::LockGuard lock(mMutex); - auto file = open(cUnitConfigFilePath, O_RDONLY); - if (file < 0) { - return AOS_ERROR_WRAP(errno); - } + mAllocator.Clear(); + + auto jsonUnitConfig = aos::MakeUnique(&mAllocator); - auto ret = read(file, version.Get(), version.MaxSize()); + jsonUnitConfig->vendorVersion = nodeUnitConfig.mVendorVersion.CStr(); + jsonUnitConfig->nodeType = nodeUnitConfig.mNodeUnitConfig.mNodeType.CStr(); + jsonUnitConfig->priority = nodeUnitConfig.mNodeUnitConfig.mPriority; + + auto ret = json_obj_encode_buf( + cUnitConfigDescr, ARRAY_SIZE(cUnitConfigDescr), jsonUnitConfig.Get(), json.Get(), json.MaxSize()); if (ret < 0) { - err = AOS_ERROR_WRAP(errno); - } else { - version.Resize(ret); + return AOS_ERROR_WRAP(ret); } - ret = close(file); - if (err.IsNone() && (ret < 0)) { - err = AOS_ERROR_WRAP(errno); + auto err = json.Resize(strlen(json.CStr())); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); } - return err; + return aos::ErrorEnum::eNone; } -aos::Error ResourceManager::CheckUnitConfig(const aos::String& version, const aos::String& unitConfig) const +// cppcheck-suppress unusedFunction +aos::Error ResourceManagerJSONProvider::ParseNodeUnitConfig( + const aos::String& json, aos::sm::resourcemanager::UnitConfig& nodeUnitConfig) const { + aos::LockGuard lock(mMutex); + + mAllocator.Clear(); + + // json_object_parse mutates the input string, so we need to copy it + mJSONBuffer = json; + + auto parsedUnitConfig = aos::MakeUnique(&mAllocator); + + auto ret = json_obj_parse( + mJSONBuffer.Get(), mJSONBuffer.Size(), cUnitConfigDescr, ARRAY_SIZE(cUnitConfigDescr), parsedUnitConfig.Get()); + if (ret < 0) { + return AOS_ERROR_WRAP(ret); + } + + nodeUnitConfig.mVendorVersion = parsedUnitConfig->vendorVersion; + nodeUnitConfig.mNodeUnitConfig.mNodeType = parsedUnitConfig->nodeType; + nodeUnitConfig.mNodeUnitConfig.mPriority = parsedUnitConfig->priority; + return aos::ErrorEnum::eNone; } -aos::Error ResourceManager::UpdateUnitConfig(const aos::String& version, const aos::String& unitConfig) +/*********************************************************************************************************************** + * HostDeviceManager + **********************************************************************************************************************/ +/*********************************************************************************************************************** + * Public + **********************************************************************************************************************/ + +// cppcheck-suppress unusedFunction +aos::Error HostDeviceManager::AllocateDevice(const aos::DeviceInfo& deviceInfo, const aos::String& instanceID) { - aos::Error err = aos::ErrorEnum::eNone; + (void)deviceInfo; + (void)instanceID; - auto file = open(cUnitConfigFilePath, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); - if (file < 0) { - return AOS_ERROR_WRAP(errno); - } + return aos::ErrorEnum::eNone; +} - auto written = write(file, version.Get(), version.Size()); - if (written < 0) { - err = AOS_ERROR_WRAP(written); - } else if ((size_t)written != version.Size()) { - err = AOS_ERROR_WRAP(aos::ErrorEnum::eRuntime); - } +// cppcheck-suppress unusedFunction +aos::Error HostDeviceManager::RemoveInstanceFromDevice(const aos::String& deviceName, const aos::String& instanceID) +{ + (void)deviceName; + (void)instanceID; - auto ret = close(file); - if (err.IsNone() && (ret < 0)) { - err = AOS_ERROR_WRAP(errno); - } + return aos::ErrorEnum::eNone; +} + +// cppcheck-suppress unusedFunction +aos::Error HostDeviceManager::RemoveInstanceFromAllDevices(const aos::String& instanceID) +{ + (void)instanceID; + + return aos::ErrorEnum::eNone; +} + +// cppcheck-suppress unusedFunction +aos::Error HostDeviceManager::GetDeviceInstances( + const aos::String& deviceName, aos::Array>& instanceIDs) const +{ + (void)deviceName; + (void)instanceIDs; + + return aos::ErrorEnum::eNone; +} + +// cppcheck-suppress unusedFunction +bool HostDeviceManager::DeviceExists(const aos::String& device) const +{ + (void)device; + + return false; +} + +/*********************************************************************************************************************** + * HostGroupManager + **********************************************************************************************************************/ +/*********************************************************************************************************************** + * Public + **********************************************************************************************************************/ + +// cppcheck-suppress unusedFunction +bool HostGroupManager::GroupExists(const aos::String& group) const +{ + (void)group; - return err; + return false; } diff --git a/src/resourcemanager/resourcemanager.hpp b/src/resourcemanager/resourcemanager.hpp index 334e51b0..2ab4050e 100644 --- a/src/resourcemanager/resourcemanager.hpp +++ b/src/resourcemanager/resourcemanager.hpp @@ -1,88 +1,121 @@ /* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 */ -#ifndef RESOURCEMANAGER_HPP_ -#define RESOURCEMANAGER_HPP_ +#ifndef RESOURCE_MANAGER_HPP_ +#define RESOURCE_MANAGER_HPP_ -#include -#include +#include + +#include +#include /** - * Resource manager interface. + * Node unit config. */ +struct UnitConfig { + const char* vendorVersion = ""; + const char* nodeType = ""; + uint32_t priority = 0; +}; -class ResourceManagerItf { +class ResourceManagerJSONProvider : public aos::sm::resourcemanager::JSONProviderItf { public: /** - * Destructor + * Dumps node unit config object from json string. + * + * @param nodeUnitConfig node unit config object. + * @param[out] json json representation of node unit config. + * @return Error. */ - virtual ~ResourceManagerItf() = default; + aos::Error DumpUnitConfig( + const aos::sm::resourcemanager::UnitConfig& nodeUnitConfig, aos::String& json) const override; /** - * Get current unit config version. + * Parses node unit config json string from object. * - * @param[out] version param to store version. - * @return aos::Error. + * @param json json representation of node unit config. + * @param[out] nodeUnitConfig node unit config. + * @return Error. */ - virtual aos::Error GetUnitConfigInfo(aos::String& version) const = 0; + aos::Error ParseNodeUnitConfig( + const aos::String& json, aos::sm::resourcemanager::UnitConfig& nodeUnitConfig) const override; + +private: + static constexpr size_t cJsonMaxContentLen = 1024; + static constexpr size_t cAllocationSize = 2048; + static constexpr size_t cMaxNumAllocations = 32; + + mutable aos::Mutex mMutex; + mutable aos::StaticString mJSONBuffer; + mutable aos::StaticAllocator mAllocator; +}; +/** + * Host device manager. + */ +class HostDeviceManager : public aos::sm::resourcemanager::HostDeviceManagerItf { +public: /** - * Check new unit configuration. + * Allocates device for instance. * - * @param version unit config version - * @param unitConfig string with unit configuration. - * @return aos::Error. + * @param deviceInfo device info. + * @param instanceID instance ID. + * @return Error. */ - virtual aos::Error CheckUnitConfig(const aos::String& version, const aos::String& unitConfig) const = 0; + aos::Error AllocateDevice(const aos::DeviceInfo& deviceInfo, const aos::String& instanceID) override; /** - * Update unit configuration. + * Removes instance from device. * - * @param version unit config version. - * @param unitConfig string with unit configuration. - * @return aos::Error. + * @param deviceName device name. + * @param instanceID instance ID. + * @return Error. */ - virtual aos::Error UpdateUnitConfig(const aos::String& version, const aos::String& unitConfig) = 0; -}; + aos::Error RemoveInstanceFromDevice(const aos::String& deviceName, const aos::String& instanceID) override; -/** - * Resource manager instance. - */ - -class ResourceManager : public ResourceManagerItf, private aos::NonCopyable { -public: /** - * Get current unit config version. + * Removes instance from all devices. * - * @param[out] version param to store version. - * @return aos::Error. + * @param instanceID instance ID. + * @return Error. */ - aos::Error GetUnitConfigInfo(aos::String& version) const override; + aos::Error RemoveInstanceFromAllDevices(const aos::String& instanceID) override; /** - * Check new unit configuration. + * Returns ID list of instances that allocate specific device. * - * @param version unit config version - * @param unitConfig string with unit configuration. - * @return aos::Error. + * @param deviceName device name. + * @param instances[out] param to store instance ID(s). + * @return Error. */ - aos::Error CheckUnitConfig(const aos::String& version, const aos::String& unitConfig) const override; + aos::Error GetDeviceInstances( + const aos::String& deviceName, aos::Array>& instanceIDs) const override; /** - * Update unit configuration. + * Checks if device exists. * - * @param version unit config version. - * @param unitConfig string with unit configuration. - * @return aos::Error. + * @param device device name. + * @return true if device exists, false otherwise. */ - aos::Error UpdateUnitConfig(const aos::String& version, const aos::String& unitConfig) override; + bool DeviceExists(const aos::String& device) const override; +}; -private: - static constexpr auto cUnitConfigFilePath = CONFIG_AOS_UNIT_CONFIG_FILE; +/** + * Host group manager. + */ +class HostGroupManager : public aos::sm::resourcemanager::HostGroupManagerItf { +public: + /** + * Checks if group exists. + * + * @param group group name. + * @return true if group exists, false otherwise. + */ + bool GroupExists(const aos::String& group) const override; }; #endif diff --git a/tests/communication/src/cmclient.cpp b/tests/communication/src/cmclient.cpp index c9a285d6..d9a7a011 100644 --- a/tests/communication/src/cmclient.cpp +++ b/tests/communication/src/cmclient.cpp @@ -276,8 +276,11 @@ ZTEST_F(cmclient, test_SetUnitConfig) zassert_equal(outgoingMessage.which_SMOutgoingMessage, servicemanager_v3_SMOutgoingMessages_unit_config_status_tag); zassert_equal(strcmp(outgoingMessage.SMOutgoingMessage.unit_config_status.vendor_version, version), 0); zassert_equal(strlen(outgoingMessage.SMOutgoingMessage.unit_config_status.error), 0); - zassert_equal(fixture->mResourceManager.GetVersion(), version); zassert_equal(fixture->mResourceManager.GetUnitConfig(), unitConfig); + + auto ret = fixture->mResourceManager.GetVersion(); + zassert_true(ret.mError.IsNone(), "Failed to get version: %s", ret.mError.Message()); + zassert_equal(ret.mValue, version); } ZTEST_F(cmclient, test_RunInstances) diff --git a/tests/communication/src/stubs/resourcemanagerstub.hpp b/tests/communication/src/stubs/resourcemanagerstub.hpp index 318331ec..9f0634b2 100644 --- a/tests/communication/src/stubs/resourcemanagerstub.hpp +++ b/tests/communication/src/stubs/resourcemanagerstub.hpp @@ -8,16 +8,11 @@ #ifndef RESOURCEMANAGERSTUB_HPP_ #define RESOURCEMANAGERSTUB_HPP_ -#include "resourcemanager/resourcemanager.hpp" +#include -class ResourceManagerStub : public ResourceManagerItf { +class ResourceManagerStub : public aos::sm::resourcemanager::ResourceManagerItf { public: - aos::Error GetUnitConfigInfo(aos::String& version) const override - { - version = mVersion.c_str(); - - return mError; - } + aos::RetWithError> GetVersion() const override { return {mVersion, mError}; } aos::Error CheckUnitConfig(const aos::String& version, const aos::String& unitConfig) const override { @@ -26,29 +21,74 @@ class ResourceManagerStub : public ResourceManagerItf { aos::Error UpdateUnitConfig(const aos::String& version, const aos::String& unitConfig) override { - mVersion = version.CStr(); + mVersion = version; mUnitConfig = unitConfig.CStr(); return mError; }; - void SetError(const aos::Error& err) { mError = err; } + aos::Error GetDeviceInfo(const aos::String& deviceName, aos::DeviceInfo& deviceInfo) const override + { + (void)deviceName; + (void)deviceInfo; + + return mError; + } + + aos::Error GetResourceInfo(const aos::String& resourceName, aos::ResourceInfo& resourceInfo) const override + { + (void)resourceName; + (void)resourceInfo; + + return mError; + } + + aos::Error AllocateDevice(const aos::String& deviceName, const aos::String& instanceID) override + { + (void)deviceName; + (void)instanceID; + + return mError; + } + + aos::Error ReleaseDevice(const aos::String& deviceName, const aos::String& instanceID) override + { + (void)deviceName; + (void)instanceID; + + return mError; + } + + aos::Error ReleaseDevices(const aos::String& instanceID) override + { + (void)instanceID; - const std::string& GetVersion() const { return mVersion; } + return mError; + } + aos::Error GetDeviceInstances( + const aos::String& deviceName, aos::Array>& instanceIDs) const override + { + (void)deviceName; + (void)instanceIDs; + + return mError; + } + + void SetError(const aos::Error& err) { mError = err; } const std::string& GetUnitConfig() const { return mUnitConfig; } void Clear() { - mVersion.clear(); + mVersion.Clear(); mUnitConfig.clear(); mError = aos::ErrorEnum::eNone; } private: - std::string mVersion; - std::string mUnitConfig; - aos::Error mError; + aos::StaticString mVersion; + std::string mUnitConfig; + aos::Error mError; }; #endif diff --git a/tests/resourcemanager/CMakeLists.txt b/tests/resourcemanager/CMakeLists.txt new file mode 100644 index 00000000..96caba15 --- /dev/null +++ b/tests/resourcemanager/CMakeLists.txt @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project(resourcemanager_test) + +# ###################################################################################################################### +# Config +# ###################################################################################################################### + +set(AOS_CORE_CONFIG aoscoreconfig.hpp) + +# ###################################################################################################################### +# Definitions +# ###################################################################################################################### + +# Aos core configuration +add_definitions(-include ${AOS_CORE_CONFIG}) + +# ###################################################################################################################### +# Includes +# ###################################################################################################################### + +target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../src) +target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../../aos_core_lib_cpp/include) +target_include_directories(app PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + +# ###################################################################################################################### +# Target +# ###################################################################################################################### + +target_sources(app PRIVATE src/main.cpp ../../src/resourcemanager/resourcemanager.cpp) diff --git a/tests/resourcemanager/Kconfig b/tests/resourcemanager/Kconfig new file mode 100644 index 00000000..d5a50da2 --- /dev/null +++ b/tests/resourcemanager/Kconfig @@ -0,0 +1,16 @@ +# Copyright (C) 2024 Renesas Electronics Corporation. +# Copyright (C) 2024 EPAM Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "Aos zephyr application" + +config AOS_NODE_TYPE + string "Node type" + default "NODE_TYPE1" + +config AOS_UNIT_CONFIG_FILE + string "Node configuration file path" + default "/aos/unit_config.cfg" + +source "Kconfig" diff --git a/tests/resourcemanager/prj.conf b/tests/resourcemanager/prj.conf new file mode 100644 index 00000000..927f0f8b --- /dev/null +++ b/tests/resourcemanager/prj.conf @@ -0,0 +1,9 @@ +# Enable C++ +CONFIG_CPP=y +CONFIG_STD_CPP14=y + +# Enable test suit +CONFIG_ZTEST=y + +# Enable JSON library +CONFIG_JSON_LIBRARY=y diff --git a/tests/resourcemanager/src/main.cpp b/tests/resourcemanager/src/main.cpp new file mode 100644 index 00000000..a2e08bdf --- /dev/null +++ b/tests/resourcemanager/src/main.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include + +#include "resourcemanager/resourcemanager.hpp" + +static constexpr auto cTestNodeConfigJSON = R"({"nodeType":"mainType","priority":1,"vendorVersion":"1.0"})"; + +static void TestLogCallback(aos::LogModule module, aos::LogLevel level, const aos::String& message) +{ + printk("[resourcemanager] %s \n", message.CStr()); +} + +ZTEST_SUITE(resourcemanager, NULL, NULL, NULL, NULL, NULL); + +ZTEST(resourcemanager, test_JSONProviderParse) +{ + aos::Log::SetCallback(TestLogCallback); + + ResourceManagerJSONProvider provider; + aos::sm::resourcemanager::UnitConfig unitConfig; + + aos::String jsonStr(cTestNodeConfigJSON); + auto err = provider.ParseNodeUnitConfig(jsonStr, unitConfig); + + zassert_true(err.IsNone(), "Failed to parse node unit config: %s", err.Message()); + zassert_equal(1, unitConfig.mNodeUnitConfig.mPriority, "Priority mismatch"); + zassert_true(strncmp("1.0", unitConfig.mVendorVersion.CStr(), unitConfig.mVendorVersion.Size()) == 0, + "File content mismatch"); + zassert_true( + strncmp("mainType", unitConfig.mNodeUnitConfig.mNodeType.CStr(), unitConfig.mNodeUnitConfig.mNodeType.Size()) + == 0, + "Node type mismatch"); +} + +ZTEST(resourcemanager, test_DumpUnitConfig) +{ + aos::Log::SetCallback(TestLogCallback); + + ResourceManagerJSONProvider provider; + aos::sm::resourcemanager::UnitConfig unitConfig; + unitConfig.mNodeUnitConfig.mPriority = 1; + unitConfig.mVendorVersion = "1.0"; + unitConfig.mNodeUnitConfig.mNodeType = "mainType"; + + aos::StaticString<1024> jsonStr; + auto err = provider.DumpUnitConfig(unitConfig, jsonStr); + + zassert_true(err.IsNone(), "Failed to dump node unit config: %s", err.Message()); + zassert_false(jsonStr.IsEmpty(), "Empty json string"); + + aos::sm::resourcemanager::UnitConfig parsedUnitConfig; + err = provider.ParseNodeUnitConfig(jsonStr, parsedUnitConfig); + + zassert_true(err.IsNone(), "Failed to parse node unit config: %s", err.Message()); + zassert_true(unitConfig.mNodeUnitConfig == parsedUnitConfig.mNodeUnitConfig, "Parsed node unit config mismatch"); + zassert_true( + unitConfig.mVendorVersion == parsedUnitConfig.mVendorVersion, "Parsed unit config vendor version mismatch"); +} diff --git a/tests/resourcemanager/testcase.yaml b/tests/resourcemanager/testcase.yaml new file mode 100644 index 00000000..a035e156 --- /dev/null +++ b/tests/resourcemanager/testcase.yaml @@ -0,0 +1,6 @@ +tests: + aoszephyrapp.resourcemanager: + build_only: false + tags: resourcemanager + timeout: 500 + platform_allow: native_posix_64 native_posix From d73b37aca6e36f912184608322ce4ed42f850aa1 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Tue, 2 Jul 2024 09:56:07 +0300 Subject: [PATCH 007/198] Switch to aosedge repo Signed-off-by: Oleksandr Grytsov --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4e0af2dd..bdee48de 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[![ci](https://github.com/aoscloud/aos_core_zephyr/actions/workflows/build_test.yaml/badge.svg)](https://github.com/aoscloud/aos_core_zephyr/actions/workflows/build_test.yaml) -[![codecov](https://codecov.io/gh/aoscloud/aos_core_zephyr/branch/main/graph/badge.svg?token=ObQrD8aaAC)](https://codecov.io/gh/aoscloud/aos_core_zephyr) +[![ci](https://github.com/aosedge/aos_core_zephyr/actions/workflows/build_test.yaml/badge.svg)](https://github.com/aosedge/aos_core_zephyr/actions/workflows/build_test.yaml) +[![codecov](https://codecov.io/gh/aosedge/aos_core_zephyr/branch/main/graph/badge.svg?token=ObQrD8aaAC)](https://codecov.io/gh/aosedge/aos_core_zephyr) # AosCore zephyr application @@ -21,7 +21,7 @@ The verified protobuf compiler version is v22.3: Date: Wed, 31 Jul 2024 14:02:17 +0300 Subject: [PATCH 008/198] [west] Use feature dynamic nodes branch Signed-off-by: Mykhailo Lohvynenko --- west.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/west.yml b/west.yml index b6563425..ea24e485 100644 --- a/west.yml +++ b/west.yml @@ -29,11 +29,11 @@ manifest: - name: aos_core_lib_cpp remote: aosedge - revision: "develop" + revision: "feature_dynamic_nodes" - name: aos_core_api remote: aosedge - revision: "develop" + revision: "feature_dynamic_nodes" - name: zephyr-xenlib remote: xen-troops From 772f60509103710258a7844870a68e0c8cb640e8 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Wed, 31 Jul 2024 14:12:02 +0300 Subject: [PATCH 009/198] [cmake] Update protobuf generation Signed-off-by: Mykhailo Lohvynenko --- CMakeLists.txt | 2 +- cmake/FindCoreAPI.cmake | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bf5f34a1..5ab119c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ set(AOS_CORE_CONFIG aoscoreconfig.hpp) # Includes # ###################################################################################################################### -zephyr_include_directories(${CMAKE_CURRENT_BINARY_DIR} src) +zephyr_include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/proto src) zephyr_include_directories_ifdef(CONFIG_NATIVE_APPLICATION mocks/include) # ###################################################################################################################### diff --git a/cmake/FindCoreAPI.cmake b/cmake/FindCoreAPI.cmake index c0533b05..376a3813 100644 --- a/cmake/FindCoreAPI.cmake +++ b/cmake/FindCoreAPI.cmake @@ -25,7 +25,9 @@ find_package(Nanopb REQUIRED) # ###################################################################################################################### # Aos core sources -set(AOS_PROTO_SRC proto/servicemanager/v3/servicemanager.proto proto/iamanager/v4/iamanager.proto) +set(AOS_PROTO_SRC proto/common/v1/common.proto proto/servicemanager/v4/servicemanager.proto + proto/iamanager/v5/iamanager.proto +) # Protobuf sources set(SYSTEM_PROTO_SRC google/protobuf/timestamp.proto google/protobuf/empty.proto) @@ -37,6 +39,7 @@ set(SYSTEM_PROTO_SRC google/protobuf/timestamp.proto google/protobuf/empty.proto # ###################################################################################################################### function(CORE_API_GENERATE CORE_API_DIR SCRIPTS_DIR) set(NANOPB_GENERATE_CPP_STANDALONE OFF) + set(NANOPB_IMPORT_DIRS ${CORE_API_DIR}/proto) get_filename_component(CORE_API_DIR ${CORE_API_DIR} ABSOLUTE) @@ -96,7 +99,8 @@ function(CORE_API_GENERATE CORE_API_DIR SCRIPTS_DIR) nanopb_generate_cpp(proto_sources proto_headers RELPATH ${PROTO_INCLUDE} ${SYSTEM_PROTO_SRC}) target_sources(app PRIVATE ${proto_sources} ${proto_headers}) - # Copy wchan API header + # Copy aos protocol header + + file(COPY ${CORE_API_DIR}/aosprotocol/aosprotocol.h DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - file(COPY ${CORE_API_DIR}/vchanapi/vchanapi.h DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) endfunction() From f6aa542a392726b98a30bb2241ffbee201ac461b Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Thu, 1 Aug 2024 17:59:59 +0300 Subject: [PATCH 010/198] [log] Fix log compilation Signed-off-by: Mykhailo Lohvynenko --- src/app/log.hpp | 7 +- src/clocksync/log.hpp | 7 +- src/communication/log.hpp | 7 +- src/downloader/log.hpp | 7 +- src/logger/logger.cpp | 116 +++++++++++------------------ src/logger/logger.hpp | 17 +---- src/monitoring/log.hpp | 7 +- src/ocispec/log.hpp | 7 +- src/provisioning/log.hpp | 7 +- src/resourcemanager/log.hpp | 7 +- src/runner/log.hpp | 7 +- src/storage/log.hpp | 7 +- tests/clocksync/src/main.cpp | 2 +- tests/communication/src/utils.cpp | 2 +- tests/communication/src/utils.hpp | 2 +- tests/downloader/src/main.cpp | 2 +- tests/provisioning/src/main.cpp | 2 +- tests/resourcemanager/src/main.cpp | 2 +- tests/storage/src/main.cpp | 2 +- 19 files changed, 71 insertions(+), 146 deletions(-) diff --git a/src/app/log.hpp b/src/app/log.hpp index a52cfb40..27374371 100644 --- a/src/app/log.hpp +++ b/src/app/log.hpp @@ -8,11 +8,8 @@ #ifndef LOG_HPP_ #define LOG_HPP_ -#include "logger/logger.hpp" +#define LOG_MODULE "app" -#define LOG_DBG() LOG_MODULE_DBG(static_cast(Logger::Module::eApp)) -#define LOG_INF() LOG_MODULE_INF(static_cast(Logger::Module::eApp)) -#define LOG_WRN() LOG_MODULE_WRN(static_cast(Logger::Module::eApp)) -#define LOG_ERR() LOG_MODULE_ERR(static_cast(Logger::Module::eApp)) +#include #endif diff --git a/src/clocksync/log.hpp b/src/clocksync/log.hpp index 6a710a50..6a96f7a6 100644 --- a/src/clocksync/log.hpp +++ b/src/clocksync/log.hpp @@ -8,11 +8,8 @@ #ifndef LOG_HPP_ #define LOG_HPP_ -#include "logger/logger.hpp" +#define LOG_MODULE "clocksync" -#define LOG_DBG() LOG_MODULE_DBG(static_cast(Logger::Module::eClockSync)) -#define LOG_INF() LOG_MODULE_INF(static_cast(Logger::Module::eClockSync)) -#define LOG_WRN() LOG_MODULE_WRN(static_cast(Logger::Module::eClockSync)) -#define LOG_ERR() LOG_MODULE_ERR(static_cast(Logger::Module::eClockSync)) +#include #endif diff --git a/src/communication/log.hpp b/src/communication/log.hpp index 23c7448c..0b76f53d 100644 --- a/src/communication/log.hpp +++ b/src/communication/log.hpp @@ -8,11 +8,8 @@ #ifndef LOG_HPP_ #define LOG_HPP_ -#include "logger/logger.hpp" +#define LOG_MODULE "communication" -#define LOG_DBG() LOG_MODULE_DBG(static_cast(Logger::Module::eCommunication)) -#define LOG_INF() LOG_MODULE_INF(static_cast(Logger::Module::eCommunication)) -#define LOG_WRN() LOG_MODULE_WRN(static_cast(Logger::Module::eCommunication)) -#define LOG_ERR() LOG_MODULE_ERR(static_cast(Logger::Module::eCommunication)) +#include #endif diff --git a/src/downloader/log.hpp b/src/downloader/log.hpp index 81a8d1c5..42d61d3d 100644 --- a/src/downloader/log.hpp +++ b/src/downloader/log.hpp @@ -8,11 +8,8 @@ #ifndef LOG_HPP_ #define LOG_HPP_ -#include "logger/logger.hpp" +#define LOG_MODULE "downloader" -#define LOG_DBG() LOG_MODULE_DBG(static_cast(Logger::Module::eDownloader)) -#define LOG_INF() LOG_MODULE_INF(static_cast(Logger::Module::eDownloader)) -#define LOG_WRN() LOG_MODULE_WRN(static_cast(Logger::Module::eDownloader)) -#define LOG_ERR() LOG_MODULE_ERR(static_cast(Logger::Module::eDownloader)) +#include #endif diff --git a/src/logger/logger.cpp b/src/logger/logger.cpp index f9c73509..a2302467 100644 --- a/src/logger/logger.cpp +++ b/src/logger/logger.cpp @@ -9,6 +9,27 @@ #include "logger.hpp" +/*********************************************************************************************************************** + * Consts + **********************************************************************************************************************/ + +static const aos::String cLogModuleApp = "app"; +static const aos::String cLogModuleCommunication = "communication"; +static const aos::String cLogModuleClockSync = "clocksync"; +static const aos::String cLogModuleDownloader = "downloader"; +static const aos::String cLogModuleOCISpec = "ocispec"; +static const aos::String cLogModuleProvisioning = "provisioning"; +static const aos::String cLogModuleResourceManager = "resourcemanager"; +static const aos::String cLogModuleRunner = "runner"; +static const aos::String cLogModuleStorage = "storage"; + +static const aos::String cLogModuleCerthandler = "certhandler"; +static const aos::String cLogModuleCrypto = "crypto"; +static const aos::String cLogModuleLauncher = "launcher"; +static const aos::String cLogModuleMonitoring = "monitoring"; +static const aos::String cLogModuleServiceManager = "servicemanager"; +static const aos::String cLogModulePKCS11 = "pkcs11"; + /*********************************************************************************************************************** * Log module callbacks **********************************************************************************************************************/ @@ -50,7 +71,6 @@ } // internal logs - LOG_CALLBACK(app); LOG_CALLBACK(clocksync); LOG_CALLBACK(communication); @@ -62,7 +82,6 @@ LOG_CALLBACK(runner); LOG_CALLBACK(storage); // Aos lib logs - LOG_CALLBACK(certhandler); LOG_CALLBACK(crypto); LOG_CALLBACK(launcher); @@ -83,91 +102,42 @@ void Logger::Init() * Public **********************************************************************************************************************/ -void Logger::LogCallback(aos::LogModule module, aos::LogLevel level, const aos::String& message) +void Logger::LogCallback(const char* module, aos::LogLevel level, const aos::String& message) { - switch (static_cast(module.GetValue())) { - // internal logs + aos::String logModule(module); - case static_cast(Module::eApp): + if (logModule == cLogModuleApp) { log_app::LogCallback(level, message); - - break; - - case static_cast(Module::eCommunication): + } else if (logModule == cLogModuleCommunication) { log_communication::LogCallback(level, message); - - break; - - case static_cast(Module::eClockSync): + } else if (logModule == cLogModuleClockSync) { log_clocksync::LogCallback(level, message); - - break; - - case static_cast(Module::eDownloader): + } else if (logModule == cLogModuleDownloader) { log_downloader::LogCallback(level, message); - - break; - - case static_cast(Module::eOCISpec): + } else if (logModule == cLogModuleOCISpec) { log_ocispec::LogCallback(level, message); - - break; - - case static_cast(Module::eProvisioning): + } else if (logModule == cLogModuleProvisioning) { log_provisioning::LogCallback(level, message); - - break; - - case static_cast(Module::eResourceManager): + } else if (logModule == cLogModuleResourceManager) { log_resourcemanager::LogCallback(level, message); - - break; - - case static_cast(Module::eRunner): + } else if (logModule == cLogModuleRunner) { log_runner::LogCallback(level, message); - - break; - - case static_cast(Module::eStorage): + } else if (logModule == cLogModuleStorage) { log_storage::LogCallback(level, message); - - break; - - // Aos lib logs - - case static_cast(aos::LogModuleEnum::eCommonPKCS11): - log_pkcs11::LogCallback(level, message); - - break; - - case static_cast(aos::LogModuleEnum::eCommonCrypto): - log_crypto::LogCallback(level, message); - - break; - - case static_cast(aos::LogModuleEnum::eIAMCertHandler): + } else if (logModule == cLogModuleCerthandler) { log_certhandler::LogCallback(level, message); - - break; - - case static_cast(aos::LogModuleEnum::eSMLauncher): + } else if (logModule == cLogModuleCrypto) { + log_crypto::LogCallback(level, message); + } else if (logModule == cLogModuleLauncher) { log_launcher::LogCallback(level, message); - - break; - - case static_cast(aos::LogModuleEnum::eCommonMonitoring): + } else if (logModule == cLogModuleMonitoring) { log_monitoring::LogCallback(level, message); - - break; - - case static_cast(aos::LogModuleEnum::eSMServiceManager): + } else if (logModule == cLogModuleServiceManager) { log_servicemanager::LogCallback(level, message); - - break; - - default: - LOG_MODULE_WRN(static_cast(Logger::Module::eCommunication)) - << "Log from unknown module received: module = " << module << ", level = " << level - << ", message = " << message; + } else if (logModule == cLogModulePKCS11) { + log_pkcs11::LogCallback(level, message); + } else { + LOG_MODULE_WRN(cLogModuleCommunication.CStr()) + << "Log from unknown module received: module=" << module << ", level=" << level << ", message=" << message; } } diff --git a/src/logger/logger.hpp b/src/logger/logger.hpp index fa1a1c11..777e565c 100644 --- a/src/logger/logger.hpp +++ b/src/logger/logger.hpp @@ -15,28 +15,13 @@ */ class Logger { public: - /** - * Local log modules. - */ - enum class Module { - eApp = static_cast(aos::LogModuleEnum::eNumModules), - eClockSync, - eCommunication, - eDownloader, - eOCISpec, - eProvisioning, - eResourceManager, - eRunner, - eStorage, - }; - /** * Inits logging system. */ static void Init(); private: - static void LogCallback(aos::LogModule module, aos::LogLevel level, const aos::String& message); + static void LogCallback(const char* module, aos::LogLevel level, const aos::String& message); }; #endif diff --git a/src/monitoring/log.hpp b/src/monitoring/log.hpp index 6c6fa782..49052ab6 100644 --- a/src/monitoring/log.hpp +++ b/src/monitoring/log.hpp @@ -8,11 +8,8 @@ #ifndef LOG_HPP_ #define LOG_HPP_ -#include "logger/logger.hpp" +#define LOG_MODULE "monitoring" -#define LOG_DBG() LOG_MODULE_DBG(aos::LogModuleEnum::eCommonMonitoring) -#define LOG_INF() LOG_MODULE_INF(aos::LogModuleEnum::eCommonMonitoring) -#define LOG_WRN() LOG_MODULE_WRN(aos::LogModuleEnum::eCommonMonitoring) -#define LOG_ERR() LOG_MODULE_ERR(aos::LogModuleEnum::eCommonMonitoring) +#include #endif diff --git a/src/ocispec/log.hpp b/src/ocispec/log.hpp index 1b0817a3..ad6ccee9 100644 --- a/src/ocispec/log.hpp +++ b/src/ocispec/log.hpp @@ -8,11 +8,8 @@ #ifndef LOG_HPP_ #define LOG_HPP_ -#include "logger/logger.hpp" +#define LOG_MODULE "ocispec" -#define LOG_DBG() LOG_MODULE_DBG(static_cast(Logger::Module::eOCISpec)) -#define LOG_INF() LOG_MODULE_INF(static_cast(Logger::Module::eOCISpec)) -#define LOG_WRN() LOG_MODULE_WRN(static_cast(Logger::Module::eOCISpec)) -#define LOG_ERR() LOG_MODULE_ERR(static_cast(Logger::Module::eOCISpec)) +#include #endif diff --git a/src/provisioning/log.hpp b/src/provisioning/log.hpp index 6487509c..26c6bc82 100644 --- a/src/provisioning/log.hpp +++ b/src/provisioning/log.hpp @@ -8,11 +8,8 @@ #ifndef LOG_HPP_ #define LOG_HPP_ -#include "logger/logger.hpp" +#define LOG_MODULE "provisioning" -#define LOG_DBG() LOG_MODULE_DBG(static_cast(Logger::Module::eProvisioning)) -#define LOG_INF() LOG_MODULE_INF(static_cast(Logger::Module::eProvisioning)) -#define LOG_WRN() LOG_MODULE_WRN(static_cast(Logger::Module::eProvisioning)) -#define LOG_ERR() LOG_MODULE_ERR(static_cast(Logger::Module::eProvisioning)) +#include #endif diff --git a/src/resourcemanager/log.hpp b/src/resourcemanager/log.hpp index 3a2ae615..9cfa6d34 100644 --- a/src/resourcemanager/log.hpp +++ b/src/resourcemanager/log.hpp @@ -8,11 +8,8 @@ #ifndef LOG_HPP_ #define LOG_HPP_ -#include "logger/logger.hpp" +#define LOG_MODULE "resourcemanager" -#define LOG_DBG() LOG_MODULE_DBG(aos::LogModuleEnum::eSMResourceManager) -#define LOG_INF() LOG_MODULE_INF(aos::LogModuleEnum::eSMResourceManager) -#define LOG_WRN() LOG_MODULE_WRN(aos::LogModuleEnum::eSMResourceManager) -#define LOG_ERR() LOG_MODULE_ERR(aos::LogModuleEnum::eSMResourceManager) +#include #endif diff --git a/src/runner/log.hpp b/src/runner/log.hpp index 3fb97fe8..f5cd9bfc 100644 --- a/src/runner/log.hpp +++ b/src/runner/log.hpp @@ -8,11 +8,8 @@ #ifndef LOG_HPP_ #define LOG_HPP_ -#include "logger/logger.hpp" +#define LOG_MODULE "runner" -#define LOG_DBG() LOG_MODULE_DBG(static_cast(Logger::Module::eRunner)) -#define LOG_INF() LOG_MODULE_INF(static_cast(Logger::Module::eRunner)) -#define LOG_WRN() LOG_MODULE_WRN(static_cast(Logger::Module::eRunner)) -#define LOG_ERR() LOG_MODULE_ERR(static_cast(Logger::Module::eRunner)) +#include #endif diff --git a/src/storage/log.hpp b/src/storage/log.hpp index 88991b49..5daf41ab 100644 --- a/src/storage/log.hpp +++ b/src/storage/log.hpp @@ -8,11 +8,8 @@ #ifndef LOG_HPP_ #define LOG_HPP_ -#include "logger/logger.hpp" +#define LOG_MODULE "storage" -#define LOG_DBG() LOG_MODULE_DBG(static_cast(Logger::Module::eStorage)) -#define LOG_INF() LOG_MODULE_INF(static_cast(Logger::Module::eStorage)) -#define LOG_WRN() LOG_MODULE_WRN(static_cast(Logger::Module::eStorage)) -#define LOG_ERR() LOG_MODULE_ERR(static_cast(Logger::Module::eStorage)) +#include #endif diff --git a/tests/clocksync/src/main.cpp b/tests/clocksync/src/main.cpp index 28aad9dc..96c1e7b3 100644 --- a/tests/clocksync/src/main.cpp +++ b/tests/clocksync/src/main.cpp @@ -33,7 +33,7 @@ struct clocksync_fixture { * Setup **********************************************************************************************************************/ -void TestLogCallback(aos::LogModule module, aos::LogLevel level, const aos::String& message) +void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message) { static std::mutex mutex; static auto startTime = std::chrono::steady_clock::now(); diff --git a/tests/communication/src/utils.cpp b/tests/communication/src/utils.cpp index 46971abe..46f5fc28 100644 --- a/tests/communication/src/utils.cpp +++ b/tests/communication/src/utils.cpp @@ -17,7 +17,7 @@ * Public **********************************************************************************************************************/ -void TestLogCallback(aos::LogModule module, aos::LogLevel level, const aos::String& message) +void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message) { static std::mutex mutex; static auto startTime = std::chrono::steady_clock::now(); diff --git a/tests/communication/src/utils.hpp b/tests/communication/src/utils.hpp index 3270b29f..2e46987b 100644 --- a/tests/communication/src/utils.hpp +++ b/tests/communication/src/utils.hpp @@ -19,7 +19,7 @@ constexpr auto cWaitTimeout = std::chrono::seconds {5}; * Public **********************************************************************************************************************/ -void TestLogCallback(aos::LogModule module, aos::LogLevel level, const aos::String& message); +void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message); aos::Error SendMessageToChannel(CommChannelStub& channel, uint32_t source, const std::string& methodName, uint64_t requestID, const std::vector& data, aos::Error messageError = aos::ErrorEnum::eNone); diff --git a/tests/downloader/src/main.cpp b/tests/downloader/src/main.cpp index 9b9dd25f..14808c95 100644 --- a/tests/downloader/src/main.cpp +++ b/tests/downloader/src/main.cpp @@ -83,7 +83,7 @@ class TestDownloadRequester : public DownloadRequesterItf { bool mSkipSendRequest; }; -void TestLogCallback(LogModule module, LogLevel level, const aos::String& message) +void TestLogCallback(const char* module, LogLevel level, const aos::String& message) { printk("[downloader] %s \n", message.CStr()); } diff --git a/tests/provisioning/src/main.cpp b/tests/provisioning/src/main.cpp index f8502bec..1af2ae69 100644 --- a/tests/provisioning/src/main.cpp +++ b/tests/provisioning/src/main.cpp @@ -27,7 +27,7 @@ struct provisioning_fixture { * Setup **********************************************************************************************************************/ -void TestLogCallback(aos::LogModule module, aos::LogLevel level, const aos::String& message) +void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message) { static std::mutex mutex; static auto startTime = std::chrono::steady_clock::now(); diff --git a/tests/resourcemanager/src/main.cpp b/tests/resourcemanager/src/main.cpp index a2e08bdf..c9adc972 100644 --- a/tests/resourcemanager/src/main.cpp +++ b/tests/resourcemanager/src/main.cpp @@ -15,7 +15,7 @@ static constexpr auto cTestNodeConfigJSON = R"({"nodeType":"mainType","priority":1,"vendorVersion":"1.0"})"; -static void TestLogCallback(aos::LogModule module, aos::LogLevel level, const aos::String& message) +static void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message) { printk("[resourcemanager] %s \n", message.CStr()); } diff --git a/tests/storage/src/main.cpp b/tests/storage/src/main.cpp index 8991636a..be686400 100644 --- a/tests/storage/src/main.cpp +++ b/tests/storage/src/main.cpp @@ -20,7 +20,7 @@ static const aos::Array StringToDN(const char* str) ZTEST_SUITE(storage, NULL, NULL, NULL, NULL, NULL); -void TestLogCallback(aos::LogModule module, aos::LogLevel level, const aos::String& message) +void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message) { printk("[storage] %s \n", message.CStr()); } From 7597ad2f3c2f64826c89ef36d9d926b37120678e Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Thu, 1 Aug 2024 18:01:00 +0300 Subject: [PATCH 011/198] [all] Fix node info namespace Signed-off-by: Mykhailo Lohvynenko --- src/communication/cmclient.cpp | 2 +- src/communication/cmclient.hpp | 2 +- src/monitoring/resourceusageprovider.cpp | 11 +++++++---- src/monitoring/resourceusageprovider.hpp | 4 ++-- tests/communication/src/cmclient.cpp | 6 +++--- tests/communication/src/stubs/monitoringstub.hpp | 8 ++++---- 6 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/communication/cmclient.cpp b/src/communication/cmclient.cpp index 3c01a6a0..1c6cedfd 100644 --- a/src/communication/cmclient.cpp +++ b/src/communication/cmclient.cpp @@ -177,7 +177,7 @@ aos::Error CMClient::SendMonitoringData(const aos::monitoring::NodeMonitoringDat aos::Error CMClient::SendNodeConfiguration() { - auto nodeInfo = aos::MakeUnique(&mAllocator); + auto nodeInfo = aos::MakeUnique(&mAllocator); auto outgoingMessage = aos::MakeUnique(&mAllocator); auto& pbNodeConfiguration = outgoingMessage->SMOutgoingMessage.node_configuration; diff --git a/src/communication/cmclient.hpp b/src/communication/cmclient.hpp index 3004f7a5..a4d1ea60 100644 --- a/src/communication/cmclient.hpp +++ b/src/communication/cmclient.hpp @@ -123,7 +123,7 @@ class CMClient : public MessageHandler + sizeof(aos::NodeInfo)> mAllocator; PBService mSMService; diff --git a/src/monitoring/resourceusageprovider.cpp b/src/monitoring/resourceusageprovider.cpp index b992a96c..82697ad9 100644 --- a/src/monitoring/resourceusageprovider.cpp +++ b/src/monitoring/resourceusageprovider.cpp @@ -28,11 +28,14 @@ aos::Error ResourceUsageProvider::Init() return AOS_ERROR_WRAP(ret); } + if (auto err = mNodeInfo.mCPUs.Resize(xstat.num_cpus); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + mNodeInfo.mNodeID = cNodeID; - mNodeInfo.mNumCPUs = xstat.num_cpus; mNodeInfo.mTotalRAM = xstat.tot_mem; - aos::monitoring::PartitionInfo partitionInfo; + aos::PartitionInfo partitionInfo; partitionInfo.mName = cDiskPartitionName; partitionInfo.mPath = cDiskPartitionPoint; partitionInfo.mTypes.EmplaceBack("services"); @@ -40,7 +43,7 @@ aos::Error ResourceUsageProvider::Init() mNodeInfo.mPartitions.PushBack(partitionInfo); - LOG_DBG() << "Number of CPUs: " << mNodeInfo.mNumCPUs << ", total RAM(K): " << (mNodeInfo.mTotalRAM / 1024); + LOG_DBG() << "Number of CPUs: " << mNodeInfo.mCPUs.Size() << ", total RAM(K): " << (mNodeInfo.mTotalRAM / 1024); for (size_t i = 0; i < mNodeInfo.mPartitions.Size(); ++i) { struct fs_statvfs sbuf; @@ -59,7 +62,7 @@ aos::Error ResourceUsageProvider::Init() return aos::ErrorEnum::eNone; } -aos::Error ResourceUsageProvider::GetNodeInfo(aos::monitoring::NodeInfo& nodeInfo) const +aos::Error ResourceUsageProvider::GetNodeInfo(aos::NodeInfo& nodeInfo) const { LOG_DBG() << "Get node info"; diff --git a/src/monitoring/resourceusageprovider.hpp b/src/monitoring/resourceusageprovider.hpp index 4b16fedc..12cccdb0 100644 --- a/src/monitoring/resourceusageprovider.hpp +++ b/src/monitoring/resourceusageprovider.hpp @@ -26,7 +26,7 @@ class ResourceUsageProvider : public aos::monitoring::ResourceUsageProviderItf { * @param systemInfo system info * @return Error */ - aos::Error GetNodeInfo(aos::monitoring::NodeInfo& systemInfo) const override; + aos::Error GetNodeInfo(aos::NodeInfo& systemInfo) const override; /** * Returns node monitoring data @@ -72,7 +72,7 @@ class ResourceUsageProvider : public aos::monitoring::ResourceUsageProviderItf { timeval mPrevTime {}; aos::StaticArray mPrevInstanceCPUTime {}; aos::Mutex mMutex {}; - aos::monitoring::NodeInfo mNodeInfo {}; + aos::NodeInfo mNodeInfo {}; }; #endif diff --git a/tests/communication/src/cmclient.cpp b/tests/communication/src/cmclient.cpp index d9a7a011..de9bb298 100644 --- a/tests/communication/src/cmclient.cpp +++ b/tests/communication/src/cmclient.cpp @@ -150,7 +150,7 @@ ZTEST_F(cmclient, test_NodeConfiguration) fixture->mCommunication.Subscribes(subscriber); - aos::monitoring::NodeInfo sendNodeInfo {CONFIG_AOS_NODE_ID, 2, 1024, {}}; + aos::NodeInfo sendNodeInfo {CONFIG_AOS_NODE_ID, 2, 1024, {}}; sendNodeInfo.mPartitions.EmplaceBack(aos::monitoring::PartitionInfo {"var", "", {}, 2048, 0}); sendNodeInfo.mPartitions.end()->mTypes.EmplaceBack("data"); @@ -177,8 +177,8 @@ ZTEST_F(cmclient, test_NodeConfiguration) err = ReceiveCMOutgoingMessage(fixture->mSecureChannel, outgoingMessage); zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - aos::monitoring::NodeInfo receiveNodeInfo {}; - const auto& pbNodeConfiguration = outgoingMessage.SMOutgoingMessage.node_configuration; + aos::NodeInfo receiveNodeInfo {}; + const auto& pbNodeConfiguration = outgoingMessage.SMOutgoingMessage.node_configuration; PBToString(pbNodeConfiguration.node_id, receiveNodeInfo.mNodeID); receiveNodeInfo.mNumCPUs = pbNodeConfiguration.num_cpus; diff --git a/tests/communication/src/stubs/monitoringstub.hpp b/tests/communication/src/stubs/monitoringstub.hpp index 9a2c099b..74475a08 100644 --- a/tests/communication/src/stubs/monitoringstub.hpp +++ b/tests/communication/src/stubs/monitoringstub.hpp @@ -12,7 +12,7 @@ class ResourceMonitorStub : public aos::monitoring::ResourceMonitorItf { public: - aos::Error GetNodeInfo(aos::monitoring::NodeInfo& nodeInfo) const override + aos::Error GetNodeInfo(aos::NodeInfo& nodeInfo) const override { nodeInfo = mNodeInfo; return aos::ErrorEnum::eNone; @@ -26,12 +26,12 @@ class ResourceMonitorStub : public aos::monitoring::ResourceMonitorItf { aos::Error StopInstanceMonitoring(const aos::String& instanceID) { return aos::ErrorEnum::eNone; } - void SetNodeInfo(const aos::monitoring::NodeInfo& nodeInfo) { mNodeInfo = nodeInfo; } + void SetNodeInfo(const aos::NodeInfo& nodeInfo) { mNodeInfo = nodeInfo; } - void Clear() { mNodeInfo = aos::monitoring::NodeInfo(); } + void Clear() { mNodeInfo = aos::NodeInfo(); } private: - aos::monitoring::NodeInfo mNodeInfo; + aos::NodeInfo mNodeInfo; }; #endif From c3408d8ee2052c67624942b6b4c923a0d181f042 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 2 Aug 2024 17:05:11 +0300 Subject: [PATCH 012/198] [communication] Remove current implementation and add new interfaces Signed-off-by: Oleksandr Grytsov --- CMakeLists.txt | 5 +- Kconfig | 19 +- .../{commchannel.hpp => channel.hpp} | 24 +- src/communication/channelmanager.hpp | 75 ++ src/communication/channeltype.hpp | 37 - src/communication/cmclient.cpp | 521 -------------- src/communication/cmclient.hpp | 132 ---- src/communication/communication.cpp | 490 ------------- src/communication/communication.hpp | 157 ----- src/communication/iamserver.cpp | 336 --------- src/communication/iamserver.hpp | 110 --- src/communication/messagehandler.hpp | 377 ---------- src/communication/tlschannel.cpp | 14 +- src/communication/tlschannel.hpp | 16 +- src/communication/transport.hpp | 65 ++ .../{vchannel.cpp => xenvchan.cpp} | 38 +- .../{vchannel.hpp => xenvchan.hpp} | 43 +- tests/communication/CMakeLists.txt | 131 ---- tests/communication/Kconfig | 56 -- tests/communication/prj.conf | 46 -- tests/communication/src/cmclient.cpp | 643 ------------------ tests/communication/src/iamserver.cpp | 241 ------- .../src/stubs/certhandlerstub.hpp | 165 ----- .../src/stubs/certloaderstub.hpp | 125 ---- .../communication/src/stubs/clocksyncstub.hpp | 82 --- .../src/stubs/commchannelstub.hpp | 129 ---- .../src/stubs/connectionsubscriberstub.hpp | 85 --- .../src/stubs/downloaderstub.hpp | 85 --- .../communication/src/stubs/launcherstub.hpp | 96 --- .../src/stubs/monitoringstub.hpp | 37 - .../src/stubs/provisioningstub.hpp | 49 -- .../src/stubs/resourcemanagerstub.hpp | 94 --- .../communication/src/stubs/rsaprivatekey.hpp | 77 --- tests/communication/src/testmbedtlsconfig.h | 22 - tests/communication/src/tlschannel.cpp | 266 -------- tests/communication/src/utils.cpp | 169 ----- tests/communication/src/utils.hpp | 34 - tests/communication/testcase.yaml | 6 - 38 files changed, 205 insertions(+), 4892 deletions(-) rename src/communication/{commchannel.hpp => channel.hpp} (74%) create mode 100644 src/communication/channelmanager.hpp delete mode 100644 src/communication/channeltype.hpp delete mode 100644 src/communication/cmclient.cpp delete mode 100644 src/communication/cmclient.hpp delete mode 100644 src/communication/communication.cpp delete mode 100644 src/communication/communication.hpp delete mode 100644 src/communication/iamserver.cpp delete mode 100644 src/communication/iamserver.hpp delete mode 100644 src/communication/messagehandler.hpp create mode 100644 src/communication/transport.hpp rename src/communication/{vchannel.cpp => xenvchan.cpp} (57%) rename src/communication/{vchannel.hpp => xenvchan.hpp} (53%) delete mode 100644 tests/communication/CMakeLists.txt delete mode 100644 tests/communication/Kconfig delete mode 100644 tests/communication/prj.conf delete mode 100644 tests/communication/src/cmclient.cpp delete mode 100644 tests/communication/src/iamserver.cpp delete mode 100644 tests/communication/src/stubs/certhandlerstub.hpp delete mode 100644 tests/communication/src/stubs/certloaderstub.hpp delete mode 100644 tests/communication/src/stubs/clocksyncstub.hpp delete mode 100644 tests/communication/src/stubs/commchannelstub.hpp delete mode 100644 tests/communication/src/stubs/connectionsubscriberstub.hpp delete mode 100644 tests/communication/src/stubs/downloaderstub.hpp delete mode 100644 tests/communication/src/stubs/launcherstub.hpp delete mode 100644 tests/communication/src/stubs/monitoringstub.hpp delete mode 100644 tests/communication/src/stubs/provisioningstub.hpp delete mode 100644 tests/communication/src/stubs/resourcemanagerstub.hpp delete mode 100644 tests/communication/src/stubs/rsaprivatekey.hpp delete mode 100644 tests/communication/src/testmbedtlsconfig.h delete mode 100644 tests/communication/src/tlschannel.cpp delete mode 100644 tests/communication/src/utils.cpp delete mode 100644 tests/communication/src/utils.hpp delete mode 100644 tests/communication/testcase.yaml diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ab119c5..a0f04cd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,11 +75,8 @@ target_sources( PRIVATE src/main.cpp src/app/app.cpp src/clocksync/clocksync.cpp - src/communication/cmclient.cpp - src/communication/communication.cpp - src/communication/iamserver.cpp src/communication/tlschannel.cpp - src/communication/vchannel.cpp + src/communication/xenvchan.cpp src/downloader/downloader.cpp src/logger/logger.cpp src/monitoring/resourceusageprovider.cpp diff --git a/Kconfig b/Kconfig index fac80638..efa6cf11 100644 --- a/Kconfig +++ b/Kconfig @@ -9,21 +9,14 @@ config AOS_DOMD_ID int "DomD id" default 1 -config AOS_VCHAN_OPEN_TX_PATH - string "Path to open TX vchan" - default "/local/domain/1/tmp/vchan/aos/open/tx" +config AOS_VCHAN_TX_PATH + string "Path to TX vchan" + default "/local/domain/1/tmp/vchan/aos/tx" -config AOS_VCHAN_OPEN_RX_PATH - string "Path to open RX vchan" - default "/local/domain/1/tmp/vchan/aos/open/rx" +config AOS_VCHAN_RX_PATH + string "Path to RX vchan" + default "/local/domain/1/tmp/vchan/aos/rx" -config AOS_VCHAN_SECURE_TX_PATH - string "Path to secure TX vchan" - default "/local/domain/1/tmp/vchan/aos/secure/tx" - -config AOS_VCHAN_SECURE_RX_PATH - string "Path to secure RX vchan" - default "/local/domain/1/tmp/vchan/aos/secure/rx" config AOS_REBOOT_XEN_STORE_PATH string "Path to user reboot request" diff --git a/src/communication/commchannel.hpp b/src/communication/channel.hpp similarity index 74% rename from src/communication/commchannel.hpp rename to src/communication/channel.hpp index 0eee933c..f3c88cc5 100644 --- a/src/communication/commchannel.hpp +++ b/src/communication/channel.hpp @@ -5,24 +5,18 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef COMMCHANNEL_HPP_ -#define COMMCHANNEL_HPP_ +#ifndef CHANNEL_HPP_ +#define CHANNEL_HPP_ -#include +namespace aos::zephyr::communication { + +#include /** - * CommChannel interface. + * Channel interface. */ -class CommChannelItf { +class ChannelItf { public: - /** - * Set TLS config. - * - * @param certType certificate type. - * @return aos::Error. - */ - virtual aos::Error SetTLSConfig(const aos::String& certType) = 0; - /** * Connects to communication channel. * @@ -63,7 +57,9 @@ class CommChannelItf { /** * Destructor. */ - virtual ~CommChannelItf() { } + virtual ~ChannelItf() = default; }; +} // namespace aos::zephyr::communication + #endif diff --git a/src/communication/channelmanager.hpp b/src/communication/channelmanager.hpp new file mode 100644 index 00000000..d330cb91 --- /dev/null +++ b/src/communication/channelmanager.hpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef COMMUNICATION_HPP_ +#define COMMUNICATION_HPP_ + +#include "channel.hpp" +#include "transport.hpp" + +namespace aos::zephyr::communication { + +/** + * Channel manager interface. + */ +class ChannelManagerItf { +public: + /** + * Create channel with dedicated port. + * + * @param port port to bind channel. + * @return aos::RetWithError + */ + virtual aos::RetWithError CreateChannel(uint32_t port) = 0; + + /** + * Deletes channel. + * + * @param port port channel is bound to. + * @return aos::Error + */ + virtual aos::Error DeleteChannel(uint32_t port) = 0; + + /** + * Destructor. + */ + virtual ~ChannelManagerItf() { } +}; + +/** + * Channel manager instance. + */ +class ChannelManager : public ChannelManagerItf { +public: + /** + * Initializes channel manager. + * + * @param transport communication transport. + * @return * aos::Error + */ + aos::Error Init(TransportItf& transport); + + /** + * Create channel with dedicated port. + * + * @param port port to bind channel. + * @return aos::RetWithError + */ + aos::RetWithError CreateChannel(uint32_t port) override; + + /** + * Deletes channel. + * + * @param port port channel is bound to. + * @return aos::Error + */ + aos::Error DeleteChannel(uint32_t port) override; +}; + +} // namespace aos::zephyr::communication + +#endif diff --git a/src/communication/channeltype.hpp b/src/communication/channeltype.hpp deleted file mode 100644 index df1e3953..00000000 --- a/src/communication/channeltype.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef CHANNELTYPE_HPP_ -#define CHANNELTYPE_HPP_ - -#include -#include - -/** - * Channel type enum. - * - */ -class ChannelType { -public: - enum class Enum { - eOpen, - eSecure, - eNumChannels, - }; - - static const aos::Array GetStrings() - { - static const char* const sContentTypeStrings[] = {"open", "secure"}; - - return aos::Array(sContentTypeStrings, aos::ArraySize(sContentTypeStrings)); - }; -}; - -using ChannelEnum = ChannelType::Enum; -using Channel = aos::EnumStringer; - -#endif diff --git a/src/communication/cmclient.cpp b/src/communication/cmclient.cpp deleted file mode 100644 index 1c6cedfd..00000000 --- a/src/communication/cmclient.cpp +++ /dev/null @@ -1,521 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include - -#include "utils/pbconvert.hpp" - -#include "cmclient.hpp" -#include "log.hpp" - -/*********************************************************************************************************************** - * Static - **********************************************************************************************************************/ - -static void InstanceStatusToPB(const aos::InstanceStatus& aosInstance, servicemanager_v3_InstanceStatus& pbInstance) -{ - pbInstance.has_instance = true; - StringToPB(aosInstance.mInstanceIdent.mServiceID, pbInstance.instance.service_id); - StringToPB(aosInstance.mInstanceIdent.mSubjectID, pbInstance.instance.subject_id); - pbInstance.instance.instance = aosInstance.mInstanceIdent.mInstance; - pbInstance.aos_version = aosInstance.mAosVersion; - StringToPB(aosInstance.mRunState.ToString(), pbInstance.run_state); - - if (!aosInstance.mError.IsNone()) { - pbInstance.has_error_info = true; - pbInstance.error_info.aos_code = static_cast(aosInstance.mError.Value()); - pbInstance.error_info.exit_code = aosInstance.mError.Errno(); - ErrorToPB(aosInstance.mError, pbInstance.error_info.message); - } -} - -static void MonitoringDataToPB( - const aos::monitoring::MonitoringData& aosMonitoring, servicemanager_v3_MonitoringData& pbMonitoring) -{ - pbMonitoring.ram = aosMonitoring.mRAM; - pbMonitoring.cpu = aosMonitoring.mCPU; - pbMonitoring.disk_count = aosMonitoring.mDisk.Size(); - - for (size_t i = 0; i < aosMonitoring.mDisk.Size(); i++) { - StringToPB(aosMonitoring.mDisk[i].mName, pbMonitoring.disk[i].name); - pbMonitoring.disk[i].used_size = aosMonitoring.mDisk[i].mUsedSize; - } - - pbMonitoring.in_traffic = aosMonitoring.mInTraffic; - pbMonitoring.out_traffic = aosMonitoring.mOutTraffic; -} - -/*********************************************************************************************************************** - * Public - **********************************************************************************************************************/ - -aos::Error CMClient::Init(aos::sm::launcher::LauncherItf& launcher, - aos::sm::resourcemanager::ResourceManagerItf& resourceManager, aos::monitoring::ResourceMonitorItf& resourceMonitor, - DownloadReceiverItf& downloader, ClockSyncItf& clockSync, MessageSenderItf& messageSender) -{ - LOG_DBG() << "Initialize CM client"; - - mLauncher = &launcher; - mResourceManager = &resourceManager; - mResourceMonitor = &resourceMonitor; - mDownloader = &downloader; - mClockSync = &clockSync; - - auto err = MessageHandler::Init(AOS_VCHAN_SM, messageSender); - if (!err.IsNone()) { - return err; - } - - if (!(err = mSMService.Init("")).IsNone()) { - return err; - } - - mSMService.RegisterMethod(""); - - if (!(err = RegisterService(mSMService, ChannelEnum::eOpen)).IsNone()) { - return err; - } - - if (!(err = RegisterService(mSMService, ChannelEnum::eSecure)).IsNone()) { - return err; - } - - return aos::ErrorEnum::eNone; -} - -aos::Error CMClient::InstancesRunStatus(const aos::Array& instances) -{ - auto outgoingMessage = aos::MakeUnique(&mAllocator); - auto& pbRunStatus = outgoingMessage->SMOutgoingMessage.run_instances_status; - - outgoingMessage->which_SMOutgoingMessage = servicemanager_v3_SMOutgoingMessages_run_instances_status_tag; - pbRunStatus = servicemanager_v3_RunInstancesStatus servicemanager_v3_RunInstancesStatus_init_default; - - outgoingMessage->SMOutgoingMessage.run_instances_status.instances_count = instances.Size(); - - for (size_t i = 0; i < instances.Size(); i++) { - InstanceStatusToPB(instances[i], pbRunStatus.instances[i]); - } - - LOG_DBG() << "Send SM message: message = RunInstancesStatus"; - - return SendPBMessage(ChannelEnum::eSecure, 0, &servicemanager_v3_SMOutgoingMessages_msg, outgoingMessage.Get()); -} - -aos::Error CMClient::InstancesUpdateStatus(const aos::Array& instances) -{ - auto outgoingMessage = aos::MakeUnique(&mAllocator); - auto& pbUpdateStatus = outgoingMessage->SMOutgoingMessage.update_instances_status; - - outgoingMessage->which_SMOutgoingMessage = servicemanager_v3_SMOutgoingMessages_update_instances_status_tag; - pbUpdateStatus = servicemanager_v3_UpdateInstancesStatus servicemanager_v3_UpdateInstancesStatus_init_default; - - outgoingMessage->SMOutgoingMessage.update_instances_status.instances_count = instances.Size(); - - for (size_t i = 0; i < instances.Size(); i++) { - InstanceStatusToPB(instances[i], pbUpdateStatus.instances[i]); - } - - LOG_DBG() << "Send SM message: message = UpdateInstancesStatus"; - - return SendPBMessage(ChannelEnum::eSecure, 0, &servicemanager_v3_SMOutgoingMessages_msg, outgoingMessage.Get()); -} - -aos::Error CMClient::SendImageContentRequest(const ImageContentRequest& request) -{ - auto outgoingMessage = aos::MakeUnique(&mAllocator); - auto& pbContentRequest = outgoingMessage->SMOutgoingMessage.image_content_request; - - outgoingMessage->which_SMOutgoingMessage = servicemanager_v3_SMOutgoingMessages_image_content_request_tag; - pbContentRequest = servicemanager_v3_ImageContentRequest servicemanager_v3_ImageContentRequest_init_default; - - StringToPB(request.mURL, pbContentRequest.url); - pbContentRequest.request_id = request.mRequestID; - StringToPB(request.mContentType.ToString(), pbContentRequest.content_type); - - LOG_DBG() << "Send SM message: message = ImageContentRequest"; - - return SendPBMessage(ChannelEnum::eSecure, 0, &servicemanager_v3_SMOutgoingMessages_msg, outgoingMessage.Get()); -} - -aos::Error CMClient::SendMonitoringData(const aos::monitoring::NodeMonitoringData& monitoringData) -{ - auto outgoingMessage = aos::MakeUnique(&mAllocator); - auto& pbMonitoringData = outgoingMessage->SMOutgoingMessage.node_monitoring; - - outgoingMessage->which_SMOutgoingMessage = servicemanager_v3_SMOutgoingMessages_node_monitoring_tag; - pbMonitoringData = servicemanager_v3_NodeMonitoring servicemanager_v3_NodeMonitoring_init_default; - - pbMonitoringData.has_monitoring_data = true; - MonitoringDataToPB(monitoringData.mMonitoringData, pbMonitoringData.monitoring_data); - - pbMonitoringData.instance_monitoring_count = monitoringData.mServiceInstances.Size(); - for (size_t i = 0; i < monitoringData.mServiceInstances.Size(); i++) { - pbMonitoringData.instance_monitoring[i].has_instance = true; - InstanceIdentToPB( - monitoringData.mServiceInstances[i].mInstanceIdent, pbMonitoringData.instance_monitoring[i].instance); - - pbMonitoringData.instance_monitoring[i].has_monitoring_data = true; - MonitoringDataToPB(monitoringData.mServiceInstances[i].mMonitoringData, - pbMonitoringData.instance_monitoring[i].monitoring_data); - } - - pbMonitoringData.has_timestamp = true; - pbMonitoringData.timestamp.seconds = monitoringData.mTimestamp.tv_sec; - pbMonitoringData.timestamp.nanos = monitoringData.mTimestamp.tv_nsec; - - LOG_DBG() << "Send SM message: message = NodeMonitoring"; - - return SendPBMessage(ChannelEnum::eSecure, 0, &servicemanager_v3_SMOutgoingMessages_msg, outgoingMessage.Get()); -} - -aos::Error CMClient::SendNodeConfiguration() -{ - auto nodeInfo = aos::MakeUnique(&mAllocator); - auto outgoingMessage = aos::MakeUnique(&mAllocator); - auto& pbNodeConfiguration = outgoingMessage->SMOutgoingMessage.node_configuration; - - outgoingMessage->which_SMOutgoingMessage = servicemanager_v3_SMOutgoingMessages_node_configuration_tag; - pbNodeConfiguration = servicemanager_v3_NodeConfiguration servicemanager_v3_NodeConfiguration_init_default; - - auto err = mResourceMonitor->GetNodeInfo(*nodeInfo); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - StringToPB(cNodeID, pbNodeConfiguration.node_id); - StringToPB(cNodeType, pbNodeConfiguration.node_type); - pbNodeConfiguration.remote_node = true; - pbNodeConfiguration.runner_features_count = 1; - StringToPB(cRunner, pbNodeConfiguration.runner_features[0]); - pbNodeConfiguration.num_cpus = nodeInfo->mNumCPUs; - pbNodeConfiguration.total_ram = nodeInfo->mTotalRAM; - pbNodeConfiguration.partitions_count = nodeInfo->mPartitions.Size(); - - for (size_t i = 0; i < nodeInfo->mPartitions.Size(); ++i) { - StringToPB(nodeInfo->mPartitions[i].mName, pbNodeConfiguration.partitions[i].name); - pbNodeConfiguration.partitions[i].total_size = nodeInfo->mPartitions[i].mTotalSize; - pbNodeConfiguration.partitions[i].types_count = nodeInfo->mPartitions[i].mTypes.Size(); - - for (size_t j = 0; j < nodeInfo->mPartitions[i].mTypes.Size(); ++j) { - StringToPB(nodeInfo->mPartitions[i].mTypes[j], pbNodeConfiguration.partitions[i].types[j]); - } - } - - LOG_DBG() << "Send SM message: message = NodeConfiguration"; - - return SendPBMessage(ChannelEnum::eSecure, 0, &servicemanager_v3_SMOutgoingMessages_msg, outgoingMessage.Get()); -} - -aos::Error CMClient::SendClockSyncRequest() -{ - auto outgoingMessage = aos::MakeUnique(&mAllocator); - auto& pbClockSyncRequest = outgoingMessage->SMOutgoingMessage.clock_sync_request; - - outgoingMessage->which_SMOutgoingMessage = servicemanager_v3_SMOutgoingMessages_clock_sync_request_tag; - pbClockSyncRequest = servicemanager_v3_ClockSyncRequest servicemanager_v3_ClockSyncRequest_init_default; - - LOG_DBG() << "Send SM message: message = ClockSyncRequest"; - - return SendPBMessage(ChannelEnum::eOpen, 0, &servicemanager_v3_SMOutgoingMessages_msg, outgoingMessage.Get()); -} - -/*********************************************************************************************************************** - * Private - **********************************************************************************************************************/ - -aos::Error CMClient::ProcessMessage(Channel channel, PBServiceItf& service, const aos::String& methodName, - uint64_t requestID, const aos::Array& data) -{ - auto message = aos::MakeUnique(&mAllocator); - auto stream = pb_istream_from_buffer(data.Get(), data.Size()); - - auto status = pb_decode(&stream, &servicemanager_v3_SMIncomingMessages_msg, message.Get()); - if (!status) { - LOG_ERR() << "Can't decode incoming message: " << PB_GET_ERROR(&stream); - return AOS_ERROR_WRAP(aos::ErrorEnum::eRuntime); - } - - aos::Error err; - - if (channel == ChannelEnum::eOpen) { - switch (message->which_SMIncomingMessage) { - case servicemanager_v3_SMIncomingMessages_clock_sync_tag: - err = ProcessClockSync(message->SMIncomingMessage.clock_sync); - break; - - default: - LOG_WRN() << "Receive unsupported message tag: " << message->which_SMIncomingMessage; - break; - } - } - - if (channel == ChannelEnum::eSecure) { - switch (message->which_SMIncomingMessage) { - case servicemanager_v3_SMIncomingMessages_get_unit_config_status_tag: - err = ProcessGetUnitConfigStatus(channel, requestID); - break; - - case servicemanager_v3_SMIncomingMessages_check_unit_config_tag: - err = ProcessCheckUnitConfig(channel, requestID, message->SMIncomingMessage.check_unit_config); - break; - - case servicemanager_v3_SMIncomingMessages_set_unit_config_tag: - err = ProcessSetUnitConfig(channel, requestID, message->SMIncomingMessage.set_unit_config); - break; - - case servicemanager_v3_SMIncomingMessages_run_instances_tag: - err = ProcessRunInstances(message->SMIncomingMessage.run_instances); - break; - - case servicemanager_v3_SMIncomingMessages_image_content_info_tag: - err = ProcessImageContentInfo(message->SMIncomingMessage.image_content_info); - break; - - case servicemanager_v3_SMIncomingMessages_image_content_tag: - err = ProcessImageContent(message->SMIncomingMessage.image_content); - break; - - default: - LOG_WRN() << "Receive unsupported message tag: " << message->which_SMIncomingMessage; - break; - } - } - - return err; -} - -aos::Error CMClient::ProcessGetUnitConfigStatus(Channel channel, uint64_t requestID) -{ - LOG_DBG() << "Receive SM message: message = GetUnitConfigStatus"; - - auto outgoingMessage = aos::MakeUnique(&mAllocator); - auto& pbConfigStatus = outgoingMessage->SMOutgoingMessage.unit_config_status; - - outgoingMessage->which_SMOutgoingMessage = servicemanager_v3_SMOutgoingMessages_unit_config_status_tag; - pbConfigStatus = servicemanager_v3_UnitConfigStatus_init_default; - - aos::Error err; - aos::StaticString version; - - aos::Tie(version, err) = mResourceManager->GetVersion(); - if (!err.IsNone()) { - err = AOS_ERROR_WRAP(err); - ErrorToPB(err, pbConfigStatus.error); - } - - StringToPB(version, pbConfigStatus.vendor_version); - - LOG_DBG() << "Send SM message: message = UnitConfigStatus"; - - auto sendErr = SendPBMessage(channel, requestID, &servicemanager_v3_SMOutgoingMessages_msg, outgoingMessage.Get()); - if (!sendErr.IsNone() && err.IsNone()) { - err = sendErr; - } - - return err; -} - -aos::Error CMClient::ProcessCheckUnitConfig( - Channel channel, uint64_t requestID, const servicemanager_v3_CheckUnitConfig& pbUnitConfig) -{ - LOG_DBG() << "Receive SM message: message = CheckUnitConfig"; - - auto outgoingMessage = aos::MakeUnique(&mAllocator); - auto& pbConfigStatus = outgoingMessage->SMOutgoingMessage.unit_config_status; - - outgoingMessage->which_SMOutgoingMessage = servicemanager_v3_SMOutgoingMessages_unit_config_status_tag; - pbConfigStatus = servicemanager_v3_UnitConfigStatus_init_default; - - auto err = mResourceManager->CheckUnitConfig(pbUnitConfig.vendor_version, pbUnitConfig.unit_config); - if (!err.IsNone()) { - err = AOS_ERROR_WRAP(err); - ErrorToPB(err, pbConfigStatus.error); - } - - aos::StaticString version; - - PBToString(pbUnitConfig.vendor_version, version); - StringToPB(version, pbConfigStatus.vendor_version); - - LOG_DBG() << "Send SM message: message = UnitConfigStatus"; - - auto sendErr = SendPBMessage(channel, requestID, &servicemanager_v3_SMOutgoingMessages_msg, outgoingMessage.Get()); - if (!sendErr.IsNone() && err.IsNone()) { - err = sendErr; - } - - return err; -} - -aos::Error CMClient::ProcessSetUnitConfig( - Channel channel, uint64_t requestID, const servicemanager_v3_SetUnitConfig& pbUnitConfig) -{ - LOG_DBG() << "Receive SM message: message = SetUnitConfig"; - - auto outgoingMessage = aos::MakeUnique(&mAllocator); - auto& pbConfigStatus = outgoingMessage->SMOutgoingMessage.unit_config_status; - - outgoingMessage->which_SMOutgoingMessage = servicemanager_v3_SMOutgoingMessages_unit_config_status_tag; - pbConfigStatus = servicemanager_v3_UnitConfigStatus_init_default; - - auto err = mResourceManager->UpdateUnitConfig(pbUnitConfig.vendor_version, pbUnitConfig.unit_config); - if (!err.IsNone()) { - err = AOS_ERROR_WRAP(err); - ErrorToPB(err, pbConfigStatus.error); - } - - strncpy(pbConfigStatus.vendor_version, pbUnitConfig.vendor_version, sizeof(pbConfigStatus.vendor_version)); - - LOG_DBG() << "Send SM message: message = UnitConfigStatus"; - - auto sendErr = SendPBMessage(channel, requestID, &servicemanager_v3_SMOutgoingMessages_msg, outgoingMessage.Get()); - if (!sendErr.IsNone() && err.IsNone()) { - err = sendErr; - } - - return err; -} - -aos::Error CMClient::ProcessRunInstances(const servicemanager_v3_RunInstances& pbRunInstances) -{ - LOG_DBG() << "Receive SM message: message = RunInstances"; - - auto aosServices = aos::MakeUnique(&mAllocator); - - aosServices->Resize(pbRunInstances.services_count); - - for (auto i = 0; i < pbRunInstances.services_count; i++) { - const auto& pbService = pbRunInstances.services[i]; - auto& aosService = (*aosServices)[i]; - - if (pbService.has_version_info) { - PBToVersionInfo(pbService.version_info, aosService.mVersionInfo); - } - - PBToString(pbService.service_id, aosService.mServiceID); - PBToString(pbService.provider_id, aosService.mProviderID); - aosService.mGID = pbService.gid; - aosService.mURL = pbService.url; - PBToByteArray(pbService.sha256, aosService.mSHA256); - PBToByteArray(pbService.sha512, aosService.mSHA512); - aosService.mSize = pbService.size; - } - - auto aosLayers = aos::MakeUnique(&mAllocator); - - aosLayers->Resize(pbRunInstances.layers_count); - - for (auto i = 0; i < pbRunInstances.layers_count; i++) { - const auto& pbLayer = pbRunInstances.layers[i]; - auto& aosLayer = (*aosLayers)[i]; - - if (pbLayer.has_version_info) { - PBToVersionInfo(pbLayer.version_info, aosLayer.mVersionInfo); - } - - PBToString(pbLayer.layer_id, aosLayer.mLayerID); - PBToString(pbLayer.digest, aosLayer.mLayerDigest); - PBToString(pbLayer.url, aosLayer.mURL); - PBToByteArray(pbLayer.sha256, aosLayer.mSHA256); - PBToByteArray(pbLayer.sha512, aosLayer.mSHA512); - aosLayer.mSize = pbLayer.size; - } - - auto aosInstances = aos::MakeUnique(&mAllocator); - - aosInstances->Resize(pbRunInstances.instances_count); - - for (auto i = 0; i < pbRunInstances.instances_count; i++) { - const auto& pbInstance = pbRunInstances.instances[i]; - auto& aosInstance = (*aosInstances)[i]; - - if (pbInstance.has_instance) { - PBToString(pbInstance.instance.service_id, aosInstance.mInstanceIdent.mServiceID); - PBToString(pbInstance.instance.subject_id, aosInstance.mInstanceIdent.mSubjectID); - aosInstance.mInstanceIdent.mInstance = pbInstance.instance.instance; - } - - aosInstance.mUID = pbInstance.uid; - aosInstance.mPriority = pbInstance.priority; - PBToString(pbInstance.storage_path, aosInstance.mStoragePath); - PBToString(pbInstance.state_path, aosInstance.mStatePath); - } - - auto err = mLauncher->RunInstances(*aosServices, *aosLayers, *aosInstances, pbRunInstances.force_restart); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - return aos::ErrorEnum::eNone; -} - -aos::Error CMClient::ProcessImageContentInfo(const servicemanager_v3_ImageContentInfo& pbContentInfo) -{ - LOG_DBG() << "Receive SM message: message = ImageContentInfo"; - - auto aosContentInfo = aos::MakeUnique(&mAllocator); - - aosContentInfo->mRequestID = pbContentInfo.request_id; - - for (auto i = 0; i < pbContentInfo.image_files_count; i++) { - FileInfo fileInfo; - - PBToString(pbContentInfo.image_files[i].relative_path, fileInfo.mRelativePath); - PBToByteArray(pbContentInfo.image_files[i].sha256, fileInfo.mSHA256); - fileInfo.mSize = pbContentInfo.image_files[i].size; - - aosContentInfo->mFiles.PushBack(fileInfo); - } - - aosContentInfo->mError = pbContentInfo.error; - - auto err = mDownloader->ReceiveImageContentInfo(*aosContentInfo); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - return aos::ErrorEnum::eNone; -} - -aos::Error CMClient::ProcessImageContent(const servicemanager_v3_ImageContent& pbContent) -{ - LOG_DBG() << "Receive SM message: message = ImageContent"; - - auto chunk = aos::MakeUnique(&mAllocator); - - chunk->mRequestID = pbContent.request_id; - PBToString(pbContent.relative_path, chunk->mRelativePath); - chunk->mPartsCount = pbContent.parts_count; - chunk->mPart = pbContent.part; - PBToByteArray(pbContent.data, chunk->mData); - - auto err = mDownloader->ReceiveFileChunk(*chunk); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - return aos::ErrorEnum::eNone; -} - -aos::Error CMClient::ProcessClockSync(const servicemanager_v3_ClockSync& pbClockSync) -{ - LOG_DBG() << "Receive SM message: message = ClockSync"; - - if (!pbClockSync.has_current_time) { - return aos::ErrorEnum::eInvalidArgument; - } - - auto err = mClockSync->Sync(aos::Time::Unix(pbClockSync.current_time.seconds, pbClockSync.current_time.nanos)); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - return aos::ErrorEnum::eNone; -} diff --git a/src/communication/cmclient.hpp b/src/communication/cmclient.hpp deleted file mode 100644 index a4d1ea60..00000000 --- a/src/communication/cmclient.hpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef CMCLIENT_HPP_ -#define CMCLIENT_HPP_ - -#include -#include -#include - -#include - -#include "clocksync/clocksync.hpp" -#include "downloader/downloader.hpp" - -#include "messagehandler.hpp" - -/** - * Number of SM PB services. - */ -constexpr auto cSMServicesCount = 1; - -/** - * CM client instance. - */ -class CMClient : public MessageHandler { -public: - /** - * Creates CM client. - */ - CMClient() = default; - - /** - * Initializes CM client instance. - * - * @param launcher launcher instance. - * @param resourceManager resource manager instance. - * @param resourceMonitor resource monitor instance. - * @param downloader downloader instance. - * @param clockSync clock sync instance. - * @param messageSender message sender instance. - * @return aos::Error. - */ - aos::Error Init(aos::sm::launcher::LauncherItf& launcher, - aos::sm::resourcemanager::ResourceManagerItf& resourceManager, - aos::monitoring::ResourceMonitorItf& resourceMonitor, DownloadReceiverItf& downloader, ClockSyncItf& clockSync, - MessageSenderItf& messageSender); - - /** - * Sends instances run status. - * - * @param instances instances status array. - * @return Error. - */ - aos::Error InstancesRunStatus(const aos::Array& instances); - - /** - * Sends instances update status. - * @param instances instances status array. - * - * @return Error. - */ - aos::Error InstancesUpdateStatus(const aos::Array& instances); - - /** - * Send image content request - * - * @param request image content request - * @return Error. - */ - aos::Error SendImageContentRequest(const ImageContentRequest& request); - - /** - * Sends monitoring data - * - * @param monitoringData monitoring data - * @return Error. - */ - aos::Error SendMonitoringData(const aos::monitoring::NodeMonitoringData& monitoringData); - - /** - * Sends node configuration. - * - * @return Error. - */ - aos::Error SendNodeConfiguration(); - - /** - * Sends clock sync request. - * - * @return Error. - */ - aos::Error SendClockSyncRequest(); - -private: - static constexpr auto cMethodCount = 1; - static constexpr auto cRunner = "xrun"; - - aos::Error ProcessMessage(Channel channel, PBServiceItf& service, const aos::String& methodName, uint64_t requestID, - const aos::Array& data) override; - aos::Error ProcessGetUnitConfigStatus(Channel channel, uint64_t requestID); - aos::Error ProcessCheckUnitConfig( - Channel channel, uint64_t requestID, const servicemanager_v3_CheckUnitConfig& pbUnitConfig); - aos::Error ProcessSetUnitConfig( - Channel channel, uint64_t requestID, const servicemanager_v3_SetUnitConfig& pbUnitConfig); - aos::Error ProcessRunInstances(const servicemanager_v3_RunInstances& pbRunInstances); - aos::Error ProcessImageContentInfo(const servicemanager_v3_ImageContentInfo& pbContentInfo); - aos::Error ProcessImageContent(const servicemanager_v3_ImageContent& pbContent); - aos::Error ProcessClockSync(const servicemanager_v3_ClockSync& pbClockSync); - - aos::sm::launcher::LauncherItf* mLauncher {}; - aos::sm::resourcemanager::ResourceManagerItf* mResourceManager {}; - aos::monitoring::ResourceMonitorItf* mResourceMonitor {}; - DownloadReceiverItf* mDownloader {}; - ClockSyncItf* mClockSync {}; - - aos::StaticAllocator - mAllocator; - - PBService mSMService; -}; - -#endif diff --git a/src/communication/communication.cpp b/src/communication/communication.cpp deleted file mode 100644 index fb527d37..00000000 --- a/src/communication/communication.cpp +++ /dev/null @@ -1,490 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include - -#include "utils/checksum.hpp" - -#include - -#include "communication.hpp" -#include "log.hpp" - -/*********************************************************************************************************************** - * Public - **********************************************************************************************************************/ - -Communication::~Communication() -{ - { - aos::LockGuard lock(mMutex); - - LOG_INF() << "Close communication channels"; - - for (auto i = 0; i < static_cast(ChannelEnum::eNumChannels); i++) { - if (mChannels[i]->IsConnected()) { - auto err = mChannels[i]->Close(); - if (!err.IsNone()) { - LOG_ERR() << "Can't close channel: " << err; - } - } - } - - mClose = true; - mCondVar.NotifyOne(); - } - - for (auto i = 0; i < static_cast(ChannelEnum::eNumChannels); i++) { - mChannelThreads[i].Join(); - } - - { - aos::LockGuard lock(mMutex); - - mConnectionSubscribers.Clear(); - } -} - -aos::Error Communication::Init(CommChannelItf& openChannel, CommChannelItf& secureChannel, - aos::sm::launcher::LauncherItf& launcher, aos::iam::certhandler::CertHandlerItf& certHandler, - aos::sm::resourcemanager::ResourceManagerItf& resourceManager, aos::monitoring::ResourceMonitorItf& resourceMonitor, - DownloadReceiverItf& downloader, ClockSyncItf& clockSync, ProvisioningItf& provisioning) -{ - LOG_DBG() << "Initialize communication"; - - mClockSync = &clockSync; - mProvisioning = &provisioning; - - auto err = mCMClient.Init(launcher, resourceManager, resourceMonitor, downloader, clockSync, *this); - if (!err.IsNone()) { - return err; - } - - err = mIAMServer.Init(certHandler, provisioning, *this); - if (!err.IsNone()) { - return err; - } - - mChannels[static_cast(ChannelEnum::eOpen)] = &openChannel; - mChannels[static_cast(ChannelEnum::eSecure)] = &secureChannel; - - err = StartChannelThreads(); - if (!err.IsNone()) { - return err; - } - - return aos::ErrorEnum::eNone; -} - -aos::Error Communication::InstancesRunStatus(const aos::Array& instances) -{ - aos::LockGuard lock(mMutex); - - return mCMClient.InstancesRunStatus(instances); -} - -aos::Error Communication::InstancesUpdateStatus(const aos::Array& instances) -{ - aos::LockGuard lock(mMutex); - - return mCMClient.InstancesUpdateStatus(instances); -} - -aos::Error Communication::SendImageContentRequest(const ImageContentRequest& request) -{ - aos::LockGuard lock(mMutex); - - return mCMClient.SendImageContentRequest(request); -} - -aos::Error Communication::SendMonitoringData(const aos::monitoring::NodeMonitoringData& monitoringData) -{ - aos::LockGuard lock(mMutex); - - return mCMClient.SendMonitoringData(monitoringData); -} - -aos::Error Communication::SendClockSyncRequest() -{ - aos::LockGuard lock(mMutex); - - return mCMClient.SendClockSyncRequest(); -} - -void Communication::ClockSynced() -{ - aos::LockGuard lock(mMutex); - - LOG_DBG() << "Clock synced"; - - mClockSynced = true; - mCondVar.NotifyOne(); -} - -void Communication::ClockUnsynced() -{ - aos::LockGuard lock(mMutex); - - LOG_WRN() << "Clock unsynced"; - - mClockSynced = false; - mCondVar.NotifyOne(); -} - -// cppcheck-suppress unusedFunction -aos::Error Communication::Subscribes(aos::ConnectionSubscriberItf& subscriber) -{ - aos::LockGuard lock(mMutex); - - auto err = mConnectionSubscribers.PushBack(&subscriber); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - return aos::ErrorEnum::eNone; -} - -// cppcheck-suppress unusedFunction -void Communication::Unsubscribes(aos::ConnectionSubscriberItf& subscriber) -{ - aos::LockGuard lock(mMutex); - - auto it = mConnectionSubscribers.Find(&subscriber); - if (it.mError.IsNone()) { - mConnectionSubscribers.Remove(it.mValue); - } -} - -/*********************************************************************************************************************** - * Private - **********************************************************************************************************************/ - -aos::Error Communication::StartChannelThreads() -{ - auto err = mChannelThreads[static_cast(ChannelEnum::eOpen)].Run( - [this](void*) { ChannelHandler(ChannelEnum::eOpen); }); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - err = mChannelThreads[static_cast(ChannelEnum::eSecure)].Run( - [this](void*) { ChannelHandler(ChannelEnum::eSecure); }); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - return aos::ErrorEnum::eNone; -} - -void Communication::ChannelHandler(Channel channel) -{ - while (true) { - aos::Error err; - - { - aos::UniqueLock lock(mMutex); - - if (mClose) { - return; - } - - err = ConnectChannel(lock, channel); - } - - if (!err.IsNone()) { - LOG_ERR() << "Can't connect to channel: channel = " << channel << ", err = " << err; - LOG_WRN() << "Reconnect in " << cConnectionTimeoutSec << " sec..."; - - sleep(cConnectionTimeoutSec); - - continue; - } - - err = ProcessMessages(channel); - if (!err.IsNone()) { - LOG_ERR() << "Error processing messages: channel = " << channel << ", err = " << err; - } - - { - aos::LockGuard lock(mMutex); - - if (mClose) { - return; - } - - err = CloseChannel(channel); - if (!err.IsNone()) { - LOG_ERR() << "Error closing channel: channel = " << channel << ", err = " << err; - } - } - } -} - -aos::Error Communication::WaitTimeSynced(aos::UniqueLock& lock) -{ - LOG_DBG() << "Wait open channel is connected..."; - - auto err - = mCondVar.Wait(lock, [this]() { return mChannels[Channel(ChannelEnum::eOpen)]->IsConnected() || mClose; }); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - if (mClose) { - return aos::ErrorEnum::eNone; - } - - err = mClockSync->Start(); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - LOG_DBG() << "Wait clock is synced..."; - - err = mCondVar.Wait(lock, [this]() { return mClockSynced || mClose; }); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - return aos::ErrorEnum::eNone; -} - -aos::Error Communication::ConnectChannel(aos::UniqueLock& lock, Channel channel) -{ - if (channel == ChannelEnum::eSecure) { - if (!mClockSynced) { - auto err = WaitTimeSynced(lock); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - if (mClose) { - return aos::ErrorEnum::eNone; - } - } - - if (mProvisioning->IsProvisioned()) { - LOG_INF() << "Set secure channel TLS config: certType = " << cSecureChannelCertType; - - auto err = mChannels[channel]->SetTLSConfig(cSecureChannelCertType); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - } - } - - auto err = mChannels[channel]->Connect(); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - LOG_INF() << "Channel connected: channel = " << channel; - - mCondVar.NotifyOne(); - - if (GetNumConnectedChannels() == static_cast(ChannelEnum::eNumChannels) && mProvisioning->IsProvisioned()) { - err = mCMClient.SendNodeConfiguration(); - if (!err.IsNone()) { - LOG_ERR() << "Can't send node configuration: " << err; - } - - ConnectNotification(true); - } - - return aos::ErrorEnum::eNone; -} - -aos::Error Communication::CloseChannel(Channel channel) -{ - auto err = mChannels[channel]->Close(); - - LOG_DBG() << "Channel closed: channel = " << channel; - - if (GetNumConnectedChannels() == static_cast(ChannelEnum::eNumChannels) - 1) { - ConnectNotification(false); - } - - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - return aos::ErrorEnum::eNone; -} - -aos::Error Communication::SendMessage(Channel channel, AosVChanSource source, const aos::String& methodName, - uint64_t requestID, const aos::Array data, aos::Error messageError) -{ - LOG_DBG() << "Send message: channel = " << channel << ", source = " << source << ", method = " << methodName - << ", size = " << data.Size() << " error = " << messageError; - - VChanMessageHeader header = {source, static_cast(data.Size()), requestID, messageError.Errno(), - static_cast(messageError.Value())}; - - if (data.Size()) { - auto checksum = CalculateSha256(data); - if (!checksum.mError.IsNone()) { - return AOS_ERROR_WRAP(checksum.mError); - } - - aos::Array(reinterpret_cast(header.mSha256), aos::cSHA256Size) = checksum.mValue; - } - - auto err - = WriteMessage(channel, aos::Array(reinterpret_cast(&header), sizeof(VChanMessageHeader))); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - err = WriteMessage(channel, data); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - return aos::ErrorEnum::eNone; -} - -aos::Error Communication::ProcessMessages(Channel channel) -{ - auto headerData = aos::StaticArray(); - - while (true) { - auto err = ReadMessage(channel, headerData, sizeof(VChanMessageHeader)); - if (!err.IsNone()) { - return err; - } - - auto header = reinterpret_cast(headerData.Get()); - - LOG_DBG() << "Receive message: channel = " << channel << ", source = " << header->mSource - << ", method = " << header->mMethodName << ", size = " << header->mDataSize; - - MessageHandlerItf* handler = nullptr; - - switch (header->mSource) { - case AOS_VCHAN_SM: - handler = &mCMClient; - break; - - case AOS_VCHAN_IAM: - handler = &mIAMServer; - break; - - default: - LOG_ERR() << "Wrong source received: " << header->mSource; - - continue; - } - - if (header->mDataSize > handler->GetReceiveBuffer().Size()) { - LOG_ERR() << "Not enough mem in receive buffer"; - continue; - } - - aos::Array data( - static_cast(handler->GetReceiveBuffer().Get()), handler->GetReceiveBuffer().Size()); - - if (header->mDataSize) { - err = ReadMessage(channel, data, header->mDataSize); - if (!err.IsNone()) { - return err; - } - - auto checksum = CalculateSha256(data); - if (!checksum.mError.IsNone()) { - LOG_ERR() << "Can't calculate checksum: " << checksum.mError; - continue; - } - - if (checksum.mValue != aos::Array(header->mSha256, aos::cSHA256Size)) { - LOG_ERR() << "Checksum error"; - continue; - } - } - - aos::LockGuard lock(mMutex); - - err = handler->ReceiveMessage(channel, header->mMethodName, header->mRequestID, data); - if (!err.IsNone()) { - LOG_ERR() << "Error processing message: " << err; - } - } -} - -size_t Communication::GetNumConnectedChannels() -{ - size_t count = 0; - - for (auto i = 0; i < static_cast(ChannelEnum::eNumChannels); i++) { - if (mChannels[i]->IsConnected()) { - count++; - } - } - - return count; -} - -void Communication::ConnectNotification(bool connected) -{ - LOG_INF() << "Connection notification: " << (connected ? "connected" : "disconnected"); - - for (auto& subscriber : mConnectionSubscribers) { - if (connected) { - subscriber->OnConnect(); - } else { - subscriber->OnDisconnect(); - } - } -} - -aos::Error Communication::ReadMessage(Channel channel, aos::Array& data, size_t size) -{ - size_t read = 0; - - auto err = data.Resize(size); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - while (read < size) { - auto ret = mChannels[channel]->Read(data.Get() + read, size - read); - if (ret < 0) { - return AOS_ERROR_WRAP(ret); - } - - read += ret; - } - - assert(read <= data.MaxSize()); - - if (read != size) { - return AOS_ERROR_WRAP(aos::ErrorEnum::eFailed); - } - - return aos::ErrorEnum::eNone; -} - -aos::Error Communication::WriteMessage(Channel channel, const aos::Array& data) -{ - size_t written = 0; - - while (written < data.Size()) { - auto ret = mChannels[channel]->Write(data.Get() + written, data.Size() - written); - if (ret < 0) { - return AOS_ERROR_WRAP(ret); - } - - written += ret; - } - - if (written != data.Size()) { - return AOS_ERROR_WRAP(aos::ErrorEnum::eFailed); - } - - return aos::ErrorEnum::eNone; -} diff --git a/src/communication/communication.hpp b/src/communication/communication.hpp deleted file mode 100644 index a526d672..00000000 --- a/src/communication/communication.hpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef COMMUNICATION_HPP_ -#define COMMUNICATION_HPP_ - -#include -#include -#include - -#include "channeltype.hpp" -#include "cmclient.hpp" -#include "commchannel.hpp" -#include "iamserver.hpp" - -/** - * Communication instance. - */ -class Communication : public aos::sm::launcher::InstanceStatusReceiverItf, - public DownloadRequesterItf, - public aos::monitoring::SenderItf, - public ClockSyncSenderItf, - public aos::ConnectionPublisherItf, - private MessageSenderItf, - private aos::NonCopyable { -public: - /** - * Initializes communication instance. - * - * @param openChannel open channel instance. - * @param secureChannel secure channel instance. - * @param launcher launcher instance. - * @param certHandler certificate handler instance. - * @param resourceManager resource manager instance. - * @param resourceMonitor resource monitor instance. - * @param downloader downloader instance. - * @param clockSync clock sync instance. - * @param provisioning provisioning instance. - * @return aos::Error. - */ - aos::Error Init(CommChannelItf& openChannel, CommChannelItf& secureChannel, - aos::sm::launcher::LauncherItf& launcher, aos::iam::certhandler::CertHandlerItf& certHandler, - aos::sm::resourcemanager::ResourceManagerItf& resourceManager, - aos::monitoring::ResourceMonitorItf& resourceMonitor, DownloadReceiverItf& downloader, ClockSyncItf& clockSync, - ProvisioningItf& provisioning); - - /** - * Destructor. - */ - ~Communication(); - - /** - * Sends instances run status. - * - * @param instances instances status array. - * @return Error. - */ - aos::Error InstancesRunStatus(const aos::Array& instances) override; - - /** - * Sends instances update status. - * @param instances instances status array. - * - * @return Error. - */ - aos::Error InstancesUpdateStatus(const aos::Array& instances) override; - - /** - * Send image content request - * - * @param request image content request - * @return Error - */ - aos::Error SendImageContentRequest(const ImageContentRequest& request) override; - - /** - * Sends monitoring data - * - * @param monitoringData monitoring data - * @return Error - */ - aos::Error SendMonitoringData(const aos::monitoring::NodeMonitoringData& monitoringData) override; - - /** - * Sends clock sync request. - * - * @return Error. - */ - aos::Error SendClockSyncRequest() override; - - /** - * Notifies sender that clock is synced. - */ - void ClockSynced() override; - - /** - * Notifies sender that clock is unsynced. - */ - void ClockUnsynced() override; - - /** - * Subscribes the provided ConnectionSubscriberItf to this object. - * - * @param subscriber The ConnectionSubscriberItf that wants to subscribe. - */ - virtual aos::Error Subscribes(aos::ConnectionSubscriberItf& subscriber) override; - - /** - * Unsubscribes the provided ConnectionSubscriberItf from this object. - * - * @param subscriber The ConnectionSubscriberItf that wants to unsubscribe. - */ - virtual void Unsubscribes(aos::ConnectionSubscriberItf& subscriber) override; - -private: - static constexpr auto cThreadStackSize = 16384; - static constexpr auto cMaxSubscribers = 2; - static constexpr auto cConnectionTimeoutSec = 5; - static constexpr auto cSecureChannelCertType = "sm"; - - aos::Error SendMessage(Channel channel, AosVChanSource source, const aos::String& methodName, uint64_t requestID, - const aos::Array data, aos::Error messageError) override; - void ConnectNotification(bool connected); - aos::Error StartChannelThreads(); - void ChannelHandler(Channel channel); - aos::Error WaitTimeSynced(aos::UniqueLock& lock); - aos::Error ConnectChannel(aos::UniqueLock& lock, Channel channel); - aos::Error CloseChannel(Channel channel); - size_t GetNumConnectedChannels(); - aos::Error ProcessMessages(Channel channel); - aos::Error ReadMessage(Channel channel, aos::Array& data, size_t size); - aos::Error WriteMessage(Channel channel, const aos::Array& data); - - aos::Mutex mMutex; - aos::ConditionalVariable mCondVar; - aos::Thread - mChannelThreads[static_cast(ChannelEnum::eNumChannels)]; - - CommChannelItf* mChannels[static_cast(ChannelEnum::eNumChannels)] {}; - bool mClose = false; - - aos::StaticArray mConnectionSubscribers; - - ClockSyncItf* mClockSync {}; - ProvisioningItf* mProvisioning {}; - - CMClient mCMClient; - IAMServer mIAMServer; - - bool mClockSynced = false; -}; - -#endif diff --git a/src/communication/iamserver.cpp b/src/communication/iamserver.cpp deleted file mode 100644 index 11035e02..00000000 --- a/src/communication/iamserver.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (C) 2024 Renesas Electronics Corporation. - * Copyright (C) 2024 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#include "utils/pbconvert.hpp" - -#include "iamserver.hpp" -#include "log.hpp" - -/*********************************************************************************************************************** - * Public - **********************************************************************************************************************/ - -aos::Error IAMServer::Init( - aos::iam::certhandler::CertHandlerItf& certHandler, ProvisioningItf& provisioning, MessageSenderItf& messageSender) -{ - LOG_DBG() << "Initialize IAM server"; - - auto err = MessageHandler::Init(AOS_VCHAN_IAM, messageSender); - if (!err.IsNone()) { - return err; - } - - mCertHandler = &certHandler; - mProvisioning = &provisioning; - mMessageSender = &messageSender; - - aos::StaticString fullMethodName; - - // Provisioning service - - if (!(err = mProvisioningService.Init(cServiceProvisioning)).IsNone()) { - return err; - } - - mProvisioningService.RegisterMethod(cMethodGetAllNodeIDs); - mProvisioningService.RegisterMethod(cMethodGetCertTypes); - mProvisioningService.RegisterMethod(cMethodSetOwner); - mProvisioningService.RegisterMethod(cMethodClear); - mProvisioningService.RegisterMethod(cMethodEncryptDisk); - mProvisioningService.RegisterMethod(cMethodFinishProvisioning); - - mProvisioningService.GetFullMethodName(cMethodGetAllNodeIDs, fullMethodName); - mHandlers.EmplaceBack(MethodHandler {fullMethodName, &IAMServer::ProcessGetAllNodeIDs}); - mProvisioningService.GetFullMethodName(cMethodGetCertTypes, fullMethodName); - mHandlers.EmplaceBack(MethodHandler {fullMethodName, &IAMServer::ProcessGetGetCertTypes}); - mProvisioningService.GetFullMethodName(cMethodSetOwner, fullMethodName); - mHandlers.EmplaceBack(MethodHandler {fullMethodName, &IAMServer::ProcessSetOwner}); - mProvisioningService.GetFullMethodName(cMethodClear, fullMethodName); - mHandlers.EmplaceBack(MethodHandler {fullMethodName, &IAMServer::ProcessClear}); - mProvisioningService.GetFullMethodName(cMethodEncryptDisk, fullMethodName); - mHandlers.EmplaceBack(MethodHandler {fullMethodName, &IAMServer::ProcessEncryptDisk}); - mProvisioningService.GetFullMethodName(cMethodFinishProvisioning, fullMethodName); - mHandlers.EmplaceBack(MethodHandler {fullMethodName, &IAMServer::ProcessFinishProvisioning}); - - // Certificate service - - if (!(err = mCertificateService.Init(cServiceCertificate)).IsNone()) { - return err; - } - - mCertificateService.RegisterMethod(cMethodCreateKey); - mCertificateService.RegisterMethod(cMethodApplyCert); - - mCertificateService.GetFullMethodName(cMethodCreateKey, fullMethodName); - mHandlers.EmplaceBack(MethodHandler {fullMethodName, &IAMServer::ProcessCreateKey}); - mCertificateService.GetFullMethodName(cMethodApplyCert, fullMethodName); - mHandlers.EmplaceBack(MethodHandler {fullMethodName, &IAMServer::ProcessApplyCert}); - - // Register services - - if (!mProvisioning->IsProvisioned()) { - if (!(err = RegisterService(mProvisioningService, ChannelEnum::eSecure)).IsNone()) { - return err; - } - } - - if (!(err = RegisterService(mCertificateService, ChannelEnum::eSecure)).IsNone()) { - return err; - } - - return aos::ErrorEnum::eNone; -} - -/*********************************************************************************************************************** - * Private - **********************************************************************************************************************/ - -aos::Error IAMServer::ProcessMessage(Channel channel, PBServiceItf& service, const aos::String& methodName, - uint64_t requestID, const aos::Array& data) -{ - LOG_DBG() << "Receive IAM message: " - << "service = " << service.GetServiceName() << ", method = " << methodName; - - auto fullMethodName = aos::MakeUnique>(&mAllocator); - - auto err = service.GetFullMethodName(methodName, *fullMethodName); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - auto methodHandler - = mHandlers.Find([&fullMethodName](const auto& item) { return item.mMethodName == *fullMethodName; }); - if (!methodHandler.mError.IsNone()) { - return AOS_ERROR_WRAP(methodHandler.mError); - } - - return (this->*methodHandler.mValue->mCallback)(channel, requestID, data); -} - -aos::Error IAMServer::ProcessGetAllNodeIDs(Channel channel, uint64_t requestID, const aos::Array& data) -{ - iamanager_v4_NodesID nodesID iamanager_v4_NodesID_init_default; - - nodesID.ids_count = 1; - StringToPB(cNodeID, nodesID.ids[0]); - - auto err = SendPBMessage(channel, requestID, &iamanager_v4_NodesID_msg, &nodesID); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - return aos::ErrorEnum::eNone; -} - -aos::Error IAMServer::ProcessGetGetCertTypes(Channel channel, uint64_t requestID, const aos::Array& data) -{ - aos::StaticArray, - aos::iam::certhandler::cIAMCertModulesMaxCount> - aosCertTypes; - iamanager_v4_CertTypes pbCertTypes iamanager_v4_CertTypes_init_default; - - auto err = mCertHandler->GetCertTypes(aosCertTypes); - if (err.IsNone()) { - pbCertTypes.types_count = aosCertTypes.Size(); - - for (size_t i = 0; i < aosCertTypes.Size(); i++) { - StringToPB(aosCertTypes[i], pbCertTypes.types[i]); - } - } - - auto sendErr = SendPBMessage(channel, requestID, &iamanager_v4_CertTypes_msg, &pbCertTypes, err); - if (!sendErr.IsNone() && err.IsNone()) { - err = sendErr; - } - - return AOS_ERROR_WRAP(err); -} - -aos::Error IAMServer::ProcessSetOwner(Channel channel, uint64_t requestID, const aos::Array& data) -{ - iamanager_v4_SetOwnerRequest pbSetOwner iamanager_v4_SetOwnerRequest_init_default; - - auto err = DecodePBMessage(data, &iamanager_v4_SetOwnerRequest_msg, &pbSetOwner); - - if (err.IsNone()) { - err = CheckPBNodeID(pbSetOwner.node_id); - } - - if (err.IsNone()) { - err = mCertHandler->SetOwner(pbSetOwner.type, pbSetOwner.password); - } - - auto sendErr = SendPBMessage(channel, requestID, nullptr, nullptr, err); - if (!sendErr.IsNone() && err.IsNone()) { - err = sendErr; - } - - return AOS_ERROR_WRAP(err); -} - -aos::Error IAMServer::ProcessClear(Channel channel, uint64_t requestID, const aos::Array& data) -{ - iamanager_v4_ClearRequest pbClear iamanager_v4_ClearRequest_init_default; - - auto err = DecodePBMessage(data, &iamanager_v4_ClearRequest_msg, &pbClear); - - if (err.IsNone()) { - err = CheckPBNodeID(pbClear.node_id); - } - - if (err.IsNone()) { - err = mCertHandler->Clear(pbClear.type); - } - - auto sendErr = SendPBMessage(channel, requestID, nullptr, nullptr, err); - if (!sendErr.IsNone() && err.IsNone()) { - err = sendErr; - } - - return AOS_ERROR_WRAP(err); -} - -aos::Error IAMServer::ProcessEncryptDisk(Channel channel, uint64_t requestID, const aos::Array& data) -{ - iamanager_v4_EncryptDiskRequest pbEncryptDisk iamanager_v4_EncryptDiskRequest_init_default; - - auto err = DecodePBMessage(data, &iamanager_v4_EncryptDiskRequest_msg, &pbEncryptDisk); - - if (err.IsNone()) { - err = CheckPBNodeID(pbEncryptDisk.node_id); - } - - if (err.IsNone()) { - err = AOS_ERROR_WRAP(aos::ErrorEnum::eNotSupported); - - LOG_ERR() << "Disk encryption error: " << err; - } - - auto sendErr = SendPBMessage(channel, requestID, nullptr, nullptr, err); - if (!sendErr.IsNone() && err.IsNone()) { - err = sendErr; - } - - return AOS_ERROR_WRAP(err); -} - -aos::Error IAMServer::ProcessFinishProvisioning(Channel channel, uint64_t requestID, const aos::Array& data) -{ - aos::Error messageError; - - auto err = RemoveService(mProvisioningService, ChannelEnum::eSecure); - if (!err.IsNone() && !messageError.IsNone()) { - messageError = err; - } - - err = mProvisioning->FinishProvisioning(); - if (!err.IsNone() && !messageError.IsNone()) { - messageError = err; - } - - auto sendErr = SendPBMessage(channel, requestID, nullptr, nullptr, messageError); - if (!sendErr.IsNone() && err.IsNone()) { - err = sendErr; - } - - return AOS_ERROR_WRAP(err); -} - -aos::Error IAMServer::ProcessCreateKey(Channel channel, uint64_t requestID, const aos::Array& data) -{ - auto pbCreateKeyRequest = aos::MakeUnique(&mAllocator); - auto pbCreateKeyResponse = aos::MakeUnique(&mAllocator); - - auto err = DecodePBMessage(data, &iamanager_v4_CreateKeyRequest_msg, pbCreateKeyRequest.Get()); - - strncpy(pbCreateKeyResponse->node_id, pbCreateKeyRequest->node_id, sizeof(pbCreateKeyResponse->node_id)); - strncpy(pbCreateKeyResponse->type, pbCreateKeyRequest->type, sizeof(pbCreateKeyResponse->type)); - - if (err.IsNone()) { - err = CheckPBNodeID(pbCreateKeyRequest->node_id); - } - - if (err.IsNone()) { - auto csr = aos::String(pbCreateKeyResponse->csr, sizeof(pbCreateKeyResponse->csr) - 1); - - err = mCertHandler->CreateKey( - pbCreateKeyRequest->type, pbCreateKeyRequest->subject, pbCreateKeyRequest->password, csr); - - pbCreateKeyResponse->csr[csr.Size()] = 0; - } - - auto sendErr - = SendPBMessage(channel, requestID, &iamanager_v4_CreateKeyResponse_msg, pbCreateKeyResponse.Get(), err); - if (!sendErr.IsNone() && err.IsNone()) { - err = sendErr; - } - - return AOS_ERROR_WRAP(err); -} - -aos::Error IAMServer::ProcessApplyCert(Channel channel, uint64_t requestID, const aos::Array& data) -{ - auto pbApplyCertRequest = aos::MakeUnique(&mAllocator); - auto pbApplyCertResponse = aos::MakeUnique(&mAllocator); - - auto err = DecodePBMessage(data, &iamanager_v4_ApplyCertRequest_msg, pbApplyCertRequest.Get()); - - strncpy(pbApplyCertResponse->node_id, pbApplyCertRequest->node_id, sizeof(pbApplyCertResponse->node_id)); - strncpy(pbApplyCertResponse->type, pbApplyCertRequest->type, sizeof(pbApplyCertResponse->type)); - - if (err.IsNone()) { - err = CheckPBNodeID(pbApplyCertRequest->node_id); - } - - if (err.IsNone()) { - auto certInfo = aos::MakeUnique(&mAllocator); - - err = mCertHandler->ApplyCertificate(pbApplyCertRequest->type, pbApplyCertRequest->cert, *certInfo); - if (err.IsNone()) { - StringToPB(certInfo->mCertURL, pbApplyCertResponse->cert_url); - err = aos::String(pbApplyCertResponse->serial, sizeof(pbApplyCertResponse->serial) - 1) - .ByteArrayToHex(certInfo->mSerial); - } - } - - auto sendErr - = SendPBMessage(channel, requestID, &iamanager_v4_ApplyCertResponse_msg, pbApplyCertResponse.Get(), err); - if (!sendErr.IsNone() && err.IsNone()) { - err = sendErr; - } - - return AOS_ERROR_WRAP(err); -} - -aos::Error IAMServer::DecodePBMessage(const aos::Array& data, const pb_msgdesc_t* fields, void* message) -{ - auto stream = pb_istream_from_buffer(data.Get(), data.Size()); - - auto status = pb_decode(&stream, fields, message); - if (!status) { - LOG_ERR() << "Can't decode incoming message: " << PB_GET_ERROR(&stream); - - return AOS_ERROR_WRAP(aos::ErrorEnum::eRuntime); - } - - return aos::ErrorEnum::eNone; -} - -template -aos::Error IAMServer::CheckPBNodeID(const char (&pbNodeID)[cSize]) -{ - if (strncmp(pbNodeID, cNodeID, cSize) != 0) { - LOG_ERR() << "Wrong node ID: " << pbNodeID; - - return aos::ErrorEnum::eFailed; - } - - return aos::ErrorEnum::eNone; -} diff --git a/src/communication/iamserver.hpp b/src/communication/iamserver.hpp deleted file mode 100644 index e3aa09db..00000000 --- a/src/communication/iamserver.hpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2024 Renesas Electronics Corporation. - * Copyright (C) 2024 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef IAMSERVER_HPP_ -#define IAMSERVER_HPP_ - -#include - -#include - -#include "provisioning/provisioning.hpp" - -#include "messagehandler.hpp" - -/** - * Number of IAM PB services. - */ -constexpr auto cIAMServicesCount = 2; - -/** - * IAM server instance. - */ -class IAMServer : public MessageHandler { -public: - /* - * IAM provisioning service. - */ - static constexpr auto cServiceProvisioning = "iamanager.v4.IAMProvisioningService"; - static constexpr auto cMethodGetAllNodeIDs = "GetAllNodeIDs"; - static constexpr auto cMethodGetCertTypes = "GetCertTypes"; - static constexpr auto cMethodSetOwner = "SetOwner"; - static constexpr auto cMethodClear = "Clear"; - static constexpr auto cMethodEncryptDisk = "EncryptDisk"; - static constexpr auto cMethodFinishProvisioning = "FinishProvisioning"; - - /* - * IAM certificate service. - */ - static constexpr auto cServiceCertificate = "iamanager.v4.IAMCertificateService"; - static constexpr auto cMethodCreateKey = "CreateKey"; - static constexpr auto cMethodApplyCert = "ApplyCert"; - - /** - * Creates IAM server. - */ - IAMServer() = default; - - /** - * Initializes CM client instance. - * - * @param certHandler certificate handler instance. - * @param provisioning provisioning instance. - * @param messageSender message sender instance. - * @return aos::Error. - */ - aos::Error Init(aos::iam::certhandler::CertHandlerItf& certHandler, ProvisioningItf& provisioning, - MessageSenderItf& messageSender); - -private: - static constexpr auto cProvisioningServiceMethodCount = 6; - static constexpr auto cCertificateServiceMethodCount = 2; - - typedef aos::Error (IAMServer::*MethodCallback)( - Channel channel, uint64_t requestID, const aos::Array& data); - - struct MethodHandler { - aos::StaticString mMethodName; - MethodCallback mCallback; - }; - - aos::Error ProcessMessage(Channel channel, PBServiceItf& service, const aos::String& methodName, uint64_t requestID, - const aos::Array& data) override; - aos::Error ProcessGetAllNodeIDs(Channel channel, uint64_t requestID, const aos::Array& data); - aos::Error ProcessGetGetCertTypes(Channel channel, uint64_t requestID, const aos::Array& data); - aos::Error ProcessSetOwner(Channel channel, uint64_t requestID, const aos::Array& data); - aos::Error ProcessClear(Channel channel, uint64_t requestID, const aos::Array& data); - aos::Error ProcessEncryptDisk(Channel channel, uint64_t requestID, const aos::Array& data); - aos::Error ProcessFinishProvisioning(Channel channel, uint64_t requestID, const aos::Array& data); - aos::Error ProcessCreateKey(Channel channel, uint64_t requestID, const aos::Array& data); - aos::Error ProcessApplyCert(Channel channel, uint64_t requestID, const aos::Array& data); - aos::Error DecodePBMessage(const aos::Array& data, const pb_msgdesc_t* fields, void* message); - template - aos::Error CheckPBNodeID(const char (&pbNodeID)[cSize]); - - aos::iam::certhandler::CertHandlerItf* mCertHandler {}; - ProvisioningItf* mProvisioning {}; - MessageSenderItf* mMessageSender {}; - - PBService mProvisioningService; - PBService mCertificateService; - - aos::StaticArray mHandlers; - - aos::StaticAllocator) - + aos::Max(sizeof(iamanager_v4_CreateKeyRequest) + sizeof(iamanager_v4_CreateKeyResponse), - sizeof(iamanager_v4_ApplyCertRequest) + sizeof(iamanager_v4_ApplyCertResponse) - + sizeof(aos::iam::certhandler::CertInfo))> - mAllocator; -}; - -#endif diff --git a/src/communication/messagehandler.hpp b/src/communication/messagehandler.hpp deleted file mode 100644 index 41e39605..00000000 --- a/src/communication/messagehandler.hpp +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (C) 2024 Renesas Electronics Corporation. - * Copyright (C) 2024 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef MESSAGEHANDLER_HPP_ -#define MESSAGEHANDLER_HPP_ - -#include -#include - -#include -#include - -#include "channeltype.hpp" - -/** - * Max service length. - */ -constexpr auto cMaxServiceLen = 128; - -/** - * Max method length. - */ -constexpr auto cMaxMethodLen = 128; - -/** - * Interface to send messages. - */ -class MessageSenderItf { -public: - /** - * Sends raw message. - * - * @param channel channel to send message. - * @param source message source. - * @param methodName message method name. - * @param requestID request ID. - * @param data message data. - * @param messageError message error. - * @return aos::Error. - */ - virtual aos::Error SendMessage(Channel channel, AosVChanSource source, const aos::String& methodName, - uint64_t requestID, const aos::Array data, aos::Error messageError) - = 0; - - /** - * Destroys message sender. - */ - virtual ~MessageSenderItf() = default; -}; - -/** - * Protobuf service interface. - */ -class PBServiceItf { -public: - /** - * Returns service name. - * - * @return aos::String. - */ - virtual const aos::String& GetServiceName() const = 0; - - /** - * Registers method in service. - * - * @param methodName message method name. - * @return aos::Error. - */ - virtual aos::Error RegisterMethod(const aos::String& methodName) = 0; - - /** - * Checks if method is registered. - * - * @param methodName - * @return bool. - */ - virtual bool IsMethodRegistered(const aos::String& methodName) const = 0; - - /** - * Returns full method name if method is registered. - * - * @param methodName method name. - * @param fullMethodName full method name. - * @return aos::Error. - */ - aos::Error GetFullMethodName(const aos::String& methodName, aos::String& fullMethodName) const - { - if (!IsMethodRegistered(methodName)) { - return AOS_ERROR_WRAP(aos::ErrorEnum::eNotFound); - } - - fullMethodName.Clear(); - fullMethodName.Append("/").Append(GetServiceName()).Append("/").Append(methodName); - - return aos::ErrorEnum::eNone; - } - - /** - * Destroys PB service. - */ - virtual ~PBServiceItf() = default; -}; - -/** - * Protobuf service implementation. - */ -template -class PBService : public PBServiceItf { -public: - /** - * Initializes service. - * - * @param name service name. - * @return aos::Error. - */ - aos::Error Init(const aos::String& serviceName) - { - mServiceName = serviceName; - - return aos::ErrorEnum::eNone; - } - - /** - * Returns service name. - * - * @return aos::String. - */ - const aos::String& GetServiceName() const override { return mServiceName; } - - /** - * Registers method in service. - * - * @param methodName message method name. - * @return aos::Error. - */ - aos::Error RegisterMethod(const aos::String& methodName) override - { - auto err = mMethods.PushBack(methodName); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - return aos::ErrorEnum::eNone; - } - - /** - * Checks if method is registered. - * - * @param methodName - * @return bool. - */ - bool IsMethodRegistered(const aos::String& methodName) const override - { - return mMethods.Find([&methodName](const auto& item) { return item == methodName; }).mError.IsNone(); - } - -private: - aos::StaticString mServiceName; - aos::StaticArray, cMaxNumMethods> mMethods; -}; - -/** - * Message handler interface. - */ -class MessageHandlerItf { -public: - /** - * Processes received message. - * - * @param channel communication channel on which message is received. - * @param fullMethodName protocol full method name. - * @param requestID protocol request ID. - * @param data raw message data. - * @return aos::Error. - */ - virtual aos::Error ReceiveMessage( - Channel channel, const aos::String& fullMethodName, uint64_t requestID, const aos::Array& data) - = 0; - - /** - * Returns send buffer. - * - * @return aos::Buffer. - */ - virtual const aos::Buffer& GetSendBuffer() const = 0; - - /** - * Returns receive buffer. - * - * @return aos::Buffer. - */ - virtual const aos::Buffer& GetReceiveBuffer() const = 0; - - /** - * Destroys message handler. - */ - virtual ~MessageHandlerItf() = default; - -protected: - /** - * Registers service to channel. - * - * @param service service to register. - * @param channel channel. - * @return aos::Error. - */ - virtual aos::Error RegisterService(PBServiceItf& service, Channel channel) = 0; - - /** - * Removes service from channel. - * - * @param service service to remove. - * @param channel channel. - * @return aos::Error. - */ - virtual aos::Error RemoveService(PBServiceItf& service, Channel channel) = 0; - - /** - * Sends protobuf message. - * - * @param channel channel to send message. - * @param requestID request ID. - * @param fields protobuf fields. - * @param message protobuf message. - * @param messageError message error. - * @return aos::Error. - */ - virtual aos::Error SendPBMessage(Channel channel, uint64_t requestID, const pb_msgdesc_t* fields, - const void* message, aos::Error messageError = aos::ErrorEnum::eNone) - = 0; - - /** - * Processes received protobuf message. - * @param channel channel on which message is received. - * @param service protobuf service instance. - * @param methodName method name. - * @param requestID request ID. - * @param data message data. - * @return aos::Error. - */ - virtual aos::Error ProcessMessage(Channel channel, PBServiceItf& service, const aos::String& methodName, - uint64_t requestID, const aos::Array& data) - = 0; -}; - -/** - * Message handler implementation. - */ -template -class MessageHandler : public MessageHandlerItf { -public: - /** - * Initializes message handler. - * - * @param source message source. - * @param messageSender message sender instance. - * @return aos::Error. - */ - aos::Error Init(AosVChanSource source, MessageSenderItf& messageSender) - { - mSource = source; - mMessageSender = &messageSender; - - return aos::ErrorEnum::eNone; - } - - /** - * Processes received message. - * - * @param channel communication channel on which message is received. - * @param fullMethodName protocol full method name. - * @param requestID protocol request ID. - * @param data raw message data. - * @return aos::Error. - */ - aos::Error ReceiveMessage(Channel channel, const aos::String& fullMethodName, uint64_t requestID, - const aos::Array& data) override - { - auto names = aos::MakeUnique, 2>>( - &mAllocator); - - if (fullMethodName.Size() > 0) { - auto err = (fullMethodName[0] != '/' ? fullMethodName : aos::String(&fullMethodName.CStr()[1])) - .Split(*names, '/'); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - } - - for (auto i = names->Size(); i < names->MaxSize(); i++) { - names->PushBack(""); - } - - auto service = mServices[channel].Find([&names](auto item) { return item->GetServiceName() == (*names)[0]; }); - - if (!service.mError.IsNone() || !(*service.mValue)->IsMethodRegistered((*names)[1])) { - return AOS_ERROR_WRAP(aos::ErrorEnum::eNotSupported); - } - - return ProcessMessage(channel, **service.mValue, (*names)[1], requestID, data); - } - - /** - * Returns send buffer. - * - * @return aos::Buffer. - */ - const aos::Buffer& GetSendBuffer() const override { return mSendBuffer; }; - - /** - * Returns receive buffer. - * - * @return aos::Buffer. - */ - const aos::Buffer& GetReceiveBuffer() const override { return mReceiveBuffer; }; - -protected: - static constexpr auto cNodeID = CONFIG_AOS_NODE_ID; - static constexpr auto cNodeType = CONFIG_AOS_NODE_TYPE; - - aos::Error RegisterService(PBServiceItf& service, Channel channel) override - { - auto result = mServices[channel].Find(&service); - if (result.mError.IsNone()) { - return AOS_ERROR_WRAP(aos::ErrorEnum::eAlreadyExist); - } - - if (result.mError == aos::ErrorEnum::eNotFound) { - return mServices[channel].PushBack(&service); - } - - return result.mError; - } - - aos::Error RemoveService(PBServiceItf& service, Channel channel) override - { - return mServices[channel].Remove([&service](auto item) { return &service == item; }).mError; - } - - aos::Error SendPBMessage(Channel channel, uint64_t requestID, const pb_msgdesc_t* fields, const void* message, - aos::Error messageError = aos::ErrorEnum::eNone) override - { - auto outStream = pb_ostream_from_buffer(static_cast(GetSendBuffer().Get()), GetSendBuffer().Size()); - - if (message && fields) { - auto status = pb_encode(&outStream, fields, message); - if (!status) { - if (messageError.IsNone()) { - messageError = AOS_ERROR_WRAP(aos::ErrorEnum::eRuntime); - } - } - } - - auto err = mMessageSender->SendMessage(channel, mSource, "", requestID, - aos::Array(static_cast(GetSendBuffer().Get()), outStream.bytes_written), messageError); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - return aos::ErrorEnum::eNone; - } - -private: - AosVChanSource mSource {}; - MessageSenderItf* mMessageSender {}; - aos::StaticBuffer mSendBuffer; - aos::StaticBuffer mReceiveBuffer; - aos::StaticArray mServices[static_cast(ChannelEnum::eNumChannels)]; - aos::StaticAllocator, 2>)> - mAllocator; -}; - -#endif diff --git a/src/communication/tlschannel.cpp b/src/communication/tlschannel.cpp index 7ccad299..232adb00 100644 --- a/src/communication/tlschannel.cpp +++ b/src/communication/tlschannel.cpp @@ -18,6 +18,11 @@ extern "C" { #include "tlschannel.hpp" +extern unsigned char __aos_root_ca_start[]; +extern unsigned char __aos_root_ca_end[]; + +namespace aos::zephyr::communication { + /*********************************************************************************************************************** * Public **********************************************************************************************************************/ @@ -28,9 +33,9 @@ TLSChannel::~TLSChannel() } aos::Error TLSChannel::Init(aos::iam::certhandler::CertHandlerItf& certHandler, - aos::cryptoutils::CertLoaderItf& certLoader, CommChannelItf& vChannel) + aos::cryptoutils::CertLoaderItf& certLoader, ChannelItf& channel) { - mChannel = &vChannel; + mChannel = &channel; mCertHandler = &certHandler; mCertLoader = &certLoader; @@ -182,9 +187,6 @@ aos::Error TLSChannel::SetupSSLConfig(const aos::String& certType) } } - extern unsigned char __aos_root_ca_start[]; - extern unsigned char __aos_root_ca_end[]; - // cppcheck-suppress comparePointers auto ret = mbedtls_x509_crt_parse(&mCACert, __aos_root_ca_start, __aos_root_ca_end - __aos_root_ca_start); if (ret != 0) { @@ -252,3 +254,5 @@ int TLSChannel::TLSRead(void* ctx, unsigned char* buf, size_t len) return channel->mChannel->Read(buf, len); } + +} // namespace aos::zephyr::communication diff --git a/src/communication/tlschannel.hpp b/src/communication/tlschannel.hpp index d23c9a37..1b4d25ff 100644 --- a/src/communication/tlschannel.hpp +++ b/src/communication/tlschannel.hpp @@ -17,9 +17,11 @@ #include #include -#include "commchannel.hpp" +#include "channel.hpp" -class TLSChannel : public CommChannelItf { +namespace aos::zephyr::communication { + +class TLSChannel : public ChannelItf { public: /** * Destructor. @@ -31,10 +33,10 @@ class TLSChannel : public CommChannelItf { * * @param certHandler certificate handler. * @param certLoader certificate loader. - * @param vChannel virtual channel. + * @param channel virtual channel. */ aos::Error Init(aos::iam::certhandler::CertHandlerItf& certHandler, aos::cryptoutils::CertLoaderItf& certLoader, - CommChannelItf& vChannel); + ChannelItf& channel); /** * Set TLS config. @@ -42,7 +44,7 @@ class TLSChannel : public CommChannelItf { * @param certType certificate type. * @return aos::Error */ - aos::Error SetTLSConfig(const aos::String& certType) override; + aos::Error SetTLSConfig(const aos::String& certType); /** * Connects to communication channel. @@ -101,10 +103,12 @@ class TLSChannel : public CommChannelItf { mbedtls_ssl_context mSSL {}; mbedtls_svc_key_id_t mKeyID {}; aos::SharedPtr mPrivKey {}; - CommChannelItf* mChannel {}; + ChannelItf* mChannel {}; aos::iam::certhandler::CertHandlerItf* mCertHandler {}; aos::cryptoutils::CertLoaderItf* mCertLoader {}; aos::StaticString mCertType; }; +} // namespace aos::zephyr::communication + #endif /* TLSCHANNEL_HPP_ */ diff --git a/src/communication/transport.hpp b/src/communication/transport.hpp new file mode 100644 index 00000000..31c70634 --- /dev/null +++ b/src/communication/transport.hpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef TRANSPORT_HPP_ +#define TRANSPORT_HPP_ + +#include + +namespace aos::zephyr::communication { + +/** + * Transport interface. + */ +class TransportItf { +public: + /** + * Opens transport. + * + * @return aos::Error. + */ + virtual aos::Error Open() = 0; + + /** + * Closes transport. + */ + virtual aos::Error Close() = 0; + + /** + * Returns if transport is opened. + * + * @return bool. + */ + virtual bool IsOpened() const = 0; + + /** + * Reads data from transport. + * + * @param data buffer where data is placed to. + * @param size specifies how many bytes to read. + * @return int num read bytes. + */ + virtual int Read(void* data, size_t size) = 0; + + /** + * Writes data to transport. + * + * @param data data buffer. + * @param size specifies how many bytes to write. + * @return int num written bytes. + */ + virtual int Write(const void* data, size_t size) = 0; + + /** + * Destructor. + */ + virtual ~TransportItf() = default; +}; + +} // namespace aos::zephyr::communication + +#endif diff --git a/src/communication/vchannel.cpp b/src/communication/xenvchan.cpp similarity index 57% rename from src/communication/vchannel.cpp rename to src/communication/xenvchan.cpp index b4e702c3..9403897b 100644 --- a/src/communication/vchannel.cpp +++ b/src/communication/xenvchan.cpp @@ -5,32 +5,24 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "vchannel.hpp" +#include "xenvchan.hpp" #include "log.hpp" +namespace aos::zephyr::communication { + /*********************************************************************************************************************** * Public **********************************************************************************************************************/ -aos::Error VChannel::Init(const aos::String& name, const aos::String& xsReadPath, const aos::String& xsWritePath) +aos::Error XenVChan::Init(const aos::String& xsReadPath, const aos::String& xsWritePath) { mXSReadPath = xsReadPath; mXSWritePath = xsWritePath; - mName = name; - - return aos::ErrorEnum::eNone; -} - -aos::Error VChannel::SetTLSConfig(const aos::String& certType) -{ - if (certType != "") { - return aos::ErrorEnum::eNotSupported; - } return aos::ErrorEnum::eNone; } -aos::Error VChannel::Connect() +aos::Error XenVChan::Open() { auto ret = vch_connect(cDomdID, mXSReadPath.CStr(), &mReadHandle); if (ret != 0) { @@ -47,39 +39,33 @@ aos::Error VChannel::Connect() mReadHandle.blocking = true; mWriteHandle.blocking = true; - mConnected = true; + mOpened = true; return aos::ErrorEnum::eNone; } -aos::Error VChannel::Close() +aos::Error XenVChan::Close() { vch_close(&mReadHandle); vch_close(&mWriteHandle); - mConnected = false; + mOpened = false; return aos::ErrorEnum::eNone; } -int VChannel::Read(void* data, size_t size) +int XenVChan::Read(void* data, size_t size) { - LOG_DBG() << "Channel wants read: channel = " << mName << ", size = " << size; - auto ret = vch_read(&mReadHandle, data, size); - LOG_DBG() << "Channel read: channel = " << mName << ", size = " << ret; - return ret; } -int VChannel::Write(const void* data, size_t size) +int XenVChan::Write(const void* data, size_t size) { - LOG_DBG() << "Channel wants write: channel = " << mName << ", size = " << size; - auto ret = vch_write(&mWriteHandle, data, size); - LOG_DBG() << "Channel wrote: channel = " << mName << ", size = " << size; - return ret; } + +} // namespace aos::zephyr::communication diff --git a/src/communication/vchannel.hpp b/src/communication/xenvchan.hpp similarity index 53% rename from src/communication/vchannel.hpp rename to src/communication/xenvchan.hpp index 682246cc..a0da2f8d 100644 --- a/src/communication/vchannel.hpp +++ b/src/communication/xenvchan.hpp @@ -12,14 +12,14 @@ #include -#include "commchannel.hpp" +#include "transport.hpp" -class VChannel : public CommChannelItf { +namespace aos::zephyr::communication { + +class XenVChan : public TransportItf { public: - static constexpr auto cXSOpenReadPath = CONFIG_AOS_VCHAN_OPEN_TX_PATH; - static constexpr auto cXSOpenWritePath = CONFIG_AOS_VCHAN_OPEN_RX_PATH; - static constexpr auto cXSCloseReadPath = CONFIG_AOS_VCHAN_SECURE_TX_PATH; - static constexpr auto cXSCloseWritePath = CONFIG_AOS_VCHAN_SECURE_RX_PATH; + static constexpr auto cXSReadPath = CONFIG_AOS_VCHAN_TX_PATH; + static constexpr auto cXSWritePath = CONFIG_AOS_VCHAN_RX_PATH; /** * Initializes vchan. @@ -28,34 +28,26 @@ class VChannel : public CommChannelItf { * @param xsWritePath Xen store write vchan path. * @return aos::Error. */ - aos::Error Init(const aos::String& name, const aos::String& xsReadPath, const aos::String& xsWritePath); + aos::Error Init(const aos::String& xsReadPath, const aos::String& xsWritePath); /** - * Set TLS config. - * - * @param certType certificate type. - * @return aos::Error - */ - aos::Error SetTLSConfig(const aos::String& certType) override; - - /** - * Connects to communication channel. + * Opens vchan. * * @return aos::Error. */ - aos::Error Connect() override; + aos::Error Open() override; /** - * Closes current connection. + * Closes vchan. */ aos::Error Close() override; /** - * Returns if channel is connected. + * Returns if vchan is opened. * * @return bool. */ - bool IsConnected() const override { return mConnected; }; + bool IsOpened() const override { return mOpened; }; /** * Reads data from channel to array. @@ -76,9 +68,8 @@ class VChannel : public CommChannelItf { int Write(const void* data, size_t size) override; private: - static constexpr auto cXSPathLen = 128; - static constexpr auto cDomdID = CONFIG_AOS_DOMD_ID; - static constexpr auto cChannelNameLen = 32; + static constexpr auto cXSPathLen = 128; + static constexpr auto cDomdID = CONFIG_AOS_DOMD_ID; aos::StaticString mXSReadPath; aos::StaticString mXSWritePath; @@ -86,9 +77,9 @@ class VChannel : public CommChannelItf { vch_handle mReadHandle; vch_handle mWriteHandle; - bool mConnected = false; - - aos::StaticString mName; + bool mOpened = false; }; +} // namespace aos::zephyr::communication + #endif diff --git a/tests/communication/CMakeLists.txt b/tests/communication/CMakeLists.txt deleted file mode 100644 index beb15d14..00000000 --- a/tests/communication/CMakeLists.txt +++ /dev/null @@ -1,131 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) - -find_package( - Zephyr - COMPONENTS - REQUIRED HINTS $ENV{ZEPHYR_BASE} -) - -set(CMAKE_MODULE_PATH ${APPLICATION_SOURCE_DIR}/../../cmake) - -project(communication_test) - -# ###################################################################################################################### -# Config -# ###################################################################################################################### - -set(aoscore_config aoscoreconfig.hpp) -set(aoscore_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../../../aos_core_lib_cpp") -set(cert_dir ${CMAKE_CURRENT_BINARY_DIR}/certificates) - -# ###################################################################################################################### -# Definitions -# ###################################################################################################################### - -# Aos core configuration -add_definitions(-include ${aoscore_config}) -# Certificate dir -add_definitions(-DCERT_DIR="${cert_dir}") -# Root CA cart path -add_definitions(-DCONFIG_AOS_ROOT_CA_PATH="${cert_dir}/ca.pem") - -# ###################################################################################################################### -# Includes -# ###################################################################################################################### - -zephyr_include_directories(${aoscore_source_dir}/include) -zephyr_include_directories(${APPLICATION_SOURCE_DIR}/../../src) -zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src) -zephyr_include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -# ###################################################################################################################### -# Generate API -# ###################################################################################################################### - -find_package(CoreAPI) - -set(CORE_API_CXX_FLAGS -I${APPLICATION_SOURCE_DIR}/../../src -I${aoscore_source_dir}/include -include - ${CMAKE_CURRENT_BINARY_DIR}/zephyr/include/generated/autoconf.h -include ${aoscore_config} -) - -core_api_generate(${CMAKE_CURRENT_SOURCE_DIR}/../../../aos_core_api ${CMAKE_CURRENT_SOURCE_DIR}/../../scripts) - -# ###################################################################################################################### -# Certificates -# ###################################################################################################################### - -file(MAKE_DIRECTORY ${cert_dir}) - -foreach(cert_type IN ITEMS "ca" "server" "client") - execute_process(COMMAND openssl genrsa -out ${cert_dir}/${cert_type}.key 2048) - - execute_process( - COMMAND openssl req -new -key ${cert_dir}/${cert_type}.key -out ${cert_dir}/${cert_type}.csr -subj - "/C=XX/ST=State/L=City/O=Organization/OU=Unit/CN=${TYPE}" COMMAND_ERROR_IS_FATAL ANY - ) -endforeach() - -execute_process( - COMMAND openssl x509 -req -days 365 -in ${cert_dir}/ca.csr -signkey ${cert_dir}/ca.key -out ${cert_dir}/ca.pem - COMMAND_ERROR_IS_FATAL ANY -) - -foreach(cert_type IN ITEMS "server" "client") - execute_process( - COMMAND openssl x509 -req -days 365 -in ${cert_dir}/${cert_type}.csr -CA ${cert_dir}/ca.pem -CAkey - ${cert_dir}/ca.key -CAcreateserial -out ${cert_dir}/${cert_type}.cer COMMAND_ERROR_IS_FATAL ANY - ) -endforeach() - -# ###################################################################################################################### -# mbedTLS -# ###################################################################################################################### - -# Enable AESNI for posix 32bit -if(${CONFIG_BOARD_NATIVE_POSIX}) - target_compile_options(mbedTLS INTERFACE -mpclmul -msse2 -maes) -endif() - -# WA to have get time on zephyr -target_compile_definitions_ifndef(CONFIG_NATIVE_APPLICATION mbedTLS INTERFACE _POSIX_VERSION=200809L) - -# Add Aos psa driver - -set(mbedtls_source_dir "${APPLICATION_SOURCE_DIR}/../../../modules/crypto/mbedtls") -set(aoscore_source_dir "${APPLICATION_SOURCE_DIR}/../../../aos_core_lib_cpp") - -set_source_files_properties( - ${mbedtls_source_dir}/library/psa_crypto_driver_wrappers_no_static.c ${mbedtls_source_dir}/library/psa_crypto.c - TARGET_DIRECTORY mbedTLS PROPERTIES HEADER_FILE_ONLY ON -) - -target_include_directories(mbedTLSCrypto PRIVATE ${mbedtls_source_dir}/library) - -target_sources( - mbedTLSCrypto - PRIVATE ${aoscore_source_dir}/src/common/crypto/mbedtls/drivers/psa_crypto_driver_wrappers_no_static.c - ${aoscore_source_dir}/src/common/crypto/mbedtls/drivers/psa_crypto.c - ${aoscore_source_dir}/src/common/crypto/mbedtls/driverwrapper.cpp ${mbedtls_source_dir}/library/pk_ecc.c -) - -target_sources(mbedTLSX509 PRIVATE ${mbedtls_source_dir}/library/x509write.c) - -# ###################################################################################################################### -# Target -# ###################################################################################################################### - -target_sources( - app - PRIVATE ../../src/communication/cmclient.cpp - ../../src/communication/communication.cpp - ../../src/communication/iamserver.cpp - ../../src/communication/tlschannel.cpp - ../../src/rootca/rootca.S - ../../src/utils/checksum.cpp - src/cmclient.cpp - src/iamserver.cpp - src/tlschannel.cpp - src/utils.cpp -) diff --git a/tests/communication/Kconfig b/tests/communication/Kconfig deleted file mode 100644 index 947b98a2..00000000 --- a/tests/communication/Kconfig +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright (C) 2023 Renesas Electronics Corporation. -# Copyright (C) 2023 EPAM Systems, Inc. -# -# SPDX-License-Identifier: Apache-2.0 - -mainmenu "Aos zephyr application" - -config AOS_DOMD_ID - int "DomD id" - default 1 - -config AOS_NODE_ID - string "Node id" - default "NODE_0" - -config AOS_NODE_TYPE - string "Node type" - default "NODE_TYPE" - -config AOS_VCHAN_TX_PATH - string "Path to the SM vchan" - default "/vchan/tx" - -config AOS_VCHAN_RX_PATH - string "Path to the SM vchan" - default "/vchan/rx" - -config AOS_RUNTIME_DIR - string "Aos runtime dir" - default "/aos/runtime" - -config AOS_SERVICES_DIR - string "Aos services dir" - default "/aos/services" - -config AOS_UNIT_CONFIG_FILE - string "Node configuration file path" - default "/aos/unit_config.cfg" - -config AOS_CLOCK_SYNC_SEND_PERIOD_SEC - int "Send clock sync period in seconds" - default 1 - -config AOS_CLOCK_SYNC_TIMEOUT_SEC - int "Clock becomes unsynced if there is no clock sync update during this period." - default 1 - -config AOS_CLOCK_SYNC_MAX_DIFF_MSEC - int "Maximum allowed difference between source and current time." - default 10000 - -config AOS_PROVISIONING_FILE - string "Path to provisioning file." - default "/aos/.provisioned" - -source "Kconfig" diff --git a/tests/communication/prj.conf b/tests/communication/prj.conf deleted file mode 100644 index e77aa792..00000000 --- a/tests/communication/prj.conf +++ /dev/null @@ -1,46 +0,0 @@ -# Enable C++ - -CONFIG_CPP=y -CONFIG_STD_CPP14=y -CONFIG_EXTERNAL_LIBCPP=y -CONFIG_CBPRINTF_FP_SUPPORT=y - -# Enable test suit - -CONFIG_ZTEST=y - -# Enable debug for tests - -CONFIG_DEBUG=y -CONFIG_NO_OPTIMIZATIONS=y - -# Enable nanopb lib - -CONFIG_NANOPB=y - -# Enable mbedtls - -CONFIG_MBEDTLS=y -CONFIG_MBEDTLS_BUILTIN=y -CONFIG_MBEDTLS_ZEPHYR_ENTROPY=y -CONFIG_MBEDTLS_USER_CONFIG_ENABLE=y -CONFIG_MBEDTLS_USER_CONFIG_FILE="testmbedtlsconfig.h" - -CONFIG_MBEDTLS_CIPHER_CCM_ENABLED=y -CONFIG_MBEDTLS_ECDH_C=y -CONFIG_MBEDTLS_ECDSA_C=y -CONFIG_MBEDTLS_ECP_C=y -CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=y -CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED=y -CONFIG_MBEDTLS_PEM_CERTIFICATE_FORMAT=y -CONFIG_MBEDTLS_PK_WRITE_C=y -CONFIG_MBEDTLS_PSA_CRYPTO_C=y -CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 -CONFIG_MBEDTLS_TLS_VERSION_1_2=y - -# Enable entropy generator - -CONFIG_ENTROPY_GENERATOR=y -CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/communication/src/cmclient.cpp b/tests/communication/src/cmclient.cpp deleted file mode 100644 index de9bb298..00000000 --- a/tests/communication/src/cmclient.cpp +++ /dev/null @@ -1,643 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#include "communication/communication.hpp" -#include "utils/pbconvert.hpp" - -#include "stubs/certhandlerstub.hpp" -#include "stubs/clocksyncstub.hpp" -#include "stubs/commchannelstub.hpp" -#include "stubs/connectionsubscriberstub.hpp" -#include "stubs/downloaderstub.hpp" -#include "stubs/launcherstub.hpp" -#include "stubs/monitoringstub.hpp" -#include "stubs/provisioningstub.hpp" -#include "stubs/resourcemanagerstub.hpp" -#include "utils.hpp" - -/*********************************************************************************************************************** - * Types - **********************************************************************************************************************/ - -struct cmclient_fixture { - CommChannelStub mOpenChannel; - CommChannelStub mSecureChannel; - LauncherStub mLauncher; - CertHandlerStub mCertHandler; - ResourceManagerStub mResourceManager; - ResourceMonitorStub mResourceMonitor; - DownloaderStub mDownloader; - ClockSyncStub mClockSync; - ProvisioningStub mProvisioning; - Communication mCommunication; -}; - -/*********************************************************************************************************************** - * Static - **********************************************************************************************************************/ - -static constexpr void PBToInstanceStatus( - const servicemanager_v3_InstanceStatus& pbInstance, aos::InstanceStatus& aosInstance) -{ - if (pbInstance.has_instance) { - PBToString(pbInstance.instance.service_id, aosInstance.mInstanceIdent.mServiceID); - PBToString(pbInstance.instance.subject_id, aosInstance.mInstanceIdent.mSubjectID); - aosInstance.mInstanceIdent.mInstance = pbInstance.instance.instance; - } - - aosInstance.mAosVersion = pbInstance.aos_version; - PBToEnum(pbInstance.run_state, aosInstance.mRunState); - - if (pbInstance.has_error_info) { - if (pbInstance.error_info.exit_code) { - aosInstance.mError = pbInstance.error_info.exit_code; - } else { - aosInstance.mError = static_cast(pbInstance.error_info.aos_code); - } - } -} - -static void PBToMonitoringData( - const servicemanager_v3_MonitoringData& pbMonitoring, aos::monitoring::MonitoringData& aosMonitoring) -{ - aosMonitoring.mRAM = pbMonitoring.ram; - aosMonitoring.mCPU = pbMonitoring.cpu; - aosMonitoring.mDisk.Resize(pbMonitoring.disk_count); - - for (size_t i = 0; i < pbMonitoring.disk_count; i++) { - - PBToString(pbMonitoring.disk[i].name, aosMonitoring.mDisk[i].mName); - aosMonitoring.mDisk[i].mUsedSize = pbMonitoring.disk[i].used_size; - } - - aosMonitoring.mInTraffic = pbMonitoring.in_traffic; - aosMonitoring.mOutTraffic = pbMonitoring.out_traffic; -} - -static aos::Error SendCMIncomingMessage(CommChannelStub& channel, const servicemanager_v3_SMIncomingMessages& message) -{ - return SendPBMessage(channel, AOS_VCHAN_SM, "", 0, &servicemanager_v3_SMIncomingMessages_msg, &message, - servicemanager_v3_SMOutgoingMessages_size); -} - -static aos::Error ReceiveCMOutgoingMessage(CommChannelStub& channel, servicemanager_v3_SMOutgoingMessages& message) -{ - return ReceivePBMessage(channel, AOS_VCHAN_SM, "", 0, &servicemanager_v3_SMOutgoingMessages_msg, &message, - servicemanager_v3_SMOutgoingMessages_size); -} - -/*********************************************************************************************************************** - * Setup - **********************************************************************************************************************/ - -ZTEST_SUITE( - cmclient, nullptr, - []() -> void* { - aos::Log::SetCallback(TestLogCallback); - - auto fixture = new cmclient_fixture; - - fixture->mProvisioning.SetProvisioned(true); - - auto err = fixture->mCommunication.Init(fixture->mOpenChannel, fixture->mSecureChannel, fixture->mLauncher, - fixture->mCertHandler, fixture->mResourceManager, fixture->mResourceMonitor, fixture->mDownloader, - fixture->mClockSync, fixture->mProvisioning); - zassert_true(err.IsNone(), "Can't initialize communication: %s", err.Message()); - - fixture->mCommunication.ClockSynced(); - - // Wait node configuration message - - servicemanager_v3_SMOutgoingMessages outgoingMessage servicemanager_v3_SMOutgoingMessages_init_default; - - err = ReceiveCMOutgoingMessage(fixture->mSecureChannel, outgoingMessage); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - zassert_equal( - outgoingMessage.which_SMOutgoingMessage, servicemanager_v3_SMOutgoingMessages_node_configuration_tag); - - return fixture; - }, - [](void* fixture) { - auto f = static_cast(fixture); - - f->mOpenChannel.Clear(); - f->mSecureChannel.Clear(); - f->mLauncher.Clear(); - f->mCertHandler.Clear(); - f->mResourceManager.Clear(); - f->mResourceMonitor.Clear(); - f->mDownloader.Clear(); - f->mClockSync.Clear(); - f->mProvisioning.SetProvisioned(true); - }, - nullptr, [](void* fixture) { delete static_cast(fixture); }); - -/*********************************************************************************************************************** - * Tests - **********************************************************************************************************************/ - -ZTEST_F(cmclient, test_NodeConfiguration) -{ - ConnectionSubscriberStub subscriber; - - fixture->mCommunication.Subscribes(subscriber); - - aos::NodeInfo sendNodeInfo {CONFIG_AOS_NODE_ID, 2, 1024, {}}; - - sendNodeInfo.mPartitions.EmplaceBack(aos::monitoring::PartitionInfo {"var", "", {}, 2048, 0}); - sendNodeInfo.mPartitions.end()->mTypes.EmplaceBack("data"); - sendNodeInfo.mPartitions.end()->mTypes.EmplaceBack("state"); - sendNodeInfo.mPartitions.end()->mTypes.EmplaceBack("storage"); - sendNodeInfo.mPartitions.EmplaceBack(aos::monitoring::PartitionInfo {"aos", "", {}, 4096, 0}); - sendNodeInfo.mPartitions.end()->mTypes.EmplaceBack("aos"); - sendNodeInfo.mPartitions.end()->mTypes.EmplaceBack("tmp"); - - fixture->mResourceMonitor.SetNodeInfo(sendNodeInfo); - - fixture->mSecureChannel.SendRead(std::vector(), aos::ErrorEnum::eFailed); - - auto err = subscriber.WaitDisconnect(cWaitTimeout); - zassert_true(err.IsNone(), "Wait connection error: %s", err.Message()); - - err = subscriber.WaitConnect(cWaitTimeout); - zassert_true(err.IsNone(), "Wait connection error: %s", err.Message()); - - // Wait node configuration message - - servicemanager_v3_SMOutgoingMessages outgoingMessage servicemanager_v3_SMOutgoingMessages_init_default; - - err = ReceiveCMOutgoingMessage(fixture->mSecureChannel, outgoingMessage); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - aos::NodeInfo receiveNodeInfo {}; - const auto& pbNodeConfiguration = outgoingMessage.SMOutgoingMessage.node_configuration; - - PBToString(pbNodeConfiguration.node_id, receiveNodeInfo.mNodeID); - receiveNodeInfo.mNumCPUs = pbNodeConfiguration.num_cpus; - receiveNodeInfo.mTotalRAM = pbNodeConfiguration.total_ram; - receiveNodeInfo.mPartitions.Resize(pbNodeConfiguration.partitions_count); - - for (size_t i = 0; i < pbNodeConfiguration.partitions_count; ++i) { - PBToString(pbNodeConfiguration.partitions[i].name, receiveNodeInfo.mPartitions[i].mName); - receiveNodeInfo.mPartitions[i].mTotalSize = pbNodeConfiguration.partitions[i].total_size; - receiveNodeInfo.mPartitions[i].mTypes.Resize(pbNodeConfiguration.partitions[i].types_count); - - for (size_t j = 0; j < pbNodeConfiguration.partitions[i].types_count; ++j) { - PBToString(pbNodeConfiguration.partitions[i].types[j], receiveNodeInfo.mPartitions[i].mTypes[j]); - } - } - - zassert_equal(outgoingMessage.which_SMOutgoingMessage, servicemanager_v3_SMOutgoingMessages_node_configuration_tag); - zassert_equal(strcmp(pbNodeConfiguration.node_type, CONFIG_AOS_NODE_TYPE), 0); - zassert_equal(pbNodeConfiguration.remote_node, true); - zassert_equal(pbNodeConfiguration.runner_features_count, 1); - zassert_equal(strcmp(pbNodeConfiguration.runner_features[0], "xrun"), 0); - zassert_equal(receiveNodeInfo, sendNodeInfo); - - fixture->mCommunication.Unsubscribes(subscriber); -} - -ZTEST_F(cmclient, test_GetUnitConfigStatus) -{ - auto version = "1.1.1"; - auto unitConfig = "unitConfig"; - - fixture->mResourceManager.UpdateUnitConfig(version, unitConfig); - fixture->mResourceManager.SetError(aos::ErrorEnum::eFailed); - - servicemanager_v3_SMIncomingMessages incomingMessage servicemanager_v3_SMIncomingMessages_init_default; - - incomingMessage.which_SMIncomingMessage = servicemanager_v3_SMIncomingMessages_get_unit_config_status_tag; - - auto err = SendCMIncomingMessage(fixture->mSecureChannel, incomingMessage); - zassert_true(err.IsNone(), "Error sending message: %s", err.Message()); - - servicemanager_v3_SMOutgoingMessages outgoingMessage servicemanager_v3_SMOutgoingMessages_init_default; - - err = ReceiveCMOutgoingMessage(fixture->mSecureChannel, outgoingMessage); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - zassert_equal(outgoingMessage.which_SMOutgoingMessage, servicemanager_v3_SMOutgoingMessages_unit_config_status_tag); - zassert_equal(strcmp(outgoingMessage.SMOutgoingMessage.unit_config_status.vendor_version, version), 0); - zassert_not_equal(strstr(outgoingMessage.SMOutgoingMessage.unit_config_status.error, - aos::Error(aos::ErrorEnum::eFailed).Message()), - nullptr); -} - -ZTEST_F(cmclient, test_CheckUnitConfig) -{ - auto version = "1.2.0"; - auto unitConfig = "unitConfig"; - servicemanager_v3_SMIncomingMessages incomingMessage servicemanager_v3_SMIncomingMessages_init_default; - - incomingMessage.which_SMIncomingMessage = servicemanager_v3_SMIncomingMessages_check_unit_config_tag; - strcpy(incomingMessage.SMIncomingMessage.check_unit_config.vendor_version, version); - strcpy(incomingMessage.SMIncomingMessage.check_unit_config.unit_config, unitConfig); - - auto err = SendCMIncomingMessage(fixture->mSecureChannel, incomingMessage); - zassert_true(err.IsNone(), "Error sending message: %s", err.Message()); - - servicemanager_v3_SMOutgoingMessages outgoingMessage servicemanager_v3_SMOutgoingMessages_init_default; - - err = ReceiveCMOutgoingMessage(fixture->mSecureChannel, outgoingMessage); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - zassert_equal(outgoingMessage.which_SMOutgoingMessage, servicemanager_v3_SMOutgoingMessages_unit_config_status_tag); - zassert_equal(strcmp(outgoingMessage.SMOutgoingMessage.unit_config_status.vendor_version, version), 0); - zassert_equal(strlen(outgoingMessage.SMOutgoingMessage.unit_config_status.error), 0); -} - -ZTEST_F(cmclient, test_SetUnitConfig) -{ - auto version = "1.2.0"; - auto unitConfig = "unitConfig"; - servicemanager_v3_SMIncomingMessages incomingMessage servicemanager_v3_SMIncomingMessages_init_default; - - incomingMessage.which_SMIncomingMessage = servicemanager_v3_SMIncomingMessages_set_unit_config_tag; - strcpy(incomingMessage.SMIncomingMessage.set_unit_config.vendor_version, version); - strcpy(incomingMessage.SMIncomingMessage.set_unit_config.unit_config, unitConfig); - - auto err = SendCMIncomingMessage(fixture->mSecureChannel, incomingMessage); - zassert_true(err.IsNone(), "Error sending message: %s", err.Message()); - - servicemanager_v3_SMOutgoingMessages outgoingMessage servicemanager_v3_SMOutgoingMessages_init_default; - - err = ReceiveCMOutgoingMessage(fixture->mSecureChannel, outgoingMessage); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - zassert_equal(outgoingMessage.which_SMOutgoingMessage, servicemanager_v3_SMOutgoingMessages_unit_config_status_tag); - zassert_equal(strcmp(outgoingMessage.SMOutgoingMessage.unit_config_status.vendor_version, version), 0); - zassert_equal(strlen(outgoingMessage.SMOutgoingMessage.unit_config_status.error), 0); - zassert_equal(fixture->mResourceManager.GetUnitConfig(), unitConfig); - - auto ret = fixture->mResourceManager.GetVersion(); - zassert_true(ret.mError.IsNone(), "Failed to get version: %s", ret.mError.Message()); - zassert_equal(ret.mValue, version); -} - -ZTEST_F(cmclient, test_RunInstances) -{ - servicemanager_v3_SMIncomingMessages incomingMessage servicemanager_v3_SMIncomingMessages_init_default; - - incomingMessage.which_SMIncomingMessage = servicemanager_v3_SMIncomingMessages_run_instances_tag; - incomingMessage.SMIncomingMessage.run_instances.force_restart = true; - - uint8_t sha256[] = {1, 2, 3, 4, 5, 6, 7, 8}; - uint8_t sha512[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - - // Fill services - - aos::ServiceInfoStaticArray services; - - services.EmplaceBack(aos::ServiceInfo {{0, "1.0.0", "this is service 1"}, "service1", "provider1", 42, - "service1 URL", aos::Array(sha256, sizeof(sha256)), aos::Array(sha512, sizeof(sha512)), 312}); - services.EmplaceBack(aos::ServiceInfo {{1, "1.0.1", "this is service 2"}, "service2", "provider2", 43, - "service2 URL", aos::Array(sha256, sizeof(sha256)), aos::Array(sha512, sizeof(sha512)), 512}); - - incomingMessage.SMIncomingMessage.run_instances.services_count = services.Size(); - - for (size_t i = 0; i < services.Size(); i++) { - const auto& aosService = services[i]; - auto& pbService = incomingMessage.SMIncomingMessage.run_instances.services[i]; - - pbService.has_version_info = true; - VersionInfoToPB(aosService.mVersionInfo, pbService.version_info); - StringToPB(aosService.mServiceID, pbService.service_id); - StringToPB(aosService.mProviderID, pbService.provider_id); - pbService.gid = aosService.mGID; - StringToPB(aosService.mURL, pbService.url); - ByteArrayToPB(aosService.mSHA256, pbService.sha256); - ByteArrayToPB(aosService.mSHA512, pbService.sha512); - pbService.size = aosService.mSize; - } - - // Fill layers - - aos::LayerInfoStaticArray layers; - - layers.EmplaceBack(aos::LayerInfo {{2, "2.1.0", "this is layer 1"}, "layer1", "digest1", "layer1 URL", - aos::Array(sha256, sizeof(sha256)), aos::Array(sha512, sizeof(sha512)), 1024}); - layers.EmplaceBack(aos::LayerInfo {{3, "2.2.0", "this is layer 2"}, "layer2", "digest2", "layer2 URL", - aos::Array(sha256, sizeof(sha256)), aos::Array(sha512, sizeof(sha512)), 2048}); - layers.EmplaceBack(aos::LayerInfo {{4, "2.3.0", "this is layer 3"}, "layer3", "digest3", "layer3 URL", - aos::Array(sha256, sizeof(sha256)), aos::Array(sha512, sizeof(sha512)), 4096}); - - incomingMessage.SMIncomingMessage.run_instances.layers_count = layers.Size(); - - for (size_t i = 0; i < layers.Size(); i++) { - const auto& aosLayer = layers[i]; - auto& pbLayer = incomingMessage.SMIncomingMessage.run_instances.layers[i]; - - pbLayer.has_version_info = true; - VersionInfoToPB(aosLayer.mVersionInfo, pbLayer.version_info); - StringToPB(aosLayer.mLayerID, pbLayer.layer_id); - StringToPB(aosLayer.mLayerDigest, pbLayer.digest); - StringToPB(aosLayer.mURL, pbLayer.url); - ByteArrayToPB(aosLayer.mSHA256, pbLayer.sha256); - ByteArrayToPB(aosLayer.mSHA512, pbLayer.sha512); - pbLayer.size = aosLayer.mSize; - } - - // Fill instances - - aos::InstanceInfoStaticArray instances; - - instances.EmplaceBack(aos::InstanceInfo {{"service1", "subject1", 1}, 1, 1, "storage1", "state1"}); - instances.EmplaceBack(aos::InstanceInfo {{"service2", "subject2", 2}, 2, 2, "storage2", "state2"}); - instances.EmplaceBack(aos::InstanceInfo {{"service3", "subject3", 3}, 3, 3, "storage3", "state3"}); - instances.EmplaceBack(aos::InstanceInfo {{"service4", "subject4", 4}, 4, 4, "storage4", "state4"}); - - incomingMessage.SMIncomingMessage.run_instances.instances_count = instances.Size(); - - for (size_t i = 0; i < instances.Size(); i++) { - const auto& aosInstance = instances[i]; - auto& pbInstance = incomingMessage.SMIncomingMessage.run_instances.instances[i]; - - pbInstance.has_instance = true; - InstanceIdentToPB(aosInstance.mInstanceIdent, pbInstance.instance); - pbInstance.uid = aosInstance.mUID; - pbInstance.priority = aosInstance.mPriority; - StringToPB(aosInstance.mStoragePath, pbInstance.storage_path); - StringToPB(aosInstance.mStatePath, pbInstance.state_path); - } - - // Send message and check result - - auto err = SendCMIncomingMessage(fixture->mSecureChannel, incomingMessage); - zassert_true(err.IsNone(), "Error sending message: %s", err.Message()); - - err = fixture->mLauncher.WaitEvent(cWaitTimeout); - zassert_true(err.IsNone(), "Error waiting run instances: %s", err.Message()); - - zassert_equal(fixture->mLauncher.IsForceRestart(), incomingMessage.SMIncomingMessage.run_instances.force_restart); - zassert_equal(fixture->mLauncher.GetServices(), services); - zassert_equal(fixture->mLauncher.GetLayers(), layers); - zassert_equal(fixture->mLauncher.GetInstances(), instances); -} - -ZTEST_F(cmclient, test_ImageContentInfo) -{ - auto aosContentInfo = ImageContentInfo {42}; - servicemanager_v3_SMIncomingMessages incomingMessage servicemanager_v3_SMIncomingMessages_init_default; - uint8_t sha256[] = {1, 2, 3, 4, 5, 6, 7, 8}; - - aosContentInfo.mFiles.EmplaceBack(FileInfo {"path/to/file1", aos::Array(sha256, sizeof(sha256)), 1024}); - aosContentInfo.mFiles.EmplaceBack(FileInfo {"path/to/file2", aos::Array(sha256, sizeof(sha256)), 2048}); - aosContentInfo.mFiles.EmplaceBack(FileInfo {"path/to/file3", aos::Array(sha256, sizeof(sha256)), 4096}); - aosContentInfo.mError = "content info error"; - - incomingMessage.which_SMIncomingMessage = servicemanager_v3_SMIncomingMessages_image_content_info_tag; - incomingMessage.SMIncomingMessage.image_content_info.request_id = aosContentInfo.mRequestID; - incomingMessage.SMIncomingMessage.image_content_info.image_files_count = aosContentInfo.mFiles.Size(); - - for (size_t i = 0; i < aosContentInfo.mFiles.Size(); i++) { - const auto& aosFileInfo = aosContentInfo.mFiles[i]; - auto& pbFileInfo = incomingMessage.SMIncomingMessage.image_content_info.image_files[i]; - - StringToPB(aosFileInfo.mRelativePath, pbFileInfo.relative_path); - ByteArrayToPB(aosFileInfo.mSHA256, pbFileInfo.sha256); - pbFileInfo.size = aosFileInfo.mSize; - } - - StringToPB(aosContentInfo.mError, incomingMessage.SMIncomingMessage.image_content_info.error); - - auto err = SendCMIncomingMessage(fixture->mSecureChannel, incomingMessage); - zassert_true(err.IsNone(), "Error sending message: %s", err.Message()); - - err = fixture->mDownloader.WaitEvent(cWaitTimeout); - zassert_true(err.IsNone(), "Error waiting downloader event: %s", err.Message()); - - zassert_equal(fixture->mDownloader.GetContentInfo(), aosContentInfo); -} - -ZTEST_F(cmclient, test_ImageContent) -{ - uint8_t data[] = {12, 23, 45, 32, 21, 56, 12, 18}; - auto aosFileChunk = FileChunk {43, "path/to/file1", 4, 1, aos::Array(data, sizeof(data))}; - servicemanager_v3_SMIncomingMessages incomingMessage servicemanager_v3_SMIncomingMessages_init_default; - - incomingMessage.which_SMIncomingMessage = servicemanager_v3_SMIncomingMessages_image_content_tag; - incomingMessage.SMIncomingMessage.image_content.request_id = aosFileChunk.mRequestID; - StringToPB(aosFileChunk.mRelativePath, incomingMessage.SMIncomingMessage.image_content.relative_path); - incomingMessage.SMIncomingMessage.image_content.parts_count = aosFileChunk.mPartsCount; - incomingMessage.SMIncomingMessage.image_content.part = aosFileChunk.mPart; - ByteArrayToPB(aosFileChunk.mData, incomingMessage.SMIncomingMessage.image_content.data); - - auto err = SendCMIncomingMessage(fixture->mSecureChannel, incomingMessage); - zassert_true(err.IsNone(), "Error sending message: %s", err.Message()); - - err = fixture->mDownloader.WaitEvent(cWaitTimeout); - zassert_true(err.IsNone(), "Error waiting downloader event: %s", err.Message()); - - zassert_equal(fixture->mDownloader.GetFileChunk(), aosFileChunk); -} - -ZTEST_F(cmclient, test_InstancesRunStatus) -{ - aos::InstanceStatusStaticArray sendRunStatus {}; - - sendRunStatus.EmplaceBack(aos::InstanceStatus { - {"service1", "subject1", 0}, 4, aos::InstanceRunStateEnum::eActive, aos::ErrorEnum::eNone}); - sendRunStatus.EmplaceBack( - aos::InstanceStatus {{"service1", "subject1", 1}, 4, aos::InstanceRunStateEnum::eFailed, 42}); - sendRunStatus.EmplaceBack(aos::InstanceStatus { - {"service1", "subject1", 2}, 4, aos::InstanceRunStateEnum::eFailed, aos::ErrorEnum::eRuntime}); - - auto err = fixture->mCommunication.InstancesRunStatus(sendRunStatus); - zassert_true(err.IsNone(), "Error sending run instances status: %s", err.Message()); - - servicemanager_v3_SMOutgoingMessages outgoingMessage servicemanager_v3_SMOutgoingMessages_init_default; - - err = ReceiveCMOutgoingMessage(fixture->mSecureChannel, outgoingMessage); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - aos::InstanceStatusStaticArray receiveRunStatus {}; - - for (auto i = 0; i < outgoingMessage.SMOutgoingMessage.run_instances_status.instances_count; i++) { - aos::InstanceStatus instanceStatus; - - PBToInstanceStatus(outgoingMessage.SMOutgoingMessage.run_instances_status.instances[i], instanceStatus); - receiveRunStatus.PushBack(instanceStatus); - } - - zassert_equal( - outgoingMessage.which_SMOutgoingMessage, servicemanager_v3_SMOutgoingMessages_run_instances_status_tag); - zassert_equal(receiveRunStatus, sendRunStatus); -} - -ZTEST_F(cmclient, test_InstancesUpdateStatus) -{ - aos::InstanceStatusStaticArray sendUpdateStatus {}; - - sendUpdateStatus.EmplaceBack(aos::InstanceStatus { - {"service1", "subject1", 0}, 1, aos::InstanceRunStateEnum::eFailed, aos::ErrorEnum::eNoMemory}); - sendUpdateStatus.EmplaceBack(aos::InstanceStatus { - {"service1", "subject1", 1}, 1, aos::InstanceRunStateEnum::eActive, aos::ErrorEnum::eNone}); - - auto err = fixture->mCommunication.InstancesUpdateStatus(sendUpdateStatus); - zassert_true(err.IsNone(), "Error sending update instances status: %s", err.Message()); - - servicemanager_v3_SMOutgoingMessages outgoingMessage servicemanager_v3_SMOutgoingMessages_init_default; - - err = ReceiveCMOutgoingMessage(fixture->mSecureChannel, outgoingMessage); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - aos::InstanceStatusStaticArray receiveUpdateStatus {}; - - for (auto i = 0; i < outgoingMessage.SMOutgoingMessage.update_instances_status.instances_count; i++) { - aos::InstanceStatus instanceStatus; - - PBToInstanceStatus(outgoingMessage.SMOutgoingMessage.update_instances_status.instances[i], instanceStatus); - receiveUpdateStatus.PushBack(instanceStatus); - } - - zassert_equal( - outgoingMessage.which_SMOutgoingMessage, servicemanager_v3_SMOutgoingMessages_update_instances_status_tag); - zassert_equal(receiveUpdateStatus, sendUpdateStatus); -} - -ZTEST_F(cmclient, test_ImageContentRequest) -{ - ImageContentRequest sendContentRequest {"content URL", 42, aos::DownloadContentEnum::eService}; - - auto err = fixture->mCommunication.SendImageContentRequest(sendContentRequest); - zassert_true(err.IsNone(), "Error sending image content request: %s", err.Message()); - - servicemanager_v3_SMOutgoingMessages outgoingMessage servicemanager_v3_SMOutgoingMessages_init_default; - - err = ReceiveCMOutgoingMessage(fixture->mSecureChannel, outgoingMessage); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - ImageContentRequest receiveContentRequest {}; - - PBToString(outgoingMessage.SMOutgoingMessage.image_content_request.url, receiveContentRequest.mURL); - receiveContentRequest.mRequestID = outgoingMessage.SMOutgoingMessage.image_content_request.request_id; - PBToEnum(outgoingMessage.SMOutgoingMessage.image_content_request.content_type, receiveContentRequest.mContentType); - - zassert_equal( - outgoingMessage.which_SMOutgoingMessage, servicemanager_v3_SMOutgoingMessages_image_content_request_tag); - zassert_equal(receiveContentRequest, sendContentRequest); -} - -ZTEST_F(cmclient, test_MonitoringData) -{ - aos::monitoring::NodeMonitoringData sendMonitoringData {"", {1024, 100, {}, 10, 20}, {10, 20}}; - - sendMonitoringData.mMonitoringData.mDisk.EmplaceBack(aos::monitoring::PartitionInfo {"disk1", "", {}, 0, 2048}); - sendMonitoringData.mMonitoringData.mDisk.EmplaceBack(aos::monitoring::PartitionInfo {"disk2", "", {}, 0, 4096}); - - sendMonitoringData.mServiceInstances.EmplaceBack( - aos::monitoring::InstanceMonitoringData {"", {"service1", "subject1", 0}, {512, 50, {}, 30, 30}}); - sendMonitoringData.mServiceInstances.end()->mMonitoringData.mDisk.EmplaceBack( - aos::monitoring::PartitionInfo {"disk3", "", {}, 0, 192}); - sendMonitoringData.mServiceInstances.end()->mMonitoringData.mDisk.EmplaceBack( - aos::monitoring::PartitionInfo {"disk4", "", {}, 0, 243}); - sendMonitoringData.mServiceInstances.EmplaceBack( - aos::monitoring::InstanceMonitoringData {"", {"service1", "subject1", 1}, {256, 32, {}, 33, 32}}); - sendMonitoringData.mServiceInstances.end()->mMonitoringData.mDisk.EmplaceBack( - aos::monitoring::PartitionInfo {"disk5", "", {}, 0, 543}); - sendMonitoringData.mServiceInstances.EmplaceBack( - aos::monitoring::InstanceMonitoringData {"", {"service1", "subject1", 2}, {128, 15, {}, 43, 12}}); - - auto err = fixture->mCommunication.SendMonitoringData(sendMonitoringData); - zassert_true(err.IsNone(), "Error sending monitoring data: %s", err.Message()); - - servicemanager_v3_SMOutgoingMessages outgoingMessage servicemanager_v3_SMOutgoingMessages_init_default; - - err = ReceiveCMOutgoingMessage(fixture->mSecureChannel, outgoingMessage); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - aos::monitoring::NodeMonitoringData receiveMonitoringData {}; - - const auto& pbMonitoringData = outgoingMessage.SMOutgoingMessage.node_monitoring; - - if (pbMonitoringData.has_monitoring_data) { - PBToMonitoringData(pbMonitoringData.monitoring_data, receiveMonitoringData.mMonitoringData); - } - - receiveMonitoringData.mServiceInstances.Resize(pbMonitoringData.instance_monitoring_count); - - for (size_t i = 0; i < pbMonitoringData.instance_monitoring_count; i++) { - if (pbMonitoringData.instance_monitoring[i].has_instance) { - PBToInstanceIdent(pbMonitoringData.instance_monitoring[i].instance, - receiveMonitoringData.mServiceInstances[i].mInstanceIdent); - } - - if (pbMonitoringData.instance_monitoring[i].has_monitoring_data) { - PBToMonitoringData(pbMonitoringData.instance_monitoring[i].monitoring_data, - receiveMonitoringData.mServiceInstances[i].mMonitoringData); - } - } - - if (pbMonitoringData.has_timestamp) { - receiveMonitoringData.mTimestamp.tv_sec = pbMonitoringData.timestamp.seconds; - receiveMonitoringData.mTimestamp.tv_nsec = pbMonitoringData.timestamp.nanos; - } - - zassert_equal(outgoingMessage.which_SMOutgoingMessage, servicemanager_v3_SMOutgoingMessages_node_monitoring_tag); - zassert_equal(receiveMonitoringData, sendMonitoringData); -} - -ZTEST_F(cmclient, test_ClockSync) -{ - fixture->mCommunication.ClockUnsynced(); - - fixture->mSecureChannel.SendRead(std::vector(), aos::ErrorEnum::eFailed); - - // Wait clock sync start - - auto err = fixture->mClockSync.WaitEvent(cWaitTimeout); - zassert_true(err.IsNone(), "Error waiting clock sync start: %s", err.Message()); - - zassert_true(fixture->mClockSync.GetStarted()); - - // Wait clock sync request - - err = fixture->mCommunication.SendClockSyncRequest(); - zassert_true(err.IsNone(), "Error sending clock sync request: %s", err.Message()); - - servicemanager_v3_SMOutgoingMessages outgoingMessage servicemanager_v3_SMOutgoingMessages_init_default; - - err = ReceiveCMOutgoingMessage(fixture->mOpenChannel, outgoingMessage); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - zassert_equal(outgoingMessage.which_SMOutgoingMessage, servicemanager_v3_SMOutgoingMessages_clock_sync_request_tag); - - // Send clock sync - - servicemanager_v3_SMIncomingMessages incomingMessage servicemanager_v3_SMIncomingMessages_init_default; - - incomingMessage.which_SMIncomingMessage = servicemanager_v3_SMIncomingMessages_clock_sync_tag; - incomingMessage.SMIncomingMessage.clock_sync.has_current_time = true; - incomingMessage.SMIncomingMessage.clock_sync.current_time.seconds = 43; - incomingMessage.SMIncomingMessage.clock_sync.current_time.nanos = 234; - - err = SendCMIncomingMessage(fixture->mOpenChannel, incomingMessage); - zassert_true(err.IsNone(), "Error sending message: %s", err.Message()); - - err = fixture->mClockSync.WaitEvent(cWaitTimeout); - zassert_true(err.IsNone(), "Error waiting clock sync start: %s", err.Message()); - - zassert_equal(fixture->mClockSync.GetSyncTime(), - aos::Time::Unix(incomingMessage.SMIncomingMessage.clock_sync.current_time.seconds, - incomingMessage.SMIncomingMessage.clock_sync.current_time.nanos)); - - fixture->mCommunication.ClockSynced(); - - // Wait node configuration - - outgoingMessage = servicemanager_v3_SMOutgoingMessages servicemanager_v3_SMOutgoingMessages_init_default; - - err = ReceiveCMOutgoingMessage(fixture->mSecureChannel, outgoingMessage); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - zassert_equal(outgoingMessage.which_SMOutgoingMessage, servicemanager_v3_SMOutgoingMessages_node_configuration_tag); -} diff --git a/tests/communication/src/iamserver.cpp b/tests/communication/src/iamserver.cpp deleted file mode 100644 index f5169c96..00000000 --- a/tests/communication/src/iamserver.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#include "communication/communication.hpp" - -#include "stubs/certhandlerstub.hpp" -#include "stubs/clocksyncstub.hpp" -#include "stubs/commchannelstub.hpp" -#include "stubs/connectionsubscriberstub.hpp" -#include "stubs/downloaderstub.hpp" -#include "stubs/launcherstub.hpp" -#include "stubs/monitoringstub.hpp" -#include "stubs/provisioningstub.hpp" -#include "stubs/resourcemanagerstub.hpp" -#include "utils.hpp" - -/*********************************************************************************************************************** - * Types - **********************************************************************************************************************/ - -struct iamserver_fixture { - CommChannelStub mOpenChannel; - CommChannelStub mSecureChannel; - LauncherStub mLauncher; - CertHandlerStub mCertHandler; - ResourceManagerStub mResourceManager; - ResourceMonitorStub mResourceMonitor; - DownloaderStub mDownloader; - ClockSyncStub mClockSync; - ProvisioningStub mProvisioning; - Communication mCommunication; -}; - -/*********************************************************************************************************************** - * Static - **********************************************************************************************************************/ - -static std::string FullMethodName(const std::string& serviceName, const std::string& methodName) -{ - return "/" + serviceName + "/" + methodName; -} - -/*********************************************************************************************************************** - * Setup - **********************************************************************************************************************/ - -ZTEST_SUITE( - iamserver, nullptr, - []() -> void* { - aos::Log::SetCallback(TestLogCallback); - - auto fixture = new iamserver_fixture; - - auto err = fixture->mCommunication.Init(fixture->mOpenChannel, fixture->mSecureChannel, fixture->mLauncher, - fixture->mCertHandler, fixture->mResourceManager, fixture->mResourceMonitor, fixture->mDownloader, - fixture->mClockSync, fixture->mProvisioning); - zassert_true(err.IsNone(), "Can't initialize communication: %s", err.Message()); - - fixture->mCommunication.ClockSynced(); - - return fixture; - }, - [](void* fixture) { - auto f = static_cast(fixture); - - f->mOpenChannel.Clear(); - f->mSecureChannel.Clear(); - f->mLauncher.Clear(); - f->mCertHandler.Clear(); - f->mResourceManager.Clear(); - f->mResourceMonitor.Clear(); - f->mDownloader.Clear(); - f->mClockSync.Clear(); - f->mProvisioning.SetProvisioned(false); - }, - nullptr, [](void* fixture) { delete static_cast(fixture); }); - -/*********************************************************************************************************************** - * Tests - **********************************************************************************************************************/ - -ZTEST_F(iamserver, test_GetAllNodeIDs) -{ - auto err = SendPBMessage(fixture->mSecureChannel, AOS_VCHAN_IAM, - FullMethodName(IAMServer::cServiceProvisioning, IAMServer::cMethodGetAllNodeIDs), 0); - zassert_true(err.IsNone(), "Error sending message: %s", err.Message()); - - iamanager_v4_NodesID nodesID; - - err = ReceivePBMessage( - fixture->mSecureChannel, AOS_VCHAN_IAM, "", 0, &iamanager_v4_NodesID_msg, &nodesID, iamanager_v4_NodesID_size); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - zassert_equal(nodesID.ids_count, 1); - zassert_equal(strcmp(nodesID.ids[0], CONFIG_AOS_NODE_ID), 0); -} - -ZTEST_F(iamserver, test_GetCertTypes) -{ - std::vector certTypes {"certType1", "certType2", "certType3"}; - - fixture->mCertHandler.SetCertTypes(certTypes); - - auto err = SendPBMessage(fixture->mSecureChannel, AOS_VCHAN_IAM, - FullMethodName(IAMServer::cServiceProvisioning, IAMServer::cMethodGetCertTypes), 0); - zassert_true(err.IsNone(), "Error sending message: %s", err.Message()); - - iamanager_v4_CertTypes pbCertTypes; - - err = ReceivePBMessage(fixture->mSecureChannel, AOS_VCHAN_IAM, "", 0, &iamanager_v4_CertTypes_msg, &pbCertTypes, - iamanager_v4_CertTypes_size); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - zassert_equal(pbCertTypes.types_count, certTypes.size()); - - for (size_t i = 0; i < certTypes.size(); i++) { - zassert_equal(strcmp(certTypes[i].c_str(), pbCertTypes.types[i]), 0); - } -} - -ZTEST_F(iamserver, test_SetOwner) -{ - iamanager_v4_SetOwnerRequest pbSetOwner {CONFIG_AOS_NODE_ID, "certType", "password"}; - - auto err = SendPBMessage(fixture->mSecureChannel, AOS_VCHAN_IAM, - FullMethodName(IAMServer::cServiceProvisioning, IAMServer::cMethodSetOwner), 42, - &iamanager_v4_SetOwnerRequest_msg, &pbSetOwner, iamanager_v4_SetOwnerRequest_size); - zassert_true(err.IsNone(), "Error sending message: %s", err.Message()); - - err = ReceivePBMessage(fixture->mSecureChannel, AOS_VCHAN_IAM, "", 42); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - zassert_equal(fixture->mCertHandler.GetCertType(), pbSetOwner.type); - zassert_equal(fixture->mCertHandler.GetPassword(), pbSetOwner.password); -} - -ZTEST_F(iamserver, test_Clear) -{ - iamanager_v4_ClearRequest pbClear {CONFIG_AOS_NODE_ID, "certType"}; - - auto err = SendPBMessage(fixture->mSecureChannel, AOS_VCHAN_IAM, - FullMethodName(IAMServer::cServiceProvisioning, IAMServer::cMethodClear), 43, &iamanager_v4_ClearRequest_msg, - &pbClear, iamanager_v4_ClearRequest_size); - zassert_true(err.IsNone(), "Error sending message: %s", err.Message()); - - err = ReceivePBMessage(fixture->mSecureChannel, AOS_VCHAN_IAM, "", 43); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - zassert_true(fixture->mCertHandler.GetClear()); -} - -ZTEST_F(iamserver, test_DiskEncryption) -{ - iamanager_v4_EncryptDiskRequest pbEncryptDisk {CONFIG_AOS_NODE_ID, "password"}; - - auto err = SendPBMessage(fixture->mSecureChannel, AOS_VCHAN_IAM, - FullMethodName(IAMServer::cServiceProvisioning, IAMServer::cMethodEncryptDisk), 44, - &iamanager_v4_EncryptDiskRequest_msg, &pbEncryptDisk, iamanager_v4_EncryptDiskRequest_size); - zassert_true(err.IsNone(), "Error sending message: %s", err.Message()); - - err = ReceivePBMessage(fixture->mSecureChannel, AOS_VCHAN_IAM, "", 44); - zassert_true(err.Is(aos::ErrorEnum::eNotSupported), "Wrong error received: %s", err.Message()); -} - -ZTEST_F(iamserver, test_CreateKey) -{ - iamanager_v4_CreateKeyRequest pbCreateKeyRequest {CONFIG_AOS_NODE_ID, "subject", "type", "password"}; - - const auto csr = "CSR payload"; - - fixture->mCertHandler.SetCSR(csr); - - auto err = SendPBMessage(fixture->mSecureChannel, AOS_VCHAN_IAM, - FullMethodName(IAMServer::cServiceCertificate, IAMServer::cMethodCreateKey), 46, - &iamanager_v4_CreateKeyRequest_msg, &pbCreateKeyRequest, iamanager_v4_CreateKeyRequest_size); - zassert_true(err.IsNone(), "Error sending message: %s", err.Message()); - - iamanager_v4_CreateKeyResponse pbCreateKeyResponse iamanager_v4_CreateKeyResponse_init_default; - - err = ReceivePBMessage(fixture->mSecureChannel, AOS_VCHAN_IAM, "", 46, &iamanager_v4_CreateKeyResponse_msg, - &pbCreateKeyResponse, iamanager_v4_CreateKeyResponse_size); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - zassert_equal(strcmp(pbCreateKeyResponse.node_id, pbCreateKeyRequest.node_id), 0); - zassert_equal(strcmp(pbCreateKeyResponse.type, pbCreateKeyRequest.type), 0); - zassert_equal(strcmp(pbCreateKeyResponse.csr, csr), 0); - zassert_equal(fixture->mCertHandler.GetSubject(), pbCreateKeyRequest.subject); -} - -ZTEST_F(iamserver, test_ApplyCert) -{ - iamanager_v4_ApplyCertRequest pbApplyCertRequest {CONFIG_AOS_NODE_ID, "type", "Certificate payload"}; - - const uint8_t serial[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - aos::iam::certhandler::CertInfo certInfo {{}, aos::Array(serial, sizeof(serial)), "certificate URL"}; - - fixture->mCertHandler.SetCertInfo(certInfo); - - auto err = SendPBMessage(fixture->mSecureChannel, AOS_VCHAN_IAM, - FullMethodName(IAMServer::cServiceCertificate, IAMServer::cMethodApplyCert), 47, - &iamanager_v4_ApplyCertRequest_msg, &pbApplyCertRequest, iamanager_v4_ApplyCertRequest_size); - zassert_true(err.IsNone(), "Error sending message: %s", err.Message()); - - iamanager_v4_ApplyCertResponse pbApplyCertResponse iamanager_v4_ApplyCertResponse_init_default; - - err = ReceivePBMessage(fixture->mSecureChannel, AOS_VCHAN_IAM, "", 47, &iamanager_v4_ApplyCertResponse_msg, - &pbApplyCertResponse, iamanager_v4_ApplyCertResponse_size); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); - - aos::StaticString strSerial; - - err = strSerial.ByteArrayToHex(aos::Array(serial, sizeof(serial))); - zassert_true(err.IsNone(), "Can't convert serial: %s", err.Message()); - - zassert_equal(strcmp(pbApplyCertResponse.node_id, pbApplyCertRequest.node_id), 0); - zassert_equal(strcmp(pbApplyCertResponse.type, pbApplyCertRequest.type), 0); - zassert_equal(fixture->mCertHandler.GetCertificate(), pbApplyCertRequest.cert); - zassert_equal(certInfo.mCertURL, pbApplyCertResponse.cert_url); - zassert_equal(strSerial, pbApplyCertResponse.serial); -} - -// Tests are executed by alphabetical order. -// This test should be run at the end as it removes provisioning PB services from open channel. -ZTEST_F(iamserver, test_ZZZ_FinishProvisioning) -{ - - auto err = SendPBMessage(fixture->mSecureChannel, AOS_VCHAN_IAM, - FullMethodName(IAMServer::cServiceProvisioning, IAMServer::cMethodFinishProvisioning), 45); - zassert_true(err.IsNone(), "Error sending message: %s", err.Message()); - - err = ReceivePBMessage(fixture->mSecureChannel, AOS_VCHAN_IAM, "", 45); - zassert_true(err.IsNone(), "Error receiving message: %s", err.Message()); -} diff --git a/tests/communication/src/stubs/certhandlerstub.hpp b/tests/communication/src/stubs/certhandlerstub.hpp deleted file mode 100644 index 12f8dfa0..00000000 --- a/tests/communication/src/stubs/certhandlerstub.hpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2024 Renesas Electronics Corporation. - * Copyright (C) 2024 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef CERTHANDLERSTUB_HPP_ -#define CERTHANDLERSTUB_HPP_ - -#include -#include - -#include - -class CertHandlerStub : public aos::iam::certhandler::CertHandlerItf { -public: - aos::Error GetCertTypes(aos::Array>& certTypes) override - { - std::lock_guard lock(mMutex); - - for (const auto& type : mCertTypes) { - certTypes.PushBack(type.c_str()); - } - - return aos::ErrorEnum::eNone; - } - - aos::Error SetOwner(const aos::String& certType, const aos::String& password) override - { - std::lock_guard lock(mMutex); - - mCertType = certType.CStr(); - mPassword = password.CStr(); - - return aos::ErrorEnum::eNone; - } - - aos::Error Clear(const aos::String& certType) override - { - std::lock_guard lock(mMutex); - - mClear = true; - - return aos::ErrorEnum::eNone; - } - - aos::Error CreateKey(const aos::String& certType, const aos::String& subjectCommonName, const aos::String& password, - aos::String& pemCSR) override - { - std::lock_guard lock(mMutex); - - mCertType = certType.CStr(); - mSubject = subjectCommonName.CStr(); - mPassword = password.CStr(); - - pemCSR = mCSR.c_str(); - - return aos::ErrorEnum::eNone; - } - - aos::Error ApplyCertificate( - const aos::String& certType, const aos::String& pemCert, aos::iam::certhandler::CertInfo& info) override - { - std::lock_guard lock(mMutex); - - mCertificate.assign(reinterpret_cast(pemCert.Get()), pemCert.Size()); - info = mCertInfo; - - return aos::ErrorEnum::eNone; - } - - aos::Error GetCertificate(const aos::String& certType, const aos::Array& issuer, - const aos::Array& serial, aos::iam::certhandler::CertInfo& resCert) override - { - resCert.mCertURL = CERT_DIR "/client.cer"; - resCert.mKeyURL = CERT_DIR "/client.key"; - - return aos::ErrorEnum::eNone; - } - - aos::Error CreateSelfSignedCert(const aos::String& certType, const aos::String& password) override - { - return aos::ErrorEnum::eNone; - } - - void Clear() - { - std::lock_guard lock(mMutex); - - mCertTypes.clear(); - mCertType.clear(); - mPassword.clear(); - mClear = false; - mSubject.clear(); - mCSR.clear(); - mCertificate.clear(); - mCertInfo = {}; - } - - void SetCertTypes(const std::vector& certTypes) - { - std::lock_guard lock(mMutex); - - mCertTypes = certTypes; - } - - void SetCSR(const std::string& csr) - { - std::lock_guard lock(mMutex); - - mCSR = csr; - } - - std::string GetCertType() const - { - std::lock_guard lock(mMutex); - - return mCertType; - } - - std::string GetPassword() const - { - std::lock_guard lock(mMutex); - - return mPassword; - } - - bool GetClear() const - { - std::lock_guard lock(mMutex); - - return mClear; - } - - std::string GetSubject() const - { - std::lock_guard lock(mMutex); - - return mSubject; - } - - std::string GetCertificate() const - { - std::lock_guard lock(mMutex); - - return mCertificate; - } - - void SetCertInfo(const aos::iam::certhandler::CertInfo& info) { mCertInfo = info; } - -private: - mutable std::mutex mMutex; - - std::vector mCertTypes; - std::string mCertType; - std::string mPassword; - bool mClear = false; - std::string mSubject; - std::string mCSR; - std::string mCertificate; - aos::iam::certhandler::CertInfo mCertInfo; -}; - -#endif diff --git a/tests/communication/src/stubs/certloaderstub.hpp b/tests/communication/src/stubs/certloaderstub.hpp deleted file mode 100644 index f8b23630..00000000 --- a/tests/communication/src/stubs/certloaderstub.hpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2024 Renesas Electronics Corporation. - * Copyright (C) 2024 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef CERTLOADERSTUB_HPP_ -#define CERTLOADERSTUB_HPP_ - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include "rsaprivatekey.hpp" - -class CertLoaderStub : public aos::cryptoutils::CertLoaderItf { -public: - aos::Error Init(aos::crypto::x509::ProviderItf& cryptoProvider, aos::pkcs11::PKCS11Manager& pkcs11Manager) override - { - return aos::ErrorEnum::eNone; - } - - aos::RetWithError> LoadCertsChainByURL( - const aos::String& url) override - { - - auto certChain = aos::MakeShared(&mCertAllocator); - - aos::StaticString mCertChainPem; - - auto err = aos::FS::ReadFileToString(url, mCertChainPem); - if (!err.IsNone()) { - return {nullptr, err}; - } - - aos::crypto::x509::Certificate cert; - cert.mRaw - = aos::Array(reinterpret_cast(mCertChainPem.Get()), mCertChainPem.Size() + 1); - - certChain->PushBack(cert); - - return {certChain, aos::ErrorEnum::eNone}; - } - - aos::RetWithError> LoadPrivKeyByURL(const aos::String& url) override - { - aos::StaticString mPKPem; - mbedtls_pk_context pkContext; - mbedtls_ctr_drbg_context ctrDrbg; - - mbedtls_pk_init(&pkContext); - mbedtls_ctr_drbg_init(&ctrDrbg); - - std::unique_ptr ctrDrbgPtr( - &ctrDrbg, mbedtls_ctr_drbg_free); - - auto err = aos::FS::ReadFileToString(url, mPKPem); - if (!err.IsNone()) { - return {nullptr, err}; - } - - auto ret = mbedtls_pk_parse_key(&pkContext, reinterpret_cast(mPKPem.Get()), - mPKPem.Size() + 1, nullptr, 0, mbedtls_ctr_drbg_random, &ctrDrbg); - if (ret != 0) { - return {nullptr, ret}; - } - - if (mbedtls_pk_get_type(&pkContext) != MBEDTLS_PK_RSA) { - return {nullptr, aos::ErrorEnum::eNotSupported}; - } - - mbedtls_rsa_context* rsa_context = mbedtls_pk_rsa(pkContext); - - mbedtls_mpi mpiN, mpiE; - - mbedtls_mpi_init(&mpiN); - mbedtls_mpi_init(&mpiE); - - std::unique_ptr mpiNPtr(&mpiN, mbedtls_mpi_free); - std::unique_ptr mpiEPtr(&mpiE, mbedtls_mpi_free); - - if ((ret = mbedtls_rsa_export(rsa_context, mpiNPtr.get(), nullptr, nullptr, nullptr, mpiEPtr.get())) != 0) { - return {nullptr, ret}; - } - - aos::StaticArray mN; - aos::StaticArray mE; - - if ((ret = ConvertMbedtlsMpiToArray(mpiNPtr.get(), mN)) != 0) { - return {nullptr, ret}; - } - - if ((ret = ConvertMbedtlsMpiToArray(mpiEPtr.get(), mE)) != 0) { - return {nullptr, ret}; - } - - aos::crypto::RSAPublicKey rsaPublicKey(mN, mE); - - return {aos::MakeShared(&mKeyAllocator, rsaPublicKey, pkContext), aos::ErrorEnum::eNone}; - } - -private: - static constexpr auto cCertAllocatorSize = 2 * sizeof(aos::crypto::x509::CertificateChain); - static constexpr auto cKeyAllocatorSize = 2 * sizeof(RSAPrivateKey); - - int ConvertMbedtlsMpiToArray(const mbedtls_mpi* mpi, aos::Array& outArray) - { - outArray.Resize(mbedtls_mpi_size(mpi)); - - return mbedtls_mpi_write_binary(mpi, outArray.Get(), outArray.Size()); - } - - aos::StaticAllocator mCertAllocator; - aos::StaticAllocator mKeyAllocator; -}; - -#endif diff --git a/tests/communication/src/stubs/clocksyncstub.hpp b/tests/communication/src/stubs/clocksyncstub.hpp deleted file mode 100644 index a5ebf619..00000000 --- a/tests/communication/src/stubs/clocksyncstub.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef CLOCKSYNCSTUB_HPP_ -#define CLOCKSYNCSTUB_HPP_ - -#include -#include - -#include "clocksync/clocksync.hpp" - -class ClockSyncStub : public ClockSyncItf { -public: - aos::Error Start() override - { - std::lock_guard lock(mMutex); - - mStarted = true; - mEventReceived = true; - mCV.notify_one(); - - return aos::ErrorEnum::eNone; - } - - aos::Error Sync(const aos::Time& time) override - { - std::lock_guard lock(mMutex); - - mSyncTime = time; - mEventReceived = true; - mCV.notify_one(); - - return aos::ErrorEnum::eNone; - } - - bool GetStarted() const - { - std::lock_guard lock(mMutex); - return mStarted; - } - - aos::Time GetSyncTime() const - { - std::lock_guard lock(mMutex); - return mSyncTime; - } - - aos::Error WaitEvent(const std::chrono::duration timeout) - { - std::unique_lock lock(mMutex); - - if (!mCV.wait_for(lock, timeout, [&] { return mEventReceived; })) { - return aos::ErrorEnum::eTimeout; - } - - mEventReceived = false; - - return aos::ErrorEnum::eNone; - } - - void Clear() - { - std::lock_guard lock(mMutex); - - mEventReceived = false; - mStarted = false; - mSyncTime = aos::Time(); - } - -private: - std::condition_variable mCV; - mutable std::mutex mMutex; - bool mEventReceived = false; - bool mStarted = false; - aos::Time mSyncTime; -}; - -#endif diff --git a/tests/communication/src/stubs/commchannelstub.hpp b/tests/communication/src/stubs/commchannelstub.hpp deleted file mode 100644 index 2794f4a9..00000000 --- a/tests/communication/src/stubs/commchannelstub.hpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef COMMCHANNELSTUB_HPP_ -#define COMMCHANNELSTUB_HPP_ - -#include -#include -#include - -#include "communication/commchannel.hpp" - -class CommChannelStub : public CommChannelItf { -public: - aos::Error SetTLSConfig(const aos::String& certType) override { return aos::ErrorEnum::eNone; } - - aos::Error Connect() override - { - std::lock_guard lock(mMutex); - - mConnected = true; - - return mConnectError; - } - - aos::Error Close() override - { - std::lock_guard lock(mMutex); - - mConnected = false; - - mCV.notify_one(); - - return mConnectError; - } - - int Read(void* data, size_t size) override - { - std::unique_lock lock(mMutex); - - mCV.wait(lock, [&] { return mReadData.size() >= size || !mReadError.IsNone() || !mConnected; }); - - if (!mConnected) { - return -1; - } - - if (!mReadError.IsNone()) { - mReadError = aos::ErrorEnum::eNone; - return -1; - } - - std::copy(mReadData.begin(), mReadData.begin() + size, static_cast(data)); - mReadData.erase(mReadData.begin(), mReadData.begin() + size); - - return size; - } - - int Write(const void* data, size_t size) override - { - std::lock_guard lock(mMutex); - - mWriteData.insert( - mWriteData.end(), static_cast(data), static_cast(data) + size); - - mCV.notify_one(); - - return size; - } - - bool IsConnected() const override - { - std::lock_guard lock(mMutex); - return mConnected; - } - - aos::Error WaitWrite(std::vector& data, size_t size, const std::chrono::duration& timeout, - aos::Error err = aos::ErrorEnum::eNone) - { - std::unique_lock lock(mMutex); - - mWriteError = err; - - if (!mCV.wait_for(lock, timeout, [&] { return mWriteData.size() >= size; })) { - return aos::ErrorEnum::eTimeout; - } - - data.assign(mWriteData.begin(), mWriteData.begin() + size); - mWriteData.erase(mWriteData.begin(), mWriteData.begin() + size); - - return aos::ErrorEnum::eNone; - } - - void SendRead(const std::vector& data, aos::Error err = aos::ErrorEnum::eNone) - { - std::lock_guard lock(mMutex); - - mReadError = err; - mReadData.insert(mReadData.end(), data.begin(), data.end()); - - mCV.notify_one(); - } - - void Clear() - { - std::lock_guard lock(mMutex); - - mReadData.clear(); - mWriteData.clear(); - mConnectError = aos::ErrorEnum::eNone; - mReadError = aos::ErrorEnum::eNone; - mWriteError = aos::ErrorEnum::eNone; - } - -private: - bool mConnected = false; - std::vector mReadData; - std::vector mWriteData; - aos::Error mConnectError; - aos::Error mReadError; - aos::Error mWriteError; - std::condition_variable mCV; - mutable std::mutex mMutex; -}; - -#endif diff --git a/tests/communication/src/stubs/connectionsubscriberstub.hpp b/tests/communication/src/stubs/connectionsubscriberstub.hpp deleted file mode 100644 index 7891644d..00000000 --- a/tests/communication/src/stubs/connectionsubscriberstub.hpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef CONNECTIONSUBSCRIBERSTUB_HPP_ -#define CONNECTIONSUBSCRIBERSTUB_HPP_ - -#include -#include - -#include - -class ConnectionSubscriberStub : public aos::ConnectionSubscriberItf { -public: - void OnConnect() override - { - std::lock_guard lock(mMutex); - - mConnected = true; - mConnect = true; - mCV.notify_one(); - } - - void OnDisconnect() override - { - std::lock_guard lock(mMutex); - - mConnected = false; - mDisconnect = true; - mCV.notify_one(); - } - - aos::Error WaitConnect(const std::chrono::duration& timeout) - { - std::unique_lock lock(mMutex); - - if (!mCV.wait_for(lock, timeout, [&] { return mConnect; })) { - return aos::ErrorEnum::eTimeout; - } - - mConnect = false; - - return aos::ErrorEnum::eNone; - } - - aos::Error WaitDisconnect(const std::chrono::duration& timeout) - { - std::unique_lock lock(mMutex); - - if (!mCV.wait_for(lock, timeout, [&] { return mDisconnect; })) { - return aos::ErrorEnum::eTimeout; - } - - mDisconnect = false; - - return aos::ErrorEnum::eNone; - } - - bool IsConnected() const - { - std::lock_guard lock(mMutex); - return mConnected; - } - - void Clear() - { - std::lock_guard lock(mMutex); - - mConnected = false; - mConnect = false; - mDisconnect = false; - } - -private: - bool mConnected = false; - bool mConnect = false; - bool mDisconnect = false; - std::condition_variable mCV; - mutable std::mutex mMutex; -}; - -#endif diff --git a/tests/communication/src/stubs/downloaderstub.hpp b/tests/communication/src/stubs/downloaderstub.hpp deleted file mode 100644 index 33a8c95b..00000000 --- a/tests/communication/src/stubs/downloaderstub.hpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef DOWNLOADERSTUB_HPP_ -#define DOWNLOADERSTUB_HPP_ - -#include -#include - -#include "downloader/downloader.hpp" - -class DownloaderStub : public DownloadReceiverItf { -public: - aos::Error ReceiveFileChunk(const FileChunk& chunk) override - { - std::lock_guard lock(mMutex); - - mFileChunk = chunk; - mEventReceived = true; - - mCV.notify_one(); - - return aos::ErrorEnum::eNone; - } - - aos::Error ReceiveImageContentInfo(const ImageContentInfo& content) override - { - std::lock_guard lock(mMutex); - - mContentInfo = content; - mEventReceived = true; - - mCV.notify_one(); - - return aos::ErrorEnum::eNone; - } - - const FileChunk& GetFileChunk() const - { - std::lock_guard lock(mMutex); - return mFileChunk; - } - - const ImageContentInfo& GetContentInfo() const - { - std::lock_guard lock(mMutex); - return mContentInfo; - } - - aos::Error WaitEvent(const std::chrono::duration timeout) - { - std::unique_lock lock(mMutex); - - if (!mCV.wait_for(lock, timeout, [&] { return mEventReceived; })) { - return aos::ErrorEnum::eTimeout; - } - - mEventReceived = false; - - return aos::ErrorEnum::eNone; - } - - void Clear() - { - std::lock_guard lock(mMutex); - - mEventReceived = false; - mContentInfo = ImageContentInfo(); - mFileChunk = FileChunk(); - } - -private: - ImageContentInfo mContentInfo {}; - FileChunk mFileChunk {}; - - std::condition_variable mCV; - mutable std::mutex mMutex; - bool mEventReceived = false; -}; - -#endif diff --git a/tests/communication/src/stubs/launcherstub.hpp b/tests/communication/src/stubs/launcherstub.hpp deleted file mode 100644 index b3ff0e97..00000000 --- a/tests/communication/src/stubs/launcherstub.hpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef LAUNCHERSTUB_HPP_ -#define LAUNCHERSTUB_HPP_ - -#include -#include - -#include -#include - -class LauncherStub : public aos::sm::launcher::LauncherItf { -public: - aos::Error RunInstances(const aos::Array& services, const aos::Array& layers, - const aos::Array& instances, bool forceRestart) override - { - std::lock_guard lock(mMutex); - - mServices = services; - mLayers = layers; - mInstances = instances; - mForceRestart = forceRestart; - mEventReceived = true; - - mCV.notify_one(); - - return aos::ErrorEnum::eNone; - } - - aos::Error WaitEvent(const std::chrono::duration timeout) - { - std::unique_lock lock(mMutex); - - if (!mCV.wait_for(lock, timeout, [&] { return mEventReceived; })) { - return aos::ErrorEnum::eTimeout; - } - - mEventReceived = false; - - return aos::ErrorEnum::eNone; - } - - const aos::Array GetServices() const - { - std::lock_guard lock(mMutex); - return mServices; - } - - const aos::Array GetLayers() const - { - std::lock_guard lock(mMutex); - return mLayers; - } - - const aos::Array GetInstances() const - { - std::lock_guard lock(mMutex); - return mInstances; - } - - bool IsForceRestart() const - { - std::lock_guard lock(mMutex); - return mForceRestart; - } - - void Clear() - { - std::lock_guard lock(mMutex); - - mEventReceived = false; - mServices.Clear(); - mLayers.Clear(); - mInstances.Clear(); - mForceRestart = false; - } - -private: - static constexpr auto cWaitTimeout = std::chrono::seconds {1}; - - aos::ServiceInfoStaticArray mServices {}; - aos::LayerInfoStaticArray mLayers {}; - aos::InstanceInfoStaticArray mInstances {}; - bool mForceRestart = false; - - std::condition_variable mCV; - mutable std::mutex mMutex; - bool mEventReceived = false; -}; - -#endif diff --git a/tests/communication/src/stubs/monitoringstub.hpp b/tests/communication/src/stubs/monitoringstub.hpp deleted file mode 100644 index 74475a08..00000000 --- a/tests/communication/src/stubs/monitoringstub.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef MONITORINGSTUB_HPP_ -#define MONITORINGSTUB_HPP_ - -#include - -class ResourceMonitorStub : public aos::monitoring::ResourceMonitorItf { -public: - aos::Error GetNodeInfo(aos::NodeInfo& nodeInfo) const override - { - nodeInfo = mNodeInfo; - return aos::ErrorEnum::eNone; - } - - aos::Error StartInstanceMonitoring( - const aos::String& instanceID, const aos::monitoring::InstanceMonitorParams& monitoringConfig) - { - return aos::ErrorEnum::eNone; - } - - aos::Error StopInstanceMonitoring(const aos::String& instanceID) { return aos::ErrorEnum::eNone; } - - void SetNodeInfo(const aos::NodeInfo& nodeInfo) { mNodeInfo = nodeInfo; } - - void Clear() { mNodeInfo = aos::NodeInfo(); } - -private: - aos::NodeInfo mNodeInfo; -}; - -#endif diff --git a/tests/communication/src/stubs/provisioningstub.hpp b/tests/communication/src/stubs/provisioningstub.hpp deleted file mode 100644 index eba87bad..00000000 --- a/tests/communication/src/stubs/provisioningstub.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef PROVISIONINGSTUB_HPP_ -#define PROVISIONINGSTUB_HPP_ - -#include - -#include "provisioning/provisioning.hpp" - -class ProvisioningStub : public ProvisioningItf { -public: - aos::Error FinishProvisioning() override - { - std::lock_guard lock(mMutex); - - mProvisioned = true; - - return aos::ErrorEnum::eNone; - } - - bool IsProvisioned() const override - { - std::lock_guard lock(mMutex); - return mProvisioned; - } - - void SetProvisioned(bool provisioned) - { - std::lock_guard lock(mMutex); - mProvisioned = provisioned; - } - - void Clear() - { - std::lock_guard lock(mMutex); - mProvisioned = false; - } - -private: - mutable std::mutex mMutex; - bool mProvisioned = false; -}; - -#endif diff --git a/tests/communication/src/stubs/resourcemanagerstub.hpp b/tests/communication/src/stubs/resourcemanagerstub.hpp deleted file mode 100644 index 9f0634b2..00000000 --- a/tests/communication/src/stubs/resourcemanagerstub.hpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef RESOURCEMANAGERSTUB_HPP_ -#define RESOURCEMANAGERSTUB_HPP_ - -#include - -class ResourceManagerStub : public aos::sm::resourcemanager::ResourceManagerItf { -public: - aos::RetWithError> GetVersion() const override { return {mVersion, mError}; } - - aos::Error CheckUnitConfig(const aos::String& version, const aos::String& unitConfig) const override - { - return mError; - }; - - aos::Error UpdateUnitConfig(const aos::String& version, const aos::String& unitConfig) override - { - mVersion = version; - mUnitConfig = unitConfig.CStr(); - - return mError; - }; - - aos::Error GetDeviceInfo(const aos::String& deviceName, aos::DeviceInfo& deviceInfo) const override - { - (void)deviceName; - (void)deviceInfo; - - return mError; - } - - aos::Error GetResourceInfo(const aos::String& resourceName, aos::ResourceInfo& resourceInfo) const override - { - (void)resourceName; - (void)resourceInfo; - - return mError; - } - - aos::Error AllocateDevice(const aos::String& deviceName, const aos::String& instanceID) override - { - (void)deviceName; - (void)instanceID; - - return mError; - } - - aos::Error ReleaseDevice(const aos::String& deviceName, const aos::String& instanceID) override - { - (void)deviceName; - (void)instanceID; - - return mError; - } - - aos::Error ReleaseDevices(const aos::String& instanceID) override - { - (void)instanceID; - - return mError; - } - aos::Error GetDeviceInstances( - const aos::String& deviceName, aos::Array>& instanceIDs) const override - { - (void)deviceName; - (void)instanceIDs; - - return mError; - } - - void SetError(const aos::Error& err) { mError = err; } - - const std::string& GetUnitConfig() const { return mUnitConfig; } - - void Clear() - { - mVersion.Clear(); - mUnitConfig.clear(); - mError = aos::ErrorEnum::eNone; - } - -private: - aos::StaticString mVersion; - std::string mUnitConfig; - aos::Error mError; -}; - -#endif diff --git a/tests/communication/src/stubs/rsaprivatekey.hpp b/tests/communication/src/stubs/rsaprivatekey.hpp deleted file mode 100644 index 286dee48..00000000 --- a/tests/communication/src/stubs/rsaprivatekey.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2024 Renesas Electronics Corporation. - * Copyright (C) 2024 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef RSAPRIVATEKEY_HPP_ -#define RSAPRIVATEKEY_HPP_ - -#include - -#include -#include -#include - -#include - -class RSAPrivateKey : public aos::crypto::PrivateKeyItf { -public: - RSAPrivateKey(const aos::crypto::RSAPublicKey& publicKey, mbedtls_pk_context pkContext) - : mPublicKey(publicKey) - , mPkContext(pkContext) - { - } - - ~RSAPrivateKey() { mbedtls_pk_free(&mPkContext); } - - const aos::crypto::PublicKeyItf& GetPublic() const { return mPublicKey; } - - aos::Error Sign(const aos::Array& digest, const aos::crypto::SignOptions& options, - aos::Array& signature) const override - { - mbedtls_entropy_context entropy; - mbedtls_ctr_drbg_context ctrDrbg; - const char* pers = "rsa_sign"; - - mbedtls_ctr_drbg_init(&ctrDrbg); - mbedtls_entropy_init(&entropy); - - std::unique_ptr ctrDrbgPtr( - &ctrDrbg, mbedtls_ctr_drbg_free); - - std::unique_ptr entropyPtr( - &entropy, mbedtls_entropy_free); - - auto ret = mbedtls_ctr_drbg_seed( - ctrDrbgPtr.get(), mbedtls_entropy_func, entropyPtr.get(), (const unsigned char*)pers, strlen(pers)); - if (ret != 0) { - return ret; - } - - size_t signatureLen; - auto pkContext = mPkContext; - - ret = mbedtls_pk_sign(&pkContext, MBEDTLS_MD_SHA256, digest.Get(), digest.Size(), signature.Get(), - signature.Size(), &signatureLen, mbedtls_ctr_drbg_random, ctrDrbgPtr.get()); - if (ret != 0) { - return ret; - } - - signature.Resize(signatureLen); - - return aos::ErrorEnum::eNone; - } - - aos::Error Decrypt(const aos::Array&, aos::Array&) const - { - return aos::ErrorEnum::eNotSupported; - } - -public: - aos::crypto::RSAPublicKey mPublicKey; - mbedtls_pk_context mPkContext; -}; - -#endif /* RSAPRIVATEKEY_HPP_ */ diff --git a/tests/communication/src/testmbedtlsconfig.h b/tests/communication/src/testmbedtlsconfig.h deleted file mode 100644 index 0e3e9f48..00000000 --- a/tests/communication/src/testmbedtlsconfig.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2024 Renesas Electronics Corporation. - * Copyright (C) 2024 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef TESTMBEDTLSCONFIG_H_ -#define TESTMBEDTLSCONFIG_H_ - -#define MBEDTLS_PEM_WRITE_C -#define MBEDTLS_PK_HAVE_ECC_KEYS -#define MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS -#define MBEDTLS_TEST_SW_INET_PTON -#define MBEDTLS_X509_CREATE_C -#define MBEDTLS_X509_CRT_WRITE_C -#define MBEDTLS_X509_CSR_PARSE_C -#define MBEDTLS_X509_CSR_WRITE_C -#define PSA_CRYPTO_DRIVER_AOS -#define MBEDTLS_NET_C - -#endif diff --git a/tests/communication/src/tlschannel.cpp b/tests/communication/src/tlschannel.cpp deleted file mode 100644 index 31d03542..00000000 --- a/tests/communication/src/tlschannel.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 2024 Renesas Electronics Corporation. - * Copyright (C) 2024 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "communication/commchannel.hpp" -#include "communication/tlschannel.hpp" - -#include "stubs/certhandlerstub.hpp" -#include "stubs/certloaderstub.hpp" -#include "stubs/rsaprivatekey.hpp" - -/*********************************************************************************************************************** - * Types - **********************************************************************************************************************/ - -class ClientChannel : public CommChannelItf { -public: - ClientChannel() { mbedtls_net_init(&mServerFd); } - ~ClientChannel() { mbedtls_net_free(&mServerFd); } - - aos::Error SetTLSConfig(const aos::String& certType) override { return aos::ErrorEnum::eNone; } - - aos::Error Connect() override - { - return mbedtls_net_connect(&mServerFd, "localhost", "4433", MBEDTLS_NET_PROTO_TCP); - } - - aos::Error Close() override { return aos::ErrorEnum::eNone; } - - bool IsConnected() const override { return true; } - - int Read(void* data, size_t size) override - { - return mbedtls_net_recv(&mServerFd, static_cast(data), size); - } - - int Write(const void* data, size_t size) override - { - return mbedtls_net_send(&mServerFd, static_cast(data), size); - } - -private: - mbedtls_net_context mServerFd; -}; - -class Server { -public: - Server(std::promise listen) - : mListen(std::move(listen)) - { - } - - ~Server() - { - mbedtls_net_free(&mClientFd); - mbedtls_net_free(&mListenFd); - mbedtls_pk_free(&mPrivKeyCtx); - mbedtls_x509_crt_free(&mCertChain); - mbedtls_x509_crt_free(&mCACert); - mbedtls_ctr_drbg_free(&mCtrDrbg); - mbedtls_entropy_free(&mEntropy); - mbedtls_ssl_config_free(&mConf); - mbedtls_ssl_free(&mSsl); - } - - aos::Error Run() - { - auto err = Init(); - if (!err.IsNone()) { - return err; - } - - if ((err = ParseCACert()) != aos::ErrorEnum::eNone) { - return err; - } - - if ((err = ParseCertChain()) != aos::ErrorEnum::eNone) { - return err; - } - - if ((err = ParsePK()) != aos::ErrorEnum::eNone) { - return err; - } - - if ((err = SetupSSLConfig()) != aos::ErrorEnum::eNone) { - return err; - } - - if ((err = Bind()) != aos::ErrorEnum::eNone) { - return err; - } - - if ((err = Listen()) != aos::ErrorEnum::eNone) { - return err; - } - - return err; - } - -private: - static constexpr auto pers = "ssl_server"; - - aos::Error Init() - { - mbedtls_ssl_init(&mSsl); - mbedtls_ssl_config_init(&mConf); - mbedtls_entropy_init(&mEntropy); - mbedtls_ctr_drbg_init(&mCtrDrbg); - mbedtls_x509_crt_init(&mCACert); - mbedtls_x509_crt_init(&mCertChain); - mbedtls_pk_init(&mPrivKeyCtx); - mbedtls_net_init(&mListenFd); - mbedtls_net_init(&mClientFd); - - return mbedtls_ctr_drbg_seed( - &mCtrDrbg, mbedtls_entropy_func, &mEntropy, reinterpret_cast(pers), strlen(pers)); - } - - aos::Error ParseCACert() - { - aos::StaticString mCACertPem; - - auto err = aos::FS::ReadFileToString(CERT_DIR "/ca.pem", mCACertPem); - if (!err.IsNone()) { - return err; - } - - return mbedtls_x509_crt_parse( - &mCACert, reinterpret_cast(mCACertPem.Get()), mCACertPem.Size() + 1); - } - - aos::Error ParseCertChain() - { - aos::StaticString mCertChainPem; - - auto err = aos::FS::ReadFileToString(CERT_DIR "/server.cer", mCertChainPem); - if (!err.IsNone()) { - return err; - } - - return mbedtls_x509_crt_parse( - &mCertChain, reinterpret_cast(mCertChainPem.Get()), mCertChainPem.Size() + 1); - } - - aos::Error ParsePK() - { - aos::StaticString<4096> mPKPem; - - auto err = aos::FS::ReadFileToString(CERT_DIR "/server.key", mPKPem); - if (!err.IsNone()) { - return err; - } - - return mbedtls_pk_parse_key(&mPrivKeyCtx, reinterpret_cast(mPKPem.Get()), - mPKPem.Size() + 1, nullptr, 0, mbedtls_ctr_drbg_random, &mCtrDrbg); - } - - aos::Error SetupSSLConfig() - { - auto ret = mbedtls_ssl_config_defaults( - &mConf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); - if (ret != 0) { - return ret; - } - - mbedtls_ssl_conf_authmode(&mConf, MBEDTLS_SSL_VERIFY_REQUIRED); - mbedtls_ssl_conf_rng(&mConf, mbedtls_ctr_drbg_random, &mCtrDrbg); - mbedtls_ssl_conf_ca_chain(&mConf, &mCACert, nullptr); - mbedtls_ssl_conf_own_cert(&mConf, &mCertChain, &mPrivKeyCtx); - - return mbedtls_ssl_setup(&mSsl, &mConf); - } - - aos::Error Bind() { return mbedtls_net_bind(&mListenFd, nullptr, "4433", MBEDTLS_NET_PROTO_TCP); } - - aos::Error Listen() - { - mbedtls_net_free(&mClientFd); - - mbedtls_ssl_session_reset(&mSsl); - - mListen.set_value(); - - auto ret = mbedtls_net_accept(&mListenFd, &mClientFd, nullptr, 0, nullptr); - if (ret != 0) { - return ret; - } - - mbedtls_ssl_set_bio(&mSsl, &mClientFd, mbedtls_net_send, mbedtls_net_recv, nullptr); - - return mbedtls_ssl_handshake(&mSsl); - } - - mbedtls_ssl_context mSsl; - mbedtls_ssl_config mConf; - mbedtls_entropy_context mEntropy; - mbedtls_ctr_drbg_context mCtrDrbg; - mbedtls_x509_crt mCACert; - mbedtls_x509_crt mCertChain; - mbedtls_pk_context mPrivKeyCtx; - mbedtls_net_context mListenFd; - mbedtls_net_context mClientFd; - std::promise mListen; -}; - -/*********************************************************************************************************************** - * Setup - **********************************************************************************************************************/ - -ZTEST_SUITE(tlschannel, nullptr, nullptr, nullptr, nullptr, nullptr); - -/*********************************************************************************************************************** - * Tests - **********************************************************************************************************************/ - -ZTEST_F(tlschannel, test_TLSChannelConnect) -{ - psa_status_t status = psa_crypto_init(); - zassert_equal(status, PSA_SUCCESS, "psa_crypto_init failed"); - - CertLoaderStub certLoader; - CertHandlerStub certHandler; - ClientChannel vChannel; - - TLSChannel channel; - - auto err = channel.Init(certHandler, certLoader, vChannel); - zassert_equal(err, aos::ErrorEnum::eNone, "test failed"); - - err = channel.SetTLSConfig("client"); - zassert_equal(err, aos::ErrorEnum::eNone, "test failed"); - - std::promise listen; - auto waitListen = listen.get_future(); - Server server(std::move(listen)); - - auto resServer = std::async(std::launch::async, &Server::Run, &server); - if (waitListen.wait_for(std::chrono::seconds(2)) == std::future_status::timeout) { - zassert_unreachable("test failed"); - } - - auto resClient = std::async(std::launch::async, &TLSChannel::Connect, &channel); - - auto errClient = resClient.get(); - auto errServer = resServer.get(); - - zassert_equal(errClient, aos::ErrorEnum::eNone, "test failed"); - zassert_equal(errServer, aos::ErrorEnum::eNone, "test failed"); -} diff --git a/tests/communication/src/utils.cpp b/tests/communication/src/utils.cpp deleted file mode 100644 index 46f5fc28..00000000 --- a/tests/communication/src/utils.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2024 Renesas Electronics Corporation. - * Copyright (C) 2024 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include -#include - -#include "communication/messagehandler.hpp" -#include "utils/checksum.hpp" - -#include "utils.hpp" - -/*********************************************************************************************************************** - * Public - **********************************************************************************************************************/ - -void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message) -{ - static std::mutex mutex; - static auto startTime = std::chrono::steady_clock::now(); - - std::lock_guard lock(mutex); - - auto now = std::chrono::duration(std::chrono::steady_clock::now() - startTime).count(); - - const char* levelStr = "unknown"; - - switch (level.GetValue()) { - case aos::LogLevelEnum::eDebug: - levelStr = "dbg"; - break; - - case aos::LogLevelEnum::eInfo: - levelStr = "inf"; - break; - - case aos::LogLevelEnum::eWarning: - levelStr = "wrn"; - break; - - case aos::LogLevelEnum::eError: - levelStr = "err"; - break; - - default: - levelStr = "n/d"; - break; - } - - printk("%0.3f [%s] %s\n", now, levelStr, message.CStr()); -} - -aos::Error SendMessageToChannel(CommChannelStub& channel, uint32_t source, const std::string& methodName, - uint64_t requestID, const std::vector& data, aos::Error messageError) -{ - auto checksum = CalculateSha256(aos::Array(data.data(), data.size())); - if (!checksum.mError.IsNone()) { - return AOS_ERROR_WRAP(checksum.mError); - } - - auto header = VChanMessageHeader {source, static_cast(data.size()), requestID, messageError.Errno(), - static_cast(messageError.Value())}; - - strncpy(header.mMethodName, methodName.c_str(), cMaxMethodLen); - - aos::Array(header.mSha256, aos::cSHA256Size) = checksum.mValue; - - auto headerPtr = reinterpret_cast(&header); - - channel.SendRead(std::vector(headerPtr, headerPtr + sizeof(VChanMessageHeader))); - channel.SendRead(data); - - return aos::ErrorEnum::eNone; -} - -aos::Error ReceiveMessageFromChannel(CommChannelStub& channel, uint32_t source, const std::string& methodName, - uint64_t requestID, std::vector& data) -{ - std::vector headerData; - - auto err = channel.WaitWrite(headerData, sizeof(VChanMessageHeader), cWaitTimeout); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - auto header = reinterpret_cast(headerData.data()); - - if (header->mSource != source) { - return AOS_ERROR_WRAP(aos::ErrorEnum::eInvalidArgument); - } - - if (header->mMethodName != methodName) { - return AOS_ERROR_WRAP(aos::ErrorEnum::eInvalidArgument); - } - - if (header->mRequestID != requestID) { - return AOS_ERROR_WRAP(aos::ErrorEnum::eInvalidArgument); - } - - err = channel.WaitWrite(data, header->mDataSize, cWaitTimeout); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - if (header->mDataSize) { - auto checksum = CalculateSha256(aos::Array(data.data(), data.size())); - if (!checksum.mError.IsNone()) { - return AOS_ERROR_WRAP(checksum.mError); - } - - if (checksum.mValue != aos::Array(header->mSha256, aos::cSHA256Size)) { - return AOS_ERROR_WRAP(aos::ErrorEnum::eInvalidChecksum); - } - } - - if (header->mAosError) { - return AOS_ERROR_WRAP(static_cast(header->mAosError)); - } - - if (header->mErrno) { - return AOS_ERROR_WRAP(header->mAosError); - } - - return aos::ErrorEnum::eNone; -} - -aos::Error SendPBMessage(CommChannelStub& channel, uint32_t source, const std::string& methodName, uint64_t requestID, - const pb_msgdesc_t* fields, const void* message, size_t messageSize) -{ - std::vector data(messageSize); - - if (messageSize) { - auto stream = pb_ostream_from_buffer(data.data(), data.size()); - - auto status = pb_encode(&stream, fields, message); - if (!status) { - return aos::ErrorEnum::eFailed; - } - - data.resize(stream.bytes_written); - } - - return SendMessageToChannel(channel, source, methodName, requestID, data); -} - -aos::Error ReceivePBMessage(CommChannelStub& channel, uint32_t source, const std::string& methodName, - uint64_t requestID, const pb_msgdesc_t* fields, void* message, size_t messageSize) -{ - std::vector data(messageSize); - - auto err = ReceiveMessageFromChannel(channel, source, methodName, requestID, data); - if (!err.IsNone()) { - return err; - } - - if (message && fields) { - auto stream = pb_istream_from_buffer(data.data(), data.size()); - - auto status = pb_decode(&stream, fields, message); - if (!status) { - return AOS_ERROR_WRAP(aos::ErrorEnum::eRuntime); - } - } - - return aos::ErrorEnum::eNone; -} diff --git a/tests/communication/src/utils.hpp b/tests/communication/src/utils.hpp deleted file mode 100644 index 2e46987b..00000000 --- a/tests/communication/src/utils.hpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2024 Renesas Electronics Corporation. - * Copyright (C) 2024 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include "stubs/commchannelstub.hpp" - -/*********************************************************************************************************************** - * Consts - **********************************************************************************************************************/ - -constexpr auto cWaitTimeout = std::chrono::seconds {5}; - -/*********************************************************************************************************************** - * Public - **********************************************************************************************************************/ - -void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message); - -aos::Error SendMessageToChannel(CommChannelStub& channel, uint32_t source, const std::string& methodName, - uint64_t requestID, const std::vector& data, aos::Error messageError = aos::ErrorEnum::eNone); - -aos::Error ReceiveMessageFromChannel(CommChannelStub& channel, uint32_t source, const std::string& methodName, - uint64_t requestID, std::vector& data); - -aos::Error SendPBMessage(CommChannelStub& channel, uint32_t source, const std::string& methodName, uint64_t requestID, - const pb_msgdesc_t* fields = nullptr, const void* message = nullptr, size_t messageSize = 0); - -aos::Error ReceivePBMessage(CommChannelStub& channel, uint32_t source, const std::string& methodName, - uint64_t requestID, const pb_msgdesc_t* fields = nullptr, void* message = nullptr, size_t messageSize = 0); diff --git a/tests/communication/testcase.yaml b/tests/communication/testcase.yaml deleted file mode 100644 index 4ba6918d..00000000 --- a/tests/communication/testcase.yaml +++ /dev/null @@ -1,6 +0,0 @@ -tests: - aoszephyrapp.communication: - build_only: false - tags: communication - timeout: 500 - platform_allow: native_posix_64 native_posix From a2489953c5592e68a2ae52ef7f6c71f5eb994cef Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 2 Aug 2024 17:19:14 +0300 Subject: [PATCH 013/198] [smclient] Add SM client interface Signed-off-by: Oleksandr Grytsov --- CMakeLists.txt | 1 + src/smclient/log.hpp | 15 +++++ src/smclient/smclient.cpp | 65 +++++++++++++++++++++ src/smclient/smclient.hpp | 117 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 198 insertions(+) create mode 100644 src/smclient/log.hpp create mode 100644 src/smclient/smclient.cpp create mode 100644 src/smclient/smclient.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a0f04cd7..e526b98d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,7 @@ target_sources( src/provisioning/provisioning.cpp src/resourcemanager/resourcemanager.cpp src/runner/runner.cpp + src/smclient/smclient.cpp src/storage/storage.cpp src/utils/checksum.cpp ) diff --git a/src/smclient/log.hpp b/src/smclient/log.hpp new file mode 100644 index 00000000..169130ca --- /dev/null +++ b/src/smclient/log.hpp @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef LOG_HPP_ +#define LOG_HPP_ + +#define LOG_MODULE "smclient" + +#include + +#endif diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp new file mode 100644 index 00000000..ec07ca58 --- /dev/null +++ b/src/smclient/smclient.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "smclient.hpp" + +namespace aos::zephyr::smclient { + +/*********************************************************************************************************************** + * Public + **********************************************************************************************************************/ + +aos::Error SMClient::Init(aos::sm::launcher::LauncherItf& launcher, + aos::sm::resourcemanager::ResourceManagerItf& resourceManager, aos::monitoring::ResourceMonitorItf& resourceMonitor, + DownloadReceiverItf& downloader, communication::ChannelManagerItf& channelManager) +{ + return aos::ErrorEnum::eNone; +} + +aos::Error SMClient::InstancesRunStatus(const aos::Array& instances) +{ + return aos::ErrorEnum::eNone; +} + +aos::Error SMClient::InstancesUpdateStatus(const aos::Array& instances) +{ + return aos::ErrorEnum::eNone; +} + +aos::Error SMClient::SendImageContentRequest(const ImageContentRequest& request) +{ + return aos::ErrorEnum::eNone; +} + +aos::Error SMClient::SendMonitoringData(const aos::monitoring::NodeMonitoringData& monitoringData) +{ + return aos::ErrorEnum::eNone; +} + +aos::Error SMClient::Subscribes(aos::ConnectionSubscriberItf& subscriber) +{ + return aos::ErrorEnum::eNone; +} + +void SMClient::Unsubscribes(aos::ConnectionSubscriberItf& subscriber) +{ +} + +aos::Error SMClient::SendClockSyncRequest() +{ + return aos::ErrorEnum::eNone; +} + +void SMClient::ClockSynced() +{ +} + +void SMClient::ClockUnsynced() +{ +} + +} // namespace aos::zephyr::smclient diff --git a/src/smclient/smclient.hpp b/src/smclient/smclient.hpp new file mode 100644 index 00000000..f439334b --- /dev/null +++ b/src/smclient/smclient.hpp @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SMCLIENT_HPP_ +#define SMCLIENT_HPP_ + +#include +#include +#include +#include + +#include "clocksync/clocksync.hpp" +#include "communication/channelmanager.hpp" +#include "downloader/downloader.hpp" + +namespace aos::zephyr::smclient { + +/** + * SM client instance. + */ +class SMClient : public aos::sm::launcher::InstanceStatusReceiverItf, + public DownloadRequesterItf, + public aos::monitoring::SenderItf, + public aos::ConnectionPublisherItf, + public ClockSyncSenderItf, + private aos::NonCopyable { +public: + /** + * Initializes SM client instance. + * + * @param launcher launcher instance. + * @param resourceManager resource manager instance. + * @param resourceMonitor resource monitor instance. + * @param downloader downloader instance. + * @return aos::Error. + */ + aos::Error Init(aos::sm::launcher::LauncherItf& launcher, + aos::sm::resourcemanager::ResourceManagerItf& resourceManager, + aos::monitoring::ResourceMonitorItf& resourceMonitor, DownloadReceiverItf& downloader, + communication::ChannelManagerItf& channelManager); + + /** + * Destructor. + */ + ~SMClient(); + + /** + * Sends instances run status. + * + * @param instances instances status array. + * @return Error. + */ + aos::Error InstancesRunStatus(const aos::Array& instances) override; + + /** + * Sends instances update status. + * @param instances instances status array. + * + * @return Error. + */ + aos::Error InstancesUpdateStatus(const aos::Array& instances) override; + + /** + * Send image content request + * + * @param request image content request + * @return Error + */ + aos::Error SendImageContentRequest(const ImageContentRequest& request) override; + + /** + * Sends monitoring data + * + * @param monitoringData monitoring data + * @return Error + */ + aos::Error SendMonitoringData(const aos::monitoring::NodeMonitoringData& monitoringData) override; + + /** + * Subscribes the provided ConnectionSubscriberItf to this object. + * + * @param subscriber The ConnectionSubscriberItf that wants to subscribe. + */ + aos::Error Subscribes(aos::ConnectionSubscriberItf& subscriber) override; + + /** + * Unsubscribes the provided ConnectionSubscriberItf from this object. + * + * @param subscriber The ConnectionSubscriberItf that wants to unsubscribe. + */ + void Unsubscribes(aos::ConnectionSubscriberItf& subscriber) override; + + /** + * Sends clock sync request. + * + * @return aos::Error. + */ + aos::Error SendClockSyncRequest() override; + + /** + * Notifies sender that clock is synced. + */ + void ClockSynced() override; + + /** + * Notifies sender that clock is unsynced. + */ + void ClockUnsynced() override; +}; + +} // namespace aos::zephyr::smclient + +#endif From 21df00762c92eb6e63cc985f1b2e329f2937ad32 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 2 Aug 2024 17:22:29 +0300 Subject: [PATCH 014/198] [app] Update app to new communication interface Signed-off-by: Oleksandr Grytsov --- src/app/app.cpp | 41 ++++++++++++++++------------------------- src/app/app.hpp | 19 ++++++++++++------- src/main.cpp | 4 ++-- 3 files changed, 30 insertions(+), 34 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index ead0f8d4..9252c597 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -8,6 +8,8 @@ #include "app.hpp" #include "log.hpp" +namespace aos::zephyr::app { + /*********************************************************************************************************************** * Variables **********************************************************************************************************************/ @@ -32,10 +34,6 @@ aos::Error App::Init() return err; } - if (!(err = mDownloader.Init(mCommunication)).IsNone()) { - return err; - } - if (!(err = mServiceManager.Init(mJsonOciSpec, mDownloader, mStorage)).IsNone()) { return err; } @@ -44,17 +42,17 @@ aos::Error App::Init() return err; } - if (!(err = mResourceMonitor.Init(mResourceUsageProvider, mCommunication, mCommunication)).IsNone()) { + if (!(err = mResourceMonitor.Init(mResourceUsageProvider, mSMClient, mSMClient)).IsNone()) { return err; } - if (!(err = mLauncher.Init( - mServiceManager, mRunner, mJsonOciSpec, mCommunication, mStorage, mResourceMonitor, mCommunication)) + if (!(err + = mLauncher.Init(mServiceManager, mRunner, mJsonOciSpec, mSMClient, mStorage, mResourceMonitor, mSMClient)) .IsNone()) { return err; } - if (!(err = mClockSync.Init(mCommunication)).IsNone()) { + if (!(err = mClockSync.Init(mSMClient)).IsNone()) { return err; } @@ -70,6 +68,12 @@ aos::Error App::Init() return err; } + if (!(err = mResourceManager.Init( + mResourceManagerJSONProvider, mHostDeviceManager, mHostGroupManager, cNodeType, cUnitConfigFile)) + .IsNone()) { + return err; + } + if (!(err = InitCertHandler()).IsNone()) { return err; } @@ -137,29 +141,16 @@ aos::Error App::InitCommunication() { aos::Error err; - if (!(err = mOpenVChannel.Init("open", VChannel::cXSOpenReadPath, VChannel::cXSOpenWritePath)).IsNone()) { - return err; - } - - if (!(err = mSecureVChannel.Init("secure", VChannel::cXSCloseReadPath, VChannel::cXSCloseWritePath)).IsNone()) { - return err; - } - - if (!(err = mSecureTLSChannel.Init(mCertHandler, mCertLoader, mSecureVChannel)).IsNone()) { - return err; - } - - if (!(err = mResourceManager.Init( - mResourceManagerJSONProvider, mHostDeviceManager, mHostGroupManager, cNodeType, cUnitConfigFile)) + if (!(err = mTransport.Init(communication::XenVChan::cXSReadPath, communication::XenVChan::cXSWritePath)) .IsNone()) { return err; } - if (!(err = mCommunication.Init(mOpenVChannel, mSecureTLSChannel, mLauncher, mCertHandler, mResourceManager, - mResourceMonitor, mDownloader, mClockSync, mProvisioning)) - .IsNone()) { + if (!(err = mChannelManager.Init(mTransport)).IsNone()) { return err; } return aos::ErrorEnum::eNone; } + +} // namespace aos::zephyr::app diff --git a/src/app/app.hpp b/src/app/app.hpp index cdb7dd0b..7b17780a 100644 --- a/src/app/app.hpp +++ b/src/app/app.hpp @@ -13,21 +13,25 @@ #include #include #include +#include #include #include #include #include "clocksync/clocksync.hpp" -#include "communication/communication.hpp" -#include "communication/tlschannel.hpp" -#include "communication/vchannel.hpp" +#include "communication/channelmanager.hpp" +#include "communication/xenvchan.hpp" +#include "downloader/downloader.hpp" #include "monitoring/resourceusageprovider.hpp" #include "ocispec/ocispec.hpp" #include "provisioning/provisioning.hpp" #include "resourcemanager/resourcemanager.hpp" #include "runner/runner.hpp" +#include "smclient/smclient.hpp" #include "storage/storage.hpp" +namespace aos::zephyr::app { + /** * Aos zephyr application. */ @@ -69,10 +73,6 @@ class App : private aos::NonCopyable { aos::cryptoutils::CertLoader mCertLoader; aos::pkcs11::PKCS11Manager mPKCS11Manager; ClockSync mClockSync; - Communication mCommunication; - VChannel mOpenVChannel; - VChannel mSecureVChannel; - TLSChannel mSecureTLSChannel; Downloader mDownloader; OCISpec mJsonOciSpec; ResourceManagerJSONProvider mResourceManagerJSONProvider; @@ -83,6 +83,11 @@ class App : private aos::NonCopyable { Runner mRunner; Storage mStorage; Provisioning mProvisioning; + smclient::SMClient mSMClient; + communication::ChannelManager mChannelManager; + communication::XenVChan mTransport; }; +} // namespace aos::zephyr::app + #endif diff --git a/src/main.cpp b/src/main.cpp index 03d9795b..e340ec8a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,7 +29,7 @@ int main(void) { printk("*** Aos zephyr application: %s ***\n", AOS_ZEPHYR_APP_VERSION); printk("*** Aos core library: %s ***\n", AOS_CORE_VERSION); - printk("*** Aos core size: %lu ***\n", sizeof(App)); + printk("*** Aos core size: %lu ***\n", sizeof(aos::zephyr::app::App)); #if !defined(CONFIG_NATIVE_APPLICATION) auto ret = littlefs_mount(); @@ -46,7 +46,7 @@ int main(void) Logger::Init(); - auto& app = App::Get(); + auto& app = aos::zephyr::app::App::Get(); auto err = app.Init(); __ASSERT(err.IsNone(), "Error initializing application: %s [%d] (%s:%d)", err.Message(), err.Errno(), From dbdf8eea2972ea5dfb301bc71480f8d1aa264389 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 5 Aug 2024 11:45:03 +0300 Subject: [PATCH 015/198] [tests,communication] Adopt and add tlschannel unit test Signed-off-by: Oleksandr Grytsov --- tests/communication/CMakeLists.txt | 107 +++++++ tests/communication/prj.conf | 46 +++ .../src/stubs/certhandlerstub.hpp | 170 +++++++++++ .../src/stubs/certloaderstub.hpp | 125 ++++++++ .../communication/src/stubs/rsaprivatekey.hpp | 77 +++++ tests/communication/src/testmbedtlsconfig.h | 22 ++ tests/communication/src/tlschannel.cpp | 268 ++++++++++++++++++ tests/communication/testcase.yaml | 6 + 8 files changed, 821 insertions(+) create mode 100644 tests/communication/CMakeLists.txt create mode 100644 tests/communication/prj.conf create mode 100644 tests/communication/src/stubs/certhandlerstub.hpp create mode 100644 tests/communication/src/stubs/certloaderstub.hpp create mode 100644 tests/communication/src/stubs/rsaprivatekey.hpp create mode 100644 tests/communication/src/testmbedtlsconfig.h create mode 100644 tests/communication/src/tlschannel.cpp create mode 100644 tests/communication/testcase.yaml diff --git a/tests/communication/CMakeLists.txt b/tests/communication/CMakeLists.txt new file mode 100644 index 00000000..ecb22250 --- /dev/null +++ b/tests/communication/CMakeLists.txt @@ -0,0 +1,107 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package( + Zephyr + COMPONENTS + REQUIRED HINTS $ENV{ZEPHYR_BASE} +) + +set(CMAKE_MODULE_PATH ${APPLICATION_SOURCE_DIR}/../../cmake) + +project(communication_test) + +# ###################################################################################################################### +# Config +# ###################################################################################################################### + +set(aoscore_config aoscoreconfig.hpp) +set(aoscore_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../../../aos_core_lib_cpp") +set(cert_dir ${CMAKE_CURRENT_BINARY_DIR}/certificates) + +# ###################################################################################################################### +# Definitions +# ###################################################################################################################### + +# Aos core configuration +add_definitions(-include ${aoscore_config}) +# Certificate dir +add_definitions(-DCERT_DIR="${cert_dir}") +# Root CA cart path +add_definitions(-DCONFIG_AOS_ROOT_CA_PATH="${cert_dir}/ca.pem") + +# ###################################################################################################################### +# Includes +# ###################################################################################################################### + +zephyr_include_directories(${aoscore_source_dir}/include) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/../../src) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src) +zephyr_include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +# ###################################################################################################################### +# Certificates +# ###################################################################################################################### + +file(MAKE_DIRECTORY ${cert_dir}) + +foreach(cert_type IN ITEMS "ca" "server" "client") + execute_process(COMMAND openssl genrsa -out ${cert_dir}/${cert_type}.key 2048) + + execute_process( + COMMAND openssl req -new -key ${cert_dir}/${cert_type}.key -out ${cert_dir}/${cert_type}.csr -subj + "/C=XX/ST=State/L=City/O=Organization/OU=Unit/CN=${TYPE}" COMMAND_ERROR_IS_FATAL ANY + ) +endforeach() + +execute_process( + COMMAND openssl x509 -req -days 365 -in ${cert_dir}/ca.csr -signkey ${cert_dir}/ca.key -out ${cert_dir}/ca.pem + COMMAND_ERROR_IS_FATAL ANY +) + +foreach(cert_type IN ITEMS "server" "client") + execute_process( + COMMAND openssl x509 -req -days 365 -in ${cert_dir}/${cert_type}.csr -CA ${cert_dir}/ca.pem -CAkey + ${cert_dir}/ca.key -CAcreateserial -out ${cert_dir}/${cert_type}.cer COMMAND_ERROR_IS_FATAL ANY + ) +endforeach() + +# ###################################################################################################################### +# mbedTLS +# ###################################################################################################################### + +# Enable AESNI for posix 32bit +if(${CONFIG_BOARD_NATIVE_POSIX}) + target_compile_options(mbedTLS INTERFACE -mpclmul -msse2 -maes) +endif() + +# WA to have get time on zephyr +target_compile_definitions_ifndef(CONFIG_NATIVE_APPLICATION mbedTLS INTERFACE _POSIX_VERSION=200809L) + +# Add Aos psa driver + +set(mbedtls_source_dir "${APPLICATION_SOURCE_DIR}/../../../modules/crypto/mbedtls") +set(aoscore_source_dir "${APPLICATION_SOURCE_DIR}/../../../aos_core_lib_cpp") + +set_source_files_properties( + ${mbedtls_source_dir}/library/psa_crypto_driver_wrappers_no_static.c ${mbedtls_source_dir}/library/psa_crypto.c + TARGET_DIRECTORY mbedTLS PROPERTIES HEADER_FILE_ONLY ON +) + +target_include_directories(mbedTLSCrypto PRIVATE ${mbedtls_source_dir}/library) + +target_sources( + mbedTLSCrypto + PRIVATE ${aoscore_source_dir}/src/common/crypto/mbedtls/drivers/psa_crypto_driver_wrappers_no_static.c + ${aoscore_source_dir}/src/common/crypto/mbedtls/drivers/psa_crypto.c + ${aoscore_source_dir}/src/common/crypto/mbedtls/driverwrapper.cpp ${mbedtls_source_dir}/library/pk_ecc.c +) + +target_sources(mbedTLSX509 PRIVATE ${mbedtls_source_dir}/library/x509write.c) + +# ###################################################################################################################### +# Target +# ###################################################################################################################### + +target_sources(app PRIVATE ../../src/communication/tlschannel.cpp ../../src/rootca/rootca.S src/tlschannel.cpp) diff --git a/tests/communication/prj.conf b/tests/communication/prj.conf new file mode 100644 index 00000000..e77aa792 --- /dev/null +++ b/tests/communication/prj.conf @@ -0,0 +1,46 @@ +# Enable C++ + +CONFIG_CPP=y +CONFIG_STD_CPP14=y +CONFIG_EXTERNAL_LIBCPP=y +CONFIG_CBPRINTF_FP_SUPPORT=y + +# Enable test suit + +CONFIG_ZTEST=y + +# Enable debug for tests + +CONFIG_DEBUG=y +CONFIG_NO_OPTIMIZATIONS=y + +# Enable nanopb lib + +CONFIG_NANOPB=y + +# Enable mbedtls + +CONFIG_MBEDTLS=y +CONFIG_MBEDTLS_BUILTIN=y +CONFIG_MBEDTLS_ZEPHYR_ENTROPY=y +CONFIG_MBEDTLS_USER_CONFIG_ENABLE=y +CONFIG_MBEDTLS_USER_CONFIG_FILE="testmbedtlsconfig.h" + +CONFIG_MBEDTLS_CIPHER_CCM_ENABLED=y +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=y +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED=y +CONFIG_MBEDTLS_PEM_CERTIFICATE_FORMAT=y +CONFIG_MBEDTLS_PK_WRITE_C=y +CONFIG_MBEDTLS_PSA_CRYPTO_C=y +CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 +CONFIG_MBEDTLS_TLS_VERSION_1_2=y + +# Enable entropy generator + +CONFIG_ENTROPY_GENERATOR=y +CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/communication/src/stubs/certhandlerstub.hpp b/tests/communication/src/stubs/certhandlerstub.hpp new file mode 100644 index 00000000..7c40c4a4 --- /dev/null +++ b/tests/communication/src/stubs/certhandlerstub.hpp @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef CERTHANDLERSTUB_HPP_ +#define CERTHANDLERSTUB_HPP_ + +#include +#include + +#include + +class CertHandlerStub : public aos::iam::certhandler::CertHandlerItf { +public: + aos::Error GetCertTypes(aos::Array>& certTypes) override + { + std::lock_guard lock(mMutex); + + for (const auto& type : mCertTypes) { + certTypes.PushBack(type.c_str()); + } + + return aos::ErrorEnum::eNone; + } + + aos::Error SetOwner(const aos::String& certType, const aos::String& password) override + { + std::lock_guard lock(mMutex); + + mCertType = certType.CStr(); + mPassword = password.CStr(); + + return aos::ErrorEnum::eNone; + } + + aos::Error Clear(const aos::String& certType) override + { + std::lock_guard lock(mMutex); + + mClear = true; + + return aos::ErrorEnum::eNone; + } + + aos::Error CreateKey(const aos::String& certType, const aos::String& subjectCommonName, const aos::String& password, + aos::String& pemCSR) override + { + std::lock_guard lock(mMutex); + + mCertType = certType.CStr(); + mSubject = subjectCommonName.CStr(); + mPassword = password.CStr(); + + pemCSR = mCSR.c_str(); + + return aos::ErrorEnum::eNone; + } + + aos::Error ApplyCertificate( + const aos::String& certType, const aos::String& pemCert, aos::iam::certhandler::CertInfo& info) override + { + std::lock_guard lock(mMutex); + + mCertificate.assign(reinterpret_cast(pemCert.Get()), pemCert.Size()); + info = mCertInfo; + + return aos::ErrorEnum::eNone; + } + + aos::Error GetCertificate(const aos::String& certType, const aos::Array& issuer, + const aos::Array& serial, aos::iam::certhandler::CertInfo& resCert) override + { + resCert.mCertURL = CERT_DIR "/client.cer"; + resCert.mKeyURL = CERT_DIR "/client.key"; + + return aos::ErrorEnum::eNone; + } + + aos::Error CreateSelfSignedCert(const aos::String& certType, const aos::String& password) override + { + return aos::ErrorEnum::eNone; + } + + aos::RetWithError GetModuleConfig(const aos::String& certType) const override + { + return {aos::iam::certhandler::ModuleConfig {}, aos::ErrorEnum::eNone}; + } + + void Clear() + { + std::lock_guard lock(mMutex); + + mCertTypes.clear(); + mCertType.clear(); + mPassword.clear(); + mClear = false; + mSubject.clear(); + mCSR.clear(); + mCertificate.clear(); + mCertInfo = {}; + } + + void SetCertTypes(const std::vector& certTypes) + { + std::lock_guard lock(mMutex); + + mCertTypes = certTypes; + } + + void SetCSR(const std::string& csr) + { + std::lock_guard lock(mMutex); + + mCSR = csr; + } + + std::string GetCertType() const + { + std::lock_guard lock(mMutex); + + return mCertType; + } + + std::string GetPassword() const + { + std::lock_guard lock(mMutex); + + return mPassword; + } + + bool GetClear() const + { + std::lock_guard lock(mMutex); + + return mClear; + } + + std::string GetSubject() const + { + std::lock_guard lock(mMutex); + + return mSubject; + } + + std::string GetCertificate() const + { + std::lock_guard lock(mMutex); + + return mCertificate; + } + + void SetCertInfo(const aos::iam::certhandler::CertInfo& info) { mCertInfo = info; } + +private: + mutable std::mutex mMutex; + + std::vector mCertTypes; + std::string mCertType; + std::string mPassword; + bool mClear = false; + std::string mSubject; + std::string mCSR; + std::string mCertificate; + aos::iam::certhandler::CertInfo mCertInfo; +}; + +#endif diff --git a/tests/communication/src/stubs/certloaderstub.hpp b/tests/communication/src/stubs/certloaderstub.hpp new file mode 100644 index 00000000..f8b23630 --- /dev/null +++ b/tests/communication/src/stubs/certloaderstub.hpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef CERTLOADERSTUB_HPP_ +#define CERTLOADERSTUB_HPP_ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "rsaprivatekey.hpp" + +class CertLoaderStub : public aos::cryptoutils::CertLoaderItf { +public: + aos::Error Init(aos::crypto::x509::ProviderItf& cryptoProvider, aos::pkcs11::PKCS11Manager& pkcs11Manager) override + { + return aos::ErrorEnum::eNone; + } + + aos::RetWithError> LoadCertsChainByURL( + const aos::String& url) override + { + + auto certChain = aos::MakeShared(&mCertAllocator); + + aos::StaticString mCertChainPem; + + auto err = aos::FS::ReadFileToString(url, mCertChainPem); + if (!err.IsNone()) { + return {nullptr, err}; + } + + aos::crypto::x509::Certificate cert; + cert.mRaw + = aos::Array(reinterpret_cast(mCertChainPem.Get()), mCertChainPem.Size() + 1); + + certChain->PushBack(cert); + + return {certChain, aos::ErrorEnum::eNone}; + } + + aos::RetWithError> LoadPrivKeyByURL(const aos::String& url) override + { + aos::StaticString mPKPem; + mbedtls_pk_context pkContext; + mbedtls_ctr_drbg_context ctrDrbg; + + mbedtls_pk_init(&pkContext); + mbedtls_ctr_drbg_init(&ctrDrbg); + + std::unique_ptr ctrDrbgPtr( + &ctrDrbg, mbedtls_ctr_drbg_free); + + auto err = aos::FS::ReadFileToString(url, mPKPem); + if (!err.IsNone()) { + return {nullptr, err}; + } + + auto ret = mbedtls_pk_parse_key(&pkContext, reinterpret_cast(mPKPem.Get()), + mPKPem.Size() + 1, nullptr, 0, mbedtls_ctr_drbg_random, &ctrDrbg); + if (ret != 0) { + return {nullptr, ret}; + } + + if (mbedtls_pk_get_type(&pkContext) != MBEDTLS_PK_RSA) { + return {nullptr, aos::ErrorEnum::eNotSupported}; + } + + mbedtls_rsa_context* rsa_context = mbedtls_pk_rsa(pkContext); + + mbedtls_mpi mpiN, mpiE; + + mbedtls_mpi_init(&mpiN); + mbedtls_mpi_init(&mpiE); + + std::unique_ptr mpiNPtr(&mpiN, mbedtls_mpi_free); + std::unique_ptr mpiEPtr(&mpiE, mbedtls_mpi_free); + + if ((ret = mbedtls_rsa_export(rsa_context, mpiNPtr.get(), nullptr, nullptr, nullptr, mpiEPtr.get())) != 0) { + return {nullptr, ret}; + } + + aos::StaticArray mN; + aos::StaticArray mE; + + if ((ret = ConvertMbedtlsMpiToArray(mpiNPtr.get(), mN)) != 0) { + return {nullptr, ret}; + } + + if ((ret = ConvertMbedtlsMpiToArray(mpiEPtr.get(), mE)) != 0) { + return {nullptr, ret}; + } + + aos::crypto::RSAPublicKey rsaPublicKey(mN, mE); + + return {aos::MakeShared(&mKeyAllocator, rsaPublicKey, pkContext), aos::ErrorEnum::eNone}; + } + +private: + static constexpr auto cCertAllocatorSize = 2 * sizeof(aos::crypto::x509::CertificateChain); + static constexpr auto cKeyAllocatorSize = 2 * sizeof(RSAPrivateKey); + + int ConvertMbedtlsMpiToArray(const mbedtls_mpi* mpi, aos::Array& outArray) + { + outArray.Resize(mbedtls_mpi_size(mpi)); + + return mbedtls_mpi_write_binary(mpi, outArray.Get(), outArray.Size()); + } + + aos::StaticAllocator mCertAllocator; + aos::StaticAllocator mKeyAllocator; +}; + +#endif diff --git a/tests/communication/src/stubs/rsaprivatekey.hpp b/tests/communication/src/stubs/rsaprivatekey.hpp new file mode 100644 index 00000000..286dee48 --- /dev/null +++ b/tests/communication/src/stubs/rsaprivatekey.hpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef RSAPRIVATEKEY_HPP_ +#define RSAPRIVATEKEY_HPP_ + +#include + +#include +#include +#include + +#include + +class RSAPrivateKey : public aos::crypto::PrivateKeyItf { +public: + RSAPrivateKey(const aos::crypto::RSAPublicKey& publicKey, mbedtls_pk_context pkContext) + : mPublicKey(publicKey) + , mPkContext(pkContext) + { + } + + ~RSAPrivateKey() { mbedtls_pk_free(&mPkContext); } + + const aos::crypto::PublicKeyItf& GetPublic() const { return mPublicKey; } + + aos::Error Sign(const aos::Array& digest, const aos::crypto::SignOptions& options, + aos::Array& signature) const override + { + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctrDrbg; + const char* pers = "rsa_sign"; + + mbedtls_ctr_drbg_init(&ctrDrbg); + mbedtls_entropy_init(&entropy); + + std::unique_ptr ctrDrbgPtr( + &ctrDrbg, mbedtls_ctr_drbg_free); + + std::unique_ptr entropyPtr( + &entropy, mbedtls_entropy_free); + + auto ret = mbedtls_ctr_drbg_seed( + ctrDrbgPtr.get(), mbedtls_entropy_func, entropyPtr.get(), (const unsigned char*)pers, strlen(pers)); + if (ret != 0) { + return ret; + } + + size_t signatureLen; + auto pkContext = mPkContext; + + ret = mbedtls_pk_sign(&pkContext, MBEDTLS_MD_SHA256, digest.Get(), digest.Size(), signature.Get(), + signature.Size(), &signatureLen, mbedtls_ctr_drbg_random, ctrDrbgPtr.get()); + if (ret != 0) { + return ret; + } + + signature.Resize(signatureLen); + + return aos::ErrorEnum::eNone; + } + + aos::Error Decrypt(const aos::Array&, aos::Array&) const + { + return aos::ErrorEnum::eNotSupported; + } + +public: + aos::crypto::RSAPublicKey mPublicKey; + mbedtls_pk_context mPkContext; +}; + +#endif /* RSAPRIVATEKEY_HPP_ */ diff --git a/tests/communication/src/testmbedtlsconfig.h b/tests/communication/src/testmbedtlsconfig.h new file mode 100644 index 00000000..0e3e9f48 --- /dev/null +++ b/tests/communication/src/testmbedtlsconfig.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef TESTMBEDTLSCONFIG_H_ +#define TESTMBEDTLSCONFIG_H_ + +#define MBEDTLS_PEM_WRITE_C +#define MBEDTLS_PK_HAVE_ECC_KEYS +#define MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS +#define MBEDTLS_TEST_SW_INET_PTON +#define MBEDTLS_X509_CREATE_C +#define MBEDTLS_X509_CRT_WRITE_C +#define MBEDTLS_X509_CSR_PARSE_C +#define MBEDTLS_X509_CSR_WRITE_C +#define PSA_CRYPTO_DRIVER_AOS +#define MBEDTLS_NET_C + +#endif diff --git a/tests/communication/src/tlschannel.cpp b/tests/communication/src/tlschannel.cpp new file mode 100644 index 00000000..20380035 --- /dev/null +++ b/tests/communication/src/tlschannel.cpp @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "communication/channel.hpp" +#include "communication/tlschannel.hpp" + +#include "stubs/certhandlerstub.hpp" +#include "stubs/certloaderstub.hpp" +#include "stubs/rsaprivatekey.hpp" + +using namespace aos::zephyr; + +/*********************************************************************************************************************** + * Types + **********************************************************************************************************************/ + +class ClientChannel : public communication::ChannelItf { +public: + ClientChannel() { mbedtls_net_init(&mServerFd); } + ~ClientChannel() { mbedtls_net_free(&mServerFd); } + + aos::Error SetTLSConfig(const aos::String& certType) { return aos::ErrorEnum::eNone; } + + aos::Error Connect() override + { + return mbedtls_net_connect(&mServerFd, "localhost", "4433", MBEDTLS_NET_PROTO_TCP); + } + + aos::Error Close() override { return aos::ErrorEnum::eNone; } + + bool IsConnected() const override { return true; } + + int Read(void* data, size_t size) override + { + return mbedtls_net_recv(&mServerFd, static_cast(data), size); + } + + int Write(const void* data, size_t size) override + { + return mbedtls_net_send(&mServerFd, static_cast(data), size); + } + +private: + mbedtls_net_context mServerFd; +}; + +class Server { +public: + Server(std::promise listen) + : mListen(std::move(listen)) + { + } + + ~Server() + { + mbedtls_net_free(&mClientFd); + mbedtls_net_free(&mListenFd); + mbedtls_pk_free(&mPrivKeyCtx); + mbedtls_x509_crt_free(&mCertChain); + mbedtls_x509_crt_free(&mCACert); + mbedtls_ctr_drbg_free(&mCtrDrbg); + mbedtls_entropy_free(&mEntropy); + mbedtls_ssl_config_free(&mConf); + mbedtls_ssl_free(&mSsl); + } + + aos::Error Run() + { + auto err = Init(); + if (!err.IsNone()) { + return err; + } + + if ((err = ParseCACert()) != aos::ErrorEnum::eNone) { + return err; + } + + if ((err = ParseCertChain()) != aos::ErrorEnum::eNone) { + return err; + } + + if ((err = ParsePK()) != aos::ErrorEnum::eNone) { + return err; + } + + if ((err = SetupSSLConfig()) != aos::ErrorEnum::eNone) { + return err; + } + + if ((err = Bind()) != aos::ErrorEnum::eNone) { + return err; + } + + if ((err = Listen()) != aos::ErrorEnum::eNone) { + return err; + } + + return err; + } + +private: + static constexpr auto pers = "ssl_server"; + + aos::Error Init() + { + mbedtls_ssl_init(&mSsl); + mbedtls_ssl_config_init(&mConf); + mbedtls_entropy_init(&mEntropy); + mbedtls_ctr_drbg_init(&mCtrDrbg); + mbedtls_x509_crt_init(&mCACert); + mbedtls_x509_crt_init(&mCertChain); + mbedtls_pk_init(&mPrivKeyCtx); + mbedtls_net_init(&mListenFd); + mbedtls_net_init(&mClientFd); + + return mbedtls_ctr_drbg_seed( + &mCtrDrbg, mbedtls_entropy_func, &mEntropy, reinterpret_cast(pers), strlen(pers)); + } + + aos::Error ParseCACert() + { + aos::StaticString mCACertPem; + + auto err = aos::FS::ReadFileToString(CERT_DIR "/ca.pem", mCACertPem); + if (!err.IsNone()) { + return err; + } + + return mbedtls_x509_crt_parse( + &mCACert, reinterpret_cast(mCACertPem.Get()), mCACertPem.Size() + 1); + } + + aos::Error ParseCertChain() + { + aos::StaticString mCertChainPem; + + auto err = aos::FS::ReadFileToString(CERT_DIR "/server.cer", mCertChainPem); + if (!err.IsNone()) { + return err; + } + + return mbedtls_x509_crt_parse( + &mCertChain, reinterpret_cast(mCertChainPem.Get()), mCertChainPem.Size() + 1); + } + + aos::Error ParsePK() + { + aos::StaticString<4096> mPKPem; + + auto err = aos::FS::ReadFileToString(CERT_DIR "/server.key", mPKPem); + if (!err.IsNone()) { + return err; + } + + return mbedtls_pk_parse_key(&mPrivKeyCtx, reinterpret_cast(mPKPem.Get()), + mPKPem.Size() + 1, nullptr, 0, mbedtls_ctr_drbg_random, &mCtrDrbg); + } + + aos::Error SetupSSLConfig() + { + auto ret = mbedtls_ssl_config_defaults( + &mConf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); + if (ret != 0) { + return ret; + } + + mbedtls_ssl_conf_authmode(&mConf, MBEDTLS_SSL_VERIFY_REQUIRED); + mbedtls_ssl_conf_rng(&mConf, mbedtls_ctr_drbg_random, &mCtrDrbg); + mbedtls_ssl_conf_ca_chain(&mConf, &mCACert, nullptr); + mbedtls_ssl_conf_own_cert(&mConf, &mCertChain, &mPrivKeyCtx); + + return mbedtls_ssl_setup(&mSsl, &mConf); + } + + aos::Error Bind() { return mbedtls_net_bind(&mListenFd, nullptr, "4433", MBEDTLS_NET_PROTO_TCP); } + + aos::Error Listen() + { + mbedtls_net_free(&mClientFd); + + mbedtls_ssl_session_reset(&mSsl); + + mListen.set_value(); + + auto ret = mbedtls_net_accept(&mListenFd, &mClientFd, nullptr, 0, nullptr); + if (ret != 0) { + return ret; + } + + mbedtls_ssl_set_bio(&mSsl, &mClientFd, mbedtls_net_send, mbedtls_net_recv, nullptr); + + return mbedtls_ssl_handshake(&mSsl); + } + + mbedtls_ssl_context mSsl; + mbedtls_ssl_config mConf; + mbedtls_entropy_context mEntropy; + mbedtls_ctr_drbg_context mCtrDrbg; + mbedtls_x509_crt mCACert; + mbedtls_x509_crt mCertChain; + mbedtls_pk_context mPrivKeyCtx; + mbedtls_net_context mListenFd; + mbedtls_net_context mClientFd; + std::promise mListen; +}; + +/*********************************************************************************************************************** + * Setup + **********************************************************************************************************************/ + +ZTEST_SUITE(tlschannel, nullptr, nullptr, nullptr, nullptr, nullptr); + +/*********************************************************************************************************************** + * Tests + **********************************************************************************************************************/ + +ZTEST_F(tlschannel, test_TLSChannelConnect) +{ + psa_status_t status = psa_crypto_init(); + zassert_equal(status, PSA_SUCCESS, "psa_crypto_init failed"); + + CertLoaderStub certLoader; + CertHandlerStub certHandler; + ClientChannel vChannel; + + communication::TLSChannel channel; + + auto err = channel.Init(certHandler, certLoader, vChannel); + zassert_equal(err, aos::ErrorEnum::eNone, "test failed"); + + err = channel.SetTLSConfig("client"); + zassert_equal(err, aos::ErrorEnum::eNone, "test failed"); + + std::promise listen; + auto waitListen = listen.get_future(); + Server server(std::move(listen)); + + auto resServer = std::async(std::launch::async, &Server::Run, &server); + if (waitListen.wait_for(std::chrono::seconds(2)) == std::future_status::timeout) { + zassert_unreachable("test failed"); + } + + auto resClient = std::async(std::launch::async, &communication::TLSChannel::Connect, &channel); + + auto errClient = resClient.get(); + auto errServer = resServer.get(); + + zassert_equal(errClient, aos::ErrorEnum::eNone, "test failed"); + zassert_equal(errServer, aos::ErrorEnum::eNone, "test failed"); +} diff --git a/tests/communication/testcase.yaml b/tests/communication/testcase.yaml new file mode 100644 index 00000000..4ba6918d --- /dev/null +++ b/tests/communication/testcase.yaml @@ -0,0 +1,6 @@ +tests: + aoszephyrapp.communication: + build_only: false + tags: communication + timeout: 500 + platform_allow: native_posix_64 native_posix From e94ac6af010df0edaaae91b42eeac8ac4b138ad3 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Fri, 2 Aug 2024 14:06:41 +0300 Subject: [PATCH 016/198] [logger] Add nodeinfoprovider log Signed-off-by: Mykhailo Lohvynenko --- src/logger/logger.cpp | 22 +++++++++++++--------- src/nodeinfoprovider/log.hpp | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 src/nodeinfoprovider/log.hpp diff --git a/src/logger/logger.cpp b/src/logger/logger.cpp index a2302467..f9583c00 100644 --- a/src/logger/logger.cpp +++ b/src/logger/logger.cpp @@ -13,15 +13,16 @@ * Consts **********************************************************************************************************************/ -static const aos::String cLogModuleApp = "app"; -static const aos::String cLogModuleCommunication = "communication"; -static const aos::String cLogModuleClockSync = "clocksync"; -static const aos::String cLogModuleDownloader = "downloader"; -static const aos::String cLogModuleOCISpec = "ocispec"; -static const aos::String cLogModuleProvisioning = "provisioning"; -static const aos::String cLogModuleResourceManager = "resourcemanager"; -static const aos::String cLogModuleRunner = "runner"; -static const aos::String cLogModuleStorage = "storage"; +static const aos::String cLogModuleApp = "app"; +static const aos::String cLogModuleCommunication = "communication"; +static const aos::String cLogModuleClockSync = "clocksync"; +static const aos::String cLogModuleDownloader = "downloader"; +static const aos::String cLogModuleOCISpec = "ocispec"; +static const aos::String cLogModuleProvisioning = "provisioning"; +static const aos::String cLogModuleResourceManager = "resourcemanager"; +static const aos::String cLogModuleRunner = "runner"; +static const aos::String cLogModuleStorage = "storage"; +static const aos::String cLogModuleNodeInfoProvider = "nodeinfoprovider"; static const aos::String cLogModuleCerthandler = "certhandler"; static const aos::String cLogModuleCrypto = "crypto"; @@ -80,6 +81,7 @@ LOG_CALLBACK(provisioning); LOG_CALLBACK(resourcemanager); LOG_CALLBACK(runner); LOG_CALLBACK(storage); +LOG_CALLBACK(nodeinfoprovider); // Aos lib logs LOG_CALLBACK(certhandler); @@ -124,6 +126,8 @@ void Logger::LogCallback(const char* module, aos::LogLevel level, const aos::Str log_runner::LogCallback(level, message); } else if (logModule == cLogModuleStorage) { log_storage::LogCallback(level, message); + } else if (logModule == cLogModuleNodeInfoProvider) { + log_nodeinfoprovider::LogCallback(level, message); } else if (logModule == cLogModuleCerthandler) { log_certhandler::LogCallback(level, message); } else if (logModule == cLogModuleCrypto) { diff --git a/src/nodeinfoprovider/log.hpp b/src/nodeinfoprovider/log.hpp new file mode 100644 index 00000000..83a15fb3 --- /dev/null +++ b/src/nodeinfoprovider/log.hpp @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef LOG_HPP_ +#define LOG_HPP_ + +#define LOG_MODULE "nodeinfoprovider" + +#include + +#endif From 1c94ef8f300a526c305ed671cf54e0f8a3de0e10 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Fri, 2 Aug 2024 16:05:44 +0300 Subject: [PATCH 017/198] [nodeinfoprovider] Implement node info provider Signed-off-by: Mykhailo Lohvynenko --- CMakeLists.txt | 1 + Kconfig | 10 +- prj.conf | 3 + src/nodeinfoprovider/nodeinfoprovider.cpp | 198 ++++++++++++++++++++++ src/nodeinfoprovider/nodeinfoprovider.hpp | 59 +++++++ tests/nodeinfoprovider/CMakeLists.txt | 37 ++++ tests/nodeinfoprovider/Kconfig | 24 +++ tests/nodeinfoprovider/prj.conf | 20 +++ tests/nodeinfoprovider/src/main.cpp | 156 +++++++++++++++++ tests/nodeinfoprovider/testcase.yaml | 6 + 10 files changed, 513 insertions(+), 1 deletion(-) create mode 100644 src/nodeinfoprovider/nodeinfoprovider.cpp create mode 100644 src/nodeinfoprovider/nodeinfoprovider.hpp create mode 100644 tests/nodeinfoprovider/CMakeLists.txt create mode 100644 tests/nodeinfoprovider/Kconfig create mode 100644 tests/nodeinfoprovider/prj.conf create mode 100644 tests/nodeinfoprovider/src/main.cpp create mode 100644 tests/nodeinfoprovider/testcase.yaml diff --git a/CMakeLists.txt b/CMakeLists.txt index e526b98d..038ca438 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,7 @@ target_sources( src/downloader/downloader.cpp src/logger/logger.cpp src/monitoring/resourceusageprovider.cpp + src/nodeinfoprovider/nodeinfoprovider.cpp src/ocispec/ocispec.cpp src/provisioning/provisioning.cpp src/resourcemanager/resourcemanager.cpp diff --git a/Kconfig b/Kconfig index efa6cf11..3d2c8064 100644 --- a/Kconfig +++ b/Kconfig @@ -74,10 +74,18 @@ config AOS_CLOCK_SYNC_MAX_DIFF_MSEC int "Maximum allowed difference between source and current time." default 10000 +config AOS_MAX_CPU_DMIPS + int "Maximum CPU DMIPS" + default 10000 + config AOS_PROVISIONING_FILE string "Path to provisioning file." default "/aos/.provisioned" - + +config AOS_PROVISION_STATE_FILE + string "Path to provisioning state file." + default "/aos/.provisionstate" + config AOS_PKCS11_MODULE_PIN_FILE string "Path to PKCS11 module PIN file." default "/aos/.pkcs11pin" diff --git a/prj.conf b/prj.conf index b369bacd..74f24647 100644 --- a/prj.conf +++ b/prj.conf @@ -23,6 +23,9 @@ CONFIG_PICOLIBC=y # Increase KOBJECT RODATA CONFIG_KOBJECT_RODATA_AREA_EXTRA_BYTES=2048 +# Enable hardware info +CONFIG_HWINFO=y + # ###################################################################################################################### # Enable C++ # ###################################################################################################################### diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp new file mode 100644 index 00000000..191b4896 --- /dev/null +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include + +#include "log.hpp" +#include "nodeinfoprovider.hpp" + +/*********************************************************************************************************************** + * Public + **********************************************************************************************************************/ + +aos::Error NodeInfoProvider::Init() +{ + LOG_DBG() << "Init node info provider"; + + if (auto err = InitNodeID(); !err.IsNone() && !err.Is(aos::ErrorEnum::eNotSupported)) { + return aos::Error(AOS_ERROR_WRAP(err), "failed to init node id"); + } + + xenstat xstat {}; + + if (int ret = xstat_getstat(&xstat); ret != 0) { + return AOS_ERROR_WRAP(ret); + } + + mNodeInfo.mTotalRAM = xstat.tot_mem; + mNodeInfo.mNodeType = cNodeType; + mNodeInfo.mMaxDMIPS = cMaxDMIPS; + + if (auto err = InitAttributes(); !err.IsNone()) { + aos::Error(AOS_ERROR_WRAP(err), "failed to init node attributes"); + } + + if (auto err = InitPartitionInfo(); !err.IsNone()) { + aos::Error(AOS_ERROR_WRAP(err), "failed to init node partition info"); + } + + return aos::ErrorEnum::eNone; +} + +aos::Error NodeInfoProvider::GetNodeInfo(aos::NodeInfo& nodeInfo) const +{ + aos::NodeStatus status; + + if (auto err = ReadNodeStatus(status); !err.IsNone() && !err.Is(aos::ErrorEnum::eNotFound)) { + LOG_ERR() << "Get node info failed: error=" << err; + + aos::Error(AOS_ERROR_WRAP(err), "failed to read node status"); + } + + LOG_DBG() << "Get node info: status=" << status.ToString(); + + nodeInfo = mNodeInfo; + nodeInfo.mStatus = status; + + return aos::ErrorEnum::eNone; +} + +aos::Error NodeInfoProvider::SetNodeStatus(const aos::NodeStatus& status) +{ + LOG_DBG() << "Set node status: status=" << status.ToString(); + + if (auto err = StoreNodeStatus(status); !err.IsNone()) { + aos::Error(AOS_ERROR_WRAP(err), "failed to store node status"); + } + + LOG_DBG() << "Node status updated: status=" << status.ToString(); + + return aos::ErrorEnum::eNone; +} + +/*********************************************************************************************************************** + * Private + **********************************************************************************************************************/ + +aos::Error NodeInfoProvider::InitNodeID() +{ + uint8_t buffer[aos::cNodeIDLen]; + memset(buffer, 0, sizeof(buffer)); + + auto ret = hwinfo_get_device_id(buffer, sizeof(buffer) - 1); + + if (ret == -ENOSYS) { + LOG_WRN() << "hwinfo_get_device_id is not supported"; + + return aos::ErrorEnum::eNotSupported; + } else if (ret < 0) { + return AOS_ERROR_WRAP(ret); + } + + mNodeInfo.mNodeID = aos::String(reinterpret_cast(buffer), ret); + + return aos::ErrorEnum::eNone; +} + +aos::Error NodeInfoProvider::InitAttributes() +{ + if (auto err = mNodeInfo.mAttrs.PushBack({aos::iam::nodeinfoprovider::cAttrAosComponents, cAosComponents}); + !err.IsNone()) { + return err; + } + + if (auto err = mNodeInfo.mAttrs.PushBack({aos::iam::nodeinfoprovider::cAttrNodeRunners, cNodeRunner}); + !err.IsNone()) { + return err; + } + + return aos::ErrorEnum::eNone; +} + +aos::Error NodeInfoProvider::InitPartitionInfo() +{ + LOG_DBG() << "Init partition info"; + + aos::PartitionInfo partitionInfo; + + partitionInfo.mName = cDiskPartitionName; + partitionInfo.mPath = cDiskPartitionPoint; + partitionInfo.mTypes.EmplaceBack("services"); + partitionInfo.mTypes.EmplaceBack("layers"); + + if (auto err = mNodeInfo.mPartitions.PushBack(partitionInfo); !err.IsNone()) { + return err; + } + + for (auto& partition : mNodeInfo.mPartitions) { + struct fs_statvfs sbuf; + + if (auto ret = fs_statvfs(partition.mPath.CStr(), &sbuf); ret != 0) { + return ret; + } + + partition.mTotalSize = sbuf.f_bsize * sbuf.f_blocks; + + LOG_DBG() << "Init partition info: name=" << partition.mName << ", size=" << partition.mTotalSize; + } + + return aos::ErrorEnum::eNone; +} + +aos::Error NodeInfoProvider::StoreNodeStatus(const aos::NodeStatus& status) const +{ + auto statusStr = status.ToString(); + + auto fd = open(cProvisioningStateFile, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + if (fd < 0) { + return aos::Error(errno, "failed to open provisioning state file"); + } + + aos::Error err = aos::ErrorEnum::eNone; + + ssize_t nwrite = write(fd, statusStr.Get(), statusStr.Size()); + if (nwrite != static_cast(statusStr.Size())) { + err = nwrite < 0 ? AOS_ERROR_WRAP(errno) : aos::ErrorEnum::eRuntime; + } + + close(fd); + + return err; +} + +aos::Error NodeInfoProvider::ReadNodeStatus(aos::NodeStatus& status) const +{ + auto fd = open(cProvisioningStateFile, O_RDONLY); + if (fd < 0) { + if (errno == ENOENT) { + return aos::ErrorEnum::eNotFound; + } + + return AOS_ERROR_WRAP(errno); + } + + char buffer[64]; + + aos::Error err = aos::ErrorEnum::eNone; + + ssize_t nread = read(fd, buffer, sizeof(buffer)); + if (nread < 0) { + err = aos::Error(errno, "failed to read provisioning state file"); + } else if (nread == 0) { + status = aos::NodeStatus(); + } else { + err = status.FromString(aos::String(buffer, nread)); + } + + close(fd); + + return err; +} diff --git a/src/nodeinfoprovider/nodeinfoprovider.hpp b/src/nodeinfoprovider/nodeinfoprovider.hpp new file mode 100644 index 00000000..cc2fc417 --- /dev/null +++ b/src/nodeinfoprovider/nodeinfoprovider.hpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NODEINFOPROVIDER_HPP_ +#define NODEINFOPROVIDER_HPP_ + +#include + +/** + * Node info provider. + */ +class NodeInfoProvider : public aos::iam::nodeinfoprovider::NodeInfoProviderItf { +public: + /** + * Initializes the node info provider. + * + * @return Error + */ + aos::Error Init(); + + /** + * Gets the node info object. + * + * @param[out] nodeInfo node info + * @return Error + */ + aos::Error GetNodeInfo(aos::NodeInfo& nodeInfo) const override; + + /** + * Sets the node status. + * + * @param status node status + * @return Error + */ + aos::Error SetNodeStatus(const aos::NodeStatus& status) override; + +private: + aos::Error InitNodeID(); + aos::Error InitAttributes(); + aos::Error InitPartitionInfo(); + aos::Error StoreNodeStatus(const aos::NodeStatus& status) const; + aos::Error ReadNodeStatus(aos::NodeStatus& status) const; + + static constexpr auto cDiskPartitionPoint = CONFIG_AOS_DISK_MOUNT_POINT; + static constexpr auto cMaxDMIPS = CONFIG_AOS_MAX_CPU_DMIPS; + static constexpr auto cNodeType = CONFIG_AOS_NODE_TYPE; + static constexpr auto cProvisioningStateFile = CONFIG_AOS_PROVISION_STATE_FILE; + static constexpr auto cDiskPartitionName = "Aos"; + static constexpr auto cNodeRunner = "xrun"; + static constexpr auto cAosComponents = "iam,sm"; + + aos::NodeInfo mNodeInfo; +}; + +#endif diff --git a/tests/nodeinfoprovider/CMakeLists.txt b/tests/nodeinfoprovider/CMakeLists.txt new file mode 100644 index 00000000..8d266b17 --- /dev/null +++ b/tests/nodeinfoprovider/CMakeLists.txt @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project(nodeinfoprovider_test) + +# ###################################################################################################################### +# Config +# ###################################################################################################################### + +set(AOS_CORE_CONFIG aoscoreconfig.hpp) + +# ###################################################################################################################### +# Definitions +# ###################################################################################################################### + +# Aos core configuration +add_definitions(-include ${AOS_CORE_CONFIG}) + +# ###################################################################################################################### +# Includes +# ###################################################################################################################### + +target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../src) +target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../../aos_core_lib_cpp/include) +target_include_directories(app PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + +zephyr_include_directories_ifdef(CONFIG_NATIVE_APPLICATION ${APPLICATION_SOURCE_DIR}/../../mocks/include) + +# ###################################################################################################################### +# Target +# ###################################################################################################################### + +target_sources(app PRIVATE src/main.cpp ../../src/nodeinfoprovider/nodeinfoprovider.cpp) + +target_sources_ifdef(CONFIG_NATIVE_APPLICATION app PRIVATE ${APPLICATION_SOURCE_DIR}/../../mocks/xstat/xstat.cpp) diff --git a/tests/nodeinfoprovider/Kconfig b/tests/nodeinfoprovider/Kconfig new file mode 100644 index 00000000..72b8f2e3 --- /dev/null +++ b/tests/nodeinfoprovider/Kconfig @@ -0,0 +1,24 @@ +# Copyright (C) 2024 Renesas Electronics Corporation. +# Copyright (C) 2024 EPAM Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "Aos zephyr application" + +config AOS_NODE_TYPE + string "Node type" + default "NODE_TYPE1" + +config AOS_MAX_CPU_DMIPS + int "Maximum CPU DMIPS" + default 10000 + +config AOS_DISK_MOUNT_POINT + string "Disk mount point" + default "/aos" + +config AOS_PROVISION_STATE_FILE + string "Path to provisioning state file." + default ".provisionstate" + +source "Kconfig" diff --git a/tests/nodeinfoprovider/prj.conf b/tests/nodeinfoprovider/prj.conf new file mode 100644 index 00000000..be4cf54f --- /dev/null +++ b/tests/nodeinfoprovider/prj.conf @@ -0,0 +1,20 @@ +# Enable C++ +CONFIG_CPP=y +CONFIG_STD_CPP17=y + +# Enable test suit +CONFIG_ZTEST=y + +# Enable JSON library +CONFIG_JSON_LIBRARY=y + +# Enable file system +CONFIG_FLASH=y +CONFIG_FLASH_MAP=y +CONFIG_FILE_SYSTEM=y +CONFIG_FILE_SYSTEM_LITTLEFS=y + + + +# Enable hardware info +CONFIG_HWINFO=y diff --git a/tests/nodeinfoprovider/src/main.cpp b/tests/nodeinfoprovider/src/main.cpp new file mode 100644 index 00000000..646bfff8 --- /dev/null +++ b/tests/nodeinfoprovider/src/main.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include +#include + +#include "nodeinfoprovider/nodeinfoprovider.hpp" + +#define LVGL_PARTITION storage_partition +#define LVGL_PARTITION_ID FIXED_PARTITION_ID(LVGL_PARTITION) + +FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(cstorage); + +static struct fs_mount_t sMnt = { + .type = FS_LITTLEFS, + .mnt_point = CONFIG_AOS_DISK_MOUNT_POINT, + .fs_data = &cstorage, + .storage_dev = (void*)LVGL_PARTITION_ID, +}; + +static struct fs_statvfs sMntStat; + +void* setup_fs(void) +{ + printk("setup_fs\n"); + + int ret = fs_mount(&sMnt); + if (ret < 0) { + TC_PRINT("Failed to mount file system: %d\n", ret); + + ztest_test_fail(); + + return NULL; + } + + ret = fs_statvfs(CONFIG_AOS_DISK_MOUNT_POINT, &sMntStat); + if (ret != 0) { + printk("Failed to get statvfs: %d\n", ret); + } else { + printk("Mounted partition: %s\n", CONFIG_AOS_DISK_MOUNT_POINT); + printk("bsize = %lu\n", sMntStat.f_bsize); + printk("frsize = %lu\n", sMntStat.f_frsize); + printk("blocks = %lu\n", sMntStat.f_blocks); + printk("bfree = %lu\n", sMntStat.f_bfree); + } + + return NULL; +} + +void teardown_fs(void* data) +{ + printk("teardown_fs\n"); + + auto ret = fs_unmount(&sMnt); + if (ret < 0) { + printk("Failed to unmount file system: %d\n", ret); + } + + return; +} + +void before_test(void* data) +{ + printk("before_test\n"); + + auto fd = open(CONFIG_AOS_PROVISION_STATE_FILE, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + if (fd < 0) { + printk("Failed to open provisioning status file: %d\n", fd); + } + + close(fd); +} + +static void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message) +{ + printk("[nodeinfoprovider] %s \n", message.CStr()); +} + +ZTEST_SUITE(nodeinfoprovider, NULL, setup_fs, before_test, NULL, teardown_fs); + +ZTEST(nodeinfoprovider, test_node_info) +{ + aos::Log::SetCallback(TestLogCallback); + + NodeInfoProvider provider; + auto err = provider.Init(); + zassert_true(err.IsNone(), "Failed to init node info provider: %s", err.Message()); + + aos::NodeInfo nodeInfo; + err = provider.GetNodeInfo(nodeInfo); + + zassert_true(err.IsNone(), "Failed to get node info: %s", err.Message()); + + zassert_equal(nodeInfo.mStatus.GetValue(), aos::NodeStatusEnum::eUnprovisioned, "Node status mismatch"); + zassert_equal(nodeInfo.mMaxDMIPS, CONFIG_AOS_MAX_CPU_DMIPS, "Max DMIPS mismatch"); + + // test partition info + zassert_equal(nodeInfo.mPartitions.Size(), 1, "Expected 1 partition"); + zassert_equal(nodeInfo.mPartitions[0].mName, "Aos", "Partition name mismatch"); + zassert_equal(nodeInfo.mPartitions[0].mPath, CONFIG_AOS_DISK_MOUNT_POINT, "Partition path mismatch"); + + const auto expectedSize = sMntStat.f_bsize * sMntStat.f_blocks; + zassert_equal(nodeInfo.mPartitions[0].mTotalSize, expectedSize, "Partition total size mismatch"); + + zassert_equal(nodeInfo.mPartitions[0].mTypes.Size(), 2, "Expected 2 partition types"); + zassert_equal(nodeInfo.mPartitions[0].mTypes[0], "services", "Partition type mismatch"); + zassert_equal(nodeInfo.mPartitions[0].mTypes[1], "layers", "Partition type mismatch"); + + // test attributes + zassert_equal(nodeInfo.mAttrs.Size(), 2, "Expected 2 attributes"); + zassert_equal(nodeInfo.mAttrs[0].mName, "AosComponents", "Attribute name mismatch"); + zassert_equal(nodeInfo.mAttrs[0].mValue, "iam,sm", "Attribute value mismatch"); + + zassert_equal(nodeInfo.mAttrs[1].mName, "NodeRunners", "Attribute name mismatch"); + zassert_equal(nodeInfo.mAttrs[1].mValue, "xrun", "Attribute value mismatch"); +} + +ZTEST(nodeinfoprovider, test_set_get_node_info) +{ + aos::Log::SetCallback(TestLogCallback); + + NodeInfoProvider provider; + auto err = provider.Init(); + zassert_true(err.IsNone(), "Failed to init node info provider: %s", err.Message()); + + aos::NodeInfo nodeInfo; + err = provider.GetNodeInfo(nodeInfo); + + zassert_true(err.IsNone(), "Failed to get node info: %s", err.Message()); + zassert_equal(nodeInfo.mStatus.GetValue(), aos::NodeStatusEnum::eUnprovisioned, "Node status mismatch"); + + err = provider.SetNodeStatus(aos::NodeStatus(aos::NodeStatusEnum::eProvisioned)); + zassert_true(err.IsNone(), "Set node status failed: %s", err.Message()); + + err = provider.GetNodeInfo(nodeInfo); + zassert_true(err.IsNone(), "Get node status failed: %s", err.Message()); + + zassert_equal(nodeInfo.mStatus.GetValue(), aos::NodeStatusEnum::eProvisioned, "Node status mismatch"); + + err = provider.SetNodeStatus(aos::NodeStatus(aos::NodeStatusEnum::ePaused)); + zassert_true(err.IsNone(), "Set node status failed: %s", err.Message()); + + err = provider.GetNodeInfo(nodeInfo); + zassert_true(err.IsNone(), "Get node status failed: %s", err.Message()); + + zassert_equal(nodeInfo.mStatus.GetValue(), aos::NodeStatusEnum::ePaused, "Node status mismatch"); +} diff --git a/tests/nodeinfoprovider/testcase.yaml b/tests/nodeinfoprovider/testcase.yaml new file mode 100644 index 00000000..686b106b --- /dev/null +++ b/tests/nodeinfoprovider/testcase.yaml @@ -0,0 +1,6 @@ +tests: + aoszephyrapp.nodeinfoprovider: + build_only: false + tags: nodeinfoprovider + timeout: 500 + platform_allow: native_posix_64 native_posix From 70b2f2dba47479cf12a6efa7d78e7fc31e28225e Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Wed, 7 Aug 2024 22:47:13 +0300 Subject: [PATCH 018/198] [nodeinfoprovider] Use aos FS for prov status file Signed-off-by: Mykhailo Lohvynenko --- src/nodeinfoprovider/nodeinfoprovider.cpp | 53 +++++++---------------- src/nodeinfoprovider/nodeinfoprovider.hpp | 1 + tests/nodeinfoprovider/src/main.cpp | 28 +++++++++--- 3 files changed, 40 insertions(+), 42 deletions(-) diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp index 191b4896..cf8daf46 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -11,6 +11,8 @@ #include +#include + #include "log.hpp" #include "nodeinfoprovider.hpp" @@ -37,11 +39,11 @@ aos::Error NodeInfoProvider::Init() mNodeInfo.mMaxDMIPS = cMaxDMIPS; if (auto err = InitAttributes(); !err.IsNone()) { - aos::Error(AOS_ERROR_WRAP(err), "failed to init node attributes"); + return aos::Error(AOS_ERROR_WRAP(err), "failed to init node attributes"); } if (auto err = InitPartitionInfo(); !err.IsNone()) { - aos::Error(AOS_ERROR_WRAP(err), "failed to init node partition info"); + return aos::Error(AOS_ERROR_WRAP(err), "failed to init node partition info"); } return aos::ErrorEnum::eNone; @@ -51,10 +53,10 @@ aos::Error NodeInfoProvider::GetNodeInfo(aos::NodeInfo& nodeInfo) const { aos::NodeStatus status; - if (auto err = ReadNodeStatus(status); !err.IsNone() && !err.Is(aos::ErrorEnum::eNotFound)) { + if (auto err = ReadNodeStatus(status); !err.IsNone()) { LOG_ERR() << "Get node info failed: error=" << err; - aos::Error(AOS_ERROR_WRAP(err), "failed to read node status"); + return AOS_ERROR_WRAP(err); } LOG_DBG() << "Get node info: status=" << status.ToString(); @@ -151,48 +153,25 @@ aos::Error NodeInfoProvider::StoreNodeStatus(const aos::NodeStatus& status) cons { auto statusStr = status.ToString(); - auto fd = open(cProvisioningStateFile, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); - if (fd < 0) { - return aos::Error(errno, "failed to open provisioning state file"); - } - - aos::Error err = aos::ErrorEnum::eNone; - - ssize_t nwrite = write(fd, statusStr.Get(), statusStr.Size()); - if (nwrite != static_cast(statusStr.Size())) { - err = nwrite < 0 ? AOS_ERROR_WRAP(errno) : aos::ErrorEnum::eRuntime; + if (auto err = aos::FS::WriteStringToFile(cProvisioningStateFile, statusStr, S_IRUSR | S_IWUSR); !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - close(fd); - - return err; + return aos::ErrorEnum::eNone; } aos::Error NodeInfoProvider::ReadNodeStatus(aos::NodeStatus& status) const { - auto fd = open(cProvisioningStateFile, O_RDONLY); - if (fd < 0) { - if (errno == ENOENT) { - return aos::ErrorEnum::eNotFound; - } + aos::StaticString statusStr; - return AOS_ERROR_WRAP(errno); + auto err = aos::FS::ReadFileToString(cProvisioningStateFile, statusStr); + if (!err.IsNone()) { + return err; } - char buffer[64]; - - aos::Error err = aos::ErrorEnum::eNone; - - ssize_t nread = read(fd, buffer, sizeof(buffer)); - if (nread < 0) { - err = aos::Error(errno, "failed to read provisioning state file"); - } else if (nread == 0) { - status = aos::NodeStatus(); - } else { - err = status.FromString(aos::String(buffer, nread)); + if (statusStr.IsEmpty()) { + return aos::ErrorEnum::eFailed; } - close(fd); - - return err; + return status.FromString(statusStr); } diff --git a/src/nodeinfoprovider/nodeinfoprovider.hpp b/src/nodeinfoprovider/nodeinfoprovider.hpp index cc2fc417..b6e62c14 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.hpp +++ b/src/nodeinfoprovider/nodeinfoprovider.hpp @@ -45,6 +45,7 @@ class NodeInfoProvider : public aos::iam::nodeinfoprovider::NodeInfoProviderItf aos::Error StoreNodeStatus(const aos::NodeStatus& status) const; aos::Error ReadNodeStatus(aos::NodeStatus& status) const; + static constexpr auto cNodeStatusLen = 16; static constexpr auto cDiskPartitionPoint = CONFIG_AOS_DISK_MOUNT_POINT; static constexpr auto cMaxDMIPS = CONFIG_AOS_MAX_CPU_DMIPS; static constexpr auto cNodeType = CONFIG_AOS_NODE_TYPE; diff --git a/tests/nodeinfoprovider/src/main.cpp b/tests/nodeinfoprovider/src/main.cpp index 646bfff8..76aefb88 100644 --- a/tests/nodeinfoprovider/src/main.cpp +++ b/tests/nodeinfoprovider/src/main.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -20,6 +21,17 @@ FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(cstorage); +/*********************************************************************************************************************** + * Consts + **********************************************************************************************************************/ + +static constexpr auto cNodeStateFile = CONFIG_AOS_PROVISION_STATE_FILE; +static constexpr auto cUnprovisioned = "unprovisioned"; + +/*********************************************************************************************************************** + * Static + **********************************************************************************************************************/ + static struct fs_mount_t sMnt = { .type = FS_LITTLEFS, .mnt_point = CONFIG_AOS_DISK_MOUNT_POINT, @@ -72,14 +84,16 @@ void before_test(void* data) { printk("before_test\n"); - auto fd = open(CONFIG_AOS_PROVISION_STATE_FILE, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); - if (fd < 0) { - printk("Failed to open provisioning status file: %d\n", fd); + auto err = aos::FS::WriteStringToFile(cNodeStateFile, cUnprovisioned, S_IRUSR | S_IWUSR); + if (!err.IsNone()) { + printk("Can't create provisioning state file: %s\n", err.Message()); } - - close(fd); } +/*********************************************************************************************************************** + * Setup + **********************************************************************************************************************/ + static void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message) { printk("[nodeinfoprovider] %s \n", message.CStr()); @@ -87,6 +101,10 @@ static void TestLogCallback(const char* module, aos::LogLevel level, const aos:: ZTEST_SUITE(nodeinfoprovider, NULL, setup_fs, before_test, NULL, teardown_fs); +/*********************************************************************************************************************** + * Tests + **********************************************************************************************************************/ + ZTEST(nodeinfoprovider, test_node_info) { aos::Log::SetCallback(TestLogCallback); From 3fc0267b047f2b66e6f91e88f231e64ef5fc9fd9 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Mon, 12 Aug 2024 17:00:58 +0300 Subject: [PATCH 019/198] [nodeinfoprovider] Add nodeinfoprovider namespace Signed-off-by: Mykhailo Lohvynenko --- src/nodeinfoprovider/nodeinfoprovider.cpp | 67 ++++++++++++----------- src/nodeinfoprovider/nodeinfoprovider.hpp | 24 ++++---- tests/nodeinfoprovider/src/main.cpp | 8 +-- 3 files changed, 53 insertions(+), 46 deletions(-) diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp index cf8daf46..314fad2c 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -16,16 +16,18 @@ #include "log.hpp" #include "nodeinfoprovider.hpp" +namespace aos::zephyr::nodeinfoprovider { + /*********************************************************************************************************************** * Public **********************************************************************************************************************/ -aos::Error NodeInfoProvider::Init() +Error NodeInfoProvider::Init() { LOG_DBG() << "Init node info provider"; - if (auto err = InitNodeID(); !err.IsNone() && !err.Is(aos::ErrorEnum::eNotSupported)) { - return aos::Error(AOS_ERROR_WRAP(err), "failed to init node id"); + if (auto err = InitNodeID(); !err.IsNone() && !err.Is(ErrorEnum::eNotSupported)) { + return Error(AOS_ERROR_WRAP(err), "failed to init node id"); } xenstat xstat {}; @@ -39,19 +41,19 @@ aos::Error NodeInfoProvider::Init() mNodeInfo.mMaxDMIPS = cMaxDMIPS; if (auto err = InitAttributes(); !err.IsNone()) { - return aos::Error(AOS_ERROR_WRAP(err), "failed to init node attributes"); + return Error(AOS_ERROR_WRAP(err), "failed to init node attributes"); } if (auto err = InitPartitionInfo(); !err.IsNone()) { - return aos::Error(AOS_ERROR_WRAP(err), "failed to init node partition info"); + return Error(AOS_ERROR_WRAP(err), "failed to init node partition info"); } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error NodeInfoProvider::GetNodeInfo(aos::NodeInfo& nodeInfo) const +Error NodeInfoProvider::GetNodeInfo(NodeInfo& nodeInfo) const { - aos::NodeStatus status; + NodeStatus status; if (auto err = ReadNodeStatus(status); !err.IsNone()) { LOG_ERR() << "Get node info failed: error=" << err; @@ -64,29 +66,29 @@ aos::Error NodeInfoProvider::GetNodeInfo(aos::NodeInfo& nodeInfo) const nodeInfo = mNodeInfo; nodeInfo.mStatus = status; - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error NodeInfoProvider::SetNodeStatus(const aos::NodeStatus& status) +Error NodeInfoProvider::SetNodeStatus(const NodeStatus& status) { LOG_DBG() << "Set node status: status=" << status.ToString(); if (auto err = StoreNodeStatus(status); !err.IsNone()) { - aos::Error(AOS_ERROR_WRAP(err), "failed to store node status"); + Error(AOS_ERROR_WRAP(err), "failed to store node status"); } LOG_DBG() << "Node status updated: status=" << status.ToString(); - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } /*********************************************************************************************************************** * Private **********************************************************************************************************************/ -aos::Error NodeInfoProvider::InitNodeID() +Error NodeInfoProvider::InitNodeID() { - uint8_t buffer[aos::cNodeIDLen]; + uint8_t buffer[cNodeIDLen]; memset(buffer, 0, sizeof(buffer)); auto ret = hwinfo_get_device_id(buffer, sizeof(buffer) - 1); @@ -94,36 +96,35 @@ aos::Error NodeInfoProvider::InitNodeID() if (ret == -ENOSYS) { LOG_WRN() << "hwinfo_get_device_id is not supported"; - return aos::ErrorEnum::eNotSupported; + return ErrorEnum::eNotSupported; } else if (ret < 0) { return AOS_ERROR_WRAP(ret); } - mNodeInfo.mNodeID = aos::String(reinterpret_cast(buffer), ret); + mNodeInfo.mNodeID = String(reinterpret_cast(buffer), ret); - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error NodeInfoProvider::InitAttributes() +Error NodeInfoProvider::InitAttributes() { - if (auto err = mNodeInfo.mAttrs.PushBack({aos::iam::nodeinfoprovider::cAttrAosComponents, cAosComponents}); + if (auto err = mNodeInfo.mAttrs.PushBack({iam::nodeinfoprovider::cAttrAosComponents, cAosComponents}); !err.IsNone()) { return err; } - if (auto err = mNodeInfo.mAttrs.PushBack({aos::iam::nodeinfoprovider::cAttrNodeRunners, cNodeRunner}); - !err.IsNone()) { + if (auto err = mNodeInfo.mAttrs.PushBack({iam::nodeinfoprovider::cAttrNodeRunners, cNodeRunner}); !err.IsNone()) { return err; } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error NodeInfoProvider::InitPartitionInfo() +Error NodeInfoProvider::InitPartitionInfo() { LOG_DBG() << "Init partition info"; - aos::PartitionInfo partitionInfo; + PartitionInfo partitionInfo; partitionInfo.mName = cDiskPartitionName; partitionInfo.mPath = cDiskPartitionPoint; @@ -146,32 +147,34 @@ aos::Error NodeInfoProvider::InitPartitionInfo() LOG_DBG() << "Init partition info: name=" << partition.mName << ", size=" << partition.mTotalSize; } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error NodeInfoProvider::StoreNodeStatus(const aos::NodeStatus& status) const +Error NodeInfoProvider::StoreNodeStatus(const NodeStatus& status) const { auto statusStr = status.ToString(); - if (auto err = aos::FS::WriteStringToFile(cProvisioningStateFile, statusStr, S_IRUSR | S_IWUSR); !err.IsNone()) { + if (auto err = FS::WriteStringToFile(cProvisioningStateFile, statusStr, S_IRUSR | S_IWUSR); !err.IsNone()) { return AOS_ERROR_WRAP(err); } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error NodeInfoProvider::ReadNodeStatus(aos::NodeStatus& status) const +Error NodeInfoProvider::ReadNodeStatus(NodeStatus& status) const { - aos::StaticString statusStr; + StaticString statusStr; - auto err = aos::FS::ReadFileToString(cProvisioningStateFile, statusStr); + auto err = FS::ReadFileToString(cProvisioningStateFile, statusStr); if (!err.IsNone()) { return err; } if (statusStr.IsEmpty()) { - return aos::ErrorEnum::eFailed; + return ErrorEnum::eFailed; } return status.FromString(statusStr); } + +} // namespace aos::zephyr::nodeinfoprovider diff --git a/src/nodeinfoprovider/nodeinfoprovider.hpp b/src/nodeinfoprovider/nodeinfoprovider.hpp index b6e62c14..d3ab770f 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.hpp +++ b/src/nodeinfoprovider/nodeinfoprovider.hpp @@ -10,17 +10,19 @@ #include +namespace aos::zephyr::nodeinfoprovider { + /** * Node info provider. */ -class NodeInfoProvider : public aos::iam::nodeinfoprovider::NodeInfoProviderItf { +class NodeInfoProvider : public iam::nodeinfoprovider::NodeInfoProviderItf { public: /** * Initializes the node info provider. * * @return Error */ - aos::Error Init(); + Error Init(); /** * Gets the node info object. @@ -28,7 +30,7 @@ class NodeInfoProvider : public aos::iam::nodeinfoprovider::NodeInfoProviderItf * @param[out] nodeInfo node info * @return Error */ - aos::Error GetNodeInfo(aos::NodeInfo& nodeInfo) const override; + Error GetNodeInfo(NodeInfo& nodeInfo) const override; /** * Sets the node status. @@ -36,14 +38,14 @@ class NodeInfoProvider : public aos::iam::nodeinfoprovider::NodeInfoProviderItf * @param status node status * @return Error */ - aos::Error SetNodeStatus(const aos::NodeStatus& status) override; + Error SetNodeStatus(const NodeStatus& status) override; private: - aos::Error InitNodeID(); - aos::Error InitAttributes(); - aos::Error InitPartitionInfo(); - aos::Error StoreNodeStatus(const aos::NodeStatus& status) const; - aos::Error ReadNodeStatus(aos::NodeStatus& status) const; + Error InitNodeID(); + Error InitAttributes(); + Error InitPartitionInfo(); + Error StoreNodeStatus(const NodeStatus& status) const; + Error ReadNodeStatus(NodeStatus& status) const; static constexpr auto cNodeStatusLen = 16; static constexpr auto cDiskPartitionPoint = CONFIG_AOS_DISK_MOUNT_POINT; @@ -54,7 +56,9 @@ class NodeInfoProvider : public aos::iam::nodeinfoprovider::NodeInfoProviderItf static constexpr auto cNodeRunner = "xrun"; static constexpr auto cAosComponents = "iam,sm"; - aos::NodeInfo mNodeInfo; + NodeInfo mNodeInfo; }; +} // namespace aos::zephyr::nodeinfoprovider + #endif diff --git a/tests/nodeinfoprovider/src/main.cpp b/tests/nodeinfoprovider/src/main.cpp index 76aefb88..f7dbd857 100644 --- a/tests/nodeinfoprovider/src/main.cpp +++ b/tests/nodeinfoprovider/src/main.cpp @@ -109,8 +109,8 @@ ZTEST(nodeinfoprovider, test_node_info) { aos::Log::SetCallback(TestLogCallback); - NodeInfoProvider provider; - auto err = provider.Init(); + aos::zephyr::nodeinfoprovider::NodeInfoProvider provider; + auto err = provider.Init(); zassert_true(err.IsNone(), "Failed to init node info provider: %s", err.Message()); aos::NodeInfo nodeInfo; @@ -146,8 +146,8 @@ ZTEST(nodeinfoprovider, test_set_get_node_info) { aos::Log::SetCallback(TestLogCallback); - NodeInfoProvider provider; - auto err = provider.Init(); + aos::zephyr::nodeinfoprovider::NodeInfoProvider provider; + auto err = provider.Init(); zassert_true(err.IsNone(), "Failed to init node info provider: %s", err.Message()); aos::NodeInfo nodeInfo; From 5558103d4d5f95add2d70e97895d53d6267c9f39 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Mon, 12 Aug 2024 17:10:58 +0300 Subject: [PATCH 020/198] [resourcemanager] Use updated core lib cpp structs Signed-off-by: Mykhailo Lohvynenko --- src/resourcemanager/resourcemanager.cpp | 36 ++++++++++++------------ src/resourcemanager/resourcemanager.hpp | 22 +++++++-------- tests/resourcemanager/src/main.cpp | 37 ++++++++++++------------- 3 files changed, 46 insertions(+), 49 deletions(-) diff --git a/src/resourcemanager/resourcemanager.cpp b/src/resourcemanager/resourcemanager.cpp index 2c834f80..b3a86191 100644 --- a/src/resourcemanager/resourcemanager.cpp +++ b/src/resourcemanager/resourcemanager.cpp @@ -14,10 +14,10 @@ * Static **********************************************************************************************************************/ -static const struct json_obj_descr cUnitConfigDescr[] = { - JSON_OBJ_DESCR_PRIM(UnitConfig, vendorVersion, JSON_TOK_STRING), - JSON_OBJ_DESCR_PRIM(UnitConfig, nodeType, JSON_TOK_STRING), - JSON_OBJ_DESCR_PRIM(UnitConfig, priority, JSON_TOK_NUMBER), +static const struct json_obj_descr cNodeConfigDescr[] = { + JSON_OBJ_DESCR_PRIM(NodeConfig, vendorVersion, JSON_TOK_STRING), + JSON_OBJ_DESCR_PRIM(NodeConfig, nodeType, JSON_TOK_STRING), + JSON_OBJ_DESCR_PRIM(NodeConfig, priority, JSON_TOK_NUMBER), }; /*********************************************************************************************************************** @@ -28,21 +28,21 @@ static const struct json_obj_descr cUnitConfigDescr[] = { **********************************************************************************************************************/ // cppcheck-suppress unusedFunction -aos::Error ResourceManagerJSONProvider::DumpUnitConfig( - const aos::sm::resourcemanager::UnitConfig& nodeUnitConfig, aos::String& json) const +aos::Error ResourceManagerJSONProvider::DumpNodeConfig( + const aos::sm::resourcemanager::NodeConfig& config, aos::String& json) const { aos::LockGuard lock(mMutex); mAllocator.Clear(); - auto jsonUnitConfig = aos::MakeUnique(&mAllocator); + auto jsonNodeConfig = aos::MakeUnique(&mAllocator); - jsonUnitConfig->vendorVersion = nodeUnitConfig.mVendorVersion.CStr(); - jsonUnitConfig->nodeType = nodeUnitConfig.mNodeUnitConfig.mNodeType.CStr(); - jsonUnitConfig->priority = nodeUnitConfig.mNodeUnitConfig.mPriority; + jsonNodeConfig->vendorVersion = config.mVendorVersion.CStr(); + jsonNodeConfig->nodeType = config.mNodeConfig.mNodeType.CStr(); + jsonNodeConfig->priority = config.mNodeConfig.mPriority; auto ret = json_obj_encode_buf( - cUnitConfigDescr, ARRAY_SIZE(cUnitConfigDescr), jsonUnitConfig.Get(), json.Get(), json.MaxSize()); + cNodeConfigDescr, ARRAY_SIZE(cNodeConfigDescr), jsonNodeConfig.Get(), json.Get(), json.MaxSize()); if (ret < 0) { return AOS_ERROR_WRAP(ret); } @@ -56,8 +56,8 @@ aos::Error ResourceManagerJSONProvider::DumpUnitConfig( } // cppcheck-suppress unusedFunction -aos::Error ResourceManagerJSONProvider::ParseNodeUnitConfig( - const aos::String& json, aos::sm::resourcemanager::UnitConfig& nodeUnitConfig) const +aos::Error ResourceManagerJSONProvider::ParseNodeConfig( + const aos::String& json, aos::sm::resourcemanager::NodeConfig& config) const { aos::LockGuard lock(mMutex); @@ -66,17 +66,17 @@ aos::Error ResourceManagerJSONProvider::ParseNodeUnitConfig( // json_object_parse mutates the input string, so we need to copy it mJSONBuffer = json; - auto parsedUnitConfig = aos::MakeUnique(&mAllocator); + auto parsedNodeConfig = aos::MakeUnique(&mAllocator); auto ret = json_obj_parse( - mJSONBuffer.Get(), mJSONBuffer.Size(), cUnitConfigDescr, ARRAY_SIZE(cUnitConfigDescr), parsedUnitConfig.Get()); + mJSONBuffer.Get(), mJSONBuffer.Size(), cNodeConfigDescr, ARRAY_SIZE(cNodeConfigDescr), parsedNodeConfig.Get()); if (ret < 0) { return AOS_ERROR_WRAP(ret); } - nodeUnitConfig.mVendorVersion = parsedUnitConfig->vendorVersion; - nodeUnitConfig.mNodeUnitConfig.mNodeType = parsedUnitConfig->nodeType; - nodeUnitConfig.mNodeUnitConfig.mPriority = parsedUnitConfig->priority; + config.mVendorVersion = parsedNodeConfig->vendorVersion; + config.mNodeConfig.mNodeType = parsedNodeConfig->nodeType; + config.mNodeConfig.mPriority = parsedNodeConfig->priority; return aos::ErrorEnum::eNone; } diff --git a/src/resourcemanager/resourcemanager.hpp b/src/resourcemanager/resourcemanager.hpp index 2ab4050e..236c09d2 100644 --- a/src/resourcemanager/resourcemanager.hpp +++ b/src/resourcemanager/resourcemanager.hpp @@ -14,9 +14,9 @@ #include /** - * Node unit config. + * Node config. */ -struct UnitConfig { +struct NodeConfig { const char* vendorVersion = ""; const char* nodeType = ""; uint32_t priority = 0; @@ -25,24 +25,22 @@ struct UnitConfig { class ResourceManagerJSONProvider : public aos::sm::resourcemanager::JSONProviderItf { public: /** - * Dumps node unit config object from json string. + * Dumps config object into string. * - * @param nodeUnitConfig node unit config object. - * @param[out] json json representation of node unit config. + * @param config config object. + * @param[out] json json representation of config. * @return Error. */ - aos::Error DumpUnitConfig( - const aos::sm::resourcemanager::UnitConfig& nodeUnitConfig, aos::String& json) const override; + aos::Error DumpNodeConfig(const aos::sm::resourcemanager::NodeConfig& config, aos::String& json) const override; /** - * Parses node unit config json string from object. + * Parses config object from string. * - * @param json json representation of node unit config. - * @param[out] nodeUnitConfig node unit config. + * @param json json representation of config. + * @param[out] config config. * @return Error. */ - aos::Error ParseNodeUnitConfig( - const aos::String& json, aos::sm::resourcemanager::UnitConfig& nodeUnitConfig) const override; + aos::Error ParseNodeConfig(const aos::String& json, aos::sm::resourcemanager::NodeConfig& config) const override; private: static constexpr size_t cJsonMaxContentLen = 1024; diff --git a/tests/resourcemanager/src/main.cpp b/tests/resourcemanager/src/main.cpp index c9adc972..a7e10e75 100644 --- a/tests/resourcemanager/src/main.cpp +++ b/tests/resourcemanager/src/main.cpp @@ -27,42 +27,41 @@ ZTEST(resourcemanager, test_JSONProviderParse) aos::Log::SetCallback(TestLogCallback); ResourceManagerJSONProvider provider; - aos::sm::resourcemanager::UnitConfig unitConfig; + aos::sm::resourcemanager::NodeConfig nodeConfig; aos::String jsonStr(cTestNodeConfigJSON); - auto err = provider.ParseNodeUnitConfig(jsonStr, unitConfig); + auto err = provider.ParseNodeConfig(jsonStr, nodeConfig); - zassert_true(err.IsNone(), "Failed to parse node unit config: %s", err.Message()); - zassert_equal(1, unitConfig.mNodeUnitConfig.mPriority, "Priority mismatch"); - zassert_true(strncmp("1.0", unitConfig.mVendorVersion.CStr(), unitConfig.mVendorVersion.Size()) == 0, + zassert_true(err.IsNone(), "Failed to parse node config: %s", err.Message()); + zassert_equal(1, nodeConfig.mNodeConfig.mPriority, "Priority mismatch"); + zassert_true(strncmp("1.0", nodeConfig.mVendorVersion.CStr(), nodeConfig.mVendorVersion.Size()) == 0, "File content mismatch"); zassert_true( - strncmp("mainType", unitConfig.mNodeUnitConfig.mNodeType.CStr(), unitConfig.mNodeUnitConfig.mNodeType.Size()) - == 0, + strncmp("mainType", nodeConfig.mNodeConfig.mNodeType.CStr(), nodeConfig.mNodeConfig.mNodeType.Size()) == 0, "Node type mismatch"); } -ZTEST(resourcemanager, test_DumpUnitConfig) +ZTEST(resourcemanager, test_DumpNodeConfig) { aos::Log::SetCallback(TestLogCallback); ResourceManagerJSONProvider provider; - aos::sm::resourcemanager::UnitConfig unitConfig; - unitConfig.mNodeUnitConfig.mPriority = 1; - unitConfig.mVendorVersion = "1.0"; - unitConfig.mNodeUnitConfig.mNodeType = "mainType"; + aos::sm::resourcemanager::NodeConfig nodeConfig; + nodeConfig.mNodeConfig.mPriority = 1; + nodeConfig.mVendorVersion = "1.0"; + nodeConfig.mNodeConfig.mNodeType = "mainType"; aos::StaticString<1024> jsonStr; - auto err = provider.DumpUnitConfig(unitConfig, jsonStr); + auto err = provider.DumpNodeConfig(nodeConfig, jsonStr); - zassert_true(err.IsNone(), "Failed to dump node unit config: %s", err.Message()); + zassert_true(err.IsNone(), "Failed to dump node config: %s", err.Message()); zassert_false(jsonStr.IsEmpty(), "Empty json string"); - aos::sm::resourcemanager::UnitConfig parsedUnitConfig; - err = provider.ParseNodeUnitConfig(jsonStr, parsedUnitConfig); + aos::sm::resourcemanager::NodeConfig parsednodeConfig; + err = provider.ParseNodeConfig(jsonStr, parsednodeConfig); - zassert_true(err.IsNone(), "Failed to parse node unit config: %s", err.Message()); - zassert_true(unitConfig.mNodeUnitConfig == parsedUnitConfig.mNodeUnitConfig, "Parsed node unit config mismatch"); + zassert_true(err.IsNone(), "Failed to parse node config: %s", err.Message()); + zassert_true(nodeConfig.mNodeConfig == parsednodeConfig.mNodeConfig, "Parsed node config mismatch"); zassert_true( - unitConfig.mVendorVersion == parsedUnitConfig.mVendorVersion, "Parsed unit config vendor version mismatch"); + nodeConfig.mVendorVersion == parsednodeConfig.mVendorVersion, "Parsed unit config vendor version mismatch"); } From 3c6194be1df6b8b96cc8ba9b138400ed2aa8da01 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Mon, 12 Aug 2024 17:26:06 +0300 Subject: [PATCH 021/198] [resourcemanager] Add resourcemanager namespace Signed-off-by: Mykhailo Lohvynenko --- src/app/app.hpp | 52 +++++++++++------------ src/resourcemanager/resourcemanager.cpp | 55 +++++++++++++++---------- src/resourcemanager/resourcemanager.hpp | 41 +++++++++--------- tests/resourcemanager/src/main.cpp | 8 ++-- 4 files changed, 82 insertions(+), 74 deletions(-) diff --git a/src/app/app.hpp b/src/app/app.hpp index 7b17780a..890f5064 100644 --- a/src/app/app.hpp +++ b/src/app/app.hpp @@ -60,32 +60,32 @@ class App : private aos::NonCopyable { aos::Error InitCertHandler(); aos::Error InitCommunication(); - static App sApp; - aos::monitoring::ResourceMonitor mResourceMonitor; - aos::sm::launcher::Launcher mLauncher; - aos::sm::servicemanager::ServiceManager mServiceManager; - aos::iam::certhandler::CertModule mIAMCertModule; - aos::iam::certhandler::PKCS11Module mIAMHSMModule; - aos::iam::certhandler::CertModule mSMCertModule; - aos::iam::certhandler::PKCS11Module mSMHSMModule; - aos::iam::certhandler::CertHandler mCertHandler; - aos::crypto::MbedTLSCryptoProvider mCryptoProvider; - aos::cryptoutils::CertLoader mCertLoader; - aos::pkcs11::PKCS11Manager mPKCS11Manager; - ClockSync mClockSync; - Downloader mDownloader; - OCISpec mJsonOciSpec; - ResourceManagerJSONProvider mResourceManagerJSONProvider; - HostDeviceManager mHostDeviceManager; - HostGroupManager mHostGroupManager; - aos::sm::resourcemanager::ResourceManager mResourceManager; - ResourceUsageProvider mResourceUsageProvider; - Runner mRunner; - Storage mStorage; - Provisioning mProvisioning; - smclient::SMClient mSMClient; - communication::ChannelManager mChannelManager; - communication::XenVChan mTransport; + static App sApp; + aos::monitoring::ResourceMonitor mResourceMonitor; + aos::sm::launcher::Launcher mLauncher; + aos::sm::servicemanager::ServiceManager mServiceManager; + aos::iam::certhandler::CertModule mIAMCertModule; + aos::iam::certhandler::PKCS11Module mIAMHSMModule; + aos::iam::certhandler::CertModule mSMCertModule; + aos::iam::certhandler::PKCS11Module mSMHSMModule; + aos::iam::certhandler::CertHandler mCertHandler; + aos::crypto::MbedTLSCryptoProvider mCryptoProvider; + aos::cryptoutils::CertLoader mCertLoader; + aos::pkcs11::PKCS11Manager mPKCS11Manager; + ClockSync mClockSync; + Downloader mDownloader; + OCISpec mJsonOciSpec; + aos::zephyr::resourcemanager::JSONProvider mResourceManagerJSONProvider; + aos::zephyr::resourcemanager::HostDeviceManager mHostDeviceManager; + aos::zephyr::resourcemanager::HostGroupManager mHostGroupManager; + aos::sm::resourcemanager::ResourceManager mResourceManager; + ResourceUsageProvider mResourceUsageProvider; + Runner mRunner; + Storage mStorage; + Provisioning mProvisioning; + smclient::SMClient mSMClient; + communication::ChannelManager mChannelManager; + communication::XenVChan mTransport; }; } // namespace aos::zephyr::app diff --git a/src/resourcemanager/resourcemanager.cpp b/src/resourcemanager/resourcemanager.cpp index b3a86191..a64173b2 100644 --- a/src/resourcemanager/resourcemanager.cpp +++ b/src/resourcemanager/resourcemanager.cpp @@ -10,10 +10,21 @@ #include "log.hpp" #include "resourcemanager.hpp" +namespace aos::zephyr::resourcemanager { + /*********************************************************************************************************************** * Static **********************************************************************************************************************/ +/** + * Node config. + */ +struct NodeConfig { + const char* vendorVersion = ""; + const char* nodeType = ""; + uint32_t priority = 0; +}; + static const struct json_obj_descr cNodeConfigDescr[] = { JSON_OBJ_DESCR_PRIM(NodeConfig, vendorVersion, JSON_TOK_STRING), JSON_OBJ_DESCR_PRIM(NodeConfig, nodeType, JSON_TOK_STRING), @@ -21,21 +32,20 @@ static const struct json_obj_descr cNodeConfigDescr[] = { }; /*********************************************************************************************************************** - * ResourceManagerJSONProvider + * JSONProvider **********************************************************************************************************************/ /*********************************************************************************************************************** * Public **********************************************************************************************************************/ // cppcheck-suppress unusedFunction -aos::Error ResourceManagerJSONProvider::DumpNodeConfig( - const aos::sm::resourcemanager::NodeConfig& config, aos::String& json) const +Error JSONProvider::DumpNodeConfig(const sm::resourcemanager::NodeConfig& config, String& json) const { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); mAllocator.Clear(); - auto jsonNodeConfig = aos::MakeUnique(&mAllocator); + auto jsonNodeConfig = MakeUnique(&mAllocator); jsonNodeConfig->vendorVersion = config.mVendorVersion.CStr(); jsonNodeConfig->nodeType = config.mNodeConfig.mNodeType.CStr(); @@ -52,21 +62,20 @@ aos::Error ResourceManagerJSONProvider::DumpNodeConfig( return AOS_ERROR_WRAP(err); } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -aos::Error ResourceManagerJSONProvider::ParseNodeConfig( - const aos::String& json, aos::sm::resourcemanager::NodeConfig& config) const +Error JSONProvider::ParseNodeConfig(const String& json, sm::resourcemanager::NodeConfig& config) const { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); mAllocator.Clear(); // json_object_parse mutates the input string, so we need to copy it mJSONBuffer = json; - auto parsedNodeConfig = aos::MakeUnique(&mAllocator); + auto parsedNodeConfig = MakeUnique(&mAllocator); auto ret = json_obj_parse( mJSONBuffer.Get(), mJSONBuffer.Size(), cNodeConfigDescr, ARRAY_SIZE(cNodeConfigDescr), parsedNodeConfig.Get()); @@ -78,7 +87,7 @@ aos::Error ResourceManagerJSONProvider::ParseNodeConfig( config.mNodeConfig.mNodeType = parsedNodeConfig->nodeType; config.mNodeConfig.mPriority = parsedNodeConfig->priority; - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } /*********************************************************************************************************************** @@ -89,43 +98,43 @@ aos::Error ResourceManagerJSONProvider::ParseNodeConfig( **********************************************************************************************************************/ // cppcheck-suppress unusedFunction -aos::Error HostDeviceManager::AllocateDevice(const aos::DeviceInfo& deviceInfo, const aos::String& instanceID) +Error HostDeviceManager::AllocateDevice(const DeviceInfo& deviceInfo, const String& instanceID) { (void)deviceInfo; (void)instanceID; - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -aos::Error HostDeviceManager::RemoveInstanceFromDevice(const aos::String& deviceName, const aos::String& instanceID) +Error HostDeviceManager::RemoveInstanceFromDevice(const String& deviceName, const String& instanceID) { (void)deviceName; (void)instanceID; - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -aos::Error HostDeviceManager::RemoveInstanceFromAllDevices(const aos::String& instanceID) +Error HostDeviceManager::RemoveInstanceFromAllDevices(const String& instanceID) { (void)instanceID; - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -aos::Error HostDeviceManager::GetDeviceInstances( - const aos::String& deviceName, aos::Array>& instanceIDs) const +Error HostDeviceManager::GetDeviceInstances( + const String& deviceName, Array>& instanceIDs) const { (void)deviceName; (void)instanceIDs; - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -bool HostDeviceManager::DeviceExists(const aos::String& device) const +bool HostDeviceManager::DeviceExists(const String& device) const { (void)device; @@ -140,9 +149,11 @@ bool HostDeviceManager::DeviceExists(const aos::String& device) const **********************************************************************************************************************/ // cppcheck-suppress unusedFunction -bool HostGroupManager::GroupExists(const aos::String& group) const +bool HostGroupManager::GroupExists(const String& group) const { (void)group; return false; } + +} // namespace aos::zephyr::resourcemanager diff --git a/src/resourcemanager/resourcemanager.hpp b/src/resourcemanager/resourcemanager.hpp index 236c09d2..2e477cc1 100644 --- a/src/resourcemanager/resourcemanager.hpp +++ b/src/resourcemanager/resourcemanager.hpp @@ -13,16 +13,12 @@ #include #include +namespace aos::zephyr::resourcemanager { + /** - * Node config. + * JSON provider. */ -struct NodeConfig { - const char* vendorVersion = ""; - const char* nodeType = ""; - uint32_t priority = 0; -}; - -class ResourceManagerJSONProvider : public aos::sm::resourcemanager::JSONProviderItf { +class JSONProvider : public sm::resourcemanager::JSONProviderItf { public: /** * Dumps config object into string. @@ -31,7 +27,7 @@ class ResourceManagerJSONProvider : public aos::sm::resourcemanager::JSONProvide * @param[out] json json representation of config. * @return Error. */ - aos::Error DumpNodeConfig(const aos::sm::resourcemanager::NodeConfig& config, aos::String& json) const override; + Error DumpNodeConfig(const sm::resourcemanager::NodeConfig& config, String& json) const override; /** * Parses config object from string. @@ -40,22 +36,22 @@ class ResourceManagerJSONProvider : public aos::sm::resourcemanager::JSONProvide * @param[out] config config. * @return Error. */ - aos::Error ParseNodeConfig(const aos::String& json, aos::sm::resourcemanager::NodeConfig& config) const override; + Error ParseNodeConfig(const String& json, sm::resourcemanager::NodeConfig& config) const override; private: static constexpr size_t cJsonMaxContentLen = 1024; static constexpr size_t cAllocationSize = 2048; static constexpr size_t cMaxNumAllocations = 32; - mutable aos::Mutex mMutex; - mutable aos::StaticString mJSONBuffer; - mutable aos::StaticAllocator mAllocator; + mutable Mutex mMutex; + mutable StaticString mJSONBuffer; + mutable StaticAllocator mAllocator; }; /** * Host device manager. */ -class HostDeviceManager : public aos::sm::resourcemanager::HostDeviceManagerItf { +class HostDeviceManager : public sm::resourcemanager::HostDeviceManagerItf { public: /** * Allocates device for instance. @@ -64,7 +60,7 @@ class HostDeviceManager : public aos::sm::resourcemanager::HostDeviceManagerItf * @param instanceID instance ID. * @return Error. */ - aos::Error AllocateDevice(const aos::DeviceInfo& deviceInfo, const aos::String& instanceID) override; + Error AllocateDevice(const DeviceInfo& deviceInfo, const String& instanceID) override; /** * Removes instance from device. @@ -73,7 +69,7 @@ class HostDeviceManager : public aos::sm::resourcemanager::HostDeviceManagerItf * @param instanceID instance ID. * @return Error. */ - aos::Error RemoveInstanceFromDevice(const aos::String& deviceName, const aos::String& instanceID) override; + Error RemoveInstanceFromDevice(const String& deviceName, const String& instanceID) override; /** * Removes instance from all devices. @@ -81,7 +77,7 @@ class HostDeviceManager : public aos::sm::resourcemanager::HostDeviceManagerItf * @param instanceID instance ID. * @return Error. */ - aos::Error RemoveInstanceFromAllDevices(const aos::String& instanceID) override; + Error RemoveInstanceFromAllDevices(const String& instanceID) override; /** * Returns ID list of instances that allocate specific device. @@ -90,8 +86,7 @@ class HostDeviceManager : public aos::sm::resourcemanager::HostDeviceManagerItf * @param instances[out] param to store instance ID(s). * @return Error. */ - aos::Error GetDeviceInstances( - const aos::String& deviceName, aos::Array>& instanceIDs) const override; + Error GetDeviceInstances(const String& deviceName, Array>& instanceIDs) const override; /** * Checks if device exists. @@ -99,13 +94,13 @@ class HostDeviceManager : public aos::sm::resourcemanager::HostDeviceManagerItf * @param device device name. * @return true if device exists, false otherwise. */ - bool DeviceExists(const aos::String& device) const override; + bool DeviceExists(const String& device) const override; }; /** * Host group manager. */ -class HostGroupManager : public aos::sm::resourcemanager::HostGroupManagerItf { +class HostGroupManager : public sm::resourcemanager::HostGroupManagerItf { public: /** * Checks if group exists. @@ -113,7 +108,9 @@ class HostGroupManager : public aos::sm::resourcemanager::HostGroupManagerItf { * @param group group name. * @return true if group exists, false otherwise. */ - bool GroupExists(const aos::String& group) const override; + bool GroupExists(const String& group) const override; }; +} // namespace aos::zephyr::resourcemanager + #endif diff --git a/tests/resourcemanager/src/main.cpp b/tests/resourcemanager/src/main.cpp index a7e10e75..7346e8a5 100644 --- a/tests/resourcemanager/src/main.cpp +++ b/tests/resourcemanager/src/main.cpp @@ -26,8 +26,8 @@ ZTEST(resourcemanager, test_JSONProviderParse) { aos::Log::SetCallback(TestLogCallback); - ResourceManagerJSONProvider provider; - aos::sm::resourcemanager::NodeConfig nodeConfig; + aos::zephyr::resourcemanager::JSONProvider provider; + aos::sm::resourcemanager::NodeConfig nodeConfig; aos::String jsonStr(cTestNodeConfigJSON); auto err = provider.ParseNodeConfig(jsonStr, nodeConfig); @@ -45,8 +45,8 @@ ZTEST(resourcemanager, test_DumpNodeConfig) { aos::Log::SetCallback(TestLogCallback); - ResourceManagerJSONProvider provider; - aos::sm::resourcemanager::NodeConfig nodeConfig; + aos::zephyr::resourcemanager::JSONProvider provider; + aos::sm::resourcemanager::NodeConfig nodeConfig; nodeConfig.mNodeConfig.mPriority = 1; nodeConfig.mVendorVersion = "1.0"; nodeConfig.mNodeConfig.mNodeType = "mainType"; From 8ac9443f8071dfd0e97d5c7e95fdd6928eca8b57 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 5 Aug 2024 21:56:33 +0300 Subject: [PATCH 022/198] [clocksync] Implement clock sync notification subscriber Signed-off-by: Oleksandr Grytsov --- src/app/app.hpp | 2 +- src/clocksync/clocksync.cpp | 73 +++++++++++--- src/clocksync/clocksync.hpp | 95 ++++++++++++++----- tests/clocksync/CMakeLists.txt | 9 +- tests/clocksync/prj.conf | 2 +- tests/clocksync/src/main.cpp | 73 +++++--------- .../sendermock.hpp => stubs/senderstub.hpp} | 41 ++------ tests/clocksync/src/stubs/subscriberstub.hpp | 63 ++++++++++++ tests/clocksync/testcase.yaml | 2 +- tests/utils/log.cpp | 48 ++++++++++ tests/utils/log.hpp | 15 +++ tests/utils/utils.cpp | 27 ++++++ tests/utils/utils.hpp | 21 ++++ 13 files changed, 341 insertions(+), 130 deletions(-) rename tests/clocksync/src/{mocks/sendermock.hpp => stubs/senderstub.hpp} (56%) create mode 100644 tests/clocksync/src/stubs/subscriberstub.hpp create mode 100644 tests/utils/log.cpp create mode 100644 tests/utils/log.hpp create mode 100644 tests/utils/utils.cpp create mode 100644 tests/utils/utils.hpp diff --git a/src/app/app.hpp b/src/app/app.hpp index 890f5064..60860070 100644 --- a/src/app/app.hpp +++ b/src/app/app.hpp @@ -72,7 +72,7 @@ class App : private aos::NonCopyable { aos::crypto::MbedTLSCryptoProvider mCryptoProvider; aos::cryptoutils::CertLoader mCertLoader; aos::pkcs11::PKCS11Manager mPKCS11Manager; - ClockSync mClockSync; + clocksync::ClockSync mClockSync; Downloader mDownloader; OCISpec mJsonOciSpec; aos::zephyr::resourcemanager::JSONProvider mResourceManagerJSONProvider; diff --git a/src/clocksync/clocksync.cpp b/src/clocksync/clocksync.cpp index ee7babb6..e5f6d715 100644 --- a/src/clocksync/clocksync.cpp +++ b/src/clocksync/clocksync.cpp @@ -8,11 +8,13 @@ #include "clocksync.hpp" #include "log.hpp" +namespace aos::zephyr::clocksync { + /*********************************************************************************************************************** * Public **********************************************************************************************************************/ -aos::Error ClockSync::Init(ClockSyncSenderItf& sender) +Error ClockSync::Init(ClockSyncSenderItf& sender) { LOG_DBG() << "Init clock sync"; @@ -20,7 +22,7 @@ aos::Error ClockSync::Init(ClockSyncSenderItf& sender) auto err = mThread.Run([this](void*) { while (true) { - aos::UniqueLock lock(mMutex); + UniqueLock lock {mMutex}; #ifdef CONFIG_NATIVE_APPLICATION auto now = aos::Time::Now(); @@ -41,21 +43,21 @@ aos::Error ClockSync::Init(ClockSyncSenderItf& sender) if (mSync) { mSync = false; - mSyncTime = aos::Time::Now(CLOCK_MONOTONIC); + mSyncTime = Time::Now(CLOCK_MONOTONIC); if (!mSynced) { mSynced = true; - mSender->ClockSynced(); + ClockSyncNotification(); } continue; } - if (mSynced && abs(aos::Time::Now(CLOCK_MONOTONIC).Sub(mSyncTime)) > cSyncTimeout) { + if (mSynced && abs(Time::Now(CLOCK_MONOTONIC).Sub(mSyncTime)) > cSyncTimeout) { LOG_WRN() << "Time is not synced"; mSynced = false; - mSender->ClockUnsynced(); + ClockSyncNotification(); } if (mStarted) { @@ -70,28 +72,28 @@ aos::Error ClockSync::Init(ClockSyncSenderItf& sender) return AOS_ERROR_WRAP(err); } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error ClockSync::Start() +Error ClockSync::Start() { - aos::LockGuard lock(mMutex); + LockGuard lock {mMutex}; LOG_DBG() << "Start"; mStart = true; mCondVar.NotifyOne(); - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error ClockSync::Sync(const aos::Time& time) +Error ClockSync::Sync(const Time& time) { - aos::LockGuard lock(mMutex); + LockGuard lock {mMutex}; LOG_DBG() << "Sync: time = " << time; - if (llabs(aos::Time::Now().Sub(time)) > cMaxTimeDiff) { + if (llabs(Time::Now().Sub(time)) > cMaxTimeDiff) { LOG_DBG() << "Set time: time = " << time; auto ts = time.UnixTime(); @@ -105,13 +107,35 @@ aos::Error ClockSync::Sync(const aos::Time& time) mSync = true; mCondVar.NotifyOne(); - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; +} + +Error ClockSync::Subscribe(ClockSyncSubscriberItf& subscriber) +{ + LockGuard lock {mMutex}; + + auto err = mConnectionSubscribers.PushBack(&subscriber); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + return ErrorEnum::eNone; +} + +void ClockSync::Unsubscribe(ClockSyncSubscriberItf& subscriber) +{ + LockGuard lock {mMutex}; + + auto it = mConnectionSubscribers.Find(&subscriber); + if (it.mError.IsNone()) { + mConnectionSubscribers.Remove(it.mValue); + } } ClockSync::~ClockSync() { { - aos::LockGuard lock(mMutex); + LockGuard lock {mMutex}; mClose = true; mCondVar.NotifyOne(); @@ -119,3 +143,22 @@ ClockSync::~ClockSync() mThread.Join(); } + +/*********************************************************************************************************************** + * Private + **********************************************************************************************************************/ + +void ClockSync::ClockSyncNotification() +{ + LOG_INF() << "Clock sync notification: synced=" << (mSynced ? "true" : "false"); + + for (auto& subscriber : mConnectionSubscribers) { + if (mSynced) { + subscriber->OnClockSynced(); + } else { + subscriber->OnClockUnsynced(); + } + } +} + +} // namespace aos::zephyr::clocksync diff --git a/src/clocksync/clocksync.hpp b/src/clocksync/clocksync.hpp index 1a756797..0578d218 100644 --- a/src/clocksync/clocksync.hpp +++ b/src/clocksync/clocksync.hpp @@ -10,6 +10,8 @@ #include +namespace aos::zephyr::clocksync { + /** * Clock sync sender interface. */ @@ -26,16 +28,24 @@ class ClockSyncSenderItf { * @return aos::Error. */ virtual aos::Error SendClockSyncRequest() = 0; +}; + +class ClockSyncSubscriberItf { +public: + /** + * Destructor. + */ + virtual ~ClockSyncSubscriberItf() = default; /** - * Notifies sender that clock is synced. + * Notifies subscriber clock is synced. */ - virtual void ClockSynced() = 0; + virtual void OnClockSynced() = 0; /** - * Notifies sender that clock is unsynced. + * Notifies subscriber clock is unsynced. */ - virtual void ClockUnsynced() = 0; + virtual void OnClockUnsynced() = 0; }; /** @@ -53,7 +63,7 @@ class ClockSyncItf { * * @return aos::Error. */ - virtual aos::Error Start() = 0; + virtual Error Start() = 0; /** * Synchronizes system clock. @@ -61,7 +71,21 @@ class ClockSyncItf { * @param time current time to set. * @return aos::Error */ - virtual aos::Error Sync(const aos::Time& time) = 0; + virtual Error Sync(const aos::Time& time) = 0; + + /** + * Subscribes for clock sync notifications. + * + * @param subscriber clock sync notification subscriber. + */ + virtual Error Subscribe(ClockSyncSubscriberItf& subscriber) = 0; + + /** + * Unsubscribes from clock sync notifications. + * + * @param subscriber clock sync notification subscriber. + */ + virtual void Unsubscribe(ClockSyncSubscriberItf& subscriber) = 0; }; /** @@ -76,43 +100,66 @@ class ClockSync : public ClockSyncItf { /** * Initializes clock sync instance. + * * @param sender sender. - * @return aos::Error. + * @return Error. */ - aos::Error Init(ClockSyncSenderItf& sender); + Error Init(ClockSyncSenderItf& sender); /** * Starts clock sync. * - * @return aos::Error. + * @return Error. */ - aos::Error Start() override; + Error Start() override; /** * Synchronizes system clock. * * @param time current time to set. - * @return aos::Error + * @return Error + */ + Error Sync(const Time& time) override; + + /** + * Subscribes for clock sync notifications. + * + * @param subscriber clock sync notification subscriber. + * @return Error. */ - aos::Error Sync(const aos::Time& time) override; + Error Subscribe(ClockSyncSubscriberItf& subscriber) override; + + /** + * Unsubscribes from clock sync notifications. + * + * @param subscriber clock sync notification subscriber. + */ + void Unsubscribe(ClockSyncSubscriberItf& subscriber) override; private: - static constexpr auto cSendPeriod = CONFIG_AOS_CLOCK_SYNC_SEND_PERIOD_SEC * aos::Time::cSeconds; - static constexpr auto cSyncTimeout = CONFIG_AOS_CLOCK_SYNC_TIMEOUT_SEC * aos::Time::cSeconds; - static constexpr auto cMaxTimeDiff = CONFIG_AOS_CLOCK_SYNC_MAX_DIFF_MSEC * aos::Time::cMilliseconds; + static constexpr auto cSendPeriod = CONFIG_AOS_CLOCK_SYNC_SEND_PERIOD_SEC * Time::cSeconds; + static constexpr auto cSyncTimeout = CONFIG_AOS_CLOCK_SYNC_TIMEOUT_SEC * Time::cSeconds; + static constexpr auto cMaxTimeDiff = CONFIG_AOS_CLOCK_SYNC_MAX_DIFF_MSEC * Time::cMilliseconds; + static constexpr auto cMaxSubscribers = 2; + + void ClockSyncNotification(); ClockSyncSenderItf* mSender {}; - aos::Thread<> mThread; - aos::Mutex mMutex; - aos::ConditionalVariable mCondVar; + Thread<> mThread; + Mutex mMutex; + ConditionalVariable mCondVar; + + Time mSyncTime; + bool mSync = false; + bool mSynced = false; + bool mStart = false; + bool mStarted = false; + bool mClose = false; - aos::Time mSyncTime; - bool mSync = false; - bool mSynced = false; - bool mStart = false; - bool mStarted = false; - bool mClose = false; + StaticArray mConnectionSubscribers; }; +} // namespace aos::zephyr::clocksync + #endif diff --git a/tests/clocksync/CMakeLists.txt b/tests/clocksync/CMakeLists.txt index 9d74337f..2d2d9ba1 100644 --- a/tests/clocksync/CMakeLists.txt +++ b/tests/clocksync/CMakeLists.txt @@ -22,12 +22,13 @@ add_definitions(-include ${AOS_CORE_CONFIG}) # Includes # ###################################################################################################################### -target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../src) -target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../../aos_core_lib_cpp/include) -target_include_directories(app PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/..) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/../../src) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/../../../aos_core_lib_cpp/include) +zephyr_include_directories(${CMAKE_CURRENT_BINARY_DIR}) # ###################################################################################################################### # Target # ###################################################################################################################### -target_sources(app PRIVATE src/main.cpp ../../src/clocksync/clocksync.cpp) +target_sources(app PRIVATE src/main.cpp ../utils/log.cpp ../utils/utils.cpp ../../src/clocksync/clocksync.cpp) diff --git a/tests/clocksync/prj.conf b/tests/clocksync/prj.conf index 490052cf..6dd50b2e 100644 --- a/tests/clocksync/prj.conf +++ b/tests/clocksync/prj.conf @@ -1,6 +1,6 @@ # Enable C++ CONFIG_CPP=y -CONFIG_STD_CPP14=y +CONFIG_STD_CPP17=y CONFIG_EXTERNAL_LIBCPP=y CONFIG_CBPRINTF_FP_SUPPORT=y diff --git a/tests/clocksync/src/main.cpp b/tests/clocksync/src/main.cpp index 96c1e7b3..eaf97965 100644 --- a/tests/clocksync/src/main.cpp +++ b/tests/clocksync/src/main.cpp @@ -12,7 +12,12 @@ #include "clocksync/clocksync.hpp" -#include "mocks/sendermock.hpp" +#include "stubs/senderstub.hpp" +#include "stubs/subscriberstub.hpp" +#include "utils/log.hpp" +#include "utils/utils.hpp" + +using namespace aos::zephyr::clocksync; /*********************************************************************************************************************** * Consts @@ -25,50 +30,15 @@ static constexpr auto cWaitTimeout = std::chrono::seconds {5}; **********************************************************************************************************************/ struct clocksync_fixture { - SenderMock mSender; - ClockSync mClockSync; + SenderStub mSender; + SubscriberStub mSubscriber; + ClockSync mClockSync; }; /*********************************************************************************************************************** * Setup **********************************************************************************************************************/ -void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message) -{ - static std::mutex mutex; - static auto startTime = std::chrono::steady_clock::now(); - - std::lock_guard lock(mutex); - - auto now = std::chrono::duration(std::chrono::steady_clock::now() - startTime).count(); - - const char* levelStr = "unknown"; - - switch (level.GetValue()) { - case aos::LogLevelEnum::eDebug: - levelStr = "dbg"; - break; - - case aos::LogLevelEnum::eInfo: - levelStr = "inf"; - break; - - case aos::LogLevelEnum::eWarning: - levelStr = "wrn"; - break; - - case aos::LogLevelEnum::eError: - levelStr = "err"; - break; - - default: - levelStr = "n/d"; - break; - } - - printk("%0.3f [%s] %s\n", now, levelStr, message.CStr()); -} - ZTEST_SUITE( clocksync, nullptr, []() -> void* { @@ -77,7 +47,10 @@ ZTEST_SUITE( auto fixture = new clocksync_fixture; auto err = fixture->mClockSync.Init(fixture->mSender); - zassert_true(err.IsNone(), "Can't initialize clock sync: %s", err.Message()); + zassert_true(err.IsNone(), "Can't initialize clock sync: %s", AosErrorToStr(err)); + + err = fixture->mClockSync.Subscribe(fixture->mSubscriber); + zassert_true(err.IsNone(), "Can't subscribe for clock sync: %s", AosErrorToStr(err)); return fixture; }, @@ -95,31 +68,31 @@ ZTEST_SUITE( ZTEST_F(clocksync, test_Synced) { auto err = fixture->mClockSync.Start(); - zassert_true(err.IsNone(), "Error starting clock sync: %s", err.Message()); + zassert_true(err.IsNone(), "Error starting clock sync: %s", AosErrorToStr(err)); err = fixture->mSender.WaitEvent(cWaitTimeout); - zassert_true(err.IsNone(), "Error waiting sync request: %s", err.Message()); + zassert_true(err.IsNone(), "Error waiting sync request: %s", AosErrorToStr(err)); zassert_true(fixture->mSender.IsSyncRequest()); err = fixture->mClockSync.Sync(aos::Time::Now()); - zassert_true(err.IsNone(), "Error sync clock: %s", err.Message()); + zassert_true(err.IsNone(), "Error sync clock: %s", AosErrorToStr(err)); - err = fixture->mSender.WaitEvent(cWaitTimeout); - zassert_true(err.IsNone(), "Error waiting clock synced: %s", err.Message()); + err = fixture->mSubscriber.WaitEvent(cWaitTimeout); + zassert_true(err.IsNone(), "Error waiting clock synced: %s", AosErrorToStr(err)); - zassert_true(fixture->mSender.IsSynced()); + zassert_true(fixture->mSubscriber.IsSynced()); } ZTEST_F(clocksync, test_Unsynced) { - auto err = fixture->mSender.WaitEvent(cWaitTimeout); - zassert_true(err.IsNone(), "Error waiting clock unsynced: %s", err.Message()); + auto err = fixture->mSubscriber.WaitEvent(cWaitTimeout); + zassert_true(err.IsNone(), "Error waiting clock unsynced: %s", AosErrorToStr(err)); - zassert_true(fixture->mSender.IsSynced()); + zassert_false(fixture->mSubscriber.IsSynced()); err = fixture->mSender.WaitEvent(cWaitTimeout); - zassert_true(err.IsNone(), "Error waiting sync request: %s", err.Message()); + zassert_true(err.IsNone(), "Error waiting sync request: %s", AosErrorToStr(err)); zassert_true(fixture->mSender.IsSyncRequest()); } diff --git a/tests/clocksync/src/mocks/sendermock.hpp b/tests/clocksync/src/stubs/senderstub.hpp similarity index 56% rename from tests/clocksync/src/mocks/sendermock.hpp rename to tests/clocksync/src/stubs/senderstub.hpp index 3df31914..7ad4754b 100644 --- a/tests/clocksync/src/mocks/sendermock.hpp +++ b/tests/clocksync/src/stubs/senderstub.hpp @@ -5,19 +5,19 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef SENDERMOCK_HPP_ -#define SENDERMOCK_HPP_ +#ifndef SENDERSTUB_HPP_ +#define SENDERSTUB_HPP_ #include #include #include "clocksync/clocksync.hpp" -class SenderMock : public ClockSyncSenderItf { +class SenderStub : public aos::zephyr::clocksync::ClockSyncSenderItf { public: aos::Error SendClockSyncRequest() override { - std::lock_guard lock(mMutex); + std::lock_guard lock {mMutex}; mSyncRequest = true; mEventReceived = true; @@ -27,29 +27,9 @@ class SenderMock : public ClockSyncSenderItf { return aos::ErrorEnum::eNone; } - void ClockSynced() override - { - std::lock_guard lock(mMutex); - - mSynced = true; - mEventReceived = true; - - mCV.notify_one(); - } - - void ClockUnsynced() override - { - std::lock_guard lock(mMutex); - - mSynced = false; - mEventReceived = true; - - mCV.notify_one(); - } - aos::Error WaitEvent(const std::chrono::duration timeout) { - std::unique_lock lock(mMutex); + std::unique_lock lock {mMutex}; if (!mCV.wait_for(lock, timeout, [&] { return mEventReceived; })) { return aos::ErrorEnum::eTimeout; @@ -62,19 +42,13 @@ class SenderMock : public ClockSyncSenderItf { bool IsSyncRequest() const { - std::lock_guard lock(mMutex); + std::lock_guard lock {mMutex}; return mSyncRequest; } - bool IsSynced() const - { - std::lock_guard lock(mMutex); - return mSynced; - } - void Clear() { - std::lock_guard lock(mMutex); + std::lock_guard lock {mMutex}; mEventReceived = false; mSyncRequest = false; @@ -85,7 +59,6 @@ class SenderMock : public ClockSyncSenderItf { mutable std::mutex mMutex; bool mEventReceived = false; bool mSyncRequest = false; - bool mSynced = false; }; #endif diff --git a/tests/clocksync/src/stubs/subscriberstub.hpp b/tests/clocksync/src/stubs/subscriberstub.hpp new file mode 100644 index 00000000..ee4c3064 --- /dev/null +++ b/tests/clocksync/src/stubs/subscriberstub.hpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SUBSCRIBERSTUB_HPP_ +#define SUBSCRIBERSTUB_HPP_ + +#include +#include + +#include "clocksync/clocksync.hpp" + +class SubscriberStub : public aos::zephyr::clocksync::ClockSyncSubscriberItf { +public: + void OnClockSynced() override + { + std::lock_guard lock {mMutex}; + + mEventReceived = true; + mSynced = true; + mCV.notify_one(); + } + + void OnClockUnsynced() override + { + std::lock_guard lock {mMutex}; + + mEventReceived = true; + mSynced = false; + mCV.notify_one(); + } + + aos::Error WaitEvent(const std::chrono::duration timeout) + { + std::unique_lock lock {mMutex}; + + if (!mCV.wait_for(lock, timeout, [&] { return mEventReceived; })) { + return aos::ErrorEnum::eTimeout; + } + + mEventReceived = false; + + return aos::ErrorEnum::eNone; + } + + bool IsSynced() const + { + std::lock_guard lock {mMutex}; + + return mSynced; + } + +private: + std::condition_variable mCV; + mutable std::mutex mMutex; + bool mSynced = false; + bool mEventReceived = false; +}; + +#endif diff --git a/tests/clocksync/testcase.yaml b/tests/clocksync/testcase.yaml index 0dd1ff35..884a73ac 100644 --- a/tests/clocksync/testcase.yaml +++ b/tests/clocksync/testcase.yaml @@ -1,5 +1,5 @@ tests: aoszephyrapp.clocksync: - tags: storage + tags: clocksync timeout: 500 platform_allow: native_posix_64 native_posix diff --git a/tests/utils/log.cpp b/tests/utils/log.cpp new file mode 100644 index 00000000..941ee015 --- /dev/null +++ b/tests/utils/log.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +#include "log.hpp" + +void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message) +{ + static std::mutex mutex; + static auto startTime = std::chrono::steady_clock::now(); + + std::lock_guard lock {mutex}; + + auto now = std::chrono::duration(std::chrono::steady_clock::now() - startTime).count(); + + const char* levelStr = "unknown"; + + switch (level.GetValue()) { + case aos::LogLevelEnum::eDebug: + levelStr = "dbg"; + break; + + case aos::LogLevelEnum::eInfo: + levelStr = "inf"; + break; + + case aos::LogLevelEnum::eWarning: + levelStr = "wrn"; + break; + + case aos::LogLevelEnum::eError: + levelStr = "err"; + break; + + default: + levelStr = "n/d"; + break; + } + + printk("%0.3f (%s) [%s] %s\n", now, module, levelStr, message.CStr()); +} diff --git a/tests/utils/log.hpp b/tests/utils/log.hpp new file mode 100644 index 00000000..0cd4a60f --- /dev/null +++ b/tests/utils/log.hpp @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _UTILS_LOG_HPP +#define _UTILS_LOG_HPP + +#include + +void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message); + +#endif diff --git a/tests/utils/utils.cpp b/tests/utils/utils.cpp new file mode 100644 index 00000000..8212acb7 --- /dev/null +++ b/tests/utils/utils.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "utils.hpp" + +/*********************************************************************************************************************** + * Static + **********************************************************************************************************************/ + +aos::StaticString<256> sErrorStr; + +/*********************************************************************************************************************** + * Public + **********************************************************************************************************************/ + +const char* AosErrorToStr(const aos::Error& err) +{ + sErrorStr.Convert(err); + + return sErrorStr.CStr(); +} diff --git a/tests/utils/utils.hpp b/tests/utils/utils.hpp new file mode 100644 index 00000000..e4edb837 --- /dev/null +++ b/tests/utils/utils.hpp @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _TEST_UTILS_HPP +#define _TEST_UTILS_HPP + +#include + +/** + * Converts Aos error to string. + * + * @param err aos error. + * @return const char* + */ +const char* AosErrorToStr(const aos::Error& err); + +#endif From 60cbf190b528a3e1084a53c13e8d62dac533aa09 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 9 Aug 2024 19:34:33 +0300 Subject: [PATCH 023/198] [cmake] Make override of protobuf source files Signed-off-by: Oleksandr Grytsov --- cmake/FindCoreAPI.cmake | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cmake/FindCoreAPI.cmake b/cmake/FindCoreAPI.cmake index 376a3813..9f5389f7 100644 --- a/cmake/FindCoreAPI.cmake +++ b/cmake/FindCoreAPI.cmake @@ -25,9 +25,11 @@ find_package(Nanopb REQUIRED) # ###################################################################################################################### # Aos core sources -set(AOS_PROTO_SRC proto/common/v1/common.proto proto/servicemanager/v4/servicemanager.proto - proto/iamanager/v5/iamanager.proto -) +if(NOT DEFINED AOS_PROTO_SRC) + set(AOS_PROTO_SRC proto/common/v1/common.proto proto/servicemanager/v4/servicemanager.proto + proto/iamanager/v5/iamanager.proto + ) +endif() # Protobuf sources set(SYSTEM_PROTO_SRC google/protobuf/timestamp.proto google/protobuf/empty.proto) From 9aa43271ab8563367cf5f9e9731f68ccf458dd34 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 9 Aug 2024 19:35:27 +0300 Subject: [PATCH 024/198] [communication,tests] Remove nanopb lib Signed-off-by: Oleksandr Grytsov --- tests/communication/prj.conf | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/communication/prj.conf b/tests/communication/prj.conf index e77aa792..2faca0e1 100644 --- a/tests/communication/prj.conf +++ b/tests/communication/prj.conf @@ -14,10 +14,6 @@ CONFIG_ZTEST=y CONFIG_DEBUG=y CONFIG_NO_OPTIMIZATIONS=y -# Enable nanopb lib - -CONFIG_NANOPB=y - # Enable mbedtls CONFIG_MBEDTLS=y From 6ef466fb377aa9384cc5484102f72912baaf2076 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 9 Aug 2024 19:38:58 +0300 Subject: [PATCH 025/198] [smclient] Implement open channel handling for time sync Signed-off-by: Oleksandr Grytsov --- CMakeLists.txt | 1 + Kconfig | 9 +- src/communication/pbhandler.cpp | 158 ++++++++++++++++++ src/communication/pbhandler.hpp | 97 +++++++++++ src/logger/logger.cpp | 4 + src/smclient/openhandler.cpp | 116 +++++++++++++ src/smclient/openhandler.hpp | 61 +++++++ src/smclient/smclient.cpp | 53 +++--- src/smclient/smclient.hpp | 73 ++++---- tests/smclient/CMakeLists.txt | 67 ++++++++ tests/smclient/Kconfig | 36 ++++ tests/smclient/prj.conf | 19 +++ tests/smclient/src/main.cpp | 123 ++++++++++++++ tests/smclient/src/stubs/clocksyncstub.hpp | 86 ++++++++++ .../src/stubs/connectionsubscriberstub.hpp | 85 ++++++++++ tests/smclient/testcase.yaml | 6 + tests/stubs/channelmanagerstub.hpp | 54 ++++++ tests/stubs/channelstub.hpp | 129 ++++++++++++++ tests/utils/pbmessages.cpp | 91 ++++++++++ tests/utils/pbmessages.hpp | 40 +++++ 20 files changed, 1254 insertions(+), 54 deletions(-) create mode 100644 src/communication/pbhandler.cpp create mode 100644 src/communication/pbhandler.hpp create mode 100644 src/smclient/openhandler.cpp create mode 100644 src/smclient/openhandler.hpp create mode 100644 tests/smclient/CMakeLists.txt create mode 100644 tests/smclient/Kconfig create mode 100644 tests/smclient/prj.conf create mode 100644 tests/smclient/src/main.cpp create mode 100644 tests/smclient/src/stubs/clocksyncstub.hpp create mode 100644 tests/smclient/src/stubs/connectionsubscriberstub.hpp create mode 100644 tests/smclient/testcase.yaml create mode 100644 tests/stubs/channelmanagerstub.hpp create mode 100644 tests/stubs/channelstub.hpp create mode 100644 tests/utils/pbmessages.cpp create mode 100644 tests/utils/pbmessages.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 038ca438..eca299c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,7 @@ target_sources( src/provisioning/provisioning.cpp src/resourcemanager/resourcemanager.cpp src/runner/runner.cpp + src/smclient/openhandler.cpp src/smclient/smclient.cpp src/storage/storage.cpp src/utils/checksum.cpp diff --git a/Kconfig b/Kconfig index 3d2c8064..8495f672 100644 --- a/Kconfig +++ b/Kconfig @@ -17,7 +17,6 @@ config AOS_VCHAN_RX_PATH string "Path to RX vchan" default "/local/domain/1/tmp/vchan/aos/rx" - config AOS_REBOOT_XEN_STORE_PATH string "Path to user reboot request" default "/local/domain/1/data/user-reboot" @@ -94,6 +93,14 @@ config AOS_ROOT_CA_PATH string "Path to Aos Root CA certificate. Required to build in root CA into app image." default "prebuilt/rootca.pem" +config AOS_SM_OPEN_PORT + int "Aos SM open port" + default 1 + +config AOS_SM_SECURE_PORT + int "Aos SM secure port" + default 2 + config DOMD_UBOOT_PATH string "Location for Domain-D IPL binary" default "prebuilt/ipl.bin" diff --git a/src/communication/pbhandler.cpp b/src/communication/pbhandler.cpp new file mode 100644 index 00000000..57421a74 --- /dev/null +++ b/src/communication/pbhandler.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "pbhandler.hpp" +#include "log.hpp" + +namespace aos::zephyr::communication { + +/*********************************************************************************************************************** + * Public + **********************************************************************************************************************/ + +template +Error PBHandler::Init(const String& name, ChannelItf& channel) +{ + mName = name; + mChannel = &channel; + + return ErrorEnum::eNone; +} + +template +Error PBHandler::Start() +{ + LockGuard lock {mMutex}; + + LOG_DBG() << "Start PB handler: name=" << mName; + + if (mStarted) { + return Error(ErrorEnum::eWrongState, "PB handler already started"); + } + + auto err = mThread.Run([this](void*) { Run(); }); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + mStarted = true; + + return ErrorEnum::eNone; +} + +template +Error PBHandler::Stop() +{ + LOG_DBG() << "Stop PB handler: name=" << mName; + + { + LockGuard lock {mMutex}; + + if (!mStarted) { + return ErrorEnum::eNone; + } + + mStarted = false; + mChannel->Close(); + } + + mThread.Join(); + + return ErrorEnum::eNone; +} + +template +PBHandler::~PBHandler() +{ + Stop(); +} + +/*********************************************************************************************************************** + * Protected + **********************************************************************************************************************/ + +template +Error PBHandler::SendMessage(const void* message, const pb_msgdesc_t* fields) +{ + auto outStream = pb_ostream_from_buffer( + static_cast(static_cast(mSendBuffer.Get()) + sizeof(AosProtobufHeader)), + mSendBuffer.Size() - sizeof(AosProtobufHeader)); + auto header = reinterpret_cast(mSendBuffer.Get()); + + if (message && fields) { + auto status = pb_encode(&outStream, fields, message); + if (!status) { + return AOS_ERROR_WRAP(Error(aos::ErrorEnum::eRuntime, "failed to encode message")); + } + } + + header->mDataSize = outStream.bytes_written; + + auto ret = mChannel->Write(mSendBuffer.Get(), sizeof(AosProtobufHeader) + outStream.bytes_written); + if (ret < 0) { + return AOS_ERROR_WRAP(Error(ret, "failed to write message")); + } + + return ErrorEnum::eNone; +} + +/*********************************************************************************************************************** + * Private + **********************************************************************************************************************/ + +template +void PBHandler::Run() +{ + while (true) { + { + LockGuard lock {mMutex}; + + if (!mStarted) { + break; + } + } + + auto err = mChannel->Connect(); + if (!err.IsNone()) { + LOG_ERR() << "Failed to connect: name=" << mName << ", err=" << err; + continue; + } + + OnConnect(); + + AosProtobufHeader header; + + while (true) { + auto ret = mChannel->Read(&header, sizeof(header)); + if (ret < 0) { + LOG_ERR() << "Failed to read channel: name=" << mName << ", ret=" << ret << ", err=" << strerror(errno); + break; + } + + if (header.mDataSize > mReceiveBuffer.Size()) { + LOG_ERR() << "Not enough mem in receive buffer: name=" << mName; + continue; + } + + if ((ret = mChannel->Read(mReceiveBuffer.Get(), header.mDataSize)) < 0) { + LOG_ERR() << "Failed to read channel: name=" << mName << ", ret=" << ret << ", err=" << strerror(errno); + break; + } + + auto err = ReceiveMessage(Array(static_cast(mReceiveBuffer.Get()), header.mDataSize)); + + if (!err.IsNone()) { + LOG_ERR() << "Receive message error: name=" << mName << ", err=" << err; + continue; + } + } + + OnDisconnect(); + } +} + +} // namespace aos::zephyr::communication diff --git a/src/communication/pbhandler.hpp b/src/communication/pbhandler.hpp new file mode 100644 index 00000000..48c74a0e --- /dev/null +++ b/src/communication/pbhandler.hpp @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef PBHANDLER_HPP_ +#define PBHANDLER_HPP_ + +#include + +#include +#include +#include + +#include "channel.hpp" + +namespace aos::zephyr::communication { + +/** + * Protobuf handler. + */ +template +class PBHandler { +public: + /** + * Initializes protobuf handler. + * + * @param channel communication channel. + * @return Error + */ + Error Init(const String& name, ChannelItf& channel); + + /** + * Starts protobuf handler. + * + * @return Error. + */ + Error Start(); + + /** + * Stops protobuf handler. + * + * @return Error. + */ + Error Stop(); + + /** + * Destructor. + */ + virtual ~PBHandler(); + +protected: + /** + * Connect notification. + */ + virtual void OnConnect() = 0; + + /** + * Disconnect notification. + */ + virtual void OnDisconnect() = 0; + + /** + * Sends protobuf message. + * + * @param message message to send. + * @param fields message fields. + * @return Error. + */ + Error SendMessage(const void* message, const pb_msgdesc_t* fields); + + /** + * Receives protobuf message. + * + * @param data received data. + * @return Error. + */ + virtual Error ReceiveMessage(const Array& data) = 0; + +private: + void Run(); + + StaticString<64> mName; + ChannelItf* mChannel; + Mutex mMutex; + ConditionalVariable mCondVar; + Thread<> mThread; + bool mStarted = false; + aos::StaticBuffer mSendBuffer; + aos::StaticBuffer mReceiveBuffer; +}; + +} // namespace aos::zephyr::communication + +#endif diff --git a/src/logger/logger.cpp b/src/logger/logger.cpp index f9583c00..26318c76 100644 --- a/src/logger/logger.cpp +++ b/src/logger/logger.cpp @@ -21,6 +21,7 @@ static const aos::String cLogModuleOCISpec = "ocispec"; static const aos::String cLogModuleProvisioning = "provisioning"; static const aos::String cLogModuleResourceManager = "resourcemanager"; static const aos::String cLogModuleRunner = "runner"; +static const aos::String cLogModuleSMClient = "smclient"; static const aos::String cLogModuleStorage = "storage"; static const aos::String cLogModuleNodeInfoProvider = "nodeinfoprovider"; @@ -80,6 +81,7 @@ LOG_CALLBACK(ocispec); LOG_CALLBACK(provisioning); LOG_CALLBACK(resourcemanager); LOG_CALLBACK(runner); +LOG_CALLBACK(smclient); LOG_CALLBACK(storage); LOG_CALLBACK(nodeinfoprovider); @@ -124,6 +126,8 @@ void Logger::LogCallback(const char* module, aos::LogLevel level, const aos::Str log_resourcemanager::LogCallback(level, message); } else if (logModule == cLogModuleRunner) { log_runner::LogCallback(level, message); + } else if (logModule == cLogModuleSMClient) { + log_smclient::LogCallback(level, message); } else if (logModule == cLogModuleStorage) { log_storage::LogCallback(level, message); } else if (logModule == cLogModuleNodeInfoProvider) { diff --git a/src/smclient/openhandler.cpp b/src/smclient/openhandler.cpp new file mode 100644 index 00000000..a092f626 --- /dev/null +++ b/src/smclient/openhandler.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "log.hpp" +#include "openhandler.hpp" + +#include "communication/pbhandler.cpp" + +namespace aos::zephyr::smclient { + +/*********************************************************************************************************************** + * Public + **********************************************************************************************************************/ + +Error OpenHandler::Init(communication::ChannelItf& channel, clocksync::ClockSyncItf& clockSync) +{ + auto err = PBHandler::Init("SM open", channel); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + if (!(err = Start()).IsNone()) { + return AOS_ERROR_WRAP(err); + } + + mClockSync = &clockSync; + + return ErrorEnum::eNone; +} + +Error OpenHandler::SendClockSyncRequest() +{ + mOutgoingMessages.SMOutgoingMessage.clock_sync_request + = servicemanager_v4_ClockSyncRequest servicemanager_v4_ClockSyncRequest_init_default; + mOutgoingMessages.which_SMOutgoingMessage = servicemanager_v4_SMOutgoingMessages_clock_sync_request_tag; + + LOG_DBG() << "Send SM message: message=ClockSyncRequest"; + + return SendMessage(&mOutgoingMessages, &servicemanager_v4_SMOutgoingMessages_msg); +} + +OpenHandler::~OpenHandler() +{ + Stop(); +} + +/*********************************************************************************************************************** + * Protected + **********************************************************************************************************************/ + +void OpenHandler::OnConnect() +{ + auto err = mClockSync->Start(); + if (!err.IsNone()) { + LOG_ERR() << "Failed to start clock sync: err=" << err; + } +} + +void OpenHandler::OnDisconnect() +{ +} + +Error OpenHandler::ReceiveMessage(const Array& data) +{ + auto stream = pb_istream_from_buffer(data.Get(), data.Size()); + + auto status = pb_decode(&stream, &servicemanager_v4_SMIncomingMessages_msg, &mIncomingMessages); + if (!status) { + return AOS_ERROR_WRAP(Error(ErrorEnum::eRuntime, "failed to decode message")); + } + + Error err; + + switch (mIncomingMessages.which_SMIncomingMessage) { + case servicemanager_v4_SMIncomingMessages_clock_sync_tag: + if (!(err = ProcessClockSync(mIncomingMessages.SMIncomingMessage.clock_sync)).IsNone()) { + return err; + } + + break; + + default: + LOG_WRN() << "Receive unsupported message: tag=" << mIncomingMessages.which_SMIncomingMessage; + break; + } + + return ErrorEnum::eNone; +} + +/*********************************************************************************************************************** + * Private + **********************************************************************************************************************/ + +Error OpenHandler::ProcessClockSync(const servicemanager_v4_ClockSync& pbClockSync) +{ + LOG_DBG() << "Receive SM message: message=ClockSync"; + + if (!pbClockSync.has_current_time) { + return AOS_ERROR_WRAP(Error(ErrorEnum::eInvalidArgument, "ClockSync message has no current time")); + } + + auto err = mClockSync->Sync(aos::Time::Unix(pbClockSync.current_time.seconds, pbClockSync.current_time.nanos)); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + return aos::ErrorEnum::eNone; +} + +} // namespace aos::zephyr::smclient diff --git a/src/smclient/openhandler.hpp b/src/smclient/openhandler.hpp new file mode 100644 index 00000000..aec0fe49 --- /dev/null +++ b/src/smclient/openhandler.hpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef OPENHANDLER_HPP_ +#define OPENHANDLER_HPP_ + +#include + +#include "clocksync/clocksync.hpp" +#include "communication/channel.hpp" +#include "communication/pbhandler.hpp" + +namespace aos::zephyr::smclient { + +/** + * SM open handler. + */ +class OpenHandler : public communication::PBHandler { +public: + /** + * Initializes open handler. + * + * @param channel communication channel. + * @param clockSync clock sync instance. + * @return Error. + */ + Error Init(communication::ChannelItf& channel, clocksync::ClockSyncItf& clockSync); + + /** + * Sends clock sync request. + * + * @return Error. + */ + Error SendClockSyncRequest(); + + /** + * Destructor. + */ + ~OpenHandler(); + +protected: + void OnConnect() override; + void OnDisconnect() override; + Error ReceiveMessage(const Array& data) override; + +private: + Error ProcessClockSync(const servicemanager_v4_ClockSync& pbClockSync); + + clocksync::ClockSyncItf* mClockSync {}; + servicemanager_v4_SMOutgoingMessages mOutgoingMessages; + servicemanager_v4_SMIncomingMessages mIncomingMessages; +}; + +} // namespace aos::zephyr::smclient + +#endif diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index ec07ca58..236581ea 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -6,6 +6,7 @@ */ #include "smclient.hpp" +#include "log.hpp" namespace aos::zephyr::smclient { @@ -13,53 +14,67 @@ namespace aos::zephyr::smclient { * Public **********************************************************************************************************************/ -aos::Error SMClient::Init(aos::sm::launcher::LauncherItf& launcher, - aos::sm::resourcemanager::ResourceManagerItf& resourceManager, aos::monitoring::ResourceMonitorItf& resourceMonitor, - DownloadReceiverItf& downloader, communication::ChannelManagerItf& channelManager) +Error SMClient::Init(clocksync::ClockSyncItf& clockSync, communication::ChannelManagerItf& channelManager) { - return aos::ErrorEnum::eNone; + LOG_DBG() << "Initialize SM client"; + + auto [openChannel, err] = channelManager.CreateChannel(cOpenPort); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + err = mOpenHandler.Init(*openChannel, clockSync); + if (!err.IsNone()) { + return err; + } + + if (!(err = clockSync.Subscribe(*this)).IsNone()) { + return AOS_ERROR_WRAP(err); + } + + return ErrorEnum::eNone; } -aos::Error SMClient::InstancesRunStatus(const aos::Array& instances) +Error SMClient::InstancesRunStatus(const Array& instances) { - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error SMClient::InstancesUpdateStatus(const aos::Array& instances) +Error SMClient::InstancesUpdateStatus(const Array& instances) { - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error SMClient::SendImageContentRequest(const ImageContentRequest& request) +Error SMClient::SendImageContentRequest(const ImageContentRequest& request) { - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error SMClient::SendMonitoringData(const aos::monitoring::NodeMonitoringData& monitoringData) +Error SMClient::SendMonitoringData(const monitoring::NodeMonitoringData& monitoringData) { - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error SMClient::Subscribes(aos::ConnectionSubscriberItf& subscriber) +Error SMClient::Subscribes(ConnectionSubscriberItf& subscriber) { - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -void SMClient::Unsubscribes(aos::ConnectionSubscriberItf& subscriber) +void SMClient::Unsubscribes(ConnectionSubscriberItf& subscriber) { } -aos::Error SMClient::SendClockSyncRequest() +void SMClient::OnClockSynced() { - return aos::ErrorEnum::eNone; } -void SMClient::ClockSynced() +void SMClient::OnClockUnsynced() { } -void SMClient::ClockUnsynced() +Error SMClient::SendClockSyncRequest() { + return mOpenHandler.SendClockSyncRequest(); } } // namespace aos::zephyr::smclient diff --git a/src/smclient/smclient.hpp b/src/smclient/smclient.hpp index f439334b..046d041c 100644 --- a/src/smclient/smclient.hpp +++ b/src/smclient/smclient.hpp @@ -17,36 +17,34 @@ #include "communication/channelmanager.hpp" #include "downloader/downloader.hpp" +#include "openhandler.hpp" + namespace aos::zephyr::smclient { /** * SM client instance. */ -class SMClient : public aos::sm::launcher::InstanceStatusReceiverItf, +class SMClient : public sm::launcher::InstanceStatusReceiverItf, public DownloadRequesterItf, - public aos::monitoring::SenderItf, - public aos::ConnectionPublisherItf, - public ClockSyncSenderItf, - private aos::NonCopyable { + public monitoring::SenderItf, + public ConnectionPublisherItf, + public clocksync::ClockSyncSenderItf, + public clocksync::ClockSyncSubscriberItf, + private NonCopyable { public: /** * Initializes SM client instance. * - * @param launcher launcher instance. - * @param resourceManager resource manager instance. - * @param resourceMonitor resource monitor instance. - * @param downloader downloader instance. - * @return aos::Error. + * @param clockSync clock sync instance. + * @param channelManager channel manager instance. + * @return Error. */ - aos::Error Init(aos::sm::launcher::LauncherItf& launcher, - aos::sm::resourcemanager::ResourceManagerItf& resourceManager, - aos::monitoring::ResourceMonitorItf& resourceMonitor, DownloadReceiverItf& downloader, - communication::ChannelManagerItf& channelManager); + Error Init(clocksync::ClockSyncItf& clockSync, communication::ChannelManagerItf& channelManager); /** * Destructor. */ - ~SMClient(); + ~SMClient() = default; /** * Sends instances run status. @@ -54,62 +52,69 @@ class SMClient : public aos::sm::launcher::InstanceStatusReceiverItf, * @param instances instances status array. * @return Error. */ - aos::Error InstancesRunStatus(const aos::Array& instances) override; + Error InstancesRunStatus(const Array& instances) override; /** * Sends instances update status. - * @param instances instances status array. * + * @param instances instances status array. * @return Error. */ - aos::Error InstancesUpdateStatus(const aos::Array& instances) override; + Error InstancesUpdateStatus(const Array& instances) override; /** - * Send image content request + * Send image content request. * - * @param request image content request - * @return Error + * @param request image content request. + * @return Error. */ - aos::Error SendImageContentRequest(const ImageContentRequest& request) override; + Error SendImageContentRequest(const ImageContentRequest& request) override; /** - * Sends monitoring data + * Sends monitoring data. * - * @param monitoringData monitoring data - * @return Error + * @param monitoringData monitoring data. + * @return Error. */ - aos::Error SendMonitoringData(const aos::monitoring::NodeMonitoringData& monitoringData) override; + Error SendMonitoringData(const monitoring::NodeMonitoringData& monitoringData) override; /** * Subscribes the provided ConnectionSubscriberItf to this object. * * @param subscriber The ConnectionSubscriberItf that wants to subscribe. + * @return Error. */ - aos::Error Subscribes(aos::ConnectionSubscriberItf& subscriber) override; + Error Subscribes(ConnectionSubscriberItf& subscriber) override; /** * Unsubscribes the provided ConnectionSubscriberItf from this object. * * @param subscriber The ConnectionSubscriberItf that wants to unsubscribe. */ - void Unsubscribes(aos::ConnectionSubscriberItf& subscriber) override; + void Unsubscribes(ConnectionSubscriberItf& subscriber) override; /** * Sends clock sync request. * - * @return aos::Error. + * @return Error. */ - aos::Error SendClockSyncRequest() override; + Error SendClockSyncRequest() override; /** - * Notifies sender that clock is synced. + * Notifies subscriber clock is synced. */ - void ClockSynced() override; + void OnClockSynced() override; /** - * Notifies sender that clock is unsynced. + * Notifies subscriber clock is unsynced. */ - void ClockUnsynced() override; + void OnClockUnsynced() override; + +private: + static constexpr auto cOpenPort = CONFIG_AOS_SM_OPEN_PORT; + static constexpr auto cSecurePort = CONFIG_AOS_SM_SECURE_PORT; + + OpenHandler mOpenHandler; }; } // namespace aos::zephyr::smclient diff --git a/tests/smclient/CMakeLists.txt b/tests/smclient/CMakeLists.txt new file mode 100644 index 00000000..08e55a9a --- /dev/null +++ b/tests/smclient/CMakeLists.txt @@ -0,0 +1,67 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package( + Zephyr + COMPONENTS + REQUIRED HINTS $ENV{ZEPHYR_BASE} +) + +set(CMAKE_MODULE_PATH ${APPLICATION_SOURCE_DIR}/../../cmake) + +project(communication_test) + +# ###################################################################################################################### +# Config +# ###################################################################################################################### + +set(aoscore_config aoscoreconfig.hpp) +set(aoscore_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../../../aos_core_lib_cpp") + +# ###################################################################################################################### +# Definitions +# ###################################################################################################################### + +# Aos core configuration +add_definitions(-include ${aoscore_config}) + +# ###################################################################################################################### +# Includes +# ###################################################################################################################### + +zephyr_include_directories(${aoscore_source_dir}/include) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/..) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/../../src) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src) +zephyr_include_directories(${CMAKE_CURRENT_BINARY_DIR}) +zephyr_include_directories(${CMAKE_CURRENT_BINARY_DIR}/proto) + +# ###################################################################################################################### +# Generate API +# ###################################################################################################################### + +find_package(CoreAPI) + +set(CORE_API_CXX_FLAGS -I${APPLICATION_SOURCE_DIR}/../../src -I${aoscore_source_dir}/include -include + ${CMAKE_CURRENT_BINARY_DIR}/zephyr/include/generated/autoconf.h -include ${aoscore_config} +) + +set(AOS_PROTO_SRC proto/common/v1/common.proto proto/servicemanager/v4/servicemanager.proto) + +core_api_generate(${CMAKE_CURRENT_SOURCE_DIR}/../../../aos_core_api ${CMAKE_CURRENT_SOURCE_DIR}/../../scripts) + +# ###################################################################################################################### +# Target +# ###################################################################################################################### + +target_sources( + app + PRIVATE ../../src/communication/pbhandler.cpp + ../../src/smclient/openhandler.cpp + ../../src/smclient/smclient.cpp + ../utils/log.cpp + ../utils/pbmessages.cpp + ../utils/utils.cpp + src/main.cpp +) diff --git a/tests/smclient/Kconfig b/tests/smclient/Kconfig new file mode 100644 index 00000000..cfcca898 --- /dev/null +++ b/tests/smclient/Kconfig @@ -0,0 +1,36 @@ +# Copyright (C) 2024 Renesas Electronics Corporation. +# Copyright (C) 2024 EPAM Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "Aos zephyr application" + +config AOS_RUNTIME_DIR + string "Aos runtime dir" + default "/aos/runtime" + +config AOS_SERVICES_DIR + string "Aos services dir" + default "/aos/services" + +config AOS_CLOCK_SYNC_SEND_PERIOD_SEC + int "Send clock sync period in seconds" + default 1 + +config AOS_CLOCK_SYNC_TIMEOUT_SEC + int "Clock becomes unsynced if there is no clock sync update during this period." + default 1 + +config AOS_CLOCK_SYNC_MAX_DIFF_MSEC + int "Maximum allowed difference between source and current time." + default 10000 + +config AOS_SM_OPEN_PORT + int "Aos SM open port" + default 1 + +config AOS_SM_SECURE_PORT + int "Aos SM secure port" + default 2 + +source "Kconfig" diff --git a/tests/smclient/prj.conf b/tests/smclient/prj.conf new file mode 100644 index 00000000..74f5898d --- /dev/null +++ b/tests/smclient/prj.conf @@ -0,0 +1,19 @@ +# Enable C++ + +CONFIG_CPP=y +CONFIG_STD_CPP17=y +CONFIG_EXTERNAL_LIBCPP=y +CONFIG_CBPRINTF_FP_SUPPORT=y + +# Enable test suit + +CONFIG_ZTEST=y + +# Enable debug for tests + +CONFIG_DEBUG=y +CONFIG_NO_OPTIMIZATIONS=y + +# Enable nanopb lib + +CONFIG_NANOPB=y diff --git a/tests/smclient/src/main.cpp b/tests/smclient/src/main.cpp new file mode 100644 index 00000000..9ac6647b --- /dev/null +++ b/tests/smclient/src/main.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include + +#include "smclient/smclient.hpp" + +#include "stubs/channelmanagerstub.hpp" +#include "stubs/clocksyncstub.hpp" +#include "utils/log.hpp" +#include "utils/pbmessages.hpp" +#include "utils/utils.hpp" + +using namespace aos::zephyr; + +/*********************************************************************************************************************** + * Consts + **********************************************************************************************************************/ + +static constexpr auto cWaitTimeout = std::chrono::seconds {5}; + +/*********************************************************************************************************************** + * Types + **********************************************************************************************************************/ + +struct smclient_fixture { + ClockSyncStub mClockSync; + ChannelManagerStub mChannelManager; + smclient::SMClient mSMClient; +}; + +/*********************************************************************************************************************** + * Static + **********************************************************************************************************************/ + +static aos::Error ReceiveSMOutgoingMessage(ChannelStub* channel, servicemanager_v4_SMOutgoingMessages& message) +{ + return ReceivePBMessage(channel, cWaitTimeout, &message, servicemanager_v4_SMOutgoingMessages_size, + &servicemanager_v4_SMOutgoingMessages_msg); +} + +static aos::Error SendSMIncomingMessage(ChannelStub* channel, const servicemanager_v4_SMIncomingMessages& message) +{ + return SendPBMessage( + channel, &message, servicemanager_v4_SMIncomingMessages_size, &servicemanager_v4_SMIncomingMessages_msg); +} + +/*********************************************************************************************************************** + * Setup + **********************************************************************************************************************/ + +ZTEST_SUITE( + smclient, nullptr, + []() -> void* { + aos::Log::SetCallback(TestLogCallback); + + auto fixture = new smclient_fixture; + + auto err = fixture->mSMClient.Init(fixture->mClockSync, fixture->mChannelManager); + + zassert_true(err.IsNone(), "Can't initialize SM client: %s", AosErrorToStr(err)); + + return fixture; + }, + nullptr, nullptr, [](void* fixture) { delete static_cast(fixture); }); + +/*********************************************************************************************************************** + * Tests + **********************************************************************************************************************/ + +ZTEST_F(smclient, test_ClockSync) +{ + // Wait clock sync start + + auto err = fixture->mClockSync.WaitEvent(cWaitTimeout); + zassert_true(err.IsNone(), "Error waiting clock sync start: %s", AosErrorToStr(err)); + + zassert_true(fixture->mClockSync.GetStarted()); + + // Wait clock sync request + + err = fixture->mSMClient.SendClockSyncRequest(); + + zassert_true(err.IsNone(), "Error sending clock sync request: %s", AosErrorToStr(err)); + + ChannelStub* channel; + + aos::Tie(channel, err) = fixture->mChannelManager.GetChannel(CONFIG_AOS_SM_OPEN_PORT); + zassert_true(err.IsNone(), "Getting channel error: %s", AosErrorToStr(err)); + + servicemanager_v4_SMOutgoingMessages outgoingMessage servicemanager_v4_SMOutgoingMessages_init_default; + + err = ReceiveSMOutgoingMessage(channel, outgoingMessage); + zassert_true(err.IsNone(), "Error receiving message: %s", AosErrorToStr(err)); + + zassert_equal(outgoingMessage.which_SMOutgoingMessage, servicemanager_v4_SMOutgoingMessages_clock_sync_request_tag); + + // Send clock sync + + servicemanager_v4_SMIncomingMessages incomingMessage servicemanager_v4_SMIncomingMessages_init_default; + + incomingMessage.which_SMIncomingMessage = servicemanager_v4_SMIncomingMessages_clock_sync_tag; + incomingMessage.SMIncomingMessage.clock_sync.has_current_time = true; + incomingMessage.SMIncomingMessage.clock_sync.current_time.seconds = 43; + incomingMessage.SMIncomingMessage.clock_sync.current_time.nanos = 234; + + err = SendSMIncomingMessage(channel, incomingMessage); + zassert_true(err.IsNone(), "Error sending message: %s", AosErrorToStr(err)); + + err = fixture->mClockSync.WaitEvent(cWaitTimeout); + zassert_true(err.IsNone(), "Error waiting clock sync start: %s", AosErrorToStr(err)); + + zassert_equal(fixture->mClockSync.GetSyncTime(), + aos::Time::Unix(incomingMessage.SMIncomingMessage.clock_sync.current_time.seconds, + incomingMessage.SMIncomingMessage.clock_sync.current_time.nanos)); +} diff --git a/tests/smclient/src/stubs/clocksyncstub.hpp b/tests/smclient/src/stubs/clocksyncstub.hpp new file mode 100644 index 00000000..9f48cacc --- /dev/null +++ b/tests/smclient/src/stubs/clocksyncstub.hpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef CLOCKSYNCSTUB_HPP_ +#define CLOCKSYNCSTUB_HPP_ + +#include +#include + +#include "clocksync/clocksync.hpp" + +class ClockSyncStub : public aos::zephyr::clocksync::ClockSyncItf { +public: + aos::Error Start() override + { + std::lock_guard lock(mMutex); + + mStarted = true; + mEventReceived = true; + mCV.notify_one(); + + return aos::ErrorEnum::eNone; + } + + aos::Error Sync(const aos::Time& time) override + { + std::lock_guard lock(mMutex); + + mSyncTime = time; + mEventReceived = true; + mCV.notify_one(); + + return aos::ErrorEnum::eNone; + } + + aos::Error Subscribe(aos::zephyr::clocksync::ClockSyncSubscriberItf& subscriber) { return aos::ErrorEnum::eNone; } + + void Unsubscribe(aos::zephyr::clocksync::ClockSyncSubscriberItf& subscriber) { } + + bool GetStarted() const + { + std::lock_guard lock(mMutex); + return mStarted; + } + + aos::Time GetSyncTime() const + { + std::lock_guard lock(mMutex); + return mSyncTime; + } + + aos::Error WaitEvent(const std::chrono::duration timeout) + { + std::unique_lock lock(mMutex); + + if (!mCV.wait_for(lock, timeout, [&] { return mEventReceived; })) { + return aos::ErrorEnum::eTimeout; + } + + mEventReceived = false; + + return aos::ErrorEnum::eNone; + } + + void Clear() + { + std::lock_guard lock(mMutex); + + mEventReceived = false; + mStarted = false; + mSyncTime = aos::Time(); + } + +private: + std::condition_variable mCV; + mutable std::mutex mMutex; + bool mEventReceived = false; + bool mStarted = false; + aos::Time mSyncTime; +}; + +#endif diff --git a/tests/smclient/src/stubs/connectionsubscriberstub.hpp b/tests/smclient/src/stubs/connectionsubscriberstub.hpp new file mode 100644 index 00000000..7891644d --- /dev/null +++ b/tests/smclient/src/stubs/connectionsubscriberstub.hpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2023 Renesas Electronics Corporation. + * Copyright (C) 2023 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef CONNECTIONSUBSCRIBERSTUB_HPP_ +#define CONNECTIONSUBSCRIBERSTUB_HPP_ + +#include +#include + +#include + +class ConnectionSubscriberStub : public aos::ConnectionSubscriberItf { +public: + void OnConnect() override + { + std::lock_guard lock(mMutex); + + mConnected = true; + mConnect = true; + mCV.notify_one(); + } + + void OnDisconnect() override + { + std::lock_guard lock(mMutex); + + mConnected = false; + mDisconnect = true; + mCV.notify_one(); + } + + aos::Error WaitConnect(const std::chrono::duration& timeout) + { + std::unique_lock lock(mMutex); + + if (!mCV.wait_for(lock, timeout, [&] { return mConnect; })) { + return aos::ErrorEnum::eTimeout; + } + + mConnect = false; + + return aos::ErrorEnum::eNone; + } + + aos::Error WaitDisconnect(const std::chrono::duration& timeout) + { + std::unique_lock lock(mMutex); + + if (!mCV.wait_for(lock, timeout, [&] { return mDisconnect; })) { + return aos::ErrorEnum::eTimeout; + } + + mDisconnect = false; + + return aos::ErrorEnum::eNone; + } + + bool IsConnected() const + { + std::lock_guard lock(mMutex); + return mConnected; + } + + void Clear() + { + std::lock_guard lock(mMutex); + + mConnected = false; + mConnect = false; + mDisconnect = false; + } + +private: + bool mConnected = false; + bool mConnect = false; + bool mDisconnect = false; + std::condition_variable mCV; + mutable std::mutex mMutex; +}; + +#endif diff --git a/tests/smclient/testcase.yaml b/tests/smclient/testcase.yaml new file mode 100644 index 00000000..eae550f1 --- /dev/null +++ b/tests/smclient/testcase.yaml @@ -0,0 +1,6 @@ +tests: + aoszephyrapp.communication: + build_only: false + tags: smclient + timeout: 500 + platform_allow: native_posix_64 native_posix diff --git a/tests/stubs/channelmanagerstub.hpp b/tests/stubs/channelmanagerstub.hpp new file mode 100644 index 00000000..3127bee8 --- /dev/null +++ b/tests/stubs/channelmanagerstub.hpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef CHANNELMANAGERSTUB_HPP_ +#define CHANNELMANAGERSTUB_HPP_ + +#include + +#include "channelstub.hpp" + +class ChannelManagerStub : public aos::zephyr::communication::ChannelManagerItf { +public: + aos::RetWithError CreateChannel(uint32_t port) override + { + if (mChannels.find(port) != mChannels.end()) { + return {nullptr, aos::ErrorEnum::eAlreadyExist}; + } + + auto channel = std::make_unique(); + + mChannels[port] = std::move(channel); + + return mChannels[port].get(); + } + + aos::Error DeleteChannel(uint32_t port) override + { + if (mChannels.find(port) == mChannels.end()) { + return aos::ErrorEnum::eNotFound; + } + + mChannels.erase(port); + + return aos::ErrorEnum::eNone; + } + + aos::RetWithError GetChannel(uint32_t port) + { + if (mChannels.find(port) == mChannels.end()) { + return {nullptr, aos::ErrorEnum::eNotFound}; + } + + return mChannels[port].get(); + } + +private: + std::unordered_map> mChannels; +}; + +#endif diff --git a/tests/stubs/channelstub.hpp b/tests/stubs/channelstub.hpp new file mode 100644 index 00000000..18697bbb --- /dev/null +++ b/tests/stubs/channelstub.hpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef CHANNELSTUB_HPP_ +#define CHANNELSTUB_HPP_ + +#include +#include +#include + +#include + +#include "communication/channel.hpp" + +class ChannelStub : public aos::zephyr::communication::ChannelItf { +public: + aos::Error Connect() override + { + std::lock_guard lock(mMutex); + + mConnected = true; + + return mConnectError; + } + + aos::Error Close() override + { + std::lock_guard lock(mMutex); + + mConnected = false; + + mCV.notify_one(); + + return mConnectError; + } + + int Read(void* data, size_t size) override + { + std::unique_lock lock(mMutex); + + mCV.wait(lock, [&] { return mReadData.size() >= size || !mReadError.IsNone() || !mConnected; }); + + if (!mConnected) { + return -1; + } + + if (!mReadError.IsNone()) { + mReadError = aos::ErrorEnum::eNone; + return -1; + } + + std::copy(mReadData.begin(), mReadData.begin() + size, static_cast(data)); + mReadData.erase(mReadData.begin(), mReadData.begin() + size); + + return size; + } + + int Write(const void* data, size_t size) override + { + std::lock_guard lock(mMutex); + + mWriteData.insert( + mWriteData.end(), static_cast(data), static_cast(data) + size); + + mCV.notify_one(); + + return size; + } + + bool IsConnected() const override + { + std::lock_guard lock(mMutex); + return mConnected; + } + + aos::Error WaitWrite(std::vector& data, size_t size, const std::chrono::duration& timeout, + aos::Error err = aos::ErrorEnum::eNone) + { + std::unique_lock lock(mMutex); + + mWriteError = err; + + if (!mCV.wait_for(lock, timeout, [&] { return mWriteData.size() >= size; })) { + return aos::ErrorEnum::eTimeout; + } + + data.assign(mWriteData.begin(), mWriteData.begin() + size); + mWriteData.erase(mWriteData.begin(), mWriteData.begin() + size); + + return aos::ErrorEnum::eNone; + } + + void SendRead(const std::vector& data, aos::Error err = aos::ErrorEnum::eNone) + { + std::lock_guard lock(mMutex); + + mReadError = err; + mReadData.insert(mReadData.end(), data.begin(), data.end()); + + mCV.notify_one(); + } + + void Clear() + { + std::lock_guard lock(mMutex); + + mReadData.clear(); + mWriteData.clear(); + mConnectError = aos::ErrorEnum::eNone; + mReadError = aos::ErrorEnum::eNone; + mWriteError = aos::ErrorEnum::eNone; + } + +private: + bool mConnected = false; + std::vector mReadData; + std::vector mWriteData; + aos::Error mConnectError; + aos::Error mReadError; + aos::Error mWriteError; + std::condition_variable mCV; + mutable std::mutex mMutex; +}; + +#endif diff --git a/tests/utils/pbmessages.cpp b/tests/utils/pbmessages.cpp new file mode 100644 index 00000000..99b9c45d --- /dev/null +++ b/tests/utils/pbmessages.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +#include + +#include "pbmessages.hpp" + +/*********************************************************************************************************************** + * Static + **********************************************************************************************************************/ + +static aos::Error SendMessageToChannel(ChannelStub* channel, const std::vector& data) +{ + auto header = AosProtobufHeader {"", static_cast(data.size())}; + auto headerPtr = reinterpret_cast(&header); + + channel->SendRead(std::vector(headerPtr, headerPtr + sizeof(AosProtobufHeader))); + channel->SendRead(data); + + return aos::ErrorEnum::eNone; +} + +static aos::Error ReceiveMessageFromChannel( + ChannelStub* channel, const std::chrono::duration& timeout, std::vector& data) +{ + std::vector headerData; + + auto err = channel->WaitWrite(headerData, sizeof(AosProtobufHeader), timeout); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + auto header = reinterpret_cast(headerData.data()); + + err = channel->WaitWrite(data, header->mDataSize, timeout); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + return aos::ErrorEnum::eNone; +} + +/*********************************************************************************************************************** + * Public + **********************************************************************************************************************/ + +aos::Error SendPBMessage(ChannelStub* channel, const void* message, size_t messageSize, const pb_msgdesc_t* fields) +{ + std::vector data(messageSize); + + if (messageSize) { + auto stream = pb_ostream_from_buffer(data.data(), data.size()); + + auto status = pb_encode(&stream, fields, message); + if (!status) { + return aos::ErrorEnum::eFailed; + } + + data.resize(stream.bytes_written); + } + + return SendMessageToChannel(channel, data); +} + +aos::Error ReceivePBMessage(ChannelStub* channel, const std::chrono::duration& timeout, void* message, + size_t messageSize, const pb_msgdesc_t* fields) +{ + std::vector data(messageSize); + + auto err = ReceiveMessageFromChannel(channel, timeout, data); + if (!err.IsNone()) { + return err; + } + + if (message && fields) { + auto stream = pb_istream_from_buffer(data.data(), data.size()); + + auto status = pb_decode(&stream, fields, message); + if (!status) { + return AOS_ERROR_WRAP(aos::ErrorEnum::eRuntime); + } + } + + return aos::ErrorEnum::eNone; +} diff --git a/tests/utils/pbmessages.hpp b/tests/utils/pbmessages.hpp new file mode 100644 index 00000000..2cc0870e --- /dev/null +++ b/tests/utils/pbmessages.hpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _UTILS_PBMESSAGES_HPP +#define _UTILS_PBMESSAGES_HPP + +#include + +#include "stubs/channelstub.hpp" + +/** + * Sends protobuf message. + * + * @param channel communication channel. + * @param message protobuf message. + * @param messageSize message size. + * @param fields protobuf fields. + * @return aos::Error + */ +aos::Error SendPBMessage( + ChannelStub* channel, const void* message = nullptr, size_t messageSize = 0, const pb_msgdesc_t* fields = nullptr); + +/** + * Receives protobuf message. + * + * @param channel communication channel. + * @param timeout timeout. + * @param message protobuf message. + * @param messageSize message size. + * @param fields protobuf fields. + * @return aos::Error + */ +aos::Error ReceivePBMessage(ChannelStub* channel, const std::chrono::duration& timeout, void* message = nullptr, + size_t messageSize = 0, const pb_msgdesc_t* fields = nullptr); + +#endif From 0d3f29ce77d6ce48280b520308f14df54bffe593 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Thu, 15 Aug 2024 13:11:46 +0300 Subject: [PATCH 026/198] [nodeinfoprovider] Notify subscribers on node status change Signed-off-by: Mykhailo Lohvynenko --- src/nodeinfoprovider/nodeinfoprovider.cpp | 57 +++++++++++- src/nodeinfoprovider/nodeinfoprovider.hpp | 40 +++++++-- tests/nodeinfoprovider/src/main.cpp | 100 ++++++++++++++++++++++ 3 files changed, 186 insertions(+), 11 deletions(-) diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp index 314fad2c..1930caec 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -74,10 +74,50 @@ Error NodeInfoProvider::SetNodeStatus(const NodeStatus& status) LOG_DBG() << "Set node status: status=" << status.ToString(); if (auto err = StoreNodeStatus(status); !err.IsNone()) { - Error(AOS_ERROR_WRAP(err), "failed to store node status"); + return AOS_ERROR_WRAP(Error(err, "failed to store node status")); } - LOG_DBG() << "Node status updated: status=" << status.ToString(); + if (status == mNodeInfo.mStatus) { + return ErrorEnum::eNone; + } + + { + LockGuard lock {mMutex}; + + mNodeInfo.mStatus = status; + } + + LOG_DBG() << "Node status updated: status=" << mNodeInfo.mStatus.ToString(); + + if (auto err = NotifyNodeStatusChanged(status); !err.IsNone()) { + return AOS_ERROR_WRAP(Error(err, "failed to notify node status observers")); + } + + return ErrorEnum::eNone; +} + +Error NodeInfoProvider::SubscribeNodeStatusChanged(iam::nodeinfoprovider::NodeStatusObserverItf& observer) +{ + LockGuard lock {mMutex}; + + LOG_DBG() << "Subscribe on node status changed event"; + + if (auto err = mStatusChangedSubscribers.Set(&observer, true); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + return ErrorEnum::eNone; +} + +Error NodeInfoProvider::UnsubscribeNodeStatusChanged(iam::nodeinfoprovider::NodeStatusObserverItf& observer) +{ + LockGuard lock {mMutex}; + + LOG_DBG() << "Unsubscribe from node status changed event"; + + if (auto err = mStatusChangedSubscribers.Remove(&observer); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } return ErrorEnum::eNone; } @@ -177,4 +217,17 @@ Error NodeInfoProvider::ReadNodeStatus(NodeStatus& status) const return status.FromString(statusStr); } +Error NodeInfoProvider::NotifyNodeStatusChanged(const NodeStatus& status) +{ + LockGuard lock {mMutex}; + + for (auto& [observer, _] : mStatusChangedSubscribers) { + if (auto err = observer->OnNodeStatusChanged(mNodeInfo.mNodeID, status); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + } + + return ErrorEnum::eNone; +} + } // namespace aos::zephyr::nodeinfoprovider diff --git a/src/nodeinfoprovider/nodeinfoprovider.hpp b/src/nodeinfoprovider/nodeinfoprovider.hpp index d3ab770f..3395355b 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.hpp +++ b/src/nodeinfoprovider/nodeinfoprovider.hpp @@ -8,6 +8,8 @@ #ifndef NODEINFOPROVIDER_HPP_ #define NODEINFOPROVIDER_HPP_ +#include +#include #include namespace aos::zephyr::nodeinfoprovider { @@ -40,23 +42,43 @@ class NodeInfoProvider : public iam::nodeinfoprovider::NodeInfoProviderItf { */ Error SetNodeStatus(const NodeStatus& status) override; + /** + * Subscribes on node status changed event. + * + * @param observer node status changed observer + * @return Error + */ + Error SubscribeNodeStatusChanged(iam::nodeinfoprovider::NodeStatusObserverItf& observer) override; + + /** + * Unsubscribes from node status changed event. + * + * @param observer node status changed observer + * @return Error + */ + Error UnsubscribeNodeStatusChanged(iam::nodeinfoprovider::NodeStatusObserverItf& observer) override; + private: Error InitNodeID(); Error InitAttributes(); Error InitPartitionInfo(); Error StoreNodeStatus(const NodeStatus& status) const; Error ReadNodeStatus(NodeStatus& status) const; + Error NotifyNodeStatusChanged(const NodeStatus& status); - static constexpr auto cNodeStatusLen = 16; - static constexpr auto cDiskPartitionPoint = CONFIG_AOS_DISK_MOUNT_POINT; - static constexpr auto cMaxDMIPS = CONFIG_AOS_MAX_CPU_DMIPS; - static constexpr auto cNodeType = CONFIG_AOS_NODE_TYPE; - static constexpr auto cProvisioningStateFile = CONFIG_AOS_PROVISION_STATE_FILE; - static constexpr auto cDiskPartitionName = "Aos"; - static constexpr auto cNodeRunner = "xrun"; - static constexpr auto cAosComponents = "iam,sm"; + static constexpr auto cNodeStatusLen = 16; + static constexpr auto cDiskPartitionPoint = CONFIG_AOS_DISK_MOUNT_POINT; + static constexpr auto cMaxDMIPS = CONFIG_AOS_MAX_CPU_DMIPS; + static constexpr auto cNodeType = CONFIG_AOS_NODE_TYPE; + static constexpr auto cProvisioningStateFile = CONFIG_AOS_PROVISION_STATE_FILE; + static constexpr auto cDiskPartitionName = "Aos"; + static constexpr auto cNodeRunner = "xrun"; + static constexpr auto cAosComponents = "iam,sm"; + static constexpr auto cMaxNodeStatusSubscribers = 4; - NodeInfo mNodeInfo; + NodeInfo mNodeInfo; + StaticMap mStatusChangedSubscribers; + Mutex mMutex; }; } // namespace aos::zephyr::nodeinfoprovider diff --git a/tests/nodeinfoprovider/src/main.cpp b/tests/nodeinfoprovider/src/main.cpp index f7dbd857..2978f6c0 100644 --- a/tests/nodeinfoprovider/src/main.cpp +++ b/tests/nodeinfoprovider/src/main.cpp @@ -90,6 +90,35 @@ void before_test(void* data) } } +/*********************************************************************************************************************** + * Types + **********************************************************************************************************************/ + +class TestNodeStatusObserver : public aos::iam::nodeinfoprovider::NodeStatusObserverItf { +public: + aos::Error OnNodeStatusChanged(const aos::String& nodeID, const aos::NodeStatus& status) override + { + printk("Node status changed: %s\n", status.ToString().CStr()); + + mNodeID = nodeID; + mNodeStatus = status; + mNotified = true; + + return aos::ErrorEnum::eNone; + } + + void Reset() + { + mNotified = false; + mNodeID.Clear(); + mNodeStatus = aos::NodeStatus(); + } + + aos::StaticString mNodeID; + aos::NodeStatus mNodeStatus; + bool mNotified = false; +}; + /*********************************************************************************************************************** * Setup **********************************************************************************************************************/ @@ -172,3 +201,74 @@ ZTEST(nodeinfoprovider, test_set_get_node_info) zassert_equal(nodeInfo.mStatus.GetValue(), aos::NodeStatusEnum::ePaused, "Node status mismatch"); } + +ZTEST(nodeinfoprovider, test_node_status_changed_observer) +{ + aos::Log::SetCallback(TestLogCallback); + + aos::zephyr::nodeinfoprovider::NodeInfoProvider provider; + auto err = provider.Init(); + zassert_true(err.IsNone(), "Failed to init node info provider: %s", err.Message()); + + aos::NodeInfo nodeInfo; + err = provider.GetNodeInfo(nodeInfo); + + zassert_true(err.IsNone(), "Failed to get node info: %s", err.Message()); + zassert_equal(nodeInfo.mStatus.GetValue(), aos::NodeStatusEnum::eUnprovisioned, "Node status mismatch"); + + TestNodeStatusObserver observer1, observer2; + + err = provider.SubscribeNodeStatusChanged(observer1); + zassert_true(err.IsNone(), "Failed to subscribe on node status changed: %s", err.Message()); + + err = provider.SubscribeNodeStatusChanged(observer2); + zassert_true(err.IsNone(), "Failed to subscribe on node status changed: %s", err.Message()); + + err = provider.SetNodeStatus(aos::NodeStatus(aos::NodeStatusEnum::eProvisioned)); + zassert_true(err.IsNone(), "Set node status failed: %s", err.Message()); + + zassert_equal(observer1.mNodeStatus.GetValue(), aos::NodeStatusEnum::eProvisioned, "Node status mismatch"); + zassert_equal(observer1.mNodeID, nodeInfo.mNodeID, "Node id mismatch"); + + zassert_equal(observer2.mNodeStatus.GetValue(), aos::NodeStatusEnum::eProvisioned, "Node status mismatch"); + zassert_equal(observer2.mNodeID, nodeInfo.mNodeID, "Node id mismatch"); + + observer1.Reset(); + observer2.Reset(); + + err = provider.SetNodeStatus(aos::NodeStatus(aos::NodeStatusEnum::ePaused)); + zassert_true(err.IsNone(), "Set node status failed: %s", err.Message()); + + zassert_equal(observer1.mNodeStatus.GetValue(), aos::NodeStatusEnum::ePaused, "Node status mismatch"); + zassert_equal(observer1.mNodeID, nodeInfo.mNodeID, "Node id mismatch"); + + zassert_equal(observer2.mNodeStatus.GetValue(), aos::NodeStatusEnum::ePaused, "Node status mismatch"); + zassert_equal(observer2.mNodeID, nodeInfo.mNodeID, "Node id mismatch"); + + observer1.Reset(); + observer2.Reset(); + + // same node status change should not trigger the observer + err = provider.SetNodeStatus(aos::NodeStatus(aos::NodeStatusEnum::ePaused)); + zassert_true(err.IsNone(), "Set node status failed: %s", err.Message()); + + zassert_false(observer1.mNotified, "Observer should not be notified"); + zassert_false(observer2.mNotified, "Observer should not be notified"); + + observer1.Reset(); + observer2.Reset(); + + // unsubscribe observer1 + err = provider.UnsubscribeNodeStatusChanged(observer1); + zassert_true(err.IsNone(), "Failed to unsubscribe from node status changed event: %s", err.Message()); + + err = provider.SetNodeStatus(aos::NodeStatus(aos::NodeStatusEnum::eProvisioned)); + zassert_true(err.IsNone(), "Set node status failed: %s", err.Message()); + + // observer1 should not receive the event + zassert_false(observer1.mNotified, "Observer should not be notified"); + + // observer2 should receive the event + zassert_true(observer2.mNotified, "Observer should be notified"); + zassert_equal(observer2.mNodeStatus.GetValue(), aos::NodeStatusEnum::eProvisioned, "Node status mismatch"); +} From 69c8a0ba4a64295358f8feb842231a7bb6bc1253 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Fri, 16 Aug 2024 12:39:02 +0300 Subject: [PATCH 027/198] [nodeinfoprovider] Suppress unused function warnings Signed-off-by: Mykhailo Lohvynenko --- src/nodeinfoprovider/nodeinfoprovider.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp index 1930caec..a7214117 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -69,6 +69,7 @@ Error NodeInfoProvider::GetNodeInfo(NodeInfo& nodeInfo) const return ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction Error NodeInfoProvider::SetNodeStatus(const NodeStatus& status) { LOG_DBG() << "Set node status: status=" << status.ToString(); @@ -96,6 +97,7 @@ Error NodeInfoProvider::SetNodeStatus(const NodeStatus& status) return ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction Error NodeInfoProvider::SubscribeNodeStatusChanged(iam::nodeinfoprovider::NodeStatusObserverItf& observer) { LockGuard lock {mMutex}; @@ -109,6 +111,7 @@ Error NodeInfoProvider::SubscribeNodeStatusChanged(iam::nodeinfoprovider::NodeSt return ErrorEnum::eNone; } +// cppcheck-suppress unusedFunction Error NodeInfoProvider::UnsubscribeNodeStatusChanged(iam::nodeinfoprovider::NodeStatusObserverItf& observer) { LockGuard lock {mMutex}; From 6e9ad80ecb4b4667960d1259bf97a25080c6d230 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 14 Aug 2024 18:14:02 +0300 Subject: [PATCH 028/198] [monitoring] Return CPU usage in DMIPs Signed-off-by: Oleksandr Grytsov --- src/monitoring/resourceusageprovider.cpp | 68 ++++++------------------ src/monitoring/resourceusageprovider.hpp | 65 ++++++++++------------ 2 files changed, 44 insertions(+), 89 deletions(-) diff --git a/src/monitoring/resourceusageprovider.cpp b/src/monitoring/resourceusageprovider.cpp index 82697ad9..faf76a46 100644 --- a/src/monitoring/resourceusageprovider.cpp +++ b/src/monitoring/resourceusageprovider.cpp @@ -13,67 +13,27 @@ #include "log.hpp" #include "resourceusageprovider.hpp" +namespace aos::zephyr::monitoring { + /*********************************************************************************************************************** * Public **********************************************************************************************************************/ -aos::Error ResourceUsageProvider::Init() +Error ResourceUsageProvider::Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider) { LOG_DBG() << "Init resource usage provider"; - xenstat xstat {}; - - int ret = xstat_getstat(&xstat); - if (ret != 0) { - return AOS_ERROR_WRAP(ret); - } - - if (auto err = mNodeInfo.mCPUs.Resize(xstat.num_cpus); !err.IsNone()) { + auto err = nodeInfoProvider.GetNodeInfo(mNodeInfo); + if (!err.IsNone()) { return AOS_ERROR_WRAP(err); } - mNodeInfo.mNodeID = cNodeID; - mNodeInfo.mTotalRAM = xstat.tot_mem; - - aos::PartitionInfo partitionInfo; - partitionInfo.mName = cDiskPartitionName; - partitionInfo.mPath = cDiskPartitionPoint; - partitionInfo.mTypes.EmplaceBack("services"); - partitionInfo.mTypes.EmplaceBack("layers"); - - mNodeInfo.mPartitions.PushBack(partitionInfo); - - LOG_DBG() << "Number of CPUs: " << mNodeInfo.mCPUs.Size() << ", total RAM(K): " << (mNodeInfo.mTotalRAM / 1024); - - for (size_t i = 0; i < mNodeInfo.mPartitions.Size(); ++i) { - struct fs_statvfs sbuf; - - ret = fs_statvfs(mNodeInfo.mPartitions[i].mPath.CStr(), &sbuf); - if (ret != 0) { - return AOS_ERROR_WRAP(ret); - } - - mNodeInfo.mPartitions[i].mTotalSize = sbuf.f_bsize * sbuf.f_blocks; - - LOG_DBG() << "Partition: " << mNodeInfo.mPartitions[i].mName - << ", total size(K): " << (mNodeInfo.mPartitions[i].mTotalSize / 1024); - } - - return aos::ErrorEnum::eNone; -} - -aos::Error ResourceUsageProvider::GetNodeInfo(aos::NodeInfo& nodeInfo) const -{ - LOG_DBG() << "Get node info"; - - nodeInfo = mNodeInfo; - - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -aos::Error ResourceUsageProvider::GetNodeMonitoringData( - const aos::String& nodeID, aos::monitoring::MonitoringData& monitoringData) +Error ResourceUsageProvider::GetNodeMonitoringData( + const String& nodeID, aos::monitoring::MonitoringData& monitoringData) { xenstat_domain domain; @@ -94,7 +54,7 @@ aos::Error ResourceUsageProvider::GetNodeMonitoringData( auto us_elapsed = (curTime.tv_sec - mPrevTime.tv_sec) * 1000000.0 + (curTime.tv_usec - mPrevTime.tv_usec); - monitoringData.mCPU = ((cpuTimeDiff_ns / 10.0) / us_elapsed); + monitoringData.mCPU = (cpuTimeDiff_ns * mNodeInfo.mMaxDMIPS / 1000.0 / us_elapsed); } LOG_DBG() << "Get node monitoring data: RAM(K): " << (monitoringData.mRAM / 1024) @@ -117,12 +77,12 @@ aos::Error ResourceUsageProvider::GetNodeMonitoringData( << ", used size(K): " << (monitoringData.mDisk[i].mUsedSize / 1024); } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -aos::Error ResourceUsageProvider::GetInstanceMonitoringData( - const aos::String& instanceID, aos::monitoring::MonitoringData& monitoringData) +Error ResourceUsageProvider::GetInstanceMonitoringData( + const String& instanceID, aos::monitoring::MonitoringData& monitoringData) { LOG_DBG() << "Get monitoring data for instance: " << instanceID; @@ -179,5 +139,7 @@ aos::Error ResourceUsageProvider::GetInstanceMonitoringData( LOG_DBG() << "RAM(K): " << (monitoringData.mRAM / 1024) << ", CPU: " << monitoringData.mCPU; - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } + +} // namespace aos::zephyr::monitoring diff --git a/src/monitoring/resourceusageprovider.hpp b/src/monitoring/resourceusageprovider.hpp index 12cccdb0..5af2061a 100644 --- a/src/monitoring/resourceusageprovider.hpp +++ b/src/monitoring/resourceusageprovider.hpp @@ -10,69 +10,62 @@ #include -#include +#include +#include + +namespace aos::zephyr::monitoring { class ResourceUsageProvider : public aos::monitoring::ResourceUsageProviderItf { public: /** - * Init resource usage provider - * @return Error - */ - aos::Error Init() override; - - /** - * Returns system info + * Initializes resource usage provider. * - * @param systemInfo system info + * @param nodeInfoProvider node info provider. * @return Error */ - aos::Error GetNodeInfo(aos::NodeInfo& systemInfo) const override; + Error Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider); /** - * Returns node monitoring data + * Returns node monitoring data. * - * @param nodeID node ident - * @param monitoringData monitoring data - * @return Error + * @param nodeID node ident. + * @param monitoringData monitoring data. + * @return Error. */ - aos::Error GetNodeMonitoringData( - const aos::String& nodeID, aos::monitoring::MonitoringData& monitoringData) override; + Error GetNodeMonitoringData(const String& nodeID, aos::monitoring::MonitoringData& monitoringData) override; /** - * Returns instance monitoring data + * Returns instance monitoring data. * - * @param instance instance ident - * @param monitoringData monitoring data - * @return Error + * @param instance instance ident. + * @param monitoringData monitoring data. + * @return Error. */ - aos::Error GetInstanceMonitoringData( - const aos::String& instanceID, aos::monitoring::MonitoringData& monitoringData) override; + Error GetInstanceMonitoringData(const String& instanceID, aos::monitoring::MonitoringData& monitoringData) override; private: - static constexpr auto cNodeID = CONFIG_AOS_NODE_ID; - static constexpr auto cDiskPartitionPoint = CONFIG_AOS_DISK_MOUNT_POINT; - static constexpr auto cDiskPartitionName = "Aos"; - static constexpr auto cDom0ID = 0; + static constexpr auto cDom0ID = 0; struct InstanceCPUData { - InstanceCPUData( - const aos::String& instanceID, unsigned long long instanceCPUTime, const timeval& instancePrevTime) + InstanceCPUData(const String& instanceID, unsigned long long instanceCPUTime, const timeval& instancePrevTime) : mInstanceCPUTime(instanceCPUTime) , mInstanceID(instanceID) , mInstancePrevTime(instancePrevTime) { } - unsigned long long mInstanceCPUTime; - aos::StaticString mInstanceID; - timeval mInstancePrevTime; + unsigned long long mInstanceCPUTime; + StaticString mInstanceID; + timeval mInstancePrevTime; }; - unsigned long long mPrevNodeCPUTime {}; - timeval mPrevTime {}; - aos::StaticArray mPrevInstanceCPUTime {}; - aos::Mutex mMutex {}; - aos::NodeInfo mNodeInfo {}; + unsigned long long mPrevNodeCPUTime {}; + timeval mPrevTime {}; + StaticArray mPrevInstanceCPUTime {}; + Mutex mMutex {}; + NodeInfo mNodeInfo {}; }; +} // namespace aos::zephyr::monitoring + #endif From 539dca6ee69baec2ae2215f1802d8e78756b8ff3 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 15 Aug 2024 20:23:51 +0300 Subject: [PATCH 029/198] [prj.conf] Remove XRUN configuration XRUN is removed from zephyr-xenlib and should be added as separate lib. Signed-off-by: Oleksandr Grytsov --- boards/native_posix.conf | 4 --- boards/native_posix_64.conf | 5 --- boards/rcar_spider.conf | 26 ++++++++++++++ boards/rcar_spider.overlay | 67 +++++++++++++++++++++++++++++++++++++ prj.conf | 5 --- 5 files changed, 93 insertions(+), 14 deletions(-) create mode 100644 boards/rcar_spider.conf create mode 100644 boards/rcar_spider.overlay diff --git a/boards/native_posix.conf b/boards/native_posix.conf index 0b7b32b1..6eaaca3e 100644 --- a/boards/native_posix.conf +++ b/boards/native_posix.conf @@ -56,10 +56,6 @@ CONFIG_XEN_LIBFDT=n CONFIG_XEN_STORE_SRV=n CONFIG_XEN_SHELL=n -# Disable xrun - -CONFIG_XRUN=n -CONFIG_XRUN_SHELL_CMDS=n # Disable vchan diff --git a/boards/native_posix_64.conf b/boards/native_posix_64.conf index 0b7b32b1..4995cc58 100644 --- a/boards/native_posix_64.conf +++ b/boards/native_posix_64.conf @@ -56,11 +56,6 @@ CONFIG_XEN_LIBFDT=n CONFIG_XEN_STORE_SRV=n CONFIG_XEN_SHELL=n -# Disable xrun - -CONFIG_XRUN=n -CONFIG_XRUN_SHELL_CMDS=n - # Disable vchan CONFIG_XEN_VCH=n diff --git a/boards/rcar_spider.conf b/boards/rcar_spider.conf new file mode 100644 index 00000000..a828accf --- /dev/null +++ b/boards/rcar_spider.conf @@ -0,0 +1,26 @@ +# +# Copyright (c) 2023 EPAM Systems +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Kernel virtual memory size + +CONFIG_KERNEL_VM_SIZE=0x4000000 +CONFIG_PARTIAL_DEVICE_TREE_SIZE=80000 + +# Aos config + +CONFIG_SHELL_STACK_SIZE=8192 + +CONFIG_DISK_ACCESS=y +CONFIG_DISK_DRIVERS=y +CONFIG_DISK_DRIVER_MMC=y + +CONFIG_MMC_RCAR=y +CONFIG_MMC_RCA=1 + +CONFIG_FS_LITTLEFS_BLK_DEV=y + +CONFIG_RCAR_MMC_SCC_SUPPORT=n +CONFIG_SD_DATA_TIMEOUT=1000 diff --git a/boards/rcar_spider.overlay b/boards/rcar_spider.overlay new file mode 100644 index 00000000..6f76f443 --- /dev/null +++ b/boards/rcar_spider.overlay @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2023 Renesas Electronics Corporation. + * Copyright (C) 2023 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&mmc0 { + disk { + status = "okay"; + }; + status = "okay"; +}; + +/ { + firmware { + tee { + compatible = "linaro,optee-tz"; + method = "smc"; + status = "okay"; + }; + }; + + fstab { + compatible = "zephyr,fstab"; + storage: storage { + compatible = "zephyr,fstab,littlefs"; + mount-point = "/tmp"; + partition = <&storage_partition>; + automount; + read-size = <16>; + prog-size = <16>; + cache-size = <64>; + lookahead-size = <32>; + block-cycles = <512>; + }; + }; + + flashcontroller0: flashcontroller { + compatible = "zephyr,sim-flash"; + label = "FLASH_SIMULATOR"; + #address-cells = <1>; + #size-cells = <1>; + erase-value = <0xff>; + flash_sim0: flash_sim@0 { + compatible = "soc-nv-flash"; + reg = <0x00000000 DT_SIZE_M(32)>; + erase-block-size = <1024>; + write-block-size = <4>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + /* + * Storage partition will be used by FCB/LittleFS/NVS + * if enabled. + */ + storage_partition: partition@1000 { + label = "storage"; + reg = <0x00001000 0x02000000>; + }; + }; + }; + }; +}; diff --git a/prj.conf b/prj.conf index 74f24647..fc91aa0f 100644 --- a/prj.conf +++ b/prj.conf @@ -167,11 +167,6 @@ CONFIG_XEN_STORE_SRV=y CONFIG_XEN_LIBFDT=y CONFIG_XEN_SHELL=y -# Enable xrun - -CONFIG_XRUN=y -CONFIG_XRUN_SHELL_CMDS=y - # Enable xstat CONFIG_XSTAT=y From 89dfd49fd216468317e9e944fb97a242fbfaf6b1 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sat, 17 Aug 2024 17:42:21 +0300 Subject: [PATCH 030/198] [utils] Combine test utils with src utils and update API Signed-off-by: Oleksandr Grytsov --- CMakeLists.txt | 1 + src/utils/checksum.cpp | 12 ++-- src/utils/checksum.hpp | 8 ++- src/utils/pbconvert.hpp | 107 +++++++++------------------------ {tests => src}/utils/utils.cpp | 12 +++- src/utils/utils.hpp | 79 ++++++++++++++++++++++++ tests/utils/pbmessages.cpp | 4 +- tests/utils/utils.hpp | 21 ------- 8 files changed, 135 insertions(+), 109 deletions(-) rename {tests => src}/utils/utils.cpp (75%) create mode 100644 src/utils/utils.hpp delete mode 100644 tests/utils/utils.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index eca299c3..5459a405 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,6 +89,7 @@ target_sources( src/smclient/smclient.cpp src/storage/storage.cpp src/utils/checksum.cpp + src/utils/utils.cpp ) # Enable vchannels and xrun mocks for native posix diff --git a/src/utils/checksum.cpp b/src/utils/checksum.cpp index baf7284f..08742454 100644 --- a/src/utils/checksum.cpp +++ b/src/utils/checksum.cpp @@ -9,16 +9,18 @@ #include "checksum.hpp" +namespace aos::zephyr::utils { + /*********************************************************************************************************************** * Public **********************************************************************************************************************/ -aos::RetWithError> CalculateSha256(const aos::Array& data) +RetWithError> CalculateSha256(const Array& data) { - mbedtls_sha256_context ctx; - aos::StaticArray digest; + mbedtls_sha256_context ctx; + StaticArray digest; - digest.Resize(aos::cSHA256Size); + digest.Resize(cSHA256Size); if (data.Size() == 0) { return digest; @@ -51,3 +53,5 @@ aos::RetWithError> CalculateSha256(c return digest; } + +} // namespace aos::zephyr::utils diff --git a/src/utils/checksum.hpp b/src/utils/checksum.hpp index 665afc75..59aba81b 100644 --- a/src/utils/checksum.hpp +++ b/src/utils/checksum.hpp @@ -10,12 +10,16 @@ #include +namespace aos::zephyr::utils { + /** * Calculates SHA-256. * * @param data[in] data array. - * @return aos::RetWithError>. + * @return RetWithError>. */ -aos::RetWithError> CalculateSha256(const aos::Array& data); +RetWithError> CalculateSha256(const Array& data); + +} // namespace aos::zephyr::utils #endif diff --git a/src/utils/pbconvert.hpp b/src/utils/pbconvert.hpp index e9fc8bc6..0eabe6e2 100644 --- a/src/utils/pbconvert.hpp +++ b/src/utils/pbconvert.hpp @@ -10,37 +10,11 @@ #include -#include +#include -/** - * Converts Aos string to PB string. - * - * @tparam cSize max PB string size. - * @param src Aos string to convert from. - */ -template -constexpr void StringToPB(const aos::String& src, char (&dst)[cSize]) -{ - aos::String(dst, cSize - 1) = src; -} - -/** - * Converts PB string to Aos string. - * - * @tparam cSize max PB string size. - * @param dst Aos string to convert to. - */ -template -constexpr void PBToString(const char (&src)[cSize], aos::String& dst) -{ - auto len = strlen(src); +#include "utils.hpp" - if (len > cSize - 1) { - len = cSize - 1; - } - - dst = aos::String(src, len); -} +namespace aos::zephyr::utils { /** * Converts PB string to Aos enum. @@ -60,28 +34,29 @@ constexpr void PBToEnum(const char (&src)[cSize], T& dst) len = cSize - 1; } - auto err = dst.FromString(aos::String(src, len)); + auto err = dst.FromString(String(src, len)); assert(err.IsNone()); } /** - * Converts Aos error to PB string. + * Converts Aos error to PB error info. * - * @tparam cSize max PB string size. * @param aosError Aos error to convert from. + * @param[out] errorInfo PB error info to convert to. */ -template -constexpr void ErrorToPB(const aos::Error& aosError, char (&dst)[cSize]) +template +void ErrorToPB(const Error& aosError, T& errorInfo) { - aos::String str(dst, cSize - 1); - - str.Clear(); - if (aosError.IsNone()) { + errorInfo.has_error = false; return; } - str.Convert(aosError); + errorInfo.has_error = true; + errorInfo.error.aos_code = int(aosError.Value()); + errorInfo.error.exit_code = aosError.Errno(); + + StringFromCStr(errorInfo.error.message).Convert(aosError); } /** @@ -92,10 +67,10 @@ constexpr void ErrorToPB(const aos::Error& aosError, char (&dst)[cSize]) * @param dst PB array to covert to. */ template -constexpr void ByteArrayToPB(const aos::Array& src, T& dst) +constexpr void ByteArrayToPB(const Array& src, T& dst) { - aos::Array(dst.bytes, sizeof(dst.bytes)) = src; - dst.size = src.Size(); + Array(dst.bytes, sizeof(dst.bytes)) = src; + dst.size = src.Size(); } /** @@ -106,7 +81,7 @@ constexpr void ByteArrayToPB(const aos::Array& src, T& dst) * @param dst Aos array to covert to. */ template -constexpr void PBToByteArray(const T& src, aos::Array& dst) +constexpr void PBToByteArray(const T& src, Array& dst) { auto size = src.size; @@ -114,33 +89,7 @@ constexpr void PBToByteArray(const T& src, aos::Array& dst) size = sizeof(src.bytes); } - dst = aos::Array(src.bytes, size); -} - -/** - * Converts PB version info to Aos version info. - * - * @param pbVersion PB version info. - * @param aosVersion Aos version info. - */ -constexpr void PBToVersionInfo(const servicemanager_v3_VersionInfo pbVersion, aos::VersionInfo& aosVersion) -{ - aosVersion.mAosVersion = pbVersion.aos_version; - PBToString(pbVersion.vendor_version, aosVersion.mVendorVersion); - PBToString(pbVersion.description, aosVersion.mDescription); -} - -/** - * Converts Aos version info PB version info. - * - * @param aosVersion Aos version info. - * @param pbVersion PB version info. - */ -constexpr void VersionInfoToPB(const aos::VersionInfo& aosVersion, servicemanager_v3_VersionInfo& pbVersion) -{ - pbVersion.aos_version = aosVersion.mAosVersion; - StringToPB(aosVersion.mVendorVersion, pbVersion.vendor_version); - StringToPB(aosVersion.mDescription, pbVersion.description); + dst = Array(src.bytes, size); } /** @@ -149,11 +98,11 @@ constexpr void VersionInfoToPB(const aos::VersionInfo& aosVersion, servicemanage * @param aosIdent Aos instance ident. * @param pbIdent PB instance ident. */ -constexpr void InstanceIdentToPB(const aos::InstanceIdent& aosIdent, servicemanager_v3_InstanceIdent& pbIdent) +inline void InstanceIdentToPB(const InstanceIdent& aosIdent, common_v1_InstanceIdent& pbIdent) { - StringToPB(aosIdent.mServiceID, pbIdent.service_id); - StringToPB(aosIdent.mSubjectID, pbIdent.subject_id); - pbIdent.instance = aosIdent.mInstance; + StringFromCStr(pbIdent.service_id) = aosIdent.mServiceID; + StringFromCStr(pbIdent.subject_id) = aosIdent.mSubjectID; + pbIdent.instance = aosIdent.mInstance; } /** @@ -162,11 +111,13 @@ constexpr void InstanceIdentToPB(const aos::InstanceIdent& aosIdent, servicemana * @param pbIdent PB instance ident. * @param aosIdent Aos instance ident. */ -constexpr void PBToInstanceIdent(const servicemanager_v3_InstanceIdent& pbIdent, aos::InstanceIdent& aosIdent) +inline void PBToInstanceIdent(const common_v1_InstanceIdent& pbIdent, InstanceIdent& aosIdent) { - PBToString(pbIdent.service_id, aosIdent.mServiceID); - PBToString(pbIdent.subject_id, aosIdent.mSubjectID); - aosIdent.mInstance = pbIdent.instance; + aosIdent.mServiceID = StringFromCStr(pbIdent.service_id); + aosIdent.mSubjectID = StringFromCStr(pbIdent.subject_id); + aosIdent.mInstance = pbIdent.instance; } +} // namespace aos::zephyr::utils + #endif diff --git a/tests/utils/utils.cpp b/src/utils/utils.cpp similarity index 75% rename from tests/utils/utils.cpp rename to src/utils/utils.cpp index 8212acb7..989fb3de 100644 --- a/tests/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -6,22 +6,30 @@ */ #include +#include #include "utils.hpp" +namespace aos::zephyr::utils { + /*********************************************************************************************************************** * Static **********************************************************************************************************************/ -aos::StaticString<256> sErrorStr; +static StaticString<256> sErrorStr; +static Mutex sMutex; /*********************************************************************************************************************** * Public **********************************************************************************************************************/ -const char* AosErrorToStr(const aos::Error& err) +const char* ErrorToCStr(const Error& err) { + LockGuard lock {sMutex}; + sErrorStr.Convert(err); return sErrorStr.CStr(); } + +} // namespace aos::zephyr::utils diff --git a/src/utils/utils.hpp b/src/utils/utils.hpp new file mode 100644 index 00000000..311fb09b --- /dev/null +++ b/src/utils/utils.hpp @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _TEST_UTILS_HPP +#define _TEST_UTILS_HPP + +#include + +namespace aos::zephyr::utils { + +/** + * Creates Aos string from fixed size C string. + * + * @tparam cSize max C string size. + * @param cStr C string. + * @return String&. + */ +template +constexpr String StringFromCStr(char (&cStr)[cSize]) +{ + return String(cStr, cSize - 1); +} + +/** + * Creates Aos string from fixed size C string. + * + * @tparam cSize max C string size. + * @param cStr C string. + * @return String&. + */ +template +constexpr const String StringFromCStr(const char (&cStr)[cSize]) +{ + return String(cStr, cSize - 1); +} + +/** + * Creates Aos array from fixed size C array. + * + * @tparam T C array type. + * @tparam cSize max C array size. + * @param arr C array. + * @return Array. + */ +template +Array ToArray(T (&arr)[cSize]) +{ + return Array(arr, cSize); +} + +/** + * Creates Aos array from fixed size C array. + * + * @tparam T C array type. + * @tparam cSize max C array size. + * @param arr C array. + * @return Array. + */ +template +const Array ToArray(const T (&arr)[cSize]) +{ + return Array(arr, cSize); +} + +/** + * Converts Aos error to string. + * + * @param err aos error. + * @return const char* + */ +const char* ErrorToCStr(const Error& err); + +} // namespace aos::zephyr::utils + +#endif diff --git a/tests/utils/pbmessages.cpp b/tests/utils/pbmessages.cpp index 99b9c45d..951bc574 100644 --- a/tests/utils/pbmessages.cpp +++ b/tests/utils/pbmessages.cpp @@ -17,7 +17,7 @@ static aos::Error SendMessageToChannel(ChannelStub* channel, const std::vector& data) { - auto header = AosProtobufHeader {"", static_cast(data.size())}; + auto header = AosProtobufHeader {static_cast(data.size())}; auto headerPtr = reinterpret_cast(&header); channel->SendRead(std::vector(headerPtr, headerPtr + sizeof(AosProtobufHeader))); @@ -83,7 +83,7 @@ aos::Error ReceivePBMessage(ChannelStub* channel, const std::chrono::duration - -/** - * Converts Aos error to string. - * - * @param err aos error. - * @return const char* - */ -const char* AosErrorToStr(const aos::Error& err); - -#endif From 8bb5f558d54382116dba1ef2cf41ed763cb94fef Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 15 Aug 2024 20:26:57 +0300 Subject: [PATCH 031/198] [storage] Update to new API with Version field instead of AosVersion Signed-off-by: Oleksandr Grytsov --- src/storage/filestorage.hpp | 100 +++++++++-------- src/storage/storage.cpp | 205 +++++++++++++++++------------------ src/storage/storage.hpp | 132 ++++++++++------------ tests/storage/CMakeLists.txt | 14 ++- tests/storage/prj.conf | 4 +- tests/storage/src/main.cpp | 44 ++++---- 6 files changed, 244 insertions(+), 255 deletions(-) diff --git a/src/storage/filestorage.hpp b/src/storage/filestorage.hpp index 1908bf1b..fafe42fe 100644 --- a/src/storage/filestorage.hpp +++ b/src/storage/filestorage.hpp @@ -21,8 +21,10 @@ #include "utils/checksum.hpp" +namespace aos::zephyr::storage { + template -class FileStorage : public aos::NonCopyable { +class FileStorage : public NonCopyable { public: /** * Default constructor. @@ -45,7 +47,7 @@ class FileStorage : public aos::NonCopyable { * @param path Path to database file. * @return Error. */ - aos::Error Init(const aos::String& path) + Error Init(const String& path) { mFileName = path; @@ -60,17 +62,17 @@ class FileStorage : public aos::NonCopyable { } if (fileSize == 0) { - aos::UniquePtr
header = aos::MakeUnique
(&mAllocator); + UniquePtr
header = MakeUnique
(&mAllocator); - auto checksum = CalculateSha256( - aos::Array(reinterpret_cast(header.Get()), sizeof(Header) - aos::cSHA256Size)); + auto checksum = utils::CalculateSha256( + Array(reinterpret_cast(header.Get()), sizeof(Header) - cSHA256Size)); if (!checksum.mError.IsNone()) { return AOS_ERROR_WRAP(checksum.mError); } ssize_t nwrite = write(mFd, header.Get(), sizeof(Header)); if (nwrite != sizeof(Header)) { - return nwrite < 0 ? AOS_ERROR_WRAP(errno) : aos::ErrorEnum::eRuntime; + return nwrite < 0 ? AOS_ERROR_WRAP(errno) : ErrorEnum::eRuntime; } } @@ -79,7 +81,7 @@ class FileStorage : public aos::NonCopyable { return err; } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } /** @@ -90,20 +92,20 @@ class FileStorage : public aos::NonCopyable { * @return Error */ template - aos::Error Add(const T& data, F filter) + Error Add(const T& data, F filter) { auto ret = lseek(mFd, sizeof(Header), SEEK_SET); if (ret < 0) { return AOS_ERROR_WRAP(errno); } - aos::UniquePtr record = aos::MakeUnique(&mAllocator); - ssize_t nread {}; - off_t deletedRecordOffset {-1}; + UniquePtr record = MakeUnique(&mAllocator); + ssize_t nread {}; + off_t deletedRecordOffset {-1}; while ((nread = read(mFd, record.Get(), sizeof(Record))) == sizeof(Record)) { if (!record->mDeleted && filter(record->mData, data)) { - return aos::ErrorEnum::eAlreadyExist; + return ErrorEnum::eAlreadyExist; } if (deletedRecordOffset == -1 && record->mDeleted) { @@ -121,13 +123,13 @@ class FileStorage : public aos::NonCopyable { record->mData = data; record->mDeleted = 0; - auto checksum = CalculateSha256( - aos::Array(reinterpret_cast(record.Get()), sizeof(Record) - aos::cSHA256Size)); + auto checksum = utils::CalculateSha256( + Array(reinterpret_cast(record.Get()), sizeof(Record) - cSHA256Size)); if (!checksum.mError.IsNone()) { return checksum.mError; } - aos::Array(reinterpret_cast(record->mChecksum), aos::cSHA256Size) = checksum.mValue; + Array(reinterpret_cast(record->mChecksum), cSHA256Size) = checksum.mValue; if (deletedRecordOffset >= 0) { ret = lseek(mFd, deletedRecordOffset, SEEK_SET); @@ -138,7 +140,7 @@ class FileStorage : public aos::NonCopyable { ssize_t nwrite = write(mFd, record.Get(), sizeof(Record)); if (nwrite != sizeof(Record)) { - return nwrite < 0 ? AOS_ERROR_WRAP(errno) : aos::ErrorEnum::eRuntime; + return nwrite < 0 ? AOS_ERROR_WRAP(errno) : ErrorEnum::eRuntime; } auto err = Sync(); @@ -146,7 +148,7 @@ class FileStorage : public aos::NonCopyable { return err; } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } /** @@ -158,15 +160,15 @@ class FileStorage : public aos::NonCopyable { * @return Error */ template - aos::Error Update(const T& data, F filter) + Error Update(const T& data, F filter) { auto ret = lseek(mFd, sizeof(Header), SEEK_SET); if (ret < 0) { return AOS_ERROR_WRAP(errno); } - aos::UniquePtr record = aos::MakeUnique(&mAllocator); - ssize_t nread {}; + UniquePtr record = MakeUnique(&mAllocator); + ssize_t nread {}; while ((nread = read(mFd, record.Get(), sizeof(Record))) == sizeof(Record)) { if (record->mDeleted) { @@ -186,20 +188,20 @@ class FileStorage : public aos::NonCopyable { record->mData = data; - auto checksum = CalculateSha256( - aos::Array(reinterpret_cast(record.Get()), sizeof(Record) - aos::cSHA256Size)); + auto checksum = utils::CalculateSha256( + Array(reinterpret_cast(record.Get()), sizeof(Record) - cSHA256Size)); if (!checksum.mError.IsNone()) { return checksum.mError; } - aos::Array(reinterpret_cast(record->mChecksum), aos::cSHA256Size) = checksum.mValue; + Array(reinterpret_cast(record->mChecksum), cSHA256Size) = checksum.mValue; ssize_t nwrite = write(mFd, record.Get(), sizeof(Record)); if (nwrite != sizeof(Record)) { - return nwrite < 0 ? AOS_ERROR_WRAP(errno) : aos::ErrorEnum::eRuntime; + return nwrite < 0 ? AOS_ERROR_WRAP(errno) : ErrorEnum::eRuntime; } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } if (nread < 0) { @@ -211,7 +213,7 @@ class FileStorage : public aos::NonCopyable { return err; } - return aos::ErrorEnum::eNotFound; + return ErrorEnum::eNotFound; } /** @@ -222,15 +224,15 @@ class FileStorage : public aos::NonCopyable { * @return Error */ template - aos::Error Remove(F filter) + Error Remove(F filter) { auto ret = lseek(mFd, sizeof(Header), SEEK_SET); if (ret < 0) { return AOS_ERROR_WRAP(errno); } - aos::UniquePtr record = aos::MakeUnique(&mAllocator); - ssize_t nread {}; + UniquePtr record = MakeUnique(&mAllocator); + ssize_t nread {}; while ((nread = read(mFd, record.Get(), sizeof(Record))) == sizeof(Record)) { if (record->mDeleted) { @@ -252,7 +254,7 @@ class FileStorage : public aos::NonCopyable { ssize_t nwrite = write(mFd, record.Get(), sizeof(Record)); if (nwrite != sizeof(Record)) { - return nwrite < 0 ? AOS_ERROR_WRAP(errno) : aos::ErrorEnum::eRuntime; + return nwrite < 0 ? AOS_ERROR_WRAP(errno) : ErrorEnum::eRuntime; } auto err = Sync(); @@ -260,14 +262,14 @@ class FileStorage : public aos::NonCopyable { return err; } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } if (nread < 0) { return AOS_ERROR_WRAP(errno); } - return aos::ErrorEnum::eNotFound; + return ErrorEnum::eNotFound; } /** @@ -278,15 +280,15 @@ class FileStorage : public aos::NonCopyable { * @return Error */ template - aos::Error ReadRecords(F append) + Error ReadRecords(F append) { auto ret = lseek(mFd, sizeof(Header), SEEK_SET); if (ret < 0) { return AOS_ERROR_WRAP(errno); } - aos::UniquePtr record = aos::MakeUnique(&mAllocator); - ssize_t nread {}; + UniquePtr record = MakeUnique(&mAllocator); + ssize_t nread {}; while ((nread = read(mFd, record.Get(), sizeof(Record))) == sizeof(Record)) { if (record->mDeleted) { @@ -303,7 +305,7 @@ class FileStorage : public aos::NonCopyable { return AOS_ERROR_WRAP(errno); } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } /** @@ -315,15 +317,15 @@ class FileStorage : public aos::NonCopyable { * @return Error */ template - aos::Error ReadRecordByFilter(T& data, F filter) + Error ReadRecordByFilter(T& data, F filter) { auto ret = lseek(mFd, sizeof(Header), SEEK_SET); if (ret < 0) { return AOS_ERROR_WRAP(errno); } - aos::UniquePtr record = aos::MakeUnique(&mAllocator); - ssize_t nread {}; + UniquePtr record = MakeUnique(&mAllocator); + ssize_t nread {}; while ((nread = read(mFd, record.Get(), sizeof(Record))) == sizeof(Record)) { if (record->mDeleted) { @@ -333,7 +335,7 @@ class FileStorage : public aos::NonCopyable { if (filter(record->mData)) { data = record->mData; - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } } @@ -341,13 +343,13 @@ class FileStorage : public aos::NonCopyable { return AOS_ERROR_WRAP(errno); } - return aos::ErrorEnum::eNotFound; + return ErrorEnum::eNotFound; } private: // Currently, zephyr doesn't provide Posix API (fsync) to flush the file correctly. We have to // rewrite this class using zephyr FS API. As workaround, we just reopen the file. - aos::Error Sync() + Error Sync() { if (mFd >= 0) { auto ret = close(mFd); @@ -361,24 +363,26 @@ class FileStorage : public aos::NonCopyable { return AOS_ERROR_WRAP(errno); } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } struct Header { uint64_t mVersion; uint8_t mReserved[256]; - uint8_t mChecksum[aos::cSHA256Size]; + uint8_t mChecksum[cSHA256Size]; }; struct Record { T mData; uint8_t mDeleted; - uint8_t mChecksum[aos::cSHA256Size]; + uint8_t mChecksum[cSHA256Size]; }; - aos::StaticString mFileName; - aos::StaticAllocator mAllocator; - int mFd {-1}; + StaticString mFileName; + StaticAllocator mAllocator; + int mFd {-1}; }; +} // namespace aos::zephyr::storage + #endif diff --git a/src/storage/storage.cpp b/src/storage/storage.cpp index 8d7b41fb..38dddf97 100644 --- a/src/storage/storage.cpp +++ b/src/storage/storage.cpp @@ -10,97 +10,97 @@ #include "log.hpp" #include "storage.hpp" +namespace aos::zephyr::storage { + /*********************************************************************************************************************** * Public **********************************************************************************************************************/ -aos::Error Storage::Init() +Error Storage::Init() { LOG_DBG() << "Initialize storage: " << cStoragePath; - aos::Error err; - - if (!(err = aos::FS::MakeDirAll(cStoragePath)).IsNone()) { + if (auto err = FS::MakeDirAll(cStoragePath); !err.IsNone()) { return AOS_ERROR_WRAP(err); } - auto instancePath = aos::FS::JoinPath(cStoragePath, "instance.db"); + auto instancePath = FS::JoinPath(cStoragePath, "instance.db"); - if (!(err = mInstanceDatabase.Init(instancePath)).IsNone()) { + if (auto err = mInstanceDatabase.Init(instancePath); !err.IsNone()) { return err; } - auto servicePath = aos::FS::JoinPath(cStoragePath, "service.db"); + auto servicePath = FS::JoinPath(cStoragePath, "service.db"); - if (!(err = mServiceDatabase.Init(servicePath)).IsNone()) { + if (auto err = mServiceDatabase.Init(servicePath); !err.IsNone()) { return AOS_ERROR_WRAP(err); } - auto certPath = aos::FS::JoinPath(cStoragePath, "cert.db"); - if (!(err = mCertDatabase.Init(certPath)).IsNone()) { + auto certPath = FS::JoinPath(cStoragePath, "cert.db"); + if (auto err = mCertDatabase.Init(certPath); !err.IsNone()) { return AOS_ERROR_WRAP(err); } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -aos::Error Storage::AddInstance(const aos::InstanceInfo& instance) +Error Storage::AddInstance(const aos::InstanceInfo& instance) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Add instance: " << instance.mInstanceIdent; auto storageInstance = ConvertInstanceInfo(instance); return mInstanceDatabase.Add( - *storageInstance, [](const InstanceInfo& storedInstance, const InstanceInfo& addedInstance) { + *storageInstance, [](const Storage::InstanceInfo& storedInstance, const Storage::InstanceInfo& addedInstance) { return storedInstance.mInstanceIdent == addedInstance.mInstanceIdent; }); } // cppcheck-suppress unusedFunction -aos::Error Storage::UpdateInstance(const aos::InstanceInfo& instance) +Error Storage::UpdateInstance(const aos::InstanceInfo& instance) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Update instance: " << instance.mInstanceIdent; auto storageInstance = ConvertInstanceInfo(instance); - return mInstanceDatabase.Update(*storageInstance, [&instance](const InstanceInfo& data) { + return mInstanceDatabase.Update(*storageInstance, [&instance](const Storage::InstanceInfo& data) { return data.mInstanceIdent.mInstance == instance.mInstanceIdent.mInstance && data.mInstanceIdent.mSubjectID == instance.mInstanceIdent.mSubjectID && data.mInstanceIdent.mServiceID == instance.mInstanceIdent.mServiceID; }); - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -aos::Error Storage::RemoveInstance(const aos::InstanceIdent& instanceIdent) +Error Storage::RemoveInstance(const aos::InstanceIdent& instanceIdent) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Remove instance: " << instanceIdent; - return mInstanceDatabase.Remove([&instanceIdent](const InstanceInfo& data) { + return mInstanceDatabase.Remove([&instanceIdent](const Storage::InstanceInfo& data) { return data.mInstanceIdent.mInstance == instanceIdent.mInstance && data.mInstanceIdent.mSubjectID == instanceIdent.mSubjectID && data.mInstanceIdent.mServiceID == instanceIdent.mServiceID; }); - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -aos::Error Storage::GetAllInstances(aos::Array& instances) +Error Storage::GetAllInstances(Array& instances) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Get all instances"; - auto err = mInstanceDatabase.ReadRecords([&instances, this](const InstanceInfo& instanceInfo) -> aos::Error { + auto err = mInstanceDatabase.ReadRecords([&instances, this](const Storage::InstanceInfo& instanceInfo) -> Error { auto instance = ConvertInstanceInfo(instanceInfo); auto err = instances.PushBack(*instance); @@ -108,59 +108,60 @@ aos::Error Storage::GetAllInstances(aos::Array& instances) return AOS_ERROR_WRAP(err); } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; }); return err; } // cppcheck-suppress unusedFunction -aos::Error Storage::AddService(const aos::sm::servicemanager::ServiceData& service) +Error Storage::AddService(const sm::servicemanager::ServiceData& service) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); - LOG_DBG() << "Add service: " << service.mServiceID; + LOG_DBG() << "Add service: id=" << service.mServiceID << ", version=" << service.mVersion; auto storageService = ConvertServiceData(service); - return mServiceDatabase.Add(*storageService, [](const ServiceData& storedService, const ServiceData& addedService) { - return strcmp(storedService.mServiceID, addedService.mServiceID) == 0 - && storedService.mVersionInfo.mAosVersion == addedService.mVersionInfo.mAosVersion; - }); + return mServiceDatabase.Add( + *storageService, [](const Storage::ServiceData& storedService, const Storage::ServiceData& addedService) { + return strcmp(storedService.mServiceID, addedService.mServiceID) == 0 + && strcmp(storedService.mVersion, addedService.mVersion) == 0; + }); } // cppcheck-suppress unusedFunction -aos::Error Storage::UpdateService(const aos::sm::servicemanager::ServiceData& service) +Error Storage::UpdateService(const sm::servicemanager::ServiceData& service) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Update service: " << service.mServiceID; auto storageService = ConvertServiceData(service); - return mServiceDatabase.Update( - *storageService, [&service](const ServiceData& data) { return data.mServiceID == service.mServiceID; }); + return mServiceDatabase.Update(*storageService, + [&service](const Storage::ServiceData& data) { return data.mServiceID == service.mServiceID; }); } -aos::Error Storage::RemoveService(const aos::String& serviceID, uint64_t aosVersion) +Error Storage::RemoveService(const String& serviceID, const String& version) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); - LOG_DBG() << "Remove service: " << serviceID; + LOG_DBG() << "Remove service: id=" << serviceID << ", version=" << version; - return mServiceDatabase.Remove([&serviceID, aosVersion](const ServiceData& data) { - return data.mServiceID == serviceID && data.mVersionInfo.mAosVersion == aosVersion; + return mServiceDatabase.Remove([&serviceID, &version](const Storage::ServiceData& data) { + return data.mServiceID == serviceID && data.mVersion == version; }); } // cppcheck-suppress unusedFunction -aos::Error Storage::GetAllServices(aos::Array& services) +Error Storage::GetAllServices(Array& services) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Get all services"; - auto err = mServiceDatabase.ReadRecords([&services, this](const ServiceData& serviceData) -> aos::Error { + auto err = mServiceDatabase.ReadRecords([&services, this](const Storage::ServiceData& serviceData) -> Error { auto service = ConvertServiceData(serviceData); auto err = services.PushBack(*service); @@ -168,44 +169,44 @@ aos::Error Storage::GetAllServices(aos::Array Storage::GetService(const aos::String& serviceID) +RetWithError Storage::GetService(const String& serviceID) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Get service: " << serviceID; - aos::UniquePtr serviceData = aos::MakeUnique(&mAllocator); + UniquePtr serviceData = MakeUnique(&mAllocator); auto err = mServiceDatabase.ReadRecordByFilter( - *serviceData, [&serviceID](const ServiceData& data) { return data.mServiceID == serviceID; }); + *serviceData, [&serviceID](const Storage::ServiceData data) { return data.mServiceID == serviceID; }); if (!err.IsNone()) { - return aos::RetWithError(aos::sm::servicemanager::ServiceData {}, err); + return RetWithError(sm::servicemanager::ServiceData {}, err); } auto retServiceData = ConvertServiceData(*serviceData); - return aos::RetWithError(*retServiceData); + return RetWithError(*retServiceData); } // cppcheck-suppress unusedFunction -aos::Error Storage::AddCertInfo(const aos::String& certType, const aos::iam::certhandler::CertInfo& certInfo) +Error Storage::AddCertInfo(const String& certType, const iam::certhandler::CertInfo& certInfo) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Add cert info: " << certType; auto storageCertInfo = ConvertCertInfo(certType, certInfo); - return mCertDatabase.Add( - *storageCertInfo, [&storageCertInfo](const CertInfo& storedCertInfo, const CertInfo& addedCertInfo) { + return mCertDatabase.Add(*storageCertInfo, + [&storageCertInfo](const Storage::CertInfo& storedCertInfo, const Storage::CertInfo& addedCertInfo) { return strcmp(storedCertInfo.mCertType, addedCertInfo.mCertType) == 0 && storedCertInfo.mIssuerSize == addedCertInfo.mIssuerSize && storedCertInfo.mSerialSize == addedCertInfo.mSerialSize @@ -215,39 +216,40 @@ aos::Error Storage::AddCertInfo(const aos::String& certType, const aos::iam::cer } // cppcheck-suppress unusedFunction -aos::Error Storage::RemoveCertInfo(const aos::String& certType, const aos::String& certURL) +Error Storage::RemoveCertInfo(const String& certType, const String& certURL) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Remove cert info: " << certType; - return mCertDatabase.Remove( - [&certType, &certURL](const CertInfo& data) { return data.mCertType == certType && data.mCertURL == certURL; }); + return mCertDatabase.Remove([&certType, &certURL](const Storage::CertInfo& data) { + return data.mCertType == certType && data.mCertURL == certURL; + }); } // cppcheck-suppress unusedFunction -aos::Error Storage::RemoveAllCertsInfo(const aos::String& certType) +Error Storage::RemoveAllCertsInfo(const String& certType) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Remove all cert info: " << certType; - auto err = mCertDatabase.Remove([&certType](const CertInfo& data) { return data.mCertType == certType; }); - if (!err.IsNone() && !err.Is(aos::ErrorEnum::eNotFound)) { + auto err = mCertDatabase.Remove([&certType](const Storage::CertInfo& data) { return data.mCertType == certType; }); + if (!err.IsNone() && !err.Is(ErrorEnum::eNotFound)) { return err; } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -aos::Error Storage::GetCertsInfo(const aos::String& certType, aos::Array& certsInfo) +Error Storage::GetCertsInfo(const String& certType, Array& certsInfo) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Get cert info: " << certType; - auto err = mCertDatabase.ReadRecords([&certsInfo, &certType, this](const CertInfo& certInfo) -> aos::Error { + auto err = mCertDatabase.ReadRecords([&certsInfo, &certType, this](const Storage::CertInfo& certInfo) -> Error { if (certInfo.mCertType == certType) { auto cert = ConvertCertInfo(certInfo); @@ -257,25 +259,24 @@ aos::Error Storage::GetCertsInfo(const aos::String& certType, aos::Array& issuer, const aos::Array& serial, aos::iam::certhandler::CertInfo& cert) +Error Storage::GetCertInfo(const Array& issuer, const Array& serial, iam::certhandler::CertInfo& cert) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Get cert info by issuer and serial"; - aos::UniquePtr certInfo = aos::MakeUnique(&mAllocator); + UniquePtr certInfo = MakeUnique(&mAllocator); - auto err = mCertDatabase.ReadRecordByFilter(*certInfo, [&issuer, &serial](const CertInfo& data) { - aos::Array issuerArray(data.mIssuer, data.mIssuerSize); - aos::Array serialArray(data.mSerial, data.mSerialSize); + auto err = mCertDatabase.ReadRecordByFilter(*certInfo, [&issuer, &serial](const Storage::CertInfo& data) { + Array issuerArray(data.mIssuer, data.mIssuerSize); + Array serialArray(data.mSerial, data.mSerialSize); return issuerArray == issuer && serialArray == serial; }); @@ -288,16 +289,16 @@ aos::Error Storage::GetCertInfo( cert = *retCertInfo; - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } /*********************************************************************************************************************** * Private **********************************************************************************************************************/ -aos::UniquePtr Storage::ConvertInstanceInfo(const aos::InstanceInfo& instance) +UniquePtr Storage::ConvertInstanceInfo(const aos::InstanceInfo& instance) { - aos::UniquePtr instanceInfo = aos::MakeUnique(&mAllocator); + UniquePtr instanceInfo = MakeUnique(&mAllocator); instanceInfo->mInstanceIdent.mInstance = instance.mInstanceIdent.mInstance; strcpy(instanceInfo->mInstanceIdent.mSubjectID, instance.mInstanceIdent.mSubjectID.CStr()); @@ -310,9 +311,9 @@ aos::UniquePtr Storage::ConvertInstanceInfo(const aos::In return instanceInfo; } -aos::UniquePtr Storage::ConvertInstanceInfo(const InstanceInfo& instance) +UniquePtr Storage::ConvertInstanceInfo(const Storage::InstanceInfo& instance) { - aos::UniquePtr instanceInfo = aos::MakeUnique(&mAllocator); + UniquePtr instanceInfo = MakeUnique(&mAllocator); instanceInfo->mInstanceIdent.mInstance = instance.mInstanceIdent.mInstance; instanceInfo->mInstanceIdent.mSubjectID = instance.mInstanceIdent.mSubjectID; @@ -325,39 +326,34 @@ aos::UniquePtr Storage::ConvertInstanceInfo(const InstanceInf return instanceInfo; } -aos::UniquePtr Storage::ConvertServiceData(const aos::sm::servicemanager::ServiceData& service) +UniquePtr Storage::ConvertServiceData(const sm::servicemanager::ServiceData& service) { - aos::UniquePtr serviceData = aos::MakeUnique(&mAllocator); + UniquePtr serviceData = MakeUnique(&mAllocator); - serviceData->mVersionInfo.mAosVersion = service.mVersionInfo.mAosVersion; - strcpy(serviceData->mVersionInfo.mVendorVersion, service.mVersionInfo.mVendorVersion.CStr()); - strcpy(serviceData->mVersionInfo.mDescription, service.mVersionInfo.mDescription.CStr()); strcpy(serviceData->mServiceID, service.mServiceID.CStr()); strcpy(serviceData->mProviderID, service.mProviderID.CStr()); + strcpy(serviceData->mVersion, service.mVersion.CStr()); strcpy(serviceData->mImagePath, service.mImagePath.CStr()); return serviceData; } -aos::UniquePtr Storage::ConvertServiceData(const Storage::ServiceData& service) +UniquePtr Storage::ConvertServiceData(const Storage::ServiceData& service) { - aos::UniquePtr serviceData - = aos::MakeUnique(&mAllocator); + UniquePtr serviceData = MakeUnique(&mAllocator); - serviceData->mVersionInfo.mAosVersion = service.mVersionInfo.mAosVersion; - serviceData->mVersionInfo.mVendorVersion = service.mVersionInfo.mVendorVersion; - serviceData->mVersionInfo.mDescription = service.mVersionInfo.mDescription; - serviceData->mServiceID = service.mServiceID; - serviceData->mProviderID = service.mProviderID; - serviceData->mImagePath = service.mImagePath; + serviceData->mServiceID = service.mServiceID; + serviceData->mProviderID = service.mProviderID; + serviceData->mVersion = service.mVersion; + serviceData->mImagePath = service.mImagePath; return serviceData; } -aos::UniquePtr Storage::ConvertCertInfo( - const aos::String& certType, const aos::iam::certhandler::CertInfo& certInfo) +UniquePtr Storage::ConvertCertInfo( + const String& certType, const iam::certhandler::CertInfo& certInfo) { - aos::UniquePtr cert = aos::MakeUnique(&mAllocator); + UniquePtr cert = MakeUnique(&mAllocator); memcpy(cert->mIssuer, certInfo.mIssuer.Get(), certInfo.mIssuer.Size()); memcpy(cert->mSerial, certInfo.mSerial.Get(), certInfo.mSerial.Size()); @@ -371,16 +367,17 @@ aos::UniquePtr Storage::ConvertCertInfo( return cert; } -aos::UniquePtr Storage::ConvertCertInfo(const Storage::CertInfo& certInfo) +UniquePtr Storage::ConvertCertInfo(const Storage::CertInfo& certInfo) { - aos::UniquePtr cert - = aos::MakeUnique(&mAllocator); + UniquePtr cert = MakeUnique(&mAllocator); - cert->mIssuer = aos::Array(certInfo.mIssuer, certInfo.mIssuerSize); - cert->mSerial = aos::Array(certInfo.mSerial, certInfo.mSerialSize); + cert->mIssuer = Array(certInfo.mIssuer, certInfo.mIssuerSize); + cert->mSerial = Array(certInfo.mSerial, certInfo.mSerialSize); cert->mCertURL = certInfo.mCertURL; cert->mKeyURL = certInfo.mKeyURL; - cert->mNotAfter = aos::Time::Unix(certInfo.mNotAfter.tv_sec, certInfo.mNotAfter.tv_nsec); + cert->mNotAfter = Time::Unix(certInfo.mNotAfter.tv_sec, certInfo.mNotAfter.tv_nsec); return cert; } + +} // namespace aos::zephyr::storage diff --git a/src/storage/storage.hpp b/src/storage/storage.hpp index d9bfebe4..3ade1f56 100644 --- a/src/storage/storage.hpp +++ b/src/storage/storage.hpp @@ -15,19 +15,21 @@ #include "filestorage.hpp" +namespace aos::zephyr::storage { + /** * Storage instance. */ -class Storage : public aos::sm::launcher::StorageItf, - public aos::sm::servicemanager::StorageItf, - public aos::iam::certhandler::StorageItf, - private aos::NonCopyable { +class Storage : public sm::launcher::StorageItf, + public sm::servicemanager::StorageItf, + public iam::certhandler::StorageItf, + private NonCopyable { public: /** * Initializes storage instance. - * @return aos::Error. + * @return Error. */ - aos::Error Init(); + Error Init(); /** * Adds new instance to storage. @@ -35,7 +37,7 @@ class Storage : public aos::sm::launcher::StorageItf, * @param instance instance to add. * @return Error. */ - aos::Error AddInstance(const aos::InstanceInfo& instance) override; + Error AddInstance(const aos::InstanceInfo& instance) override; /** * Updates previously stored instance. @@ -43,7 +45,7 @@ class Storage : public aos::sm::launcher::StorageItf, * @param instance instance to update. * @return Error. */ - aos::Error UpdateInstance(const aos::InstanceInfo& instance) override; + Error UpdateInstance(const aos::InstanceInfo& instance) override; /** * Removes previously stored instance. @@ -51,7 +53,7 @@ class Storage : public aos::sm::launcher::StorageItf, * @param instanceID instance ID to remove. * @return Error. */ - aos::Error RemoveInstance(const aos::InstanceIdent& instanceIdent) override; + Error RemoveInstance(const aos::InstanceIdent& instanceIdent) override; /** * Returns all stored instances. @@ -59,7 +61,7 @@ class Storage : public aos::sm::launcher::StorageItf, * @param instances array to return stored instances. * @return Error. */ - aos::Error GetAllInstances(aos::Array& instances) override; + Error GetAllInstances(Array& instances) override; /** * Adds new service to storage. @@ -67,7 +69,7 @@ class Storage : public aos::sm::launcher::StorageItf, * @param service service to add. * @return Error. */ - aos::Error AddService(const aos::sm::servicemanager::ServiceData& service) override; + Error AddService(const sm::servicemanager::ServiceData& service) override; /** * Updates previously stored service. @@ -75,7 +77,7 @@ class Storage : public aos::sm::launcher::StorageItf, * @param service service to update. * @return Error. */ - aos::Error UpdateService(const aos::sm::servicemanager::ServiceData& service) override; + Error UpdateService(const sm::servicemanager::ServiceData& service) override; /** * Removes previously stored service. @@ -84,7 +86,7 @@ class Storage : public aos::sm::launcher::StorageItf, * @param aosVersion Aos service version. * @return Error. */ - aos::Error RemoveService(const aos::String& serviceID, uint64_t aosVersion) override; + Error RemoveService(const String& serviceID, const String& version) override; /** * Returns all stored services. @@ -92,7 +94,7 @@ class Storage : public aos::sm::launcher::StorageItf, * @param services array to return stored services. * @return Error. */ - aos::Error GetAllServices(aos::Array& services) override; + Error GetAllServices(Array& services) override; /** * Returns service data by service ID. @@ -100,7 +102,7 @@ class Storage : public aos::sm::launcher::StorageItf, * @param serviceID service ID. * @return RetWithError. */ - aos::RetWithError GetService(const aos::String& serviceID) override; + RetWithError GetService(const String& serviceID) override; /** * Adds new certificate info to the storage. @@ -109,7 +111,7 @@ class Storage : public aos::sm::launcher::StorageItf, * @param certInfo certificate information. * @return Error. */ - aos::Error AddCertInfo(const aos::String& certType, const aos::iam::certhandler::CertInfo& certInfo) override; + Error AddCertInfo(const String& certType, const iam::certhandler::CertInfo& certInfo) override; /** * Returns information about certificate with specified issuer and serial number. @@ -119,8 +121,8 @@ class Storage : public aos::sm::launcher::StorageItf, * @param cert result certificate. * @return Error. */ - aos::Error GetCertInfo(const aos::Array& issuer, const aos::Array& serial, - aos::iam::certhandler::CertInfo& cert) override; + Error GetCertInfo( + const Array& issuer, const Array& serial, iam::certhandler::CertInfo& cert) override; /** * Returns info for all certificates with specified certificate type. @@ -129,8 +131,7 @@ class Storage : public aos::sm::launcher::StorageItf, * @param[out] certsInfo result certificates info. * @return Error. */ - aos::Error GetCertsInfo( - const aos::String& certType, aos::Array& certsInfo) override; + Error GetCertsInfo(const String& certType, Array& certsInfo) override; /** * Removes certificate with specified certificate type and url. @@ -139,7 +140,7 @@ class Storage : public aos::sm::launcher::StorageItf, * @param certURL certificate URL. * @return Error. */ - aos::Error RemoveCertInfo(const aos::String& certType, const aos::String& certURL) override; + Error RemoveCertInfo(const String& certType, const String& certURL) override; /** * Removes all certificates with specified certificate type. @@ -147,14 +148,14 @@ class Storage : public aos::sm::launcher::StorageItf, * @param certType certificate type. * @return Error. */ - aos::Error RemoveAllCertsInfo(const aos::String& certType) override; + Error RemoveAllCertsInfo(const String& certType) override; private: constexpr static auto cStoragePath = CONFIG_AOS_STORAGE_DIR; struct InstanceIdent { - char mServiceID[aos::cServiceIDLen + 1]; - char mSubjectID[aos::cSubjectIDLen + 1]; + char mServiceID[cServiceIDLen + 1]; + char mSubjectID[cSubjectIDLen + 1]; uint64_t mInstance; /** @@ -171,11 +172,11 @@ class Storage : public aos::sm::launcher::StorageItf, }; struct InstanceInfo { - InstanceIdent mInstanceIdent; - uint32_t mUID; - uint64_t mPriority; - char mStoragePath[aos::cFilePathLen + 1]; - char mStatePath[aos::cFilePathLen + 1]; + Storage::InstanceIdent mInstanceIdent; + uint32_t mUID; + uint64_t mPriority; + char mStoragePath[cFilePathLen + 1]; + char mStatePath[cFilePathLen + 1]; /** * Compares instance info. @@ -190,29 +191,11 @@ class Storage : public aos::sm::launcher::StorageItf, } }; - struct VersionInfo { - uint64_t mAosVersion; - char mVendorVersion[aos::cVersionLen + 1]; - char mDescription[aos::cDescriptionLen + 1]; - - /** - * Compares version info. - * - * @param version info to compare. - * @return bool. - */ - bool operator==(const VersionInfo& rhs) const - { - return mAosVersion == rhs.mAosVersion && strcmp(mVendorVersion, rhs.mVendorVersion) == 0 - && strcmp(mDescription, rhs.mDescription) == 0; - } - }; - struct ServiceData { - VersionInfo mVersionInfo; - char mServiceID[aos::cServiceIDLen + 1]; - char mProviderID[aos::cProviderIDLen + 1]; - char mImagePath[aos::cFilePathLen + 1]; + char mServiceID[cServiceIDLen + 1]; + char mProviderID[cProviderIDLen + 1]; + char mVersion[cVersionLen + 1]; + char mImagePath[cFilePathLen + 1]; /** * Compares service data. @@ -222,19 +205,19 @@ class Storage : public aos::sm::launcher::StorageItf, */ bool operator==(const ServiceData& rhs) const { - return mVersionInfo == rhs.mVersionInfo && strcmp(mServiceID, rhs.mServiceID) == 0 - && strcmp(mProviderID, rhs.mProviderID) == 0 && strcmp(mImagePath, rhs.mImagePath) == 0; + return strcmp(mServiceID, rhs.mServiceID) == 0 && strcmp(mProviderID, rhs.mProviderID) == 0 + && strcmp(mVersion, rhs.mVersion) == 0 && strcmp(mImagePath, rhs.mImagePath) == 0; } }; struct CertInfo { - uint8_t mIssuer[aos::crypto::cCertIssuerSize]; + uint8_t mIssuer[crypto::cCertIssuerSize]; size_t mIssuerSize; - uint8_t mSerial[aos::crypto::cSerialNumSize]; + uint8_t mSerial[crypto::cSerialNumSize]; size_t mSerialSize; - char mCertURL[aos::cURLLen + 1]; - char mKeyURL[aos::cURLLen + 1]; - char mCertType[aos::iam::certhandler::cCertTypeLen + 1]; + char mCertURL[cURLLen + 1]; + char mKeyURL[cURLLen + 1]; + char mCertType[iam::certhandler::cCertTypeLen + 1]; timespec mNotAfter; /** @@ -253,23 +236,24 @@ class Storage : public aos::sm::launcher::StorageItf, } }; - aos::UniquePtr ConvertInstanceInfo(const aos::InstanceInfo& instance); - aos::UniquePtr ConvertInstanceInfo(const InstanceInfo& instance); - aos::UniquePtr ConvertServiceData(const aos::sm::servicemanager::ServiceData& service); - aos::UniquePtr ConvertServiceData(const ServiceData& service); - aos::UniquePtr ConvertCertInfo( - const aos::String& certType, const aos::iam::certhandler::CertInfo& certInfo); - aos::UniquePtr ConvertCertInfo(const CertInfo& certInfo); - - FileStorage mInstanceDatabase; - FileStorage mServiceDatabase; - FileStorage mCertDatabase; - aos::Mutex mMutex; - - aos::StaticAllocator + UniquePtr ConvertInstanceInfo(const aos::InstanceInfo& instance); + UniquePtr ConvertInstanceInfo(const Storage::InstanceInfo& instance); + UniquePtr ConvertServiceData(const sm::servicemanager::ServiceData& service); + UniquePtr ConvertServiceData(const Storage::ServiceData& service); + UniquePtr ConvertCertInfo(const String& certType, const iam::certhandler::CertInfo& certInfo); + UniquePtr ConvertCertInfo(const Storage::CertInfo& certInfo); + + FileStorage mInstanceDatabase; + FileStorage mServiceDatabase; + FileStorage mCertDatabase; + Mutex mMutex; + + StaticAllocator mAllocator; }; +} // namespace aos::zephyr::storage + #endif diff --git a/tests/storage/CMakeLists.txt b/tests/storage/CMakeLists.txt index dffe2949..f8fe8662 100644 --- a/tests/storage/CMakeLists.txt +++ b/tests/storage/CMakeLists.txt @@ -9,25 +9,27 @@ project(storage_test) # Config # ###################################################################################################################### -set(AOS_CORE_CONFIG aoscoreconfig.hpp) +set(aoscore_config aoscoreconfig.hpp) +set(aoscore_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../../../aos_core_lib_cpp") # ###################################################################################################################### # Definitions # ###################################################################################################################### # Aos core configuration -add_definitions(-include ${AOS_CORE_CONFIG}) +add_definitions(-include ${aoscore_config}) # ###################################################################################################################### # Includes # ###################################################################################################################### -target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../src) -target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../../aos_core_lib_cpp/include) -target_include_directories(app PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +zephyr_include_directories(${aoscore_source_dir}/include) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/..) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/../../src) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src) # ###################################################################################################################### # Target # ###################################################################################################################### -target_sources(app PRIVATE src/main.cpp ../../src/storage/storage.cpp ../../src/utils/checksum.cpp) +target_sources(app PRIVATE src/main.cpp ../utils/log.cpp ../../src/storage/storage.cpp ../../src/utils/checksum.cpp) diff --git a/tests/storage/prj.conf b/tests/storage/prj.conf index 40ffbd73..055a08e3 100644 --- a/tests/storage/prj.conf +++ b/tests/storage/prj.conf @@ -1,6 +1,8 @@ # Enable C++ CONFIG_CPP=y -CONFIG_STD_CPP14=y +CONFIG_STD_CPP17=y +CONFIG_EXTERNAL_LIBCPP=y +CONFIG_CBPRINTF_FP_SUPPORT=y # Enable test suit CONFIG_ZTEST=y diff --git a/tests/storage/src/main.cpp b/tests/storage/src/main.cpp index be686400..5d19c5a4 100644 --- a/tests/storage/src/main.cpp +++ b/tests/storage/src/main.cpp @@ -12,6 +12,9 @@ #include #include "storage/storage.hpp" +#include "utils/log.hpp" + +using namespace aos::zephyr; static const aos::Array StringToDN(const char* str) { @@ -20,16 +23,11 @@ static const aos::Array StringToDN(const char* str) ZTEST_SUITE(storage, NULL, NULL, NULL, NULL, NULL); -void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message) -{ - printk("[storage] %s \n", message.CStr()); -} - ZTEST(storage, test_AddUpdateRemoveInstance) { aos::Log::SetCallback(TestLogCallback); - Storage storage; + storage::Storage storage; zassert_equal(storage.Init(), aos::ErrorEnum::eNone, "Failed to initialize storage"); @@ -112,29 +110,27 @@ ZTEST(storage, test_AddUpdateRemoveService) { aos::Log::SetCallback(TestLogCallback); - Storage storage; + storage::Storage storage; zassert_equal(storage.Init(), aos::ErrorEnum::eNone, "Failed to initialize storage"); aos::StaticArray services; aos::sm::servicemanager::ServiceData serviceData; - serviceData.mVersionInfo.mAosVersion = 1; - serviceData.mVersionInfo.mVendorVersion = "vendor_version"; - serviceData.mVersionInfo.mDescription = "description"; - serviceData.mServiceID = "service_id"; - serviceData.mProviderID = "provider_id"; - serviceData.mImagePath = "image_path"; + + serviceData.mServiceID = "service_id"; + serviceData.mProviderID = "provider_id"; + serviceData.mVersion = "1.0.0"; + serviceData.mImagePath = "image_path"; services.PushBack(serviceData); aos::sm::servicemanager::ServiceData serviceData2; - serviceData2.mVersionInfo.mAosVersion = 2; - serviceData2.mVersionInfo.mVendorVersion = "vendor_version2"; - serviceData2.mVersionInfo.mDescription = "description2"; - serviceData2.mServiceID = "service_id2"; - serviceData2.mProviderID = "provider_id2"; - serviceData2.mImagePath = "image_path2"; + + serviceData2.mServiceID = "service_id2"; + serviceData2.mProviderID = "provider_id2"; + serviceData2.mVersion = "2.0.0"; + serviceData2.mImagePath = "image_path2"; services.PushBack(serviceData2); @@ -164,6 +160,10 @@ ZTEST(storage, test_AddUpdateRemoveService) auto ret = storage.GetService(serviceID); zassert_equal(ret.mError, aos::ErrorEnum::eNone, "Failed to get service"); + + printk("serviceID: %s\n", serviceData.mVersion.CStr()); + printk("serviceID: %s\n", ret.mValue.mVersion.CStr()); + zassert_equal(ret.mValue, serviceData, "Unexpected service"); services[0].mImagePath = "image_path3"; @@ -183,8 +183,8 @@ ZTEST(storage, test_AddUpdateRemoveService) } for (const auto& service : services) { - zassert_equal(storage.RemoveService(service.mServiceID, service.mVersionInfo.mAosVersion), - aos::ErrorEnum::eNone, "Failed to remove service"); + zassert_equal(storage.RemoveService(service.mServiceID, service.mVersion), aos::ErrorEnum::eNone, + "Failed to remove service"); } services2.Clear(); @@ -197,7 +197,7 @@ ZTEST(storage, test_AddRemoveCertInfo) { aos::Log::SetCallback(TestLogCallback); - Storage storage; + storage::Storage storage; zassert_equal(storage.Init(), aos::ErrorEnum::eNone, "Failed to initialize storage"); From d138e9e5ef57c4a5c1803f58fb6ecffb032f65ab Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sat, 17 Aug 2024 17:40:54 +0300 Subject: [PATCH 032/198] [provisioning] Remove outdated provisioning module Provision manager from aos::iam will be used instead. Signed-off-by: Oleksandr Grytsov --- CMakeLists.txt | 1 - Kconfig | 4 -- src/provisioning/log.hpp | 15 ----- src/provisioning/provisioning.cpp | 54 --------------- src/provisioning/provisioning.hpp | 71 -------------------- tests/provisioning/CMakeLists.txt | 41 ------------ tests/provisioning/Kconfig | 12 ---- tests/provisioning/prj.conf | 24 ------- tests/provisioning/src/main.cpp | 107 ------------------------------ tests/provisioning/testcase.yaml | 6 -- 10 files changed, 335 deletions(-) delete mode 100644 src/provisioning/log.hpp delete mode 100644 src/provisioning/provisioning.cpp delete mode 100644 src/provisioning/provisioning.hpp delete mode 100644 tests/provisioning/CMakeLists.txt delete mode 100644 tests/provisioning/Kconfig delete mode 100644 tests/provisioning/prj.conf delete mode 100644 tests/provisioning/src/main.cpp delete mode 100644 tests/provisioning/testcase.yaml diff --git a/CMakeLists.txt b/CMakeLists.txt index 5459a405..907f138e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,7 +82,6 @@ target_sources( src/monitoring/resourceusageprovider.cpp src/nodeinfoprovider/nodeinfoprovider.cpp src/ocispec/ocispec.cpp - src/provisioning/provisioning.cpp src/resourcemanager/resourcemanager.cpp src/runner/runner.cpp src/smclient/openhandler.cpp diff --git a/Kconfig b/Kconfig index 8495f672..10fd2ba1 100644 --- a/Kconfig +++ b/Kconfig @@ -77,10 +77,6 @@ config AOS_MAX_CPU_DMIPS int "Maximum CPU DMIPS" default 10000 -config AOS_PROVISIONING_FILE - string "Path to provisioning file." - default "/aos/.provisioned" - config AOS_PROVISION_STATE_FILE string "Path to provisioning state file." default "/aos/.provisionstate" diff --git a/src/provisioning/log.hpp b/src/provisioning/log.hpp deleted file mode 100644 index 26c6bc82..00000000 --- a/src/provisioning/log.hpp +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2024 Renesas Electronics Corporation. - * Copyright (C) 2024 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef LOG_HPP_ -#define LOG_HPP_ - -#define LOG_MODULE "provisioning" - -#include - -#endif diff --git a/src/provisioning/provisioning.cpp b/src/provisioning/provisioning.cpp deleted file mode 100644 index 3f4a9bfb..00000000 --- a/src/provisioning/provisioning.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2024 Renesas Electronics Corporation. - * Copyright (C) 2024 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include "log.hpp" -#include "provisioning.hpp" - -/*********************************************************************************************************************** - * Public - **********************************************************************************************************************/ - -aos::Error Provisioning::Init() -{ - LOG_DBG() << "Init provisioning"; - - aos::StaticString payload; - - auto err = aos::FS::ReadFileToString(cProvisioningFile, payload); - if (!err.IsNone() || payload != cProvisioningText) { - LOG_INF() << "Unit is not provisioned"; - - mProvisioned = false; - } else { - LOG_DBG() << "Unit is provisioned"; - - mProvisioned = true; - } - - return aos::ErrorEnum::eNone; -} - -aos::Error Provisioning::FinishProvisioning() -{ - auto err = aos::FS::MakeDirAll(aos::FS::Dir(cProvisioningFile)); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - err = aos::FS::WriteStringToFile(cProvisioningFile, cProvisioningText, 0600); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - mProvisioned = true; - - LOG_INF() << "Provisioning finished"; - - return aos::ErrorEnum::eNone; -} diff --git a/src/provisioning/provisioning.hpp b/src/provisioning/provisioning.hpp deleted file mode 100644 index 6074149c..00000000 --- a/src/provisioning/provisioning.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2024 Renesas Electronics Corporation. - * Copyright (C) 2024 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef AOS_PROVISIONING_HPP_ -#define AOS_PROVISIONING_HPP_ - -#include - -/** - * Provisioning interface. - */ -class ProvisioningItf { -public: - /** - * Finishes provisioning. - * - * @return aos::Error. - */ - virtual aos::Error FinishProvisioning() = 0; - - /** - * Synchronizes system clock. - * - * @return bool. - */ - virtual bool IsProvisioned() const = 0; - - /** - * Destructor. - */ - virtual ~ProvisioningItf() = default; -}; - -/** - * Provisioning instance. - */ -class Provisioning : public ProvisioningItf { -public: - /** - * Initializes provisioning. - * - * @return aos::Error. - */ - aos::Error Init(); - - /** - * Finishes aos::provisioning. - * - * @return Error. - */ - aos::Error FinishProvisioning() override; - - /** - * Synchronizes system clock. - * - * @return bool. - */ - bool IsProvisioned() const override { return mProvisioned; } - -private: - static constexpr auto cProvisioningFile = CONFIG_AOS_PROVISIONING_FILE; - static constexpr auto cProvisioningText = "provisioned"; - - bool mProvisioned = false; -}; - -#endif diff --git a/tests/provisioning/CMakeLists.txt b/tests/provisioning/CMakeLists.txt deleted file mode 100644 index 912a28f5..00000000 --- a/tests/provisioning/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) - -find_package( - Zephyr - COMPONENTS - REQUIRED HINTS $ENV{ZEPHYR_BASE} -) - -set(CMAKE_MODULE_PATH ${APPLICATION_SOURCE_DIR}/../../cmake) - -project(provisioning_test) - -# ###################################################################################################################### -# Config -# ###################################################################################################################### - -set(AOS_CORE_CONFIG aoscoreconfig.hpp) - -# ###################################################################################################################### -# Definitions -# ###################################################################################################################### - -# Aos core configuration -add_definitions(-include ${AOS_CORE_CONFIG}) - -# ###################################################################################################################### -# Includes -# ###################################################################################################################### - -target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../../aos_core_lib_cpp/include) -target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../src) -target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/src) -target_include_directories(app PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) - -# ###################################################################################################################### -# Target -# ###################################################################################################################### - -target_sources(app PRIVATE ../../src/provisioning/provisioning.cpp src/main.cpp) diff --git a/tests/provisioning/Kconfig b/tests/provisioning/Kconfig deleted file mode 100644 index dbc8dfe6..00000000 --- a/tests/provisioning/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (C) 2023 Renesas Electronics Corporation. -# Copyright (C) 2023 EPAM Systems, Inc. -# -# SPDX-License-Identifier: Apache-2.0 - -mainmenu "Aos zephyr application" - -config AOS_PROVISIONING_FILE - string "Path to provisioning file." - default "/tmp/aos/.provisioned" - -source "Kconfig" diff --git a/tests/provisioning/prj.conf b/tests/provisioning/prj.conf deleted file mode 100644 index b5f5cdaf..00000000 --- a/tests/provisioning/prj.conf +++ /dev/null @@ -1,24 +0,0 @@ -# Enable C++ - -CONFIG_CPP=y -CONFIG_STD_CPP14=y -CONFIG_EXTERNAL_LIBCPP=y -CONFIG_CBPRINTF_FP_SUPPORT=y - -# Enable test suit - -CONFIG_ZTEST=y - -# Enable debug for tests - -CONFIG_DEBUG=y -CONFIG_NO_OPTIMIZATIONS=y - -# Enable nanopb lib - -CONFIG_NANOPB=y - -# Enable tiny crypt lib - -CONFIG_TINYCRYPT=y -CONFIG_TINYCRYPT_SHA256=y diff --git a/tests/provisioning/src/main.cpp b/tests/provisioning/src/main.cpp deleted file mode 100644 index 1af2ae69..00000000 --- a/tests/provisioning/src/main.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2024 Renesas Electronics Corporation. - * Copyright (C) 2024 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include -#include - -#include -#include - -#include "provisioning/provisioning.hpp" - -/*********************************************************************************************************************** - * Types - **********************************************************************************************************************/ - -struct provisioning_fixture { - Provisioning mProvisioning; -}; - -/*********************************************************************************************************************** - * Setup - **********************************************************************************************************************/ - -void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message) -{ - static std::mutex mutex; - static auto startTime = std::chrono::steady_clock::now(); - - std::lock_guard lock(mutex); - - auto now = std::chrono::duration(std::chrono::steady_clock::now() - startTime).count(); - - const char* levelStr = "unknown"; - - switch (level.GetValue()) { - case aos::LogLevelEnum::eDebug: - levelStr = "dbg"; - break; - - case aos::LogLevelEnum::eInfo: - levelStr = "inf"; - break; - - case aos::LogLevelEnum::eWarning: - levelStr = "wrn"; - break; - - case aos::LogLevelEnum::eError: - levelStr = "err"; - break; - - default: - levelStr = "n/d"; - break; - } - - printk("%0.3f [%s] %s\n", now, levelStr, message.CStr()); -} - -ZTEST_SUITE( - provisioning, nullptr, - []() -> void* { - aos::Log::SetCallback(TestLogCallback); - - auto fixture = new provisioning_fixture; - - return fixture; - }, - [](void* fixture) { - auto err = aos::FS::RemoveAll(aos::FS::Dir(CONFIG_AOS_PROVISIONING_FILE)); - zassert_true(err.IsNone(), "Can't remove provisioning dir: %s", err.Message()); - }, - nullptr, - [](void* fixture) { - auto err = aos::FS::RemoveAll(aos::FS::Dir(CONFIG_AOS_PROVISIONING_FILE)); - zassert_true(err.IsNone(), "Can't remove provisioning dir: %s", err.Message()); - - delete static_cast(fixture); - }); - -/*********************************************************************************************************************** - * Tests - **********************************************************************************************************************/ - -ZTEST_F(provisioning, test_FinishProvisioning) -{ - auto err = fixture->mProvisioning.Init(); - zassert_true(err.IsNone(), "Can't initialize provisioning: %s", err.Message()); - - zassert_false(fixture->mProvisioning.IsProvisioned()); - - err = fixture->mProvisioning.FinishProvisioning(); - zassert_true(err.IsNone(), "Can't finish provisioning: %s", err.Message()); - - zassert_true(fixture->mProvisioning.IsProvisioned()); - - err = fixture->mProvisioning.Init(); - zassert_true(err.IsNone(), "Can't initialize provisioning: %s", err.Message()); - - zassert_true(fixture->mProvisioning.IsProvisioned()); -} diff --git a/tests/provisioning/testcase.yaml b/tests/provisioning/testcase.yaml deleted file mode 100644 index 1dd98df4..00000000 --- a/tests/provisioning/testcase.yaml +++ /dev/null @@ -1,6 +0,0 @@ -tests: - aoszephyrapp.provisioning: - build_only: false - tags: provisioning - timeout: 500 - platform_allow: native_posix_64 native_posix From c592beb89b73ec7c9d5012d5f02e0e6802a48fa3 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sat, 17 Aug 2024 17:50:23 +0300 Subject: [PATCH 033/198] [clocksync] Use condvar wait with duration and update unit tests Signed-off-by: Oleksandr Grytsov --- src/clocksync/clocksync.cpp | 8 +------- tests/clocksync/CMakeLists.txt | 2 +- tests/clocksync/src/main.cpp | 24 ++++++++++++------------ 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/clocksync/clocksync.cpp b/src/clocksync/clocksync.cpp index e5f6d715..a1966f26 100644 --- a/src/clocksync/clocksync.cpp +++ b/src/clocksync/clocksync.cpp @@ -24,13 +24,7 @@ Error ClockSync::Init(ClockSyncSenderItf& sender) while (true) { UniqueLock lock {mMutex}; -#ifdef CONFIG_NATIVE_APPLICATION - auto now = aos::Time::Now(); -#else - auto now = aos::Time::Now(CLOCK_MONOTONIC); -#endif - - mCondVar.Wait(lock, now.Add(cSendPeriod), [this] { return mStart || mClose || mSync; }); + mCondVar.Wait(lock, cSendPeriod, [this] { return mStart || mClose || mSync; }); if (mClose) { return; diff --git a/tests/clocksync/CMakeLists.txt b/tests/clocksync/CMakeLists.txt index 2d2d9ba1..cc9afd94 100644 --- a/tests/clocksync/CMakeLists.txt +++ b/tests/clocksync/CMakeLists.txt @@ -31,4 +31,4 @@ zephyr_include_directories(${CMAKE_CURRENT_BINARY_DIR}) # Target # ###################################################################################################################### -target_sources(app PRIVATE src/main.cpp ../utils/log.cpp ../utils/utils.cpp ../../src/clocksync/clocksync.cpp) +target_sources(app PRIVATE src/main.cpp ../utils/log.cpp ../../src/utils/utils.cpp ../../src/clocksync/clocksync.cpp) diff --git a/tests/clocksync/src/main.cpp b/tests/clocksync/src/main.cpp index eaf97965..036d64f6 100644 --- a/tests/clocksync/src/main.cpp +++ b/tests/clocksync/src/main.cpp @@ -17,7 +17,7 @@ #include "utils/log.hpp" #include "utils/utils.hpp" -using namespace aos::zephyr::clocksync; +using namespace aos::zephyr; /*********************************************************************************************************************** * Consts @@ -30,9 +30,9 @@ static constexpr auto cWaitTimeout = std::chrono::seconds {5}; **********************************************************************************************************************/ struct clocksync_fixture { - SenderStub mSender; - SubscriberStub mSubscriber; - ClockSync mClockSync; + SenderStub mSender; + SubscriberStub mSubscriber; + clocksync::ClockSync mClockSync; }; /*********************************************************************************************************************** @@ -47,10 +47,10 @@ ZTEST_SUITE( auto fixture = new clocksync_fixture; auto err = fixture->mClockSync.Init(fixture->mSender); - zassert_true(err.IsNone(), "Can't initialize clock sync: %s", AosErrorToStr(err)); + zassert_true(err.IsNone(), "Can't initialize clock sync: %s", utils::ErrorToCStr(err)); err = fixture->mClockSync.Subscribe(fixture->mSubscriber); - zassert_true(err.IsNone(), "Can't subscribe for clock sync: %s", AosErrorToStr(err)); + zassert_true(err.IsNone(), "Can't subscribe for clock sync: %s", utils::ErrorToCStr(err)); return fixture; }, @@ -68,18 +68,18 @@ ZTEST_SUITE( ZTEST_F(clocksync, test_Synced) { auto err = fixture->mClockSync.Start(); - zassert_true(err.IsNone(), "Error starting clock sync: %s", AosErrorToStr(err)); + zassert_true(err.IsNone(), "Error starting clock sync: %s", utils::ErrorToCStr(err)); err = fixture->mSender.WaitEvent(cWaitTimeout); - zassert_true(err.IsNone(), "Error waiting sync request: %s", AosErrorToStr(err)); + zassert_true(err.IsNone(), "Error waiting sync request: %s", utils::ErrorToCStr(err)); zassert_true(fixture->mSender.IsSyncRequest()); err = fixture->mClockSync.Sync(aos::Time::Now()); - zassert_true(err.IsNone(), "Error sync clock: %s", AosErrorToStr(err)); + zassert_true(err.IsNone(), "Error sync clock: %s", utils::ErrorToCStr(err)); err = fixture->mSubscriber.WaitEvent(cWaitTimeout); - zassert_true(err.IsNone(), "Error waiting clock synced: %s", AosErrorToStr(err)); + zassert_true(err.IsNone(), "Error waiting clock synced: %s", utils::ErrorToCStr(err)); zassert_true(fixture->mSubscriber.IsSynced()); } @@ -87,12 +87,12 @@ ZTEST_F(clocksync, test_Synced) ZTEST_F(clocksync, test_Unsynced) { auto err = fixture->mSubscriber.WaitEvent(cWaitTimeout); - zassert_true(err.IsNone(), "Error waiting clock unsynced: %s", AosErrorToStr(err)); + zassert_true(err.IsNone(), "Error waiting clock unsynced: %s", utils::ErrorToCStr(err)); zassert_false(fixture->mSubscriber.IsSynced()); err = fixture->mSender.WaitEvent(cWaitTimeout); - zassert_true(err.IsNone(), "Error waiting sync request: %s", AosErrorToStr(err)); + zassert_true(err.IsNone(), "Error waiting sync request: %s", utils::ErrorToCStr(err)); zassert_true(fixture->mSender.IsSyncRequest()); } From bbe3c308b4b2df713c90d72f764257bd8ba4824b Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sat, 17 Aug 2024 17:51:19 +0300 Subject: [PATCH 034/198] [donwloader] Move and aos::zephyr::downloader namespace Signed-off-by: Oleksandr Grytsov --- src/downloader/downloader.cpp | 44 ++++++++++--------- src/downloader/downloader.hpp | 76 +++++++++++++++++---------------- tests/downloader/CMakeLists.txt | 14 +++--- tests/downloader/prj.conf | 3 ++ tests/downloader/src/main.cpp | 32 ++++++-------- 5 files changed, 89 insertions(+), 80 deletions(-) diff --git a/src/downloader/downloader.cpp b/src/downloader/downloader.cpp index f086a55b..e48b3ea1 100644 --- a/src/downloader/downloader.cpp +++ b/src/downloader/downloader.cpp @@ -13,31 +13,33 @@ #include "downloader.hpp" #include "log.hpp" +namespace aos::zephyr::downloader { + /*********************************************************************************************************************** * Public **********************************************************************************************************************/ Downloader::~Downloader() { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); mFinishDownload = true; mWaitDownload.NotifyOne(); } -aos::Error Downloader::Init(DownloadRequesterItf& downloadRequester) +Error Downloader::Init(DownloadRequesterItf& downloadRequester) { LOG_DBG() << "Initialize downloader"; mDownloadRequester = &downloadRequester; - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -aos::Error Downloader::Download(const aos::String& url, const aos::String& path, aos::DownloadContent contentType) +Error Downloader::Download(const String& url, const String& path, DownloadContent contentType) { - aos::UniqueLock lock(mMutex); + UniqueLock lock(mMutex); LOG_DBG() << "Download: " << url; @@ -45,7 +47,7 @@ aos::Error Downloader::Download(const aos::String& url, const aos::String& path, mDownloadResults.Clear(); auto err = mTimer.Create( - Downloader::cDownloadTimeout, [this](void*) { SetErrorAndNotify(AOS_ERROR_WRAP(aos::ErrorEnum::eTimeout)); }); + Downloader::cDownloadTimeout, [this](void*) { SetErrorAndNotify(AOS_ERROR_WRAP(ErrorEnum::eTimeout)); }); if (!err.IsNone()) { LOG_DBG() << "Create timer failed: " << err; @@ -86,12 +88,12 @@ aos::Error Downloader::Download(const aos::String& url, const aos::String& path, return mErrProcessImageRequest; } -aos::Error Downloader::ReceiveFileChunk(const FileChunk& chunk) +Error Downloader::ReceiveFileChunk(const FileChunk& chunk) { LOG_DBG() << "Receive file chunk: path = " << chunk.mRelativePath << ", chunk = " << chunk.mPart << "/" << chunk.mPartsCount; - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); auto downloadResult = mDownloadResults.Find( [&chunk](const DownloadResult& result) { return result.mRelativePath == chunk.mRelativePath; }); @@ -105,10 +107,10 @@ aos::Error Downloader::ReceiveFileChunk(const FileChunk& chunk) } if (downloadResult.mValue->mFile == -1) { - auto path = aos::FS::JoinPath(mRequestedPath, chunk.mRelativePath); - auto dirPath = aos::FS::Dir(path); + auto path = FS::JoinPath(mRequestedPath, chunk.mRelativePath); + auto dirPath = FS::Dir(path); - auto err = aos::FS::MakeDirAll(dirPath); + auto err = FS::MakeDirAll(dirPath); if (!err.IsNone()) { err = AOS_ERROR_WRAP(errno); @@ -136,7 +138,7 @@ aos::Error Downloader::ReceiveFileChunk(const FileChunk& chunk) return err; } - mTimer.Reset([this](void*) { SetErrorAndNotify(AOS_ERROR_WRAP(aos::ErrorEnum::eTimeout)); }); + mTimer.Reset([this](void*) { SetErrorAndNotify(AOS_ERROR_WRAP(ErrorEnum::eTimeout)); }); if (chunk.mPart == chunk.mPartsCount) { ret = close(downloadResult.mValue->mFile); @@ -157,23 +159,23 @@ aos::Error Downloader::ReceiveFileChunk(const FileChunk& chunk) } } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error Downloader::ReceiveImageContentInfo(const ImageContentInfo& content) +Error Downloader::ReceiveImageContentInfo(const ImageContentInfo& content) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Receive image content info"; if (content.mRequestID != mRequestID) { - return AOS_ERROR_WRAP(aos::ErrorEnum::eFailed); + return AOS_ERROR_WRAP(ErrorEnum::eFailed); } if (content.mError != "") { LOG_ERR() << "Error: " << content.mError; - auto err = AOS_ERROR_WRAP(aos::ErrorEnum::eFailed); + auto err = AOS_ERROR_WRAP(ErrorEnum::eFailed); SetErrorAndNotify(err); @@ -184,9 +186,9 @@ aos::Error Downloader::ReceiveImageContentInfo(const ImageContentInfo& content) mDownloadResults.PushBack(DownloadResult {file.mRelativePath, -1, false}); } - mTimer.Reset([this](void*) { SetErrorAndNotify(AOS_ERROR_WRAP(aos::ErrorEnum::eTimeout)); }); + mTimer.Reset([this](void*) { SetErrorAndNotify(AOS_ERROR_WRAP(ErrorEnum::eTimeout)); }); - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } /*********************************************************************************************************************** @@ -204,9 +206,11 @@ bool Downloader::IsAllDownloadDone() const return true; } -void Downloader::SetErrorAndNotify(const aos::Error& err) +void Downloader::SetErrorAndNotify(const Error& err) { mFinishDownload = true; mErrProcessImageRequest = err; mWaitDownload.NotifyOne(); } + +} // namespace aos::zephyr::downloader diff --git a/src/downloader/downloader.hpp b/src/downloader/downloader.hpp index 178b995c..24a271d2 100644 --- a/src/downloader/downloader.hpp +++ b/src/downloader/downloader.hpp @@ -16,13 +16,15 @@ #include #include +namespace aos::zephyr::downloader { + /** * Image content request. */ struct ImageContentRequest { - aos::StaticString mURL; - uint64_t mRequestID; - aos::DownloadContent mContentType; + StaticString mURL; + uint64_t mRequestID; + DownloadContent mContentType; /** * Compares image content request. @@ -48,9 +50,9 @@ struct ImageContentRequest { * File info. */ struct FileInfo { - aos::StaticString mRelativePath; - aos::StaticArray mSHA256; - uint64_t mSize; + StaticString mRelativePath; + StaticArray mSHA256; + uint64_t mSize; /** * Compares file info. @@ -76,9 +78,9 @@ struct FileInfo { * Image content info. */ struct ImageContentInfo { - uint64_t mRequestID; - aos::StaticArray mFiles; - aos::StaticString mError; + uint64_t mRequestID; + StaticArray mFiles; + StaticString mError; /** * Compares content info. @@ -104,11 +106,11 @@ struct ImageContentInfo { * File chunk. */ struct FileChunk { - uint64_t mRequestID; - aos::StaticString mRelativePath; - uint64_t mPartsCount; - uint64_t mPart; - aos::StaticArray mData; + uint64_t mRequestID; + StaticString mRelativePath; + uint64_t mPartsCount; + uint64_t mPart; + StaticArray mData; /** * Compares file chunks. @@ -142,7 +144,7 @@ class DownloadRequesterItf { * @param request image content request * @return Error */ - virtual aos::Error SendImageContentRequest(const ImageContentRequest& request) = 0; + virtual Error SendImageContentRequest(const ImageContentRequest& request) = 0; /** * Destroys the Download Requester Itf object. @@ -162,7 +164,7 @@ class DownloadReceiverItf { * @param chunk file chunk * @return Error */ - virtual aos::Error ReceiveFileChunk(const FileChunk& chunk) = 0; + virtual Error ReceiveFileChunk(const FileChunk& chunk) = 0; /** * Receives image content info. @@ -170,7 +172,7 @@ class DownloadReceiverItf { * @param content image content info * @return Error */ - virtual aos::Error ReceiveImageContentInfo(const ImageContentInfo& content) = 0; + virtual Error ReceiveImageContentInfo(const ImageContentInfo& content) = 0; /** * Destroys the Download Receiver Itf object. @@ -182,7 +184,7 @@ class DownloadReceiverItf { * Downloader class. * */ -class Downloader : public aos::DownloaderItf, public DownloadReceiverItf { +class Downloader : public DownloaderItf, public DownloadReceiverItf { public: /** * Default constructor. @@ -200,7 +202,7 @@ class Downloader : public aos::DownloaderItf, public DownloadReceiverItf { * @param downloadRequester download requester instance. * @return Error */ - aos::Error Init(DownloadRequesterItf& downloadRequester); + Error Init(DownloadRequesterItf& downloadRequester); /** * Downloads file. @@ -210,7 +212,7 @@ class Downloader : public aos::DownloaderItf, public DownloadReceiverItf { * @param contentType content type. * @return Error */ - aos::Error Download(const aos::String& url, const aos::String& path, aos::DownloadContent contentType) override; + Error Download(const String& url, const String& path, DownloadContent contentType) override; /** * Receives image content request. @@ -218,7 +220,7 @@ class Downloader : public aos::DownloaderItf, public DownloadReceiverItf { * @param chunk file chunk * @return Error */ - aos::Error ReceiveFileChunk(const FileChunk& chunk) override; + Error ReceiveFileChunk(const FileChunk& chunk) override; /** * Receives image content info. @@ -226,29 +228,31 @@ class Downloader : public aos::DownloaderItf, public DownloadReceiverItf { * @param content image content info * @return Error */ - aos::Error ReceiveImageContentInfo(const ImageContentInfo& content) override; + Error ReceiveImageContentInfo(const ImageContentInfo& content) override; private: static constexpr auto cDownloadTimeout = 10000; struct DownloadResult { - aos::StaticString mRelativePath; - int mFile; - bool mIsDone; + StaticString mRelativePath; + int mFile; + bool mIsDone; }; bool IsAllDownloadDone() const; - void SetErrorAndNotify(const aos::Error& err); - - DownloadRequesterItf* mDownloadRequester {}; - aos::Mutex mMutex; - aos::ConditionalVariable mWaitDownload; - aos::Error mErrProcessImageRequest {}; - aos::StaticString mRequestedPath {}; - aos::StaticArray mDownloadResults {}; - aos::Timer mTimer {}; - uint64_t mRequestID {}; - bool mFinishDownload {false}; + void SetErrorAndNotify(const Error& err); + + DownloadRequesterItf* mDownloadRequester {}; + Mutex mMutex; + ConditionalVariable mWaitDownload; + Error mErrProcessImageRequest {}; + StaticString mRequestedPath {}; + StaticArray mDownloadResults {}; + Timer mTimer {}; + uint64_t mRequestID {}; + bool mFinishDownload {false}; }; +} // namespace aos::zephyr::downloader + #endif diff --git a/tests/downloader/CMakeLists.txt b/tests/downloader/CMakeLists.txt index 7172b7e7..d12ecde3 100644 --- a/tests/downloader/CMakeLists.txt +++ b/tests/downloader/CMakeLists.txt @@ -9,25 +9,27 @@ project(downloader_test) # Config # ###################################################################################################################### -set(AOS_CORE_CONFIG aoscoreconfig.hpp) +set(aoscore_config aoscoreconfig.hpp) +set(aoscore_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../../../aos_core_lib_cpp") # ###################################################################################################################### # Definitions # ###################################################################################################################### # Aos core configuration -add_definitions(-include ${AOS_CORE_CONFIG}) +add_definitions(-include ${aoscore_config}) # ###################################################################################################################### # Includes # ###################################################################################################################### -target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../src) -target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../../aos_core_lib_cpp/include) -target_include_directories(app PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +zephyr_include_directories(${aoscore_source_dir}/include) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/..) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/../../src) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src) # ###################################################################################################################### # Target # ###################################################################################################################### -target_sources(app PRIVATE src/main.cpp ../../src/downloader/downloader.cpp) +target_sources(app PRIVATE ../../src/downloader/downloader.cpp ../utils/log.cpp src/main.cpp) diff --git a/tests/downloader/prj.conf b/tests/downloader/prj.conf index b6be069f..45fd0d87 100644 --- a/tests/downloader/prj.conf +++ b/tests/downloader/prj.conf @@ -1,5 +1,8 @@ # Enable C++ CONFIG_CPP=y +CONFIG_STD_CPP17=y +CONFIG_EXTERNAL_LIBCPP=y +CONFIG_CBPRINTF_FP_SUPPORT=y CONFIG_ZTEST=y diff --git a/tests/downloader/src/main.cpp b/tests/downloader/src/main.cpp index 14808c95..673d67b3 100644 --- a/tests/downloader/src/main.cpp +++ b/tests/downloader/src/main.cpp @@ -17,46 +17,47 @@ #include #include "downloader/downloader.hpp" +#include "utils/log.hpp" -using namespace aos; +using namespace aos::zephyr; constexpr auto cDownloadPath = "download"; constexpr auto cFileName = "test.txt"; constexpr auto cDownloadUrl = "http://www.example.com"; constexpr auto cData = "file content"; -static Downloader downloader; +static downloader::Downloader sDownloader; void sendImageContentInfo(void*) { - aos::StaticArray files; - FileInfo file {}; + aos::StaticArray files; + downloader::FileInfo file {}; file.mRelativePath = cFileName; files.PushBack(file); - zassert_equal(downloader.ReceiveImageContentInfo(ImageContentInfo {1, files}), aos::ErrorEnum::eNone, + zassert_equal(sDownloader.ReceiveImageContentInfo(downloader::ImageContentInfo {1, files}), aos::ErrorEnum::eNone, "Failed to initialize downloader"); aos::StaticArray fileData {}; fileData.Resize(strlen(cData)); memcpy(fileData.Get(), cData, strlen(cData)); - FileChunk chunk {1, file.mRelativePath, 1, 1, fileData}; + downloader::FileChunk chunk {1, file.mRelativePath, 1, 1, fileData}; - zassert_equal(downloader.ReceiveFileChunk(chunk), aos::ErrorEnum::eNone, "Failed to receive file chunk"); + zassert_equal(sDownloader.ReceiveFileChunk(chunk), aos::ErrorEnum::eNone, "Failed to receive file chunk"); } static aos::Timer timerReceive {}; -class TestDownloadRequester : public DownloadRequesterItf { +class TestDownloadRequester : public downloader::DownloadRequesterItf { public: TestDownloadRequester(bool skipSendRequest = false) : mSkipSendRequest(skipSendRequest) { } - aos::Error SendImageContentRequest(const ImageContentRequest& request) override + aos::Error SendImageContentRequest(const downloader::ImageContentRequest& request) override { if (mSkipSendRequest) { return aos::ErrorEnum::eNone; @@ -83,11 +84,6 @@ class TestDownloadRequester : public DownloadRequesterItf { bool mSkipSendRequest; }; -void TestLogCallback(const char* module, LogLevel level, const aos::String& message) -{ - printk("[downloader] %s \n", message.CStr()); -} - ZTEST_SUITE(downloader, NULL, NULL, NULL, NULL, NULL); ZTEST(downloader, test_download_image) @@ -96,12 +92,12 @@ ZTEST(downloader, test_download_image) TestDownloadRequester requester; - zassert_equal(downloader.Init(requester), aos::ErrorEnum::eNone, "Failed to initialize downloader"); + zassert_equal(sDownloader.Init(requester), aos::ErrorEnum::eNone, "Failed to initialize downloader"); aos::StaticString url {cDownloadUrl}; aos::StaticString path {cDownloadPath}; - zassert_equal(downloader.Download(url, path, aos::DownloadContentEnum::eService), aos::ErrorEnum::eNone, + zassert_equal(sDownloader.Download(url, path, aos::DownloadContentEnum::eService), aos::ErrorEnum::eNone, "Failed to download image"); aos::StaticString filePath {aos::FS::JoinPath(cDownloadPath, cFileName)}; @@ -124,11 +120,11 @@ ZTEST(downloader, test_timeout_download_image) TestDownloadRequester requester {true}; - zassert_equal(downloader.Init(requester), aos::ErrorEnum::eNone, "Failed to initialize downloader"); + zassert_equal(sDownloader.Init(requester), aos::ErrorEnum::eNone, "Failed to initialize downloader"); aos::StaticString url {cDownloadUrl}; aos::StaticString path {cDownloadPath}; - zassert_equal(downloader.Download(url, path, aos::DownloadContentEnum::eService), aos::ErrorEnum::eTimeout, + zassert_equal(sDownloader.Download(url, path, aos::DownloadContentEnum::eService), aos::ErrorEnum::eTimeout, "Expected timeout error"); } From 728a0788a2352502c8c95e34334b8a9b7a7efdfa Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sat, 17 Aug 2024 17:54:59 +0300 Subject: [PATCH 035/198] [smclient] Refactor logs, error handling and update unit test Signed-off-by: Oleksandr Grytsov --- src/smclient/openhandler.cpp | 25 ++++------- src/smclient/openhandler.hpp | 4 +- src/smclient/smclient.cpp | 7 ++-- src/smclient/smclient.hpp | 10 ++--- tests/smclient/CMakeLists.txt | 2 +- tests/smclient/src/main.cpp | 48 ++++++++++++---------- tests/smclient/src/stubs/clocksyncstub.hpp | 7 +++- tests/smclient/testcase.yaml | 2 +- 8 files changed, 50 insertions(+), 55 deletions(-) diff --git a/src/smclient/openhandler.cpp b/src/smclient/openhandler.cpp index a092f626..34f897ec 100644 --- a/src/smclient/openhandler.cpp +++ b/src/smclient/openhandler.cpp @@ -20,12 +20,11 @@ namespace aos::zephyr::smclient { Error OpenHandler::Init(communication::ChannelItf& channel, clocksync::ClockSyncItf& clockSync) { - auto err = PBHandler::Init("SM open", channel); - if (!err.IsNone()) { + if (auto err = PBHandler::Init("SM open", channel); !err.IsNone()) { return AOS_ERROR_WRAP(err); } - if (!(err = Start()).IsNone()) { + if (auto err = Start(); err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -40,7 +39,7 @@ Error OpenHandler::SendClockSyncRequest() = servicemanager_v4_ClockSyncRequest servicemanager_v4_ClockSyncRequest_init_default; mOutgoingMessages.which_SMOutgoingMessage = servicemanager_v4_SMOutgoingMessages_clock_sync_request_tag; - LOG_DBG() << "Send SM message: message=ClockSyncRequest"; + LOG_INF() << "Send SM clock sync request"; return SendMessage(&mOutgoingMessages, &servicemanager_v4_SMOutgoingMessages_msg); } @@ -51,7 +50,7 @@ OpenHandler::~OpenHandler() } /*********************************************************************************************************************** - * Protected + * Private **********************************************************************************************************************/ void OpenHandler::OnConnect() @@ -70,8 +69,7 @@ Error OpenHandler::ReceiveMessage(const Array& data) { auto stream = pb_istream_from_buffer(data.Get(), data.Size()); - auto status = pb_decode(&stream, &servicemanager_v4_SMIncomingMessages_msg, &mIncomingMessages); - if (!status) { + if (auto status = pb_decode(&stream, &servicemanager_v4_SMIncomingMessages_msg, &mIncomingMessages); !status) { return AOS_ERROR_WRAP(Error(ErrorEnum::eRuntime, "failed to decode message")); } @@ -79,10 +77,7 @@ Error OpenHandler::ReceiveMessage(const Array& data) switch (mIncomingMessages.which_SMIncomingMessage) { case servicemanager_v4_SMIncomingMessages_clock_sync_tag: - if (!(err = ProcessClockSync(mIncomingMessages.SMIncomingMessage.clock_sync)).IsNone()) { - return err; - } - + err = ProcessClockSync(mIncomingMessages.SMIncomingMessage.clock_sync); break; default: @@ -90,16 +85,12 @@ Error OpenHandler::ReceiveMessage(const Array& data) break; } - return ErrorEnum::eNone; + return err; } -/*********************************************************************************************************************** - * Private - **********************************************************************************************************************/ - Error OpenHandler::ProcessClockSync(const servicemanager_v4_ClockSync& pbClockSync) { - LOG_DBG() << "Receive SM message: message=ClockSync"; + LOG_INF() << "Process clock sync"; if (!pbClockSync.has_current_time) { return AOS_ERROR_WRAP(Error(ErrorEnum::eInvalidArgument, "ClockSync message has no current time")); diff --git a/src/smclient/openhandler.hpp b/src/smclient/openhandler.hpp index aec0fe49..0970aec3 100644 --- a/src/smclient/openhandler.hpp +++ b/src/smclient/openhandler.hpp @@ -43,12 +43,10 @@ class OpenHandler : public communication::PBHandler& data) override; - -private: Error ProcessClockSync(const servicemanager_v4_ClockSync& pbClockSync); clocksync::ClockSyncItf* mClockSync {}; diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index 236581ea..a056ec89 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -23,12 +23,11 @@ Error SMClient::Init(clocksync::ClockSyncItf& clockSync, communication::ChannelM return AOS_ERROR_WRAP(err); } - err = mOpenHandler.Init(*openChannel, clockSync); - if (!err.IsNone()) { + if (auto err = mOpenHandler.Init(*openChannel, clockSync); !err.IsNone()) { return err; } - if (!(err = clockSync.Subscribe(*this)).IsNone()) { + if (auto err = clockSync.Subscribe(*this); err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -45,7 +44,7 @@ Error SMClient::InstancesUpdateStatus(const Array& instances) return ErrorEnum::eNone; } -Error SMClient::SendImageContentRequest(const ImageContentRequest& request) +Error SMClient::SendImageContentRequest(const downloader::ImageContentRequest& request) { return ErrorEnum::eNone; } diff --git a/src/smclient/smclient.hpp b/src/smclient/smclient.hpp index 046d041c..0ef477d3 100644 --- a/src/smclient/smclient.hpp +++ b/src/smclient/smclient.hpp @@ -9,7 +9,7 @@ #define SMCLIENT_HPP_ #include -#include +#include #include #include @@ -25,8 +25,8 @@ namespace aos::zephyr::smclient { * SM client instance. */ class SMClient : public sm::launcher::InstanceStatusReceiverItf, - public DownloadRequesterItf, - public monitoring::SenderItf, + public downloader::DownloadRequesterItf, + public aos::monitoring::SenderItf, public ConnectionPublisherItf, public clocksync::ClockSyncSenderItf, public clocksync::ClockSyncSubscriberItf, @@ -68,7 +68,7 @@ class SMClient : public sm::launcher::InstanceStatusReceiverItf, * @param request image content request. * @return Error. */ - Error SendImageContentRequest(const ImageContentRequest& request) override; + Error SendImageContentRequest(const downloader::ImageContentRequest& request) override; /** * Sends monitoring data. @@ -76,7 +76,7 @@ class SMClient : public sm::launcher::InstanceStatusReceiverItf, * @param monitoringData monitoring data. * @return Error. */ - Error SendMonitoringData(const monitoring::NodeMonitoringData& monitoringData) override; + Error SendMonitoringData(const aos::monitoring::NodeMonitoringData& monitoringData) override; /** * Subscribes the provided ConnectionSubscriberItf to this object. diff --git a/tests/smclient/CMakeLists.txt b/tests/smclient/CMakeLists.txt index 08e55a9a..9351fc0c 100644 --- a/tests/smclient/CMakeLists.txt +++ b/tests/smclient/CMakeLists.txt @@ -59,9 +59,9 @@ target_sources( app PRIVATE ../../src/communication/pbhandler.cpp ../../src/smclient/openhandler.cpp + ../../src/utils/utils.cpp ../../src/smclient/smclient.cpp ../utils/log.cpp ../utils/pbmessages.cpp - ../utils/utils.cpp src/main.cpp ) diff --git a/tests/smclient/src/main.cpp b/tests/smclient/src/main.cpp index 9ac6647b..8ed40b8b 100644 --- a/tests/smclient/src/main.cpp +++ b/tests/smclient/src/main.cpp @@ -5,8 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - #include #include @@ -65,7 +63,7 @@ ZTEST_SUITE( auto err = fixture->mSMClient.Init(fixture->mClockSync, fixture->mChannelManager); - zassert_true(err.IsNone(), "Can't initialize SM client: %s", AosErrorToStr(err)); + zassert_true(err.IsNone(), "Can't initialize SM client: %s", utils::ErrorToCStr(err)); return fixture; }, @@ -77,10 +75,13 @@ ZTEST_SUITE( ZTEST_F(smclient, test_ClockSync) { + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_SM_OPEN_PORT); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + // Wait clock sync start - auto err = fixture->mClockSync.WaitEvent(cWaitTimeout); - zassert_true(err.IsNone(), "Error waiting clock sync start: %s", AosErrorToStr(err)); + err = fixture->mClockSync.WaitEvent(cWaitTimeout); + zassert_true(err.IsNone(), "Error waiting clock sync start: %s", utils::ErrorToCStr(err)); zassert_true(fixture->mClockSync.GetStarted()); @@ -88,36 +89,39 @@ ZTEST_F(smclient, test_ClockSync) err = fixture->mSMClient.SendClockSyncRequest(); - zassert_true(err.IsNone(), "Error sending clock sync request: %s", AosErrorToStr(err)); - - ChannelStub* channel; + zassert_true(err.IsNone(), "Error sending clock sync request: %s", utils::ErrorToCStr(err)); - aos::Tie(channel, err) = fixture->mChannelManager.GetChannel(CONFIG_AOS_SM_OPEN_PORT); - zassert_true(err.IsNone(), "Getting channel error: %s", AosErrorToStr(err)); + servicemanager_v4_SMOutgoingMessages outgoingMessage; + auto& pbClockSyncRequest = outgoingMessage.SMOutgoingMessage.clock_sync_request; - servicemanager_v4_SMOutgoingMessages outgoingMessage servicemanager_v4_SMOutgoingMessages_init_default; + pbClockSyncRequest = servicemanager_v4_ClockSyncRequest servicemanager_v4_ClockSyncRequest_init_default; err = ReceiveSMOutgoingMessage(channel, outgoingMessage); - zassert_true(err.IsNone(), "Error receiving message: %s", AosErrorToStr(err)); + zassert_true(err.IsNone(), "Error receiving message: %s", utils::ErrorToCStr(err)); zassert_equal(outgoingMessage.which_SMOutgoingMessage, servicemanager_v4_SMOutgoingMessages_clock_sync_request_tag); // Send clock sync - servicemanager_v4_SMIncomingMessages incomingMessage servicemanager_v4_SMIncomingMessages_init_default; + auto timestamp = aos::Time::Now(); + + servicemanager_v4_SMIncomingMessages incomingMessage; + auto& pbClockSync = incomingMessage.SMIncomingMessage.clock_sync; + + auto unixTime = timestamp.UnixTime(); + + incomingMessage.which_SMIncomingMessage = servicemanager_v4_SMIncomingMessages_clock_sync_tag; + pbClockSync = servicemanager_v4_ClockSync servicemanager_v4_ClockSync_init_default; - incomingMessage.which_SMIncomingMessage = servicemanager_v4_SMIncomingMessages_clock_sync_tag; - incomingMessage.SMIncomingMessage.clock_sync.has_current_time = true; - incomingMessage.SMIncomingMessage.clock_sync.current_time.seconds = 43; - incomingMessage.SMIncomingMessage.clock_sync.current_time.nanos = 234; + incomingMessage.SMIncomingMessage.clock_sync.has_current_time = true; + incomingMessage.SMIncomingMessage.clock_sync.current_time.seconds = unixTime.tv_sec; + incomingMessage.SMIncomingMessage.clock_sync.current_time.nanos = unixTime.tv_nsec; err = SendSMIncomingMessage(channel, incomingMessage); - zassert_true(err.IsNone(), "Error sending message: %s", AosErrorToStr(err)); + zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); err = fixture->mClockSync.WaitEvent(cWaitTimeout); - zassert_true(err.IsNone(), "Error waiting clock sync start: %s", AosErrorToStr(err)); + zassert_true(err.IsNone(), "Error waiting clock sync start: %s", utils::ErrorToCStr(err)); - zassert_equal(fixture->mClockSync.GetSyncTime(), - aos::Time::Unix(incomingMessage.SMIncomingMessage.clock_sync.current_time.seconds, - incomingMessage.SMIncomingMessage.clock_sync.current_time.nanos)); + zassert_equal(fixture->mClockSync.GetSyncTime(), timestamp, "Wrong timestamp"); } diff --git a/tests/smclient/src/stubs/clocksyncstub.hpp b/tests/smclient/src/stubs/clocksyncstub.hpp index 9f48cacc..f566b169 100644 --- a/tests/smclient/src/stubs/clocksyncstub.hpp +++ b/tests/smclient/src/stubs/clocksyncstub.hpp @@ -37,9 +37,12 @@ class ClockSyncStub : public aos::zephyr::clocksync::ClockSyncItf { return aos::ErrorEnum::eNone; } - aos::Error Subscribe(aos::zephyr::clocksync::ClockSyncSubscriberItf& subscriber) { return aos::ErrorEnum::eNone; } + aos::Error Subscribe(aos::zephyr::clocksync::ClockSyncSubscriberItf& subscriber) override + { + return aos::ErrorEnum::eNone; + } - void Unsubscribe(aos::zephyr::clocksync::ClockSyncSubscriberItf& subscriber) { } + void Unsubscribe(aos::zephyr::clocksync::ClockSyncSubscriberItf& subscriber) override { } bool GetStarted() const { diff --git a/tests/smclient/testcase.yaml b/tests/smclient/testcase.yaml index eae550f1..254bc98d 100644 --- a/tests/smclient/testcase.yaml +++ b/tests/smclient/testcase.yaml @@ -1,5 +1,5 @@ tests: - aoszephyrapp.communication: + aoszephyrapp.smclient: build_only: false tags: smclient timeout: 500 From 42692850c79a15ed4acd6e7f25b3224d0fabb4f7 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sat, 17 Aug 2024 17:56:36 +0300 Subject: [PATCH 036/198] [provisionmanager] Add initial provision manager callback implementation Signed-off-by: Oleksandr Grytsov --- CMakeLists.txt | 1 + src/logger/logger.cpp | 8 +-- src/provisionmanager/log.hpp | 15 +++++ .../provisionmanagercallback.cpp | 40 +++++++++++++ .../provisionmanagercallback.hpp | 59 +++++++++++++++++++ 5 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 src/provisionmanager/log.hpp create mode 100644 src/provisionmanager/provisionmanagercallback.cpp create mode 100644 src/provisionmanager/provisionmanagercallback.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 907f138e..c0720bd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,6 +82,7 @@ target_sources( src/monitoring/resourceusageprovider.cpp src/nodeinfoprovider/nodeinfoprovider.cpp src/ocispec/ocispec.cpp + src/provisionmanager/provisionmanagercallback.cpp src/resourcemanager/resourcemanager.cpp src/runner/runner.cpp src/smclient/openhandler.cpp diff --git a/src/logger/logger.cpp b/src/logger/logger.cpp index 26318c76..d6f1cee0 100644 --- a/src/logger/logger.cpp +++ b/src/logger/logger.cpp @@ -18,7 +18,7 @@ static const aos::String cLogModuleCommunication = "communication"; static const aos::String cLogModuleClockSync = "clocksync"; static const aos::String cLogModuleDownloader = "downloader"; static const aos::String cLogModuleOCISpec = "ocispec"; -static const aos::String cLogModuleProvisioning = "provisioning"; +static const aos::String cLogModuleProvisionManager = "provisionmanager"; static const aos::String cLogModuleResourceManager = "resourcemanager"; static const aos::String cLogModuleRunner = "runner"; static const aos::String cLogModuleSMClient = "smclient"; @@ -78,7 +78,7 @@ LOG_CALLBACK(clocksync); LOG_CALLBACK(communication); LOG_CALLBACK(downloader); LOG_CALLBACK(ocispec); -LOG_CALLBACK(provisioning); +LOG_CALLBACK(provisionmanager); LOG_CALLBACK(resourcemanager); LOG_CALLBACK(runner); LOG_CALLBACK(smclient); @@ -120,8 +120,8 @@ void Logger::LogCallback(const char* module, aos::LogLevel level, const aos::Str log_downloader::LogCallback(level, message); } else if (logModule == cLogModuleOCISpec) { log_ocispec::LogCallback(level, message); - } else if (logModule == cLogModuleProvisioning) { - log_provisioning::LogCallback(level, message); + } else if (logModule == cLogModuleProvisionManager) { + log_provisionmanager::LogCallback(level, message); } else if (logModule == cLogModuleResourceManager) { log_resourcemanager::LogCallback(level, message); } else if (logModule == cLogModuleRunner) { diff --git a/src/provisionmanager/log.hpp b/src/provisionmanager/log.hpp new file mode 100644 index 00000000..b420c302 --- /dev/null +++ b/src/provisionmanager/log.hpp @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2023 Renesas Electronics Corporation. + * Copyright (C) 2023 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef LOG_HPP_ +#define LOG_HPP_ + +#define LOG_MODULE "provisionmanager" + +#include + +#endif diff --git a/src/provisionmanager/provisionmanagercallback.cpp b/src/provisionmanager/provisionmanagercallback.cpp new file mode 100644 index 00000000..b03bb92d --- /dev/null +++ b/src/provisionmanager/provisionmanagercallback.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "provisionmanagercallback.hpp" + +namespace aos::zephyr::provisionmanager { + +/*********************************************************************************************************************** + * Public + **********************************************************************************************************************/ + +Error ProvisionManagerCallback::OnStartProvisioning(const String& password) +{ + return ErrorEnum::eNone; +} + +Error ProvisionManagerCallback::OnFinishProvisioning(const String& password) +{ + return ErrorEnum::eNone; +} + +Error ProvisionManagerCallback::OnDeprovision(const String& password) +{ + if (auto err = FS::ClearDir(cHSMDir); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + return ErrorEnum::eNone; +} + +Error ProvisionManagerCallback::OnEncryptDisk(const String& password) +{ + return ErrorEnum::eNone; +} + +} // namespace aos::zephyr::provisionmanager diff --git a/src/provisionmanager/provisionmanagercallback.hpp b/src/provisionmanager/provisionmanagercallback.hpp new file mode 100644 index 00000000..a8a65051 --- /dev/null +++ b/src/provisionmanager/provisionmanagercallback.hpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef PROVISIONMANAGER_HPP_ +#define PROVISIONMANAGER_HPP_ + +#include + +namespace aos::zephyr::provisionmanager { + +/** + * JSON provider. + */ +class ProvisionManagerCallback : public iam::provisionmanager::ProvisionManagerCallbackItf { + +public: + /** + * Called when provisioning starts. + * + * @param password password. + * @returns Error. + */ + Error OnStartProvisioning(const String& password) override; + + /** + * Called when provisioning finishes. + * + * @param password password. + * @returns Error. + */ + Error OnFinishProvisioning(const String& password) override; + + /** + * Called on deprovisioning. + * + * @param password password. + * @returns Error. + */ + Error OnDeprovision(const String& password) override; + + /** + * Called on disk encryption. + * + * @param password password. + * @returns Error. + */ + Error OnEncryptDisk(const String& password) override; + +private: + static constexpr auto cHSMDir = CONFIG_AOS_HSM_DIR; +}; + +} // namespace aos::zephyr::provisionmanager + +#endif From 1fb3e1cb8a18db133a32ca27a4fd98abbe127294 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sat, 17 Aug 2024 17:52:40 +0300 Subject: [PATCH 037/198] [nodeinfoprovider] Fix mutex usage and update unit test Signed-off-by: Oleksandr Grytsov --- src/nodeinfoprovider/nodeinfoprovider.cpp | 12 +++++------- src/nodeinfoprovider/nodeinfoprovider.hpp | 2 +- tests/nodeinfoprovider/CMakeLists.txt | 15 ++++++++------- tests/nodeinfoprovider/prj.conf | 4 ++-- tests/nodeinfoprovider/src/main.cpp | 6 +----- 5 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp index a7214117..80ab4fea 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -53,6 +53,8 @@ Error NodeInfoProvider::Init() Error NodeInfoProvider::GetNodeInfo(NodeInfo& nodeInfo) const { + LockGuard lock {mMutex}; + NodeStatus status; if (auto err = ReadNodeStatus(status); !err.IsNone()) { @@ -72,6 +74,8 @@ Error NodeInfoProvider::GetNodeInfo(NodeInfo& nodeInfo) const // cppcheck-suppress unusedFunction Error NodeInfoProvider::SetNodeStatus(const NodeStatus& status) { + LockGuard lock {mMutex}; + LOG_DBG() << "Set node status: status=" << status.ToString(); if (auto err = StoreNodeStatus(status); !err.IsNone()) { @@ -82,11 +86,7 @@ Error NodeInfoProvider::SetNodeStatus(const NodeStatus& status) return ErrorEnum::eNone; } - { - LockGuard lock {mMutex}; - - mNodeInfo.mStatus = status; - } + mNodeInfo.mStatus = status; LOG_DBG() << "Node status updated: status=" << mNodeInfo.mStatus.ToString(); @@ -222,8 +222,6 @@ Error NodeInfoProvider::ReadNodeStatus(NodeStatus& status) const Error NodeInfoProvider::NotifyNodeStatusChanged(const NodeStatus& status) { - LockGuard lock {mMutex}; - for (auto& [observer, _] : mStatusChangedSubscribers) { if (auto err = observer->OnNodeStatusChanged(mNodeInfo.mNodeID, status); !err.IsNone()) { return AOS_ERROR_WRAP(err); diff --git a/src/nodeinfoprovider/nodeinfoprovider.hpp b/src/nodeinfoprovider/nodeinfoprovider.hpp index 3395355b..297d11c0 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.hpp +++ b/src/nodeinfoprovider/nodeinfoprovider.hpp @@ -78,7 +78,7 @@ class NodeInfoProvider : public iam::nodeinfoprovider::NodeInfoProviderItf { NodeInfo mNodeInfo; StaticMap mStatusChangedSubscribers; - Mutex mMutex; + mutable Mutex mMutex; }; } // namespace aos::zephyr::nodeinfoprovider diff --git a/tests/nodeinfoprovider/CMakeLists.txt b/tests/nodeinfoprovider/CMakeLists.txt index 8d266b17..1a9b407c 100644 --- a/tests/nodeinfoprovider/CMakeLists.txt +++ b/tests/nodeinfoprovider/CMakeLists.txt @@ -9,29 +9,30 @@ project(nodeinfoprovider_test) # Config # ###################################################################################################################### -set(AOS_CORE_CONFIG aoscoreconfig.hpp) +set(aoscore_config aoscoreconfig.hpp) +set(aoscore_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../../../aos_core_lib_cpp") # ###################################################################################################################### # Definitions # ###################################################################################################################### # Aos core configuration -add_definitions(-include ${AOS_CORE_CONFIG}) +add_definitions(-include ${aoscore_config}) # ###################################################################################################################### # Includes # ###################################################################################################################### -target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../src) -target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../../aos_core_lib_cpp/include) -target_include_directories(app PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) - +zephyr_include_directories(${aoscore_source_dir}/include) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/..) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/../../src) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src) zephyr_include_directories_ifdef(CONFIG_NATIVE_APPLICATION ${APPLICATION_SOURCE_DIR}/../../mocks/include) # ###################################################################################################################### # Target # ###################################################################################################################### -target_sources(app PRIVATE src/main.cpp ../../src/nodeinfoprovider/nodeinfoprovider.cpp) +target_sources(app PRIVATE ../../src/nodeinfoprovider/nodeinfoprovider.cpp ../utils/log.cpp src/main.cpp) target_sources_ifdef(CONFIG_NATIVE_APPLICATION app PRIVATE ${APPLICATION_SOURCE_DIR}/../../mocks/xstat/xstat.cpp) diff --git a/tests/nodeinfoprovider/prj.conf b/tests/nodeinfoprovider/prj.conf index be4cf54f..c3d5ac3c 100644 --- a/tests/nodeinfoprovider/prj.conf +++ b/tests/nodeinfoprovider/prj.conf @@ -1,6 +1,8 @@ # Enable C++ CONFIG_CPP=y CONFIG_STD_CPP17=y +CONFIG_EXTERNAL_LIBCPP=y +CONFIG_CBPRINTF_FP_SUPPORT=y # Enable test suit CONFIG_ZTEST=y @@ -14,7 +16,5 @@ CONFIG_FLASH_MAP=y CONFIG_FILE_SYSTEM=y CONFIG_FILE_SYSTEM_LITTLEFS=y - - # Enable hardware info CONFIG_HWINFO=y diff --git a/tests/nodeinfoprovider/src/main.cpp b/tests/nodeinfoprovider/src/main.cpp index 2978f6c0..eb609dc6 100644 --- a/tests/nodeinfoprovider/src/main.cpp +++ b/tests/nodeinfoprovider/src/main.cpp @@ -15,6 +15,7 @@ #include #include "nodeinfoprovider/nodeinfoprovider.hpp" +#include "utils/log.hpp" #define LVGL_PARTITION storage_partition #define LVGL_PARTITION_ID FIXED_PARTITION_ID(LVGL_PARTITION) @@ -123,11 +124,6 @@ class TestNodeStatusObserver : public aos::iam::nodeinfoprovider::NodeStatusObse * Setup **********************************************************************************************************************/ -static void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message) -{ - printk("[nodeinfoprovider] %s \n", message.CStr()); -} - ZTEST_SUITE(nodeinfoprovider, NULL, setup_fs, before_test, NULL, teardown_fs); /*********************************************************************************************************************** From 3b3d6bcbbfc392c03dd5effdf84c33719ab8f3ce Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 18 Aug 2024 15:41:01 +0300 Subject: [PATCH 038/198] [nodeinfoprovider] Use machine-id as node id and host fs as aos storage Signed-off-by: Oleksandr Grytsov --- Kconfig | 4 + src/nodeinfoprovider/nodeinfoprovider.cpp | 83 +++++++++------ src/nodeinfoprovider/nodeinfoprovider.hpp | 19 ++-- tests/nodeinfoprovider/CMakeLists.txt | 4 +- tests/nodeinfoprovider/Kconfig | 4 +- tests/nodeinfoprovider/prj.conf | 12 --- tests/nodeinfoprovider/src/main.cpp | 119 ++++++++-------------- 7 files changed, 114 insertions(+), 131 deletions(-) diff --git a/Kconfig b/Kconfig index 10fd2ba1..d9238d8f 100644 --- a/Kconfig +++ b/Kconfig @@ -21,6 +21,10 @@ config AOS_REBOOT_XEN_STORE_PATH string "Path to user reboot request" default "/local/domain/1/data/user-reboot" +config AOS_DISK_MOUNT_POINT + string "Disk mount point" + default "/aos" + config AOS_STORAGE_DIR string "Path to the storage" default "/aos/storage" diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp index 80ab4fea..03a9520c 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -7,12 +7,18 @@ #include #include +#ifndef CONFIG_NATIVE_APPLICATION #include +#else +#include +#endif #include #include +#include "utils/utils.hpp" + #include "log.hpp" #include "nodeinfoprovider.hpp" @@ -40,12 +46,18 @@ Error NodeInfoProvider::Init() mNodeInfo.mNodeType = cNodeType; mNodeInfo.mMaxDMIPS = cMaxDMIPS; - if (auto err = InitAttributes(); !err.IsNone()) { - return Error(AOS_ERROR_WRAP(err), "failed to init node attributes"); + Error err; + + if (Tie(mNodeInfo.mStatus, err) = ReadNodeStatus(); !err.IsNone()) { + return AOS_ERROR_WRAP(Error(err, "failed to get node status")); + } + + if (err = InitAttributes(); !err.IsNone()) { + return AOS_ERROR_WRAP(Error(err, "failed to init node attributes")); } - if (auto err = InitPartitionInfo(); !err.IsNone()) { - return Error(AOS_ERROR_WRAP(err), "failed to init node partition info"); + if (err = InitPartitionInfo(); !err.IsNone()) { + return AOS_ERROR_WRAP(Error(err, "failed to init node partition info")); } return ErrorEnum::eNone; @@ -55,18 +67,9 @@ Error NodeInfoProvider::GetNodeInfo(NodeInfo& nodeInfo) const { LockGuard lock {mMutex}; - NodeStatus status; - - if (auto err = ReadNodeStatus(status); !err.IsNone()) { - LOG_ERR() << "Get node info failed: error=" << err; - - return AOS_ERROR_WRAP(err); - } - - LOG_DBG() << "Get node info: status=" << status.ToString(); + LOG_DBG() << "Get node info: status=" << nodeInfo.mStatus; - nodeInfo = mNodeInfo; - nodeInfo.mStatus = status; + nodeInfo = mNodeInfo; return ErrorEnum::eNone; } @@ -78,14 +81,14 @@ Error NodeInfoProvider::SetNodeStatus(const NodeStatus& status) LOG_DBG() << "Set node status: status=" << status.ToString(); - if (auto err = StoreNodeStatus(status); !err.IsNone()) { - return AOS_ERROR_WRAP(Error(err, "failed to store node status")); - } - if (status == mNodeInfo.mStatus) { return ErrorEnum::eNone; } + if (auto err = StoreNodeStatus(status); !err.IsNone()) { + return AOS_ERROR_WRAP(Error(err, "failed to store node status")); + } + mNodeInfo.mStatus = status; LOG_DBG() << "Node status updated: status=" << mNodeInfo.mStatus.ToString(); @@ -131,10 +134,10 @@ Error NodeInfoProvider::UnsubscribeNodeStatusChanged(iam::nodeinfoprovider::Node Error NodeInfoProvider::InitNodeID() { - uint8_t buffer[cNodeIDLen]; - memset(buffer, 0, sizeof(buffer)); +#ifndef CONFIG_NATIVE_APPLICATION + char buffer[cNodeIDLen + 1] {}; - auto ret = hwinfo_get_device_id(buffer, sizeof(buffer) - 1); + auto ret = hwinfo_get_device_id(reinterpret_cast(buffer), sizeof(buffer) - 1); if (ret == -ENOSYS) { LOG_WRN() << "hwinfo_get_device_id is not supported"; @@ -144,7 +147,12 @@ Error NodeInfoProvider::InitNodeID() return AOS_ERROR_WRAP(ret); } - mNodeInfo.mNodeID = String(reinterpret_cast(buffer), ret); + mNodeInfo.mNodeID = utils::StringFromCStr(buffer); +#else + if (auto err = FS::ReadFileToString(cNodeIDFile, mNodeInfo.mNodeID); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } +#endif return ErrorEnum::eNone; } @@ -179,15 +187,22 @@ Error NodeInfoProvider::InitPartitionInfo() } for (auto& partition : mNodeInfo.mPartitions) { +#ifdef CONFIG_NATIVE_APPLICATION + struct statvfs sbuf; + + if (auto ret = statvfs(partition.mPath.CStr(), &sbuf); ret != 0) { + return ret; + } +#else struct fs_statvfs sbuf; if (auto ret = fs_statvfs(partition.mPath.CStr(), &sbuf); ret != 0) { return ret; } - +#endif partition.mTotalSize = sbuf.f_bsize * sbuf.f_blocks; - LOG_DBG() << "Init partition info: name=" << partition.mName << ", size=" << partition.mTotalSize; + LOG_DBG() << "Init partition info: name=" << partition.mName << ", totalSize=" << partition.mTotalSize; } return ErrorEnum::eNone; @@ -204,20 +219,30 @@ Error NodeInfoProvider::StoreNodeStatus(const NodeStatus& status) const return ErrorEnum::eNone; } -Error NodeInfoProvider::ReadNodeStatus(NodeStatus& status) const +RetWithError NodeInfoProvider::ReadNodeStatus() const { StaticString statusStr; auto err = FS::ReadFileToString(cProvisioningStateFile, statusStr); if (!err.IsNone()) { - return err; + if (err == -ENOENT) { + return {NodeStatusEnum::eUnprovisioned, ErrorEnum::eNone}; + } + + return {NodeStatusEnum::eUnprovisioned, AOS_ERROR_WRAP(err)}; } if (statusStr.IsEmpty()) { - return ErrorEnum::eFailed; + return {NodeStatusEnum::eUnprovisioned, AOS_ERROR_WRAP(Error(ErrorEnum::eFailed, "node status is empty"))}; + } + + NodeStatus status; + + if (err = status.FromString(statusStr); !err.IsNone()) { + return {NodeStatusEnum::eUnprovisioned, AOS_ERROR_WRAP(err)}; } - return status.FromString(statusStr); + return status; } Error NodeInfoProvider::NotifyNodeStatusChanged(const NodeStatus& status) diff --git a/src/nodeinfoprovider/nodeinfoprovider.hpp b/src/nodeinfoprovider/nodeinfoprovider.hpp index 297d11c0..ac20932c 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.hpp +++ b/src/nodeinfoprovider/nodeinfoprovider.hpp @@ -59,22 +59,25 @@ class NodeInfoProvider : public iam::nodeinfoprovider::NodeInfoProviderItf { Error UnsubscribeNodeStatusChanged(iam::nodeinfoprovider::NodeStatusObserverItf& observer) override; private: - Error InitNodeID(); - Error InitAttributes(); - Error InitPartitionInfo(); - Error StoreNodeStatus(const NodeStatus& status) const; - Error ReadNodeStatus(NodeStatus& status) const; - Error NotifyNodeStatusChanged(const NodeStatus& status); - static constexpr auto cNodeStatusLen = 16; static constexpr auto cDiskPartitionPoint = CONFIG_AOS_DISK_MOUNT_POINT; static constexpr auto cMaxDMIPS = CONFIG_AOS_MAX_CPU_DMIPS; static constexpr auto cNodeType = CONFIG_AOS_NODE_TYPE; static constexpr auto cProvisioningStateFile = CONFIG_AOS_PROVISION_STATE_FILE; - static constexpr auto cDiskPartitionName = "Aos"; + static constexpr auto cDiskPartitionName = "aos"; static constexpr auto cNodeRunner = "xrun"; static constexpr auto cAosComponents = "iam,sm"; static constexpr auto cMaxNodeStatusSubscribers = 4; +#ifdef CONFIG_NATIVE_APPLICATION + static constexpr auto cNodeIDFile = "/etc/machine-id"; +#endif + + Error InitNodeID(); + Error InitAttributes(); + Error InitPartitionInfo(); + Error StoreNodeStatus(const NodeStatus& status) const; + RetWithError ReadNodeStatus() const; + Error NotifyNodeStatusChanged(const NodeStatus& status); NodeInfo mNodeInfo; StaticMap mStatusChangedSubscribers; diff --git a/tests/nodeinfoprovider/CMakeLists.txt b/tests/nodeinfoprovider/CMakeLists.txt index 1a9b407c..acba899d 100644 --- a/tests/nodeinfoprovider/CMakeLists.txt +++ b/tests/nodeinfoprovider/CMakeLists.txt @@ -33,6 +33,8 @@ zephyr_include_directories_ifdef(CONFIG_NATIVE_APPLICATION ${APPLICATION_SOURCE_ # Target # ###################################################################################################################### -target_sources(app PRIVATE ../../src/nodeinfoprovider/nodeinfoprovider.cpp ../utils/log.cpp src/main.cpp) +target_sources( + app PRIVATE ../../src/nodeinfoprovider/nodeinfoprovider.cpp ../../src/utils/utils.cpp ../utils/log.cpp src/main.cpp +) target_sources_ifdef(CONFIG_NATIVE_APPLICATION app PRIVATE ${APPLICATION_SOURCE_DIR}/../../mocks/xstat/xstat.cpp) diff --git a/tests/nodeinfoprovider/Kconfig b/tests/nodeinfoprovider/Kconfig index 72b8f2e3..6a59205a 100644 --- a/tests/nodeinfoprovider/Kconfig +++ b/tests/nodeinfoprovider/Kconfig @@ -15,10 +15,10 @@ config AOS_MAX_CPU_DMIPS config AOS_DISK_MOUNT_POINT string "Disk mount point" - default "/aos" + default ".aos" config AOS_PROVISION_STATE_FILE string "Path to provisioning state file." - default ".provisionstate" + default ".aos/provisionstate" source "Kconfig" diff --git a/tests/nodeinfoprovider/prj.conf b/tests/nodeinfoprovider/prj.conf index c3d5ac3c..6dd50b2e 100644 --- a/tests/nodeinfoprovider/prj.conf +++ b/tests/nodeinfoprovider/prj.conf @@ -6,15 +6,3 @@ CONFIG_CBPRINTF_FP_SUPPORT=y # Enable test suit CONFIG_ZTEST=y - -# Enable JSON library -CONFIG_JSON_LIBRARY=y - -# Enable file system -CONFIG_FLASH=y -CONFIG_FLASH_MAP=y -CONFIG_FILE_SYSTEM=y -CONFIG_FILE_SYSTEM_LITTLEFS=y - -# Enable hardware info -CONFIG_HWINFO=y diff --git a/tests/nodeinfoprovider/src/main.cpp b/tests/nodeinfoprovider/src/main.cpp index eb609dc6..844eba16 100644 --- a/tests/nodeinfoprovider/src/main.cpp +++ b/tests/nodeinfoprovider/src/main.cpp @@ -5,8 +5,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include +#include + +#include #include #include @@ -16,11 +17,9 @@ #include "nodeinfoprovider/nodeinfoprovider.hpp" #include "utils/log.hpp" +#include "utils/utils.hpp" -#define LVGL_PARTITION storage_partition -#define LVGL_PARTITION_ID FIXED_PARTITION_ID(LVGL_PARTITION) - -FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(cstorage); +using namespace aos::zephyr; /*********************************************************************************************************************** * Consts @@ -33,62 +32,26 @@ static constexpr auto cUnprovisioned = "unprovisioned"; * Static **********************************************************************************************************************/ -static struct fs_mount_t sMnt = { - .type = FS_LITTLEFS, - .mnt_point = CONFIG_AOS_DISK_MOUNT_POINT, - .fs_data = &cstorage, - .storage_dev = (void*)LVGL_PARTITION_ID, -}; - -static struct fs_statvfs sMntStat; - -void* setup_fs(void) +void* setup(void) { - printk("setup_fs\n"); - - int ret = fs_mount(&sMnt); - if (ret < 0) { - TC_PRINT("Failed to mount file system: %d\n", ret); - - ztest_test_fail(); - - return NULL; - } + aos::Log::SetCallback(TestLogCallback); - ret = fs_statvfs(CONFIG_AOS_DISK_MOUNT_POINT, &sMntStat); - if (ret != 0) { - printk("Failed to get statvfs: %d\n", ret); - } else { - printk("Mounted partition: %s\n", CONFIG_AOS_DISK_MOUNT_POINT); - printk("bsize = %lu\n", sMntStat.f_bsize); - printk("frsize = %lu\n", sMntStat.f_frsize); - printk("blocks = %lu\n", sMntStat.f_blocks); - printk("bfree = %lu\n", sMntStat.f_bfree); - } + auto err = aos::FS::ClearDir(CONFIG_AOS_DISK_MOUNT_POINT); + zassert_true(err.IsNone(), "Failed to clear disk mount point: %s", utils::ErrorToCStr(err)); return NULL; } -void teardown_fs(void* data) +void teardown(void* data) { - printk("teardown_fs\n"); - - auto ret = fs_unmount(&sMnt); - if (ret < 0) { - printk("Failed to unmount file system: %d\n", ret); - } - - return; + auto err = aos::FS::RemoveAll(CONFIG_AOS_DISK_MOUNT_POINT); + zassert_true(err.IsNone(), "Failed to remove disk mount point: %s", utils::ErrorToCStr(err)); } void before_test(void* data) { - printk("before_test\n"); - auto err = aos::FS::WriteStringToFile(cNodeStateFile, cUnprovisioned, S_IRUSR | S_IWUSR); - if (!err.IsNone()) { - printk("Can't create provisioning state file: %s\n", err.Message()); - } + zassert_true(err.IsNone(), "Failed to create provisioning state file: %s", utils::ErrorToCStr(err)); } /*********************************************************************************************************************** @@ -99,8 +62,6 @@ class TestNodeStatusObserver : public aos::iam::nodeinfoprovider::NodeStatusObse public: aos::Error OnNodeStatusChanged(const aos::String& nodeID, const aos::NodeStatus& status) override { - printk("Node status changed: %s\n", status.ToString().CStr()); - mNodeID = nodeID; mNodeStatus = status; mNotified = true; @@ -124,7 +85,7 @@ class TestNodeStatusObserver : public aos::iam::nodeinfoprovider::NodeStatusObse * Setup **********************************************************************************************************************/ -ZTEST_SUITE(nodeinfoprovider, NULL, setup_fs, before_test, NULL, teardown_fs); +ZTEST_SUITE(nodeinfoprovider, nullptr, setup, before_test, nullptr, teardown); /*********************************************************************************************************************** * Tests @@ -132,26 +93,30 @@ ZTEST_SUITE(nodeinfoprovider, NULL, setup_fs, before_test, NULL, teardown_fs); ZTEST(nodeinfoprovider, test_node_info) { - aos::Log::SetCallback(TestLogCallback); - aos::zephyr::nodeinfoprovider::NodeInfoProvider provider; - auto err = provider.Init(); - zassert_true(err.IsNone(), "Failed to init node info provider: %s", err.Message()); + + auto err = provider.Init(); + zassert_true(err.IsNone(), "Failed to init node info provider: %s", utils::ErrorToCStr(err)); aos::NodeInfo nodeInfo; err = provider.GetNodeInfo(nodeInfo); - zassert_true(err.IsNone(), "Failed to get node info: %s", err.Message()); + zassert_true(err.IsNone(), "Failed to get node info: %s", utils::ErrorToCStr(err)); zassert_equal(nodeInfo.mStatus.GetValue(), aos::NodeStatusEnum::eUnprovisioned, "Node status mismatch"); zassert_equal(nodeInfo.mMaxDMIPS, CONFIG_AOS_MAX_CPU_DMIPS, "Max DMIPS mismatch"); // test partition info zassert_equal(nodeInfo.mPartitions.Size(), 1, "Expected 1 partition"); - zassert_equal(nodeInfo.mPartitions[0].mName, "Aos", "Partition name mismatch"); + zassert_equal(nodeInfo.mPartitions[0].mName, "aos", "Partition name mismatch"); zassert_equal(nodeInfo.mPartitions[0].mPath, CONFIG_AOS_DISK_MOUNT_POINT, "Partition path mismatch"); - const auto expectedSize = sMntStat.f_bsize * sMntStat.f_blocks; + struct statvfs sbuf; + + auto ret = statvfs(CONFIG_AOS_DISK_MOUNT_POINT, &sbuf); + zassert_equal(ret, 0, "Failed to get partition info: %s [%d]", strerror(ret), ret); + + const auto expectedSize = sbuf.f_bsize * sbuf.f_blocks; zassert_equal(nodeInfo.mPartitions[0].mTotalSize, expectedSize, "Partition total size mismatch"); zassert_equal(nodeInfo.mPartitions[0].mTypes.Size(), 2, "Expected 2 partition types"); @@ -169,59 +134,55 @@ ZTEST(nodeinfoprovider, test_node_info) ZTEST(nodeinfoprovider, test_set_get_node_info) { - aos::Log::SetCallback(TestLogCallback); - aos::zephyr::nodeinfoprovider::NodeInfoProvider provider; auto err = provider.Init(); - zassert_true(err.IsNone(), "Failed to init node info provider: %s", err.Message()); + zassert_true(err.IsNone(), "Failed to init node info provider: %s", utils::ErrorToCStr(err)); aos::NodeInfo nodeInfo; err = provider.GetNodeInfo(nodeInfo); - zassert_true(err.IsNone(), "Failed to get node info: %s", err.Message()); + zassert_true(err.IsNone(), "Failed to get node info: %s", utils::ErrorToCStr(err)); zassert_equal(nodeInfo.mStatus.GetValue(), aos::NodeStatusEnum::eUnprovisioned, "Node status mismatch"); err = provider.SetNodeStatus(aos::NodeStatus(aos::NodeStatusEnum::eProvisioned)); - zassert_true(err.IsNone(), "Set node status failed: %s", err.Message()); + zassert_true(err.IsNone(), "Set node status failed: %s", utils::ErrorToCStr(err)); err = provider.GetNodeInfo(nodeInfo); - zassert_true(err.IsNone(), "Get node status failed: %s", err.Message()); + zassert_true(err.IsNone(), "Get node status failed: %s", utils::ErrorToCStr(err)); zassert_equal(nodeInfo.mStatus.GetValue(), aos::NodeStatusEnum::eProvisioned, "Node status mismatch"); err = provider.SetNodeStatus(aos::NodeStatus(aos::NodeStatusEnum::ePaused)); - zassert_true(err.IsNone(), "Set node status failed: %s", err.Message()); + zassert_true(err.IsNone(), "Set node status failed: %s", utils::ErrorToCStr(err)); err = provider.GetNodeInfo(nodeInfo); - zassert_true(err.IsNone(), "Get node status failed: %s", err.Message()); + zassert_true(err.IsNone(), "Get node status failed: %s", utils::ErrorToCStr(err)); zassert_equal(nodeInfo.mStatus.GetValue(), aos::NodeStatusEnum::ePaused, "Node status mismatch"); } ZTEST(nodeinfoprovider, test_node_status_changed_observer) { - aos::Log::SetCallback(TestLogCallback); - aos::zephyr::nodeinfoprovider::NodeInfoProvider provider; auto err = provider.Init(); - zassert_true(err.IsNone(), "Failed to init node info provider: %s", err.Message()); + zassert_true(err.IsNone(), "Failed to init node info provider: %s", utils::ErrorToCStr(err)); aos::NodeInfo nodeInfo; err = provider.GetNodeInfo(nodeInfo); - zassert_true(err.IsNone(), "Failed to get node info: %s", err.Message()); + zassert_true(err.IsNone(), "Failed to get node info: %s", utils::ErrorToCStr(err)); zassert_equal(nodeInfo.mStatus.GetValue(), aos::NodeStatusEnum::eUnprovisioned, "Node status mismatch"); TestNodeStatusObserver observer1, observer2; err = provider.SubscribeNodeStatusChanged(observer1); - zassert_true(err.IsNone(), "Failed to subscribe on node status changed: %s", err.Message()); + zassert_true(err.IsNone(), "Failed to subscribe on node status changed: %s", utils::ErrorToCStr(err)); err = provider.SubscribeNodeStatusChanged(observer2); - zassert_true(err.IsNone(), "Failed to subscribe on node status changed: %s", err.Message()); + zassert_true(err.IsNone(), "Failed to subscribe on node status changed: %s", utils::ErrorToCStr(err)); err = provider.SetNodeStatus(aos::NodeStatus(aos::NodeStatusEnum::eProvisioned)); - zassert_true(err.IsNone(), "Set node status failed: %s", err.Message()); + zassert_true(err.IsNone(), "Set node status failed: %s", utils::ErrorToCStr(err)); zassert_equal(observer1.mNodeStatus.GetValue(), aos::NodeStatusEnum::eProvisioned, "Node status mismatch"); zassert_equal(observer1.mNodeID, nodeInfo.mNodeID, "Node id mismatch"); @@ -233,7 +194,7 @@ ZTEST(nodeinfoprovider, test_node_status_changed_observer) observer2.Reset(); err = provider.SetNodeStatus(aos::NodeStatus(aos::NodeStatusEnum::ePaused)); - zassert_true(err.IsNone(), "Set node status failed: %s", err.Message()); + zassert_true(err.IsNone(), "Set node status failed: %s", utils::ErrorToCStr(err)); zassert_equal(observer1.mNodeStatus.GetValue(), aos::NodeStatusEnum::ePaused, "Node status mismatch"); zassert_equal(observer1.mNodeID, nodeInfo.mNodeID, "Node id mismatch"); @@ -246,7 +207,7 @@ ZTEST(nodeinfoprovider, test_node_status_changed_observer) // same node status change should not trigger the observer err = provider.SetNodeStatus(aos::NodeStatus(aos::NodeStatusEnum::ePaused)); - zassert_true(err.IsNone(), "Set node status failed: %s", err.Message()); + zassert_true(err.IsNone(), "Set node status failed: %s", utils::ErrorToCStr(err)); zassert_false(observer1.mNotified, "Observer should not be notified"); zassert_false(observer2.mNotified, "Observer should not be notified"); @@ -256,10 +217,10 @@ ZTEST(nodeinfoprovider, test_node_status_changed_observer) // unsubscribe observer1 err = provider.UnsubscribeNodeStatusChanged(observer1); - zassert_true(err.IsNone(), "Failed to unsubscribe from node status changed event: %s", err.Message()); + zassert_true(err.IsNone(), "Failed to unsubscribe from node status changed event: %s", utils::ErrorToCStr(err)); err = provider.SetNodeStatus(aos::NodeStatus(aos::NodeStatusEnum::eProvisioned)); - zassert_true(err.IsNone(), "Set node status failed: %s", err.Message()); + zassert_true(err.IsNone(), "Set node status failed: %s", utils::ErrorToCStr(err)); // observer1 should not receive the event zassert_false(observer1.mNotified, "Observer should not be notified"); From 5bb8e9c9d2cbd04a028ee8e3bdb89945ed90690f Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 18 Aug 2024 15:45:59 +0300 Subject: [PATCH 039/198] [logger] Move to aos::zephyr::logger namespace Signed-off-by: Oleksandr Grytsov --- src/logger/logger.cpp | 64 ++++++++++++++++++++++++------------------- src/logger/logger.hpp | 6 +++- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/src/logger/logger.cpp b/src/logger/logger.cpp index d6f1cee0..0af29440 100644 --- a/src/logger/logger.cpp +++ b/src/logger/logger.cpp @@ -9,28 +9,31 @@ #include "logger.hpp" +namespace aos::zephyr::logger { + /*********************************************************************************************************************** * Consts **********************************************************************************************************************/ -static const aos::String cLogModuleApp = "app"; -static const aos::String cLogModuleCommunication = "communication"; -static const aos::String cLogModuleClockSync = "clocksync"; -static const aos::String cLogModuleDownloader = "downloader"; -static const aos::String cLogModuleOCISpec = "ocispec"; -static const aos::String cLogModuleProvisionManager = "provisionmanager"; -static const aos::String cLogModuleResourceManager = "resourcemanager"; -static const aos::String cLogModuleRunner = "runner"; -static const aos::String cLogModuleSMClient = "smclient"; -static const aos::String cLogModuleStorage = "storage"; -static const aos::String cLogModuleNodeInfoProvider = "nodeinfoprovider"; - -static const aos::String cLogModuleCerthandler = "certhandler"; -static const aos::String cLogModuleCrypto = "crypto"; -static const aos::String cLogModuleLauncher = "launcher"; -static const aos::String cLogModuleMonitoring = "monitoring"; -static const aos::String cLogModuleServiceManager = "servicemanager"; -static const aos::String cLogModulePKCS11 = "pkcs11"; +static const String cLogModuleApp = "app"; +static const String cLogModuleClockSync = "clocksync"; +static const String cLogModuleCommunication = "communication"; +static const String cLogModuleDownloader = "downloader"; +static const String cLogModuleIAMClient = "iamclient"; +static const String cLogModuleNodeInfoProvider = "nodeinfoprovider"; +static const String cLogModuleOCISpec = "ocispec"; +static const String cLogModuleProvisionManager = "provisionmanager"; +static const String cLogModuleResourceManager = "resourcemanager"; +static const String cLogModuleRunner = "runner"; +static const String cLogModuleSMClient = "smclient"; +static const String cLogModuleStorage = "storage"; + +static const String cLogModuleCerthandler = "certhandler"; +static const String cLogModuleCrypto = "crypto"; +static const String cLogModuleLauncher = "launcher"; +static const String cLogModuleMonitoring = "monitoring"; +static const String cLogModulePKCS11 = "pkcs11"; +static const String cLogModuleServiceManager = "servicemanager"; /*********************************************************************************************************************** * Log module callbacks @@ -41,25 +44,25 @@ static const aos::String cLogModulePKCS11 = "pkcs11"; { \ LOG_MODULE_REGISTER(name, CONFIG_LOG_DEFAULT_LEVEL); \ \ - static void LogCallback(aos::LogLevel level, const aos::String& message) \ + static void LogCallback(LogLevel level, const String& message) \ { \ switch (level.GetValue()) { \ - case aos::LogLevelEnum::eDebug: \ + case LogLevelEnum::eDebug: \ LOG_DBG("%s", message.CStr()); \ \ break; \ \ - case aos::LogLevelEnum::eInfo: \ + case LogLevelEnum::eInfo: \ LOG_INF("%s", message.CStr()); \ \ break; \ \ - case aos::LogLevelEnum::eWarning: \ + case LogLevelEnum::eWarning: \ LOG_WRN("%s", message.CStr()); \ \ break; \ \ - case aos::LogLevelEnum::eError: \ + case LogLevelEnum::eError: \ LOG_ERR("%s", message.CStr()); \ \ break; \ @@ -77,21 +80,22 @@ LOG_CALLBACK(app); LOG_CALLBACK(clocksync); LOG_CALLBACK(communication); LOG_CALLBACK(downloader); +LOG_CALLBACK(iamclient); +LOG_CALLBACK(nodeinfoprovider); LOG_CALLBACK(ocispec); LOG_CALLBACK(provisionmanager); LOG_CALLBACK(resourcemanager); LOG_CALLBACK(runner); LOG_CALLBACK(smclient); LOG_CALLBACK(storage); -LOG_CALLBACK(nodeinfoprovider); // Aos lib logs LOG_CALLBACK(certhandler); LOG_CALLBACK(crypto); LOG_CALLBACK(launcher); LOG_CALLBACK(monitoring); -LOG_CALLBACK(servicemanager); LOG_CALLBACK(pkcs11); +LOG_CALLBACK(servicemanager); /*********************************************************************************************************************** * Public @@ -99,16 +103,16 @@ LOG_CALLBACK(pkcs11); void Logger::Init() { - aos::Log::SetCallback(LogCallback); + Log::SetCallback(LogCallback); } /*********************************************************************************************************************** * Public **********************************************************************************************************************/ -void Logger::LogCallback(const char* module, aos::LogLevel level, const aos::String& message) +void Logger::LogCallback(const char* module, LogLevel level, const String& message) { - aos::String logModule(module); + String logModule(module); if (logModule == cLogModuleApp) { log_app::LogCallback(level, message); @@ -128,6 +132,8 @@ void Logger::LogCallback(const char* module, aos::LogLevel level, const aos::Str log_runner::LogCallback(level, message); } else if (logModule == cLogModuleSMClient) { log_smclient::LogCallback(level, message); + } else if (logModule == cLogModuleIAMClient) { + log_iamclient::LogCallback(level, message); } else if (logModule == cLogModuleStorage) { log_storage::LogCallback(level, message); } else if (logModule == cLogModuleNodeInfoProvider) { @@ -149,3 +155,5 @@ void Logger::LogCallback(const char* module, aos::LogLevel level, const aos::Str << "Log from unknown module received: module=" << module << ", level=" << level << ", message=" << message; } } + +} // namespace aos::zephyr::logger diff --git a/src/logger/logger.hpp b/src/logger/logger.hpp index 777e565c..fda587ec 100644 --- a/src/logger/logger.hpp +++ b/src/logger/logger.hpp @@ -10,6 +10,8 @@ #include +namespace aos::zephyr::logger { + /** * Logger instance. */ @@ -21,7 +23,9 @@ class Logger { static void Init(); private: - static void LogCallback(const char* module, aos::LogLevel level, const aos::String& message); + static void LogCallback(const char* module, LogLevel level, const String& message); }; +} // namespace aos::zephyr::logger + #endif From 12a119405bd8a354f99b466b4e44362784e399f2 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 18 Aug 2024 15:47:19 +0300 Subject: [PATCH 040/198] [communication] Add channel manager skeleton API Signed-off-by: Oleksandr Grytsov --- CMakeLists.txt | 1 + src/communication/channelmanager.cpp | 31 +++++++++++++++++++ src/communication/channelmanager.hpp | 20 +++++++----- tests/communication/prj.conf | 2 +- .../src/stubs/certloaderstub.hpp | 5 --- 5 files changed, 45 insertions(+), 14 deletions(-) create mode 100644 src/communication/channelmanager.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c0720bd1..7710debd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,7 @@ target_sources( PRIVATE src/main.cpp src/app/app.cpp src/clocksync/clocksync.cpp + src/communication/channelmanager.cpp src/communication/tlschannel.cpp src/communication/xenvchan.cpp src/downloader/downloader.cpp diff --git a/src/communication/channelmanager.cpp b/src/communication/channelmanager.cpp new file mode 100644 index 00000000..7511ce92 --- /dev/null +++ b/src/communication/channelmanager.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "channelmanager.hpp" + +namespace aos::zephyr::communication { + +/*********************************************************************************************************************** + * Public + **********************************************************************************************************************/ + +Error ChannelManager::Init(TransportItf& transport) +{ + return ErrorEnum::eNone; +} + +RetWithError ChannelManager::CreateChannel(uint32_t port) +{ + return {nullptr, ErrorEnum::eNotSupported}; +} + +Error ChannelManager::DeleteChannel(uint32_t port) +{ + return ErrorEnum::eNone; +} + +} // namespace aos::zephyr::communication diff --git a/src/communication/channelmanager.hpp b/src/communication/channelmanager.hpp index d330cb91..32ffaf7a 100644 --- a/src/communication/channelmanager.hpp +++ b/src/communication/channelmanager.hpp @@ -8,6 +8,10 @@ #ifndef COMMUNICATION_HPP_ #define COMMUNICATION_HPP_ +#include + +#include + #include "channel.hpp" #include "transport.hpp" @@ -22,17 +26,17 @@ class ChannelManagerItf { * Create channel with dedicated port. * * @param port port to bind channel. - * @return aos::RetWithError + * @return RetWithError. */ - virtual aos::RetWithError CreateChannel(uint32_t port) = 0; + virtual RetWithError CreateChannel(uint32_t port) = 0; /** * Deletes channel. * * @param port port channel is bound to. - * @return aos::Error + * @return Error. */ - virtual aos::Error DeleteChannel(uint32_t port) = 0; + virtual Error DeleteChannel(uint32_t port) = 0; /** * Destructor. @@ -49,9 +53,9 @@ class ChannelManager : public ChannelManagerItf { * Initializes channel manager. * * @param transport communication transport. - * @return * aos::Error + * @return Error. */ - aos::Error Init(TransportItf& transport); + Error Init(TransportItf& transport); /** * Create channel with dedicated port. @@ -59,7 +63,7 @@ class ChannelManager : public ChannelManagerItf { * @param port port to bind channel. * @return aos::RetWithError */ - aos::RetWithError CreateChannel(uint32_t port) override; + RetWithError CreateChannel(uint32_t port) override; /** * Deletes channel. @@ -67,7 +71,7 @@ class ChannelManager : public ChannelManagerItf { * @param port port channel is bound to. * @return aos::Error */ - aos::Error DeleteChannel(uint32_t port) override; + Error DeleteChannel(uint32_t port) override; }; } // namespace aos::zephyr::communication diff --git a/tests/communication/prj.conf b/tests/communication/prj.conf index 2faca0e1..54959e6f 100644 --- a/tests/communication/prj.conf +++ b/tests/communication/prj.conf @@ -1,7 +1,7 @@ # Enable C++ CONFIG_CPP=y -CONFIG_STD_CPP14=y +CONFIG_STD_CPP17=y CONFIG_EXTERNAL_LIBCPP=y CONFIG_CBPRINTF_FP_SUPPORT=y diff --git a/tests/communication/src/stubs/certloaderstub.hpp b/tests/communication/src/stubs/certloaderstub.hpp index f8b23630..12ad88c7 100644 --- a/tests/communication/src/stubs/certloaderstub.hpp +++ b/tests/communication/src/stubs/certloaderstub.hpp @@ -23,11 +23,6 @@ class CertLoaderStub : public aos::cryptoutils::CertLoaderItf { public: - aos::Error Init(aos::crypto::x509::ProviderItf& cryptoProvider, aos::pkcs11::PKCS11Manager& pkcs11Manager) override - { - return aos::ErrorEnum::eNone; - } - aos::RetWithError> LoadCertsChainByURL( const aos::String& url) override { From 99924ca2268b9e56a2acd2db325a9aab4f3e6fb7 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 18 Aug 2024 15:49:46 +0300 Subject: [PATCH 041/198] [communication,pbhandler] Add mutex to Init as it can be reinit Signed-off-by: Oleksandr Grytsov --- src/communication/pbhandler.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/communication/pbhandler.cpp b/src/communication/pbhandler.cpp index 57421a74..c88bd275 100644 --- a/src/communication/pbhandler.cpp +++ b/src/communication/pbhandler.cpp @@ -17,6 +17,12 @@ namespace aos::zephyr::communication { template Error PBHandler::Init(const String& name, ChannelItf& channel) { + LockGuard lock {mMutex}; + + if (mStarted) { + return Error(ErrorEnum::eWrongState, "PB handler already started"); + } + mName = name; mChannel = &channel; @@ -47,8 +53,6 @@ Error PBHandler::Start() template Error PBHandler::Stop() { - LOG_DBG() << "Stop PB handler: name=" << mName; - { LockGuard lock {mMutex}; @@ -56,6 +60,8 @@ Error PBHandler::Stop() return ErrorEnum::eNone; } + LOG_DBG() << "Stop PB handler: name=" << mName; + mStarted = false; mChannel->Close(); } From 5b8c253f39c87142c439f6dabd1ca7df185a7060 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 18 Aug 2024 15:57:49 +0300 Subject: [PATCH 042/198] [ocispec] Move to aos::zephyr::ocispec namespace Signed-off-by: Oleksandr Grytsov --- src/ocispec/ocispec.cpp | 116 +++++++++++++++++------------------ src/ocispec/ocispec.hpp | 42 +++++++------ tests/ocispec/CMakeLists.txt | 12 ++-- tests/ocispec/Kconfig | 28 --------- tests/ocispec/prj.conf | 4 +- tests/ocispec/src/main.cpp | 8 ++- 6 files changed, 96 insertions(+), 114 deletions(-) diff --git a/src/ocispec/ocispec.cpp b/src/ocispec/ocispec.cpp index 6ffe1fc4..d46b629f 100644 --- a/src/ocispec/ocispec.cpp +++ b/src/ocispec/ocispec.cpp @@ -13,6 +13,8 @@ #include "log.hpp" #include "ocispec.hpp" +namespace aos::zephyr::ocispec { + /*********************************************************************************************************************** * Vars **********************************************************************************************************************/ @@ -29,17 +31,17 @@ const struct json_obj_descr ImageManifestDescr[] = { JSON_OBJ_DESCR_PRIM(ImageManifest, schemaVersion, JSON_TOK_NUMBER), JSON_OBJ_DESCR_PRIM(ImageManifest, mediaType, JSON_TOK_STRING), JSON_OBJ_DESCR_OBJECT(ImageManifest, config, ContentDescriptorDescr), - JSON_OBJ_DESCR_OBJ_ARRAY(ImageManifest, layers, aos::cMaxNumLayers, layersLen, ContentDescriptorDescr, - ARRAY_SIZE(ContentDescriptorDescr)), + JSON_OBJ_DESCR_OBJ_ARRAY( + ImageManifest, layers, cMaxNumLayers, layersLen, ContentDescriptorDescr, ARRAY_SIZE(ContentDescriptorDescr)), JSON_OBJ_DESCR_OBJECT(ImageManifest, aosService, ContentDescriptorDescr), }; // Image spec const struct json_obj_descr ImageConfigDescr[] = { - JSON_OBJ_DESCR_ARRAY(ImageConfig, Env, aos::oci::cMaxParamCount, envLen, JSON_TOK_STRING), - JSON_OBJ_DESCR_ARRAY(ImageConfig, Entrypoint, aos::oci::cMaxParamCount, entrypointLen, JSON_TOK_STRING), - JSON_OBJ_DESCR_ARRAY(ImageConfig, Cmd, aos::oci::cMaxParamCount, cmdLen, JSON_TOK_STRING), + JSON_OBJ_DESCR_ARRAY(ImageConfig, Env, oci::cMaxParamCount, envLen, JSON_TOK_STRING), + JSON_OBJ_DESCR_ARRAY(ImageConfig, Entrypoint, oci::cMaxParamCount, entrypointLen, JSON_TOK_STRING), + JSON_OBJ_DESCR_ARRAY(ImageConfig, Cmd, oci::cMaxParamCount, cmdLen, JSON_TOK_STRING), }; const struct json_obj_descr ImageSpecDescr[] = { @@ -50,12 +52,12 @@ const struct json_obj_descr ImageSpecDescr[] = { static const struct json_obj_descr VMHypervisorDescr[] = { JSON_OBJ_DESCR_PRIM(VMHypervisor, path, JSON_TOK_STRING), - JSON_OBJ_DESCR_ARRAY(VMHypervisor, parameters, aos::oci::cMaxParamCount, parametersLen, JSON_TOK_STRING), + JSON_OBJ_DESCR_ARRAY(VMHypervisor, parameters, oci::cMaxParamCount, parametersLen, JSON_TOK_STRING), }; static const struct json_obj_descr VMKernelDescr[] = { JSON_OBJ_DESCR_PRIM(VMKernel, path, JSON_TOK_STRING), - JSON_OBJ_DESCR_ARRAY(VMKernel, parameters, aos::oci::cMaxParamCount, parametersLen, JSON_TOK_STRING), + JSON_OBJ_DESCR_ARRAY(VMKernel, parameters, oci::cMaxParamCount, parametersLen, JSON_TOK_STRING), }; static const struct json_obj_descr VMHWConfigIOMEMDescr[] = { @@ -68,10 +70,10 @@ static const struct json_obj_descr VMHWConfigDescr[] = { JSON_OBJ_DESCR_PRIM(VMHWConfig, deviceTree, JSON_TOK_STRING), JSON_OBJ_DESCR_PRIM(VMHWConfig, vcpus, JSON_TOK_NUMBER), JSON_OBJ_DESCR_PRIM(VMHWConfig, memKB, JSON_TOK_FLOAT), - JSON_OBJ_DESCR_ARRAY(VMHWConfig, dtdevs, aos::oci::cMaxDTDevsCount, dtdevsLen, JSON_TOK_STRING), - JSON_OBJ_DESCR_OBJ_ARRAY(VMHWConfig, iomems, aos::oci::cMaxIOMEMsCount, iomemsLen, VMHWConfigIOMEMDescr, - ARRAY_SIZE(VMHWConfigIOMEMDescr)), - JSON_OBJ_DESCR_ARRAY(VMHWConfig, irqs, aos::oci::cMaxIRQsCount, irqsLen, JSON_TOK_NUMBER), + JSON_OBJ_DESCR_ARRAY(VMHWConfig, dtdevs, oci::cMaxDTDevsCount, dtdevsLen, JSON_TOK_STRING), + JSON_OBJ_DESCR_OBJ_ARRAY( + VMHWConfig, iomems, oci::cMaxIOMEMsCount, iomemsLen, VMHWConfigIOMEMDescr, ARRAY_SIZE(VMHWConfigIOMEMDescr)), + JSON_OBJ_DESCR_ARRAY(VMHWConfig, irqs, oci::cMaxIRQsCount, irqsLen, JSON_TOK_NUMBER), }; static const struct json_obj_descr VMDescr[] = { @@ -90,13 +92,13 @@ static const struct json_obj_descr RuntimeSpecDescr[] = { **********************************************************************************************************************/ // cppcheck-suppress unusedFunction -aos::Error OCISpec::LoadImageManifest(const aos::String& path, aos::oci::ImageManifest& manifest) +Error OCISpec::LoadImageManifest(const String& path, oci::ImageManifest& manifest) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Load image manifest: " << path; - auto err = aos::FS::ReadFileToString(path, mJsonFileContent); + auto err = FS::ReadFileToString(path, mJsonFileContent); if (!err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -127,8 +129,7 @@ aos::Error OCISpec::LoadImageManifest(const aos::String& path, aos::oci::ImageMa int64_t size = 0; if (jsonImageManifest->config.size.start) { - auto configSize - = aos::String(jsonImageManifest->config.size.start, jsonImageManifest->config.size.length).ToInt64(); + auto configSize = String(jsonImageManifest->config.size.start, jsonImageManifest->config.size.length).ToInt64(); if (!configSize.mError.IsNone()) { return AOS_ERROR_WRAP(configSize.mError); } @@ -145,8 +146,7 @@ aos::Error OCISpec::LoadImageManifest(const aos::String& path, aos::oci::ImageMa if (jsonImageManifest->layers[i].size.start) { auto layerSize - = aos::String(jsonImageManifest->layers[i].size.start, jsonImageManifest->layers[i].size.length) - .ToInt64(); + = String(jsonImageManifest->layers[i].size.start, jsonImageManifest->layers[i].size.length).ToInt64(); if (!layerSize.mError.IsNone()) { return AOS_ERROR_WRAP(layerSize.mError); } @@ -161,15 +161,14 @@ aos::Error OCISpec::LoadImageManifest(const aos::String& path, aos::oci::ImageMa if (ret & eImageManifestAosServiceField) { if (manifest.mAosService == nullptr) { - return AOS_ERROR_WRAP(aos::ErrorEnum::eNoMemory); + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } size = 0; if (jsonImageManifest->aosService.size.start) { auto serviceSize - = aos::String(jsonImageManifest->aosService.size.start, jsonImageManifest->aosService.size.length) - .ToInt64(); + = String(jsonImageManifest->aosService.size.start, jsonImageManifest->aosService.size.length).ToInt64(); if (!serviceSize.mError.IsNone()) { return AOS_ERROR_WRAP(serviceSize.mError); } @@ -180,13 +179,13 @@ aos::Error OCISpec::LoadImageManifest(const aos::String& path, aos::oci::ImageMa *manifest.mAosService = {jsonImageManifest->aosService.mediaType, jsonImageManifest->aosService.digest, size}; } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -aos::Error OCISpec::SaveImageManifest(const aos::String& path, const aos::oci::ImageManifest& manifest) +Error OCISpec::SaveImageManifest(const String& path, const oci::ImageManifest& manifest) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Save image manifest: " << path; @@ -204,7 +203,7 @@ aos::Error OCISpec::SaveImageManifest(const aos::String& path, const aos::oci::I // config - auto configSize = new (&mAllocator) aos::StaticString<20>; + auto configSize = new (&mAllocator) StaticString<20>; auto err = configSize->Convert(manifest.mConfig.mSize); if (!err.IsNone()) { @@ -219,7 +218,7 @@ aos::Error OCISpec::SaveImageManifest(const aos::String& path, const aos::oci::I jsonImageManifest->layersLen = manifest.mLayers.Size(); for (size_t i = 0; i < jsonImageManifest->layersLen; i++) { - auto layerSize = new (&mAllocator) aos::StaticString<20>; + auto layerSize = new (&mAllocator) StaticString<20>; err = layerSize->Convert(manifest.mLayers[i].mSize); if (!err.IsNone()) { @@ -233,7 +232,7 @@ aos::Error OCISpec::SaveImageManifest(const aos::String& path, const aos::oci::I // aosService if (manifest.mAosService) { - auto serviceSize = new (&mAllocator) aos::StaticString<20>; + auto serviceSize = new (&mAllocator) StaticString<20>; err = serviceSize->Convert(manifest.mAosService->mSize); if (!err.IsNone()) { @@ -255,22 +254,22 @@ aos::Error OCISpec::SaveImageManifest(const aos::String& path, const aos::oci::I return AOS_ERROR_WRAP(err); } - err = aos::FS::WriteStringToFile(path, mJsonFileContent, S_IRUSR | S_IWUSR); + err = FS::WriteStringToFile(path, mJsonFileContent, S_IRUSR | S_IWUSR); if (!err.IsNone()) { return err; } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -aos::Error OCISpec::LoadImageSpec(const aos::String& path, aos::oci::ImageSpec& imageSpec) +Error OCISpec::LoadImageSpec(const String& path, oci::ImageSpec& imageSpec) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Load image spec: " << path; - auto err = aos::FS::ReadFileToString(path, mJsonFileContent); + auto err = FS::ReadFileToString(path, mJsonFileContent); if (!err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -305,13 +304,13 @@ aos::Error OCISpec::LoadImageSpec(const aos::String& path, aos::oci::ImageSpec& imageSpec.mConfig.mCmd.PushBack(jsonImageSpec->config.Cmd[i]); } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -aos::Error OCISpec::SaveImageSpec(const aos::String& path, const aos::oci::ImageSpec& imageSpec) +Error OCISpec::SaveImageSpec(const String& path, const oci::ImageSpec& imageSpec) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Save image spec: " << path; @@ -356,22 +355,22 @@ aos::Error OCISpec::SaveImageSpec(const aos::String& path, const aos::oci::Image return AOS_ERROR_WRAP(err); } - err = aos::FS::WriteStringToFile(path, mJsonFileContent, S_IRUSR | S_IWUSR); + err = FS::WriteStringToFile(path, mJsonFileContent, S_IRUSR | S_IWUSR); if (!err.IsNone()) { return err; } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -aos::Error OCISpec::LoadRuntimeSpec(const aos::String& path, aos::oci::RuntimeSpec& runtimeSpec) +Error OCISpec::LoadRuntimeSpec(const String& path, oci::RuntimeSpec& runtimeSpec) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Load runtime spec: " << path; - auto err = aos::FS::ReadFileToString(path, mJsonFileContent); + auto err = FS::ReadFileToString(path, mJsonFileContent); if (!err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -397,7 +396,7 @@ aos::Error OCISpec::LoadRuntimeSpec(const aos::String& path, aos::oci::RuntimeSp if (ret & eRuntimeVMField) { if (runtimeSpec.mVM == nullptr) { - return AOS_ERROR_WRAP(aos::ErrorEnum::eNoMemory); + return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } runtimeSpec.mVM->mHypervisor.mPath = jsonRuntimeSpec->vm.hypervisor.path; @@ -417,9 +416,8 @@ aos::Error OCISpec::LoadRuntimeSpec(const aos::String& path, aos::oci::RuntimeSp uint64_t memKB = 0; if (jsonRuntimeSpec->vm.hwConfig.memKB.start) { - auto result - = aos::String(jsonRuntimeSpec->vm.hwConfig.memKB.start, jsonRuntimeSpec->vm.hwConfig.memKB.length) - .ToUint64(); + auto result = String(jsonRuntimeSpec->vm.hwConfig.memKB.start, jsonRuntimeSpec->vm.hwConfig.memKB.length) + .ToUint64(); if (!result.mError.IsNone()) { return AOS_ERROR_WRAP(result.mError); } @@ -434,11 +432,11 @@ aos::Error OCISpec::LoadRuntimeSpec(const aos::String& path, aos::oci::RuntimeSp } for (size_t i = 0; i < jsonRuntimeSpec->vm.hwConfig.iomemsLen; i++) { - aos::oci::VMHWConfigIOMEM ioMem {}; - auto jsonIOMem = jsonRuntimeSpec->vm.hwConfig.iomems[i]; + oci::VMHWConfigIOMEM ioMem {}; + auto jsonIOMem = jsonRuntimeSpec->vm.hwConfig.iomems[i]; if (jsonIOMem.firstGFN.start) { - auto result = aos::String(jsonIOMem.firstGFN.start, jsonIOMem.firstGFN.length).ToUint64(); + auto result = String(jsonIOMem.firstGFN.start, jsonIOMem.firstGFN.length).ToUint64(); if (!result.mError.IsNone()) { return AOS_ERROR_WRAP(result.mError); } @@ -447,7 +445,7 @@ aos::Error OCISpec::LoadRuntimeSpec(const aos::String& path, aos::oci::RuntimeSp } if (jsonIOMem.firstMFN.start) { - auto result = aos::String(jsonIOMem.firstMFN.start, jsonIOMem.firstMFN.length).ToUint64(); + auto result = String(jsonIOMem.firstMFN.start, jsonIOMem.firstMFN.length).ToUint64(); if (!result.mError.IsNone()) { return AOS_ERROR_WRAP(result.mError); } @@ -456,7 +454,7 @@ aos::Error OCISpec::LoadRuntimeSpec(const aos::String& path, aos::oci::RuntimeSp } if (jsonIOMem.nrMFNs.start) { - auto result = aos::String(jsonIOMem.nrMFNs.start, jsonIOMem.nrMFNs.length).ToUint64(); + auto result = String(jsonIOMem.nrMFNs.start, jsonIOMem.nrMFNs.length).ToUint64(); if (!result.mError.IsNone()) { return AOS_ERROR_WRAP(result.mError); } @@ -472,13 +470,13 @@ aos::Error OCISpec::LoadRuntimeSpec(const aos::String& path, aos::oci::RuntimeSp } } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -aos::Error OCISpec::SaveRuntimeSpec(const aos::String& path, const aos::oci::RuntimeSpec& runtimeSpec) +Error OCISpec::SaveRuntimeSpec(const String& path, const oci::RuntimeSpec& runtimeSpec) { - aos::LockGuard lock(mMutex); + LockGuard lock(mMutex); LOG_DBG() << "Save runtime spec: " << path; @@ -512,7 +510,7 @@ aos::Error OCISpec::SaveRuntimeSpec(const aos::String& path, const aos::oci::Run jsonRuntimeSpec->vm.hwConfig.deviceTree = runtimeSpec.mVM->mHWConfig.mDeviceTree.CStr(); jsonRuntimeSpec->vm.hwConfig.vcpus = runtimeSpec.mVM->mHWConfig.mVCPUs; - auto memKB = new (&mAllocator) aos::StaticString<20>; + auto memKB = new (&mAllocator) StaticString<20>; auto err = memKB->Convert(runtimeSpec.mVM->mHWConfig.mMemKB); if (!err.IsNone()) { @@ -532,21 +530,21 @@ aos::Error OCISpec::SaveRuntimeSpec(const aos::String& path, const aos::oci::Run for (size_t i = 0; i < jsonRuntimeSpec->vm.hwConfig.iomemsLen; i++) { auto iomem = runtimeSpec.mVM->mHWConfig.mIOMEMs[i]; - auto firstGFN = new (&mAllocator) aos::StaticString<20>; + auto firstGFN = new (&mAllocator) StaticString<20>; err = firstGFN->Convert(iomem.mFirstGFN); if (!err.IsNone()) { return AOS_ERROR_WRAP(err); } - auto firstMFN = new (&mAllocator) aos::StaticString<20>; + auto firstMFN = new (&mAllocator) StaticString<20>; err = firstMFN->Convert(iomem.mFirstMFN); if (!err.IsNone()) { return AOS_ERROR_WRAP(err); } - auto nrMFNs = new (&mAllocator) aos::StaticString<20>; + auto nrMFNs = new (&mAllocator) StaticString<20>; err = nrMFNs->Convert(iomem.mNrMFNs); if (!err.IsNone()) { @@ -578,10 +576,12 @@ aos::Error OCISpec::SaveRuntimeSpec(const aos::String& path, const aos::oci::Run return AOS_ERROR_WRAP(err); } - err = aos::FS::WriteStringToFile(path, mJsonFileContent, S_IRUSR | S_IWUSR); + err = FS::WriteStringToFile(path, mJsonFileContent, S_IRUSR | S_IWUSR); if (!err.IsNone()) { return err; } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } + +} // namespace aos::zephyr::ocispec diff --git a/src/ocispec/ocispec.hpp b/src/ocispec/ocispec.hpp index ea2e077f..87aa2da2 100644 --- a/src/ocispec/ocispec.hpp +++ b/src/ocispec/ocispec.hpp @@ -14,6 +14,8 @@ #include #include +namespace aos::zephyr::ocispec { + // Image spec /** @@ -33,7 +35,7 @@ struct ImageManifest { int schemaVersion; const char* mediaType; ContentDescriptor config; - ContentDescriptor layers[aos::cMaxNumLayers]; + ContentDescriptor layers[cMaxNumLayers]; size_t layersLen; ContentDescriptor aosService; }; @@ -53,11 +55,11 @@ enum ImageManifestFields { * OCI image config. */ struct ImageConfig { - const char* Cmd[aos::oci::cMaxParamCount]; + const char* Cmd[oci::cMaxParamCount]; size_t cmdLen; - const char* Env[aos::oci::cMaxParamCount]; + const char* Env[oci::cMaxParamCount]; size_t envLen; - const char* Entrypoint[aos::oci::cMaxParamCount]; + const char* Entrypoint[oci::cMaxParamCount]; size_t entrypointLen; }; @@ -75,7 +77,7 @@ struct ImageSpec { */ struct VMHypervisor { const char* path; - const char* parameters[aos::oci::cMaxParamCount]; + const char* parameters[oci::cMaxParamCount]; size_t parametersLen; }; @@ -84,7 +86,7 @@ struct VMHypervisor { */ struct VMKernel { const char* path; - const char* parameters[aos::oci::cMaxParamCount]; + const char* parameters[oci::cMaxParamCount]; size_t parametersLen; }; @@ -104,11 +106,11 @@ struct VMHWConfig { const char* deviceTree; uint32_t vcpus; json_obj_token memKB; - const char* dtdevs[aos::oci::cMaxDTDevsCount]; + const char* dtdevs[oci::cMaxDTDevsCount]; size_t dtdevsLen; - VMHWConfigIOMEM iomems[aos::oci::cMaxIOMEMsCount]; + VMHWConfigIOMEM iomems[oci::cMaxIOMEMsCount]; size_t iomemsLen; - uint32_t irqs[aos::oci::cMaxIRQsCount]; + uint32_t irqs[oci::cMaxIRQsCount]; size_t irqsLen; }; @@ -140,7 +142,7 @@ struct RuntimeSpec { /** * OCISpec instance. */ -class OCISpec : public aos::OCISpecItf { +class OCISpec : public OCISpecItf { public: /** * Loads OCI image manifest. @@ -149,7 +151,7 @@ class OCISpec : public aos::OCISpecItf { * @param manifest image manifest. * @return Error. */ - aos::Error LoadImageManifest(const aos::String& path, aos::oci::ImageManifest& manifest) override; + Error LoadImageManifest(const String& path, oci::ImageManifest& manifest) override; /** * Saves OCI image manifest. @@ -158,7 +160,7 @@ class OCISpec : public aos::OCISpecItf { * @param manifest image manifest. * @return Error. */ - aos::Error SaveImageManifest(const aos::String& path, const aos::oci::ImageManifest& manifest) override; + Error SaveImageManifest(const String& path, const oci::ImageManifest& manifest) override; /** * Loads OCI image spec. @@ -167,7 +169,7 @@ class OCISpec : public aos::OCISpecItf { * @param imageSpec image spec. * @return Error. */ - aos::Error LoadImageSpec(const aos::String& path, aos::oci::ImageSpec& imageSpec) override; + Error LoadImageSpec(const String& path, oci::ImageSpec& imageSpec) override; /** * Saves OCI image spec. @@ -176,7 +178,7 @@ class OCISpec : public aos::OCISpecItf { * @param imageSpec image spec. * @return Error. */ - aos::Error SaveImageSpec(const aos::String& path, const aos::oci::ImageSpec& imageSpec) override; + Error SaveImageSpec(const String& path, const oci::ImageSpec& imageSpec) override; /** * Loads OCI runtime spec. @@ -185,7 +187,7 @@ class OCISpec : public aos::OCISpecItf { * @param runtimeSpec runtime spec. * @return Error. */ - aos::Error LoadRuntimeSpec(const aos::String& path, aos::oci::RuntimeSpec& runtimeSpec) override; + Error LoadRuntimeSpec(const String& path, oci::RuntimeSpec& runtimeSpec) override; /** * Saves OCI runtime spec. @@ -194,16 +196,18 @@ class OCISpec : public aos::OCISpecItf { * @param runtimeSpec runtime spec. * @return Error. */ - virtual aos::Error SaveRuntimeSpec(const aos::String& path, const aos::oci::RuntimeSpec& runtimeSpec) override; + virtual Error SaveRuntimeSpec(const String& path, const oci::RuntimeSpec& runtimeSpec) override; private: static constexpr size_t cJsonMaxContentLen = 4096; static constexpr size_t cAllocationSize = 2048; static constexpr size_t cMaxNumAllocations = 32; - aos::Mutex mMutex; - aos::StaticString mJsonFileContent; - aos::StaticAllocator mAllocator; + Mutex mMutex; + StaticString mJsonFileContent; + StaticAllocator mAllocator; }; +} // namespace aos::zephyr::ocispec + #endif diff --git a/tests/ocispec/CMakeLists.txt b/tests/ocispec/CMakeLists.txt index d64c48cf..2daaaa5c 100644 --- a/tests/ocispec/CMakeLists.txt +++ b/tests/ocispec/CMakeLists.txt @@ -14,22 +14,24 @@ project(ocispec_test) # Config # ###################################################################################################################### -set(AOS_CORE_CONFIG aoscoreconfig.hpp) +set(aoscore_config aoscoreconfig.hpp) +set(aoscore_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../../../aos_core_lib_cpp") # ###################################################################################################################### # Definitions # ###################################################################################################################### # Aos core configuration -add_definitions(-include ${AOS_CORE_CONFIG}) +add_definitions(-include ${aoscore_config}) # ###################################################################################################################### # Includes # ###################################################################################################################### -target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../src) -target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../../aos_core_lib_cpp/include) -target_include_directories(app PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +zephyr_include_directories(${aoscore_source_dir}/include) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/..) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/../../src) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src) # ###################################################################################################################### # Target diff --git a/tests/ocispec/Kconfig b/tests/ocispec/Kconfig index a1ed37ad..3bc0c765 100644 --- a/tests/ocispec/Kconfig +++ b/tests/ocispec/Kconfig @@ -5,32 +5,4 @@ mainmenu "Aos zephyr application" -config AOS_DOMD_ID - int "DomD id" - default 1 - -config AOS_SM_VCHAN_PATH - string "Path to the SM vchan" - default "/vchan/sm" - -config AOS_NODE_ID - string "Node id" - default "NODE_0" - -config AOS_NODE_TYPE - string "Node type" - default "NODE_TYPE1" - -config AOS_NUM_CPU - int "Count of CPUs for domain with Zephyr" - default 1 - -config AOS_TOTAL_RAM - int "Total RAM of the domain" - default 204800 - -config AOS_PARTITION_SIZE - int "Partition size" - default 209715200 - source "Kconfig" diff --git a/tests/ocispec/prj.conf b/tests/ocispec/prj.conf index 4460169e..bbfb6174 100644 --- a/tests/ocispec/prj.conf +++ b/tests/ocispec/prj.conf @@ -1,7 +1,9 @@ # Enable C++ CONFIG_CPP=y -CONFIG_STD_CPP14=y +CONFIG_STD_CPP17=y +CONFIG_EXTERNAL_LIBCPP=y +CONFIG_CBPRINTF_FP_SUPPORT=y # Enable test suit diff --git a/tests/ocispec/src/main.cpp b/tests/ocispec/src/main.cpp index 0b64f30e..6a5b1bc8 100644 --- a/tests/ocispec/src/main.cpp +++ b/tests/ocispec/src/main.cpp @@ -12,6 +12,8 @@ #include +using namespace aos::zephyr; + /*********************************************************************************************************************** * Consts **********************************************************************************************************************/ @@ -165,7 +167,7 @@ ZTEST(ocispec, test_ImageManifest) // Save image spec - OCISpec ociSpec; + ocispec::OCISpec ociSpec; for (auto testItem : testData) { auto err = ociSpec.SaveImageManifest(cImageManifestPath, testItem.mImageManifest); @@ -334,7 +336,7 @@ ZTEST(ocispec, test_ImageSpec) // Save image spec - OCISpec ociSpec; + ocispec::OCISpec ociSpec; for (auto testItem : testData) { auto err = ociSpec.SaveImageSpec(cImageSpecPath, testItem.mImageSpec); @@ -549,7 +551,7 @@ ZTEST(ocispec, test_RuntimeSpec) // Save runtime spec - OCISpec ociSpec; + ocispec::OCISpec ociSpec; for (auto testItem : testData) { auto err = ociSpec.SaveRuntimeSpec(cRuntimeSpecPath, testItem.mRuntimeSpec); From 810095ee352a7ef020a65d27fd49aefcdd32840f Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 18 Aug 2024 16:08:38 +0300 Subject: [PATCH 043/198] [runner] Move to aos::zephyr::runner namespace Signed-off-by: Oleksandr Grytsov --- src/runner/runner.cpp | 18 ++++++++++-------- src/runner/runner.hpp | 16 ++++++++++------ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/runner/runner.cpp b/src/runner/runner.cpp index 26a6563c..f4ddb4e0 100644 --- a/src/runner/runner.cpp +++ b/src/runner/runner.cpp @@ -10,29 +10,29 @@ #include "log.hpp" #include "runner.hpp" -using namespace aos::sm::runner; +namespace aos::zephyr::runner { /*********************************************************************************************************************** * Public **********************************************************************************************************************/ -aos::Error Runner::Init(RunStatusReceiverItf& statusReceiver) +Error Runner::Init(sm::runner::RunStatusReceiverItf& statusReceiver) { LOG_DBG() << "Initialize runner"; mStatusReceiver = &statusReceiver; - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } // cppcheck-suppress unusedFunction -RunStatus Runner::StartInstance(const aos::String& instanceID, const aos::String& runtimeDir) +sm::runner::RunStatus Runner::StartInstance(const String& instanceID, const String& runtimeDir) { - RunStatus runStatus {instanceID, aos::InstanceRunStateEnum::eActive, aos::ErrorEnum::eNone}; + sm::runner::RunStatus runStatus {instanceID, InstanceRunStateEnum::eActive, ErrorEnum::eNone}; auto ret = xrun_run(runtimeDir.CStr(), cConsoleSocket, instanceID.CStr()); if (ret != 0) { - runStatus.mState = aos::InstanceRunStateEnum::eFailed; + runStatus.mState = InstanceRunStateEnum::eFailed; runStatus.mError = AOS_ERROR_WRAP(ret); } @@ -40,12 +40,14 @@ RunStatus Runner::StartInstance(const aos::String& instanceID, const aos::String } // cppcheck-suppress unusedFunction -aos::Error Runner::StopInstance(const aos::String& instanceID) +Error Runner::StopInstance(const String& instanceID) { auto ret = xrun_kill(instanceID.CStr()); if (ret != 0) { return AOS_ERROR_WRAP(ret); } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } + +} // namespace aos::zephyr::runner diff --git a/src/runner/runner.hpp b/src/runner/runner.hpp index f6a565ed..9814e217 100644 --- a/src/runner/runner.hpp +++ b/src/runner/runner.hpp @@ -10,10 +10,12 @@ #include +namespace aos::zephyr::runner { + /** * Runner instance. */ -class Runner : public aos::sm::runner::RunnerItf, private aos::NonCopyable { +class Runner : public sm::runner::RunnerItf, private NonCopyable { public: /** * Creates runner instance. @@ -26,9 +28,9 @@ class Runner : public aos::sm::runner::RunnerItf, private aos::NonCopyable { /** * Initializes runner instance. * @param launcher instance launcher. - * @return aos::Error. + * @return Error. */ - aos::Error Init(aos::sm::runner::RunStatusReceiverItf& statusReceiver); + Error Init(sm::runner::RunStatusReceiverItf& statusReceiver); /** * Starts instance. @@ -37,7 +39,7 @@ class Runner : public aos::sm::runner::RunnerItf, private aos::NonCopyable { * @param runtimeDir directory with runtime spec. * @return RunStatus. */ - aos::sm::runner::RunStatus StartInstance(const aos::String& instanceID, const aos::String& runtimeDir) override; + sm::runner::RunStatus StartInstance(const String& instanceID, const String& runtimeDir) override; /** * Stops instance. @@ -45,12 +47,14 @@ class Runner : public aos::sm::runner::RunnerItf, private aos::NonCopyable { * @param instanceID instance ID> * @return Error. */ - aos::Error StopInstance(const aos::String& instanceID) override; + Error StopInstance(const String& instanceID) override; private: static constexpr int cConsoleSocket = 0; - aos::sm::runner::RunStatusReceiverItf* mStatusReceiver; + sm::runner::RunStatusReceiverItf* mStatusReceiver; }; +} // namespace aos::zephyr::runner + #endif From 57ef0502ce522760e5680db0e9746c0d571c3373 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 18 Aug 2024 16:09:42 +0300 Subject: [PATCH 044/198] [aosconfig] Set AOS_CONFIG_THREAD_CLOCK_ID to CLOCK_MONOTONIC for HW Signed-off-by: Oleksandr Grytsov --- src/aoscoreconfig.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/aoscoreconfig.hpp b/src/aoscoreconfig.hpp index 090fe5e6..e083a6bf 100644 --- a/src/aoscoreconfig.hpp +++ b/src/aoscoreconfig.hpp @@ -35,6 +35,11 @@ */ #define AOS_CONFIG_CRYPTOUTILS_DEFAULT_PKCS11_LIB "libckteec" +/** + * Configures clock ID used for thread time operations. + */ +#define AOS_CONFIG_THREAD_CLOCK_ID CLOCK_MONOTONIC + #endif // CONFIG_POSIX_API // This config also used to generate proto options file. Using Aos new operator causes redefinition error. From 178df170ed916568db6286f129d6853661b5d22a Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 18 Aug 2024 16:11:19 +0300 Subject: [PATCH 045/198] [boards] Set AOS_DISK_MOUNT_POINT to local .aos folder for native build Signed-off-by: Oleksandr Grytsov --- boards/native_posix.conf | 1 + boards/native_posix_64.conf | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/native_posix.conf b/boards/native_posix.conf index 6eaaca3e..b421c199 100644 --- a/boards/native_posix.conf +++ b/boards/native_posix.conf @@ -68,6 +68,7 @@ CONFIG_XSTAT_SHELL_CMDS=n # Application config +CONFIG_AOS_DISK_MOUNT_POINT=".aos" CONFIG_AOS_STORAGE_DIR=".aos/storage" CONFIG_AOS_RUNTIME_DIR=".aos/runtime" CONFIG_AOS_SERVICES_DIR=".aos/services" diff --git a/boards/native_posix_64.conf b/boards/native_posix_64.conf index 4995cc58..eecb97b6 100644 --- a/boards/native_posix_64.conf +++ b/boards/native_posix_64.conf @@ -67,6 +67,7 @@ CONFIG_XSTAT_SHELL_CMDS=n # Application config +CONFIG_AOS_DISK_MOUNT_POINT=".aos" CONFIG_AOS_STORAGE_DIR=".aos/storage" CONFIG_AOS_RUNTIME_DIR=".aos/runtime" CONFIG_AOS_SERVICES_DIR=".aos/services" From 65e235c68e37e51d7b039bafd1df92b3ff099141 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 18 Aug 2024 16:12:23 +0300 Subject: [PATCH 046/198] [resourcemanager] Fix name of header include guard Signed-off-by: Oleksandr Grytsov --- src/resourcemanager/resourcemanager.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/resourcemanager/resourcemanager.hpp b/src/resourcemanager/resourcemanager.hpp index 2e477cc1..04135bd5 100644 --- a/src/resourcemanager/resourcemanager.hpp +++ b/src/resourcemanager/resourcemanager.hpp @@ -5,8 +5,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef RESOURCE_MANAGER_HPP_ -#define RESOURCE_MANAGER_HPP_ +#ifndef RESOURCEMANAGER_HPP_ +#define RESOURCEMANAGER_HPP_ #include From 64ad4684beee46f0e6770317cfa374610b60344d Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 18 Aug 2024 16:13:17 +0300 Subject: [PATCH 047/198] [main] Update to use aos::zephyr namespace Signed-off-by: Oleksandr Grytsov --- src/main.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index e340ec8a..37dc8e3d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,6 +13,7 @@ #include "app/app.hpp" #include "logger/logger.hpp" +#include "utils/utils.hpp" // cppcheck-suppress missingInclude #include "version.hpp" @@ -25,11 +26,13 @@ #include "domains/dom_runner.h" #endif +using namespace aos::zephyr; + int main(void) { printk("*** Aos zephyr application: %s ***\n", AOS_ZEPHYR_APP_VERSION); printk("*** Aos core library: %s ***\n", AOS_CORE_VERSION); - printk("*** Aos core size: %lu ***\n", sizeof(aos::zephyr::app::App)); + printk("*** Aos core size: %lu ***\n", sizeof(app::App)); #if !defined(CONFIG_NATIVE_APPLICATION) auto ret = littlefs_mount(); @@ -44,13 +47,12 @@ int main(void) __ASSERT(ret == 0, "Error creating domains: %s [%d]", strerror(ret), ret); #endif - Logger::Init(); + logger::Logger::Init(); auto& app = aos::zephyr::app::App::Get(); auto err = app.Init(); - __ASSERT(err.IsNone(), "Error initializing application: %s [%d] (%s:%d)", err.Message(), err.Errno(), - err.FileName(), err.LineNumber()); + __ASSERT(err.IsNone(), "Error initializing application: %s", utils::ErrorToCStr(err)); return 0; } From 847f98240717403aec2f15d1ebf9b4d9c70d8232 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 18 Aug 2024 18:58:17 +0300 Subject: [PATCH 048/198] [Kconfig] Rename unit config to node config and remove unused entries Signed-off-by: Oleksandr Grytsov --- Kconfig | 20 ++------------------ boards/native_posix.conf | 2 +- boards/native_posix_64.conf | 2 +- 3 files changed, 4 insertions(+), 20 deletions(-) diff --git a/Kconfig b/Kconfig index d9238d8f..ac0d20bf 100644 --- a/Kconfig +++ b/Kconfig @@ -37,9 +37,9 @@ config AOS_SERVICES_DIR string "Aos services dir" default "/aos/services" -config AOS_UNIT_CONFIG_FILE +config AOS_NODE_CONFIG_FILE string "Node configuration file path" - default "/aos/unit_config.cfg" + default "/aos/node_config.cfg" config AOS_NODE_ID string "Node id" @@ -49,22 +49,6 @@ config AOS_NODE_TYPE string "Node type" default "NODE_TYPE1" -config AOS_NUM_CPU - int "Count of CPUs for domain with Zephyr" - default 1 - -config AOS_TOTAL_RAM - int "Total RAM of the domain" - default 204800 - -config AOS_PARTITION_SIZE - int "Partition size" - default 209715200 - -config AOS_DISK_MOUNT_POINT - string "Disk mount point" - default "/aos" - config AOS_CLOCK_SYNC_SEND_PERIOD_SEC int "Send clock sync period in seconds" default 60 diff --git a/boards/native_posix.conf b/boards/native_posix.conf index b421c199..bcbb6c75 100644 --- a/boards/native_posix.conf +++ b/boards/native_posix.conf @@ -72,7 +72,7 @@ CONFIG_AOS_DISK_MOUNT_POINT=".aos" CONFIG_AOS_STORAGE_DIR=".aos/storage" CONFIG_AOS_RUNTIME_DIR=".aos/runtime" CONFIG_AOS_SERVICES_DIR=".aos/services" -CONFIG_AOS_UNIT_CONFIG_FILE=".aos/unit_config.cfg" +CONFIG_AOS_NODE_CONFIG_FILE=".aos/node_config.cfg" # Disable OP-TEE driver and client libraries # TEE is not supported by this platform diff --git a/boards/native_posix_64.conf b/boards/native_posix_64.conf index eecb97b6..18ba439e 100644 --- a/boards/native_posix_64.conf +++ b/boards/native_posix_64.conf @@ -71,7 +71,7 @@ CONFIG_AOS_DISK_MOUNT_POINT=".aos" CONFIG_AOS_STORAGE_DIR=".aos/storage" CONFIG_AOS_RUNTIME_DIR=".aos/runtime" CONFIG_AOS_SERVICES_DIR=".aos/services" -CONFIG_AOS_UNIT_CONFIG_FILE=".aos/unit_config.cfg" +CONFIG_AOS_NODE_CONFIG_FILE=".aos/node_config.cfg" # Disable OP-TEE driver and client libraries # TEE is not supported by this platform From 73e76f3a5cff331e428955f88df247f1a818d068 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 18 Aug 2024 19:03:34 +0300 Subject: [PATCH 049/198] [app] Update app initialization to use new API Signed-off-by: Oleksandr Grytsov --- src/app/app.cpp | 181 +++++++++++++++++++++++++++++------------------- src/app/app.hpp | 79 ++++++++++++--------- 2 files changed, 153 insertions(+), 107 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index 9252c597..4a8985f0 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -20,137 +20,172 @@ App App::sApp; * Public **********************************************************************************************************************/ -aos::Error App::Init() +Error App::Init() { LOG_INF() << "Initialize application"; - aos::Error err; - - if (!(err = mStorage.Init()).IsNone()) { + if (auto err = InitZephyr(); !err.IsNone()) { return err; } - if (!(err = mRunner.Init(mLauncher)).IsNone()) { + if (auto err = InitCommon(); !err.IsNone()) { return err; } - if (!(err = mServiceManager.Init(mJsonOciSpec, mDownloader, mStorage)).IsNone()) { + if (auto err = InitIAM(); !err.IsNone()) { return err; } - if (!(err = mResourceUsageProvider.Init()).IsNone()) { + if (auto err = InitSM(); !err.IsNone()) { return err; } - if (!(err = mResourceMonitor.Init(mResourceUsageProvider, mSMClient, mSMClient)).IsNone()) { - return err; + return ErrorEnum::eNone; +} + +/*********************************************************************************************************************** + * Private + **********************************************************************************************************************/ + +Error App::InitCommon() +{ + if (auto err = mCryptoProvider.Init(); !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - if (!(err - = mLauncher.Init(mServiceManager, mRunner, mJsonOciSpec, mSMClient, mStorage, mResourceMonitor, mSMClient)) - .IsNone()) { - return err; + if (auto err = mCertLoader.Init(mCryptoProvider, mPKCS11Manager); !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - if (!(err = mClockSync.Init(mSMClient)).IsNone()) { - return err; + if (auto err = mResourceMonitor.Init(mNodeInfoProvider, mResourceUsageProvider, mSMClient, mSMClient); + !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - if (!(err = mProvisioning.Init()).IsNone()) { - return err; + return ErrorEnum::eNone; +} + +Error App::InitIAM() +{ + iam::certhandler::ExtendedKeyUsage keyUsage[] = {iam::certhandler::ExtendedKeyUsageEnum::eClientAuth}; + + // Register iam cert module + + if (auto err + = mIAMHSMModule.Init("iam", {cPKCS11ModuleLibrary, {}, {}, cPKCS11ModuleTokenLabel, cPKCS11ModulePinFile}, + mPKCS11Manager, mCryptoProvider); + !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - if (!(err = mCryptoProvider.Init()).IsNone()) { - return err; + if (auto err = mIAMCertModule.Init("iam", + {crypto::KeyTypeEnum::eECDSA, 2, Array(keyUsage, ArraySize(keyUsage))}, + mCryptoProvider, mIAMHSMModule, mStorage); + !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - if (!(err = mCertLoader.Init(mCryptoProvider, mPKCS11Manager)).IsNone()) { - return err; + if (auto err = mCertHandler.RegisterModule(mIAMCertModule); !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - if (!(err = mResourceManager.Init( - mResourceManagerJSONProvider, mHostDeviceManager, mHostGroupManager, cNodeType, cUnitConfigFile)) - .IsNone()) { - return err; + // Register sm cert module + + if (auto err + = mSMHSMModule.Init("sm", {cPKCS11ModuleLibrary, {}, {}, cPKCS11ModuleTokenLabel, cPKCS11ModulePinFile}, + mPKCS11Manager, mCryptoProvider); + !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - if (!(err = InitCertHandler()).IsNone()) { - return err; + if (auto err = mSMCertModule.Init("sm", + {crypto::KeyTypeEnum::eECDSA, 2, Array(keyUsage, ArraySize(keyUsage))}, + mCryptoProvider, mSMHSMModule, mStorage); + !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - if (!(err = InitCommunication()).IsNone()) { - return err; + if (auto err = mCertHandler.RegisterModule(mSMCertModule); !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - return aos::ErrorEnum::eNone; -} + if (auto err = mProvisionManager.Init(mProvisionManagerCallback, mCertHandler); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } -/*********************************************************************************************************************** - * Private - **********************************************************************************************************************/ + return ErrorEnum::eNone; +} -aos::Error App::InitCertHandler() +Error App::InitSM() { - aos::Error err; - aos::iam::certhandler::ExtendedKeyUsage keyUsage[] = {aos::iam::certhandler::ExtendedKeyUsageEnum::eClientAuth}; + if (auto err + = mLauncher.Init(mServiceManager, mRunner, mJsonOciSpec, mSMClient, mStorage, mResourceMonitor, mSMClient); + !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } - // Register iam cert module + if (auto err = mResourceManager.Init( + mResourceManagerJSONProvider, mHostDeviceManager, mHostGroupManager, cNodeType, cNodeConfigFile); + !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } - if (!(err = mIAMHSMModule.Init("iam", {cPKCS11ModuleLibrary, {}, {}, cPKCS11ModuleTokenLabel, cPKCS11ModulePinFile}, - mPKCS11Manager, mCryptoProvider)) - .IsNone()) { - return err; + if (auto err = mServiceManager.Init(mJsonOciSpec, mDownloader, mStorage); !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - if (!(err = mIAMCertModule.Init("iam", - {aos::crypto::KeyTypeEnum::eECDSA, 2, - aos::Array(keyUsage, aos::ArraySize(keyUsage))}, - mCryptoProvider, mIAMHSMModule, mStorage)) - .IsNone()) { - return err; + return ErrorEnum::eNone; +} + +Error App::InitZephyr() +{ + if (auto err = mClockSync.Init(mSMClient); !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - if (!(err = mCertHandler.RegisterModule(mIAMCertModule)).IsNone()) { - return err; + if (auto err = mDownloader.Init(mSMClient); !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - // Register sm cert module + if (auto err = mResourceUsageProvider.Init(mNodeInfoProvider); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } - if (!(err = mSMHSMModule.Init("sm", {cPKCS11ModuleLibrary, {}, {}, cPKCS11ModuleTokenLabel, cPKCS11ModulePinFile}, - mPKCS11Manager, mCryptoProvider)) - .IsNone()) { - return err; + if (auto err = mNodeInfoProvider.Init(); !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - if (!(err = mSMCertModule.Init("sm", - {aos::crypto::KeyTypeEnum::eECDSA, 2, - aos::Array(keyUsage, aos::ArraySize(keyUsage))}, - mCryptoProvider, mSMHSMModule, mStorage)) - .IsNone()) { - return err; + if (auto err = mRunner.Init(mLauncher); !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - if (!(err = mCertHandler.RegisterModule(mSMCertModule)).IsNone()) { - return err; + if (auto err = mSMClient.Init(mClockSync, mChannelManager); !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - return aos::ErrorEnum::eNone; + if (auto err = mStorage.Init(); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + if (auto err = InitCommunication(); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + return ErrorEnum::eNone; } -aos::Error App::InitCommunication() +Error App::InitCommunication() { - aos::Error err; - - if (!(err = mTransport.Init(communication::XenVChan::cXSReadPath, communication::XenVChan::cXSWritePath)) - .IsNone()) { - return err; + if (auto err = mTransport.Init(communication::XenVChan::cXSReadPath, communication::XenVChan::cXSWritePath); + !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - if (!(err = mChannelManager.Init(mTransport)).IsNone()) { - return err; + if (auto err = mChannelManager.Init(mTransport); !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } } // namespace aos::zephyr::app diff --git a/src/app/app.hpp b/src/app/app.hpp index 60860070..db1f7042 100644 --- a/src/app/app.hpp +++ b/src/app/app.hpp @@ -10,11 +10,12 @@ #include #include -#include +#include #include #include #include #include +#include #include #include @@ -23,8 +24,9 @@ #include "communication/xenvchan.hpp" #include "downloader/downloader.hpp" #include "monitoring/resourceusageprovider.hpp" +#include "nodeinfoprovider/nodeinfoprovider.hpp" #include "ocispec/ocispec.hpp" -#include "provisioning/provisioning.hpp" +#include "provisionmanager/provisionmanagercallback.hpp" #include "resourcemanager/resourcemanager.hpp" #include "runner/runner.hpp" #include "smclient/smclient.hpp" @@ -35,14 +37,14 @@ namespace aos::zephyr::app { /** * Aos zephyr application. */ -class App : private aos::NonCopyable { +class App : private NonCopyable { public: /** * Initializes application. * - * @return aos::Error + * @return Error */ - aos::Error Init(); + Error Init(); /** * Returns Aos application instance. @@ -55,37 +57,46 @@ class App : private aos::NonCopyable { static constexpr auto cPKCS11ModuleTokenLabel = "aoscore"; static constexpr auto cPKCS11ModulePinFile = CONFIG_AOS_PKCS11_MODULE_PIN_FILE; static constexpr auto cNodeType = CONFIG_AOS_NODE_TYPE; - static constexpr auto cUnitConfigFile = CONFIG_AOS_UNIT_CONFIG_FILE; + static constexpr auto cNodeConfigFile = CONFIG_AOS_NODE_CONFIG_FILE; - aos::Error InitCertHandler(); - aos::Error InitCommunication(); + Error InitCommon(); + Error InitIAM(); + Error InitSM(); + Error InitZephyr(); + Error InitCommunication(); - static App sApp; - aos::monitoring::ResourceMonitor mResourceMonitor; - aos::sm::launcher::Launcher mLauncher; - aos::sm::servicemanager::ServiceManager mServiceManager; - aos::iam::certhandler::CertModule mIAMCertModule; - aos::iam::certhandler::PKCS11Module mIAMHSMModule; - aos::iam::certhandler::CertModule mSMCertModule; - aos::iam::certhandler::PKCS11Module mSMHSMModule; - aos::iam::certhandler::CertHandler mCertHandler; - aos::crypto::MbedTLSCryptoProvider mCryptoProvider; - aos::cryptoutils::CertLoader mCertLoader; - aos::pkcs11::PKCS11Manager mPKCS11Manager; - clocksync::ClockSync mClockSync; - Downloader mDownloader; - OCISpec mJsonOciSpec; - aos::zephyr::resourcemanager::JSONProvider mResourceManagerJSONProvider; - aos::zephyr::resourcemanager::HostDeviceManager mHostDeviceManager; - aos::zephyr::resourcemanager::HostGroupManager mHostGroupManager; - aos::sm::resourcemanager::ResourceManager mResourceManager; - ResourceUsageProvider mResourceUsageProvider; - Runner mRunner; - Storage mStorage; - Provisioning mProvisioning; - smclient::SMClient mSMClient; - communication::ChannelManager mChannelManager; - communication::XenVChan mTransport; + static App sApp; + + aos::crypto::MbedTLSCryptoProvider mCryptoProvider; + aos::cryptoutils::CertLoader mCertLoader; + aos::monitoring::ResourceMonitor mResourceMonitor; + aos::pkcs11::PKCS11Manager mPKCS11Manager; + + iam::certhandler::CertHandler mCertHandler; + iam::certhandler::CertModule mIAMCertModule; + iam::certhandler::CertModule mSMCertModule; + iam::certhandler::PKCS11Module mIAMHSMModule; + iam::certhandler::PKCS11Module mSMHSMModule; + iam::provisionmanager::ProvisionManager mProvisionManager; + + sm::launcher::Launcher mLauncher; + sm::resourcemanager::ResourceManager mResourceManager; + sm::servicemanager::ServiceManager mServiceManager; + + clocksync::ClockSync mClockSync; + communication::ChannelManager mChannelManager; + communication::XenVChan mTransport; + downloader::Downloader mDownloader; + monitoring::ResourceUsageProvider mResourceUsageProvider; + nodeinfoprovider::NodeInfoProvider mNodeInfoProvider; + ocispec::OCISpec mJsonOciSpec; + provisionmanager::ProvisionManagerCallback mProvisionManagerCallback; + resourcemanager::HostDeviceManager mHostDeviceManager; + resourcemanager::HostGroupManager mHostGroupManager; + resourcemanager::JSONProvider mResourceManagerJSONProvider; + runner::Runner mRunner; + smclient::SMClient mSMClient; + storage::Storage mStorage; }; } // namespace aos::zephyr::app From 55765e1f68f48e812d3558356782f885f9de12e0 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 18 Aug 2024 19:09:49 +0300 Subject: [PATCH 050/198] [all] Add sofhsm configuration for native build Signed-off-by: Oleksandr Grytsov --- CMakeLists.txt | 15 +++++++++++++++ Kconfig | 4 ++++ boards/native_posix.conf | 1 + boards/native_posix_64.conf | 1 + src/aoscoreconfig.hpp | 14 +++++++------- src/app/app.cpp | 16 ++++++++++++++++ src/app/app.hpp | 4 ++++ 7 files changed, 48 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7710debd..b6b5aa58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -260,3 +260,18 @@ set_target_properties(aoscommon PROPERTIES IMPORTED_LOCATION ${aoscore_build_dir set_target_properties(aoscommon PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${aoscore_build_dir}/include) target_link_libraries(app PUBLIC aoscommon) + +# ###################################################################################################################### +# Prepare softhsm2 config +# ###################################################################################################################### + +if(CONFIG_NATIVE_APPLICATION) + set(tokendir ${CONFIG_AOS_HSM_DIR}) + + if(NOT IS_ABSOLUTE ${tokendir}) + set(tokendir ${CMAKE_CURRENT_BINARY_DIR}/${tokendir}) + endif() + + file(COPY misc/softhsm2.conf DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/softhsm) + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/softhsm2.conf "directories.tokendir = ${tokendir}/\n") +endif() diff --git a/Kconfig b/Kconfig index ac0d20bf..8a29e849 100644 --- a/Kconfig +++ b/Kconfig @@ -73,6 +73,10 @@ config AOS_PKCS11_MODULE_PIN_FILE string "Path to PKCS11 module PIN file." default "/aos/.pkcs11pin" +config AOS_HSM_DIR + string "Path HSM tokens dir." + default "/aos/tee" + config AOS_ROOT_CA_PATH string "Path to Aos Root CA certificate. Required to build in root CA into app image." default "prebuilt/rootca.pem" diff --git a/boards/native_posix.conf b/boards/native_posix.conf index bcbb6c75..f3ce535d 100644 --- a/boards/native_posix.conf +++ b/boards/native_posix.conf @@ -73,6 +73,7 @@ CONFIG_AOS_STORAGE_DIR=".aos/storage" CONFIG_AOS_RUNTIME_DIR=".aos/runtime" CONFIG_AOS_SERVICES_DIR=".aos/services" CONFIG_AOS_NODE_CONFIG_FILE=".aos/node_config.cfg" +CONFIG_AOS_HSM_DIR=".aos/hsm" # Disable OP-TEE driver and client libraries # TEE is not supported by this platform diff --git a/boards/native_posix_64.conf b/boards/native_posix_64.conf index 18ba439e..6c1f1a4e 100644 --- a/boards/native_posix_64.conf +++ b/boards/native_posix_64.conf @@ -72,6 +72,7 @@ CONFIG_AOS_STORAGE_DIR=".aos/storage" CONFIG_AOS_RUNTIME_DIR=".aos/runtime" CONFIG_AOS_SERVICES_DIR=".aos/services" CONFIG_AOS_NODE_CONFIG_FILE=".aos/node_config.cfg" +CONFIG_AOS_HSM_DIR=".aos/hsm" # Disable OP-TEE driver and client libraries # TEE is not supported by this platform diff --git a/src/aoscoreconfig.hpp b/src/aoscoreconfig.hpp index e083a6bf..bfa3f6fc 100644 --- a/src/aoscoreconfig.hpp +++ b/src/aoscoreconfig.hpp @@ -8,7 +8,7 @@ #ifndef AOSCORECONFIG_HPP_ #define AOSCORECONFIG_HPP_ -#ifndef CONFIG_BOARD_NATIVE_POSIX +#ifndef CONFIG_NATIVE_APPLICATION /** * Set thread stack size. @@ -40,7 +40,12 @@ */ #define AOS_CONFIG_THREAD_CLOCK_ID CLOCK_MONOTONIC -#endif // CONFIG_POSIX_API +/** + * Default static PKCS11 lib. + */ +#define AOS_CONFIG_CRYPTOUTILS_DEFAULT_PKCS11_LIB "libckteec" + +#endif // CONFIG_NATIVE_APPLICATION // This config also used to generate proto options file. Using Aos new operator causes redefinition error. // Add condition to enable it for zephyr only to avoid the error. @@ -67,9 +72,4 @@ */ #define AOS_CONFIG_SERVICEMANAGER_SERVICES_DIR CONFIG_AOS_SERVICES_DIR -/** - * Default static PKCS11 lib. - */ -#define AOS_CONFIG_CRYPTOUTILS_DEFAULT_PKCS11_LIB "libckteec" - #endif diff --git a/src/app/app.cpp b/src/app/app.cpp index 4a8985f0..3fd38d9a 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -67,6 +67,16 @@ Error App::InitCommon() Error App::InitIAM() { +#ifdef CONFIG_NATIVE_APPLICATION + if (auto ret = setenv("SOFTHSM2_CONF", "softhsm/softhsm2.conf", true); ret != 0) { + return AOS_ERROR_WRAP(Error(ret, "can't set softhsm env")); + } + + if (auto err = FS::MakeDirAll(cHSMDir); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } +#endif + iam::certhandler::ExtendedKeyUsage keyUsage[] = {iam::certhandler::ExtendedKeyUsageEnum::eClientAuth}; // Register iam cert module @@ -139,6 +149,12 @@ Error App::InitSM() Error App::InitZephyr() { +#ifdef CONFIG_NATIVE_APPLICATION + if (auto err = FS::MakeDirAll(cAosDiskMountPoint); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } +#endif + if (auto err = mClockSync.Init(mSMClient); !err.IsNone()) { return AOS_ERROR_WRAP(err); } diff --git a/src/app/app.hpp b/src/app/app.hpp index db1f7042..1833d237 100644 --- a/src/app/app.hpp +++ b/src/app/app.hpp @@ -58,6 +58,10 @@ class App : private NonCopyable { static constexpr auto cPKCS11ModulePinFile = CONFIG_AOS_PKCS11_MODULE_PIN_FILE; static constexpr auto cNodeType = CONFIG_AOS_NODE_TYPE; static constexpr auto cNodeConfigFile = CONFIG_AOS_NODE_CONFIG_FILE; +#ifdef CONFIG_NATIVE_APPLICATION + static constexpr auto cHSMDir = CONFIG_AOS_HSM_DIR; + static constexpr auto cAosDiskMountPoint = CONFIG_AOS_DISK_MOUNT_POINT; +#endif Error InitCommon(); Error InitIAM(); From 440e6d9aa606c24b68ccb43ba3f8dcb308ce75e3 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 18 Aug 2024 21:41:02 +0300 Subject: [PATCH 051/198] [misc] Add softhsm2.conf for native build Signed-off-by: Oleksandr Grytsov --- misc/softhsm2.conf | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 misc/softhsm2.conf diff --git a/misc/softhsm2.conf b/misc/softhsm2.conf new file mode 100644 index 00000000..d98d08f8 --- /dev/null +++ b/misc/softhsm2.conf @@ -0,0 +1,6 @@ +objectstore.backend = file +objectstore.umask = 0077 +log.level = INFO +slots.removable = false +slots.mechanisms = ALL +library.reset_on_fork = false From 3005ffbceeb5a8b7ee19fa42cb9f96aa1b6a7849 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 18 Aug 2024 22:33:16 +0300 Subject: [PATCH 052/198] [cmake] Fix appending token dir to softhsm config Signed-off-by: Oleksandr Grytsov --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b6b5aa58..649ec70d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -273,5 +273,5 @@ if(CONFIG_NATIVE_APPLICATION) endif() file(COPY misc/softhsm2.conf DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/softhsm) - file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/softhsm2.conf "directories.tokendir = ${tokendir}/\n") + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/softhsm/softhsm2.conf "directories.tokendir = ${tokendir}/\n") endif() From 67b7f07e8557fb1241e6233dfe18748c746d7c80 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 19 Aug 2024 10:55:32 +0300 Subject: [PATCH 053/198] [boards] Remove spider configs added by mistake Signed-off-by: Oleksandr Grytsov --- boards/rcar_spider.conf | 26 --------------- boards/rcar_spider.overlay | 67 -------------------------------------- 2 files changed, 93 deletions(-) delete mode 100644 boards/rcar_spider.conf delete mode 100644 boards/rcar_spider.overlay diff --git a/boards/rcar_spider.conf b/boards/rcar_spider.conf deleted file mode 100644 index a828accf..00000000 --- a/boards/rcar_spider.conf +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright (c) 2023 EPAM Systems -# -# SPDX-License-Identifier: Apache-2.0 -# - -# Kernel virtual memory size - -CONFIG_KERNEL_VM_SIZE=0x4000000 -CONFIG_PARTIAL_DEVICE_TREE_SIZE=80000 - -# Aos config - -CONFIG_SHELL_STACK_SIZE=8192 - -CONFIG_DISK_ACCESS=y -CONFIG_DISK_DRIVERS=y -CONFIG_DISK_DRIVER_MMC=y - -CONFIG_MMC_RCAR=y -CONFIG_MMC_RCA=1 - -CONFIG_FS_LITTLEFS_BLK_DEV=y - -CONFIG_RCAR_MMC_SCC_SUPPORT=n -CONFIG_SD_DATA_TIMEOUT=1000 diff --git a/boards/rcar_spider.overlay b/boards/rcar_spider.overlay deleted file mode 100644 index 6f76f443..00000000 --- a/boards/rcar_spider.overlay +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -&mmc0 { - disk { - status = "okay"; - }; - status = "okay"; -}; - -/ { - firmware { - tee { - compatible = "linaro,optee-tz"; - method = "smc"; - status = "okay"; - }; - }; - - fstab { - compatible = "zephyr,fstab"; - storage: storage { - compatible = "zephyr,fstab,littlefs"; - mount-point = "/tmp"; - partition = <&storage_partition>; - automount; - read-size = <16>; - prog-size = <16>; - cache-size = <64>; - lookahead-size = <32>; - block-cycles = <512>; - }; - }; - - flashcontroller0: flashcontroller { - compatible = "zephyr,sim-flash"; - label = "FLASH_SIMULATOR"; - #address-cells = <1>; - #size-cells = <1>; - erase-value = <0xff>; - flash_sim0: flash_sim@0 { - compatible = "soc-nv-flash"; - reg = <0x00000000 DT_SIZE_M(32)>; - erase-block-size = <1024>; - write-block-size = <4>; - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - /* - * Storage partition will be used by FCB/LittleFS/NVS - * if enabled. - */ - storage_partition: partition@1000 { - label = "storage"; - reg = <0x00001000 0x02000000>; - }; - }; - }; - }; -}; From 3cf1436ed40dc02218b0ad38fcf6158965065b97 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 19 Aug 2024 10:59:54 +0300 Subject: [PATCH 054/198] [west.yml] Add zephyr-xrun library Signed-off-by: Oleksandr Grytsov --- boards/native_posix.conf | 6 +++++- boards/native_posix_64.conf | 5 +++++ prj.conf | 5 +++++ west.yml | 4 ++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/boards/native_posix.conf b/boards/native_posix.conf index f3ce535d..dc806138 100644 --- a/boards/native_posix.conf +++ b/boards/native_posix.conf @@ -56,7 +56,6 @@ CONFIG_XEN_LIBFDT=n CONFIG_XEN_STORE_SRV=n CONFIG_XEN_SHELL=n - # Disable vchan CONFIG_XEN_VCH=n @@ -66,6 +65,11 @@ CONFIG_XEN_VCH=n CONFIG_XSTAT=n CONFIG_XSTAT_SHELL_CMDS=n +# Disable xrun + +CONFIG_XRUN=n +CONFIG_XRUN_SHELL_CMDS=n + # Application config CONFIG_AOS_DISK_MOUNT_POINT=".aos" diff --git a/boards/native_posix_64.conf b/boards/native_posix_64.conf index 6c1f1a4e..dc806138 100644 --- a/boards/native_posix_64.conf +++ b/boards/native_posix_64.conf @@ -65,6 +65,11 @@ CONFIG_XEN_VCH=n CONFIG_XSTAT=n CONFIG_XSTAT_SHELL_CMDS=n +# Disable xrun + +CONFIG_XRUN=n +CONFIG_XRUN_SHELL_CMDS=n + # Application config CONFIG_AOS_DISK_MOUNT_POINT=".aos" diff --git a/prj.conf b/prj.conf index fc91aa0f..74f24647 100644 --- a/prj.conf +++ b/prj.conf @@ -167,6 +167,11 @@ CONFIG_XEN_STORE_SRV=y CONFIG_XEN_LIBFDT=y CONFIG_XEN_SHELL=y +# Enable xrun + +CONFIG_XRUN=y +CONFIG_XRUN_SHELL_CMDS=y + # Enable xstat CONFIG_XSTAT=y diff --git a/west.yml b/west.yml index ea24e485..47536b69 100644 --- a/west.yml +++ b/west.yml @@ -43,6 +43,10 @@ manifest: remote: xen-troops revision: "master" + - name: zephyr-xrun + remote: xen-troops + revision: "main" + - name: littlefs remote: zephyrproject-rtos revision: "zephyr" From 998bf2f6c8c6892f2726c2621de1bed46bf8a725 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 19 Aug 2024 11:40:53 +0300 Subject: [PATCH 055/198] [lint] Add unusedFunction as exception Signed-off-by: Oleksandr Grytsov --- suppressions.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/suppressions.txt b/suppressions.txt index 17da75d1..d4e8c6d2 100644 --- a/suppressions.txt +++ b/suppressions.txt @@ -1,2 +1,3 @@ missingIncludeSystem useStlAlgorithm +unusedFunction From c03cf9b3f2f11257154c2a7dff84909042d46ca4 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 19 Aug 2024 11:41:38 +0300 Subject: [PATCH 056/198] [all] Fix lint warnings Signed-off-by: Oleksandr Grytsov --- src/communication/pbhandler.cpp | 19 ++++++++++++++----- src/communication/pbhandler.hpp | 5 +++++ src/downloader/downloader.cpp | 1 - src/monitoring/resourceusageprovider.cpp | 2 -- src/nodeinfoprovider/nodeinfoprovider.cpp | 3 --- src/ocispec/ocispec.cpp | 6 ------ src/resourcemanager/resourcemanager.cpp | 9 +-------- src/runner/runner.cpp | 2 -- src/smclient/smclient.cpp | 4 ++-- src/storage/storage.cpp | 13 ------------- 10 files changed, 22 insertions(+), 42 deletions(-) diff --git a/src/communication/pbhandler.cpp b/src/communication/pbhandler.cpp index c88bd275..69aa1e27 100644 --- a/src/communication/pbhandler.cpp +++ b/src/communication/pbhandler.cpp @@ -122,8 +122,7 @@ void PBHandler::Run() } } - auto err = mChannel->Connect(); - if (!err.IsNone()) { + if (auto err = mChannel->Connect(); !err.IsNone()) { LOG_ERR() << "Failed to connect: name=" << mName << ", err=" << err; continue; } @@ -139,19 +138,29 @@ void PBHandler::Run() break; } + if (static_cast(ret) != sizeof(header)) { + LOG_ERR() << "Wrong header size: name=" << mName << ", ret=" << ret; + break; + } + if (header.mDataSize > mReceiveBuffer.Size()) { LOG_ERR() << "Not enough mem in receive buffer: name=" << mName; continue; } - if ((ret = mChannel->Read(mReceiveBuffer.Get(), header.mDataSize)) < 0) { + ret = mChannel->Read(mReceiveBuffer.Get(), header.mDataSize); + if (ret < 0) { LOG_ERR() << "Failed to read channel: name=" << mName << ", ret=" << ret << ", err=" << strerror(errno); break; } - auto err = ReceiveMessage(Array(static_cast(mReceiveBuffer.Get()), header.mDataSize)); + if (static_cast(ret) != header.mDataSize) { + LOG_ERR() << "Wrong data size: name=" << mName << ", ret=" << ret; + break; + } - if (!err.IsNone()) { + if (auto err = ReceiveMessage(Array(static_cast(mReceiveBuffer.Get()), header.mDataSize)); + !err.IsNone()) { LOG_ERR() << "Receive message error: name=" << mName << ", err=" << err; continue; } diff --git a/src/communication/pbhandler.hpp b/src/communication/pbhandler.hpp index 48c74a0e..6bf17cf0 100644 --- a/src/communication/pbhandler.hpp +++ b/src/communication/pbhandler.hpp @@ -24,6 +24,11 @@ namespace aos::zephyr::communication { template class PBHandler { public: + /** + * Constructor. + */ + PBHandler() = default; + /** * Initializes protobuf handler. * diff --git a/src/downloader/downloader.cpp b/src/downloader/downloader.cpp index e48b3ea1..3597ea92 100644 --- a/src/downloader/downloader.cpp +++ b/src/downloader/downloader.cpp @@ -36,7 +36,6 @@ Error Downloader::Init(DownloadRequesterItf& downloadRequester) return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error Downloader::Download(const String& url, const String& path, DownloadContent contentType) { UniqueLock lock(mMutex); diff --git a/src/monitoring/resourceusageprovider.cpp b/src/monitoring/resourceusageprovider.cpp index faf76a46..f92e9812 100644 --- a/src/monitoring/resourceusageprovider.cpp +++ b/src/monitoring/resourceusageprovider.cpp @@ -31,7 +31,6 @@ Error ResourceUsageProvider::Init(iam::nodeinfoprovider::NodeInfoProviderItf& no return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error ResourceUsageProvider::GetNodeMonitoringData( const String& nodeID, aos::monitoring::MonitoringData& monitoringData) { @@ -80,7 +79,6 @@ Error ResourceUsageProvider::GetNodeMonitoringData( return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error ResourceUsageProvider::GetInstanceMonitoringData( const String& instanceID, aos::monitoring::MonitoringData& monitoringData) { diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp index 03a9520c..5750bcc2 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -74,7 +74,6 @@ Error NodeInfoProvider::GetNodeInfo(NodeInfo& nodeInfo) const return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error NodeInfoProvider::SetNodeStatus(const NodeStatus& status) { LockGuard lock {mMutex}; @@ -100,7 +99,6 @@ Error NodeInfoProvider::SetNodeStatus(const NodeStatus& status) return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error NodeInfoProvider::SubscribeNodeStatusChanged(iam::nodeinfoprovider::NodeStatusObserverItf& observer) { LockGuard lock {mMutex}; @@ -114,7 +112,6 @@ Error NodeInfoProvider::SubscribeNodeStatusChanged(iam::nodeinfoprovider::NodeSt return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error NodeInfoProvider::UnsubscribeNodeStatusChanged(iam::nodeinfoprovider::NodeStatusObserverItf& observer) { LockGuard lock {mMutex}; diff --git a/src/ocispec/ocispec.cpp b/src/ocispec/ocispec.cpp index d46b629f..a28a8820 100644 --- a/src/ocispec/ocispec.cpp +++ b/src/ocispec/ocispec.cpp @@ -91,7 +91,6 @@ static const struct json_obj_descr RuntimeSpecDescr[] = { * Public **********************************************************************************************************************/ -// cppcheck-suppress unusedFunction Error OCISpec::LoadImageManifest(const String& path, oci::ImageManifest& manifest) { LockGuard lock(mMutex); @@ -182,7 +181,6 @@ Error OCISpec::LoadImageManifest(const String& path, oci::ImageManifest& manifes return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error OCISpec::SaveImageManifest(const String& path, const oci::ImageManifest& manifest) { LockGuard lock(mMutex); @@ -262,7 +260,6 @@ Error OCISpec::SaveImageManifest(const String& path, const oci::ImageManifest& m return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error OCISpec::LoadImageSpec(const String& path, oci::ImageSpec& imageSpec) { LockGuard lock(mMutex); @@ -307,7 +304,6 @@ Error OCISpec::LoadImageSpec(const String& path, oci::ImageSpec& imageSpec) return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error OCISpec::SaveImageSpec(const String& path, const oci::ImageSpec& imageSpec) { LockGuard lock(mMutex); @@ -363,7 +359,6 @@ Error OCISpec::SaveImageSpec(const String& path, const oci::ImageSpec& imageSpec return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error OCISpec::LoadRuntimeSpec(const String& path, oci::RuntimeSpec& runtimeSpec) { LockGuard lock(mMutex); @@ -473,7 +468,6 @@ Error OCISpec::LoadRuntimeSpec(const String& path, oci::RuntimeSpec& runtimeSpec return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error OCISpec::SaveRuntimeSpec(const String& path, const oci::RuntimeSpec& runtimeSpec) { LockGuard lock(mMutex); diff --git a/src/resourcemanager/resourcemanager.cpp b/src/resourcemanager/resourcemanager.cpp index a64173b2..425aee3c 100644 --- a/src/resourcemanager/resourcemanager.cpp +++ b/src/resourcemanager/resourcemanager.cpp @@ -38,7 +38,6 @@ static const struct json_obj_descr cNodeConfigDescr[] = { * Public **********************************************************************************************************************/ -// cppcheck-suppress unusedFunction Error JSONProvider::DumpNodeConfig(const sm::resourcemanager::NodeConfig& config, String& json) const { LockGuard lock(mMutex); @@ -65,7 +64,6 @@ Error JSONProvider::DumpNodeConfig(const sm::resourcemanager::NodeConfig& config return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error JSONProvider::ParseNodeConfig(const String& json, sm::resourcemanager::NodeConfig& config) const { LockGuard lock(mMutex); @@ -93,11 +91,11 @@ Error JSONProvider::ParseNodeConfig(const String& json, sm::resourcemanager::Nod /*********************************************************************************************************************** * HostDeviceManager **********************************************************************************************************************/ + /*********************************************************************************************************************** * Public **********************************************************************************************************************/ -// cppcheck-suppress unusedFunction Error HostDeviceManager::AllocateDevice(const DeviceInfo& deviceInfo, const String& instanceID) { (void)deviceInfo; @@ -106,7 +104,6 @@ Error HostDeviceManager::AllocateDevice(const DeviceInfo& deviceInfo, const Stri return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error HostDeviceManager::RemoveInstanceFromDevice(const String& deviceName, const String& instanceID) { (void)deviceName; @@ -115,7 +112,6 @@ Error HostDeviceManager::RemoveInstanceFromDevice(const String& deviceName, cons return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error HostDeviceManager::RemoveInstanceFromAllDevices(const String& instanceID) { (void)instanceID; @@ -123,7 +119,6 @@ Error HostDeviceManager::RemoveInstanceFromAllDevices(const String& instanceID) return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error HostDeviceManager::GetDeviceInstances( const String& deviceName, Array>& instanceIDs) const { @@ -133,7 +128,6 @@ Error HostDeviceManager::GetDeviceInstances( return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction bool HostDeviceManager::DeviceExists(const String& device) const { (void)device; @@ -148,7 +142,6 @@ bool HostDeviceManager::DeviceExists(const String& device) const * Public **********************************************************************************************************************/ -// cppcheck-suppress unusedFunction bool HostGroupManager::GroupExists(const String& group) const { (void)group; diff --git a/src/runner/runner.cpp b/src/runner/runner.cpp index f4ddb4e0..ac41c9e2 100644 --- a/src/runner/runner.cpp +++ b/src/runner/runner.cpp @@ -25,7 +25,6 @@ Error Runner::Init(sm::runner::RunStatusReceiverItf& statusReceiver) return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction sm::runner::RunStatus Runner::StartInstance(const String& instanceID, const String& runtimeDir) { sm::runner::RunStatus runStatus {instanceID, InstanceRunStateEnum::eActive, ErrorEnum::eNone}; @@ -39,7 +38,6 @@ sm::runner::RunStatus Runner::StartInstance(const String& instanceID, const Stri return runStatus; } -// cppcheck-suppress unusedFunction Error Runner::StopInstance(const String& instanceID) { auto ret = xrun_kill(instanceID.CStr()); diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index a056ec89..809dff9d 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -23,11 +23,11 @@ Error SMClient::Init(clocksync::ClockSyncItf& clockSync, communication::ChannelM return AOS_ERROR_WRAP(err); } - if (auto err = mOpenHandler.Init(*openChannel, clockSync); !err.IsNone()) { + if (err = mOpenHandler.Init(*openChannel, clockSync); !err.IsNone()) { return err; } - if (auto err = clockSync.Subscribe(*this); err.IsNone()) { + if (err = clockSync.Subscribe(*this); err.IsNone()) { return AOS_ERROR_WRAP(err); } diff --git a/src/storage/storage.cpp b/src/storage/storage.cpp index 38dddf97..c191d378 100644 --- a/src/storage/storage.cpp +++ b/src/storage/storage.cpp @@ -44,7 +44,6 @@ Error Storage::Init() return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error Storage::AddInstance(const aos::InstanceInfo& instance) { LockGuard lock(mMutex); @@ -59,7 +58,6 @@ Error Storage::AddInstance(const aos::InstanceInfo& instance) }); } -// cppcheck-suppress unusedFunction Error Storage::UpdateInstance(const aos::InstanceInfo& instance) { LockGuard lock(mMutex); @@ -77,7 +75,6 @@ Error Storage::UpdateInstance(const aos::InstanceInfo& instance) return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error Storage::RemoveInstance(const aos::InstanceIdent& instanceIdent) { LockGuard lock(mMutex); @@ -93,7 +90,6 @@ Error Storage::RemoveInstance(const aos::InstanceIdent& instanceIdent) return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error Storage::GetAllInstances(Array& instances) { LockGuard lock(mMutex); @@ -114,7 +110,6 @@ Error Storage::GetAllInstances(Array& instances) return err; } -// cppcheck-suppress unusedFunction Error Storage::AddService(const sm::servicemanager::ServiceData& service) { LockGuard lock(mMutex); @@ -130,7 +125,6 @@ Error Storage::AddService(const sm::servicemanager::ServiceData& service) }); } -// cppcheck-suppress unusedFunction Error Storage::UpdateService(const sm::servicemanager::ServiceData& service) { LockGuard lock(mMutex); @@ -154,7 +148,6 @@ Error Storage::RemoveService(const String& serviceID, const String& version) }); } -// cppcheck-suppress unusedFunction Error Storage::GetAllServices(Array& services) { LockGuard lock(mMutex); @@ -175,7 +168,6 @@ Error Storage::GetAllServices(Array& services) return err; } -// cppcheck-suppress unusedFunction RetWithError Storage::GetService(const String& serviceID) { LockGuard lock(mMutex); @@ -196,7 +188,6 @@ RetWithError Storage::GetService(const String& return RetWithError(*retServiceData); } -// cppcheck-suppress unusedFunction Error Storage::AddCertInfo(const String& certType, const iam::certhandler::CertInfo& certInfo) { LockGuard lock(mMutex); @@ -215,7 +206,6 @@ Error Storage::AddCertInfo(const String& certType, const iam::certhandler::CertI }); } -// cppcheck-suppress unusedFunction Error Storage::RemoveCertInfo(const String& certType, const String& certURL) { LockGuard lock(mMutex); @@ -227,7 +217,6 @@ Error Storage::RemoveCertInfo(const String& certType, const String& certURL) }); } -// cppcheck-suppress unusedFunction Error Storage::RemoveAllCertsInfo(const String& certType) { LockGuard lock(mMutex); @@ -242,7 +231,6 @@ Error Storage::RemoveAllCertsInfo(const String& certType) return ErrorEnum::eNone; } -// cppcheck-suppress unusedFunction Error Storage::GetCertsInfo(const String& certType, Array& certsInfo) { LockGuard lock(mMutex); @@ -265,7 +253,6 @@ Error Storage::GetCertsInfo(const String& certType, Array& issuer, const Array& serial, iam::certhandler::CertInfo& cert) { LockGuard lock(mMutex); From e948019e14b6975de28d2581140ab8e8a39e5437 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 19 Aug 2024 12:33:41 +0300 Subject: [PATCH 057/198] [smclient] Fix raise accessing mClockSync in OnConnect function mClockSync should be initialized before handler start. Signed-off-by: Oleksandr Grytsov --- src/smclient/openhandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/smclient/openhandler.cpp b/src/smclient/openhandler.cpp index 34f897ec..650188b5 100644 --- a/src/smclient/openhandler.cpp +++ b/src/smclient/openhandler.cpp @@ -20,6 +20,8 @@ namespace aos::zephyr::smclient { Error OpenHandler::Init(communication::ChannelItf& channel, clocksync::ClockSyncItf& clockSync) { + mClockSync = &clockSync; + if (auto err = PBHandler::Init("SM open", channel); !err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -28,8 +30,6 @@ Error OpenHandler::Init(communication::ChannelItf& channel, clocksync::ClockSync return AOS_ERROR_WRAP(err); } - mClockSync = &clockSync; - return ErrorEnum::eNone; } From eded175afaa231baadab48f81c10126b37f5d107 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 16 Aug 2024 16:27:39 +0300 Subject: [PATCH 058/198] [iamclient] Add iam client skeleton with unit test Signed-off-by: Oleksandr Grytsov --- CMakeLists.txt | 1 + Kconfig | 12 ++- src/app/app.cpp | 4 + src/app/app.hpp | 2 + src/iamclient/iamclient.cpp | 67 ++++++++++++++++ src/iamclient/iamclient.hpp | 76 ++++++++++++++++++ src/iamclient/log.hpp | 15 ++++ tests/iamclient/CMakeLists.txt | 61 ++++++++++++++ tests/iamclient/Kconfig | 28 +++++++ tests/iamclient/prj.conf | 19 +++++ tests/iamclient/src/main.cpp | 80 +++++++++++++++++++ tests/iamclient/src/stubs/clocksyncstub.hpp | 27 +++++++ .../src/stubs/nodeinfoproviderstub.hpp | 30 +++++++ tests/iamclient/testcase.yaml | 6 ++ 14 files changed, 426 insertions(+), 2 deletions(-) create mode 100644 src/iamclient/iamclient.cpp create mode 100644 src/iamclient/iamclient.hpp create mode 100644 src/iamclient/log.hpp create mode 100644 tests/iamclient/CMakeLists.txt create mode 100644 tests/iamclient/Kconfig create mode 100644 tests/iamclient/prj.conf create mode 100644 tests/iamclient/src/main.cpp create mode 100644 tests/iamclient/src/stubs/clocksyncstub.hpp create mode 100644 tests/iamclient/src/stubs/nodeinfoproviderstub.hpp create mode 100644 tests/iamclient/testcase.yaml diff --git a/CMakeLists.txt b/CMakeLists.txt index 649ec70d..479c2a3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,7 @@ target_sources( src/communication/tlschannel.cpp src/communication/xenvchan.cpp src/downloader/downloader.cpp + src/iamclient/iamclient.cpp src/logger/logger.cpp src/monitoring/resourceusageprovider.cpp src/nodeinfoprovider/nodeinfoprovider.cpp diff --git a/Kconfig b/Kconfig index 8a29e849..33113185 100644 --- a/Kconfig +++ b/Kconfig @@ -81,13 +81,21 @@ config AOS_ROOT_CA_PATH string "Path to Aos Root CA certificate. Required to build in root CA into app image." default "prebuilt/rootca.pem" +config AOS_IAM_OPEN_PORT + int "Aos IAM open port" + default 1 + +config AOS_IAM_SECURE_PORT + int "Aos IAM secure port" + default 2 + config AOS_SM_OPEN_PORT int "Aos SM open port" - default 1 + default 3 config AOS_SM_SECURE_PORT int "Aos SM secure port" - default 2 + default 4 config DOMD_UBOOT_PATH string "Location for Domain-D IPL binary" diff --git a/src/app/app.cpp b/src/app/app.cpp index 3fd38d9a..187b7113 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -159,6 +159,10 @@ Error App::InitZephyr() return AOS_ERROR_WRAP(err); } + if (auto err = mIAMClient.Init(mClockSync, mNodeInfoProvider, mChannelManager); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + if (auto err = mDownloader.Init(mSMClient); !err.IsNone()) { return AOS_ERROR_WRAP(err); } diff --git a/src/app/app.hpp b/src/app/app.hpp index 1833d237..353fc31f 100644 --- a/src/app/app.hpp +++ b/src/app/app.hpp @@ -30,6 +30,7 @@ #include "resourcemanager/resourcemanager.hpp" #include "runner/runner.hpp" #include "smclient/smclient.hpp" +#include "iamclient/iamclient.hpp" #include "storage/storage.hpp" namespace aos::zephyr::app { @@ -91,6 +92,7 @@ class App : private NonCopyable { communication::ChannelManager mChannelManager; communication::XenVChan mTransport; downloader::Downloader mDownloader; + iamclient::IAMClient mIAMClient; monitoring::ResourceUsageProvider mResourceUsageProvider; nodeinfoprovider::NodeInfoProvider mNodeInfoProvider; ocispec::OCISpec mJsonOciSpec; diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp new file mode 100644 index 00000000..46a8c9b9 --- /dev/null +++ b/src/iamclient/iamclient.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "iamclient.hpp" +#include "log.hpp" + +#include "communication/pbhandler.cpp" + +namespace aos::zephyr::iamclient { + +/*********************************************************************************************************************** + * Public + **********************************************************************************************************************/ + +Error IAMClient::Init(clocksync::ClockSyncItf& clockSync, iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider, + communication::ChannelManagerItf& channelManager) +{ + LOG_DBG() << "Initialize IAM client"; + + Error err; + + if (!(err = clockSync.Subscribe(*this)).IsNone()) { + return AOS_ERROR_WRAP(err); + } + + if (!(err = nodeInfoProvider.SubscribeNodeStatusChanged(*this)).IsNone()) { + return AOS_ERROR_WRAP(err); + } + + return ErrorEnum::eNone; +} + +void IAMClient::OnClockSynced() +{ +} + +void IAMClient::OnClockUnsynced() +{ +} + +Error IAMClient::OnNodeStatusChanged(const String& nodeID, const NodeStatus& status) +{ + return ErrorEnum::eNone; +} + +/*********************************************************************************************************************** + * Private + **********************************************************************************************************************/ + +void IAMClient::OnConnect() +{ +} + +void IAMClient::OnDisconnect() +{ +} + +Error IAMClient::ReceiveMessage(const Array& data) +{ + return ErrorEnum::eNone; +} + +} // namespace aos::zephyr::iamclient diff --git a/src/iamclient/iamclient.hpp b/src/iamclient/iamclient.hpp new file mode 100644 index 00000000..76187082 --- /dev/null +++ b/src/iamclient/iamclient.hpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef IAMCLIENT_HPP_ +#define IAMCLIENT_HPP_ + +#include + +#include + +#include "clocksync/clocksync.hpp" +#include "communication/channelmanager.hpp" +#include "communication/pbhandler.hpp" + +namespace aos::zephyr::iamclient { + +/** + * IAM client instance. + */ +class IAMClient + : public communication::PBHandler, + public clocksync::ClockSyncSubscriberItf, + iam::nodeinfoprovider::NodeStatusObserverItf, + private NonCopyable { +public: + /** + * Initializes IAM client instance. + * + * @param clockSync clock sync instance. + * @param nodeInfoProvider node info provider. + * @param channelManager channel manager instance. + * @return Error. + */ + Error Init(clocksync::ClockSyncItf& clockSync, iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider, + communication::ChannelManagerItf& channelManager); + + /** + * Destructor. + */ + ~IAMClient() = default; + + /** + * Notifies subscriber clock is synced. + */ + void OnClockSynced() override; + + /** + * Notifies subscriber clock is unsynced. + */ + void OnClockUnsynced() override; + + /** + * On node status changed event. + * + * @param nodeID node id + * @param status node status + * @return Error + */ + Error OnNodeStatusChanged(const String& nodeID, const NodeStatus& status) override; + +private: + static constexpr auto cOpenPort = CONFIG_AOS_IAM_OPEN_PORT; + static constexpr auto cSecurePort = CONFIG_AOS_IAM_SECURE_PORT; + + void OnConnect() override; + void OnDisconnect() override; + Error ReceiveMessage(const Array& data) override; +}; + +} // namespace aos::zephyr::iamclient + +#endif diff --git a/src/iamclient/log.hpp b/src/iamclient/log.hpp new file mode 100644 index 00000000..157754e7 --- /dev/null +++ b/src/iamclient/log.hpp @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef LOG_HPP_ +#define LOG_HPP_ + +#define LOG_MODULE "iamclient" + +#include + +#endif diff --git a/tests/iamclient/CMakeLists.txt b/tests/iamclient/CMakeLists.txt new file mode 100644 index 00000000..bd233bd0 --- /dev/null +++ b/tests/iamclient/CMakeLists.txt @@ -0,0 +1,61 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package( + Zephyr + COMPONENTS + REQUIRED HINTS $ENV{ZEPHYR_BASE} +) + +set(CMAKE_MODULE_PATH ${APPLICATION_SOURCE_DIR}/../../cmake) + +project(communication_test) + +# ###################################################################################################################### +# Config +# ###################################################################################################################### + +set(aoscore_config aoscoreconfig.hpp) +set(aoscore_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../../../aos_core_lib_cpp") + +# ###################################################################################################################### +# Definitions +# ###################################################################################################################### + +# Aos core configuration +add_definitions(-include ${aoscore_config}) + +# ###################################################################################################################### +# Includes +# ###################################################################################################################### + +zephyr_include_directories(${aoscore_source_dir}/include) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/..) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/../../src) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src) +zephyr_include_directories(${CMAKE_CURRENT_BINARY_DIR}) +zephyr_include_directories(${CMAKE_CURRENT_BINARY_DIR}/proto) + +# ###################################################################################################################### +# Generate API +# ###################################################################################################################### + +find_package(CoreAPI) + +set(CORE_API_CXX_FLAGS -I${APPLICATION_SOURCE_DIR}/../../src -I${aoscore_source_dir}/include -include + ${CMAKE_CURRENT_BINARY_DIR}/zephyr/include/generated/autoconf.h -include ${aoscore_config} +) + +set(AOS_PROTO_SRC proto/common/v1/common.proto proto/iamanager/v5/iamanager.proto) + +core_api_generate(${CMAKE_CURRENT_SOURCE_DIR}/../../../aos_core_api ${CMAKE_CURRENT_SOURCE_DIR}/../../scripts) + +# ###################################################################################################################### +# Target +# ###################################################################################################################### + +target_sources( + app PRIVATE ../../src/communication/pbhandler.cpp ../../src/iamclient/iamclient.cpp ../utils/log.cpp + ../utils/pbmessages.cpp ../utils/utils.cpp src/main.cpp +) diff --git a/tests/iamclient/Kconfig b/tests/iamclient/Kconfig new file mode 100644 index 00000000..a10b40d2 --- /dev/null +++ b/tests/iamclient/Kconfig @@ -0,0 +1,28 @@ +# Copyright (C) 2024 Renesas Electronics Corporation. +# Copyright (C) 2024 EPAM Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "Aos zephyr application" + +config AOS_CLOCK_SYNC_SEND_PERIOD_SEC + int "Send clock sync period in seconds" + default 1 + +config AOS_CLOCK_SYNC_TIMEOUT_SEC + int "Clock becomes unsynced if there is no clock sync update during this period." + default 1 + +config AOS_CLOCK_SYNC_MAX_DIFF_MSEC + int "Maximum allowed difference between source and current time." + default 10000 + +config AOS_IAM_OPEN_PORT + int "Aos SM open port" + default 1 + +config AOS_IAM_SECURE_PORT + int "Aos SM secure port" + default 2 + +source "Kconfig" diff --git a/tests/iamclient/prj.conf b/tests/iamclient/prj.conf new file mode 100644 index 00000000..74f5898d --- /dev/null +++ b/tests/iamclient/prj.conf @@ -0,0 +1,19 @@ +# Enable C++ + +CONFIG_CPP=y +CONFIG_STD_CPP17=y +CONFIG_EXTERNAL_LIBCPP=y +CONFIG_CBPRINTF_FP_SUPPORT=y + +# Enable test suit + +CONFIG_ZTEST=y + +# Enable debug for tests + +CONFIG_DEBUG=y +CONFIG_NO_OPTIMIZATIONS=y + +# Enable nanopb lib + +CONFIG_NANOPB=y diff --git a/tests/iamclient/src/main.cpp b/tests/iamclient/src/main.cpp new file mode 100644 index 00000000..6455cf50 --- /dev/null +++ b/tests/iamclient/src/main.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "iamclient/iamclient.hpp" + +#include "stubs/channelmanagerstub.hpp" +#include "stubs/clocksyncstub.hpp" +#include "stubs/nodeinfoproviderstub.hpp" +#include "utils/log.hpp" +#include "utils/pbmessages.hpp" +#include "utils/utils.hpp" + +using namespace aos::zephyr; + +/*********************************************************************************************************************** + * Consts + **********************************************************************************************************************/ + +static constexpr auto cWaitTimeout = std::chrono::seconds {5}; + +/*********************************************************************************************************************** + * Types + **********************************************************************************************************************/ + +struct iamclient_fixture { + ClockSyncStub mClockSync; + NodeInfoProviderStub mNodeInfoProvider; + ChannelManagerStub mChannelManager; + iamclient::IAMClient mIAMClient; +}; + +/*********************************************************************************************************************** + * Static + **********************************************************************************************************************/ + +static aos::Error ReceiveIAMOutgoingMessage(ChannelStub* channel, iamanager_v5_IAMOutgoingMessages& message) +{ + return ReceivePBMessage( + channel, cWaitTimeout, &message, iamanager_v5_IAMOutgoingMessages_size, &iamanager_v5_IAMOutgoingMessages_msg); +} + +static aos::Error SendIAMIncomingMessage(ChannelStub* channel, const iamanager_v5_IAMIncomingMessages& message) +{ + return SendPBMessage( + channel, &message, iamanager_v5_IAMIncomingMessages_size, &iamanager_v5_IAMIncomingMessages_msg); +} + +/*********************************************************************************************************************** + * Setup + **********************************************************************************************************************/ + +ZTEST_SUITE( + iamclient, nullptr, + []() -> void* { + aos::Log::SetCallback(TestLogCallback); + + auto fixture = new iamclient_fixture; + + auto err = fixture->mIAMClient.Init(fixture->mClockSync, fixture->mNodeInfoProvider, fixture->mChannelManager); + + zassert_true(err.IsNone(), "Can't initialize SM client: %s", AosErrorToStr(err)); + + return fixture; + }, + nullptr, nullptr, [](void* fixture) { delete static_cast(fixture); }); + +/*********************************************************************************************************************** + * Tests + **********************************************************************************************************************/ + +ZTEST_F(iamclient, test_Provisioning) +{ +} diff --git a/tests/iamclient/src/stubs/clocksyncstub.hpp b/tests/iamclient/src/stubs/clocksyncstub.hpp new file mode 100644 index 00000000..31b35da6 --- /dev/null +++ b/tests/iamclient/src/stubs/clocksyncstub.hpp @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef CLOCKSYNCSTUB_HPP_ +#define CLOCKSYNCSTUB_HPP_ + +#include "clocksync/clocksync.hpp" + +class ClockSyncStub : public aos::zephyr::clocksync::ClockSyncItf { +public: + aos::Error Start() override { return aos::ErrorEnum::eNone; } + + aos::Error Sync(const aos::Time& time) override { return aos::ErrorEnum::eNone; } + + aos::Error Subscribe(aos::zephyr::clocksync::ClockSyncSubscriberItf& subscriber) override + { + return aos::ErrorEnum::eNone; + } + + void Unsubscribe(aos::zephyr::clocksync::ClockSyncSubscriberItf& subscriber) override {}; +}; + +#endif diff --git a/tests/iamclient/src/stubs/nodeinfoproviderstub.hpp b/tests/iamclient/src/stubs/nodeinfoproviderstub.hpp new file mode 100644 index 00000000..a45d049e --- /dev/null +++ b/tests/iamclient/src/stubs/nodeinfoproviderstub.hpp @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NODEINFOPROVIDERSTUB_HPP_ +#define NODEINFOPROVIDERSTUB_HPP_ + +#include + +class NodeInfoProviderStub : public aos::iam::nodeinfoprovider::NodeInfoProviderItf { +public: + aos::Error GetNodeInfo(aos::NodeInfo& nodeInfo) const override { return aos::ErrorEnum::eNone; } + + aos::Error SetNodeStatus(const aos::NodeStatus& status) override { return aos::ErrorEnum::eNone; } + + aos::Error SubscribeNodeStatusChanged(aos::iam::nodeinfoprovider::NodeStatusObserverItf& observer) override + { + return aos::ErrorEnum::eNone; + } + + aos::Error UnsubscribeNodeStatusChanged(aos::iam::nodeinfoprovider::NodeStatusObserverItf& observer) override + { + return aos::ErrorEnum::eNone; + } +}; + +#endif diff --git a/tests/iamclient/testcase.yaml b/tests/iamclient/testcase.yaml new file mode 100644 index 00000000..4250e3f9 --- /dev/null +++ b/tests/iamclient/testcase.yaml @@ -0,0 +1,6 @@ +tests: + aoszephyrapp.iamclient: + build_only: false + tags: iamclient + timeout: 500 + platform_allow: native_posix_64 native_posix From fc233ab4472b6fba004bcb9e8a4cd8b39e20facb Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sat, 17 Aug 2024 11:49:39 +0300 Subject: [PATCH 059/198] [iamclient] Implement provisioning functionality Signed-off-by: Oleksandr Grytsov --- src/app/app.cpp | 2 +- src/iamclient/iamclient.cpp | 238 +++++++++++++++- src/iamclient/iamclient.hpp | 29 +- tests/iamclient/CMakeLists.txt | 4 +- tests/iamclient/src/main.cpp | 258 +++++++++++++++++- .../src/stubs/nodeinfoproviderstub.hpp | 12 +- .../src/stubs/provisionmanagerstub.hpp | 85 ++++++ 7 files changed, 610 insertions(+), 18 deletions(-) create mode 100644 tests/iamclient/src/stubs/provisionmanagerstub.hpp diff --git a/src/app/app.cpp b/src/app/app.cpp index 187b7113..44a57442 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -159,7 +159,7 @@ Error App::InitZephyr() return AOS_ERROR_WRAP(err); } - if (auto err = mIAMClient.Init(mClockSync, mNodeInfoProvider, mChannelManager); !err.IsNone()) { + if (auto err = mIAMClient.Init(mClockSync, mNodeInfoProvider, mProvisionManager, mChannelManager); !err.IsNone()) { return AOS_ERROR_WRAP(err); } diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index 46a8c9b9..21ae0f53 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -5,6 +5,10 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + +#include "utils/pbconvert.hpp" + #include "iamclient.hpp" #include "log.hpp" @@ -17,20 +21,45 @@ namespace aos::zephyr::iamclient { **********************************************************************************************************************/ Error IAMClient::Init(clocksync::ClockSyncItf& clockSync, iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider, - communication::ChannelManagerItf& channelManager) + iam::provisionmanager::ProvisionManagerItf& provisionManager, communication::ChannelManagerItf& channelManager) { LOG_DBG() << "Initialize IAM client"; - Error err; + mProvisionManager = &provisionManager; - if (!(err = clockSync.Subscribe(*this)).IsNone()) { + if (auto err = clockSync.Subscribe(*this); !err.IsNone()) { return AOS_ERROR_WRAP(err); } - if (!(err = nodeInfoProvider.SubscribeNodeStatusChanged(*this)).IsNone()) { + if (auto err = nodeInfoProvider.SubscribeNodeStatusChanged(*this); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + NodeInfo nodeInfo; + + if (auto err = nodeInfoProvider.GetNodeInfo(nodeInfo); !err.IsNone()) { return AOS_ERROR_WRAP(err); } + mNodeID = nodeInfo.mNodeID; + + if (nodeInfo.mStatus == NodeStatusEnum::eUnprovisioned) { + LOG_INF() << "Node is unprovisioned"; + + auto channel = channelManager.CreateChannel(cOpenPort); + if (!channel.mError.IsNone()) { + return AOS_ERROR_WRAP(channel.mError); + } + + if (auto err = PBHandler::Init("IAM open", *channel.mValue); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + if (auto err = Start(); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + } + return ErrorEnum::eNone; } @@ -47,6 +76,11 @@ Error IAMClient::OnNodeStatusChanged(const String& nodeID, const NodeStatus& sta return ErrorEnum::eNone; } +IAMClient::~IAMClient() +{ + Stop(); +} + /*********************************************************************************************************************** * Private **********************************************************************************************************************/ @@ -61,7 +95,201 @@ void IAMClient::OnDisconnect() Error IAMClient::ReceiveMessage(const Array& data) { - return ErrorEnum::eNone; + auto stream = pb_istream_from_buffer(data.Get(), data.Size()); + + if (auto status = pb_decode(&stream, &iamanager_v5_IAMIncomingMessages_msg, &mIncomingMessages); !status) { + return AOS_ERROR_WRAP(Error(ErrorEnum::eRuntime, "failed to decode message")); + } + + Error err; + + switch (mIncomingMessages.which_IAMIncomingMessage) { + case iamanager_v5_IAMIncomingMessages_start_provisioning_request_tag: + err = ProcessStartProvisioning(mIncomingMessages.IAMIncomingMessage.start_provisioning_request); + break; + + case iamanager_v5_IAMIncomingMessages_finish_provisioning_request_tag: + err = ProcessFinishProvisioning(mIncomingMessages.IAMIncomingMessage.finish_provisioning_request); + break; + + case iamanager_v5_IAMIncomingMessages_deprovision_request_tag: + err = ProcessDeprovision(mIncomingMessages.IAMIncomingMessage.deprovision_request); + break; + + case iamanager_v5_IAMIncomingMessages_get_cert_types_request_tag: + err = ProcessGetCertTypes(mIncomingMessages.IAMIncomingMessage.get_cert_types_request); + break; + + case iamanager_v5_IAMIncomingMessages_create_key_request_tag: + err = ProcessCreateKey(mIncomingMessages.IAMIncomingMessage.create_key_request); + break; + + case iamanager_v5_IAMIncomingMessages_apply_cert_request_tag: + err = ProcessApplyCert(mIncomingMessages.IAMIncomingMessage.apply_cert_request); + break; + + default: + LOG_WRN() << "Receive unsupported message: tag=" << mIncomingMessages.which_IAMIncomingMessage; + break; + } + + return err; +} + +template +Error IAMClient::SendError(const Error& err, T& pbMessage) +{ + LOG_ERR() << "Process message error: err=" << err; + + utils::ErrorToPB(err, pbMessage); + + return SendMessage(&mOutgoingMessages, &iamanager_v5_IAMOutgoingMessages_msg); +} + +Error IAMClient::ProcessStartProvisioning(const iamanager_v5_StartProvisioningRequest& pbStartProvisioningRequest) +{ + LOG_INF() << "Process start provisioning request"; + + auto& pbStartProvisionResponse = mOutgoingMessages.IAMOutgoingMessage.start_provisioning_response; + + mOutgoingMessages.which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_start_provisioning_response_tag; + pbStartProvisionResponse + = iamanager_v5_StartProvisioningResponse iamanager_v5_StartProvisioningResponse_init_default; + + if (pbStartProvisioningRequest.node_id != mNodeID) { + return SendError(AOS_ERROR_WRAP(Error(ErrorEnum::eInvalidArgument, "wrong node ID")), pbStartProvisionResponse); + } + + if (auto err = mProvisionManager->StartProvisioning(pbStartProvisioningRequest.password); !err.IsNone()) { + return SendError(err, pbStartProvisionResponse); + } + + return SendMessage(&mOutgoingMessages, &iamanager_v5_IAMOutgoingMessages_msg); +} + +Error IAMClient::ProcessFinishProvisioning(const iamanager_v5_FinishProvisioningRequest& pbFinishProvisioningRequest) +{ + LOG_INF() << "Process finish provisioning request"; + + auto& pbFinishProvisionResponse = mOutgoingMessages.IAMOutgoingMessage.finish_provisioning_response; + + mOutgoingMessages.which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_finish_provisioning_response_tag; + pbFinishProvisionResponse + = iamanager_v5_FinishProvisioningResponse iamanager_v5_FinishProvisioningResponse_init_default; + + if (pbFinishProvisioningRequest.node_id != mNodeID) { + return SendError( + AOS_ERROR_WRAP(Error(ErrorEnum::eInvalidArgument, "wrong node ID")), pbFinishProvisionResponse); + } + + if (auto err = mProvisionManager->FinishProvisioning(pbFinishProvisioningRequest.password); !err.IsNone()) { + return SendError(err, pbFinishProvisionResponse); + } + + return SendMessage(&mOutgoingMessages, &iamanager_v5_IAMOutgoingMessages_msg); +} + +Error IAMClient::ProcessDeprovision(const iamanager_v5_DeprovisionRequest& pbDeprovisionRequest) +{ + LOG_INF() << "Process deprovision request"; + + auto& pbDeprovisionResponse = mOutgoingMessages.IAMOutgoingMessage.deprovision_response; + + mOutgoingMessages.which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_deprovision_response_tag; + pbDeprovisionResponse = iamanager_v5_DeprovisionResponse iamanager_v5_DeprovisionResponse_init_default; + + if (pbDeprovisionRequest.node_id != mNodeID) { + return SendError(AOS_ERROR_WRAP(Error(ErrorEnum::eInvalidArgument, "wrong node ID")), pbDeprovisionResponse); + } + + if (auto err = mProvisionManager->Deprovision(pbDeprovisionRequest.password); !err.IsNone()) { + return SendError(err, pbDeprovisionResponse); + } + + return SendMessage(&mOutgoingMessages, &iamanager_v5_IAMOutgoingMessages_msg); +} + +Error IAMClient::ProcessGetCertTypes(const iamanager_v5_GetCertTypesRequest& pbGetCertTypesRequest) +{ + LOG_INF() << "Process get cert types"; + + auto& pbGetCertTypesResponse = mOutgoingMessages.IAMOutgoingMessage.cert_types_response; + + mOutgoingMessages.which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_cert_types_response_tag; + pbGetCertTypesResponse = iamanager_v5_CertTypes iamanager_v5_CertTypes_init_default; + + if (pbGetCertTypesRequest.node_id != mNodeID) { + LOG_ERR() << "Wrong node ID: " << pbGetCertTypesRequest.node_id; + } + + auto certTypes = mProvisionManager->GetCertTypes(); + if (!certTypes.mError.IsNone()) { + LOG_ERR() << "Getting cert types error: err=" << certTypes.mError; + } + + pbGetCertTypesResponse.types_count = certTypes.mValue.Size(); + + for (size_t i = 0; i < certTypes.mValue.Size(); i++) { + utils::StringFromCStr(pbGetCertTypesResponse.types[i]) = certTypes.mValue[i]; + } + + return SendMessage(&mOutgoingMessages, &iamanager_v5_IAMOutgoingMessages_msg); +} + +Error IAMClient::ProcessCreateKey(const iamanager_v5_CreateKeyRequest& pbCreateKeyRequest) +{ + LOG_INF() << "Process create key: type=" << pbCreateKeyRequest.type << ", subject=" << pbCreateKeyRequest.subject; + + auto& pbCreateKeyResponse = mOutgoingMessages.IAMOutgoingMessage.create_key_response; + + mOutgoingMessages.which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_create_key_response_tag; + pbCreateKeyResponse = iamanager_v5_CreateKeyResponse iamanager_v5_CreateKeyResponse_init_default; + + if (pbCreateKeyRequest.node_id != mNodeID) { + return SendError(AOS_ERROR_WRAP(Error(ErrorEnum::eInvalidArgument, "wrong node ID")), pbCreateKeyResponse); + } + + auto csr = utils::StringFromCStr(pbCreateKeyResponse.csr); + + if (auto err = mProvisionManager->CreateKey( + pbCreateKeyRequest.type, pbCreateKeyRequest.subject, pbCreateKeyRequest.password, csr); + !err.IsNone()) { + return SendError(err, pbCreateKeyResponse); + } + + utils::StringFromCStr(pbCreateKeyResponse.type) = pbCreateKeyRequest.type; + + return SendMessage(&mOutgoingMessages, &iamanager_v5_IAMOutgoingMessages_msg); +} + +Error IAMClient::ProcessApplyCert(const iamanager_v5_ApplyCertRequest& pbApplyCertRequest) +{ + LOG_INF() << "Process apply cert: type=" << pbApplyCertRequest.type; + + auto& pbApplyCertResponse = mOutgoingMessages.IAMOutgoingMessage.apply_cert_response; + + mOutgoingMessages.which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_apply_cert_response_tag; + pbApplyCertResponse = iamanager_v5_ApplyCertResponse iamanager_v5_ApplyCertResponse_init_default; + + if (pbApplyCertRequest.node_id != mNodeID) { + return SendError(AOS_ERROR_WRAP(Error(ErrorEnum::eInvalidArgument, "wrong node ID")), pbApplyCertResponse); + } + + iam::certhandler::CertInfo certInfo {}; + + if (auto err = mProvisionManager->ApplyCert(pbApplyCertRequest.type, pbApplyCertRequest.cert, certInfo); + !err.IsNone()) { + return SendError(err, pbApplyCertResponse); + } + + utils::StringFromCStr(pbApplyCertResponse.type) = pbApplyCertRequest.type; + utils::StringFromCStr(pbApplyCertResponse.cert_url) = certInfo.mCertURL; + + if (auto err = utils::StringFromCStr(pbApplyCertResponse.serial).ByteArrayToHex(certInfo.mSerial); !err.IsNone()) { + return SendError(err, pbApplyCertResponse); + } + + return SendMessage(&mOutgoingMessages, &iamanager_v5_IAMOutgoingMessages_msg); } } // namespace aos::zephyr::iamclient diff --git a/src/iamclient/iamclient.hpp b/src/iamclient/iamclient.hpp index 76187082..70b11862 100644 --- a/src/iamclient/iamclient.hpp +++ b/src/iamclient/iamclient.hpp @@ -9,6 +9,7 @@ #define IAMCLIENT_HPP_ #include +#include #include @@ -32,16 +33,12 @@ class IAMClient * * @param clockSync clock sync instance. * @param nodeInfoProvider node info provider. + * @param provisionManager provision manager. * @param channelManager channel manager instance. * @return Error. */ Error Init(clocksync::ClockSyncItf& clockSync, iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider, - communication::ChannelManagerItf& channelManager); - - /** - * Destructor. - */ - ~IAMClient() = default; + iam::provisionmanager::ProvisionManagerItf& provisionManager, communication::ChannelManagerItf& channelManager); /** * Notifies subscriber clock is synced. @@ -62,6 +59,11 @@ class IAMClient */ Error OnNodeStatusChanged(const String& nodeID, const NodeStatus& status) override; + /** + * Destructor. + */ + ~IAMClient(); + private: static constexpr auto cOpenPort = CONFIG_AOS_IAM_OPEN_PORT; static constexpr auto cSecurePort = CONFIG_AOS_IAM_SECURE_PORT; @@ -69,6 +71,21 @@ class IAMClient void OnConnect() override; void OnDisconnect() override; Error ReceiveMessage(const Array& data) override; + + template + Error SendError(const Error& err, T& pbMessage); + Error ProcessStartProvisioning(const iamanager_v5_StartProvisioningRequest& pbStartProvisioningRequest); + Error ProcessFinishProvisioning(const iamanager_v5_FinishProvisioningRequest& pbFinishProvisioningRequest); + Error ProcessDeprovision(const iamanager_v5_DeprovisionRequest& pbDeprovisionRequest); + Error ProcessGetCertTypes(const iamanager_v5_GetCertTypesRequest& pbGetCertTypesRequest); + Error ProcessCreateKey(const iamanager_v5_CreateKeyRequest& pbCreateKeyRequest); + Error ProcessApplyCert(const iamanager_v5_ApplyCertRequest& pbApplyCertRequest); + + iam::provisionmanager::ProvisionManagerItf* mProvisionManager {}; + + StaticString mNodeID; + iamanager_v5_IAMOutgoingMessages mOutgoingMessages; + iamanager_v5_IAMIncomingMessages mIncomingMessages; }; } // namespace aos::zephyr::iamclient diff --git a/tests/iamclient/CMakeLists.txt b/tests/iamclient/CMakeLists.txt index bd233bd0..78b55940 100644 --- a/tests/iamclient/CMakeLists.txt +++ b/tests/iamclient/CMakeLists.txt @@ -56,6 +56,6 @@ core_api_generate(${CMAKE_CURRENT_SOURCE_DIR}/../../../aos_core_api ${CMAKE_CURR # ###################################################################################################################### target_sources( - app PRIVATE ../../src/communication/pbhandler.cpp ../../src/iamclient/iamclient.cpp ../utils/log.cpp - ../utils/pbmessages.cpp ../utils/utils.cpp src/main.cpp + app PRIVATE ../../src/communication/pbhandler.cpp ../../src/iamclient/iamclient.cpp ../../src/utils/utils.cpp + ../utils/log.cpp ../utils/pbmessages.cpp src/main.cpp ) diff --git a/tests/iamclient/src/main.cpp b/tests/iamclient/src/main.cpp index 6455cf50..495f6877 100644 --- a/tests/iamclient/src/main.cpp +++ b/tests/iamclient/src/main.cpp @@ -13,7 +13,9 @@ #include "stubs/channelmanagerstub.hpp" #include "stubs/clocksyncstub.hpp" #include "stubs/nodeinfoproviderstub.hpp" +#include "stubs/provisionmanagerstub.hpp" #include "utils/log.hpp" +#include "utils/pbconvert.hpp" #include "utils/pbmessages.hpp" #include "utils/utils.hpp" @@ -25,6 +27,8 @@ using namespace aos::zephyr; static constexpr auto cWaitTimeout = std::chrono::seconds {5}; +static aos::NodeInfo sNodeInfo = {.mNodeID = "node0"}; + /*********************************************************************************************************************** * Types **********************************************************************************************************************/ @@ -32,6 +36,7 @@ static constexpr auto cWaitTimeout = std::chrono::seconds {5}; struct iamclient_fixture { ClockSyncStub mClockSync; NodeInfoProviderStub mNodeInfoProvider; + ProvisionManagerStub mProvisionManager; ChannelManagerStub mChannelManager; iamclient::IAMClient mIAMClient; }; @@ -63,9 +68,12 @@ ZTEST_SUITE( auto fixture = new iamclient_fixture; - auto err = fixture->mIAMClient.Init(fixture->mClockSync, fixture->mNodeInfoProvider, fixture->mChannelManager); + fixture->mNodeInfoProvider.SetNodeInfo(sNodeInfo); + + auto err = fixture->mIAMClient.Init( + fixture->mClockSync, fixture->mNodeInfoProvider, fixture->mProvisionManager, fixture->mChannelManager); - zassert_true(err.IsNone(), "Can't initialize SM client: %s", AosErrorToStr(err)); + zassert_true(err.IsNone(), "Can't initialize SM client: %s", utils::ErrorToCStr(err)); return fixture; }, @@ -75,6 +83,250 @@ ZTEST_SUITE( * Tests **********************************************************************************************************************/ -ZTEST_F(iamclient, test_Provisioning) +ZTEST_F(iamclient, test_StartProvisioning) { + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Send start provisioning request + + iamanager_v5_IAMIncomingMessages incomingMessage; + auto& pbStartProvisioningRequest = incomingMessage.IAMIncomingMessage.start_provisioning_request; + + incomingMessage.which_IAMIncomingMessage = iamanager_v5_IAMIncomingMessages_start_provisioning_request_tag; + pbStartProvisioningRequest + = iamanager_v5_StartProvisioningRequest iamanager_v5_StartProvisioningRequest_init_default; + + utils::StringFromCStr(pbStartProvisioningRequest.node_id) = sNodeInfo.mNodeID; + utils::StringFromCStr(pbStartProvisioningRequest.password) = "12345"; + + err = SendIAMIncomingMessage(channel, incomingMessage); + zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + + // Receive start provisioning response + + iamanager_v5_IAMOutgoingMessages outgoingMessage; + auto& pbStartProvisioningResponse = outgoingMessage.IAMOutgoingMessage.start_provisioning_response; + + pbStartProvisioningResponse + = iamanager_v5_StartProvisioningResponse iamanager_v5_StartProvisioningResponse_init_default; + + err = ReceiveIAMOutgoingMessage(channel, outgoingMessage); + zassert_true(err.IsNone(), "Error receiving message: %s", utils::ErrorToCStr(err)); + + zassert_equal(outgoingMessage.which_IAMOutgoingMessage, + iamanager_v5_IAMOutgoingMessages_start_provisioning_response_tag, "Unexpected message type"); + zassert_false(pbStartProvisioningResponse.has_error, "Unexpected error received"); + + zassert_equal(fixture->mProvisionManager.GetPassword(), pbStartProvisioningRequest.password, "Wrong password"); +} + +ZTEST_F(iamclient, test_FinishProvisioning) +{ + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Send finish provisioning request + + iamanager_v5_IAMIncomingMessages incomingMessage; + auto& pbFinishProvisioningRequest = incomingMessage.IAMIncomingMessage.finish_provisioning_request; + + incomingMessage.which_IAMIncomingMessage = iamanager_v5_IAMIncomingMessages_finish_provisioning_request_tag; + pbFinishProvisioningRequest + = iamanager_v5_FinishProvisioningRequest iamanager_v5_FinishProvisioningRequest_init_default; + + utils::StringFromCStr(pbFinishProvisioningRequest.node_id) = sNodeInfo.mNodeID; + utils::StringFromCStr(pbFinishProvisioningRequest.password) = "ABCDEF"; + + err = SendIAMIncomingMessage(channel, incomingMessage); + zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + + // Receive finish provisioning response + + iamanager_v5_IAMOutgoingMessages outgoingMessage; + auto& pbFinishProvisioningResponse = outgoingMessage.IAMOutgoingMessage.finish_provisioning_response; + + pbFinishProvisioningResponse + = iamanager_v5_FinishProvisioningResponse iamanager_v5_FinishProvisioningResponse_init_default; + + err = ReceiveIAMOutgoingMessage(channel, outgoingMessage); + zassert_true(err.IsNone(), "Error receiving message: %s", utils::ErrorToCStr(err)); + + zassert_equal(outgoingMessage.which_IAMOutgoingMessage, + iamanager_v5_IAMOutgoingMessages_finish_provisioning_response_tag, "Unexpected message type"); + zassert_false(pbFinishProvisioningResponse.has_error, "Unexpected error received"); + + zassert_equal(fixture->mProvisionManager.GetPassword(), pbFinishProvisioningRequest.password, "Wrong password"); +} + +ZTEST_F(iamclient, test_Deprovision) +{ + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Send deprovision request + + iamanager_v5_IAMIncomingMessages incomingMessage; + auto& pbDeprovisionRequest = incomingMessage.IAMIncomingMessage.deprovision_request; + + incomingMessage.which_IAMIncomingMessage = iamanager_v5_IAMIncomingMessages_deprovision_request_tag; + pbDeprovisionRequest = iamanager_v5_DeprovisionRequest iamanager_v5_DeprovisionRequest_init_default; + + utils::StringFromCStr(pbDeprovisionRequest.node_id) = sNodeInfo.mNodeID; + utils::StringFromCStr(pbDeprovisionRequest.password) = "FEDCBA"; + + err = SendIAMIncomingMessage(channel, incomingMessage); + zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + + // Receive deprovision response + + iamanager_v5_IAMOutgoingMessages outgoingMessage; + auto& pbDeprovisionResponse = outgoingMessage.IAMOutgoingMessage.finish_provisioning_response; + + pbDeprovisionResponse + = iamanager_v5_FinishProvisioningResponse iamanager_v5_FinishProvisioningResponse_init_default; + + err = ReceiveIAMOutgoingMessage(channel, outgoingMessage); + zassert_true(err.IsNone(), "Error receiving message: %s", utils::ErrorToCStr(err)); + + zassert_equal(outgoingMessage.which_IAMOutgoingMessage, iamanager_v5_IAMOutgoingMessages_deprovision_response_tag, + "Unexpected message type"); + zassert_false(pbDeprovisionResponse.has_error, "Unexpected error received"); + + zassert_equal(fixture->mProvisionManager.GetPassword(), pbDeprovisionRequest.password, "Wrong password"); +} + +ZTEST_F(iamclient, test_GetCertTypes) +{ + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + aos::iam::provisionmanager::CertTypes certTypes; + + certTypes.PushBack("certType1"); + certTypes.PushBack("certType2"); + + fixture->mProvisionManager.SetCertTypes(certTypes); + + // Send get cert types request + + iamanager_v5_IAMIncomingMessages incomingMessage; + auto& pbGetCertTypesRequest = incomingMessage.IAMIncomingMessage.get_cert_types_request; + + incomingMessage.which_IAMIncomingMessage = iamanager_v5_IAMIncomingMessages_get_cert_types_request_tag; + pbGetCertTypesRequest = iamanager_v5_GetCertTypesRequest iamanager_v5_GetCertTypesRequest_init_default; + + utils::StringFromCStr(pbGetCertTypesRequest.node_id) = sNodeInfo.mNodeID; + + err = SendIAMIncomingMessage(channel, incomingMessage); + zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + + // Receive get cert types response + + iamanager_v5_IAMOutgoingMessages outgoingMessage; + auto& pbGetCertTypesResponse = outgoingMessage.IAMOutgoingMessage.cert_types_response; + + pbGetCertTypesResponse = iamanager_v5_CertTypes iamanager_v5_CertTypes_init_default; + + err = ReceiveIAMOutgoingMessage(channel, outgoingMessage); + zassert_true(err.IsNone(), "Error receiving message: %s", utils::ErrorToCStr(err)); + + zassert_equal(outgoingMessage.which_IAMOutgoingMessage, iamanager_v5_IAMOutgoingMessages_cert_types_response_tag, + "Unexpected message type"); + zassert_equal(pbGetCertTypesResponse.types_count, certTypes.Size(), "Wrong cert types count"); + + for (size_t i = 0; i < certTypes.Size(); i++) { + zassert_equal(pbGetCertTypesResponse.types[i], certTypes[i], "Wrong cert type"); + } +} + +ZTEST_F(iamclient, test_CreateKey) +{ + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + fixture->mProvisionManager.SetCSR("csr1"); + + // Send create key request + + iamanager_v5_IAMIncomingMessages incomingMessage; + auto& pbCreateKeyRequest = incomingMessage.IAMIncomingMessage.create_key_request; + + incomingMessage.which_IAMIncomingMessage = iamanager_v5_IAMIncomingMessages_create_key_request_tag; + pbCreateKeyRequest = iamanager_v5_CreateKeyRequest iamanager_v5_CreateKeyRequest_init_default; + + utils::StringFromCStr(pbCreateKeyRequest.node_id) = sNodeInfo.mNodeID; + utils::StringFromCStr(pbCreateKeyRequest.type) = "certType1"; + utils::StringFromCStr(pbCreateKeyRequest.subject) = "subject1"; + utils::StringFromCStr(pbCreateKeyRequest.password) = "54321"; + + err = SendIAMIncomingMessage(channel, incomingMessage); + zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + + // Receive create key response + + iamanager_v5_IAMOutgoingMessages outgoingMessage; + auto& pbCreateKeyResponse = outgoingMessage.IAMOutgoingMessage.create_key_response; + + pbCreateKeyResponse = iamanager_v5_CreateKeyResponse iamanager_v5_CreateKeyResponse_init_default; + + err = ReceiveIAMOutgoingMessage(channel, outgoingMessage); + zassert_true(err.IsNone(), "Error receiving message: %s", utils::ErrorToCStr(err)); + + zassert_equal(outgoingMessage.which_IAMOutgoingMessage, iamanager_v5_IAMOutgoingMessages_create_key_response_tag, + "Unexpected message type"); + zassert_false(pbCreateKeyResponse.has_error, "Unexpected error received"); + zassert_equal(utils::StringFromCStr(pbCreateKeyResponse.type), utils::StringFromCStr(pbCreateKeyRequest.type), + "Wrong cert type"); + zassert_equal(pbCreateKeyResponse.csr, fixture->mProvisionManager.GetCSR(), "Wrong CSR"); + zassert_equal(pbCreateKeyRequest.type, fixture->mProvisionManager.GetCertType(), "Wrong cert type"); + zassert_equal(pbCreateKeyRequest.subject, fixture->mProvisionManager.GetSubject(), "Wrong subject"); + zassert_equal(pbCreateKeyRequest.password, fixture->mProvisionManager.GetPassword(), "Wrong password"); +} + +ZTEST_F(iamclient, test_ApplyCert) +{ + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + aos::iam::certhandler::CertInfo certInfo {}; + + aos::StaticString serial = "0123456789abcdef"; + + err = serial.HexToByteArray(certInfo.mSerial); + zassert_true(err.IsNone(), "Convert serial error: %s", utils::ErrorToCStr(err)); + + fixture->mProvisionManager.SetCertInfo(certInfo); + + // Send apply cert request + + iamanager_v5_IAMIncomingMessages incomingMessage; + auto& pbApplyCertRequest = incomingMessage.IAMIncomingMessage.apply_cert_request; + + incomingMessage.which_IAMIncomingMessage = iamanager_v5_IAMIncomingMessages_apply_cert_request_tag; + pbApplyCertRequest = iamanager_v5_ApplyCertRequest iamanager_v5_ApplyCertRequest_init_default; + + utils::StringFromCStr(pbApplyCertRequest.node_id) = sNodeInfo.mNodeID; + utils::StringFromCStr(pbApplyCertRequest.type) = "certType2"; + utils::StringFromCStr(pbApplyCertRequest.cert) = "cert1"; + + err = SendIAMIncomingMessage(channel, incomingMessage); + zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + + // Receive apply cert response + + iamanager_v5_IAMOutgoingMessages outgoingMessage; + auto& pbApplyCertResponse = outgoingMessage.IAMOutgoingMessage.apply_cert_response; + + pbApplyCertResponse = iamanager_v5_ApplyCertResponse iamanager_v5_ApplyCertResponse_init_default; + + err = ReceiveIAMOutgoingMessage(channel, outgoingMessage); + zassert_true(err.IsNone(), "Error receiving message: %s", utils::ErrorToCStr(err)); + + zassert_equal(outgoingMessage.which_IAMOutgoingMessage, iamanager_v5_IAMOutgoingMessages_apply_cert_response_tag, + "Unexpected message type"); + zassert_false(pbApplyCertResponse.has_error, "Unexpected error received"); + zassert_equal(pbApplyCertResponse.type, fixture->mProvisionManager.GetCertType(), "Wrong cert type"); + zassert_equal(pbApplyCertResponse.cert_url, certInfo.mCertURL, "Wrong cert URL"); + zassert_equal(pbApplyCertResponse.serial, serial, "Wrong serial"); } diff --git a/tests/iamclient/src/stubs/nodeinfoproviderstub.hpp b/tests/iamclient/src/stubs/nodeinfoproviderstub.hpp index a45d049e..76585f8c 100644 --- a/tests/iamclient/src/stubs/nodeinfoproviderstub.hpp +++ b/tests/iamclient/src/stubs/nodeinfoproviderstub.hpp @@ -12,7 +12,12 @@ class NodeInfoProviderStub : public aos::iam::nodeinfoprovider::NodeInfoProviderItf { public: - aos::Error GetNodeInfo(aos::NodeInfo& nodeInfo) const override { return aos::ErrorEnum::eNone; } + aos::Error GetNodeInfo(aos::NodeInfo& nodeInfo) const override + { + nodeInfo = mNodeInfo; + + return aos::ErrorEnum::eNone; + } aos::Error SetNodeStatus(const aos::NodeStatus& status) override { return aos::ErrorEnum::eNone; } @@ -25,6 +30,11 @@ class NodeInfoProviderStub : public aos::iam::nodeinfoprovider::NodeInfoProvider { return aos::ErrorEnum::eNone; } + + void SetNodeInfo(const aos::NodeInfo& nodeInfo) { mNodeInfo = nodeInfo; } + +private: + aos::NodeInfo mNodeInfo; }; #endif diff --git a/tests/iamclient/src/stubs/provisionmanagerstub.hpp b/tests/iamclient/src/stubs/provisionmanagerstub.hpp new file mode 100644 index 00000000..ef7bcc36 --- /dev/null +++ b/tests/iamclient/src/stubs/provisionmanagerstub.hpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef PROVISIONMANAGERSTUB_HPP_ +#define PROVISIONMANAGERSTUB_HPP_ + +#include + +class ProvisionManagerStub : public aos::iam::provisionmanager::ProvisionManagerItf { +public: + aos::Error StartProvisioning(const aos::String& password) override + { + mPassword = password; + + return aos::ErrorEnum::eNone; + } + + aos::RetWithError GetCertTypes() { return mCertTypes; } + + aos::Error CreateKey( + const aos::String& certType, const aos::String& subject, const aos::String& password, aos::String& csr) override + { + mCertType = certType; + mSubject = subject; + mPassword = password; + csr = mCSR; + + return aos::ErrorEnum::eNone; + } + + aos::Error ApplyCert( + const aos::String& certType, const aos::String& pemCert, aos::iam::certhandler::CertInfo& certInfo) override + { + mCertType = certType; + mCert = pemCert; + certInfo = mCertInfo; + + return aos::ErrorEnum::eNone; + } + + aos::Error GetCert(const aos::String& certType, const aos::Array& issuer, + const aos::Array& serial, aos::iam::certhandler::CertInfo& resCert) override + { + return aos::ErrorEnum::eNone; + } + + aos::Error FinishProvisioning(const aos::String& password) override + { + mPassword = password; + + return aos::ErrorEnum::eNone; + } + + aos::Error Deprovision(const aos::String& password) override + { + mPassword = password; + + return aos::ErrorEnum::eNone; + } + + aos::String GetPassword() const { return mPassword; } + aos::String GetCertType() const { return mCertType; } + aos::String GetSubject() const { return mSubject; } + aos::String GetCSR() const { return mCSR; } + aos::String GetCert() const { return mCert; } + + void SetCSR(const aos::String& csr) { mCSR = csr; } + void SetCertTypes(const aos::iam::provisionmanager::CertTypes& certTypes) { mCertTypes = certTypes; } + void SetCertInfo(const aos::iam::certhandler::CertInfo& certInfo) { mCertInfo = certInfo; } + +private: + aos::StaticString mPassword; + aos::iam::provisionmanager::CertTypes mCertTypes; + aos::StaticString mCertType; + aos::StaticString mSubject; + aos::StaticString mCSR; + aos::StaticString mCert; + aos::iam::certhandler::CertInfo mCertInfo; +}; + +#endif From 4ee0a3aa8aeaae183f8b8f3d22d103ec990f41ef Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sat, 17 Aug 2024 14:56:03 +0300 Subject: [PATCH 060/198] [iamclient] Implement pause/resume node Signed-off-by: Oleksandr Grytsov --- src/iamclient/iamclient.cpp | 321 ++++++++++++++---- src/iamclient/iamclient.hpp | 17 +- tests/iamclient/src/main.cpp | 172 ++++++++-- .../src/stubs/nodeinfoproviderstub.hpp | 43 ++- 4 files changed, 459 insertions(+), 94 deletions(-) diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index 21ae0f53..3dd7682b 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -25,7 +25,10 @@ Error IAMClient::Init(clocksync::ClockSyncItf& clockSync, iam::nodeinfoprovider: { LOG_DBG() << "Initialize IAM client"; + mClockSync = &clockSync; + mNodeInfoProvider = &nodeInfoProvider; mProvisionManager = &provisionManager; + mChannelManager = &channelManager; if (auto err = clockSync.Subscribe(*this); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -35,29 +38,25 @@ Error IAMClient::Init(clocksync::ClockSyncItf& clockSync, iam::nodeinfoprovider: return AOS_ERROR_WRAP(err); } - NodeInfo nodeInfo; - - if (auto err = nodeInfoProvider.GetNodeInfo(nodeInfo); !err.IsNone()) { + if (auto err = mNodeInfoProvider->GetNodeInfo(mNodeInfo); !err.IsNone()) { return AOS_ERROR_WRAP(err); } - mNodeID = nodeInfo.mNodeID; - - if (nodeInfo.mStatus == NodeStatusEnum::eUnprovisioned) { + if (mNodeInfo.mStatus == NodeStatusEnum::eUnprovisioned) { LOG_INF() << "Node is unprovisioned"; + } - auto channel = channelManager.CreateChannel(cOpenPort); - if (!channel.mError.IsNone()) { - return AOS_ERROR_WRAP(channel.mError); - } + auto channel = channelManager.CreateChannel(cOpenPort); + if (!channel.mError.IsNone()) { + return AOS_ERROR_WRAP(channel.mError); + } - if (auto err = PBHandler::Init("IAM open", *channel.mValue); !err.IsNone()) { - return AOS_ERROR_WRAP(err); - } + if (auto err = PBHandler::Init("IAM open", *channel.mValue); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } - if (auto err = Start(); !err.IsNone()) { - return AOS_ERROR_WRAP(err); - } + if (auto err = Start(); !err.IsNone()) { + return AOS_ERROR_WRAP(err); } return ErrorEnum::eNone; @@ -73,12 +72,45 @@ void IAMClient::OnClockUnsynced() Error IAMClient::OnNodeStatusChanged(const String& nodeID, const NodeStatus& status) { + LOG_DBG() << "Node status changed: nodeID=" << nodeID << ", status=" << status; + + if (nodeID != mNodeInfo.mNodeID) { + LOG_ERR() << "Wrong node ID: nodeID=" << nodeID; + } + + if (mNodeInfo.mStatus == status) { + return ErrorEnum::eNone; + } + + auto sendNodeInfo = true; + + if (mNodeInfo.mStatus == NodeStatusEnum::eUnprovisioned || status == NodeStatusEnum::eUnprovisioned) { + sendNodeInfo = false; + } + + mNodeInfo.mStatus = status; + + if (sendNodeInfo) { + if (auto err = SendNodeInfo(); !err.IsNone()) { + return err; + } + } + return ErrorEnum::eNone; } IAMClient::~IAMClient() { - Stop(); + if (auto err = Stop(); !err.IsNone()) { + LOG_ERR() << "Can't stop IAM handler: err=" << err; + } + + if (auto err = mChannelManager->DeleteChannel(cOpenPort); !err.IsNone()) { + LOG_ERR() << "Can't delete IAM open channel: err=" << err; + } + + mClockSync->Unsubscribe(*this); + mNodeInfoProvider->UnsubscribeNodeStatusChanged(*this); } /*********************************************************************************************************************** @@ -95,41 +127,52 @@ void IAMClient::OnDisconnect() Error IAMClient::ReceiveMessage(const Array& data) { - auto stream = pb_istream_from_buffer(data.Get(), data.Size()); + LockGuard lock {mMutex}; - if (auto status = pb_decode(&stream, &iamanager_v5_IAMIncomingMessages_msg, &mIncomingMessages); !status) { + auto incomingMessages = MakeUnique(&mAllocator); + auto stream = pb_istream_from_buffer(data.Get(), data.Size()); + + if (auto status = pb_decode(&stream, &iamanager_v5_IAMIncomingMessages_msg, incomingMessages.Get()); !status) { return AOS_ERROR_WRAP(Error(ErrorEnum::eRuntime, "failed to decode message")); } Error err; - switch (mIncomingMessages.which_IAMIncomingMessage) { + switch (incomingMessages->which_IAMIncomingMessage) { case iamanager_v5_IAMIncomingMessages_start_provisioning_request_tag: - err = ProcessStartProvisioning(mIncomingMessages.IAMIncomingMessage.start_provisioning_request); + err = ProcessStartProvisioning(incomingMessages->IAMIncomingMessage.start_provisioning_request); break; case iamanager_v5_IAMIncomingMessages_finish_provisioning_request_tag: - err = ProcessFinishProvisioning(mIncomingMessages.IAMIncomingMessage.finish_provisioning_request); + err = ProcessFinishProvisioning(incomingMessages->IAMIncomingMessage.finish_provisioning_request); break; case iamanager_v5_IAMIncomingMessages_deprovision_request_tag: - err = ProcessDeprovision(mIncomingMessages.IAMIncomingMessage.deprovision_request); + err = ProcessDeprovision(incomingMessages->IAMIncomingMessage.deprovision_request); break; case iamanager_v5_IAMIncomingMessages_get_cert_types_request_tag: - err = ProcessGetCertTypes(mIncomingMessages.IAMIncomingMessage.get_cert_types_request); + err = ProcessGetCertTypes(incomingMessages->IAMIncomingMessage.get_cert_types_request); break; case iamanager_v5_IAMIncomingMessages_create_key_request_tag: - err = ProcessCreateKey(mIncomingMessages.IAMIncomingMessage.create_key_request); + err = ProcessCreateKey(incomingMessages->IAMIncomingMessage.create_key_request); break; case iamanager_v5_IAMIncomingMessages_apply_cert_request_tag: - err = ProcessApplyCert(mIncomingMessages.IAMIncomingMessage.apply_cert_request); + err = ProcessApplyCert(incomingMessages->IAMIncomingMessage.apply_cert_request); + break; + + case iamanager_v5_IAMIncomingMessages_pause_node_request_tag: + err = ProcessPauseNode(incomingMessages->IAMIncomingMessage.pause_node_request); + break; + + case iamanager_v5_IAMIncomingMessages_resume_node_request_tag: + err = ProcessResumeNode(incomingMessages->IAMIncomingMessage.resume_node_request); break; default: - LOG_WRN() << "Receive unsupported message: tag=" << mIncomingMessages.which_IAMIncomingMessage; + LOG_WRN() << "Receive unsupported message: tag=" << incomingMessages->which_IAMIncomingMessage; break; } @@ -137,89 +180,179 @@ Error IAMClient::ReceiveMessage(const Array& data) } template -Error IAMClient::SendError(const Error& err, T& pbMessage) +Error IAMClient::SendError(const void* message, T& pbMessage, const Error& err) { LOG_ERR() << "Process message error: err=" << err; utils::ErrorToPB(err, pbMessage); - return SendMessage(&mOutgoingMessages, &iamanager_v5_IAMOutgoingMessages_msg); + return SendMessage(message, &iamanager_v5_IAMOutgoingMessages_msg); +} + +Error IAMClient::CheckNodeIDAndStatus(const String& nodeID, const Array& expectedStatuses) +{ + if (nodeID != mNodeInfo.mNodeID) { + return Error(ErrorEnum::eInvalidArgument, "wrong node ID"); + } + + if (auto [_, err] = expectedStatuses.Find(mNodeInfo.mStatus); !err.IsNone()) { + return Error(ErrorEnum::eWrongState, "wrong node status"); + } + + return ErrorEnum::eNone; +} + +Error IAMClient::SendNodeInfo() +{ + LOG_DBG() << "Send node info: status=" << mNodeInfo.mStatus; + + auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto& pbNodeInfo = outgoingMessage->IAMOutgoingMessage.node_info; + + outgoingMessage->which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_node_info_tag; + pbNodeInfo = iamanager_v5_NodeInfo iamanager_v5_NodeInfo_init_default; + + utils::StringFromCStr(pbNodeInfo.node_id) = mNodeInfo.mNodeID; + utils::StringFromCStr(pbNodeInfo.node_type) = mNodeInfo.mNodeType; + utils::StringFromCStr(pbNodeInfo.name) = mNodeInfo.mName; + utils::StringFromCStr(pbNodeInfo.status) = mNodeInfo.mStatus.ToString(); + utils::StringFromCStr(pbNodeInfo.os_type) = mNodeInfo.mOSType; + pbNodeInfo.max_dmips = mNodeInfo.mMaxDMIPS; + pbNodeInfo.total_ram = mNodeInfo.mTotalRAM; + + pbNodeInfo.cpus_count = mNodeInfo.mCPUs.Size(); + + for (size_t i = 0; i < mNodeInfo.mCPUs.Size(); i++) { + utils::StringFromCStr(pbNodeInfo.cpus[i].model_name) = mNodeInfo.mCPUs[i].mModelName; + pbNodeInfo.cpus[i].num_cores = mNodeInfo.mCPUs[i].mNumCores; + pbNodeInfo.cpus[i].num_threads = mNodeInfo.mCPUs[i].mNumThreads; + utils::StringFromCStr(pbNodeInfo.cpus[i].arch) = mNodeInfo.mCPUs[i].mArch; + utils::StringFromCStr(pbNodeInfo.cpus[i].arch_family) = mNodeInfo.mCPUs[i].mArchFamily; + pbNodeInfo.cpus[i].max_dmips = mNodeInfo.mCPUs[i].mMaxDMIPS; + } + + pbNodeInfo.partitions_count = mNodeInfo.mPartitions.Size(); + + for (size_t i = 0; i < mNodeInfo.mPartitions.Size(); i++) { + utils::StringFromCStr(pbNodeInfo.partitions[i].name) = mNodeInfo.mPartitions[i].mName; + pbNodeInfo.partitions[i].total_size = mNodeInfo.mPartitions[i].mTotalSize; + utils::StringFromCStr(pbNodeInfo.partitions[i].path) = mNodeInfo.mPartitions[i].mPath; + + pbNodeInfo.partitions[i].types_count = mNodeInfo.mPartitions[i].mTypes.Size(); + + for (size_t j = 0; j < mNodeInfo.mPartitions[i].mTypes.Size(); j++) { + utils::StringFromCStr(pbNodeInfo.partitions[i].types[j]) = mNodeInfo.mPartitions[i].mTypes[j]; + } + } + + pbNodeInfo.attrs_count = mNodeInfo.mAttrs.Size(); + + for (size_t i = 0; i < mNodeInfo.mAttrs.Size(); i++) { + utils::StringFromCStr(pbNodeInfo.attrs[i].name) = mNodeInfo.mAttrs[i].mName; + utils::StringFromCStr(pbNodeInfo.attrs[i].value) = mNodeInfo.mAttrs[i].mValue; + } + + return SendMessage(outgoingMessage.Get(), &iamanager_v5_IAMOutgoingMessages_msg); } Error IAMClient::ProcessStartProvisioning(const iamanager_v5_StartProvisioningRequest& pbStartProvisioningRequest) { LOG_INF() << "Process start provisioning request"; - auto& pbStartProvisionResponse = mOutgoingMessages.IAMOutgoingMessage.start_provisioning_response; + auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto& pbStartProvisionResponse = outgoingMessage->IAMOutgoingMessage.start_provisioning_response; - mOutgoingMessages.which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_start_provisioning_response_tag; + outgoingMessage->which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_start_provisioning_response_tag; pbStartProvisionResponse = iamanager_v5_StartProvisioningResponse iamanager_v5_StartProvisioningResponse_init_default; - if (pbStartProvisioningRequest.node_id != mNodeID) { - return SendError(AOS_ERROR_WRAP(Error(ErrorEnum::eInvalidArgument, "wrong node ID")), pbStartProvisionResponse); + NodeStatus expectedStatuses[] {NodeStatusEnum::eUnprovisioned}; + + if (auto err = CheckNodeIDAndStatus(pbStartProvisioningRequest.node_id, utils::ToArray(expectedStatuses)); + !err.IsNone()) { + return SendError(outgoingMessage.Get(), pbStartProvisionResponse, AOS_ERROR_WRAP(err)); } if (auto err = mProvisionManager->StartProvisioning(pbStartProvisioningRequest.password); !err.IsNone()) { - return SendError(err, pbStartProvisionResponse); + return SendError(outgoingMessage.Get(), pbStartProvisionResponse, AOS_ERROR_WRAP(err)); } - return SendMessage(&mOutgoingMessages, &iamanager_v5_IAMOutgoingMessages_msg); + return SendMessage(outgoingMessage.Get(), &iamanager_v5_IAMOutgoingMessages_msg); } Error IAMClient::ProcessFinishProvisioning(const iamanager_v5_FinishProvisioningRequest& pbFinishProvisioningRequest) { LOG_INF() << "Process finish provisioning request"; - auto& pbFinishProvisionResponse = mOutgoingMessages.IAMOutgoingMessage.finish_provisioning_response; + auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto& pbFinishProvisionResponse = outgoingMessage->IAMOutgoingMessage.finish_provisioning_response; - mOutgoingMessages.which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_finish_provisioning_response_tag; + outgoingMessage->which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_finish_provisioning_response_tag; pbFinishProvisionResponse = iamanager_v5_FinishProvisioningResponse iamanager_v5_FinishProvisioningResponse_init_default; - if (pbFinishProvisioningRequest.node_id != mNodeID) { - return SendError( - AOS_ERROR_WRAP(Error(ErrorEnum::eInvalidArgument, "wrong node ID")), pbFinishProvisionResponse); + NodeStatus expectedStatuses[] {NodeStatusEnum::eUnprovisioned}; + + if (auto err = CheckNodeIDAndStatus(pbFinishProvisioningRequest.node_id, utils::ToArray(expectedStatuses)); + !err.IsNone()) { + return SendError(outgoingMessage.Get(), pbFinishProvisionResponse, AOS_ERROR_WRAP(err)); } if (auto err = mProvisionManager->FinishProvisioning(pbFinishProvisioningRequest.password); !err.IsNone()) { - return SendError(err, pbFinishProvisionResponse); + return SendError(outgoingMessage.Get(), pbFinishProvisionResponse, AOS_ERROR_WRAP(err)); + } + + if (auto err = mNodeInfoProvider->SetNodeStatus(NodeStatusEnum::eProvisioned); !err.IsNone()) { + return SendError(outgoingMessage.Get(), pbFinishProvisionResponse, AOS_ERROR_WRAP(err)); } - return SendMessage(&mOutgoingMessages, &iamanager_v5_IAMOutgoingMessages_msg); + return SendMessage(outgoingMessage.Get(), &iamanager_v5_IAMOutgoingMessages_msg); } Error IAMClient::ProcessDeprovision(const iamanager_v5_DeprovisionRequest& pbDeprovisionRequest) { LOG_INF() << "Process deprovision request"; - auto& pbDeprovisionResponse = mOutgoingMessages.IAMOutgoingMessage.deprovision_response; + auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto& pbDeprovisionResponse = outgoingMessage->IAMOutgoingMessage.deprovision_response; - mOutgoingMessages.which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_deprovision_response_tag; + outgoingMessage->which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_deprovision_response_tag; pbDeprovisionResponse = iamanager_v5_DeprovisionResponse iamanager_v5_DeprovisionResponse_init_default; - if (pbDeprovisionRequest.node_id != mNodeID) { - return SendError(AOS_ERROR_WRAP(Error(ErrorEnum::eInvalidArgument, "wrong node ID")), pbDeprovisionResponse); + NodeStatus expectedStatuses[] {NodeStatusEnum::eProvisioned, NodeStatusEnum::ePaused}; + + if (auto err = CheckNodeIDAndStatus(pbDeprovisionRequest.node_id, utils::ToArray(expectedStatuses)); + !err.IsNone()) { + return SendError(outgoingMessage.Get(), pbDeprovisionResponse, AOS_ERROR_WRAP(err)); } if (auto err = mProvisionManager->Deprovision(pbDeprovisionRequest.password); !err.IsNone()) { - return SendError(err, pbDeprovisionResponse); + return SendError(outgoingMessage.Get(), pbDeprovisionResponse, AOS_ERROR_WRAP(err)); } - return SendMessage(&mOutgoingMessages, &iamanager_v5_IAMOutgoingMessages_msg); + if (auto err = mNodeInfoProvider->SetNodeStatus(NodeStatusEnum::eUnprovisioned); !err.IsNone()) { + return SendError(outgoingMessage.Get(), pbDeprovisionResponse, AOS_ERROR_WRAP(err)); + } + + return SendMessage(outgoingMessage.Get(), &iamanager_v5_IAMOutgoingMessages_msg); } Error IAMClient::ProcessGetCertTypes(const iamanager_v5_GetCertTypesRequest& pbGetCertTypesRequest) { LOG_INF() << "Process get cert types"; - auto& pbGetCertTypesResponse = mOutgoingMessages.IAMOutgoingMessage.cert_types_response; + auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto& pbGetCertTypesResponse = outgoingMessage->IAMOutgoingMessage.cert_types_response; + + outgoingMessage->which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_cert_types_response_tag; + pbGetCertTypesResponse = iamanager_v5_CertTypes iamanager_v5_CertTypes_init_default; - mOutgoingMessages.which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_cert_types_response_tag; - pbGetCertTypesResponse = iamanager_v5_CertTypes iamanager_v5_CertTypes_init_default; + NodeStatus expectedStatuses[] { + NodeStatusEnum::eUnprovisioned, NodeStatusEnum::eProvisioned, NodeStatusEnum::ePaused}; - if (pbGetCertTypesRequest.node_id != mNodeID) { - LOG_ERR() << "Wrong node ID: " << pbGetCertTypesRequest.node_id; + if (auto err = CheckNodeIDAndStatus(pbGetCertTypesRequest.node_id, utils::ToArray(expectedStatuses)); + !err.IsNone()) { + LOG_ERR() << "Wrong get cert types condition: err=" << err; } auto certTypes = mProvisionManager->GetCertTypes(); @@ -233,20 +366,24 @@ Error IAMClient::ProcessGetCertTypes(const iamanager_v5_GetCertTypesRequest& pbG utils::StringFromCStr(pbGetCertTypesResponse.types[i]) = certTypes.mValue[i]; } - return SendMessage(&mOutgoingMessages, &iamanager_v5_IAMOutgoingMessages_msg); + return SendMessage(outgoingMessage.Get(), &iamanager_v5_IAMOutgoingMessages_msg); } Error IAMClient::ProcessCreateKey(const iamanager_v5_CreateKeyRequest& pbCreateKeyRequest) { LOG_INF() << "Process create key: type=" << pbCreateKeyRequest.type << ", subject=" << pbCreateKeyRequest.subject; - auto& pbCreateKeyResponse = mOutgoingMessages.IAMOutgoingMessage.create_key_response; + auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto& pbCreateKeyResponse = outgoingMessage->IAMOutgoingMessage.create_key_response; - mOutgoingMessages.which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_create_key_response_tag; + outgoingMessage->which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_create_key_response_tag; pbCreateKeyResponse = iamanager_v5_CreateKeyResponse iamanager_v5_CreateKeyResponse_init_default; - if (pbCreateKeyRequest.node_id != mNodeID) { - return SendError(AOS_ERROR_WRAP(Error(ErrorEnum::eInvalidArgument, "wrong node ID")), pbCreateKeyResponse); + NodeStatus expectedStatuses[] { + NodeStatusEnum::eUnprovisioned, NodeStatusEnum::eProvisioned, NodeStatusEnum::ePaused}; + + if (auto err = CheckNodeIDAndStatus(pbCreateKeyRequest.node_id, utils::ToArray(expectedStatuses)); !err.IsNone()) { + return SendError(outgoingMessage.Get(), pbCreateKeyResponse, AOS_ERROR_WRAP(err)); } auto csr = utils::StringFromCStr(pbCreateKeyResponse.csr); @@ -254,42 +391,92 @@ Error IAMClient::ProcessCreateKey(const iamanager_v5_CreateKeyRequest& pbCreateK if (auto err = mProvisionManager->CreateKey( pbCreateKeyRequest.type, pbCreateKeyRequest.subject, pbCreateKeyRequest.password, csr); !err.IsNone()) { - return SendError(err, pbCreateKeyResponse); + return SendError(outgoingMessage.Get(), pbCreateKeyResponse, AOS_ERROR_WRAP(err)); } utils::StringFromCStr(pbCreateKeyResponse.type) = pbCreateKeyRequest.type; - return SendMessage(&mOutgoingMessages, &iamanager_v5_IAMOutgoingMessages_msg); + return SendMessage(outgoingMessage.Get(), &iamanager_v5_IAMOutgoingMessages_msg); } Error IAMClient::ProcessApplyCert(const iamanager_v5_ApplyCertRequest& pbApplyCertRequest) { LOG_INF() << "Process apply cert: type=" << pbApplyCertRequest.type; - auto& pbApplyCertResponse = mOutgoingMessages.IAMOutgoingMessage.apply_cert_response; + auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto& pbApplyCertResponse = outgoingMessage->IAMOutgoingMessage.apply_cert_response; - mOutgoingMessages.which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_apply_cert_response_tag; + outgoingMessage->which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_apply_cert_response_tag; pbApplyCertResponse = iamanager_v5_ApplyCertResponse iamanager_v5_ApplyCertResponse_init_default; - if (pbApplyCertRequest.node_id != mNodeID) { - return SendError(AOS_ERROR_WRAP(Error(ErrorEnum::eInvalidArgument, "wrong node ID")), pbApplyCertResponse); + NodeStatus expectedStatuses[] { + NodeStatusEnum::eUnprovisioned, NodeStatusEnum::eProvisioned, NodeStatusEnum::ePaused}; + + if (auto err = CheckNodeIDAndStatus(pbApplyCertRequest.node_id, utils::ToArray(expectedStatuses)); !err.IsNone()) { + return SendError(outgoingMessage.Get(), pbApplyCertResponse, AOS_ERROR_WRAP(err)); } iam::certhandler::CertInfo certInfo {}; if (auto err = mProvisionManager->ApplyCert(pbApplyCertRequest.type, pbApplyCertRequest.cert, certInfo); !err.IsNone()) { - return SendError(err, pbApplyCertResponse); + return SendError(outgoingMessage.Get(), pbApplyCertResponse, AOS_ERROR_WRAP(err)); } utils::StringFromCStr(pbApplyCertResponse.type) = pbApplyCertRequest.type; utils::StringFromCStr(pbApplyCertResponse.cert_url) = certInfo.mCertURL; if (auto err = utils::StringFromCStr(pbApplyCertResponse.serial).ByteArrayToHex(certInfo.mSerial); !err.IsNone()) { - return SendError(err, pbApplyCertResponse); + return SendError(outgoingMessage.Get(), pbApplyCertResponse, AOS_ERROR_WRAP(err)); + } + + return SendMessage(outgoingMessage.Get(), &iamanager_v5_IAMOutgoingMessages_msg); +} + +Error IAMClient::ProcessPauseNode(const iamanager_v5_PauseNodeRequest& pbPauseNodeRequest) +{ + LOG_INF() << "Process pause node request"; + + auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto& pbPauseNodeResponse = outgoingMessage->IAMOutgoingMessage.pause_node_response; + + outgoingMessage->which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_pause_node_response_tag; + pbPauseNodeResponse = iamanager_v5_PauseNodeResponse iamanager_v5_PauseNodeResponse_init_default; + + NodeStatus expectedStatuses[] {NodeStatusEnum::eProvisioned}; + + if (auto err = CheckNodeIDAndStatus(pbPauseNodeRequest.node_id, utils::ToArray(expectedStatuses)); !err.IsNone()) { + return SendError(outgoingMessage.Get(), pbPauseNodeResponse, AOS_ERROR_WRAP(err)); + } + + if (auto err = mNodeInfoProvider->SetNodeStatus(NodeStatusEnum::ePaused); !err.IsNone()) { + return SendError(outgoingMessage.Get(), pbPauseNodeResponse, AOS_ERROR_WRAP(err)); + } + + return SendMessage(outgoingMessage.Get(), &iamanager_v5_IAMOutgoingMessages_msg); +} + +Error IAMClient::ProcessResumeNode(const iamanager_v5_ResumeNodeRequest& pbResumeNodeRequest) +{ + LOG_INF() << "Process resume node request"; + + auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto& pbResumeNodeResponse = outgoingMessage->IAMOutgoingMessage.resume_node_response; + + outgoingMessage->which_IAMOutgoingMessage = iamanager_v5_IAMOutgoingMessages_resume_node_response_tag; + pbResumeNodeResponse = iamanager_v5_ResumeNodeResponse iamanager_v5_ResumeNodeResponse_init_default; + + NodeStatus expectedStatuses[] {NodeStatusEnum::ePaused}; + + if (auto err = CheckNodeIDAndStatus(pbResumeNodeRequest.node_id, utils::ToArray(expectedStatuses)); !err.IsNone()) { + return SendError(outgoingMessage.Get(), pbResumeNodeResponse, AOS_ERROR_WRAP(err)); + } + + if (auto err = mNodeInfoProvider->SetNodeStatus(NodeStatusEnum::eProvisioned); !err.IsNone()) { + return SendError(outgoingMessage.Get(), pbResumeNodeResponse, AOS_ERROR_WRAP(err)); } - return SendMessage(&mOutgoingMessages, &iamanager_v5_IAMOutgoingMessages_msg); + return SendMessage(outgoingMessage.Get(), &iamanager_v5_IAMOutgoingMessages_msg); } } // namespace aos::zephyr::iamclient diff --git a/src/iamclient/iamclient.hpp b/src/iamclient/iamclient.hpp index 70b11862..02bac63e 100644 --- a/src/iamclient/iamclient.hpp +++ b/src/iamclient/iamclient.hpp @@ -8,6 +8,7 @@ #ifndef IAMCLIENT_HPP_ #define IAMCLIENT_HPP_ +#include #include #include @@ -73,19 +74,27 @@ class IAMClient Error ReceiveMessage(const Array& data) override; template - Error SendError(const Error& err, T& pbMessage); + Error SendError(const void* message, T& pbMessage, const Error& err); + Error SendNodeInfo(); + Error CheckNodeIDAndStatus(const String& nodeID, const Array& expectedStatuses); Error ProcessStartProvisioning(const iamanager_v5_StartProvisioningRequest& pbStartProvisioningRequest); Error ProcessFinishProvisioning(const iamanager_v5_FinishProvisioningRequest& pbFinishProvisioningRequest); Error ProcessDeprovision(const iamanager_v5_DeprovisionRequest& pbDeprovisionRequest); + Error ProcessPauseNode(const iamanager_v5_PauseNodeRequest& pbPauseNodeRequest); + Error ProcessResumeNode(const iamanager_v5_ResumeNodeRequest& pbResumeNodeRequest); Error ProcessGetCertTypes(const iamanager_v5_GetCertTypesRequest& pbGetCertTypesRequest); Error ProcessCreateKey(const iamanager_v5_CreateKeyRequest& pbCreateKeyRequest); Error ProcessApplyCert(const iamanager_v5_ApplyCertRequest& pbApplyCertRequest); + clocksync::ClockSyncItf* mClockSync {}; + iam::nodeinfoprovider::NodeInfoProviderItf* mNodeInfoProvider {}; iam::provisionmanager::ProvisionManagerItf* mProvisionManager {}; + communication::ChannelManagerItf* mChannelManager {}; - StaticString mNodeID; - iamanager_v5_IAMOutgoingMessages mOutgoingMessages; - iamanager_v5_IAMIncomingMessages mIncomingMessages; + NodeInfo mNodeInfo; + Mutex mMutex; + + StaticAllocator mAllocator; }; } // namespace aos::zephyr::iamclient diff --git a/tests/iamclient/src/main.cpp b/tests/iamclient/src/main.cpp index 495f6877..962581ad 100644 --- a/tests/iamclient/src/main.cpp +++ b/tests/iamclient/src/main.cpp @@ -5,6 +5,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + #include #include @@ -27,18 +29,16 @@ using namespace aos::zephyr; static constexpr auto cWaitTimeout = std::chrono::seconds {5}; -static aos::NodeInfo sNodeInfo = {.mNodeID = "node0"}; - /*********************************************************************************************************************** * Types **********************************************************************************************************************/ struct iamclient_fixture { - ClockSyncStub mClockSync; - NodeInfoProviderStub mNodeInfoProvider; - ProvisionManagerStub mProvisionManager; - ChannelManagerStub mChannelManager; - iamclient::IAMClient mIAMClient; + ClockSyncStub mClockSync; + NodeInfoProviderStub mNodeInfoProvider; + ProvisionManagerStub mProvisionManager; + ChannelManagerStub mChannelManager; + std::unique_ptr mIAMClient; }; /*********************************************************************************************************************** @@ -57,6 +57,32 @@ static aos::Error SendIAMIncomingMessage(ChannelStub* channel, const iamanager_v channel, &message, iamanager_v5_IAMIncomingMessages_size, &iamanager_v5_IAMIncomingMessages_msg); } +static void InitIAMClient(iamclient_fixture* fixture, const aos::NodeInfo& nodeInfo) +{ + fixture->mNodeInfoProvider.SetNodeInfo(nodeInfo); + + auto err = fixture->mIAMClient->Init( + fixture->mClockSync, fixture->mNodeInfoProvider, fixture->mProvisionManager, fixture->mChannelManager); + zassert_true(err.IsNone(), "Can't initialize IAM client: %s", utils::ErrorToCStr(err)); +} + +static void ReceiveNodeInfo(ChannelStub* channel, const aos::NodeInfo& nodeInfo) +{ + iamanager_v5_IAMOutgoingMessages outgoingMessage; + auto& pbNodeInfo = outgoingMessage.IAMOutgoingMessage.node_info; + + pbNodeInfo = iamanager_v5_NodeInfo iamanager_v5_NodeInfo_init_default; + + auto err = ReceiveIAMOutgoingMessage(channel, outgoingMessage); + zassert_true(err.IsNone(), "Error receiving message: %s", utils::ErrorToCStr(err)); + + zassert_equal(outgoingMessage.which_IAMOutgoingMessage, iamanager_v5_IAMOutgoingMessages_node_info_tag, + "Unexpected message type"); + zassert_false(pbNodeInfo.has_error, "Unexpected error received"); + zassert_equal(pbNodeInfo.node_id, nodeInfo.mNodeID, "Wrong node ID"); + zassert_equal(pbNodeInfo.status, nodeInfo.mStatus.ToString(), "Wrong node status"); +} + /*********************************************************************************************************************** * Setup **********************************************************************************************************************/ @@ -68,16 +94,10 @@ ZTEST_SUITE( auto fixture = new iamclient_fixture; - fixture->mNodeInfoProvider.SetNodeInfo(sNodeInfo); - - auto err = fixture->mIAMClient.Init( - fixture->mClockSync, fixture->mNodeInfoProvider, fixture->mProvisionManager, fixture->mChannelManager); - - zassert_true(err.IsNone(), "Can't initialize SM client: %s", utils::ErrorToCStr(err)); - return fixture; }, - nullptr, nullptr, [](void* fixture) { delete static_cast(fixture); }); + [](void* fixture) { static_cast(fixture)->mIAMClient.reset(new iamclient::IAMClient); }, + nullptr, [](void* fixture) { delete static_cast(fixture); }); /*********************************************************************************************************************** * Tests @@ -85,6 +105,10 @@ ZTEST_SUITE( ZTEST_F(iamclient, test_StartProvisioning) { + aos::NodeInfo nodeInfo = {.mNodeID = "node1", .mStatus = aos::NodeStatusEnum::eUnprovisioned}; + + InitIAMClient(fixture, nodeInfo); + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); @@ -97,7 +121,7 @@ ZTEST_F(iamclient, test_StartProvisioning) pbStartProvisioningRequest = iamanager_v5_StartProvisioningRequest iamanager_v5_StartProvisioningRequest_init_default; - utils::StringFromCStr(pbStartProvisioningRequest.node_id) = sNodeInfo.mNodeID; + utils::StringFromCStr(pbStartProvisioningRequest.node_id) = nodeInfo.mNodeID; utils::StringFromCStr(pbStartProvisioningRequest.password) = "12345"; err = SendIAMIncomingMessage(channel, incomingMessage); @@ -123,6 +147,10 @@ ZTEST_F(iamclient, test_StartProvisioning) ZTEST_F(iamclient, test_FinishProvisioning) { + aos::NodeInfo nodeInfo = {.mNodeID = "node1", .mStatus = aos::NodeStatusEnum::eUnprovisioned}; + + InitIAMClient(fixture, nodeInfo); + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); @@ -135,7 +163,7 @@ ZTEST_F(iamclient, test_FinishProvisioning) pbFinishProvisioningRequest = iamanager_v5_FinishProvisioningRequest iamanager_v5_FinishProvisioningRequest_init_default; - utils::StringFromCStr(pbFinishProvisioningRequest.node_id) = sNodeInfo.mNodeID; + utils::StringFromCStr(pbFinishProvisioningRequest.node_id) = nodeInfo.mNodeID; utils::StringFromCStr(pbFinishProvisioningRequest.password) = "ABCDEF"; err = SendIAMIncomingMessage(channel, incomingMessage); @@ -161,6 +189,10 @@ ZTEST_F(iamclient, test_FinishProvisioning) ZTEST_F(iamclient, test_Deprovision) { + aos::NodeInfo nodeInfo = {.mNodeID = "node1", .mStatus = aos::NodeStatusEnum::eProvisioned}; + + InitIAMClient(fixture, nodeInfo); + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); @@ -172,7 +204,7 @@ ZTEST_F(iamclient, test_Deprovision) incomingMessage.which_IAMIncomingMessage = iamanager_v5_IAMIncomingMessages_deprovision_request_tag; pbDeprovisionRequest = iamanager_v5_DeprovisionRequest iamanager_v5_DeprovisionRequest_init_default; - utils::StringFromCStr(pbDeprovisionRequest.node_id) = sNodeInfo.mNodeID; + utils::StringFromCStr(pbDeprovisionRequest.node_id) = nodeInfo.mNodeID; utils::StringFromCStr(pbDeprovisionRequest.password) = "FEDCBA"; err = SendIAMIncomingMessage(channel, incomingMessage); @@ -198,6 +230,10 @@ ZTEST_F(iamclient, test_Deprovision) ZTEST_F(iamclient, test_GetCertTypes) { + aos::NodeInfo nodeInfo = {.mNodeID = "node1", .mStatus = aos::NodeStatusEnum::eUnprovisioned}; + + InitIAMClient(fixture, nodeInfo); + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); @@ -216,7 +252,7 @@ ZTEST_F(iamclient, test_GetCertTypes) incomingMessage.which_IAMIncomingMessage = iamanager_v5_IAMIncomingMessages_get_cert_types_request_tag; pbGetCertTypesRequest = iamanager_v5_GetCertTypesRequest iamanager_v5_GetCertTypesRequest_init_default; - utils::StringFromCStr(pbGetCertTypesRequest.node_id) = sNodeInfo.mNodeID; + utils::StringFromCStr(pbGetCertTypesRequest.node_id) = nodeInfo.mNodeID; err = SendIAMIncomingMessage(channel, incomingMessage); zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); @@ -242,6 +278,10 @@ ZTEST_F(iamclient, test_GetCertTypes) ZTEST_F(iamclient, test_CreateKey) { + aos::NodeInfo nodeInfo = {.mNodeID = "node1", .mStatus = aos::NodeStatusEnum::eUnprovisioned}; + + InitIAMClient(fixture, nodeInfo); + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); @@ -255,7 +295,7 @@ ZTEST_F(iamclient, test_CreateKey) incomingMessage.which_IAMIncomingMessage = iamanager_v5_IAMIncomingMessages_create_key_request_tag; pbCreateKeyRequest = iamanager_v5_CreateKeyRequest iamanager_v5_CreateKeyRequest_init_default; - utils::StringFromCStr(pbCreateKeyRequest.node_id) = sNodeInfo.mNodeID; + utils::StringFromCStr(pbCreateKeyRequest.node_id) = nodeInfo.mNodeID; utils::StringFromCStr(pbCreateKeyRequest.type) = "certType1"; utils::StringFromCStr(pbCreateKeyRequest.subject) = "subject1"; utils::StringFromCStr(pbCreateKeyRequest.password) = "54321"; @@ -286,6 +326,10 @@ ZTEST_F(iamclient, test_CreateKey) ZTEST_F(iamclient, test_ApplyCert) { + aos::NodeInfo nodeInfo = {.mNodeID = "node1", .mStatus = aos::NodeStatusEnum::eUnprovisioned}; + + InitIAMClient(fixture, nodeInfo); + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); @@ -306,7 +350,7 @@ ZTEST_F(iamclient, test_ApplyCert) incomingMessage.which_IAMIncomingMessage = iamanager_v5_IAMIncomingMessages_apply_cert_request_tag; pbApplyCertRequest = iamanager_v5_ApplyCertRequest iamanager_v5_ApplyCertRequest_init_default; - utils::StringFromCStr(pbApplyCertRequest.node_id) = sNodeInfo.mNodeID; + utils::StringFromCStr(pbApplyCertRequest.node_id) = nodeInfo.mNodeID; utils::StringFromCStr(pbApplyCertRequest.type) = "certType2"; utils::StringFromCStr(pbApplyCertRequest.cert) = "cert1"; @@ -330,3 +374,89 @@ ZTEST_F(iamclient, test_ApplyCert) zassert_equal(pbApplyCertResponse.cert_url, certInfo.mCertURL, "Wrong cert URL"); zassert_equal(pbApplyCertResponse.serial, serial, "Wrong serial"); } + +ZTEST_F(iamclient, test_PauseNode) +{ + aos::NodeInfo nodeInfo = {.mNodeID = "node1", .mStatus = aos::NodeStatusEnum::eProvisioned}; + + InitIAMClient(fixture, nodeInfo); + + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Send pause node request + + iamanager_v5_IAMIncomingMessages incomingMessage; + auto& pbPauseNodeRequest = incomingMessage.IAMIncomingMessage.pause_node_request; + + incomingMessage.which_IAMIncomingMessage = iamanager_v5_IAMIncomingMessages_pause_node_request_tag; + pbPauseNodeRequest = iamanager_v5_PauseNodeRequest iamanager_v5_PauseNodeRequest_init_default; + + utils::StringFromCStr(pbPauseNodeRequest.node_id) = nodeInfo.mNodeID; + + err = SendIAMIncomingMessage(channel, incomingMessage); + zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + + // Receive node info + + nodeInfo.mStatus = aos::NodeStatusEnum::ePaused; + + ReceiveNodeInfo(channel, nodeInfo); + + // Receive pause node response + + iamanager_v5_IAMOutgoingMessages outgoingMessage; + auto& pbPauseNodeResponse = outgoingMessage.IAMOutgoingMessage.pause_node_response; + + pbPauseNodeResponse = iamanager_v5_PauseNodeResponse iamanager_v5_PauseNodeResponse_init_default; + + err = ReceiveIAMOutgoingMessage(channel, outgoingMessage); + zassert_true(err.IsNone(), "Error receiving message: %s", utils::ErrorToCStr(err)); + + zassert_equal(outgoingMessage.which_IAMOutgoingMessage, iamanager_v5_IAMOutgoingMessages_pause_node_response_tag, + "Unexpected message type"); + zassert_false(pbPauseNodeResponse.has_error, "Unexpected error received"); +} + +ZTEST_F(iamclient, test_ResumeNode) +{ + aos::NodeInfo nodeInfo = {.mNodeID = "node1", .mStatus = aos::NodeStatusEnum::ePaused}; + + InitIAMClient(fixture, nodeInfo); + + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Send resume node request + + iamanager_v5_IAMIncomingMessages incomingMessage; + auto& pbResumeNodeRequest = incomingMessage.IAMIncomingMessage.resume_node_request; + + incomingMessage.which_IAMIncomingMessage = iamanager_v5_IAMIncomingMessages_resume_node_request_tag; + pbResumeNodeRequest = iamanager_v5_ResumeNodeRequest iamanager_v5_ResumeNodeRequest_init_default; + + utils::StringFromCStr(pbResumeNodeRequest.node_id) = nodeInfo.mNodeID; + + err = SendIAMIncomingMessage(channel, incomingMessage); + zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + + // Receive node info + + nodeInfo.mStatus = aos::NodeStatusEnum::eProvisioned; + + ReceiveNodeInfo(channel, nodeInfo); + + // Receive resume node response + + iamanager_v5_IAMOutgoingMessages outgoingMessage; + auto& pbResumeNodeResponse = outgoingMessage.IAMOutgoingMessage.resume_node_response; + + pbResumeNodeResponse = iamanager_v5_ResumeNodeResponse iamanager_v5_ResumeNodeResponse_init_default; + + err = ReceiveIAMOutgoingMessage(channel, outgoingMessage); + zassert_true(err.IsNone(), "Error receiving message: %s", utils::ErrorToCStr(err)); + + zassert_equal(outgoingMessage.which_IAMOutgoingMessage, iamanager_v5_IAMOutgoingMessages_resume_node_response_tag, + "Unexpected message type"); + zassert_false(pbResumeNodeResponse.has_error, "Unexpected error received"); +} diff --git a/tests/iamclient/src/stubs/nodeinfoproviderstub.hpp b/tests/iamclient/src/stubs/nodeinfoproviderstub.hpp index 76585f8c..42b72d4f 100644 --- a/tests/iamclient/src/stubs/nodeinfoproviderstub.hpp +++ b/tests/iamclient/src/stubs/nodeinfoproviderstub.hpp @@ -8,33 +8,72 @@ #ifndef NODEINFOPROVIDERSTUB_HPP_ #define NODEINFOPROVIDERSTUB_HPP_ +#include +#include +#include + #include class NodeInfoProviderStub : public aos::iam::nodeinfoprovider::NodeInfoProviderItf { public: aos::Error GetNodeInfo(aos::NodeInfo& nodeInfo) const override { + std::lock_guard lock {mMutex}; + nodeInfo = mNodeInfo; return aos::ErrorEnum::eNone; } - aos::Error SetNodeStatus(const aos::NodeStatus& status) override { return aos::ErrorEnum::eNone; } + aos::Error SetNodeStatus(const aos::NodeStatus& status) override + { + std::lock_guard lock {mMutex}; + + if (mNodeInfo.mStatus == status) { + return aos::ErrorEnum::eNone; + } + + for (auto observer : mObservers) { + observer->OnNodeStatusChanged(mNodeInfo.mNodeID, status); + } + + mNodeInfo.mStatus = status; + + return aos::ErrorEnum::eNone; + } aos::Error SubscribeNodeStatusChanged(aos::iam::nodeinfoprovider::NodeStatusObserverItf& observer) override { + std::lock_guard lock {mMutex}; + + if (std::find(mObservers.begin(), mObservers.end(), &observer) != mObservers.end()) { + return aos::ErrorEnum::eAlreadyExist; + } + + mObservers.push_back(&observer); + return aos::ErrorEnum::eNone; } aos::Error UnsubscribeNodeStatusChanged(aos::iam::nodeinfoprovider::NodeStatusObserverItf& observer) override { + std::lock_guard lock {mMutex}; + + if (std::find(mObservers.begin(), mObservers.end(), &observer) == mObservers.end()) { + return aos::ErrorEnum::eNotFound; + } + + mObservers.erase(std::remove(mObservers.begin(), mObservers.end(), &observer), mObservers.end()); + return aos::ErrorEnum::eNone; } void SetNodeInfo(const aos::NodeInfo& nodeInfo) { mNodeInfo = nodeInfo; } private: - aos::NodeInfo mNodeInfo; + aos::NodeInfo mNodeInfo; + mutable std::mutex mMutex; + std::vector mObservers; }; #endif From c0930575ed6b697d3bde679380b35859f5de3973 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sat, 17 Aug 2024 16:36:52 +0300 Subject: [PATCH 061/198] [iamclient] Implement switching channels on provision/deprovision Signed-off-by: Oleksandr Grytsov --- src/app/app.cpp | 4 +- src/iamclient/iamclient.cpp | 203 ++++++++++++++++++++++++++--- src/iamclient/iamclient.hpp | 42 +++++- tests/iamclient/src/main.cpp | 55 ++++++-- tests/stubs/channelmanagerstub.hpp | 19 ++- 5 files changed, 287 insertions(+), 36 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index 44a57442..a3cf3cd3 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -159,7 +159,9 @@ Error App::InitZephyr() return AOS_ERROR_WRAP(err); } - if (auto err = mIAMClient.Init(mClockSync, mNodeInfoProvider, mProvisionManager, mChannelManager); !err.IsNone()) { + if (auto err + = mIAMClient.Init(mClockSync, mNodeInfoProvider, mProvisionManager, mChannelManager, mCertHandler, mCertLoader); + !err.IsNone()) { return AOS_ERROR_WRAP(err); } diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index 3dd7682b..71c358b5 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -21,7 +21,12 @@ namespace aos::zephyr::iamclient { **********************************************************************************************************************/ Error IAMClient::Init(clocksync::ClockSyncItf& clockSync, iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider, - iam::provisionmanager::ProvisionManagerItf& provisionManager, communication::ChannelManagerItf& channelManager) + iam::provisionmanager::ProvisionManagerItf& provisionManager, communication::ChannelManagerItf& channelManager +#ifndef CONFIG_ZTEST + , + iam::certhandler::CertHandlerItf& certHandler, cryptoutils::CertLoaderItf& certLoader +#endif +) { LOG_DBG() << "Initialize IAM client"; @@ -29,6 +34,10 @@ Error IAMClient::Init(clocksync::ClockSyncItf& clockSync, iam::nodeinfoprovider: mNodeInfoProvider = &nodeInfoProvider; mProvisionManager = &provisionManager; mChannelManager = &channelManager; +#ifndef CONFIG_ZTEST + mCertHandler = &certHandler; + mCertLoader = &certLoader; +#endif if (auto err = clockSync.Subscribe(*this); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -42,21 +51,13 @@ Error IAMClient::Init(clocksync::ClockSyncItf& clockSync, iam::nodeinfoprovider: return AOS_ERROR_WRAP(err); } - if (mNodeInfo.mStatus == NodeStatusEnum::eUnprovisioned) { - LOG_INF() << "Node is unprovisioned"; - } - - auto channel = channelManager.CreateChannel(cOpenPort); - if (!channel.mError.IsNone()) { - return AOS_ERROR_WRAP(channel.mError); - } - - if (auto err = PBHandler::Init("IAM open", *channel.mValue); !err.IsNone()) { + auto err = mThread.Run([this](void*) { HandleChannels(); }); + if (!err.IsNone()) { return AOS_ERROR_WRAP(err); } - if (auto err = Start(); !err.IsNone()) { - return AOS_ERROR_WRAP(err); + if (mNodeInfo.mStatus == NodeStatusEnum::eUnprovisioned) { + LOG_INF() << "Node is unprovisioned"; } return ErrorEnum::eNone; @@ -64,10 +65,22 @@ Error IAMClient::Init(clocksync::ClockSyncItf& clockSync, iam::nodeinfoprovider: void IAMClient::OnClockSynced() { + LockGuard lock {mMutex}; + + LOG_DBG() << "Clock synced"; + + mClockSynced = true; + mCondVar.NotifyOne(); } void IAMClient::OnClockUnsynced() { + LockGuard lock {mMutex}; + + LOG_WRN() << "Clock unsynced"; + + mClockSynced = false; + mCondVar.NotifyOne(); } Error IAMClient::OnNodeStatusChanged(const String& nodeID, const NodeStatus& status) @@ -85,7 +98,9 @@ Error IAMClient::OnNodeStatusChanged(const String& nodeID, const NodeStatus& sta auto sendNodeInfo = true; if (mNodeInfo.mStatus == NodeStatusEnum::eUnprovisioned || status == NodeStatusEnum::eUnprovisioned) { - sendNodeInfo = false; + sendNodeInfo = false; + mSwitchChannel = true; + mCondVar.NotifyOne(); } mNodeInfo.mStatus = status; @@ -105,12 +120,17 @@ IAMClient::~IAMClient() LOG_ERR() << "Can't stop IAM handler: err=" << err; } - if (auto err = mChannelManager->DeleteChannel(cOpenPort); !err.IsNone()) { - LOG_ERR() << "Can't delete IAM open channel: err=" << err; - } - mClockSync->Unsubscribe(*this); mNodeInfoProvider->UnsubscribeNodeStatusChanged(*this); + + { + LockGuard lock {mMutex}; + + mClose = true; + mCondVar.NotifyOne(); + } + + mThread.Join(); } /*********************************************************************************************************************** @@ -119,10 +139,157 @@ IAMClient::~IAMClient() void IAMClient::OnConnect() { + LockGuard lock {mMutex}; + + LOG_DBG() << "Channel connected: port=" << mCurrentPort; + + mConnected = true; + mCondVar.NotifyOne(); } void IAMClient::OnDisconnect() { + LockGuard lock {mMutex}; + + LOG_DBG() << "Channel disconnected: port=" << mCurrentPort; + + mConnected = false; + mCondVar.NotifyOne(); +} + +Error IAMClient::ReleaseChannel() +{ + if (!mCurrentPort) { + return ErrorEnum::eNone; + } + + Error err; + + LOG_DBG() << "Release channel: port=" << mCurrentPort; + + if (auto stopErr = Stop(); !stopErr.IsNone() && err.IsNone()) { + err = AOS_ERROR_WRAP(stopErr); + } + + if (auto deleteErr = mChannelManager->DeleteChannel(mCurrentPort); !deleteErr.IsNone() && err.IsNone()) { + err = AOS_ERROR_WRAP(deleteErr); + } + + return err; +} + +Error IAMClient::SetupChannel() +{ + communication::ChannelItf* channel {}; + Error err; + + if (mNodeInfo.mStatus == NodeStatusEnum::eUnprovisioned) { + LOG_DBG() << "Setup open channel: port=" << cOpenPort; + + if (Tie(channel, err) = mChannelManager->CreateChannel(cOpenPort); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + mCurrentPort = cOpenPort; + + if (err = PBHandler::Init("IAM open", *channel); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + } else { + LOG_DBG() << "Setup secure channel: port=" << cSecurePort; + + if (Tie(channel, err) = mChannelManager->CreateChannel(cSecurePort); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + mCurrentPort = cSecurePort; + +#ifndef CONFIG_ZTEST + if (err = mTLSChannel.Init(*mCertHandler, *mCertLoader, *channel); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + if (err = mTLSChannel.SetTLSConfig(cIAMCertType); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } +#endif + + if (err = PBHandler::Init("IAM secure", *channel); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + } + + if (err = Start(); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + return ErrorEnum::eNone; +} + +bool IAMClient::WaitChannelSwitch(UniqueLock& lock) +{ + mCondVar.Wait(lock, [this]() { return mSwitchChannel || mClose; }); + mSwitchChannel = false; + + return !mClose; +} + +bool IAMClient::WaitClockSynced(UniqueLock& lock) +{ + if (mNodeInfo.mStatus != NodeStatusEnum::eUnprovisioned) { + mCondVar.Wait(lock, [this]() { return mClockSynced || mClose; }); + mClockSynced = false; + } + + return !mClose; +} + +bool IAMClient::WaitChannelConnected(UniqueLock& lock) +{ + mCondVar.Wait(lock, [this]() { return mConnected || mClose; }); + + return !mClose; +} + +void IAMClient::HandleChannels() +{ + while (true) { + if (auto err = ReleaseChannel(); !err.IsNone()) { + LOG_ERR() << "Can't release channel: err=" << err; + } + + UniqueLock lock {mMutex}; + + if (mClose) { + return; + } + + if (!WaitClockSynced(lock)) { + continue; + } + + if (auto err = SetupChannel(); !err.IsNone()) { + LOG_ERR() << "Can't setup channel: err=" << err; + + usleep(cReconnectInterval / 1000); + + continue; + } + + if (!WaitChannelConnected(lock)) { + continue; + } + + if (auto err = SendNodeInfo(); !err.IsNone()) { + LOG_ERR() << "Can't send node info: err=" << err; + + mSwitchChannel = true; + } + + if (!WaitChannelSwitch(lock)) { + continue; + } + } } Error IAMClient::ReceiveMessage(const Array& data) diff --git a/src/iamclient/iamclient.hpp b/src/iamclient/iamclient.hpp index 02bac63e..46c95c4e 100644 --- a/src/iamclient/iamclient.hpp +++ b/src/iamclient/iamclient.hpp @@ -17,6 +17,7 @@ #include "clocksync/clocksync.hpp" #include "communication/channelmanager.hpp" #include "communication/pbhandler.hpp" +#include "communication/tlschannel.hpp" namespace aos::zephyr::iamclient { @@ -26,7 +27,7 @@ namespace aos::zephyr::iamclient { class IAMClient : public communication::PBHandler, public clocksync::ClockSyncSubscriberItf, - iam::nodeinfoprovider::NodeStatusObserverItf, + public iam::nodeinfoprovider::NodeStatusObserverItf, private NonCopyable { public: /** @@ -36,10 +37,17 @@ class IAMClient * @param nodeInfoProvider node info provider. * @param provisionManager provision manager. * @param channelManager channel manager instance. + * @param certHandler certificate handler. + * @param certLoader certificate loader * @return Error. */ Error Init(clocksync::ClockSyncItf& clockSync, iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider, - iam::provisionmanager::ProvisionManagerItf& provisionManager, communication::ChannelManagerItf& channelManager); + iam::provisionmanager::ProvisionManagerItf& provisionManager, communication::ChannelManagerItf& channelManager +#ifndef CONFIG_ZTEST + , + iam::certhandler::CertHandlerItf& certHandler, cryptoutils::CertLoaderItf& certLoader +#endif + ); /** * Notifies subscriber clock is synced. @@ -66,13 +74,23 @@ class IAMClient ~IAMClient(); private: - static constexpr auto cOpenPort = CONFIG_AOS_IAM_OPEN_PORT; - static constexpr auto cSecurePort = CONFIG_AOS_IAM_SECURE_PORT; + static constexpr auto cOpenPort = CONFIG_AOS_IAM_OPEN_PORT; + static constexpr auto cSecurePort = CONFIG_AOS_IAM_SECURE_PORT; + static constexpr auto cReconnectInterval = 5 * Time::cSeconds; +#ifndef CONFIG_ZTEST + static constexpr auto cIAMCertType = "iam"; +#endif void OnConnect() override; void OnDisconnect() override; Error ReceiveMessage(const Array& data) override; + Error ReleaseChannel(); + Error SetupChannel(); + bool WaitChannelSwitch(UniqueLock& lock); + bool WaitClockSynced(UniqueLock& lock); + bool WaitChannelConnected(UniqueLock& lock); + void HandleChannels(); template Error SendError(const void* message, T& pbMessage, const Error& err); Error SendNodeInfo(); @@ -90,9 +108,21 @@ class IAMClient iam::nodeinfoprovider::NodeInfoProviderItf* mNodeInfoProvider {}; iam::provisionmanager::ProvisionManagerItf* mProvisionManager {}; communication::ChannelManagerItf* mChannelManager {}; +#ifndef CONFIG_ZTEST + iam::certhandler::CertHandlerItf* mCertHandler {}; + cryptoutils::CertLoaderItf* mCertLoader {}; + communication::TLSChannel mTLSChannel; +#endif - NodeInfo mNodeInfo; - Mutex mMutex; + NodeInfo mNodeInfo; + Mutex mMutex; + Thread<> mThread; + ConditionalVariable mCondVar; + bool mClockSynced = false; + bool mSwitchChannel = false; + int mCurrentPort = 0; + bool mClose = false; + bool mConnected = false; StaticAllocator mAllocator; }; diff --git a/tests/iamclient/src/main.cpp b/tests/iamclient/src/main.cpp index 962581ad..1513030d 100644 --- a/tests/iamclient/src/main.cpp +++ b/tests/iamclient/src/main.cpp @@ -64,6 +64,8 @@ static void InitIAMClient(iamclient_fixture* fixture, const aos::NodeInfo& nodeI auto err = fixture->mIAMClient->Init( fixture->mClockSync, fixture->mNodeInfoProvider, fixture->mProvisionManager, fixture->mChannelManager); zassert_true(err.IsNone(), "Can't initialize IAM client: %s", utils::ErrorToCStr(err)); + + fixture->mIAMClient->OnClockSynced(); } static void ReceiveNodeInfo(ChannelStub* channel, const aos::NodeInfo& nodeInfo) @@ -97,7 +99,8 @@ ZTEST_SUITE( return fixture; }, [](void* fixture) { static_cast(fixture)->mIAMClient.reset(new iamclient::IAMClient); }, - nullptr, [](void* fixture) { delete static_cast(fixture); }); + [](void* fixture) { static_cast(fixture)->mIAMClient.reset(); }, + [](void* fixture) { delete static_cast(fixture); }); /*********************************************************************************************************************** * Tests @@ -109,9 +112,11 @@ ZTEST_F(iamclient, test_StartProvisioning) InitIAMClient(fixture, nodeInfo); - auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT, cWaitTimeout); zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + ReceiveNodeInfo(channel, nodeInfo); + // Send start provisioning request iamanager_v5_IAMIncomingMessages incomingMessage; @@ -151,9 +156,11 @@ ZTEST_F(iamclient, test_FinishProvisioning) InitIAMClient(fixture, nodeInfo); - auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT, cWaitTimeout); zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + ReceiveNodeInfo(channel, nodeInfo); + // Send finish provisioning request iamanager_v5_IAMIncomingMessages incomingMessage; @@ -185,6 +192,15 @@ ZTEST_F(iamclient, test_FinishProvisioning) zassert_false(pbFinishProvisioningResponse.has_error, "Unexpected error received"); zassert_equal(fixture->mProvisionManager.GetPassword(), pbFinishProvisioningRequest.password, "Wrong password"); + + // Wait for node status changed + + aos::Tie(channel, err) = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_SECURE_PORT, cWaitTimeout); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + nodeInfo.mStatus = aos::NodeStatusEnum::eProvisioned; + + ReceiveNodeInfo(channel, nodeInfo); } ZTEST_F(iamclient, test_Deprovision) @@ -193,9 +209,11 @@ ZTEST_F(iamclient, test_Deprovision) InitIAMClient(fixture, nodeInfo); - auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_SECURE_PORT, cWaitTimeout); zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + ReceiveNodeInfo(channel, nodeInfo); + // Send deprovision request iamanager_v5_IAMIncomingMessages incomingMessage; @@ -226,6 +244,15 @@ ZTEST_F(iamclient, test_Deprovision) zassert_false(pbDeprovisionResponse.has_error, "Unexpected error received"); zassert_equal(fixture->mProvisionManager.GetPassword(), pbDeprovisionRequest.password, "Wrong password"); + + // Wait for node status changed + + aos::Tie(channel, err) = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT, cWaitTimeout); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + nodeInfo.mStatus = aos::NodeStatusEnum::eUnprovisioned; + + ReceiveNodeInfo(channel, nodeInfo); } ZTEST_F(iamclient, test_GetCertTypes) @@ -234,9 +261,11 @@ ZTEST_F(iamclient, test_GetCertTypes) InitIAMClient(fixture, nodeInfo); - auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT, cWaitTimeout); zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + ReceiveNodeInfo(channel, nodeInfo); + aos::iam::provisionmanager::CertTypes certTypes; certTypes.PushBack("certType1"); @@ -282,9 +311,11 @@ ZTEST_F(iamclient, test_CreateKey) InitIAMClient(fixture, nodeInfo); - auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT, cWaitTimeout); zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + ReceiveNodeInfo(channel, nodeInfo); + fixture->mProvisionManager.SetCSR("csr1"); // Send create key request @@ -330,9 +361,11 @@ ZTEST_F(iamclient, test_ApplyCert) InitIAMClient(fixture, nodeInfo); - auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT, cWaitTimeout); zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + ReceiveNodeInfo(channel, nodeInfo); + aos::iam::certhandler::CertInfo certInfo {}; aos::StaticString serial = "0123456789abcdef"; @@ -381,9 +414,11 @@ ZTEST_F(iamclient, test_PauseNode) InitIAMClient(fixture, nodeInfo); - auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_SECURE_PORT, cWaitTimeout); zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + ReceiveNodeInfo(channel, nodeInfo); + // Send pause node request iamanager_v5_IAMIncomingMessages incomingMessage; @@ -424,9 +459,11 @@ ZTEST_F(iamclient, test_ResumeNode) InitIAMClient(fixture, nodeInfo); - auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_OPEN_PORT); + auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_IAM_SECURE_PORT, cWaitTimeout); zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + ReceiveNodeInfo(channel, nodeInfo); + // Send resume node request iamanager_v5_IAMIncomingMessages incomingMessage; diff --git a/tests/stubs/channelmanagerstub.hpp b/tests/stubs/channelmanagerstub.hpp index 3127bee8..7fe1cc6a 100644 --- a/tests/stubs/channelmanagerstub.hpp +++ b/tests/stubs/channelmanagerstub.hpp @@ -10,12 +10,16 @@ #include +#include "communication/channelmanager.hpp" + #include "channelstub.hpp" class ChannelManagerStub : public aos::zephyr::communication::ChannelManagerItf { public: aos::RetWithError CreateChannel(uint32_t port) override { + std::lock_guard lock {mMutex}; + if (mChannels.find(port) != mChannels.end()) { return {nullptr, aos::ErrorEnum::eAlreadyExist}; } @@ -24,23 +28,32 @@ class ChannelManagerStub : public aos::zephyr::communication::ChannelManagerItf mChannels[port] = std::move(channel); + mCV.notify_one(); + return mChannels[port].get(); } aos::Error DeleteChannel(uint32_t port) override { + std::lock_guard lock {mMutex}; + if (mChannels.find(port) == mChannels.end()) { return aos::ErrorEnum::eNotFound; } mChannels.erase(port); + mCV.notify_one(); + return aos::ErrorEnum::eNone; } - aos::RetWithError GetChannel(uint32_t port) + aos::RetWithError GetChannel( + uint32_t port, const std::chrono::duration& timeout = std::chrono::duration::zero()) { - if (mChannels.find(port) == mChannels.end()) { + std::unique_lock lock {mMutex}; + + if (!mCV.wait_for(lock, timeout, [&] { return mChannels.find(port) != mChannels.end(); })) { return {nullptr, aos::ErrorEnum::eNotFound}; } @@ -49,6 +62,8 @@ class ChannelManagerStub : public aos::zephyr::communication::ChannelManagerItf private: std::unordered_map> mChannels; + std::mutex mMutex; + std::condition_variable mCV; }; #endif From f1075b77a45501c86d15d4e3dd55602e5095bf27 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 19 Aug 2024 14:32:07 +0300 Subject: [PATCH 062/198] [iamclient] Fix usage tlschannel for test Signed-off-by: Oleksandr Grytsov --- src/iamclient/iamclient.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/iamclient/iamclient.hpp b/src/iamclient/iamclient.hpp index 46c95c4e..4fa7c014 100644 --- a/src/iamclient/iamclient.hpp +++ b/src/iamclient/iamclient.hpp @@ -17,7 +17,9 @@ #include "clocksync/clocksync.hpp" #include "communication/channelmanager.hpp" #include "communication/pbhandler.hpp" +#ifndef CONFIG_ZTEST #include "communication/tlschannel.hpp" +#endif namespace aos::zephyr::iamclient { From a0060b5363b37b9e4a09a56c20211091fcb595ae Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 19 Aug 2024 16:20:06 +0300 Subject: [PATCH 063/198] [tests,stubs] Fix notify cond var in channlstub We have two threads waiting for events: for read and write. We should send notify_all instead of notify_one. Signed-off-by: Oleksandr Grytsov --- tests/stubs/channelstub.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/stubs/channelstub.hpp b/tests/stubs/channelstub.hpp index 18697bbb..ee76dba8 100644 --- a/tests/stubs/channelstub.hpp +++ b/tests/stubs/channelstub.hpp @@ -33,7 +33,7 @@ class ChannelStub : public aos::zephyr::communication::ChannelItf { mConnected = false; - mCV.notify_one(); + mCV.notify_all(); return mConnectError; } @@ -66,7 +66,7 @@ class ChannelStub : public aos::zephyr::communication::ChannelItf { mWriteData.insert( mWriteData.end(), static_cast(data), static_cast(data) + size); - mCV.notify_one(); + mCV.notify_all(); return size; } @@ -101,7 +101,7 @@ class ChannelStub : public aos::zephyr::communication::ChannelItf { mReadError = err; mReadData.insert(mReadData.end(), data.begin(), data.end()); - mCV.notify_one(); + mCV.notify_all(); } void Clear() From 6e71972c08b952d2cbee81449cf6ec6e62d6add0 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Tue, 20 Aug 2024 13:59:27 +0300 Subject: [PATCH 064/198] [boards] Add provision state file and pin file configs for native build Signed-off-by: Oleksandr Grytsov --- boards/native_posix.conf | 2 ++ boards/native_posix_64.conf | 2 ++ 2 files changed, 4 insertions(+) diff --git a/boards/native_posix.conf b/boards/native_posix.conf index dc806138..ec9f9c46 100644 --- a/boards/native_posix.conf +++ b/boards/native_posix.conf @@ -78,6 +78,8 @@ CONFIG_AOS_RUNTIME_DIR=".aos/runtime" CONFIG_AOS_SERVICES_DIR=".aos/services" CONFIG_AOS_NODE_CONFIG_FILE=".aos/node_config.cfg" CONFIG_AOS_HSM_DIR=".aos/hsm" +CONFIG_AOS_PROVISION_STATE_FILE=".aos/.provisionstate" +CONFIG_AOS_PKCS11_MODULE_PIN_FILE=".aos/.pkcs11pin" # Disable OP-TEE driver and client libraries # TEE is not supported by this platform diff --git a/boards/native_posix_64.conf b/boards/native_posix_64.conf index dc806138..ec9f9c46 100644 --- a/boards/native_posix_64.conf +++ b/boards/native_posix_64.conf @@ -78,6 +78,8 @@ CONFIG_AOS_RUNTIME_DIR=".aos/runtime" CONFIG_AOS_SERVICES_DIR=".aos/services" CONFIG_AOS_NODE_CONFIG_FILE=".aos/node_config.cfg" CONFIG_AOS_HSM_DIR=".aos/hsm" +CONFIG_AOS_PROVISION_STATE_FILE=".aos/.provisionstate" +CONFIG_AOS_PKCS11_MODULE_PIN_FILE=".aos/.pkcs11pin" # Disable OP-TEE driver and client libraries # TEE is not supported by this platform From af0d211fb6a64fb407acae4ce024a726e7ad4ffd Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Tue, 20 Aug 2024 15:03:31 +0300 Subject: [PATCH 065/198] [app] Move init node info provider before iam client Signed-off-by: Oleksandr Grytsov --- src/app/app.cpp | 8 ++++---- src/app/app.hpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index a3cf3cd3..7bcd6010 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -155,6 +155,10 @@ Error App::InitZephyr() } #endif + if (auto err = mNodeInfoProvider.Init(); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + if (auto err = mClockSync.Init(mSMClient); !err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -173,10 +177,6 @@ Error App::InitZephyr() return AOS_ERROR_WRAP(err); } - if (auto err = mNodeInfoProvider.Init(); !err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - if (auto err = mRunner.Init(mLauncher); !err.IsNone()) { return AOS_ERROR_WRAP(err); } diff --git a/src/app/app.hpp b/src/app/app.hpp index 353fc31f..984351f4 100644 --- a/src/app/app.hpp +++ b/src/app/app.hpp @@ -23,6 +23,7 @@ #include "communication/channelmanager.hpp" #include "communication/xenvchan.hpp" #include "downloader/downloader.hpp" +#include "iamclient/iamclient.hpp" #include "monitoring/resourceusageprovider.hpp" #include "nodeinfoprovider/nodeinfoprovider.hpp" #include "ocispec/ocispec.hpp" @@ -30,7 +31,6 @@ #include "resourcemanager/resourcemanager.hpp" #include "runner/runner.hpp" #include "smclient/smclient.hpp" -#include "iamclient/iamclient.hpp" #include "storage/storage.hpp" namespace aos::zephyr::app { From d6470a98604d1575f9c5327f70d81e393aa668c2 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Tue, 6 Aug 2024 12:08:57 +0300 Subject: [PATCH 066/198] [communication] Implement channel Signed-off-by: Mykola Solianko --- src/communication/channel.cpp | 116 +++++++++++++++++++++++++++++++ src/communication/channel.hpp | 127 ++++++++++++++++++++++++++++++++-- 2 files changed, 237 insertions(+), 6 deletions(-) create mode 100644 src/communication/channel.cpp diff --git a/src/communication/channel.cpp b/src/communication/channel.cpp new file mode 100644 index 00000000..40f63888 --- /dev/null +++ b/src/communication/channel.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "channel.hpp" +#include "log.hpp" + +namespace aos::zephyr::communication { + +Channel::Channel(CommunicationItf* communication, int port) + : mCommunication(communication) + , mPort(port) +{ +} + +Error Channel::Connect() +{ + UniqueLock lock {mMutex}; + + LOG_DBG() << "Connect channel: port=" << mPort; + + if (auto err = mCommunication->Connect(); !err.IsNone()) { + return err; + } + + return ErrorEnum::eNone; +} + +Error Channel::Close() +{ + UniqueLock lock {mMutex}; + + LOG_DBG() << "Close channel: port=" << mPort; + + mClose = true; + mCondVar.NotifyAll(); + + return ErrorEnum::eNone; +} + +int Channel::Read(void* buffer, size_t size) +{ + UniqueLock lock {mMutex}; + + LOG_DBG() << "Read channel: port=" << mPort << " size=" << size; + + mBufferLen = 0; + + while (mBufferLen < size) { + mReadReady = true; + mBuffer = reinterpret_cast(buffer) + mBufferLen; + mBufferLen = size - mBufferLen; + + mCondVar.NotifyAll(); + + mCondVar.Wait(lock, [this] { return !mReadReady || mClose; }); + + if (mClose) { + return -ECONNRESET; + } + } + + LOG_DBG() << "Read channel done: port=" << mPort << " size=" << size; + + return static_cast(size); +} + +int Channel::Write(const void* buffer, size_t size) +{ + return mCommunication->Write(mPort, buffer, size); +} + +Error Channel::WaitRead(void** buffer, size_t* size) +{ + UniqueLock lock {mMutex}; + + LOG_DBG() << "Wait read: port=" << mPort; + + auto err = mCondVar.Wait(lock, cWaitReadPeriod, [this] { return mReadReady || mClose; }); + if (!err.IsNone()) { + return err; + } + + if (mClose) { + return {aos::ErrorEnum::eRuntime, "channel is closed"}; + } + + *buffer = mBuffer; + *size = mBufferLen; + + return ErrorEnum::eNone; +} + +Error Channel::ReadDone(size_t size) +{ + UniqueLock lock {mMutex}; + + LOG_DBG() << "Read done: port=" << mPort << " size=" << size; + + mReadReady = false; + mBufferLen = size; + + mCondVar.NotifyAll(); + + return ErrorEnum::eNone; +} + +bool Channel::IsConnected() const +{ + return mCommunication->IsConnected(); +} + +} // namespace aos::zephyr::communication diff --git a/src/communication/channel.hpp b/src/communication/channel.hpp index f3c88cc5..fc6e0527 100644 --- a/src/communication/channel.hpp +++ b/src/communication/channel.hpp @@ -1,6 +1,6 @@ /* - * Copyright (C) 2023 Renesas Electronics Corporation. - * Copyright (C) 2023 EPAM Systems, Inc. + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,9 +8,13 @@ #ifndef CHANNEL_HPP_ #define CHANNEL_HPP_ -namespace aos::zephyr::communication { - #include +#include +#include + +#include "transport.hpp" + +namespace aos::zephyr::communication { /** * Channel interface. @@ -22,12 +26,12 @@ class ChannelItf { * * @return aos::Error. */ - virtual aos::Error Connect() = 0; + virtual Error Connect() = 0; /** * Closes current connection. */ - virtual aos::Error Close() = 0; + virtual Error Close() = 0; /** * Returns if channel is connected. @@ -60,6 +64,117 @@ class ChannelItf { virtual ~ChannelItf() = default; }; +/** + * Communication interface. + */ +class CommunicationItf { +public: + /** + * Connects to communication channel. + * + * @return aos::Error. + */ + virtual Error Connect() = 0; + + /** + * Closes current connection. + * + * @return aos::Error. + */ + virtual bool IsConnected() const = 0; + + /** + * Reads data from channel to array. + * + * @param data buffer where data is placed to. + * @param size specifies how many bytes to read. + * @return int num read bytes. + */ + virtual int Write(uint32_t port, const void* data, size_t size) = 0; +}; + +/** + * Channel class. + */ +class Channel : public ChannelItf { +public: + /** + * Constructor. + * + * @param communication communication interface. + * @param port port number. + */ + Channel(CommunicationItf* communication, int port); + + /** + * Connects to communication channel. + * + * @return aos::Error. + */ + Error Connect() override; + + /** + * Closes current connection. + * + * @return aos::Error. + */ + Error Close() override; + + /** + * Reads data from channel to buffer. + * + * @param data buffer where data is placed to. + * @param size specifies how many bytes to read. + * @return int num read bytes. + */ + int Read(void* buffer, size_t size) override; + + /** + * Writes data from buffer to channel. + * + * @param data data buffer. + * @param size specifies how many bytes to write. + * @return int num written bytes. + */ + int Write(const void* buffer, size_t size) override; + + /** + * Returns if channel is connected. + * + * @return bool. + */ + bool IsConnected() const override; + + /** + * Waits for read. + * + * @param buffer buffer where data is placed to. + * @param size specifies how many bytes to read. + * @return aos::Error. + */ + Error WaitRead(void** buffer, size_t* size); + + /** + * Notifies that read is done. + * + * @param size specifies how many bytes were read. + * @return aos::Error. + */ + Error ReadDone(size_t size); + +private: + static constexpr auto cWaitReadPeriod = 3 * Time::cSeconds; + + CommunicationItf* mCommunication {}; + int mPort {}; + bool mReadReady {}; + bool mClose {}; + uint8_t* mBuffer {}; + size_t mBufferLen {}; + Mutex mMutex; + ConditionalVariable mCondVar; +}; + } // namespace aos::zephyr::communication #endif From 2fde7f1f51a201573e23ee10b50be33694f30717 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Tue, 6 Aug 2024 12:10:10 +0300 Subject: [PATCH 067/198] [communication] Implement channelmanager Signed-off-by: Mykola Solianko --- src/communication/channelmanager.cpp | 284 ++++++++++++++++++++++++++- src/communication/channelmanager.hpp | 84 +++++++- 2 files changed, 359 insertions(+), 9 deletions(-) diff --git a/src/communication/channelmanager.cpp b/src/communication/channelmanager.cpp index 7511ce92..2a839cc9 100644 --- a/src/communication/channelmanager.cpp +++ b/src/communication/channelmanager.cpp @@ -5,7 +5,13 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include +#include + +#include "channel.hpp" #include "channelmanager.hpp" +#include "log.hpp" +#include "utils/checksum.hpp" namespace aos::zephyr::communication { @@ -13,19 +19,293 @@ namespace aos::zephyr::communication { * Public **********************************************************************************************************************/ +Mutex ChannelManager::sWriteMutex; + Error ChannelManager::Init(TransportItf& transport) { - return ErrorEnum::eNone; + LOG_INF() << "Init channel manager"; + + mTransport = &transport; + + return Run(); } RetWithError ChannelManager::CreateChannel(uint32_t port) { - return {nullptr, ErrorEnum::eNotSupported}; + UniqueLock lock {mMutex}; + + auto findChannel = mChannels.At(port); + if (findChannel.mError.IsNone()) { + return {findChannel.mValue.Get(), ErrorEnum::eNone}; + } + + LOG_DBG() << "Create channel: port=" << port; + + auto channel = aos::MakeShared(&mChanAllocator, static_cast(this), port); + + if (auto err = mChannels.Set(port, channel); !err.IsNone()) { + return {nullptr, err}; + } + + mCondVar.NotifyAll(); + + return {channel.Get(), ErrorEnum::eNone}; } Error ChannelManager::DeleteChannel(uint32_t port) { + UniqueLock lock {mMutex}; + + LOG_DBG() << "Delete channel: port=" << port; + + return mChannels.Remove(port); +} + +Error ChannelManager::Connect() +{ + UniqueLock lock {mMutex}; + + LOG_DBG() << "Connect channel manager"; + + mCondVar.Wait(lock, [this] { return mTransport->IsOpened() || mClose; }); + if (mClose) { + return ErrorEnum::eRuntime; + } + + LOG_DBG() << "Channel manager connected"; + return ErrorEnum::eNone; } +Error ChannelManager::Close() +{ + { + UniqueLock lock {mMutex}; + + LOG_DBG() << "Close channel manager"; + + mClose = true; + mCondVar.NotifyAll(); + + if (!mTransport->IsOpened()) { + return ErrorEnum::eNone; + } + + if (auto err = mTransport->Close(); !err.IsNone()) { + return err; + } + } + + return mThread.Join(); +} + +int ChannelManager::Write(uint32_t port, const void* data, size_t size) +{ + LOG_DBG() << "Write channel: port=" << port << " size=" << size; + + auto header = PrepareHeader(port, aos::Array(reinterpret_cast(data), size)); + if (!header.mError.IsNone()) { + LOG_ERR() << "Failed to prepare header: err=" << header.mError.Message(); + + return -EINVAL; + } + + aos::UniqueLock lock {sWriteMutex}; + + if (auto ret = mTransport->Write(&header.mValue, sizeof(AosProtocolHeader)); + ret < static_cast(sizeof(AosProtocolHeader))) { + return ret; + } + + return mTransport->Write(data, size); +} + +bool ChannelManager::IsConnected() const +{ + return mTransport->IsOpened(); +} + +/*********************************************************************************************************************** + * Private + **********************************************************************************************************************/ + +Error ChannelManager::TryConnect() +{ + UniqueLock lock {mMutex}; + + if (mTransport->IsOpened()) { + return ErrorEnum::eNone; + } + + if (auto err = mTransport->Open(); !err.IsNone()) { + return err; + } + + return ErrorEnum::eNone; +} + +Error ChannelManager::Run() +{ + return mThread.Run([this](void*) { + while (true) { + { + aos::UniqueLock lock {mMutex}; + if (mClose) { + return aos::Error(aos::ErrorEnum::eNone); + } + } + + if (auto err = TryConnect(); !err.IsNone()) { + LOG_ERR() << "Failed to connect: err=" << err.Message(); + + if (err = WaitTimeout(); !err.IsNone()) { + return err; + } + + continue; + } + + mCondVar.NotifyAll(); + + if (auto err = HandleRead(); !err.IsNone()) { + LOG_ERR() << "Failed to handle read: err=" << err.Message(); + } + + CloseChannels(); + + if (auto err = WaitTimeout(); !err.IsNone()) { + return err; + } + } + }); +} + +Error ChannelManager::WaitTimeout() +{ + aos::UniqueLock lock {mMutex}; + + if (auto err = mCondVar.Wait(lock, cReconnectPeriod, [this] { return mClose; }); !err.IsNone()) { + return err; + } + + return ErrorEnum::eNone; +} + +Error ChannelManager::HandleRead() +{ + while (true) { + { + aos::UniqueLock lock {mMutex}; + + mCondVar.Wait(lock, [this] { return mChannels.Size() > 0 || mClose; }); + if (mClose) { + return ErrorEnum::eNone; + } + } + + AosProtocolHeader header; + + if (auto err = ReadFromTransport(header); !err.IsNone()) { + return err; + } + + if (auto err = ProcessData(header); !err.IsNone()) { + LOG_ERR() << "Failed to process data: err=" << err.Message(); + } + } +} + +Error ChannelManager::ReadFromTransport(AosProtocolHeader& header) +{ + if (auto ret = mTransport->Read(&header, sizeof(AosProtocolHeader)); + ret < static_cast(sizeof(AosProtocolHeader))) { + return {ret, "failed to read header"}; + } + + if (header.mDataSize > cReadBufferSize) { + return {ErrorEnum::eRuntime, "not enough memory in read buffer"}; + } + + LOG_DBG() << "Read channel CM: port=" << header.mPort << " size=" << header.mDataSize; + + size_t totalRead = 0; + + while (totalRead < header.mDataSize) { + size_t readSize = header.mDataSize - totalRead; + + if (auto ret = mTransport->Read(mTmpReadBuffer + totalRead, readSize); ret < static_cast(readSize)) { + return {ret, "failed to read data into local buffer"}; + } + + totalRead += readSize; + } + + return ErrorEnum::eNone; +} + +Error ChannelManager::ProcessData(const AosProtocolHeader& header) +{ + UniqueLock lock {mMutex}; + + LOG_DBG() << "Read channel CM: port=" << header.mPort << " size=" << header.mDataSize; + + auto [channel, err] = mChannels.At(header.mPort); + if (!err.IsNone()) { + return err; + } + + size_t processedSize = 0; + + while (processedSize < header.mDataSize) { + void* buffer = nullptr; + size_t size = 0; + + if (err = channel->WaitRead(&buffer, &size); !err.IsNone()) { + return err; + } + + LOG_DBG() << "Request read channel: port=" << header.mPort << " size=" << size; + + size = aos::Min(size, static_cast(header.mDataSize - processedSize)); + + memcpy(buffer, mTmpReadBuffer + processedSize, size); + + if (err = channel->ReadDone(size); !err.IsNone()) { + return err; + } + + processedSize += size; + } + + LOG_DBG() << "Read channel done: port=" << header.mPort << " size=" << header.mDataSize; + + return ErrorEnum::eNone; +} + +void ChannelManager::CloseChannels() +{ + LOG_DBG() << "Close channels"; + + // cppcheck-suppress unusedVariable + for (auto& [_, channel] : mChannels) { + channel->Close(); + } +} + +aos::RetWithError ChannelManager::PrepareHeader(uint32_t port, const aos::Array& data) +{ + AosProtocolHeader header; + header.mPort = port; + header.mDataSize = data.Size(); + + auto ret = aos::zephyr::utils::CalculateSha256(data); + if (!ret.mError.IsNone()) { + return {header, AOS_ERROR_WRAP(ret.mError)}; + } + + aos::Array(reinterpret_cast(header.mCheckSum), aos::cSHA256Size) = ret.mValue; + + return header; +} + } // namespace aos::zephyr::communication diff --git a/src/communication/channelmanager.hpp b/src/communication/channelmanager.hpp index 32ffaf7a..a2b26fcd 100644 --- a/src/communication/channelmanager.hpp +++ b/src/communication/channelmanager.hpp @@ -8,9 +8,9 @@ #ifndef COMMUNICATION_HPP_ #define COMMUNICATION_HPP_ -#include - -#include +#include +#include +#include #include "channel.hpp" #include "transport.hpp" @@ -26,7 +26,7 @@ class ChannelManagerItf { * Create channel with dedicated port. * * @param port port to bind channel. - * @return RetWithError. + * @return aos::RetWithError */ virtual RetWithError CreateChannel(uint32_t port) = 0; @@ -38,17 +38,29 @@ class ChannelManagerItf { */ virtual Error DeleteChannel(uint32_t port) = 0; + /** + * Closes communication channel. + * + * @return aos::Error. + */ + virtual Error Close() = 0; + /** * Destructor. */ - virtual ~ChannelManagerItf() { } + virtual ~ChannelManagerItf() = default; }; /** * Channel manager instance. */ -class ChannelManager : public ChannelManagerItf { +class ChannelManager : public ChannelManagerItf, public CommunicationItf { public: + /** + * Constructor. + */ + ChannelManager() = default; + /** * Initializes channel manager. * @@ -61,7 +73,7 @@ class ChannelManager : public ChannelManagerItf { * Create channel with dedicated port. * * @param port port to bind channel. - * @return aos::RetWithError + * @return aos::RetWithError */ RetWithError CreateChannel(uint32_t port) override; @@ -72,6 +84,64 @@ class ChannelManager : public ChannelManagerItf { * @return aos::Error */ Error DeleteChannel(uint32_t port) override; + + /** + * Closes communication channel. + * + * @return aos::Error. + */ + Error Close() override; + + /** + * Connects to communication channel. + * + * @return aos::Error. + */ + Error Connect() override; + + /** + * Write data to channel. + * + * @param port port to write data to. + * @param data data to write. + * @param size size of data. + * @return uint32_t number of bytes written. + */ + int Write(uint32_t port, const void* data, size_t size) override; + + /** + * Checks if channel manager is connected. + * + * @return bool true if connected, false otherwise. + */ + bool IsConnected() const override; + +private: + static constexpr int cMaxChannels = 3; + static constexpr auto cChanAllocatorSize = cMaxChannels * sizeof(Channel); + static constexpr auto cReconnectPeriod = 2 * Time::cSeconds; + static constexpr size_t cReadBufferSize = 65 * 1024; // 65KB + + Error Run(); + Error HandleRead(); + void CloseChannels(); + Error TryConnect(); + Error WaitTimeout(); + Error ReadFromTransport(AosProtocolHeader& header); + Error ProcessData(const AosProtocolHeader& header); + + aos::RetWithError PrepareHeader(uint32_t port, const aos::Array& data); + + StaticAllocator mChanAllocator; + TransportItf* mTransport {}; + StaticMap, cMaxChannels> mChannels; + + aos::Thread<> mThread; + aos::Mutex mMutex; + bool mClose {false}; + ConditionalVariable mCondVar; + static Mutex sWriteMutex; + uint8_t mTmpReadBuffer[cReadBufferSize] {}; }; } // namespace aos::zephyr::communication From 2020184cfda0a64f8b732b8610d3f16d72c715cc Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Tue, 6 Aug 2024 12:15:19 +0300 Subject: [PATCH 068/198] [communication] Remove aos namespace in transport Signed-off-by: Mykola Solianko --- src/communication/transport.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/communication/transport.hpp b/src/communication/transport.hpp index 31c70634..55e86f24 100644 --- a/src/communication/transport.hpp +++ b/src/communication/transport.hpp @@ -22,12 +22,12 @@ class TransportItf { * * @return aos::Error. */ - virtual aos::Error Open() = 0; + virtual Error Open() = 0; /** * Closes transport. */ - virtual aos::Error Close() = 0; + virtual Error Close() = 0; /** * Returns if transport is opened. From 6399303976587e3f26643e8a29e5acff694f2530 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Tue, 6 Aug 2024 12:19:50 +0300 Subject: [PATCH 069/198] [cmake] Update cmake Signed-off-by: Mykola Solianko --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 479c2a3b..50a2c5b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,8 @@ target_sources( src/communication/channelmanager.cpp src/communication/tlschannel.cpp src/communication/xenvchan.cpp + src/communication/channel.cpp + src/communication/channelmanager.cpp src/downloader/downloader.cpp src/iamclient/iamclient.cpp src/logger/logger.cpp From 71edd6352524997a3a7c30db194fca805ac201e4 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Tue, 6 Aug 2024 12:20:59 +0300 Subject: [PATCH 070/198] [tests] Add test on channelmanager Signed-off-by: Mykola Solianko --- tests/communication/CMakeLists.txt | 17 +- tests/communication/src/channelmanager.cpp | 186 ++++++++++++++++++ .../communication/src/stubs/transportstub.hpp | 107 ++++++++++ 3 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 tests/communication/src/channelmanager.cpp create mode 100644 tests/communication/src/stubs/transportstub.hpp diff --git a/tests/communication/CMakeLists.txt b/tests/communication/CMakeLists.txt index ecb22250..ca90b435 100644 --- a/tests/communication/CMakeLists.txt +++ b/tests/communication/CMakeLists.txt @@ -35,7 +35,12 @@ add_definitions(-DCONFIG_AOS_ROOT_CA_PATH="${cert_dir}/ca.pem") # Includes # ###################################################################################################################### +file(COPY ${APPLICATION_SOURCE_DIR}/../../../aos_core_api/aosprotocol/aosprotocol.h + DESTINATION ${CMAKE_CURRENT_BINARY_DIR} +) + zephyr_include_directories(${aoscore_source_dir}/include) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/..) zephyr_include_directories(${APPLICATION_SOURCE_DIR}/../../src) zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src) zephyr_include_directories(${CMAKE_CURRENT_BINARY_DIR}) @@ -104,4 +109,14 @@ target_sources(mbedTLSX509 PRIVATE ${mbedtls_source_dir}/library/x509write.c) # Target # ###################################################################################################################### -target_sources(app PRIVATE ../../src/communication/tlschannel.cpp ../../src/rootca/rootca.S src/tlschannel.cpp) +target_sources( + app + PRIVATE ../../src/communication/tlschannel.cpp + ../../src/rootca/rootca.S + ../../src/communication/channel.cpp + ../../src/communication/channelmanager.cpp + ../../src/utils/checksum.cpp + ../utils/log.cpp + src/channelmanager.cpp + src/tlschannel.cpp +) diff --git a/tests/communication/src/channelmanager.cpp b/tests/communication/src/channelmanager.cpp new file mode 100644 index 00000000..fad50c48 --- /dev/null +++ b/tests/communication/src/channelmanager.cpp @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2023 Renesas Electronics Corporation. + * Copyright (C) 2023 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include +#include + +#include + +#include "communication/channelmanager.hpp" +#include "utils/checksum.hpp" +#include "utils/log.hpp" + +#include "stubs/transportstub.hpp" + +/*********************************************************************************************************************** + * Static + **********************************************************************************************************************/ + +static aos::RetWithError PrepareHeader(uint32_t port, const aos::Array& data) +{ + AosProtocolHeader header; + header.mPort = port; + header.mDataSize = data.Size(); + + auto ret = aos::zephyr::utils::CalculateSha256(data); + if (!ret.mError.IsNone()) { + return {header, AOS_ERROR_WRAP(ret.mError)}; + } + + aos::Array(reinterpret_cast(header.mCheckSum), aos::cSHA256Size) = ret.mValue; + + return header; +} + +/*********************************************************************************************************************** + * Setup + **********************************************************************************************************************/ + +ZTEST_SUITE(channelmanager, nullptr, nullptr, nullptr, nullptr, nullptr); + +/*********************************************************************************************************************** + * Tests + **********************************************************************************************************************/ + +ZTEST(channelmanager, test_message_exchange) +{ + aos::Log::SetCallback(TestLogCallback); + + aos::zephyr::communication::Pipe pipe1; + aos::zephyr::communication::Pipe pipe2; + aos::zephyr::communication::TransportStub transport(pipe1, pipe2); + aos::zephyr::communication::ChannelManager channelManager; + + auto err = channelManager.Init(transport); + zassert_true(err.IsNone(), "Channel manager initialization failed"); + + auto ret = channelManager.CreateChannel(8080); + zassert_true(ret.mError.IsNone(), "Channel creation failed", ret.mError.Message()); + zassert_true(ret.mValue != nullptr, "Channel creation failed"); + + const char* msg = "Test1"; + ret.mValue->Write(msg, strlen(msg)); + + AosProtocolHeader header; + int bytesRead = pipe2.Read(reinterpret_cast(&header), sizeof(AosProtocolHeader)); + zassert_true(bytesRead == sizeof(AosProtocolHeader), "Failed to read header"); + zassert_equal(header.mPort, 8080, "Port mismatch"); + + char buffer[100] {}; + bytesRead = pipe2.Read(reinterpret_cast(buffer), header.mDataSize); + buffer[bytesRead] = '\0'; + zassert_equal(strcmp(buffer, msg), 0, "Message read from transport does not match"); + + char response[] = "Test2!"; + auto headerRet = PrepareHeader(8080, aos::Array(reinterpret_cast(response), strlen(response))); + zassert_true(headerRet.mError.IsNone(), "Failed to prepare header"); + + pipe1.Write(reinterpret_cast(&headerRet.mValue), sizeof(AosProtocolHeader)); + pipe1.Write(reinterpret_cast(response), strlen(response)); + + memset(buffer, 0, sizeof(buffer)); + + bytesRead = ret.mValue->Read(buffer, strlen(response)); + buffer[bytesRead] = '\0'; + zassert_equal(strcmp(buffer, response), 0, "Message read from transport does not match"); + + pipe1.Close(); + pipe2.Close(); + + channelManager.Close(); +} + +ZTEST(channelmanager, test_read_message) +{ + aos::Log::SetCallback(TestLogCallback); + + aos::zephyr::communication::Pipe pipe1; + aos::zephyr::communication::Pipe pipe2; + aos::zephyr::communication::TransportStub transport(pipe1, pipe2); + aos::zephyr::communication::ChannelManager channelManager; + + auto err = channelManager.Init(transport); + zassert_true(err.IsNone(), "Channel manager initialization failed"); + + auto ret = channelManager.CreateChannel(8080); + zassert_true(ret.mError.IsNone(), "Channel creation failed", ret.mError.Message()); + zassert_true(ret.mValue != nullptr, "Channel creation failed"); + + char response[] = "Test!"; + auto headerRet = PrepareHeader(8080, aos::Array(reinterpret_cast(response), strlen(response))); + zassert_true(headerRet.mError.IsNone(), "Failed to prepare header"); + + std::thread tRead([&]() { + char buffer[100] {}; + auto bytesRead = ret.mValue->Read(buffer, strlen(response)); + + buffer[bytesRead] = '\0'; + zassert_equal(strcmp(buffer, response), 0, "Message read from transport does not match"); + }); + + pipe1.Write(reinterpret_cast(&headerRet.mValue), sizeof(AosProtocolHeader)); + pipe1.Write(reinterpret_cast(response), strlen(response)); + + tRead.join(); + + pipe1.Close(); + pipe2.Close(); + + channelManager.Close(); +} + +ZTEST(channelmanager, test_read_message_in_chunks) +{ + aos::Log::SetCallback(TestLogCallback); + + aos::zephyr::communication::Pipe pipe1; + aos::zephyr::communication::Pipe pipe2; + aos::zephyr::communication::TransportStub transport(pipe1, pipe2); + aos::zephyr::communication::ChannelManager channelManager; + + auto err = channelManager.Init(transport); + zassert_true(err.IsNone(), "Channel manager initialization failed"); + + auto ret = channelManager.CreateChannel(8080); + zassert_true(ret.mError.IsNone(), "Channel creation failed", ret.mError.Message()); + zassert_true(ret.mValue != nullptr, "Channel creation failed"); + + char response[] = "Test"; + auto headerRet = PrepareHeader(8080, aos::Array(reinterpret_cast(response), strlen(response))); + zassert_true(headerRet.mError.IsNone(), "Failed to prepare header"); + + std::thread tRead([&]() { + char resultBuffer[100] {}; + char buffer[100] {}; + auto bytesRead = ret.mValue->Read(buffer, strlen(response) / 2); + memcpy(resultBuffer, buffer, bytesRead); + + memset(buffer, 0, sizeof(buffer)); + + bytesRead = ret.mValue->Read(buffer, strlen(response) / 2); + memcpy(resultBuffer + strlen(response) / 2, buffer, bytesRead); + + resultBuffer[strlen(response)] = '\0'; + + zassert_equal(strcmp(resultBuffer, response), 0, "Message read from transport does not match"); + }); + + pipe1.Write(reinterpret_cast(&headerRet.mValue), sizeof(AosProtocolHeader)); + pipe1.Write(reinterpret_cast(response), strlen(response)); + + tRead.join(); + + pipe1.Close(); + pipe2.Close(); + + channelManager.Close(); +} diff --git a/tests/communication/src/stubs/transportstub.hpp b/tests/communication/src/stubs/transportstub.hpp new file mode 100644 index 00000000..2f2afe26 --- /dev/null +++ b/tests/communication/src/stubs/transportstub.hpp @@ -0,0 +1,107 @@ +#include +#include +#include +#include +#include + +#include "communication/transport.hpp" + +namespace aos::zephyr::communication { + +class Pipe { +public: + Pipe() + : mClosed(false) + { + } + + void Write(const uint8_t* data, size_t size) + { + std::unique_lock lock(mMutex); + mBuffer.insert(mBuffer.end(), data, data + size); + mCondVar.notify_one(); + } + + size_t Read(uint8_t* data, size_t size) + { + std::unique_lock lock(mMutex); + + mCondVar.wait(lock, [this] { return !mBuffer.empty() || mClosed; }); + if (mClosed || mBuffer.empty()) { + return -1; + } + + size_t bytesRead = std::min(size, mBuffer.size()); + std::copy(mBuffer.begin(), mBuffer.begin() + bytesRead, data); + mBuffer.erase(mBuffer.begin(), mBuffer.begin() + bytesRead); + + std::cout << "Read " << bytesRead << " bytes" << std::endl; + + return bytesRead; + } + + void Close() + { + std::unique_lock lock(mMutex); + mClosed = true; + mCondVar.notify_all(); + } + +private: + std::vector mBuffer; + std::mutex mMutex; + std::condition_variable mCondVar; + std::atomic mClosed; +}; + +class TransportStub : public TransportItf { +public: + TransportStub(Pipe& readPipe, Pipe& writePipe) + : mReadPipe(readPipe) + , mWritePipe(writePipe) + , mIsOpened(true) + { + } + + Error Open() override + { + mIsOpened.store(true); + + return ErrorEnum::eNone; + } + + Error Close() override + { + mIsOpened.store(false); + return ErrorEnum::eNone; + } + + bool IsOpened() const override { return mIsOpened.load(); } + + int Read(void* data, size_t size) override + { + if (!mIsOpened.load()) { + return -1; + } + + return static_cast(mReadPipe.Read(static_cast(data), size)); + } + + int Write(const void* data, size_t size) override + { + if (!mIsOpened.load()) { + return -1; + } + + mWritePipe.Write(static_cast(data), size); + + return static_cast(size); + } + +private: + Pipe& mReadPipe; + Pipe& mWritePipe; + std::atomic mIsOpened; +}; + +} // namespace aos::zephyr::communication From 6c721d184370ba1bb2297cfbc6f3ac09b66d170b Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Tue, 6 Aug 2024 18:50:41 +0300 Subject: [PATCH 071/198] [communication] Use socket for native build Signed-off-by: Mykola Solianko --- CMakeLists.txt | 7 +- Kconfig | 20 ++++- src/app/app.cpp | 17 ++-- src/app/app.hpp | 14 +++- src/communication/socket.cpp | 141 +++++++++++++++++++++++++++++++++ src/communication/socket.hpp | 82 +++++++++++++++++++ src/communication/xenvchan.cpp | 8 +- src/communication/xenvchan.hpp | 4 +- 8 files changed, 272 insertions(+), 21 deletions(-) create mode 100644 src/communication/socket.cpp create mode 100644 src/communication/socket.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 50a2c5b8..cb324a2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,7 +77,6 @@ target_sources( src/clocksync/clocksync.cpp src/communication/channelmanager.cpp src/communication/tlschannel.cpp - src/communication/xenvchan.cpp src/communication/channel.cpp src/communication/channelmanager.cpp src/downloader/downloader.cpp @@ -96,6 +95,12 @@ target_sources( src/utils/utils.cpp ) +# use pipe for native posix +target_sources_ifdef(CONFIG_NATIVE_APPLICATION app PRIVATE src/communication/socket.cpp) + +# use xenvchan for xen +target_sources_ifndef(CONFIG_NATIVE_APPLICATION app PRIVATE src/communication/xenvchan.cpp) + # Enable vchannels and xrun mocks for native posix target_sources_ifdef(CONFIG_NATIVE_APPLICATION app PRIVATE mocks/vch/vch.cpp mocks/xrun/xrun.cpp mocks/xstat/xstat.cpp) diff --git a/Kconfig b/Kconfig index 33113185..f2850c5a 100644 --- a/Kconfig +++ b/Kconfig @@ -9,12 +9,14 @@ config AOS_DOMD_ID int "DomD id" default 1 -config AOS_VCHAN_TX_PATH - string "Path to TX vchan" +config AOS_CHAN_TX_PATH + string "Path to TX channel" + depends on !NATIVE_APPLICATION default "/local/domain/1/tmp/vchan/aos/tx" -config AOS_VCHAN_RX_PATH - string "Path to RX vchan" +config AOS_CHAN_RX_PATH + string "Path to RX channel" + depends on !NATIVE_APPLICATION default "/local/domain/1/tmp/vchan/aos/rx" config AOS_REBOOT_XEN_STORE_PATH @@ -97,6 +99,16 @@ config AOS_SM_SECURE_PORT int "Aos SM secure port" default 4 +config AOS_SOCKET_SERVER_ADDRESS + string "Aos socket server address" + depends on NATIVE_APPLICATION + default "10.0.0.100" + +config AOS_SOCKET_SERVER_PORT + int "Aos socket server port" + depends on NATIVE_APPLICATION + default 30001 + config DOMD_UBOOT_PATH string "Location for Domain-D IPL binary" default "prebuilt/ipl.bin" diff --git a/src/app/app.cpp b/src/app/app.cpp index 7bcd6010..79adf484 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -181,15 +181,15 @@ Error App::InitZephyr() return AOS_ERROR_WRAP(err); } - if (auto err = mSMClient.Init(mClockSync, mChannelManager); !err.IsNone()) { + if (auto err = mStorage.Init(); !err.IsNone()) { return AOS_ERROR_WRAP(err); } - if (auto err = mStorage.Init(); !err.IsNone()) { + if (auto err = InitCommunication(); !err.IsNone()) { return AOS_ERROR_WRAP(err); } - if (auto err = InitCommunication(); !err.IsNone()) { + if (auto err = mSMClient.Init(mClockSync, mChannelManager); !err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -198,10 +198,17 @@ Error App::InitZephyr() Error App::InitCommunication() { - if (auto err = mTransport.Init(communication::XenVChan::cXSReadPath, communication::XenVChan::cXSWritePath); +#ifdef CONFIG_NATIVE_APPLICATION + if (auto err = mTransport.Init(communication::Socket::cServerAddress, communication::Socket::cServerPort); !err.IsNone()) { - return AOS_ERROR_WRAP(err); + return err; + } +#else + if (auto err = mTransport.Init(communication::XenVChan::cReadPath, communication::XenVChan::cWritePath); + !err.IsNone()) { + return err; } +#endif if (auto err = mChannelManager.Init(mTransport); !err.IsNone()) { return AOS_ERROR_WRAP(err); diff --git a/src/app/app.hpp b/src/app/app.hpp index 984351f4..75fc65c9 100644 --- a/src/app/app.hpp +++ b/src/app/app.hpp @@ -21,7 +21,11 @@ #include "clocksync/clocksync.hpp" #include "communication/channelmanager.hpp" +#ifdef CONFIG_NATIVE_APPLICATION +#include "communication/socket.hpp" +#else #include "communication/xenvchan.hpp" +#endif #include "downloader/downloader.hpp" #include "iamclient/iamclient.hpp" #include "monitoring/resourceusageprovider.hpp" @@ -88,9 +92,13 @@ class App : private NonCopyable { sm::resourcemanager::ResourceManager mResourceManager; sm::servicemanager::ServiceManager mServiceManager; - clocksync::ClockSync mClockSync; - communication::ChannelManager mChannelManager; - communication::XenVChan mTransport; + clocksync::ClockSync mClockSync; + communication::ChannelManager mChannelManager; +#ifdef CONFIG_NATIVE_APPLICATION + communication::Socket mTransport; +#else + communication::XenVChan mTransport; +#endif downloader::Downloader mDownloader; iamclient::IAMClient mIAMClient; monitoring::ResourceUsageProvider mResourceUsageProvider; diff --git a/src/communication/socket.cpp b/src/communication/socket.cpp new file mode 100644 index 00000000..6aadfa12 --- /dev/null +++ b/src/communication/socket.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "log.hpp" +#include "socket.hpp" + +namespace aos::zephyr::communication { + +/*********************************************************************************************************************** + * Public + **********************************************************************************************************************/ + +aos::Error Socket::Init(const aos::String& serverAddress, int serverPort) +{ + mServerAddress = serverAddress; + mServerPort = serverPort; + mSocketFd = -1; + + return aos::ErrorEnum::eNone; +} + +aos::Error Socket::Open() +{ + LOG_DBG() << "Connecting client socket to connect to: address=" << mServerAddress.CStr() << " port=" << mServerPort; + + mSocketFd = socket(AF_INET, SOCK_STREAM, 0); + if (mSocketFd == -1) { + return aos::Error(aos::ErrorEnum::eRuntime, "failed to create socket"); + } + + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(mServerPort); + + if (inet_pton(AF_INET, mServerAddress.CStr(), &addr.sin_addr) <= 0) { + close(mSocketFd); + mSocketFd = -1; + return aos::Error(aos::ErrorEnum::eRuntime, "invalid server address"); + } + + if (connect(mSocketFd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { + close(mSocketFd); + mSocketFd = -1; + return aos::Error(aos::ErrorEnum::eRuntime, "failed to connect to server"); + } + + LOG_DBG() << "Connected to server: address=" << mServerAddress.CStr() << " port=" << mServerPort; + + mOpened = true; + + return aos::ErrorEnum::eNone; +} + +aos::Error Socket::Close() +{ + if (mSocketFd != -1) { + close(mSocketFd); + mSocketFd = -1; + } + + mOpened = false; + + return aos::ErrorEnum::eNone; +} + +int Socket::Read(void* data, size_t size) +{ + LOG_DBG() << "Read from server: size=" << size; + + return ReadFromSocket(mSocketFd, data, size); +} + +int Socket::Write(const void* data, size_t size) +{ + LOG_DBG() << "Write to server: size=" << size; + + return WriteToSocket(mSocketFd, data, size); +} + +/*********************************************************************************************************************** + * Private + **********************************************************************************************************************/ + +int Socket::ReadFromSocket(int fd, void* data, size_t size) +{ + ssize_t readBytes = 0; + + while (readBytes < static_cast(size)) { + ssize_t len = recv(fd, static_cast(data) + readBytes, size - readBytes, 0); + if (len < 0) { + if (errno == EINTR) + continue; + + return -errno; + } + + if (len == 0) { + LOG_DBG() << "Connection closed by peer"; + + return -ECONNRESET; + } + + readBytes += len; + } + + LOG_DBG() << "Read from socket: readBytes=" << readBytes; + + return readBytes; +} + +int Socket::WriteToSocket(int fd, const void* data, size_t size) +{ + ssize_t writtenBytes = 0; + while (writtenBytes < static_cast(size)) { + ssize_t len = send(fd, static_cast(data) + writtenBytes, size - writtenBytes, 0); + if (len < 0) { + if (errno == EINTR) + continue; + + return -1; + } + + writtenBytes += len; + } + + LOG_DBG() << "Written to socket: writtenBytes=" << writtenBytes; + + return writtenBytes; +} + +} // namespace aos::zephyr::communication diff --git a/src/communication/socket.hpp b/src/communication/socket.hpp new file mode 100644 index 00000000..2e0f762f --- /dev/null +++ b/src/communication/socket.hpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOCKET_HPP_ +#define SOCKET_HPP_ + +#include + +#include "transport.hpp" + +namespace aos::zephyr::communication { + +class Socket : public TransportItf { +public: + constexpr static auto cServerAddress = CONFIG_AOS_SOCKET_SERVER_ADDRESS; + constexpr static auto cServerPort = CONFIG_AOS_SOCKET_SERVER_PORT; + + /** + * Initializes the socket. + * + * @param serverAddress Server address. + * @param serverPort Server port. + * @return aos::Error. + */ + Error Init(const aos::String& serverAddress, int serverPort); + + /** + * Opens the socket. + * + * @return aos::Error. + */ + Error Open() override; + + /** + * Returns if the socket is opened. + * + * @return bool. + */ + bool IsOpened() const override { return mOpened; }; + + /** + * Closes the pipes. + */ + Error Close() override; + + /** + * Reads data from the socket. + * + * @param data Buffer where data is placed. + * @param size Specifies how many bytes to read. + * @return int Number of bytes read. + */ + int Read(void* data, size_t size) override; + + /** + * Writes data to the socket. + * + * @param data Data buffer. + * @param size Specifies how many bytes to write. + * @return int Number of bytes written. + */ + int Write(const void* data, size_t size) override; + +private: + static constexpr auto cIPAddrLen = 16; + + int ReadFromSocket(int fd, void* data, size_t size); + int WriteToSocket(int fd, const void* data, size_t size); + + aos::StaticString mServerAddress; + int mServerPort {-1}; + int mSocketFd {-1}; + bool mOpened {}; +}; + +} // namespace aos::zephyr::communication + +#endif // SOCKET_HPP_ diff --git a/src/communication/xenvchan.cpp b/src/communication/xenvchan.cpp index 9403897b..bdb4fa43 100644 --- a/src/communication/xenvchan.cpp +++ b/src/communication/xenvchan.cpp @@ -56,16 +56,12 @@ aos::Error XenVChan::Close() int XenVChan::Read(void* data, size_t size) { - auto ret = vch_read(&mReadHandle, data, size); - - return ret; + return vch_read(&mReadHandle, data, size); } int XenVChan::Write(const void* data, size_t size) { - auto ret = vch_write(&mWriteHandle, data, size); - - return ret; + return vch_write(&mWriteHandle, data, size); } } // namespace aos::zephyr::communication diff --git a/src/communication/xenvchan.hpp b/src/communication/xenvchan.hpp index a0da2f8d..d079d91b 100644 --- a/src/communication/xenvchan.hpp +++ b/src/communication/xenvchan.hpp @@ -18,8 +18,8 @@ namespace aos::zephyr::communication { class XenVChan : public TransportItf { public: - static constexpr auto cXSReadPath = CONFIG_AOS_VCHAN_TX_PATH; - static constexpr auto cXSWritePath = CONFIG_AOS_VCHAN_RX_PATH; + static constexpr auto cReadPath = CONFIG_AOS_CHAN_TX_PATH; + static constexpr auto cWritePath = CONFIG_AOS_CHAN_RX_PATH; /** * Initializes vchan. From 2fea1559fe3f034e723bb0c45ccd5d6e77a175b7 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Fri, 16 Aug 2024 08:46:08 +0300 Subject: [PATCH 072/198] [tests] Fix smclient tests Signed-off-by: Mykola Solianko --- src/communication/channelmanager.cpp | 4 ++-- tests/stubs/channelmanagerstub.hpp | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/communication/channelmanager.cpp b/src/communication/channelmanager.cpp index 2a839cc9..6b211acc 100644 --- a/src/communication/channelmanager.cpp +++ b/src/communication/channelmanager.cpp @@ -226,7 +226,7 @@ Error ChannelManager::ReadFromTransport(AosProtocolHeader& header) return {ErrorEnum::eRuntime, "not enough memory in read buffer"}; } - LOG_DBG() << "Read channel CM: port=" << header.mPort << " size=" << header.mDataSize; + LOG_DBG() << "Read channel: port=" << header.mPort << " size=" << header.mDataSize; size_t totalRead = 0; @@ -247,7 +247,7 @@ Error ChannelManager::ProcessData(const AosProtocolHeader& header) { UniqueLock lock {mMutex}; - LOG_DBG() << "Read channel CM: port=" << header.mPort << " size=" << header.mDataSize; + LOG_DBG() << "Read channel: port=" << header.mPort << " size=" << header.mDataSize; auto [channel, err] = mChannels.At(header.mPort); if (!err.IsNone()) { diff --git a/tests/stubs/channelmanagerstub.hpp b/tests/stubs/channelmanagerstub.hpp index 7fe1cc6a..7d58c549 100644 --- a/tests/stubs/channelmanagerstub.hpp +++ b/tests/stubs/channelmanagerstub.hpp @@ -60,6 +60,15 @@ class ChannelManagerStub : public aos::zephyr::communication::ChannelManagerItf return mChannels[port].get(); } + aos::Error Close() override + { + for (auto& [port, channel] : mChannels) { + channel->Close(); + } + + return aos::ErrorEnum::eNone; + } + private: std::unordered_map> mChannels; std::mutex mMutex; From d0f822494350b964ea2c8124af31c72de1001406 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Tue, 20 Aug 2024 17:35:26 +0300 Subject: [PATCH 073/198] [app] Fix race initialization Signed-off-by: Mykola Solianko --- src/app/app.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index 79adf484..c645efe1 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -163,6 +163,10 @@ Error App::InitZephyr() return AOS_ERROR_WRAP(err); } + if (auto err = InitCommunication(); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + if (auto err = mIAMClient.Init(mClockSync, mNodeInfoProvider, mProvisionManager, mChannelManager, mCertHandler, mCertLoader); !err.IsNone()) { @@ -185,10 +189,6 @@ Error App::InitZephyr() return AOS_ERROR_WRAP(err); } - if (auto err = InitCommunication(); !err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - if (auto err = mSMClient.Init(mClockSync, mChannelManager); !err.IsNone()) { return AOS_ERROR_WRAP(err); } From 3b6e8efd52224159ea6976b37ea2fcf74f6ff622 Mon Sep 17 00:00:00 2001 From: Mykola Kobets Date: Thu, 22 Aug 2024 20:17:01 +0300 Subject: [PATCH 074/198] [mocks] Fix empty node info for host build Signed-off-by: Mykola Kobets --- mocks/xstat/xstat.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/mocks/xstat/xstat.cpp b/mocks/xstat/xstat.cpp index f2f6627f..717bac28 100644 --- a/mocks/xstat/xstat.cpp +++ b/mocks/xstat/xstat.cpp @@ -7,14 +7,33 @@ */ #include "xstat.h" +#include + +static constexpr auto MB = 1024 * 1024; int xstat_getstat(struct xenstat* stat) { + stat->num_cpus = 1; + stat->cpu_hz = 1000; + stat->tot_mem = 1024 * MB; + stat->free_mem = stat->tot_mem - 100 * MB; + strcpy(stat->xen_version, "1.0"); + return 0; } int xstat_getdominfo(struct xenstat_domain* info, uint16_t first, uint16_t num) { + info->id = first; + strcpy(info->name, "DOM0"); + + info->state = 0; + info->cpu_ns = 1; + info->num_vcpus = 0; + info->cur_mem = 1000; + info->max_mem = 1000 * MB; + info->ssid = 0; + return 0; } From 096a189168527c19046f99171b727e05a6be1b9d Mon Sep 17 00:00:00 2001 From: Mykola Kobets Date: Thu, 22 Aug 2024 20:18:45 +0300 Subject: [PATCH 075/198] [iamclient] Fix empty nodeID for CreateKey/ApplyCert responses Signed-off-by: Mykola Kobets --- src/iamclient/iamclient.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index 71c358b5..0753f3b9 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -561,7 +561,8 @@ Error IAMClient::ProcessCreateKey(const iamanager_v5_CreateKeyRequest& pbCreateK return SendError(outgoingMessage.Get(), pbCreateKeyResponse, AOS_ERROR_WRAP(err)); } - utils::StringFromCStr(pbCreateKeyResponse.type) = pbCreateKeyRequest.type; + utils::StringFromCStr(pbCreateKeyResponse.type) = pbCreateKeyRequest.type; + utils::StringFromCStr(pbCreateKeyResponse.node_id) = mNodeInfo.mNodeID; return SendMessage(outgoingMessage.Get(), &iamanager_v5_IAMOutgoingMessages_msg); } @@ -592,6 +593,7 @@ Error IAMClient::ProcessApplyCert(const iamanager_v5_ApplyCertRequest& pbApplyCe utils::StringFromCStr(pbApplyCertResponse.type) = pbApplyCertRequest.type; utils::StringFromCStr(pbApplyCertResponse.cert_url) = certInfo.mCertURL; + utils::StringFromCStr(pbApplyCertResponse.node_id) = mNodeInfo.mNodeID; if (auto err = utils::StringFromCStr(pbApplyCertResponse.serial).ByteArrayToHex(certInfo.mSerial); !err.IsNone()) { return SendError(outgoingMessage.Get(), pbApplyCertResponse, AOS_ERROR_WRAP(err)); From a09b104daabe050fb1f28463c91913363f44c42f Mon Sep 17 00:00:00 2001 From: Mykola Kobets Date: Thu, 22 Aug 2024 20:19:37 +0300 Subject: [PATCH 076/198] [nodeinfoprovider] Fix empty node name Signed-off-by: Mykola Kobets --- Kconfig | 4 ++++ src/nodeinfoprovider/nodeinfoprovider.cpp | 1 + src/nodeinfoprovider/nodeinfoprovider.hpp | 1 + 3 files changed, 6 insertions(+) diff --git a/Kconfig b/Kconfig index f2850c5a..3a694a3c 100644 --- a/Kconfig +++ b/Kconfig @@ -47,6 +47,10 @@ config AOS_NODE_ID string "Node id" default "NODE_0" +config AOS_NODE_NAME + string "Node name" + default "zephyr" + config AOS_NODE_TYPE string "Node type" default "NODE_TYPE1" diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp index 5750bcc2..f168cd9c 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -42,6 +42,7 @@ Error NodeInfoProvider::Init() return AOS_ERROR_WRAP(ret); } + mNodeInfo.mName = cNodeName; mNodeInfo.mTotalRAM = xstat.tot_mem; mNodeInfo.mNodeType = cNodeType; mNodeInfo.mMaxDMIPS = cMaxDMIPS; diff --git a/src/nodeinfoprovider/nodeinfoprovider.hpp b/src/nodeinfoprovider/nodeinfoprovider.hpp index ac20932c..7d743840 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.hpp +++ b/src/nodeinfoprovider/nodeinfoprovider.hpp @@ -60,6 +60,7 @@ class NodeInfoProvider : public iam::nodeinfoprovider::NodeInfoProviderItf { private: static constexpr auto cNodeStatusLen = 16; + static constexpr auto cNodeName = CONFIG_AOS_NODE_NAME; static constexpr auto cDiskPartitionPoint = CONFIG_AOS_DISK_MOUNT_POINT; static constexpr auto cMaxDMIPS = CONFIG_AOS_MAX_CPU_DMIPS; static constexpr auto cNodeType = CONFIG_AOS_NODE_TYPE; From 18ca9c9d46a326b8cd5aff2a4506a9e6efd9e7c3 Mon Sep 17 00:00:00 2001 From: Mykola Kobets Date: Fri, 23 Aug 2024 12:55:14 +0300 Subject: [PATCH 077/198] [nodeinfoprovider] Trim trailing new lines after reading nodeID Signed-off-by: Mykola Kobets --- src/nodeinfoprovider/nodeinfoprovider.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp index f168cd9c..b6aec66d 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -150,6 +150,8 @@ Error NodeInfoProvider::InitNodeID() if (auto err = FS::ReadFileToString(cNodeIDFile, mNodeInfo.mNodeID); !err.IsNone()) { return AOS_ERROR_WRAP(err); } + + mNodeInfo.mNodeID.Trim("\r\n"); #endif return ErrorEnum::eNone; From cec7fb595432edb319b6d0ce4545564b7cdc7135 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 21 Aug 2024 21:15:34 +0300 Subject: [PATCH 078/198] [smclient] Implement creating secure channel and handler Signed-off-by: Oleksandr Grytsov --- src/communication/pbhandler.hpp | 14 +- src/smclient/smclient.cpp | 151 +++++++++++++++++- src/smclient/smclient.hpp | 41 ++++- tests/smclient/src/main.cpp | 39 +++-- .../src/stubs/resourcemanagerstub.hpp | 60 +++++++ .../src => }/stubs/nodeinfoproviderstub.hpp | 0 6 files changed, 287 insertions(+), 18 deletions(-) create mode 100644 tests/smclient/src/stubs/resourcemanagerstub.hpp rename tests/{iamclient/src => }/stubs/nodeinfoproviderstub.hpp (100%) diff --git a/src/communication/pbhandler.hpp b/src/communication/pbhandler.hpp index 6bf17cf0..208c7217 100644 --- a/src/communication/pbhandler.hpp +++ b/src/communication/pbhandler.hpp @@ -51,6 +51,18 @@ class PBHandler { */ Error Stop(); + /** + * Returns true if handler is started. + * + * @return bool. + */ + bool IsStarted() const + { + LockGuard lock {mMutex}; + + return mStarted; + } + /** * Destructor. */ @@ -89,7 +101,7 @@ class PBHandler { StaticString<64> mName; ChannelItf* mChannel; - Mutex mMutex; + mutable Mutex mMutex; ConditionalVariable mCondVar; Thread<> mThread; bool mStarted = false; diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index 809dff9d..1503e6bd 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -5,8 +5,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "smclient.hpp" +#include + +#include "utils/pbconvert.hpp" + #include "log.hpp" +#include "smclient.hpp" + +#include "communication/pbhandler.cpp" namespace aos::zephyr::smclient { @@ -14,11 +20,25 @@ namespace aos::zephyr::smclient { * Public **********************************************************************************************************************/ -Error SMClient::Init(clocksync::ClockSyncItf& clockSync, communication::ChannelManagerItf& channelManager) +Error SMClient::Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider, + sm::resourcemanager::ResourceManagerItf& resourceManager, clocksync::ClockSyncItf& clockSync, + communication::ChannelManagerItf& channelManager) { LOG_DBG() << "Initialize SM client"; - auto [openChannel, err] = channelManager.CreateChannel(cOpenPort); + mNodeInfoProvider = &nodeInfoProvider; + mResourceManager = &resourceManager; + mChannelManager = &channelManager; + + auto nodeInfo = MakeUnique(&mAllocator); + + if (auto err = mNodeInfoProvider->GetNodeInfo(*nodeInfo); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + mProvisioned = nodeInfo->mStatus != NodeStatusEnum::eUnprovisioned; + + auto [openChannel, err] = mChannelManager->CreateChannel(cOpenPort); if (!err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -31,9 +51,36 @@ Error SMClient::Init(clocksync::ClockSyncItf& clockSync, communication::ChannelM return AOS_ERROR_WRAP(err); } + if (err = mNodeInfoProvider->SubscribeNodeStatusChanged(*this); err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + return ErrorEnum::eNone; } +SMClient::~SMClient() +{ + if (IsStarted()) { + if (auto err = Stop(); !err.IsNone()) { + LOG_ERR() << "Failed to stop PB handler: err=" << err; + } + + if (auto err = mChannelManager->DeleteChannel(cSecurePort); !err.IsNone()) { + LOG_ERR() << "Failed to delete channel: err=" << err; + } + } + + if (mOpenHandler.IsStarted()) { + if (auto err = mOpenHandler.Stop(); !err.IsNone()) { + LOG_ERR() << "Failed to stop open handler: err=" << err; + } + + if (auto err = mChannelManager->DeleteChannel(cOpenPort); !err.IsNone()) { + LOG_ERR() << "Failed to delete channel: err=" << err; + } + } +} + Error SMClient::InstancesRunStatus(const Array& instances) { return ErrorEnum::eNone; @@ -63,12 +110,45 @@ void SMClient::Unsubscribes(ConnectionSubscriberItf& subscriber) { } +Error SMClient::OnNodeStatusChanged(const String& nodeID, const NodeStatus& status) +{ + LOG_DBG() << "Node status changed: status=" << status; + + { + LockGuard lock {mMutex}; + + mProvisioned = status != NodeStatusEnum::eUnprovisioned; + } + + UpdatePBHandlerState(); + + return ErrorEnum::eNone; +} + void SMClient::OnClockSynced() { + LOG_DBG() << "Clock synced"; + + { + LockGuard lock {mMutex}; + + mClockSynced = true; + } + + UpdatePBHandlerState(); } void SMClient::OnClockUnsynced() { + LOG_DBG() << "Clock unsynced"; + + { + LockGuard lock {mMutex}; + + mClockSynced = false; + } + + UpdatePBHandlerState(); } Error SMClient::SendClockSyncRequest() @@ -76,4 +156,69 @@ Error SMClient::SendClockSyncRequest() return mOpenHandler.SendClockSyncRequest(); } +/*********************************************************************************************************************** + * Private + **********************************************************************************************************************/ + +void SMClient::OnConnect() +{ +} + +void SMClient::OnDisconnect() +{ +} + +Error SMClient::ReceiveMessage(const Array& data) +{ + return ErrorEnum::eNone; +} + +void SMClient::UpdatePBHandlerState() +{ + auto start = false; + auto stop = false; + + { + LockGuard lock {mMutex}; + + if (mClockSynced && mProvisioned && !IsStarted()) { + start = true; + } + + if ((!mClockSynced || !mProvisioned) && IsStarted()) { + stop = true; + } + } + + if (start) { + auto [secureChannel, err] = mChannelManager->CreateChannel(cSecurePort); + if (!err.IsNone()) { + LOG_ERR() << "Failed to create channel: err=" << err; + return; + } + + if (err = PBHandler::Init("SM secure", *secureChannel); !err.IsNone()) { + LOG_ERR() << "Failed to init PB handler: err=" << err; + return; + } + + if (err = Start(); !err.IsNone()) { + LOG_ERR() << "Failed to start PB handler: err=" << err; + return; + } + } + + if (stop) { + if (auto err = Stop(); !err.IsNone()) { + LOG_ERR() << "Failed to stop PB handler: err=" << err; + return; + } + + if (auto err = mChannelManager->DeleteChannel(cSecurePort); !err.IsNone()) { + LOG_ERR() << "Failed to delete channel: err=" << err; + return; + } + } +} + } // namespace aos::zephyr::smclient diff --git a/src/smclient/smclient.hpp b/src/smclient/smclient.hpp index 0ef477d3..6311e39f 100644 --- a/src/smclient/smclient.hpp +++ b/src/smclient/smclient.hpp @@ -24,7 +24,10 @@ namespace aos::zephyr::smclient { /** * SM client instance. */ -class SMClient : public sm::launcher::InstanceStatusReceiverItf, +class SMClient : public communication::PBHandler, + public iam::nodeinfoprovider::NodeStatusObserverItf, + public sm::launcher::InstanceStatusReceiverItf, public downloader::DownloadRequesterItf, public aos::monitoring::SenderItf, public ConnectionPublisherItf, @@ -35,16 +38,20 @@ class SMClient : public sm::launcher::InstanceStatusReceiverItf, /** * Initializes SM client instance. * + * @param nodeInfoProvider node info provider instance. + * @param resourceManager resource manager instance. * @param clockSync clock sync instance. * @param channelManager channel manager instance. * @return Error. */ - Error Init(clocksync::ClockSyncItf& clockSync, communication::ChannelManagerItf& channelManager); + Error Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider, + sm::resourcemanager::ResourceManagerItf& resourceManager, clocksync::ClockSyncItf& clockSync, + communication::ChannelManagerItf& channelManager); /** * Destructor. */ - ~SMClient() = default; + ~SMClient(); /** * Sends instances run status. @@ -100,6 +107,15 @@ class SMClient : public sm::launcher::InstanceStatusReceiverItf, */ Error SendClockSyncRequest() override; + /** + * On node status changed event. + * + * @param nodeID node id + * @param status node status + * @return Error + */ + Error OnNodeStatusChanged(const String& nodeID, const NodeStatus& status) override; + /** * Notifies subscriber clock is synced. */ @@ -114,7 +130,24 @@ class SMClient : public sm::launcher::InstanceStatusReceiverItf, static constexpr auto cOpenPort = CONFIG_AOS_SM_OPEN_PORT; static constexpr auto cSecurePort = CONFIG_AOS_SM_SECURE_PORT; - OpenHandler mOpenHandler; + void OnConnect() override; + void OnDisconnect() override; + Error ReceiveMessage(const Array& data) override; + + void UpdatePBHandlerState(); + + OpenHandler mOpenHandler; + iam::nodeinfoprovider::NodeInfoProviderItf* mNodeInfoProvider {}; + sm::resourcemanager::ResourceManagerItf* mResourceManager {}; + communication::ChannelManagerItf* mChannelManager {}; + + Mutex mMutex; + bool mClockSynced = false; + bool mProvisioned = false; + + StaticAllocator + mAllocator; }; } // namespace aos::zephyr::smclient diff --git a/tests/smclient/src/main.cpp b/tests/smclient/src/main.cpp index 8ed40b8b..0ab06977 100644 --- a/tests/smclient/src/main.cpp +++ b/tests/smclient/src/main.cpp @@ -5,6 +5,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + #include #include @@ -12,6 +14,8 @@ #include "stubs/channelmanagerstub.hpp" #include "stubs/clocksyncstub.hpp" +#include "stubs/nodeinfoproviderstub.hpp" +#include "stubs/resourcemanagerstub.hpp" #include "utils/log.hpp" #include "utils/pbmessages.hpp" #include "utils/utils.hpp" @@ -29,9 +33,11 @@ static constexpr auto cWaitTimeout = std::chrono::seconds {5}; **********************************************************************************************************************/ struct smclient_fixture { - ClockSyncStub mClockSync; - ChannelManagerStub mChannelManager; - smclient::SMClient mSMClient; + NodeInfoProviderStub mNodeInfoProvider; + ResourceManagerStub mResourceManager; + ClockSyncStub mClockSync; + ChannelManagerStub mChannelManager; + std::unique_ptr mSMClient; }; /*********************************************************************************************************************** @@ -50,6 +56,21 @@ static aos::Error SendSMIncomingMessage(ChannelStub* channel, const servicemanag channel, &message, servicemanager_v4_SMIncomingMessages_size, &servicemanager_v4_SMIncomingMessages_msg); } +static aos::RetWithError InitSMClient(smclient_fixture* fixture, uint32_t port, + const aos::NodeInfo& nodeInfo = {}, const aos::String& nodeConfigVersion = "1.0.0") +{ + fixture->mNodeInfoProvider.SetNodeInfo(nodeInfo); + fixture->mResourceManager.UpdateNodeConfig(nodeConfigVersion, ""); + + auto err = fixture->mSMClient->Init( + fixture->mNodeInfoProvider, fixture->mResourceManager, fixture->mClockSync, fixture->mChannelManager); + zassert_true(err.IsNone(), "Can't initialize SM client: %s", utils::ErrorToCStr(err)); + + fixture->mSMClient->OnClockSynced(); + + return fixture->mChannelManager.GetChannel(CONFIG_AOS_SM_OPEN_PORT); +} + /*********************************************************************************************************************** * Setup **********************************************************************************************************************/ @@ -61,13 +82,11 @@ ZTEST_SUITE( auto fixture = new smclient_fixture; - auto err = fixture->mSMClient.Init(fixture->mClockSync, fixture->mChannelManager); - - zassert_true(err.IsNone(), "Can't initialize SM client: %s", utils::ErrorToCStr(err)); - return fixture; }, - nullptr, nullptr, [](void* fixture) { delete static_cast(fixture); }); + [](void* fixture) { static_cast(fixture)->mSMClient.reset(new smclient::SMClient); }, + [](void* fixture) { static_cast(fixture)->mSMClient.reset(); }, + [](void* fixture) { delete static_cast(fixture); }); /*********************************************************************************************************************** * Tests @@ -75,7 +94,7 @@ ZTEST_SUITE( ZTEST_F(smclient, test_ClockSync) { - auto [channel, err] = fixture->mChannelManager.GetChannel(CONFIG_AOS_SM_OPEN_PORT); + auto [channel, err] = InitSMClient(fixture, CONFIG_AOS_SM_OPEN_PORT); zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); // Wait clock sync start @@ -87,7 +106,7 @@ ZTEST_F(smclient, test_ClockSync) // Wait clock sync request - err = fixture->mSMClient.SendClockSyncRequest(); + err = fixture->mSMClient->SendClockSyncRequest(); zassert_true(err.IsNone(), "Error sending clock sync request: %s", utils::ErrorToCStr(err)); diff --git a/tests/smclient/src/stubs/resourcemanagerstub.hpp b/tests/smclient/src/stubs/resourcemanagerstub.hpp new file mode 100644 index 00000000..4f4b37e5 --- /dev/null +++ b/tests/smclient/src/stubs/resourcemanagerstub.hpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef RESOURCEMANAGERSTUB_HPP_ +#define RESOURCEMANAGERSTUB_HPP_ + +#include + +class ResourceManagerStub : public aos::sm::resourcemanager::ResourceManagerItf { +public: + aos::RetWithError> GetNodeConfigVersion() const override { return {"1.0.0"}; } + + aos::Error GetDeviceInfo(const aos::String& deviceName, aos::DeviceInfo& deviceInfo) const override + { + return aos::ErrorEnum::eNone; + } + + aos::Error GetResourceInfo(const aos::String& resourceName, aos::ResourceInfo& resourceInfo) const override + { + return aos::ErrorEnum::eNone; + } + + aos::Error AllocateDevice(const aos::String& deviceName, const aos::String& instanceID) override + { + return aos::ErrorEnum::eNone; + } + + aos::Error ReleaseDevice(const aos::String& deviceName, const aos::String& instanceID) override + { + return aos::ErrorEnum::eNone; + } + + aos::Error ReleaseDevices(const aos::String& instanceID) override { return aos::ErrorEnum::eNone; } + + aos::Error GetDeviceInstances( + const aos::String& deviceName, aos::Array>& instanceIDs) const override + { + return aos::ErrorEnum::eNone; + } + + aos::Error CheckNodeConfig(const aos::String& version, const aos::String& config) const override + { + return aos::ErrorEnum::eNone; + } + + aos::Error UpdateNodeConfig(const aos::String& version, const aos::String& config) override + { + return aos::ErrorEnum::eNone; + } + +private: + aos::StaticString mVersion; + aos::StaticString mConfig; +}; + +#endif diff --git a/tests/iamclient/src/stubs/nodeinfoproviderstub.hpp b/tests/stubs/nodeinfoproviderstub.hpp similarity index 100% rename from tests/iamclient/src/stubs/nodeinfoproviderstub.hpp rename to tests/stubs/nodeinfoproviderstub.hpp From a9d89eb163b172cc13e4766e94196b43fb74e89e Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 22 Aug 2024 10:28:01 +0300 Subject: [PATCH 079/198] [utils] Fix setting correct sting len in StringFromCStr Signed-off-by: Oleksandr Grytsov --- src/utils/utils.hpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/utils/utils.hpp b/src/utils/utils.hpp index 311fb09b..a7740a82 100644 --- a/src/utils/utils.hpp +++ b/src/utils/utils.hpp @@ -22,7 +22,12 @@ namespace aos::zephyr::utils { template constexpr String StringFromCStr(char (&cStr)[cSize]) { - return String(cStr, cSize - 1); + auto str = String(cStr, cSize - 1); + + cStr[cSize - 1] = '\0'; + str.Resize(strlen(cStr)); + + return str; } /** @@ -35,7 +40,10 @@ constexpr String StringFromCStr(char (&cStr)[cSize]) template constexpr const String StringFromCStr(const char (&cStr)[cSize]) { - return String(cStr, cSize - 1); + auto str = String(cStr, cSize - 1); + str.Resize(strlen(cStr)); + + return str; } /** From 7f9fe79d8108087293b0f8ddbaf3b05b00d83988 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 22 Aug 2024 10:29:18 +0300 Subject: [PATCH 080/198] [smclient] Implement handling of get/set node config messages Signed-off-by: Oleksandr Grytsov --- src/smclient/smclient.cpp | 96 ++++++++++++++- src/smclient/smclient.hpp | 6 +- tests/smclient/src/main.cpp | 114 +++++++++++++++++- .../src/stubs/resourcemanagerstub.hpp | 7 +- 4 files changed, 218 insertions(+), 5 deletions(-) diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index 1503e6bd..d036083f 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -170,7 +170,94 @@ void SMClient::OnDisconnect() Error SMClient::ReceiveMessage(const Array& data) { - return ErrorEnum::eNone; + LockGuard lock {mMutex}; + + auto incomingMessages = MakeUnique(&mAllocator); + auto stream = pb_istream_from_buffer(data.Get(), data.Size()); + + if (auto status = pb_decode(&stream, &servicemanager_v4_SMIncomingMessages_msg, incomingMessages.Get()); !status) { + return AOS_ERROR_WRAP(Error(ErrorEnum::eRuntime, "failed to decode message")); + } + + Error err; + + switch (incomingMessages->which_SMIncomingMessage) { + case servicemanager_v4_SMIncomingMessages_get_node_config_status_tag: + err = ProcessGetNodeConfigStatus(incomingMessages->SMIncomingMessage.get_node_config_status); + break; + + case servicemanager_v4_SMIncomingMessages_check_node_config_tag: + err = ProcessCheckNodeConfig(incomingMessages->SMIncomingMessage.check_node_config); + break; + + case servicemanager_v4_SMIncomingMessages_set_node_config_tag: + err = ProcessSetNodeConfig(incomingMessages->SMIncomingMessage.set_node_config); + break; + + default: + LOG_WRN() << "Receive unsupported message: tag=" << incomingMessages->which_SMIncomingMessage; + break; + } + + return err; +} + +Error SMClient::ProcessGetNodeConfigStatus(const servicemanager_v4_GetNodeConfigStatus& pbGetNodeConfigStatus) +{ + LOG_INF() << "Process get node config status"; + + auto [version, configErr] = mResourceManager->GetNodeConfigVersion(); + + return SendNodeConfigStatus(version, configErr); +} + +Error SMClient::ProcessCheckNodeConfig(const servicemanager_v4_CheckNodeConfig& pbCheckNodeConfig) +{ + auto version = utils::StringFromCStr(pbCheckNodeConfig.version); + + LOG_INF() << "Process check node config: version=" << version; + + auto configErr = mResourceManager->CheckNodeConfig(version, utils::StringFromCStr(pbCheckNodeConfig.node_config)); + + return SendNodeConfigStatus(version, configErr); +} + +Error SMClient::ProcessSetNodeConfig(const servicemanager_v4_SetNodeConfig& pbSetNodeConfig) +{ + auto version = utils::StringFromCStr(pbSetNodeConfig.version); + + LOG_INF() << "Process set node config: version=" << version; + + auto configErr = mResourceManager->UpdateNodeConfig(version, utils::StringFromCStr(pbSetNodeConfig.node_config)); + + return SendNodeConfigStatus(version, configErr); +} + +Error SMClient::SendNodeConfigStatus(const String& version, const Error& configErr) +{ + LOG_INF() << "Send node config status: version=" << version << ", configErr=" << configErr; + + auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto& pbNodeConfigStatus = outgoingMessage->SMOutgoingMessage.node_config_status; + + outgoingMessage->which_SMOutgoingMessage = servicemanager_v4_SMOutgoingMessages_node_config_status_tag; + pbNodeConfigStatus = servicemanager_v4_NodeConfigStatus servicemanager_v4_NodeConfigStatus_init_default; + + auto nodeInfo = MakeUnique(&mAllocator); + + if (auto err = mNodeInfoProvider->GetNodeInfo(*nodeInfo); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + utils::StringFromCStr(pbNodeConfigStatus.node_id) = nodeInfo->mNodeID; + utils::StringFromCStr(pbNodeConfigStatus.node_type) = nodeInfo->mNodeType; + utils::StringFromCStr(pbNodeConfigStatus.version) = version; + + if (!configErr.IsNone()) { + utils::ErrorToPB(configErr, pbNodeConfigStatus); + } + + return SendMessage(outgoingMessage.Get(), &servicemanager_v4_SMOutgoingMessages_msg); } void SMClient::UpdatePBHandlerState() @@ -206,6 +293,13 @@ void SMClient::UpdatePBHandlerState() LOG_ERR() << "Failed to start PB handler: err=" << err; return; } + + auto [version, configErr] = mResourceManager->GetNodeConfigVersion(); + + if (err = SendNodeConfigStatus(version, configErr); !err.IsNone()) { + LOG_ERR() << "Failed to send node config status: err=" << err; + return; + } } if (stop) { diff --git a/src/smclient/smclient.hpp b/src/smclient/smclient.hpp index 6311e39f..e11ab668 100644 --- a/src/smclient/smclient.hpp +++ b/src/smclient/smclient.hpp @@ -134,7 +134,11 @@ class SMClient : public communication::PBHandler& data) override; - void UpdatePBHandlerState(); + void UpdatePBHandlerState(); + Error SendNodeConfigStatus(const String& version, const Error& configErr); + Error ProcessGetNodeConfigStatus(const servicemanager_v4_GetNodeConfigStatus& pbGetNodeConfigStatus); + Error ProcessCheckNodeConfig(const servicemanager_v4_CheckNodeConfig& pbCheckNodeConfig); + Error ProcessSetNodeConfig(const servicemanager_v4_SetNodeConfig& pbSetNodeConfig); OpenHandler mOpenHandler; iam::nodeinfoprovider::NodeInfoProviderItf* mNodeInfoProvider {}; diff --git a/tests/smclient/src/main.cpp b/tests/smclient/src/main.cpp index 0ab06977..215f605e 100644 --- a/tests/smclient/src/main.cpp +++ b/tests/smclient/src/main.cpp @@ -56,6 +56,25 @@ static aos::Error SendSMIncomingMessage(ChannelStub* channel, const servicemanag channel, &message, servicemanager_v4_SMIncomingMessages_size, &servicemanager_v4_SMIncomingMessages_msg); } +static void ReceiveNodeConfigStatus( + ChannelStub* channel, const aos::NodeInfo& nodeInfo, const aos::String& nodeConfigVersion) +{ + servicemanager_v4_SMOutgoingMessages outgoingMessage; + auto& pbNodeConfigStatus = outgoingMessage.SMOutgoingMessage.node_config_status; + + pbNodeConfigStatus = servicemanager_v4_NodeConfigStatus servicemanager_v4_NodeConfigStatus_init_default; + + auto err = ReceiveSMOutgoingMessage(channel, outgoingMessage); + zassert_true(err.IsNone(), "Error receiving message: %s", utils::ErrorToCStr(err)); + + zassert_equal(outgoingMessage.which_SMOutgoingMessage, servicemanager_v4_SMOutgoingMessages_node_config_status_tag, + "Unexpected message type"); + zassert_false(pbNodeConfigStatus.has_error, "Unexpected error received"); + zassert_equal(pbNodeConfigStatus.node_id, nodeInfo.mNodeID, "Wrong node ID"); + zassert_equal(pbNodeConfigStatus.node_type, nodeInfo.mNodeType, "Wrong node type"); + zassert_equal(pbNodeConfigStatus.version, nodeConfigVersion, "Wrong node config version"); +} + static aos::RetWithError InitSMClient(smclient_fixture* fixture, uint32_t port, const aos::NodeInfo& nodeInfo = {}, const aos::String& nodeConfigVersion = "1.0.0") { @@ -68,7 +87,16 @@ static aos::RetWithError InitSMClient(smclient_fixture* fixture, u fixture->mSMClient->OnClockSynced(); - return fixture->mChannelManager.GetChannel(CONFIG_AOS_SM_OPEN_PORT); + auto channel = fixture->mChannelManager.GetChannel(port); + if (!channel.mError.IsNone()) { + return {nullptr, channel.mError}; + } + + if (port == CONFIG_AOS_SM_SECURE_PORT) { + ReceiveNodeConfigStatus(channel.mValue, nodeInfo, nodeConfigVersion); + } + + return channel; } /*********************************************************************************************************************** @@ -84,7 +112,12 @@ ZTEST_SUITE( return fixture; }, - [](void* fixture) { static_cast(fixture)->mSMClient.reset(new smclient::SMClient); }, + [](void* fixture) { + auto smclientFixture = static_cast(fixture); + + smclientFixture->mClockSync.Clear(); + smclientFixture->mSMClient.reset(new smclient::SMClient); + }, [](void* fixture) { static_cast(fixture)->mSMClient.reset(); }, [](void* fixture) { delete static_cast(fixture); }); @@ -144,3 +177,80 @@ ZTEST_F(smclient, test_ClockSync) zassert_equal(fixture->mClockSync.GetSyncTime(), timestamp, "Wrong timestamp"); } + +ZTEST_F(smclient, test_GetNodeConfigStatus) +{ + const auto nodeConfigVersion = "1.0.0"; + aos::NodeInfo nodeInfo {.mNodeID = "nodeID", .mNodeType = "nodeType", .mStatus = aos::NodeStatusEnum::eProvisioned}; + + auto [channel, err] = InitSMClient(fixture, CONFIG_AOS_SM_SECURE_PORT, nodeInfo, nodeConfigVersion); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Send get node config status + + servicemanager_v4_SMIncomingMessages incomingMessage; + auto& pbGetNodeConfigStatus = incomingMessage.SMIncomingMessage.get_node_config_status; + + incomingMessage.which_SMIncomingMessage = servicemanager_v4_SMIncomingMessages_get_node_config_status_tag; + pbGetNodeConfigStatus = servicemanager_v4_GetNodeConfigStatus servicemanager_v4_GetNodeConfigStatus_init_default; + + err = SendSMIncomingMessage(channel, incomingMessage); + zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + + // Receive node config status + + ReceiveNodeConfigStatus(channel, nodeInfo, nodeConfigVersion); +} + +ZTEST_F(smclient, test_CheckNodeConfig) +{ + aos::NodeInfo nodeInfo {.mNodeID = "nodeID", .mNodeType = "nodeType", .mStatus = aos::NodeStatusEnum::eProvisioned}; + + auto [channel, err] = InitSMClient(fixture, CONFIG_AOS_SM_SECURE_PORT, nodeInfo); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Send get node config status + + servicemanager_v4_SMIncomingMessages incomingMessage; + auto& pbCheckNodeConfig = incomingMessage.SMIncomingMessage.check_node_config; + + incomingMessage.which_SMIncomingMessage = servicemanager_v4_SMIncomingMessages_check_node_config_tag; + pbCheckNodeConfig = servicemanager_v4_CheckNodeConfig servicemanager_v4_CheckNodeConfig_init_default; + + utils::StringFromCStr(pbCheckNodeConfig.node_config) = "check node config"; + utils::StringFromCStr(pbCheckNodeConfig.version) = "2.0.0"; + + err = SendSMIncomingMessage(channel, incomingMessage); + zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + + // Receive node config status + + ReceiveNodeConfigStatus(channel, nodeInfo, pbCheckNodeConfig.version); +} + +ZTEST_F(smclient, test_SetNodeConfig) +{ + aos::NodeInfo nodeInfo {.mNodeID = "nodeID", .mNodeType = "nodeType", .mStatus = aos::NodeStatusEnum::eProvisioned}; + + auto [channel, err] = InitSMClient(fixture, CONFIG_AOS_SM_SECURE_PORT, nodeInfo); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Send get node config status + + servicemanager_v4_SMIncomingMessages incomingMessage; + auto& pbSetNodeConfig = incomingMessage.SMIncomingMessage.set_node_config; + + incomingMessage.which_SMIncomingMessage = servicemanager_v4_SMIncomingMessages_set_node_config_tag; + pbSetNodeConfig = servicemanager_v4_SetNodeConfig servicemanager_v4_SetNodeConfig_init_default; + + utils::StringFromCStr(pbSetNodeConfig.node_config) = "set node config"; + utils::StringFromCStr(pbSetNodeConfig.version) = "2.0.0"; + + err = SendSMIncomingMessage(channel, incomingMessage); + zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + + // Receive node config status + + ReceiveNodeConfigStatus(channel, nodeInfo, pbSetNodeConfig.version); + zassert_equal(fixture->mResourceManager.GetNodeConfig(), pbSetNodeConfig.node_config, "Wrong node config"); +} diff --git a/tests/smclient/src/stubs/resourcemanagerstub.hpp b/tests/smclient/src/stubs/resourcemanagerstub.hpp index 4f4b37e5..482269da 100644 --- a/tests/smclient/src/stubs/resourcemanagerstub.hpp +++ b/tests/smclient/src/stubs/resourcemanagerstub.hpp @@ -12,7 +12,7 @@ class ResourceManagerStub : public aos::sm::resourcemanager::ResourceManagerItf { public: - aos::RetWithError> GetNodeConfigVersion() const override { return {"1.0.0"}; } + aos::RetWithError> GetNodeConfigVersion() const override { return mVersion; } aos::Error GetDeviceInfo(const aos::String& deviceName, aos::DeviceInfo& deviceInfo) const override { @@ -49,9 +49,14 @@ class ResourceManagerStub : public aos::sm::resourcemanager::ResourceManagerItf aos::Error UpdateNodeConfig(const aos::String& version, const aos::String& config) override { + mVersion = version; + mConfig = config; + return aos::ErrorEnum::eNone; } + const aos::String& GetNodeConfig() const { return mConfig; } + private: aos::StaticString mVersion; aos::StaticString mConfig; From d2c75dfcd9de917794aefd00992b7033c2b69562 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 22 Aug 2024 16:10:00 +0300 Subject: [PATCH 081/198] [smclient] Implement sending node instant and average monitoring Signed-off-by: Oleksandr Grytsov --- src/smclient/smclient.cpp | 91 ++++++++++- src/smclient/smclient.hpp | 13 +- tests/smclient/src/main.cpp | 142 +++++++++++++++++- .../src/stubs/resourcemonitorstub.hpp | 39 +++++ 4 files changed, 274 insertions(+), 11 deletions(-) create mode 100644 tests/smclient/src/stubs/resourcemonitorstub.hpp diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index d036083f..cc499ba5 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -16,18 +16,64 @@ namespace aos::zephyr::smclient { +/*********************************************************************************************************************** + * Static + **********************************************************************************************************************/ + +static google_protobuf_Timestamp TimestampToPB(const Time& time) +{ + auto unixTime = time.UnixTime(); + + return google_protobuf_Timestamp {unixTime.tv_sec, static_cast(unixTime.tv_nsec)}; +} + +static void MonitoringDataToPB(const monitoring::MonitoringData& monitoringData, const Time& timestamp, + servicemanager_v4_MonitoringData& pbMonitoringData) +{ + pbMonitoringData.cpu = monitoringData.mCPU; + pbMonitoringData.ram = monitoringData.mRAM; + pbMonitoringData.download = monitoringData.mDownload; + pbMonitoringData.upload = monitoringData.mUpload; + pbMonitoringData.disk_count = monitoringData.mDisk.Size(); + pbMonitoringData.has_timestamp = true; + pbMonitoringData.timestamp = TimestampToPB(timestamp); + + for (size_t i = 0; i < monitoringData.mDisk.Size(); i++) { + utils::StringFromCStr(pbMonitoringData.disk[i].name) = monitoringData.mDisk[i].mName; + pbMonitoringData.disk[i].used_size = monitoringData.mDisk[i].mUsedSize; + } +} + +template +static constexpr void NodeMonitoringToPB(const monitoring::NodeMonitoringData& nodeMonitoring, T& pbNodeMonitoring) +{ + pbNodeMonitoring.has_node_monitoring = true; + MonitoringDataToPB(nodeMonitoring.mMonitoringData, nodeMonitoring.mTimestamp, pbNodeMonitoring.node_monitoring); + pbNodeMonitoring.instances_monitoring_count = nodeMonitoring.mServiceInstances.Size(); + + for (size_t i = 0; i < nodeMonitoring.mServiceInstances.Size(); i++) { + pbNodeMonitoring.instances_monitoring[i].has_instance = true; + utils::InstanceIdentToPB( + nodeMonitoring.mServiceInstances[i].mInstanceIdent, pbNodeMonitoring.instances_monitoring[i].instance); + pbNodeMonitoring.instances_monitoring[i].has_monitoring_data = true; + MonitoringDataToPB(nodeMonitoring.mServiceInstances[i].mMonitoringData, nodeMonitoring.mTimestamp, + pbNodeMonitoring.instances_monitoring[i].monitoring_data); + } +} + /*********************************************************************************************************************** * Public **********************************************************************************************************************/ Error SMClient::Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider, - sm::resourcemanager::ResourceManagerItf& resourceManager, clocksync::ClockSyncItf& clockSync, - communication::ChannelManagerItf& channelManager) + sm::resourcemanager::ResourceManagerItf& resourceManager, monitoring::ResourceMonitorItf& resourceMonitor, + clocksync::ClockSyncItf& clockSync, communication::ChannelManagerItf& channelManager) { LOG_DBG() << "Initialize SM client"; mNodeInfoProvider = &nodeInfoProvider; mResourceManager = &resourceManager; + mResourceMonitor = &resourceMonitor; mChannelManager = &channelManager; auto nodeInfo = MakeUnique(&mAllocator); @@ -96,9 +142,21 @@ Error SMClient::SendImageContentRequest(const downloader::ImageContentRequest& r return ErrorEnum::eNone; } -Error SMClient::SendMonitoringData(const monitoring::NodeMonitoringData& monitoringData) +Error SMClient::SendMonitoringData(const monitoring::NodeMonitoringData& nodeMonitoring) { - return ErrorEnum::eNone; + LockGuard lock {mMutex}; + + LOG_INF() << "Send node monitoring"; + + auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto& pbInstantMonitoring = outgoingMessage->SMOutgoingMessage.instant_monitoring; + + outgoingMessage->which_SMOutgoingMessage = servicemanager_v4_SMOutgoingMessages_instant_monitoring_tag; + pbInstantMonitoring = servicemanager_v4_InstantMonitoring servicemanager_v4_InstantMonitoring_init_default; + + NodeMonitoringToPB(nodeMonitoring, pbInstantMonitoring); + + return SendMessage(outgoingMessage.Get(), &servicemanager_v4_SMOutgoingMessages_msg); } Error SMClient::Subscribes(ConnectionSubscriberItf& subscriber) @@ -194,6 +252,10 @@ Error SMClient::ReceiveMessage(const Array& data) err = ProcessSetNodeConfig(incomingMessages->SMIncomingMessage.set_node_config); break; + case servicemanager_v4_SMIncomingMessages_get_average_monitoring_tag: + err = ProcessGetAverageMonitoring(incomingMessages->SMIncomingMessage.get_average_monitoring); + break; + default: LOG_WRN() << "Receive unsupported message: tag=" << incomingMessages->which_SMIncomingMessage; break; @@ -233,6 +295,27 @@ Error SMClient::ProcessSetNodeConfig(const servicemanager_v4_SetNodeConfig& pbSe return SendNodeConfigStatus(version, configErr); } +Error SMClient::ProcessGetAverageMonitoring(const servicemanager_v4_GetAverageMonitoring& pbGetAverageMonitoring) +{ + LOG_INF() << "Process get average monitoring"; + + auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto& pbAverageMonitoring = outgoingMessage->SMOutgoingMessage.average_monitoring; + + outgoingMessage->which_SMOutgoingMessage = servicemanager_v4_SMOutgoingMessages_average_monitoring_tag; + pbAverageMonitoring = servicemanager_v4_AverageMonitoring servicemanager_v4_AverageMonitoring_init_default; + + auto averageMonitoring = aos::MakeUnique(&mAllocator); + + if (auto err = mResourceMonitor->GetAverageMonitoringData(*averageMonitoring); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + NodeMonitoringToPB(*averageMonitoring, pbAverageMonitoring); + + return SendMessage(outgoingMessage.Get(), &servicemanager_v4_SMOutgoingMessages_msg); +} + Error SMClient::SendNodeConfigStatus(const String& version, const Error& configErr) { LOG_INF() << "Send node config status: version=" << version << ", configErr=" << configErr; diff --git a/src/smclient/smclient.hpp b/src/smclient/smclient.hpp index e11ab668..6abca8d1 100644 --- a/src/smclient/smclient.hpp +++ b/src/smclient/smclient.hpp @@ -40,13 +40,14 @@ class SMClient : public communication::PBHandler + + Max(sizeof(NodeInfo), sizeof(aos::monitoring::NodeMonitoringData))> mAllocator; }; diff --git a/tests/smclient/src/main.cpp b/tests/smclient/src/main.cpp index 215f605e..d2d043c2 100644 --- a/tests/smclient/src/main.cpp +++ b/tests/smclient/src/main.cpp @@ -16,7 +16,9 @@ #include "stubs/clocksyncstub.hpp" #include "stubs/nodeinfoproviderstub.hpp" #include "stubs/resourcemanagerstub.hpp" +#include "stubs/resourcemonitorstub.hpp" #include "utils/log.hpp" +#include "utils/pbconvert.hpp" #include "utils/pbmessages.hpp" #include "utils/utils.hpp" @@ -35,6 +37,7 @@ static constexpr auto cWaitTimeout = std::chrono::seconds {5}; struct smclient_fixture { NodeInfoProviderStub mNodeInfoProvider; ResourceManagerStub mResourceManager; + ResourceMonitorStub mResourceMonitor; ClockSyncStub mClockSync; ChannelManagerStub mChannelManager; std::unique_ptr mSMClient; @@ -81,8 +84,8 @@ static aos::RetWithError InitSMClient(smclient_fixture* fixture, u fixture->mNodeInfoProvider.SetNodeInfo(nodeInfo); fixture->mResourceManager.UpdateNodeConfig(nodeConfigVersion, ""); - auto err = fixture->mSMClient->Init( - fixture->mNodeInfoProvider, fixture->mResourceManager, fixture->mClockSync, fixture->mChannelManager); + auto err = fixture->mSMClient->Init(fixture->mNodeInfoProvider, fixture->mResourceManager, + fixture->mResourceMonitor, fixture->mClockSync, fixture->mChannelManager); zassert_true(err.IsNone(), "Can't initialize SM client: %s", utils::ErrorToCStr(err)); fixture->mSMClient->OnClockSynced(); @@ -99,6 +102,65 @@ static aos::RetWithError InitSMClient(smclient_fixture* fixture, u return channel; } +static void PBToMonitoringData( + const servicemanager_v4_MonitoringData& pbMonitoring, aos::monitoring::MonitoringData& aosMonitoring) +{ + aosMonitoring.mRAM = pbMonitoring.ram; + aosMonitoring.mCPU = pbMonitoring.cpu; + aosMonitoring.mDisk.Resize(pbMonitoring.disk_count); + + for (size_t i = 0; i < pbMonitoring.disk_count; i++) { + aosMonitoring.mDisk[i].mName = utils::StringFromCStr(pbMonitoring.disk[i].name); + aosMonitoring.mDisk[i].mUsedSize = pbMonitoring.disk[i].used_size; + } + + aosMonitoring.mDownload = pbMonitoring.download; + aosMonitoring.mUpload = pbMonitoring.upload; +} + +template +static void PBToNodeMonitoring(const T& pbNodeMonitoring, aos::monitoring::NodeMonitoringData& nodeMonitoring) +{ + if (pbNodeMonitoring.has_node_monitoring) { + if (pbNodeMonitoring.node_monitoring.has_timestamp) { + nodeMonitoring.mTimestamp = aos::Time::Unix( + pbNodeMonitoring.node_monitoring.timestamp.seconds, pbNodeMonitoring.node_monitoring.timestamp.nanos); + } + + PBToMonitoringData(pbNodeMonitoring.node_monitoring, nodeMonitoring.mMonitoringData); + } + + nodeMonitoring.mServiceInstances.Resize(pbNodeMonitoring.instances_monitoring_count); + + for (size_t i = 0; i < pbNodeMonitoring.instances_monitoring_count; i++) { + utils::PBToInstanceIdent( + pbNodeMonitoring.instances_monitoring[i].instance, nodeMonitoring.mServiceInstances[i].mInstanceIdent); + PBToMonitoringData(pbNodeMonitoring.instances_monitoring[i].monitoring_data, + nodeMonitoring.mServiceInstances[i].mMonitoringData); + } +} + +static void GenerateNodeMonitoring(aos::monitoring::NodeMonitoringData& nodeMonitoring) +{ + aos::PartitionInfo nodeDisks[] = {{.mName = "disk1", .mUsedSize = 512}, {.mName = "disk2", .mUsedSize = 1024}}; + aos::PartitionInfo instanceDisks[] = {{.mName = "disk3", .mUsedSize = 2048}}; + + aos::monitoring::InstanceMonitoringData instancesData[] = { + {{"service1", "subject1", 1}, + {2000, 34423, aos::Array(instanceDisks, aos::ArraySize(instanceDisks)), 342, 432}}, + {{"service2", "subject2", 2}, + {3000, 54344, aos::Array(instanceDisks, aos::ArraySize(instanceDisks)), 432, 321}}, + {{"service3", "subject3", 3}, + {4000, 90995, aos::Array(instanceDisks, aos::ArraySize(instanceDisks)), 594, 312}}, + }; + + nodeMonitoring.mTimestamp = aos::Time::Now(); + nodeMonitoring.mMonitoringData + = {1000, 2048, aos::Array(nodeDisks, aos::ArraySize(nodeDisks)), 4, 5}; + nodeMonitoring.mServiceInstances + = aos::Array(instancesData, aos::ArraySize(instancesData)); +} + /*********************************************************************************************************************** * Setup **********************************************************************************************************************/ @@ -254,3 +316,79 @@ ZTEST_F(smclient, test_SetNodeConfig) ReceiveNodeConfigStatus(channel, nodeInfo, pbSetNodeConfig.version); zassert_equal(fixture->mResourceManager.GetNodeConfig(), pbSetNodeConfig.node_config, "Wrong node config"); } + +ZTEST_F(smclient, test_InstantMonitoring) +{ + auto [channel, err] = InitSMClient(fixture, CONFIG_AOS_SM_SECURE_PORT, + {.mNodeID = "nodeID", .mNodeType = "nodeType", .mStatus = aos::NodeStatusEnum::eProvisioned}); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Send node monitoring + + aos::monitoring::NodeMonitoringData sendMonitoring; + + GenerateNodeMonitoring(sendMonitoring); + + err = fixture->mSMClient->SendMonitoringData(sendMonitoring); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Receive monitoring data + + servicemanager_v4_SMOutgoingMessages outgoingMessage; + auto& pbInstantMonitoring = outgoingMessage.SMOutgoingMessage.instant_monitoring; + + pbInstantMonitoring = servicemanager_v4_InstantMonitoring servicemanager_v4_InstantMonitoring_init_default; + + err = ReceiveSMOutgoingMessage(channel, outgoingMessage); + zassert_true(err.IsNone(), "Error receiving message: %s", utils::ErrorToCStr(err)); + + zassert_equal(outgoingMessage.which_SMOutgoingMessage, servicemanager_v4_SMOutgoingMessages_instant_monitoring_tag, + "Unexpected message type"); + + aos::monitoring::NodeMonitoringData receiveMonitoring; + + PBToNodeMonitoring(pbInstantMonitoring, receiveMonitoring); + zassert_equal(receiveMonitoring, sendMonitoring, "Wrong node monitoring"); +} + +ZTEST_F(smclient, test_GetAverageMonitoring) +{ + auto [channel, err] = InitSMClient(fixture, CONFIG_AOS_SM_SECURE_PORT, + {.mNodeID = "nodeID", .mNodeType = "nodeType", .mStatus = aos::NodeStatusEnum::eProvisioned}); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Send get average monitoring + + aos::monitoring::NodeMonitoringData sendMonitoring; + + GenerateNodeMonitoring(sendMonitoring); + + fixture->mResourceMonitor.SetMonitoringData(sendMonitoring); + + servicemanager_v4_SMIncomingMessages incomingMessage; + auto& pbGetAverageMonitoring = incomingMessage.SMIncomingMessage.get_average_monitoring; + + incomingMessage.which_SMIncomingMessage = servicemanager_v4_SMIncomingMessages_get_average_monitoring_tag; + pbGetAverageMonitoring = servicemanager_v4_GetAverageMonitoring servicemanager_v4_GetAverageMonitoring_init_default; + + err = SendSMIncomingMessage(channel, incomingMessage); + zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + + // Receive monitoring data + + servicemanager_v4_SMOutgoingMessages outgoingMessage; + auto& pbAverageMonitoring = outgoingMessage.SMOutgoingMessage.average_monitoring; + + pbAverageMonitoring = servicemanager_v4_AverageMonitoring servicemanager_v4_AverageMonitoring_init_default; + + err = ReceiveSMOutgoingMessage(channel, outgoingMessage); + zassert_true(err.IsNone(), "Error receiving message: %s", utils::ErrorToCStr(err)); + + zassert_equal(outgoingMessage.which_SMOutgoingMessage, servicemanager_v4_SMOutgoingMessages_average_monitoring_tag, + "Unexpected message type"); + + aos::monitoring::NodeMonitoringData receiveMonitoring; + + PBToNodeMonitoring(pbAverageMonitoring, receiveMonitoring); + zassert_equal(receiveMonitoring, sendMonitoring, "Wrong node monitoring"); +} diff --git a/tests/smclient/src/stubs/resourcemonitorstub.hpp b/tests/smclient/src/stubs/resourcemonitorstub.hpp new file mode 100644 index 00000000..fd2da223 --- /dev/null +++ b/tests/smclient/src/stubs/resourcemonitorstub.hpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef RESOURCEMONITORSTUB_HPP_ +#define RESOURCEMONITORSTUB_HPP_ + +#include + +class ResourceMonitorStub : public aos::monitoring::ResourceMonitorItf { +public: + aos::Error StartInstanceMonitoring( + const aos::String& instanceID, const aos::monitoring::InstanceMonitorParams& monitoringConfig) + { + return aos::ErrorEnum::eNone; + } + + aos::Error StopInstanceMonitoring(const aos::String& instanceID) { return aos::ErrorEnum::eNone; } + + aos::Error GetAverageMonitoringData(aos::monitoring::NodeMonitoringData& monitoringData) + { + monitoringData = mMonitoringData; + + return aos::ErrorEnum::eNone; + } + + void SetMonitoringData(const aos::monitoring::NodeMonitoringData& monitoringData) + { + mMonitoringData = monitoringData; + } + +private: + aos::monitoring::NodeMonitoringData mMonitoringData; +}; + +#endif From a80ea108b542f49518ea0ce0b26976b0eec0f95e Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 22 Aug 2024 18:51:20 +0300 Subject: [PATCH 082/198] [utils] Redesign ErroToPB and add PBToError functions Signed-off-by: Oleksandr Grytsov --- src/iamclient/iamclient.cpp | 3 ++- src/utils/pbconvert.hpp | 33 +++++++++++++++++++++++---------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index 0753f3b9..b37f129b 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -351,7 +351,8 @@ Error IAMClient::SendError(const void* message, T& pbMessage, const Error& err) { LOG_ERR() << "Process message error: err=" << err; - utils::ErrorToPB(err, pbMessage); + pbMessage.has_error = true; + pbMessage.error = utils::ErrorToPB(err); return SendMessage(message, &iamanager_v5_IAMOutgoingMessages_msg); } diff --git a/src/utils/pbconvert.hpp b/src/utils/pbconvert.hpp index 0eabe6e2..7368c07a 100644 --- a/src/utils/pbconvert.hpp +++ b/src/utils/pbconvert.hpp @@ -42,21 +42,34 @@ constexpr void PBToEnum(const char (&src)[cSize], T& dst) * Converts Aos error to PB error info. * * @param aosError Aos error to convert from. - * @param[out] errorInfo PB error info to convert to. + * @return common_v1_ErrorInfo. */ -template -void ErrorToPB(const Error& aosError, T& errorInfo) +inline common_v1_ErrorInfo ErrorToPB(const Error& aosError) { - if (aosError.IsNone()) { - errorInfo.has_error = false; - return; + common_v1_ErrorInfo errorInfo = {static_cast(aosError.Value()), aosError.Errno()}; + + StringFromCStr(errorInfo.message).Convert(aosError); + + return errorInfo; +} + +/** + * Converts Aos error to PB error info. + * + * @param errorInfo PB error info to convert from. + * return Error. + */ +inline Error PBToError(const common_v1_ErrorInfo& errorInfo) +{ + if (errorInfo.aos_code) { + return Error(static_cast(errorInfo.aos_code), errorInfo.message); } - errorInfo.has_error = true; - errorInfo.error.aos_code = int(aosError.Value()); - errorInfo.error.exit_code = aosError.Errno(); + if (errorInfo.exit_code) { + return Error(errorInfo.exit_code, errorInfo.message); + } - StringFromCStr(errorInfo.error.message).Convert(aosError); + return ErrorEnum::eNone; } /** From 03ef3f3b77e4d49961ba687bff55ac2b7f9e9169 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 22 Aug 2024 18:52:45 +0300 Subject: [PATCH 083/198] [iamclient] Wrap PB strings by utils::StringFromCStr Signed-off-by: Oleksandr Grytsov --- src/iamclient/iamclient.cpp | 44 +++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index b37f129b..6b4a87d7 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -436,12 +436,14 @@ Error IAMClient::ProcessStartProvisioning(const iamanager_v5_StartProvisioningRe NodeStatus expectedStatuses[] {NodeStatusEnum::eUnprovisioned}; - if (auto err = CheckNodeIDAndStatus(pbStartProvisioningRequest.node_id, utils::ToArray(expectedStatuses)); + if (auto err = CheckNodeIDAndStatus( + utils::StringFromCStr(pbStartProvisioningRequest.node_id), utils::ToArray(expectedStatuses)); !err.IsNone()) { return SendError(outgoingMessage.Get(), pbStartProvisionResponse, AOS_ERROR_WRAP(err)); } - if (auto err = mProvisionManager->StartProvisioning(pbStartProvisioningRequest.password); !err.IsNone()) { + if (auto err = mProvisionManager->StartProvisioning(utils::StringFromCStr(pbStartProvisioningRequest.password)); + !err.IsNone()) { return SendError(outgoingMessage.Get(), pbStartProvisionResponse, AOS_ERROR_WRAP(err)); } @@ -461,12 +463,14 @@ Error IAMClient::ProcessFinishProvisioning(const iamanager_v5_FinishProvisioning NodeStatus expectedStatuses[] {NodeStatusEnum::eUnprovisioned}; - if (auto err = CheckNodeIDAndStatus(pbFinishProvisioningRequest.node_id, utils::ToArray(expectedStatuses)); + if (auto err = CheckNodeIDAndStatus( + utils::StringFromCStr(pbFinishProvisioningRequest.node_id), utils::ToArray(expectedStatuses)); !err.IsNone()) { return SendError(outgoingMessage.Get(), pbFinishProvisionResponse, AOS_ERROR_WRAP(err)); } - if (auto err = mProvisionManager->FinishProvisioning(pbFinishProvisioningRequest.password); !err.IsNone()) { + if (auto err = mProvisionManager->FinishProvisioning(utils::StringFromCStr(pbFinishProvisioningRequest.password)); + !err.IsNone()) { return SendError(outgoingMessage.Get(), pbFinishProvisionResponse, AOS_ERROR_WRAP(err)); } @@ -489,12 +493,14 @@ Error IAMClient::ProcessDeprovision(const iamanager_v5_DeprovisionRequest& pbDep NodeStatus expectedStatuses[] {NodeStatusEnum::eProvisioned, NodeStatusEnum::ePaused}; - if (auto err = CheckNodeIDAndStatus(pbDeprovisionRequest.node_id, utils::ToArray(expectedStatuses)); + if (auto err + = CheckNodeIDAndStatus(utils::StringFromCStr(pbDeprovisionRequest.node_id), utils::ToArray(expectedStatuses)); !err.IsNone()) { return SendError(outgoingMessage.Get(), pbDeprovisionResponse, AOS_ERROR_WRAP(err)); } - if (auto err = mProvisionManager->Deprovision(pbDeprovisionRequest.password); !err.IsNone()) { + if (auto err = mProvisionManager->Deprovision(utils::StringFromCStr(pbDeprovisionRequest.password)); + !err.IsNone()) { return SendError(outgoingMessage.Get(), pbDeprovisionResponse, AOS_ERROR_WRAP(err)); } @@ -518,7 +524,8 @@ Error IAMClient::ProcessGetCertTypes(const iamanager_v5_GetCertTypesRequest& pbG NodeStatus expectedStatuses[] { NodeStatusEnum::eUnprovisioned, NodeStatusEnum::eProvisioned, NodeStatusEnum::ePaused}; - if (auto err = CheckNodeIDAndStatus(pbGetCertTypesRequest.node_id, utils::ToArray(expectedStatuses)); + if (auto err + = CheckNodeIDAndStatus(utils::StringFromCStr(pbGetCertTypesRequest.node_id), utils::ToArray(expectedStatuses)); !err.IsNone()) { LOG_ERR() << "Wrong get cert types condition: err=" << err; } @@ -550,14 +557,16 @@ Error IAMClient::ProcessCreateKey(const iamanager_v5_CreateKeyRequest& pbCreateK NodeStatus expectedStatuses[] { NodeStatusEnum::eUnprovisioned, NodeStatusEnum::eProvisioned, NodeStatusEnum::ePaused}; - if (auto err = CheckNodeIDAndStatus(pbCreateKeyRequest.node_id, utils::ToArray(expectedStatuses)); !err.IsNone()) { + if (auto err + = CheckNodeIDAndStatus(utils::StringFromCStr(pbCreateKeyRequest.node_id), utils::ToArray(expectedStatuses)); + !err.IsNone()) { return SendError(outgoingMessage.Get(), pbCreateKeyResponse, AOS_ERROR_WRAP(err)); } auto csr = utils::StringFromCStr(pbCreateKeyResponse.csr); - if (auto err = mProvisionManager->CreateKey( - pbCreateKeyRequest.type, pbCreateKeyRequest.subject, pbCreateKeyRequest.password, csr); + if (auto err = mProvisionManager->CreateKey(utils::StringFromCStr(pbCreateKeyRequest.type), + utils::StringFromCStr(pbCreateKeyRequest.subject), utils::StringFromCStr(pbCreateKeyRequest.password), csr); !err.IsNone()) { return SendError(outgoingMessage.Get(), pbCreateKeyResponse, AOS_ERROR_WRAP(err)); } @@ -581,13 +590,16 @@ Error IAMClient::ProcessApplyCert(const iamanager_v5_ApplyCertRequest& pbApplyCe NodeStatus expectedStatuses[] { NodeStatusEnum::eUnprovisioned, NodeStatusEnum::eProvisioned, NodeStatusEnum::ePaused}; - if (auto err = CheckNodeIDAndStatus(pbApplyCertRequest.node_id, utils::ToArray(expectedStatuses)); !err.IsNone()) { + if (auto err + = CheckNodeIDAndStatus(utils::StringFromCStr(pbApplyCertRequest.node_id), utils::ToArray(expectedStatuses)); + !err.IsNone()) { return SendError(outgoingMessage.Get(), pbApplyCertResponse, AOS_ERROR_WRAP(err)); } iam::certhandler::CertInfo certInfo {}; - if (auto err = mProvisionManager->ApplyCert(pbApplyCertRequest.type, pbApplyCertRequest.cert, certInfo); + if (auto err = mProvisionManager->ApplyCert( + utils::StringFromCStr(pbApplyCertRequest.type), utils::StringFromCStr(pbApplyCertRequest.cert), certInfo); !err.IsNone()) { return SendError(outgoingMessage.Get(), pbApplyCertResponse, AOS_ERROR_WRAP(err)); } @@ -615,7 +627,9 @@ Error IAMClient::ProcessPauseNode(const iamanager_v5_PauseNodeRequest& pbPauseNo NodeStatus expectedStatuses[] {NodeStatusEnum::eProvisioned}; - if (auto err = CheckNodeIDAndStatus(pbPauseNodeRequest.node_id, utils::ToArray(expectedStatuses)); !err.IsNone()) { + if (auto err + = CheckNodeIDAndStatus(utils::StringFromCStr(pbPauseNodeRequest.node_id), utils::ToArray(expectedStatuses)); + !err.IsNone()) { return SendError(outgoingMessage.Get(), pbPauseNodeResponse, AOS_ERROR_WRAP(err)); } @@ -638,7 +652,9 @@ Error IAMClient::ProcessResumeNode(const iamanager_v5_ResumeNodeRequest& pbResum NodeStatus expectedStatuses[] {NodeStatusEnum::ePaused}; - if (auto err = CheckNodeIDAndStatus(pbResumeNodeRequest.node_id, utils::ToArray(expectedStatuses)); !err.IsNone()) { + if (auto err + = CheckNodeIDAndStatus(utils::StringFromCStr(pbResumeNodeRequest.node_id), utils::ToArray(expectedStatuses)); + !err.IsNone()) { return SendError(outgoingMessage.Get(), pbResumeNodeResponse, AOS_ERROR_WRAP(err)); } From 96b9e954d1913379ee56ed16b438bcf6ee215724 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 22 Aug 2024 19:15:29 +0300 Subject: [PATCH 084/198] [tests,iamclient] Add check cert on apply cert request Signed-off-by: Oleksandr Grytsov --- tests/iamclient/src/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/iamclient/src/main.cpp b/tests/iamclient/src/main.cpp index 1513030d..605ecda5 100644 --- a/tests/iamclient/src/main.cpp +++ b/tests/iamclient/src/main.cpp @@ -406,6 +406,7 @@ ZTEST_F(iamclient, test_ApplyCert) zassert_equal(pbApplyCertResponse.type, fixture->mProvisionManager.GetCertType(), "Wrong cert type"); zassert_equal(pbApplyCertResponse.cert_url, certInfo.mCertURL, "Wrong cert URL"); zassert_equal(pbApplyCertResponse.serial, serial, "Wrong serial"); + zassert_equal(pbApplyCertRequest.cert, fixture->mProvisionManager.GetCert(), "Wrong cert"); } ZTEST_F(iamclient, test_PauseNode) From 7377276bba1aae4a32fa54f8abf223122f09ca5d Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 22 Aug 2024 19:16:04 +0300 Subject: [PATCH 085/198] [smclient] Implement handling run instances and run instances status Signed-off-by: Oleksandr Grytsov --- src/smclient/smclient.cpp | 131 ++++++++++++- src/smclient/smclient.hpp | 8 +- tests/smclient/src/main.cpp | 225 +++++++++++++++++++++- tests/smclient/src/stubs/launcherstub.hpp | 96 +++++++++ 4 files changed, 449 insertions(+), 11 deletions(-) create mode 100644 tests/smclient/src/stubs/launcherstub.hpp diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index cc499ba5..d1b4273d 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -61,17 +61,31 @@ static constexpr void NodeMonitoringToPB(const monitoring::NodeMonitoringData& n } } +static void InstanceStatusToPB( + const InstanceStatus& aosInstanceStatus, servicemanager_v4_InstanceStatus& pbInstanceStatus) +{ + pbInstanceStatus.has_instance = true; + utils::InstanceIdentToPB(aosInstanceStatus.mInstanceIdent, pbInstanceStatus.instance); + utils::StringFromCStr(pbInstanceStatus.service_version) = aosInstanceStatus.mServiceVersion; + utils::StringFromCStr(pbInstanceStatus.run_state) = aosInstanceStatus.mRunState.ToString(); + + if (!aosInstanceStatus.mError.IsNone()) { + pbInstanceStatus.has_error_info = true; + pbInstanceStatus.error_info = utils::ErrorToPB(aosInstanceStatus.mError); + } +} /*********************************************************************************************************************** * Public **********************************************************************************************************************/ -Error SMClient::Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider, +Error SMClient::Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider, sm::launcher::LauncherItf& launcher, sm::resourcemanager::ResourceManagerItf& resourceManager, monitoring::ResourceMonitorItf& resourceMonitor, clocksync::ClockSyncItf& clockSync, communication::ChannelManagerItf& channelManager) { LOG_DBG() << "Initialize SM client"; mNodeInfoProvider = &nodeInfoProvider; + mLauncher = &launcher; mResourceManager = &resourceManager; mResourceMonitor = &resourceMonitor; mChannelManager = &channelManager; @@ -129,12 +143,45 @@ SMClient::~SMClient() Error SMClient::InstancesRunStatus(const Array& instances) { - return ErrorEnum::eNone; + LockGuard lock {mMutex}; + + LOG_INF() << "Send run instances status"; + + auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto& pbRunInstancesStatus = outgoingMessage->SMOutgoingMessage.run_instances_status; + + outgoingMessage->which_SMOutgoingMessage = servicemanager_v4_SMOutgoingMessages_run_instances_status_tag; + pbRunInstancesStatus = servicemanager_v4_RunInstancesStatus servicemanager_v4_RunInstancesStatus_init_default; + + pbRunInstancesStatus.instances_count = instances.Size(); + + for (size_t i = 0; i < instances.Size(); i++) { + InstanceStatusToPB(instances[i], pbRunInstancesStatus.instances[i]); + } + + return SendMessage(outgoingMessage.Get(), &servicemanager_v4_SMOutgoingMessages_msg); } Error SMClient::InstancesUpdateStatus(const Array& instances) { - return ErrorEnum::eNone; + LockGuard lock {mMutex}; + + LOG_INF() << "Send update instances status"; + + auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto& pbUpdateInstancesStatus = outgoingMessage->SMOutgoingMessage.update_instances_status; + + outgoingMessage->which_SMOutgoingMessage = servicemanager_v4_SMOutgoingMessages_update_instances_status_tag; + pbUpdateInstancesStatus + = servicemanager_v4_UpdateInstancesStatus servicemanager_v4_UpdateInstancesStatus_init_default; + + pbUpdateInstancesStatus.instances_count = instances.Size(); + + for (size_t i = 0; i < instances.Size(); i++) { + InstanceStatusToPB(instances[i], pbUpdateInstancesStatus.instances[i]); + } + + return SendMessage(outgoingMessage.Get(), &servicemanager_v4_SMOutgoingMessages_msg); } Error SMClient::SendImageContentRequest(const downloader::ImageContentRequest& request) @@ -148,7 +195,7 @@ Error SMClient::SendMonitoringData(const monitoring::NodeMonitoringData& nodeMon LOG_INF() << "Send node monitoring"; - auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto outgoingMessage = MakeUnique(&mAllocator); auto& pbInstantMonitoring = outgoingMessage->SMOutgoingMessage.instant_monitoring; outgoingMessage->which_SMOutgoingMessage = servicemanager_v4_SMOutgoingMessages_instant_monitoring_tag; @@ -256,6 +303,10 @@ Error SMClient::ReceiveMessage(const Array& data) err = ProcessGetAverageMonitoring(incomingMessages->SMIncomingMessage.get_average_monitoring); break; + case servicemanager_v4_SMIncomingMessages_run_instances_tag: + err = ProcessRunInstances(incomingMessages->SMIncomingMessage.run_instances); + break; + default: LOG_WRN() << "Receive unsupported message: tag=" << incomingMessages->which_SMIncomingMessage; break; @@ -299,13 +350,13 @@ Error SMClient::ProcessGetAverageMonitoring(const servicemanager_v4_GetAverageMo { LOG_INF() << "Process get average monitoring"; - auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto outgoingMessage = MakeUnique(&mAllocator); auto& pbAverageMonitoring = outgoingMessage->SMOutgoingMessage.average_monitoring; outgoingMessage->which_SMOutgoingMessage = servicemanager_v4_SMOutgoingMessages_average_monitoring_tag; pbAverageMonitoring = servicemanager_v4_AverageMonitoring servicemanager_v4_AverageMonitoring_init_default; - auto averageMonitoring = aos::MakeUnique(&mAllocator); + auto averageMonitoring = MakeUnique(&mAllocator); if (auto err = mResourceMonitor->GetAverageMonitoringData(*averageMonitoring); !err.IsNone()) { return AOS_ERROR_WRAP(err); @@ -316,11 +367,74 @@ Error SMClient::ProcessGetAverageMonitoring(const servicemanager_v4_GetAverageMo return SendMessage(outgoingMessage.Get(), &servicemanager_v4_SMOutgoingMessages_msg); } +Error SMClient::ProcessRunInstances(const servicemanager_v4_RunInstances& pbRunInstances) +{ + LOG_INF() << "Process run instances"; + + auto aosServices = MakeUnique(&mAllocator); + + aosServices->Resize(pbRunInstances.services_count); + + for (auto i = 0; i < pbRunInstances.services_count; i++) { + const auto& pbService = pbRunInstances.services[i]; + auto& aosService = (*aosServices)[i]; + + aosService.mServiceID = utils::StringFromCStr(pbService.service_id); + aosService.mProviderID = utils::StringFromCStr(pbService.provider_id); + aosService.mVersion = utils::StringFromCStr(pbService.version); + aosService.mGID = pbService.gid; + aosService.mURL = pbService.url; + utils::PBToByteArray(pbService.sha256, aosService.mSHA256); + aosService.mSize = pbService.size; + } + + auto aosLayers = MakeUnique(&mAllocator); + + aosLayers->Resize(pbRunInstances.layers_count); + + for (auto i = 0; i < pbRunInstances.layers_count; i++) { + const auto& pbLayer = pbRunInstances.layers[i]; + auto& aosLayer = (*aosLayers)[i]; + + aosLayer.mLayerID = utils::StringFromCStr(pbLayer.layer_id); + aosLayer.mLayerDigest = utils::StringFromCStr(pbLayer.digest); + aosLayer.mVersion = utils::StringFromCStr(pbLayer.version); + aosLayer.mURL = utils::StringFromCStr(pbLayer.url); + utils::PBToByteArray(pbLayer.sha256, aosLayer.mSHA256); + aosLayer.mSize = pbLayer.size; + } + + auto aosInstances = MakeUnique(&mAllocator); + + aosInstances->Resize(pbRunInstances.instances_count); + + for (auto i = 0; i < pbRunInstances.instances_count; i++) { + const auto& pbInstance = pbRunInstances.instances[i]; + auto& aosInstance = (*aosInstances)[i]; + + if (pbInstance.has_instance) { + utils::PBToInstanceIdent(pbInstance.instance, aosInstance.mInstanceIdent); + } + + aosInstance.mUID = pbInstance.uid; + aosInstance.mPriority = pbInstance.priority; + aosInstance.mStoragePath = utils::StringFromCStr(pbInstance.storage_path); + aosInstance.mStatePath = utils::StringFromCStr(pbInstance.state_path); + } + + auto err = mLauncher->RunInstances(*aosServices, *aosLayers, *aosInstances, pbRunInstances.force_restart); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + return ErrorEnum::eNone; +} + Error SMClient::SendNodeConfigStatus(const String& version, const Error& configErr) { LOG_INF() << "Send node config status: version=" << version << ", configErr=" << configErr; - auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto outgoingMessage = MakeUnique(&mAllocator); auto& pbNodeConfigStatus = outgoingMessage->SMOutgoingMessage.node_config_status; outgoingMessage->which_SMOutgoingMessage = servicemanager_v4_SMOutgoingMessages_node_config_status_tag; @@ -337,7 +451,8 @@ Error SMClient::SendNodeConfigStatus(const String& version, const Error& configE utils::StringFromCStr(pbNodeConfigStatus.version) = version; if (!configErr.IsNone()) { - utils::ErrorToPB(configErr, pbNodeConfigStatus); + pbNodeConfigStatus.has_error = true; + pbNodeConfigStatus.error = utils::ErrorToPB(configErr); } return SendMessage(outgoingMessage.Get(), &servicemanager_v4_SMOutgoingMessages_msg); diff --git a/src/smclient/smclient.hpp b/src/smclient/smclient.hpp index 6abca8d1..e92bc62e 100644 --- a/src/smclient/smclient.hpp +++ b/src/smclient/smclient.hpp @@ -39,13 +39,14 @@ class SMClient : public communication::PBHandler + + Max(sizeof(NodeInfo), sizeof(aos::monitoring::NodeMonitoringData))>, + sizeof(ServiceInfoStaticArray) + sizeof(LayerInfoStaticArray) + sizeof(InstanceInfoStaticArray))> mAllocator; }; diff --git a/tests/smclient/src/main.cpp b/tests/smclient/src/main.cpp index d2d043c2..20d8844f 100644 --- a/tests/smclient/src/main.cpp +++ b/tests/smclient/src/main.cpp @@ -14,6 +14,7 @@ #include "stubs/channelmanagerstub.hpp" #include "stubs/clocksyncstub.hpp" +#include "stubs/launcherstub.hpp" #include "stubs/nodeinfoproviderstub.hpp" #include "stubs/resourcemanagerstub.hpp" #include "stubs/resourcemonitorstub.hpp" @@ -36,6 +37,7 @@ static constexpr auto cWaitTimeout = std::chrono::seconds {5}; struct smclient_fixture { NodeInfoProviderStub mNodeInfoProvider; + LauncherStub mLauncher; ResourceManagerStub mResourceManager; ResourceMonitorStub mResourceMonitor; ClockSyncStub mClockSync; @@ -84,7 +86,7 @@ static aos::RetWithError InitSMClient(smclient_fixture* fixture, u fixture->mNodeInfoProvider.SetNodeInfo(nodeInfo); fixture->mResourceManager.UpdateNodeConfig(nodeConfigVersion, ""); - auto err = fixture->mSMClient->Init(fixture->mNodeInfoProvider, fixture->mResourceManager, + auto err = fixture->mSMClient->Init(fixture->mNodeInfoProvider, fixture->mLauncher, fixture->mResourceManager, fixture->mResourceMonitor, fixture->mClockSync, fixture->mChannelManager); zassert_true(err.IsNone(), "Can't initialize SM client: %s", utils::ErrorToCStr(err)); @@ -140,6 +142,26 @@ static void PBToNodeMonitoring(const T& pbNodeMonitoring, aos::monitoring::NodeM } } +static void PBToInstanceStatus(const servicemanager_v4_InstanceStatus& pbInstance, aos::InstanceStatus& aosInstance) +{ + if (pbInstance.has_instance) { + utils::PBToInstanceIdent(pbInstance.instance, aosInstance.mInstanceIdent); + } + + aosInstance.mServiceVersion = utils::StringFromCStr(pbInstance.service_version); + utils::PBToEnum(pbInstance.run_state, aosInstance.mRunState); + + aosInstance.mError = utils::PBToError(pbInstance.error_info); + + if (pbInstance.has_error_info) { + if (pbInstance.error_info.exit_code) { + aosInstance.mError = pbInstance.error_info.exit_code; + } else { + aosInstance.mError = static_cast(pbInstance.error_info.aos_code); + } + } +} + static void GenerateNodeMonitoring(aos::monitoring::NodeMonitoringData& nodeMonitoring) { aos::PartitionInfo nodeDisks[] = {{.mName = "disk1", .mUsedSize = 512}, {.mName = "disk2", .mUsedSize = 1024}}; @@ -161,6 +183,46 @@ static void GenerateNodeMonitoring(aos::monitoring::NodeMonitoringData& nodeMoni = aos::Array(instancesData, aos::ArraySize(instancesData)); } +static void GenerateServicesInfo(aos::Array& services) +{ + uint8_t sha256[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + + services.EmplaceBack(aos::ServiceInfo { + "service1", "provider1", "1.0.0", 1, "service1 URL", aos::Array(sha256, sizeof(sha256)), 312}); + services.EmplaceBack(aos::ServiceInfo { + "service2", "provider2", "2.0.0", 2, "service2 URL", aos::Array(sha256, sizeof(sha256)), 512}); +} + +static void GenerateLayersInfo(aos::Array& layers) +{ + uint8_t sha256[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; + + layers.EmplaceBack( + aos::LayerInfo {"layer1", "digest1", "1.0.0", "layer1 URL", aos::Array(sha256, sizeof(sha256)), 1024}); + layers.EmplaceBack( + aos::LayerInfo {"layer2", "digest2", "2.0.0", "layer2 URL", aos::Array(sha256, sizeof(sha256)), 2048}); + layers.EmplaceBack( + aos::LayerInfo {"layer3", "digest3", "3.0.0", "layer3 URL", aos::Array(sha256, sizeof(sha256)), 4096}); +} + +static void GenerateInstancesInfo(aos::Array& instances) +{ + instances.EmplaceBack(aos::InstanceInfo {{"service1", "subject1", 1}, 1, 1, "storage1", "state1"}); + instances.EmplaceBack(aos::InstanceInfo {{"service2", "subject2", 2}, 2, 2, "storage2", "state2"}); + instances.EmplaceBack(aos::InstanceInfo {{"service3", "subject3", 3}, 3, 3, "storage3", "state3"}); + instances.EmplaceBack(aos::InstanceInfo {{"service4", "subject4", 4}, 4, 4, "storage4", "state4"}); +} + +static void GenerateInstancesRunStatus(aos::Array& status) +{ + status.EmplaceBack(aos::InstanceStatus { + {"service1", "subject1", 0}, "1.0.0", aos::InstanceRunStateEnum::eActive, aos::ErrorEnum::eNone}); + status.EmplaceBack( + aos::InstanceStatus {{"service1", "subject1", 1}, "3.0.0", aos::InstanceRunStateEnum::eFailed, 42}); + status.EmplaceBack(aos::InstanceStatus { + {"service1", "subject1", 2}, "2.0.0", aos::InstanceRunStateEnum::eFailed, aos::ErrorEnum::eRuntime}); +} + /*********************************************************************************************************************** * Setup **********************************************************************************************************************/ @@ -177,6 +239,7 @@ ZTEST_SUITE( [](void* fixture) { auto smclientFixture = static_cast(fixture); + smclientFixture->mLauncher.Clear(); smclientFixture->mClockSync.Clear(); smclientFixture->mSMClient.reset(new smclient::SMClient); }, @@ -392,3 +455,163 @@ ZTEST_F(smclient, test_GetAverageMonitoring) PBToNodeMonitoring(pbAverageMonitoring, receiveMonitoring); zassert_equal(receiveMonitoring, sendMonitoring, "Wrong node monitoring"); } + +ZTEST_F(smclient, test_RunInstance) +{ + auto [channel, err] = InitSMClient(fixture, CONFIG_AOS_SM_SECURE_PORT, + {.mNodeID = "nodeID", .mNodeType = "nodeType", .mStatus = aos::NodeStatusEnum::eProvisioned}); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Send run instances + + aos::ServiceInfoStaticArray services; + aos::LayerInfoStaticArray layers; + aos::InstanceInfoStaticArray instances; + + GenerateServicesInfo(services); + GenerateLayersInfo(layers); + GenerateInstancesInfo(instances); + + servicemanager_v4_SMIncomingMessages incomingMessage; + auto& pbRunInstances = incomingMessage.SMIncomingMessage.run_instances; + + incomingMessage.which_SMIncomingMessage = servicemanager_v4_SMIncomingMessages_run_instances_tag; + pbRunInstances = servicemanager_v4_RunInstances servicemanager_v4_RunInstances_init_default; + + pbRunInstances.services_count = services.Size(); + + for (size_t i = 0; i < services.Size(); i++) { + const auto& aosService = services[i]; + auto& pbService = pbRunInstances.services[i]; + + utils::StringFromCStr(pbService.service_id) = aosService.mServiceID; + utils::StringFromCStr(pbService.provider_id) = aosService.mProviderID; + utils::StringFromCStr(pbService.version) = aosService.mVersion; + pbService.gid = aosService.mGID; + utils::StringFromCStr(pbService.url) = aosService.mURL; + utils::ByteArrayToPB(aosService.mSHA256, pbService.sha256); + pbService.size = aosService.mSize; + } + + pbRunInstances.layers_count = layers.Size(); + + for (size_t i = 0; i < layers.Size(); i++) { + const auto& aosLayer = layers[i]; + auto& pbLayer = incomingMessage.SMIncomingMessage.run_instances.layers[i]; + + utils::StringFromCStr(pbLayer.layer_id) = aosLayer.mLayerID; + utils::StringFromCStr(pbLayer.digest) = aosLayer.mLayerDigest; + utils::StringFromCStr(pbLayer.version) = aosLayer.mVersion; + utils::StringFromCStr(pbLayer.url) = aosLayer.mURL; + utils::ByteArrayToPB(aosLayer.mSHA256, pbLayer.sha256); + pbLayer.size = aosLayer.mSize; + } + + pbRunInstances.instances_count = instances.Size(); + + for (size_t i = 0; i < instances.Size(); i++) { + const auto& aosInstance = instances[i]; + auto& pbInstance = incomingMessage.SMIncomingMessage.run_instances.instances[i]; + + pbInstance.has_instance = true; + utils::InstanceIdentToPB(aosInstance.mInstanceIdent, pbInstance.instance); + pbInstance.uid = aosInstance.mUID; + pbInstance.priority = aosInstance.mPriority; + utils::StringFromCStr(pbInstance.storage_path) = aosInstance.mStoragePath; + utils::StringFromCStr(pbInstance.state_path) = aosInstance.mStatePath; + } + + err = SendSMIncomingMessage(channel, incomingMessage); + zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + + // Check run instances + + err = fixture->mLauncher.WaitEvent(cWaitTimeout); + zassert_true(err.IsNone(), "Error waiting run instances: %s", utils::ErrorToCStr(err)); + + auto receivedServices = fixture->mLauncher.GetServices(); + + zassert_equal(fixture->mLauncher.IsForceRestart(), incomingMessage.SMIncomingMessage.run_instances.force_restart); + zassert_equal(fixture->mLauncher.GetServices(), services); + zassert_equal(fixture->mLauncher.GetLayers(), layers); + zassert_equal(fixture->mLauncher.GetInstances(), instances); +} + +ZTEST_F(smclient, test_RunInstancesStatus) +{ + auto [channel, err] = InitSMClient(fixture, CONFIG_AOS_SM_SECURE_PORT, + {.mNodeID = "nodeID", .mNodeType = "nodeType", .mStatus = aos::NodeStatusEnum::eProvisioned}); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Send run instances status + + aos::InstanceStatusStaticArray sendRunStatus; + + GenerateInstancesRunStatus(sendRunStatus); + + err = fixture->mSMClient->InstancesRunStatus(sendRunStatus); + zassert_true(err.IsNone(), "Error sending run instances status: %s", utils::ErrorToCStr(err)); + + // Receive run instances status + + servicemanager_v4_SMOutgoingMessages outgoingMessage; + auto& pbRunInstancesStatus = outgoingMessage.SMOutgoingMessage.run_instances_status; + + pbRunInstancesStatus = servicemanager_v4_RunInstancesStatus servicemanager_v4_RunInstancesStatus_init_default; + + err = ReceiveSMOutgoingMessage(channel, outgoingMessage); + zassert_true(err.IsNone(), "Error receiving message: %s", utils::ErrorToCStr(err)); + + zassert_equal(outgoingMessage.which_SMOutgoingMessage, + servicemanager_v4_SMOutgoingMessages_run_instances_status_tag, "Unexpected message type"); + + aos::InstanceStatusStaticArray receivedRunStatus; + + receivedRunStatus.Resize(pbRunInstancesStatus.instances_count); + + for (auto i = 0; i < pbRunInstancesStatus.instances_count; i++) { + PBToInstanceStatus(pbRunInstancesStatus.instances[i], receivedRunStatus[i]); + } + + zassert_equal(receivedRunStatus, sendRunStatus, "Wrong run instances status"); +} + +ZTEST_F(smclient, test_UpdateInstancesStatus) +{ + auto [channel, err] = InitSMClient(fixture, CONFIG_AOS_SM_SECURE_PORT, + {.mNodeID = "nodeID", .mNodeType = "nodeType", .mStatus = aos::NodeStatusEnum::eProvisioned}); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Send update instances status + + aos::InstanceStatusStaticArray sendUpdateStatus; + + GenerateInstancesRunStatus(sendUpdateStatus); + + err = fixture->mSMClient->InstancesUpdateStatus(sendUpdateStatus); + zassert_true(err.IsNone(), "Error sending update instances status: %s", utils::ErrorToCStr(err)); + + // Receive run instances status + + servicemanager_v4_SMOutgoingMessages outgoingMessage; + auto& pbUpdateInstancesStatus = outgoingMessage.SMOutgoingMessage.update_instances_status; + + pbUpdateInstancesStatus + = servicemanager_v4_UpdateInstancesStatus servicemanager_v4_UpdateInstancesStatus_init_default; + + err = ReceiveSMOutgoingMessage(channel, outgoingMessage); + zassert_true(err.IsNone(), "Error receiving message: %s", utils::ErrorToCStr(err)); + + zassert_equal(outgoingMessage.which_SMOutgoingMessage, + servicemanager_v4_SMOutgoingMessages_update_instances_status_tag, "Unexpected message type"); + + aos::InstanceStatusStaticArray receivedUpdateStatus; + + receivedUpdateStatus.Resize(pbUpdateInstancesStatus.instances_count); + + for (auto i = 0; i < outgoingMessage.SMOutgoingMessage.run_instances_status.instances_count; i++) { + PBToInstanceStatus(pbUpdateInstancesStatus.instances[i], receivedUpdateStatus[i]); + } + + zassert_equal(receivedUpdateStatus, sendUpdateStatus, "Wrong update instances status"); +} diff --git a/tests/smclient/src/stubs/launcherstub.hpp b/tests/smclient/src/stubs/launcherstub.hpp new file mode 100644 index 00000000..3cff0bf7 --- /dev/null +++ b/tests/smclient/src/stubs/launcherstub.hpp @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef LAUNCHERSTUB_HPP_ +#define LAUNCHERSTUB_HPP_ + +#include +#include + +#include +#include + +class LauncherStub : public aos::sm::launcher::LauncherItf { +public: + aos::Error RunInstances(const aos::Array& services, const aos::Array& layers, + const aos::Array& instances, bool forceRestart) override + { + std::lock_guard lock(mMutex); + + mServices = services; + mLayers = layers; + mInstances = instances; + mForceRestart = forceRestart; + mEventReceived = true; + + mCV.notify_one(); + + return aos::ErrorEnum::eNone; + } + + aos::Error WaitEvent(const std::chrono::duration timeout) + { + std::unique_lock lock(mMutex); + + if (!mCV.wait_for(lock, timeout, [&] { return mEventReceived; })) { + return aos::ErrorEnum::eTimeout; + } + + mEventReceived = false; + + return aos::ErrorEnum::eNone; + } + + const aos::Array GetServices() const + { + std::lock_guard lock(mMutex); + return mServices; + } + + const aos::Array GetLayers() const + { + std::lock_guard lock(mMutex); + return mLayers; + } + + const aos::Array GetInstances() const + { + std::lock_guard lock(mMutex); + return mInstances; + } + + bool IsForceRestart() const + { + std::lock_guard lock(mMutex); + return mForceRestart; + } + + void Clear() + { + std::lock_guard lock(mMutex); + + mEventReceived = false; + mServices.Clear(); + mLayers.Clear(); + mInstances.Clear(); + mForceRestart = false; + } + +private: + static constexpr auto cWaitTimeout = std::chrono::seconds {1}; + + aos::ServiceInfoStaticArray mServices {}; + aos::LayerInfoStaticArray mLayers {}; + aos::InstanceInfoStaticArray mInstances {}; + bool mForceRestart = false; + + std::condition_variable mCV; + mutable std::mutex mMutex; + bool mEventReceived = false; +}; + +#endif From c08f64aa70c2d45286f656d5cb3878de2bfa4f97 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 22 Aug 2024 19:34:40 +0300 Subject: [PATCH 086/198] [downloader] Use Error instead of String in image content info Signed-off-by: Oleksandr Grytsov --- src/downloader/downloader.cpp | 10 ++++------ src/downloader/downloader.hpp | 6 +++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/downloader/downloader.cpp b/src/downloader/downloader.cpp index 3597ea92..08f6c3f9 100644 --- a/src/downloader/downloader.cpp +++ b/src/downloader/downloader.cpp @@ -171,14 +171,12 @@ Error Downloader::ReceiveImageContentInfo(const ImageContentInfo& content) return AOS_ERROR_WRAP(ErrorEnum::eFailed); } - if (content.mError != "") { - LOG_ERR() << "Error: " << content.mError; + if (!content.mError.IsNone()) { + LOG_ERR() << "Image content info error: err=" << content.mError; - auto err = AOS_ERROR_WRAP(ErrorEnum::eFailed); + SetErrorAndNotify(content.mError); - SetErrorAndNotify(err); - - return err; + return content.mError; } for (auto& file : content.mFiles) { diff --git a/src/downloader/downloader.hpp b/src/downloader/downloader.hpp index 24a271d2..0d251fa8 100644 --- a/src/downloader/downloader.hpp +++ b/src/downloader/downloader.hpp @@ -78,9 +78,9 @@ struct FileInfo { * Image content info. */ struct ImageContentInfo { - uint64_t mRequestID; - StaticArray mFiles; - StaticString mError; + uint64_t mRequestID; + StaticArray mFiles; + Error mError; /** * Compares content info. From a68d78e4574edf05bbd56a89c652a2bf7b81e7ed Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 22 Aug 2024 21:20:58 +0300 Subject: [PATCH 087/198] [smclient] Implement handling downloader messages Signed-off-by: Oleksandr Grytsov --- src/smclient/smclient.cpp | 77 ++++++++++- src/smclient/smclient.hpp | 12 +- tests/smclient/src/main.cpp | 135 +++++++++++++++++++- tests/smclient/src/stubs/downloaderstub.hpp | 85 ++++++++++++ 4 files changed, 303 insertions(+), 6 deletions(-) create mode 100644 tests/smclient/src/stubs/downloaderstub.hpp diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index d1b4273d..8e3a894f 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -80,7 +80,8 @@ static void InstanceStatusToPB( Error SMClient::Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider, sm::launcher::LauncherItf& launcher, sm::resourcemanager::ResourceManagerItf& resourceManager, monitoring::ResourceMonitorItf& resourceMonitor, - clocksync::ClockSyncItf& clockSync, communication::ChannelManagerItf& channelManager) + downloader::DownloadReceiverItf& downloader, clocksync::ClockSyncItf& clockSync, + communication::ChannelManagerItf& channelManager) { LOG_DBG() << "Initialize SM client"; @@ -88,6 +89,7 @@ Error SMClient::Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvide mLauncher = &launcher; mResourceManager = &resourceManager; mResourceMonitor = &resourceMonitor; + mDownloader = &downloader; mChannelManager = &channelManager; auto nodeInfo = MakeUnique(&mAllocator); @@ -186,7 +188,22 @@ Error SMClient::InstancesUpdateStatus(const Array& instances) Error SMClient::SendImageContentRequest(const downloader::ImageContentRequest& request) { - return ErrorEnum::eNone; + LockGuard lock {mMutex}; + + LOG_INF() << "Send image content request: requestID=" << request.mRequestID << ", url=" << request.mURL + << ", contentType=" << request.mContentType; + + auto outgoingMessage = aos::MakeUnique(&mAllocator); + auto& pbImageContentRequest = outgoingMessage->SMOutgoingMessage.image_content_request; + + outgoingMessage->which_SMOutgoingMessage = servicemanager_v4_SMOutgoingMessages_image_content_request_tag; + pbImageContentRequest = servicemanager_v4_ImageContentRequest servicemanager_v4_ImageContentRequest_init_default; + + pbImageContentRequest.request_id = request.mRequestID; + utils::StringFromCStr(pbImageContentRequest.content_type) = request.mContentType.ToString(); + utils::StringFromCStr(pbImageContentRequest.url) = request.mURL; + + return SendMessage(outgoingMessage.Get(), &servicemanager_v4_SMOutgoingMessages_msg); } Error SMClient::SendMonitoringData(const monitoring::NodeMonitoringData& nodeMonitoring) @@ -307,6 +324,14 @@ Error SMClient::ReceiveMessage(const Array& data) err = ProcessRunInstances(incomingMessages->SMIncomingMessage.run_instances); break; + case servicemanager_v4_SMIncomingMessages_image_content_info_tag: + err = ProcessImageContentInfo(incomingMessages->SMIncomingMessage.image_content_info); + break; + + case servicemanager_v4_SMIncomingMessages_image_content_tag: + err = ProcessImageContent(incomingMessages->SMIncomingMessage.image_content); + break; + default: LOG_WRN() << "Receive unsupported message: tag=" << incomingMessages->which_SMIncomingMessage; break; @@ -430,6 +455,54 @@ Error SMClient::ProcessRunInstances(const servicemanager_v4_RunInstances& pbRunI return ErrorEnum::eNone; } +Error SMClient::ProcessImageContentInfo(const servicemanager_v4_ImageContentInfo& pbImageContentInfo) +{ + LOG_INF() << "Process image content info: requestID=" << pbImageContentInfo.request_id; + + auto aosImageContentInfo = aos::MakeUnique(&mAllocator); + + aosImageContentInfo->mRequestID = pbImageContentInfo.request_id; + aosImageContentInfo->mFiles.Resize(pbImageContentInfo.image_files_count); + + for (auto i = 0; i < pbImageContentInfo.image_files_count; i++) { + aosImageContentInfo->mFiles[i].mRelativePath + = utils::StringFromCStr(pbImageContentInfo.image_files[i].relative_path); + utils::PBToByteArray(pbImageContentInfo.image_files[i].sha256, aosImageContentInfo->mFiles[i].mSHA256); + aosImageContentInfo->mFiles[i].mSize = pbImageContentInfo.image_files[i].size; + } + + if (pbImageContentInfo.has_error) { + aosImageContentInfo->mError = utils::PBToError(pbImageContentInfo.error); + } + + if (auto err = mDownloader->ReceiveImageContentInfo(*aosImageContentInfo); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + return aos::ErrorEnum::eNone; +} + +Error SMClient::ProcessImageContent(const servicemanager_v4_ImageContent& pbImageContent) +{ + LOG_DBG() << "Process image content: requestID=" << pbImageContent.request_id + << ", relativePath=" << pbImageContent.relative_path; + + auto fileChunk = aos::MakeUnique(&mAllocator); + + fileChunk->mRequestID = pbImageContent.request_id; + fileChunk->mRelativePath = utils::StringFromCStr(pbImageContent.relative_path); + fileChunk->mPartsCount = pbImageContent.parts_count; + fileChunk->mPart = pbImageContent.part; + utils::PBToByteArray(pbImageContent.data, fileChunk->mData); + + auto err = mDownloader->ReceiveFileChunk(*fileChunk); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + return aos::ErrorEnum::eNone; +} + Error SMClient::SendNodeConfigStatus(const String& version, const Error& configErr) { LOG_INF() << "Send node config status: version=" << version << ", configErr=" << configErr; diff --git a/src/smclient/smclient.hpp b/src/smclient/smclient.hpp index e92bc62e..c315f634 100644 --- a/src/smclient/smclient.hpp +++ b/src/smclient/smclient.hpp @@ -42,13 +42,15 @@ class SMClient : public communication::PBHandler, - sizeof(ServiceInfoStaticArray) + sizeof(LayerInfoStaticArray) + sizeof(InstanceInfoStaticArray))> + + Max(sizeof(NodeInfo), sizeof(aos::monitoring::NodeMonitoringData), + sizeof(ServiceInfoStaticArray) + sizeof(LayerInfoStaticArray) + sizeof(InstanceInfoStaticArray), + sizeof(downloader::ImageContentInfo), sizeof(downloader::FileChunk))> mAllocator; }; diff --git a/tests/smclient/src/main.cpp b/tests/smclient/src/main.cpp index 20d8844f..18356ab1 100644 --- a/tests/smclient/src/main.cpp +++ b/tests/smclient/src/main.cpp @@ -14,6 +14,7 @@ #include "stubs/channelmanagerstub.hpp" #include "stubs/clocksyncstub.hpp" +#include "stubs/downloaderstub.hpp" #include "stubs/launcherstub.hpp" #include "stubs/nodeinfoproviderstub.hpp" #include "stubs/resourcemanagerstub.hpp" @@ -40,6 +41,7 @@ struct smclient_fixture { LauncherStub mLauncher; ResourceManagerStub mResourceManager; ResourceMonitorStub mResourceMonitor; + DownloaderStub mDownloader; ClockSyncStub mClockSync; ChannelManagerStub mChannelManager; std::unique_ptr mSMClient; @@ -87,7 +89,7 @@ static aos::RetWithError InitSMClient(smclient_fixture* fixture, u fixture->mResourceManager.UpdateNodeConfig(nodeConfigVersion, ""); auto err = fixture->mSMClient->Init(fixture->mNodeInfoProvider, fixture->mLauncher, fixture->mResourceManager, - fixture->mResourceMonitor, fixture->mClockSync, fixture->mChannelManager); + fixture->mResourceMonitor, fixture->mDownloader, fixture->mClockSync, fixture->mChannelManager); zassert_true(err.IsNone(), "Can't initialize SM client: %s", utils::ErrorToCStr(err)); fixture->mSMClient->OnClockSynced(); @@ -223,6 +225,21 @@ static void GenerateInstancesRunStatus(aos::Array& status) {"service1", "subject1", 2}, "2.0.0", aos::InstanceRunStateEnum::eFailed, aos::ErrorEnum::eRuntime}); } +static void GenerateImageContentInfo(downloader::ImageContentInfo& contentInfo) + +{ + uint8_t sha256[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + + contentInfo.mRequestID = 42; + contentInfo.mFiles.EmplaceBack( + downloader::FileInfo {"path/to/file1", aos::Array(sha256, sizeof(sha256)), 1024}); + contentInfo.mFiles.EmplaceBack( + downloader::FileInfo {"path/to/file2", aos::Array(sha256, sizeof(sha256)), 2048}); + contentInfo.mFiles.EmplaceBack( + downloader::FileInfo {"path/to/file3", aos::Array(sha256, sizeof(sha256)), 4096}); + contentInfo.mError = aos::Error(aos::ErrorEnum::eRuntime, "some error"); +} + /*********************************************************************************************************************** * Setup **********************************************************************************************************************/ @@ -240,6 +257,7 @@ ZTEST_SUITE( auto smclientFixture = static_cast(fixture); smclientFixture->mLauncher.Clear(); + smclientFixture->mDownloader.Clear(); smclientFixture->mClockSync.Clear(); smclientFixture->mSMClient.reset(new smclient::SMClient); }, @@ -615,3 +633,118 @@ ZTEST_F(smclient, test_UpdateInstancesStatus) zassert_equal(receivedUpdateStatus, sendUpdateStatus, "Wrong update instances status"); } + +ZTEST_F(smclient, test_ImageContentRequest) +{ + auto [channel, err] = InitSMClient(fixture, CONFIG_AOS_SM_SECURE_PORT, + {.mNodeID = "nodeID", .mNodeType = "nodeType", .mStatus = aos::NodeStatusEnum::eProvisioned}); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Send image content request + + downloader::ImageContentRequest sendContentRequest {"content URL", 42, aos::DownloadContentEnum::eService}; + + err = fixture->mSMClient->SendImageContentRequest(sendContentRequest); + zassert_true(err.IsNone(), "Error sending image content request: %s", utils::ErrorToCStr(err)); + + // Receive image content request + + servicemanager_v4_SMOutgoingMessages outgoingMessage; + auto& pbImageContentRequest = outgoingMessage.SMOutgoingMessage.image_content_request; + + pbImageContentRequest = servicemanager_v4_ImageContentRequest servicemanager_v4_ImageContentRequest_init_default; + + err = ReceiveSMOutgoingMessage(channel, outgoingMessage); + zassert_true(err.IsNone(), "Error receiving message: %s", utils::ErrorToCStr(err)); + + zassert_equal(outgoingMessage.which_SMOutgoingMessage, + servicemanager_v4_SMOutgoingMessages_image_content_request_tag, "Unexpected message type"); + + downloader::ImageContentRequest receiveContentRequest; + + receiveContentRequest.mRequestID = pbImageContentRequest.request_id; + utils::PBToEnum(pbImageContentRequest.content_type, receiveContentRequest.mContentType); + receiveContentRequest.mURL = utils::StringFromCStr(pbImageContentRequest.url); + + zassert_equal(receiveContentRequest, sendContentRequest); +} + +ZTEST_F(smclient, test_ImageContentInfo) +{ + auto [channel, err] = InitSMClient(fixture, CONFIG_AOS_SM_SECURE_PORT, + {.mNodeID = "nodeID", .mNodeType = "nodeType", .mStatus = aos::NodeStatusEnum::eProvisioned}); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Send image content info + + downloader::ImageContentInfo aosContentInfo; + + GenerateImageContentInfo(aosContentInfo); + + servicemanager_v4_SMIncomingMessages incomingMessage; + auto& pbImageContentInfo = incomingMessage.SMIncomingMessage.image_content_info; + + incomingMessage.which_SMIncomingMessage = servicemanager_v4_SMIncomingMessages_image_content_info_tag; + pbImageContentInfo = servicemanager_v4_ImageContentInfo servicemanager_v4_ImageContentInfo_init_default; + + pbImageContentInfo.request_id = aosContentInfo.mRequestID; + pbImageContentInfo.image_files_count = aosContentInfo.mFiles.Size(); + + for (size_t i = 0; i < aosContentInfo.mFiles.Size(); i++) { + const auto& aosFileInfo = aosContentInfo.mFiles[i]; + auto& pbFileInfo = incomingMessage.SMIncomingMessage.image_content_info.image_files[i]; + + utils::StringFromCStr(pbFileInfo.relative_path) = aosFileInfo.mRelativePath; + utils::ByteArrayToPB(aosFileInfo.mSHA256, pbFileInfo.sha256); + pbFileInfo.size = aosFileInfo.mSize; + } + + if (!aosContentInfo.mError.IsNone()) { + pbImageContentInfo.has_error = true; + pbImageContentInfo.error = utils::ErrorToPB(aosContentInfo.mError); + } + + err = SendSMIncomingMessage(channel, incomingMessage); + zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + + // Receive image content info + + err = fixture->mDownloader.WaitEvent(cWaitTimeout); + zassert_true(err.IsNone(), "Error waiting downloader event: %s", utils::ErrorToCStr(err)); + + zassert_equal(fixture->mDownloader.GetContentInfo(), aosContentInfo); +} + +ZTEST_F(smclient, test_ImageContent) +{ + auto [channel, err] = InitSMClient(fixture, CONFIG_AOS_SM_SECURE_PORT, + {.mNodeID = "nodeID", .mNodeType = "nodeType", .mStatus = aos::NodeStatusEnum::eProvisioned}); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Send image content + + uint8_t data[] = {12, 23, 45, 32, 21, 56, 12, 18}; + auto aosFileChunk = downloader::FileChunk {43, "path/to/file1", 4, 1, aos::Array(data, sizeof(data))}; + + servicemanager_v4_SMIncomingMessages incomingMessage; + auto& pbImageContent = incomingMessage.SMIncomingMessage.image_content; + + incomingMessage.which_SMIncomingMessage = servicemanager_v4_SMIncomingMessages_image_content_tag; + pbImageContent = servicemanager_v4_ImageContent servicemanager_v4_ImageContent_init_default; + + pbImageContent.request_id = aosFileChunk.mRequestID; + utils::StringFromCStr(pbImageContent.relative_path) = aosFileChunk.mRelativePath; + pbImageContent.parts_count = aosFileChunk.mPartsCount; + pbImageContent.part = aosFileChunk.mPart; + utils::ByteArrayToPB(aosFileChunk.mData, pbImageContent.data); + + err = SendSMIncomingMessage(channel, incomingMessage); + zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + + // Receive image content + + err = fixture->mDownloader.WaitEvent(cWaitTimeout); + zassert_true(err.IsNone(), "Error waiting downloader event: %s", utils::ErrorToCStr(err)); + + zassert_equal(fixture->mDownloader.GetFileChunk(), aosFileChunk); +} diff --git a/tests/smclient/src/stubs/downloaderstub.hpp b/tests/smclient/src/stubs/downloaderstub.hpp new file mode 100644 index 00000000..596ebc39 --- /dev/null +++ b/tests/smclient/src/stubs/downloaderstub.hpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2024 Renesas Electronics Corporation. + * Copyright (C) 2024 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef DOWNLOADERSTUB_HPP_ +#define DOWNLOADERSTUB_HPP_ + +#include +#include + +#include "downloader/downloader.hpp" + +class DownloaderStub : public aos::zephyr::downloader::DownloadReceiverItf { +public: + aos::Error ReceiveFileChunk(const aos::zephyr::downloader::FileChunk& chunk) override + { + std::lock_guard lock(mMutex); + + mFileChunk = chunk; + mEventReceived = true; + + mCV.notify_one(); + + return aos::ErrorEnum::eNone; + } + + aos::Error ReceiveImageContentInfo(const aos::zephyr::downloader::ImageContentInfo& content) override + { + std::lock_guard lock(mMutex); + + mContentInfo = content; + mEventReceived = true; + + mCV.notify_one(); + + return aos::ErrorEnum::eNone; + } + + const aos::zephyr::downloader::FileChunk& GetFileChunk() const + { + std::lock_guard lock(mMutex); + return mFileChunk; + } + + const aos::zephyr::downloader::ImageContentInfo& GetContentInfo() const + { + std::lock_guard lock(mMutex); + return mContentInfo; + } + + aos::Error WaitEvent(const std::chrono::duration timeout) + { + std::unique_lock lock(mMutex); + + if (!mCV.wait_for(lock, timeout, [&] { return mEventReceived; })) { + return aos::ErrorEnum::eTimeout; + } + + mEventReceived = false; + + return aos::ErrorEnum::eNone; + } + + void Clear() + { + std::lock_guard lock(mMutex); + + mEventReceived = false; + mContentInfo = aos::zephyr::downloader::ImageContentInfo(); + mFileChunk = aos::zephyr::downloader::FileChunk(); + } + +private: + aos::zephyr::downloader::ImageContentInfo mContentInfo {}; + aos::zephyr::downloader::FileChunk mFileChunk {}; + + std::condition_variable mCV; + mutable std::mutex mMutex; + bool mEventReceived = false; +}; + +#endif From 456a6eaff5701c662ed7d4873d7bc96d0eca99d0 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 22 Aug 2024 22:38:24 +0300 Subject: [PATCH 088/198] [smclient] Implement connection publisher interface Signed-off-by: Oleksandr Grytsov --- src/smclient/smclient.cpp | 35 ++++++++++++++++++++++++++++++++--- src/smclient/smclient.hpp | 11 +++++++---- tests/smclient/src/main.cpp | 29 +++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index 8e3a894f..7cc5f2c0 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -141,6 +141,10 @@ SMClient::~SMClient() LOG_ERR() << "Failed to delete channel: err=" << err; } } + + LockGuard lock {mMutex}; + + mConnectionSubscribers.Clear(); } Error SMClient::InstancesRunStatus(const Array& instances) @@ -223,13 +227,24 @@ Error SMClient::SendMonitoringData(const monitoring::NodeMonitoringData& nodeMon return SendMessage(outgoingMessage.Get(), &servicemanager_v4_SMOutgoingMessages_msg); } -Error SMClient::Subscribes(ConnectionSubscriberItf& subscriber) +Error SMClient::Subscribe(ConnectionSubscriberItf& subscriber) { - return ErrorEnum::eNone; + LockGuard lock(mMutex); + + if (auto err = mConnectionSubscribers.PushBack(&subscriber); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + return aos::ErrorEnum::eNone; } -void SMClient::Unsubscribes(ConnectionSubscriberItf& subscriber) +void SMClient::Unsubscribe(ConnectionSubscriberItf& subscriber) { + LockGuard lock(mMutex); + + if (auto it = mConnectionSubscribers.Find(&subscriber); it.mError.IsNone()) { + mConnectionSubscribers.Remove(it.mValue); + } } Error SMClient::OnNodeStatusChanged(const String& nodeID, const NodeStatus& status) @@ -284,10 +299,24 @@ Error SMClient::SendClockSyncRequest() void SMClient::OnConnect() { + LockGuard lock {mMutex}; + + LOG_INF() << "On connect notification"; + + for (auto& subscriber : mConnectionSubscribers) { + subscriber->OnConnect(); + } } void SMClient::OnDisconnect() { + LockGuard lock {mMutex}; + + LOG_INF() << "On disconnect notification"; + + for (auto& subscriber : mConnectionSubscribers) { + subscriber->OnDisconnect(); + } } Error SMClient::ReceiveMessage(const Array& data) diff --git a/src/smclient/smclient.hpp b/src/smclient/smclient.hpp index c315f634..fa0d2490 100644 --- a/src/smclient/smclient.hpp +++ b/src/smclient/smclient.hpp @@ -95,14 +95,14 @@ class SMClient : public communication::PBHandler mConnectionSubscribers; + StaticAllocatormDownloader.GetFileChunk(), aosFileChunk); } + +ZTEST_F(smclient, test_ConnectionNotification) +{ + ConnectionSubscriberStub subscriber; + + auto err = fixture->mSMClient->Subscribe(subscriber); + zassert_true(err.IsNone(), "Error subscribing connection notification: %s", utils::ErrorToCStr(err)); + + ChannelStub* channel = nullptr; + + aos::Tie(channel, err) = InitSMClient(fixture, CONFIG_AOS_SM_SECURE_PORT, + {.mNodeID = "nodeID", .mNodeType = "nodeType", .mStatus = aos::NodeStatusEnum::eProvisioned}); + zassert_true(err.IsNone(), "Getting channel error: %s", utils::ErrorToCStr(err)); + + // Wait connected + + err = subscriber.WaitConnect(cWaitTimeout); + zassert_true(err.IsNone(), "Wait connection error: %s", err.Message()); + + // Wait disconnected + + fixture->mSMClient->OnClockUnsynced(); + + err = subscriber.WaitDisconnect(cWaitTimeout); + zassert_true(err.IsNone(), "Wait connection error: %s", err.Message()); + + fixture->mSMClient->Unsubscribe(subscriber); +} From 71a954a5b14331ee808c190378deb44d258a459b Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 22 Aug 2024 23:02:14 +0300 Subject: [PATCH 089/198] [resourcemanager] Rename node config vendorVersion to version Signed-off-by: Oleksandr Grytsov --- src/resourcemanager/resourcemanager.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/resourcemanager/resourcemanager.cpp b/src/resourcemanager/resourcemanager.cpp index 425aee3c..34726797 100644 --- a/src/resourcemanager/resourcemanager.cpp +++ b/src/resourcemanager/resourcemanager.cpp @@ -20,13 +20,13 @@ namespace aos::zephyr::resourcemanager { * Node config. */ struct NodeConfig { - const char* vendorVersion = ""; - const char* nodeType = ""; - uint32_t priority = 0; + const char* version = ""; + const char* nodeType = ""; + uint32_t priority = 0; }; static const struct json_obj_descr cNodeConfigDescr[] = { - JSON_OBJ_DESCR_PRIM(NodeConfig, vendorVersion, JSON_TOK_STRING), + JSON_OBJ_DESCR_PRIM(NodeConfig, version, JSON_TOK_STRING), JSON_OBJ_DESCR_PRIM(NodeConfig, nodeType, JSON_TOK_STRING), JSON_OBJ_DESCR_PRIM(NodeConfig, priority, JSON_TOK_NUMBER), }; @@ -46,9 +46,9 @@ Error JSONProvider::DumpNodeConfig(const sm::resourcemanager::NodeConfig& config auto jsonNodeConfig = MakeUnique(&mAllocator); - jsonNodeConfig->vendorVersion = config.mVendorVersion.CStr(); - jsonNodeConfig->nodeType = config.mNodeConfig.mNodeType.CStr(); - jsonNodeConfig->priority = config.mNodeConfig.mPriority; + jsonNodeConfig->version = config.mVersion.CStr(); + jsonNodeConfig->nodeType = config.mNodeConfig.mNodeType.CStr(); + jsonNodeConfig->priority = config.mNodeConfig.mPriority; auto ret = json_obj_encode_buf( cNodeConfigDescr, ARRAY_SIZE(cNodeConfigDescr), jsonNodeConfig.Get(), json.Get(), json.MaxSize()); @@ -81,7 +81,7 @@ Error JSONProvider::ParseNodeConfig(const String& json, sm::resourcemanager::Nod return AOS_ERROR_WRAP(ret); } - config.mVendorVersion = parsedNodeConfig->vendorVersion; + config.mVersion = parsedNodeConfig->version; config.mNodeConfig.mNodeType = parsedNodeConfig->nodeType; config.mNodeConfig.mPriority = parsedNodeConfig->priority; From 32f7c2ded01928ecb17db910ffa3d97d719a2db5 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 22 Aug 2024 23:13:45 +0300 Subject: [PATCH 090/198] [app] Update SM client initialization Signed-off-by: Oleksandr Grytsov --- src/app/app.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index c645efe1..00bd1106 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -167,12 +167,6 @@ Error App::InitZephyr() return AOS_ERROR_WRAP(err); } - if (auto err - = mIAMClient.Init(mClockSync, mNodeInfoProvider, mProvisionManager, mChannelManager, mCertHandler, mCertLoader); - !err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - if (auto err = mDownloader.Init(mSMClient); !err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -189,7 +183,15 @@ Error App::InitZephyr() return AOS_ERROR_WRAP(err); } - if (auto err = mSMClient.Init(mClockSync, mChannelManager); !err.IsNone()) { + if (auto err + = mIAMClient.Init(mClockSync, mNodeInfoProvider, mProvisionManager, mChannelManager, mCertHandler, mCertLoader); + !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + if (auto err = mSMClient.Init( + mNodeInfoProvider, mLauncher, mResourceManager, mResourceMonitor, mDownloader, mClockSync, mChannelManager); + !err.IsNone()) { return AOS_ERROR_WRAP(err); } From b3c61c11de0099a5881aadb0de0acb3d85cdd377 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 22 Aug 2024 23:26:30 +0300 Subject: [PATCH 091/198] [communication] Set connection socket logs inf level Signed-off-by: Oleksandr Grytsov --- src/communication/socket.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/communication/socket.cpp b/src/communication/socket.cpp index 6aadfa12..46b6c731 100644 --- a/src/communication/socket.cpp +++ b/src/communication/socket.cpp @@ -31,7 +31,7 @@ aos::Error Socket::Init(const aos::String& serverAddress, int serverPort) aos::Error Socket::Open() { - LOG_DBG() << "Connecting client socket to connect to: address=" << mServerAddress.CStr() << " port=" << mServerPort; + LOG_INF() << "Connecting socket to: address=" << mServerAddress.CStr() << " port=" << mServerPort; mSocketFd = socket(AF_INET, SOCK_STREAM, 0); if (mSocketFd == -1) { @@ -54,7 +54,7 @@ aos::Error Socket::Open() return aos::Error(aos::ErrorEnum::eRuntime, "failed to connect to server"); } - LOG_DBG() << "Connected to server: address=" << mServerAddress.CStr() << " port=" << mServerPort; + LOG_INF() << "Connected to server: address=" << mServerAddress.CStr() << " port=" << mServerPort; mOpened = true; From ccb232e31bb1513cfc2ff69379558b1324dce03f Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 22 Aug 2024 23:27:07 +0300 Subject: [PATCH 092/198] [boards] Set CONFIG_LOG_MODE_IMMEDIATE=y for native boards Signed-off-by: Oleksandr Grytsov --- boards/native_posix.conf | 1 + boards/native_posix_64.conf | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/native_posix.conf b/boards/native_posix.conf index ec9f9c46..ab94e62e 100644 --- a/boards/native_posix.conf +++ b/boards/native_posix.conf @@ -17,6 +17,7 @@ CONFIG_NEWLIB_LIBC_NANO=n CONFIG_LOG_BACKEND_NATIVE_POSIX=y CONFIG_SHELL_LOG_BACKEND=n +CONFIG_LOG_MODE_IMMEDIATE=y # Slow down to real time diff --git a/boards/native_posix_64.conf b/boards/native_posix_64.conf index ec9f9c46..ab94e62e 100644 --- a/boards/native_posix_64.conf +++ b/boards/native_posix_64.conf @@ -17,6 +17,7 @@ CONFIG_NEWLIB_LIBC_NANO=n CONFIG_LOG_BACKEND_NATIVE_POSIX=y CONFIG_SHELL_LOG_BACKEND=n +CONFIG_LOG_MODE_IMMEDIATE=y # Slow down to real time From 0e23333945ab11683ff47dfebf4f613f3aafaf36 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 22 Aug 2024 23:59:30 +0300 Subject: [PATCH 093/198] [boards] Set log level to debug for native boards Signed-off-by: Oleksandr Grytsov --- boards/native_posix.conf | 1 + boards/native_posix_64.conf | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/native_posix.conf b/boards/native_posix.conf index ab94e62e..e5498e4d 100644 --- a/boards/native_posix.conf +++ b/boards/native_posix.conf @@ -15,6 +15,7 @@ CONFIG_NEWLIB_LIBC_NANO=n # Configure logs +CONFIG_LOG_DEFAULT_LEVEL=4 CONFIG_LOG_BACKEND_NATIVE_POSIX=y CONFIG_SHELL_LOG_BACKEND=n CONFIG_LOG_MODE_IMMEDIATE=y diff --git a/boards/native_posix_64.conf b/boards/native_posix_64.conf index ab94e62e..e5498e4d 100644 --- a/boards/native_posix_64.conf +++ b/boards/native_posix_64.conf @@ -15,6 +15,7 @@ CONFIG_NEWLIB_LIBC_NANO=n # Configure logs +CONFIG_LOG_DEFAULT_LEVEL=4 CONFIG_LOG_BACKEND_NATIVE_POSIX=y CONFIG_SHELL_LOG_BACKEND=n CONFIG_LOG_MODE_IMMEDIATE=y From b8f6d201ece548eb65f03f1e7d23b0e0c3747c34 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 22 Aug 2024 23:59:59 +0300 Subject: [PATCH 094/198] [communication] Remove redundant aos:: namespace Signed-off-by: Oleksandr Grytsov --- src/communication/socket.cpp | 22 +++++++++++----------- src/communication/socket.hpp | 14 +++++++------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/communication/socket.cpp b/src/communication/socket.cpp index 46b6c731..a8e78354 100644 --- a/src/communication/socket.cpp +++ b/src/communication/socket.cpp @@ -20,22 +20,22 @@ namespace aos::zephyr::communication { * Public **********************************************************************************************************************/ -aos::Error Socket::Init(const aos::String& serverAddress, int serverPort) +Error Socket::Init(const String& serverAddress, int serverPort) { mServerAddress = serverAddress; mServerPort = serverPort; mSocketFd = -1; - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error Socket::Open() +Error Socket::Open() { - LOG_INF() << "Connecting socket to: address=" << mServerAddress.CStr() << " port=" << mServerPort; + LOG_INF() << "Connecting socket to: address=" << mServerAddress << ", port=" << mServerPort; mSocketFd = socket(AF_INET, SOCK_STREAM, 0); if (mSocketFd == -1) { - return aos::Error(aos::ErrorEnum::eRuntime, "failed to create socket"); + return Error(ErrorEnum::eRuntime, "failed to create socket"); } struct sockaddr_in addr; @@ -45,23 +45,23 @@ aos::Error Socket::Open() if (inet_pton(AF_INET, mServerAddress.CStr(), &addr.sin_addr) <= 0) { close(mSocketFd); mSocketFd = -1; - return aos::Error(aos::ErrorEnum::eRuntime, "invalid server address"); + return Error(ErrorEnum::eRuntime, "invalid server address"); } if (connect(mSocketFd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { close(mSocketFd); mSocketFd = -1; - return aos::Error(aos::ErrorEnum::eRuntime, "failed to connect to server"); + return Error(ErrorEnum::eRuntime, "failed to connect to server"); } - LOG_INF() << "Connected to server: address=" << mServerAddress.CStr() << " port=" << mServerPort; + LOG_INF() << "Connected to server: address=" << mServerAddress.CStr() << ", port=" << mServerPort; mOpened = true; - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error Socket::Close() +Error Socket::Close() { if (mSocketFd != -1) { close(mSocketFd); @@ -70,7 +70,7 @@ aos::Error Socket::Close() mOpened = false; - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } int Socket::Read(void* data, size_t size) diff --git a/src/communication/socket.hpp b/src/communication/socket.hpp index 2e0f762f..af4ff18e 100644 --- a/src/communication/socket.hpp +++ b/src/communication/socket.hpp @@ -24,14 +24,14 @@ class Socket : public TransportItf { * * @param serverAddress Server address. * @param serverPort Server port. - * @return aos::Error. + * @return Error. */ - Error Init(const aos::String& serverAddress, int serverPort); + Error Init(const String& serverAddress, int serverPort); /** * Opens the socket. * - * @return aos::Error. + * @return Error. */ Error Open() override; @@ -71,10 +71,10 @@ class Socket : public TransportItf { int ReadFromSocket(int fd, void* data, size_t size); int WriteToSocket(int fd, const void* data, size_t size); - aos::StaticString mServerAddress; - int mServerPort {-1}; - int mSocketFd {-1}; - bool mOpened {}; + StaticString mServerAddress; + int mServerPort {-1}; + int mSocketFd {-1}; + bool mOpened {}; }; } // namespace aos::zephyr::communication From 8bc7b0fa65ff09a04d10011a7ae60504ed1b5382 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 23 Aug 2024 10:51:48 +0300 Subject: [PATCH 095/198] [Kconfig] Remove unused AOS_NODE_ID Signed-off-by: Oleksandr Grytsov --- Kconfig | 4 ---- README.md | 2 -- 2 files changed, 6 deletions(-) diff --git a/Kconfig b/Kconfig index 3a694a3c..a5149dcb 100644 --- a/Kconfig +++ b/Kconfig @@ -43,10 +43,6 @@ config AOS_NODE_CONFIG_FILE string "Node configuration file path" default "/aos/node_config.cfg" -config AOS_NODE_ID - string "Node id" - default "NODE_0" - config AOS_NODE_NAME string "Node name" default "zephyr" diff --git a/README.md b/README.md index bdee48de..615861ca 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,6 @@ For real hardware with Xen the following command shall be used: ```sh west build -b ${BOARD} -p auto -S xen_dom0 -- \ --D'DCONFIG_AOS_NODE_ID="my_node_id"' \ -D'DCONFIG_AOS_NODE_TYPE="my_node_type"' \ -D'CONFIG_DOMD_UBOOT_PATH="path/to/domd/u-boot"' \ -D'CONFIG_DOMD_DTB_PATH="path/to/domd/dtb"' \ @@ -52,7 +51,6 @@ west build -b ${BOARD} -p auto -S xen_dom0 -- \ where: -* `CONFIG_AOS_NODE_ID` - Aos node ID; * `CONFIG_AOS_NODE_TYPE` - Aos node type; * `CONFIG_DOMD_UBOOT_PATH` - path to DomD u-boot binary; * `CONFIG_DOMD_DTB_PATH` - path to DomD DTB file; From 8c20a3319c1055d176235c37824cad47c52102e6 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 23 Aug 2024 10:56:45 +0300 Subject: [PATCH 096/198] [resourcemanager] Use calculated size for allocator Signed-off-by: Oleksandr Grytsov --- src/resourcemanager/resourcemanager.cpp | 4 ---- src/resourcemanager/resourcemanager.hpp | 8 +++----- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/resourcemanager/resourcemanager.cpp b/src/resourcemanager/resourcemanager.cpp index 34726797..f109503d 100644 --- a/src/resourcemanager/resourcemanager.cpp +++ b/src/resourcemanager/resourcemanager.cpp @@ -42,8 +42,6 @@ Error JSONProvider::DumpNodeConfig(const sm::resourcemanager::NodeConfig& config { LockGuard lock(mMutex); - mAllocator.Clear(); - auto jsonNodeConfig = MakeUnique(&mAllocator); jsonNodeConfig->version = config.mVersion.CStr(); @@ -68,8 +66,6 @@ Error JSONProvider::ParseNodeConfig(const String& json, sm::resourcemanager::Nod { LockGuard lock(mMutex); - mAllocator.Clear(); - // json_object_parse mutates the input string, so we need to copy it mJSONBuffer = json; diff --git a/src/resourcemanager/resourcemanager.hpp b/src/resourcemanager/resourcemanager.hpp index 04135bd5..2159800c 100644 --- a/src/resourcemanager/resourcemanager.hpp +++ b/src/resourcemanager/resourcemanager.hpp @@ -40,12 +40,10 @@ class JSONProvider : public sm::resourcemanager::JSONProviderItf { private: static constexpr size_t cJsonMaxContentLen = 1024; - static constexpr size_t cAllocationSize = 2048; - static constexpr size_t cMaxNumAllocations = 32; - mutable Mutex mMutex; - mutable StaticString mJSONBuffer; - mutable StaticAllocator mAllocator; + mutable Mutex mMutex; + mutable StaticString mJSONBuffer; + mutable StaticAllocator mAllocator; }; /** From 75cb086ae814d84a5c708cfef9be5cf31b16edc1 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 23 Aug 2024 11:53:55 +0300 Subject: [PATCH 097/198] [monitoring] Remove DMIPS scaling from resource usage provider Signed-off-by: Oleksandr Grytsov --- src/app/app.cpp | 2 +- src/monitoring/resourceusageprovider.cpp | 9 ++------- src/monitoring/resourceusageprovider.hpp | 5 ++--- src/smclient/smclient.cpp | 2 +- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index 00bd1106..93e32bae 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -171,7 +171,7 @@ Error App::InitZephyr() return AOS_ERROR_WRAP(err); } - if (auto err = mResourceUsageProvider.Init(mNodeInfoProvider); !err.IsNone()) { + if (auto err = mResourceUsageProvider.Init(); !err.IsNone()) { return AOS_ERROR_WRAP(err); } diff --git a/src/monitoring/resourceusageprovider.cpp b/src/monitoring/resourceusageprovider.cpp index f92e9812..f4f5676c 100644 --- a/src/monitoring/resourceusageprovider.cpp +++ b/src/monitoring/resourceusageprovider.cpp @@ -19,15 +19,10 @@ namespace aos::zephyr::monitoring { * Public **********************************************************************************************************************/ -Error ResourceUsageProvider::Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider) +Error ResourceUsageProvider::Init() { LOG_DBG() << "Init resource usage provider"; - auto err = nodeInfoProvider.GetNodeInfo(mNodeInfo); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - return ErrorEnum::eNone; } @@ -53,7 +48,7 @@ Error ResourceUsageProvider::GetNodeMonitoringData( auto us_elapsed = (curTime.tv_sec - mPrevTime.tv_sec) * 1000000.0 + (curTime.tv_usec - mPrevTime.tv_usec); - monitoringData.mCPU = (cpuTimeDiff_ns * mNodeInfo.mMaxDMIPS / 1000.0 / us_elapsed); + monitoringData.mCPU = (cpuTimeDiff_ns * 100.0 / 1000.0 / us_elapsed); } LOG_DBG() << "Get node monitoring data: RAM(K): " << (monitoringData.mRAM / 1024) diff --git a/src/monitoring/resourceusageprovider.hpp b/src/monitoring/resourceusageprovider.hpp index 5af2061a..ce1f43c1 100644 --- a/src/monitoring/resourceusageprovider.hpp +++ b/src/monitoring/resourceusageprovider.hpp @@ -21,9 +21,9 @@ class ResourceUsageProvider : public aos::monitoring::ResourceUsageProviderItf { * Initializes resource usage provider. * * @param nodeInfoProvider node info provider. - * @return Error + * @return Error. */ - Error Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider); + Error Init(); /** * Returns node monitoring data. @@ -63,7 +63,6 @@ class ResourceUsageProvider : public aos::monitoring::ResourceUsageProviderItf { timeval mPrevTime {}; StaticArray mPrevInstanceCPUTime {}; Mutex mMutex {}; - NodeInfo mNodeInfo {}; }; } // namespace aos::zephyr::monitoring diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index 7cc5f2c0..2f7a5b76 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -30,7 +30,7 @@ static google_protobuf_Timestamp TimestampToPB(const Time& time) static void MonitoringDataToPB(const monitoring::MonitoringData& monitoringData, const Time& timestamp, servicemanager_v4_MonitoringData& pbMonitoringData) { - pbMonitoringData.cpu = monitoringData.mCPU; + pbMonitoringData.cpu = monitoringData.mCPU + 0.5; pbMonitoringData.ram = monitoringData.mRAM; pbMonitoringData.download = monitoringData.mDownload; pbMonitoringData.upload = monitoringData.mUpload; From b9979eba612c6a06456b1f05987a16b9dd487603 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 23 Aug 2024 12:35:09 +0300 Subject: [PATCH 098/198] [tests,resourcemanager] Update to new interface Signed-off-by: Oleksandr Grytsov --- tests/resourcemanager/CMakeLists.txt | 16 ++++++----- tests/resourcemanager/prj.conf | 4 ++- tests/resourcemanager/src/main.cpp | 40 +++++++++++++++------------- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/tests/resourcemanager/CMakeLists.txt b/tests/resourcemanager/CMakeLists.txt index 96caba15..e48a3764 100644 --- a/tests/resourcemanager/CMakeLists.txt +++ b/tests/resourcemanager/CMakeLists.txt @@ -9,25 +9,29 @@ project(resourcemanager_test) # Config # ###################################################################################################################### -set(AOS_CORE_CONFIG aoscoreconfig.hpp) +set(aoscore_config aoscoreconfig.hpp) +set(aoscore_source_dir "${CMAKE_CURRENT_SOURCE_DIR}/../../../aos_core_lib_cpp") # ###################################################################################################################### # Definitions # ###################################################################################################################### # Aos core configuration -add_definitions(-include ${AOS_CORE_CONFIG}) +add_definitions(-include ${aoscore_config}) # ###################################################################################################################### # Includes # ###################################################################################################################### -target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../src) -target_include_directories(app PRIVATE ${APPLICATION_SOURCE_DIR}/../../../aos_core_lib_cpp/include) -target_include_directories(app PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +zephyr_include_directories(${aoscore_source_dir}/include) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/..) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/../../src) +zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src) # ###################################################################################################################### # Target # ###################################################################################################################### -target_sources(app PRIVATE src/main.cpp ../../src/resourcemanager/resourcemanager.cpp) +target_sources( + app PRIVATE src/main.cpp ../utils/log.cpp ../../src/utils/utils.cpp ../../src/resourcemanager/resourcemanager.cpp +) diff --git a/tests/resourcemanager/prj.conf b/tests/resourcemanager/prj.conf index 927f0f8b..0f4fd171 100644 --- a/tests/resourcemanager/prj.conf +++ b/tests/resourcemanager/prj.conf @@ -1,6 +1,8 @@ # Enable C++ CONFIG_CPP=y -CONFIG_STD_CPP14=y +CONFIG_STD_CPP17=y +CONFIG_EXTERNAL_LIBCPP=y +CONFIG_CBPRINTF_FP_SUPPORT=y # Enable test suit CONFIG_ZTEST=y diff --git a/tests/resourcemanager/src/main.cpp b/tests/resourcemanager/src/main.cpp index 7346e8a5..0a6d8598 100644 --- a/tests/resourcemanager/src/main.cpp +++ b/tests/resourcemanager/src/main.cpp @@ -13,12 +13,20 @@ #include "resourcemanager/resourcemanager.hpp" -static constexpr auto cTestNodeConfigJSON = R"({"nodeType":"mainType","priority":1,"vendorVersion":"1.0"})"; +#include "utils/log.hpp" +#include "utils/utils.hpp" -static void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message) -{ - printk("[resourcemanager] %s \n", message.CStr()); -} +using namespace aos::zephyr; + +/*********************************************************************************************************************** + * Consts + **********************************************************************************************************************/ + +static constexpr auto cTestNodeConfigJSON = R"({"nodeType":"mainType","priority":1,"version":"1.0.0"})"; + +/*********************************************************************************************************************** + * Tests + **********************************************************************************************************************/ ZTEST_SUITE(resourcemanager, NULL, NULL, NULL, NULL, NULL); @@ -34,11 +42,8 @@ ZTEST(resourcemanager, test_JSONProviderParse) zassert_true(err.IsNone(), "Failed to parse node config: %s", err.Message()); zassert_equal(1, nodeConfig.mNodeConfig.mPriority, "Priority mismatch"); - zassert_true(strncmp("1.0", nodeConfig.mVendorVersion.CStr(), nodeConfig.mVendorVersion.Size()) == 0, - "File content mismatch"); - zassert_true( - strncmp("mainType", nodeConfig.mNodeConfig.mNodeType.CStr(), nodeConfig.mNodeConfig.mNodeType.Size()) == 0, - "Node type mismatch"); + zassert_equal(nodeConfig.mVersion, "1.0.0", "File content mismatch"); + zassert_equal(nodeConfig.mNodeConfig.mNodeType, "mainType", "Node type mismatch"); } ZTEST(resourcemanager, test_DumpNodeConfig) @@ -48,20 +53,19 @@ ZTEST(resourcemanager, test_DumpNodeConfig) aos::zephyr::resourcemanager::JSONProvider provider; aos::sm::resourcemanager::NodeConfig nodeConfig; nodeConfig.mNodeConfig.mPriority = 1; - nodeConfig.mVendorVersion = "1.0"; + nodeConfig.mVersion = "1.0.0"; nodeConfig.mNodeConfig.mNodeType = "mainType"; aos::StaticString<1024> jsonStr; auto err = provider.DumpNodeConfig(nodeConfig, jsonStr); - zassert_true(err.IsNone(), "Failed to dump node config: %s", err.Message()); + zassert_true(err.IsNone(), "Failed to dump node config: %s", utils::ErrorToCStr(err)); zassert_false(jsonStr.IsEmpty(), "Empty json string"); - aos::sm::resourcemanager::NodeConfig parsednodeConfig; - err = provider.ParseNodeConfig(jsonStr, parsednodeConfig); + aos::sm::resourcemanager::NodeConfig parsedNodeConfig; + err = provider.ParseNodeConfig(jsonStr, parsedNodeConfig); - zassert_true(err.IsNone(), "Failed to parse node config: %s", err.Message()); - zassert_true(nodeConfig.mNodeConfig == parsednodeConfig.mNodeConfig, "Parsed node config mismatch"); - zassert_true( - nodeConfig.mVendorVersion == parsednodeConfig.mVendorVersion, "Parsed unit config vendor version mismatch"); + zassert_true(err.IsNone(), "Failed to parse node config: %s", utils::ErrorToCStr(err)); + zassert_equal(nodeConfig.mNodeConfig, parsedNodeConfig.mNodeConfig, "Parsed node config mismatch"); + zassert_equal(nodeConfig.mVersion, parsedNodeConfig.mVersion, "Parsed unit config vendor version mismatch"); } From d2c94d3f217f03ef7e24acd4dff413eb27b437c3 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 23 Aug 2024 15:17:16 +0300 Subject: [PATCH 099/198] [tests,nodeinfoprovider] Add CONFIG_AOS_NODE_NAME Signed-off-by: Oleksandr Grytsov --- src/nodeinfoprovider/nodeinfoprovider.hpp | 4 ++-- tests/nodeinfoprovider/Kconfig | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/nodeinfoprovider/nodeinfoprovider.hpp b/src/nodeinfoprovider/nodeinfoprovider.hpp index 7d743840..77e6a81f 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.hpp +++ b/src/nodeinfoprovider/nodeinfoprovider.hpp @@ -60,10 +60,10 @@ class NodeInfoProvider : public iam::nodeinfoprovider::NodeInfoProviderItf { private: static constexpr auto cNodeStatusLen = 16; + static constexpr auto cNodeType = CONFIG_AOS_NODE_TYPE; static constexpr auto cNodeName = CONFIG_AOS_NODE_NAME; - static constexpr auto cDiskPartitionPoint = CONFIG_AOS_DISK_MOUNT_POINT; static constexpr auto cMaxDMIPS = CONFIG_AOS_MAX_CPU_DMIPS; - static constexpr auto cNodeType = CONFIG_AOS_NODE_TYPE; + static constexpr auto cDiskPartitionPoint = CONFIG_AOS_DISK_MOUNT_POINT; static constexpr auto cProvisioningStateFile = CONFIG_AOS_PROVISION_STATE_FILE; static constexpr auto cDiskPartitionName = "aos"; static constexpr auto cNodeRunner = "xrun"; diff --git a/tests/nodeinfoprovider/Kconfig b/tests/nodeinfoprovider/Kconfig index 6a59205a..12f71080 100644 --- a/tests/nodeinfoprovider/Kconfig +++ b/tests/nodeinfoprovider/Kconfig @@ -7,7 +7,11 @@ mainmenu "Aos zephyr application" config AOS_NODE_TYPE string "Node type" - default "NODE_TYPE1" + default "NODE_NAME" + +config AOS_NODE_NAME + string "Node name" + default "NODE_NAME" config AOS_MAX_CPU_DMIPS int "Maximum CPU DMIPS" From 2ebf6e425c86cefbe1e91bd68d55b3f08724806b Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 23 Aug 2024 15:51:42 +0300 Subject: [PATCH 100/198] [Kconfig] Use /lfs as default aos disk mount point Signed-off-by: Oleksandr Grytsov --- Kconfig | 32 ++++++++++++++++---------------- prj.conf | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Kconfig b/Kconfig index a5149dcb..419503e9 100644 --- a/Kconfig +++ b/Kconfig @@ -25,11 +25,11 @@ config AOS_REBOOT_XEN_STORE_PATH config AOS_DISK_MOUNT_POINT string "Disk mount point" - default "/aos" + default "/lfs" config AOS_STORAGE_DIR string "Path to the storage" - default "/aos/storage" + default "/lfs/aos/storage" config AOS_RUNTIME_DIR string "Aos runtime dir" @@ -37,11 +37,23 @@ config AOS_RUNTIME_DIR config AOS_SERVICES_DIR string "Aos services dir" - default "/aos/services" + default "/lfs/aos/services" config AOS_NODE_CONFIG_FILE string "Node configuration file path" - default "/aos/node_config.cfg" + default "/lfs/aos/node_config.cfg" + +config AOS_NODE_STATUS_FILE + string "Path to provisioning state file." + default "/lfs/aos/.nodestatus" + +config AOS_PKCS11_MODULE_PIN_FILE + string "Path to PKCS11 module PIN file." + default "/lfs/aos/.pkcs11pin" + +config AOS_HSM_DIR + string "Path HSM tokens dir." + default "/lfs/tee" config AOS_NODE_NAME string "Node name" @@ -67,18 +79,6 @@ config AOS_MAX_CPU_DMIPS int "Maximum CPU DMIPS" default 10000 -config AOS_PROVISION_STATE_FILE - string "Path to provisioning state file." - default "/aos/.provisionstate" - -config AOS_PKCS11_MODULE_PIN_FILE - string "Path to PKCS11 module PIN file." - default "/aos/.pkcs11pin" - -config AOS_HSM_DIR - string "Path HSM tokens dir." - default "/aos/tee" - config AOS_ROOT_CA_PATH string "Path to Aos Root CA certificate. Required to build in root CA into app image." default "prebuilt/rootca.pem" diff --git a/prj.conf b/prj.conf index 74f24647..4503a1b6 100644 --- a/prj.conf +++ b/prj.conf @@ -153,7 +153,7 @@ CONFIG_OPTEE_LIBTEEC=y CONFIG_OPTEE_LIBCKTEEC=y CONFIG_OPTEE_TEE_SUPPLICANT=y CONFIG_OPTEE_TEE_SUPPLICANT_AUTOINIT=n -CONFIG_OPTEE_STORAGE_ROOT="/aos/tee" +CONFIG_OPTEE_STORAGE_ROOT="/lfs/tee" # ###################################################################################################################### # Xen and its components From a115360bc5c1f1bb306dd5429d379c104071ae31 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 23 Aug 2024 15:52:41 +0300 Subject: [PATCH 101/198] [nodeinfoprovider] Rename cProvisionStateFile to cNodeStatusFile Signed-off-by: Oleksandr Grytsov --- boards/native_posix.conf | 2 +- boards/native_posix_64.conf | 2 +- src/nodeinfoprovider/nodeinfoprovider.cpp | 4 ++-- src/nodeinfoprovider/nodeinfoprovider.hpp | 2 +- tests/nodeinfoprovider/Kconfig | 4 ++-- tests/nodeinfoprovider/src/main.cpp | 6 +++--- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/boards/native_posix.conf b/boards/native_posix.conf index e5498e4d..2b7b54cd 100644 --- a/boards/native_posix.conf +++ b/boards/native_posix.conf @@ -80,7 +80,7 @@ CONFIG_AOS_RUNTIME_DIR=".aos/runtime" CONFIG_AOS_SERVICES_DIR=".aos/services" CONFIG_AOS_NODE_CONFIG_FILE=".aos/node_config.cfg" CONFIG_AOS_HSM_DIR=".aos/hsm" -CONFIG_AOS_PROVISION_STATE_FILE=".aos/.provisionstate" +CONFIG_AOS_NODE_STATUS_FILE=".aos/.nodestatus" CONFIG_AOS_PKCS11_MODULE_PIN_FILE=".aos/.pkcs11pin" # Disable OP-TEE driver and client libraries diff --git a/boards/native_posix_64.conf b/boards/native_posix_64.conf index e5498e4d..2b7b54cd 100644 --- a/boards/native_posix_64.conf +++ b/boards/native_posix_64.conf @@ -80,7 +80,7 @@ CONFIG_AOS_RUNTIME_DIR=".aos/runtime" CONFIG_AOS_SERVICES_DIR=".aos/services" CONFIG_AOS_NODE_CONFIG_FILE=".aos/node_config.cfg" CONFIG_AOS_HSM_DIR=".aos/hsm" -CONFIG_AOS_PROVISION_STATE_FILE=".aos/.provisionstate" +CONFIG_AOS_NODE_STATUS_FILE=".aos/.nodestatus" CONFIG_AOS_PKCS11_MODULE_PIN_FILE=".aos/.pkcs11pin" # Disable OP-TEE driver and client libraries diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp index b6aec66d..efedd2e2 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -212,7 +212,7 @@ Error NodeInfoProvider::StoreNodeStatus(const NodeStatus& status) const { auto statusStr = status.ToString(); - if (auto err = FS::WriteStringToFile(cProvisioningStateFile, statusStr, S_IRUSR | S_IWUSR); !err.IsNone()) { + if (auto err = FS::WriteStringToFile(cNodeStatusFile, statusStr, S_IRUSR | S_IWUSR); !err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -223,7 +223,7 @@ RetWithError NodeInfoProvider::ReadNodeStatus() const { StaticString statusStr; - auto err = FS::ReadFileToString(cProvisioningStateFile, statusStr); + auto err = FS::ReadFileToString(cNodeStatusFile, statusStr); if (!err.IsNone()) { if (err == -ENOENT) { return {NodeStatusEnum::eUnprovisioned, ErrorEnum::eNone}; diff --git a/src/nodeinfoprovider/nodeinfoprovider.hpp b/src/nodeinfoprovider/nodeinfoprovider.hpp index 77e6a81f..70be458e 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.hpp +++ b/src/nodeinfoprovider/nodeinfoprovider.hpp @@ -64,7 +64,7 @@ class NodeInfoProvider : public iam::nodeinfoprovider::NodeInfoProviderItf { static constexpr auto cNodeName = CONFIG_AOS_NODE_NAME; static constexpr auto cMaxDMIPS = CONFIG_AOS_MAX_CPU_DMIPS; static constexpr auto cDiskPartitionPoint = CONFIG_AOS_DISK_MOUNT_POINT; - static constexpr auto cProvisioningStateFile = CONFIG_AOS_PROVISION_STATE_FILE; + static constexpr auto cNodeStatusFile = CONFIG_AOS_NODE_STATUS_FILE; static constexpr auto cDiskPartitionName = "aos"; static constexpr auto cNodeRunner = "xrun"; static constexpr auto cAosComponents = "iam,sm"; diff --git a/tests/nodeinfoprovider/Kconfig b/tests/nodeinfoprovider/Kconfig index 12f71080..14b83304 100644 --- a/tests/nodeinfoprovider/Kconfig +++ b/tests/nodeinfoprovider/Kconfig @@ -21,8 +21,8 @@ config AOS_DISK_MOUNT_POINT string "Disk mount point" default ".aos" -config AOS_PROVISION_STATE_FILE +config AOS_NODE_STATUS_FILE string "Path to provisioning state file." - default ".aos/provisionstate" + default ".aos/.nodestatus" source "Kconfig" diff --git a/tests/nodeinfoprovider/src/main.cpp b/tests/nodeinfoprovider/src/main.cpp index 844eba16..2b51b019 100644 --- a/tests/nodeinfoprovider/src/main.cpp +++ b/tests/nodeinfoprovider/src/main.cpp @@ -25,8 +25,8 @@ using namespace aos::zephyr; * Consts **********************************************************************************************************************/ -static constexpr auto cNodeStateFile = CONFIG_AOS_PROVISION_STATE_FILE; -static constexpr auto cUnprovisioned = "unprovisioned"; +static constexpr auto cNodeStatusFile = CONFIG_AOS_NODE_STATUS_FILE; +static constexpr auto cUnprovisioned = "unprovisioned"; /*********************************************************************************************************************** * Static @@ -50,7 +50,7 @@ void teardown(void* data) void before_test(void* data) { - auto err = aos::FS::WriteStringToFile(cNodeStateFile, cUnprovisioned, S_IRUSR | S_IWUSR); + auto err = aos::FS::WriteStringToFile(cNodeStatusFile, cUnprovisioned, S_IRUSR | S_IWUSR); zassert_true(err.IsNone(), "Failed to create provisioning state file: %s", utils::ErrorToCStr(err)); } From f90d25d33fb323b90070fcafdf088c43ed249568 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 26 Aug 2024 12:55:11 +0300 Subject: [PATCH 102/198] [iamclient] Fix using TLS channel for secure communication Signed-off-by: Oleksandr Grytsov --- src/iamclient/iamclient.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index 6b4a87d7..f0f13501 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -212,6 +212,8 @@ Error IAMClient::SetupChannel() if (err = mTLSChannel.SetTLSConfig(cIAMCertType); !err.IsNone()) { return AOS_ERROR_WRAP(err); } + + channel = &mTLSChannel; #endif if (err = PBHandler::Init("IAM secure", *channel); !err.IsNone()) { From ea9b95f1e98d0e911891a38689de7d1741b6915b Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 26 Aug 2024 13:28:28 +0300 Subject: [PATCH 103/198] [smclient] Add TLS channel for secure connection Signed-off-by: Oleksandr Grytsov --- src/app/app.cpp | 4 ++-- src/smclient/smclient.cpp | 29 ++++++++++++++++++++++++++--- src/smclient/smclient.hpp | 21 ++++++++++++++++++++- 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index 93e32bae..e6c413ef 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -189,8 +189,8 @@ Error App::InitZephyr() return AOS_ERROR_WRAP(err); } - if (auto err = mSMClient.Init( - mNodeInfoProvider, mLauncher, mResourceManager, mResourceMonitor, mDownloader, mClockSync, mChannelManager); + if (auto err = mSMClient.Init(mNodeInfoProvider, mLauncher, mResourceManager, mResourceMonitor, mDownloader, + mClockSync, mChannelManager, mCertHandler, mCertLoader); !err.IsNone()) { return AOS_ERROR_WRAP(err); } diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index 2f7a5b76..654bee8b 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -81,7 +81,12 @@ static void InstanceStatusToPB( Error SMClient::Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvider, sm::launcher::LauncherItf& launcher, sm::resourcemanager::ResourceManagerItf& resourceManager, monitoring::ResourceMonitorItf& resourceMonitor, downloader::DownloadReceiverItf& downloader, clocksync::ClockSyncItf& clockSync, - communication::ChannelManagerItf& channelManager) + communication::ChannelManagerItf& channelManager +#ifndef CONFIG_ZTEST + , + iam::certhandler::CertHandlerItf& certHandler, cryptoutils::CertLoaderItf& certLoader +#endif +) { LOG_DBG() << "Initialize SM client"; @@ -91,6 +96,10 @@ Error SMClient::Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvide mResourceMonitor = &resourceMonitor; mDownloader = &downloader; mChannelManager = &channelManager; +#ifndef CONFIG_ZTEST + mCertHandler = &certHandler; + mCertLoader = &certLoader; +#endif auto nodeInfo = MakeUnique(&mAllocator); @@ -578,13 +587,27 @@ void SMClient::UpdatePBHandlerState() } if (start) { - auto [secureChannel, err] = mChannelManager->CreateChannel(cSecurePort); + auto [channel, err] = mChannelManager->CreateChannel(cSecurePort); if (!err.IsNone()) { LOG_ERR() << "Failed to create channel: err=" << err; return; } - if (err = PBHandler::Init("SM secure", *secureChannel); !err.IsNone()) { +#ifndef CONFIG_ZTEST + if (err = mTLSChannel.Init(*mCertHandler, *mCertLoader, *channel); !err.IsNone()) { + LOG_ERR() << "Failed to init TLS channel: err=" << err; + return; + } + + if (err = mTLSChannel.SetTLSConfig(cSMCertType); !err.IsNone()) { + LOG_ERR() << "Failed to set TLS config: err=" << err; + return; + } + + channel = &mTLSChannel; +#endif + + if (err = PBHandler::Init("SM secure", *channel); !err.IsNone()) { LOG_ERR() << "Failed to init PB handler: err=" << err; return; } diff --git a/src/smclient/smclient.hpp b/src/smclient/smclient.hpp index fa0d2490..299a35c6 100644 --- a/src/smclient/smclient.hpp +++ b/src/smclient/smclient.hpp @@ -16,6 +16,9 @@ #include "clocksync/clocksync.hpp" #include "communication/channelmanager.hpp" #include "downloader/downloader.hpp" +#ifndef CONFIG_ZTEST +#include "communication/tlschannel.hpp" +#endif #include "openhandler.hpp" @@ -45,12 +48,19 @@ class SMClient : public communication::PBHandler mConnectionSubscribers; StaticAllocator Date: Wed, 21 Aug 2024 14:23:15 +0300 Subject: [PATCH 104/198] [west] Add fatfs Signed-off-by: Mykhailo Lohvynenko --- west.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/west.yml b/west.yml index 47536b69..01cc6ae7 100644 --- a/west.yml +++ b/west.yml @@ -54,6 +54,13 @@ manifest: groups: - fs + - name: fatfs + remote: zephyrproject-rtos + revision: master + path: modules/fs/fatfs + groups: + - fs + - name: nanopb remote: zephyrproject-rtos revision: "zephyr" From 794c634369f4f4dc54bbdf7d46d35050bc15e41b Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Wed, 21 Aug 2024 14:06:22 +0300 Subject: [PATCH 105/198] [boards] Add rpi5 board Signed-off-by: Mykhailo Lohvynenko --- .github/workflows/build_test.yaml | 1 + Kconfig | 12 +++-- boards/rpi_5.conf | 33 +++++++++++++ boards/rpi_5.overlay | 77 +++++++++++++++++++++++++++++++ 4 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 boards/rpi_5.conf create mode 100644 boards/rpi_5.overlay diff --git a/.github/workflows/build_test.yaml b/.github/workflows/build_test.yaml index 94d2b710..822825b1 100644 --- a/.github/workflows/build_test.yaml +++ b/.github/workflows/build_test.yaml @@ -26,6 +26,7 @@ jobs: rcar_h3ulcb_ca57, native_posix, native_posix_64, + rpi_5, ] steps: diff --git a/Kconfig b/Kconfig index 419503e9..317e433e 100644 --- a/Kconfig +++ b/Kconfig @@ -109,17 +109,20 @@ config AOS_SOCKET_SERVER_PORT depends on NATIVE_APPLICATION default 30001 +config DOMD_ENABLE + bool "Enable Domain-D creation" + default y + config DOMD_UBOOT_PATH string "Location for Domain-D IPL binary" + depends on DOMD_ENABLE default "prebuilt/ipl.bin" config DOMD_DTB_PATH string "Location of Domain-D partial device-tree" + depends on DOMD_ENABLE default "prebuilt/ipl.dtb" -config TA_DEPLOY_DIR - string "Location of optee TA's deploy dir" - config DOMU_ENABLE bool "Enable Domain-U creation" @@ -133,4 +136,7 @@ config DOMU_DTB_PATH depends on DOMU_ENABLE default "prebuilt/domu.dtb" +config TA_DEPLOY_DIR + string "Location of optee TA's deploy dir" + source "Kconfig" diff --git a/boards/rpi_5.conf b/boards/rpi_5.conf new file mode 100644 index 00000000..b1a2559c --- /dev/null +++ b/boards/rpi_5.conf @@ -0,0 +1,33 @@ +# Copyright (c) 2024 EPAM Systems +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_IPM_CONSOLE_STACK_SIZE=4096 + +CONFIG_XEN_DOMCTL_INTERFACE_VERSION=0x16 + +CONFIG_XEN_DOM0=y +CONFIG_XEN_DOM0LESS_BOOT=y + +CONFIG_NOCACHE_MEMORY=y +CONFIG_FS_MULTI_PARTITION=y + +CONFIG_FILE_SYSTEM_LITTLEFS=n + +CONFIG_FAT_FILESYSTEM_ELM=y +CONFIG_FS_FATFS_MOUNT_MKFS=n +CONFIG_FS_FATFS_EXFAT=y +CONFIG_FS_FATFS_LBA64=y +CONFIG_FS_FATFS_NUM_FILES=16 + +CONFIG_DOMD_ENABLE=n + +CONFIG_OPTEE_STORAGE_ROOT="/1:/tee" + +CONFIG_AOS_STORAGE_DIR="/1:/aos/storage" +CONFIG_AOS_RUNTIME_DIR="/1:/tmp/aos/runtime" +CONFIG_AOS_SERVICES_DIR="/1:/aos/services" +CONFIG_AOS_NODE_CONFIG_FILE="/1:/aos/node_config.cfg" +CONFIG_AOS_DISK_MOUNT_POINT="/1:" +CONFIG_AOS_NODE_STATUS_FILE="/1:/aos/.nodestatus" +CONFIG_AOS_PKCS11_MODULE_PIN_FILE="/1:/aos/.pkcs11pin" +CONFIG_AOS_HSM_DIR="/1:/tee" diff --git a/boards/rpi_5.overlay b/boards/rpi_5.overlay new file mode 100644 index 00000000..d41b7eaa --- /dev/null +++ b/boards/rpi_5.overlay @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2024 EPAM Systems. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + /delete-node/ &sram0; + +#include + +/ { + #address-cells = <2>; + #size-cells = <1>; + + chosen { + zephyr,console = &xen_consoleio_hvc; + zephyr,shell-uart = &xen_consoleio_hvc; + }; + + psci { + compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci"; + method = "hvc"; + }; + + xen_consoleio_hvc: hvc { + compatible = "xen,hvc-consoleio"; + status = "okay"; + }; + + + /* + * This node may differs on different setups, please check + * following line in Xen boot log to set it right: + * (XEN) Grant table range: 0x00000002800000-0x00000002840000 + * Also, add extended region 1: + * (XEN) d0: extended region 1: 0x40000000->0x5fe00000 + * + * Xen passes actual values for setup in domain device tree, but Zephyr + * is not capable to parse and handle it in runtime. + */ + hypervisor: hypervisor@2000000 { + compatible = "xen,xen"; + reg = <0x00 0x2000000 0x40000>, <0x00 0x2200000 0x5400000>; + interrupts = ; + interrupt-parent = <&gic>; + status = "okay"; + }; + + /* + * This node may differs on different setups, because Xen picks + * region for Domain-0 for every specific configuration. You can + * start Xen for your platform and check following log: + * (XEN) Allocating 1:1 mappings totalling 512MB for dom0: + * (XEN) BANK[0] 0x00000060000000-0x00000080000000 (512MB) + * (XEN) Loading zImage from 0000000000080000 to 0000000060000000-0000000060038004 + * + * Xen passes actual values for setup in domain device tree, but Zephyr + * is not capable to parse and handle it in runtime. + */ + sram0: memory@10000000 { + compatible = "mmio-sram"; + reg = <0x00 0x10000000 DT_SIZE_M(128)>; + }; + + firmware { + tee { + compatible = "linaro,optee-tz"; + method = "smc"; + status = "okay"; + }; + }; + +}; + +&uart10 { + status = "disabled"; +}; From a730969e7c3565ae535475d6e3ab7d9c08828e6e Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Wed, 21 Aug 2024 16:31:49 +0300 Subject: [PATCH 106/198] [bsp] Mount FAT FS Signed-off-by: Mykhailo Lohvynenko --- CMakeLists.txt | 2 ++ src/bsp/mount.c | 35 +++++++++--------- src/bsp/mount.h | 2 ++ src/bsp/mount_fatfs.c | 77 ++++++++++++++++++++++++++++++++++++++++ src/bsp/mount_littlefs.c | 24 +++++++++++++ src/main.cpp | 4 +-- 6 files changed, 126 insertions(+), 18 deletions(-) create mode 100644 src/bsp/mount_fatfs.c create mode 100644 src/bsp/mount_littlefs.c diff --git a/CMakeLists.txt b/CMakeLists.txt index cb324a2e..192f564d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,6 +118,8 @@ target_sources_ifdef(CONFIG_DOMU_ENABLE app PRIVATE src/domains/domu/domu_cfg.c) # Include HW-specific source file target_sources_ifndef(CONFIG_NATIVE_APPLICATION app PRIVATE src/bsp/reboot.c src/bsp/mount.c) +target_sources_ifdef(CONFIG_FILE_SYSTEM_LITTLEFS app PRIVATE src/bsp/mount_littlefs.c) +target_sources_ifdef(CONFIG_FAT_FILESYSTEM_ELM app PRIVATE src/bsp/mount_fatfs.c) # ###################################################################################################################### # Versioning diff --git a/src/bsp/mount.c b/src/bsp/mount.c index 3147a0f4..efab4b53 100644 --- a/src/bsp/mount.c +++ b/src/bsp/mount.c @@ -1,24 +1,27 @@ -#include -#include +#include #include "mount.h" -FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(lfsfs); -static struct fs_mount_t mp = { - .type = FS_LITTLEFS, - .fs_data = &lfsfs, - .flags = FS_MOUNT_FLAG_USE_DISK_ACCESS, -}; - -int littlefs_mount() +int mount_fs() { - static const char* disk_mount_pt = CONFIG_AOS_DISK_MOUNT_POINT; - static const char* disk_pdrv = CONFIG_MMC_VOLUME_NAME; + int ret = 0; + +#if defined(CONFIG_FILE_SYSTEM_LITTLEFS) + ret = littlefs_mount(); + if (ret != 0) { + printk("littlefs mount failed (%d)\n", ret); + + return ret; + } - printk("Mounting littlefs..."); +#elif defined(CONFIG_FAT_FILESYSTEM_ELM) + ret = fatfs_mount(); + if (ret != 0) { + printk("fatfs mount failed (%d)\n", ret); - mp.storage_dev = (void*)disk_pdrv; - mp.mnt_point = disk_mount_pt; + return ret; + } +#endif - return fs_mount(&mp); + return ret; } diff --git a/src/bsp/mount.h b/src/bsp/mount.h index 1bd64259..8670db8f 100644 --- a/src/bsp/mount.h +++ b/src/bsp/mount.h @@ -6,6 +6,8 @@ extern "C" { #endif int littlefs_mount(); +int fatfs_mount(); +int mount_fs(); #ifdef __cplusplus } diff --git a/src/bsp/mount_fatfs.c b/src/bsp/mount_fatfs.c new file mode 100644 index 00000000..eb75e25d --- /dev/null +++ b/src/bsp/mount_fatfs.c @@ -0,0 +1,77 @@ +#include +#include + +#include +#include +#include +#include + +#include "mount.h" + +#define DISK_DRIVE_NAME CONFIG_SDMMC_VOLUME_NAME + +static FATFS fat_fs; + +/* mounting info */ +static struct fs_mount_t mp = { + .type = FS_FATFS, + .fs_data = &fat_fs, +}; + +#if defined(CONFIG_FS_MULTI_PARTITION) +PARTITION VolToPart[FF_VOLUMES] = { + [0] = {3, 1}, /* "0:" ==> 1st partition on the pd#0 */ + [1] = {3, 2}, /* "1:" ==> 2nd partition on the pd#0 */ + [2] = {0, -1}, /* "2:" ==> 3rd partition on the pd#0 */ + [3] = {0, -1}, + [4] = {0, -1}, + [5] = {0, -1}, + [6] = {0, -1}, + [7] = {0, -1}, +}; +#endif /* CONFIG_FS_MULTI_PARTITION */ + +int fatfs_mount() +{ + printk("Mounting fatfs..."); + + uint32_t block_count; + uint32_t block_size; + + int ret = disk_access_init(DISK_DRIVE_NAME); + if (ret) { + printk("[fatfs] access init failed (%d)\n", ret); + + return ret; + } + + ret = disk_access_ioctl(DISK_DRIVE_NAME, DISK_IOCTL_GET_SECTOR_COUNT, &block_count); + if (ret) { + printk("[fatfs] get sector count failed (%d)\n", ret); + + return ret; + } + + ret = disk_access_ioctl(DISK_DRIVE_NAME, DISK_IOCTL_GET_SECTOR_SIZE, &block_size); + if (ret) { + printk("[fatfs] get sector size failed (%d)\n", ret); + + return ret; + } + + mp.mnt_point = CONFIG_AOS_DISK_MOUNT_POINT; + + ret = fs_mount(&mp); + if (ret) { + printk("[fatfs] mount failed (%d)\n", ret); + + return ret; + } + + uint64_t memory_size_mb = (uint64_t)block_count * block_size; + + printk("[fatfs] Mounted %s, block count=%u, Sector size=%u, Memory Size(MB)=%u\n", CONFIG_AOS_DISK_MOUNT_POINT, + block_count, block_size, (uint32_t)(memory_size_mb >> 20)); + + return 0; +} diff --git a/src/bsp/mount_littlefs.c b/src/bsp/mount_littlefs.c new file mode 100644 index 00000000..3147a0f4 --- /dev/null +++ b/src/bsp/mount_littlefs.c @@ -0,0 +1,24 @@ +#include +#include + +#include "mount.h" + +FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(lfsfs); +static struct fs_mount_t mp = { + .type = FS_LITTLEFS, + .fs_data = &lfsfs, + .flags = FS_MOUNT_FLAG_USE_DISK_ACCESS, +}; + +int littlefs_mount() +{ + static const char* disk_mount_pt = CONFIG_AOS_DISK_MOUNT_POINT; + static const char* disk_pdrv = CONFIG_MMC_VOLUME_NAME; + + printk("Mounting littlefs..."); + + mp.storage_dev = (void*)disk_pdrv; + mp.mnt_point = disk_mount_pt; + + return fs_mount(&mp); +} diff --git a/src/main.cpp b/src/main.cpp index 37dc8e3d..2a51a65d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,8 +35,8 @@ int main(void) printk("*** Aos core size: %lu ***\n", sizeof(app::App)); #if !defined(CONFIG_NATIVE_APPLICATION) - auto ret = littlefs_mount(); - __ASSERT(ret == 0, "Error mounting little FS: %s [%d]", strerror(ret), ret); + auto ret = mount_fs(); + __ASSERT(ret == 0, "Error mounting FS: %s [%d]", strerror(ret), ret); ret = TEE_SupplicantInit(); __ASSERT(ret == 0, "Error initializing TEE supplicant: %s [%d]", strerror(ret), ret); From 8046d6b53f3071b88a3ed61184066ab878bb5301 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Wed, 21 Aug 2024 16:33:06 +0300 Subject: [PATCH 107/198] [domains] Don't create domains for RPI Signed-off-by: Mykhailo Lohvynenko --- src/domains/dom_runner.c | 4 +++- src/domains/domain_bins.S | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/domains/dom_runner.c b/src/domains/dom_runner.c index 20b9f844..820b2a8a 100644 --- a/src/domains/dom_runner.c +++ b/src/domains/dom_runner.c @@ -21,8 +21,9 @@ extern struct xen_domain_cfg domd_cfg; int create_domains(void) { - int rc; + int rc = 0; +#ifdef CONFIG_DOMD_ENABLE rc = domain_create(&domd_cfg, DOMID_DOMD); if (rc < 0) { LOG_ERR("Failed to start Domain-D, rc = %d", rc); @@ -32,6 +33,7 @@ int create_domains(void) LOG_ERR("Failed to start Domain-D with specified domid"); return rc; } +#endif #ifdef CONFIG_DOMU_ENABLE rc = domu_start(); diff --git a/src/domains/domain_bins.S b/src/domains/domain_bins.S index 0de4b46b..92633857 100644 --- a/src/domains/domain_bins.S +++ b/src/domains/domain_bins.S @@ -6,6 +6,7 @@ #include +#ifdef CONFIG_DOMD_ENABLE .section .data.img_ipl,"a" GDATA(__img_ipl_start) GDATA(__img_ipl_end) @@ -20,6 +21,7 @@ __dtb_ipl_start: .align 8 .incbin CONFIG_DOMD_DTB_PATH __dtb_ipl_end: +#endif #ifdef CONFIG_DOMU_ENABLE .section .data.img_domu,"a" From a49e3d443a9df6a80aa0570dcb6a67211c4923fd Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 26 Aug 2024 22:23:33 +0300 Subject: [PATCH 108/198] [smclient] Move sending node config status to on connect event Signed-off-by: Oleksandr Grytsov --- src/smclient/smclient.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index 654bee8b..cfd7212e 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -312,6 +312,13 @@ void SMClient::OnConnect() LOG_INF() << "On connect notification"; + auto [version, configErr] = mResourceManager->GetNodeConfigVersion(); + + if (auto err = SendNodeConfigStatus(version, configErr); !err.IsNone()) { + LOG_ERR() << "Failed to send node config status: err=" << err; + return; + } + for (auto& subscriber : mConnectionSubscribers) { subscriber->OnConnect(); } @@ -616,13 +623,6 @@ void SMClient::UpdatePBHandlerState() LOG_ERR() << "Failed to start PB handler: err=" << err; return; } - - auto [version, configErr] = mResourceManager->GetNodeConfigVersion(); - - if (err = SendNodeConfigStatus(version, configErr); !err.IsNone()) { - LOG_ERR() << "Failed to send node config status: err=" << err; - return; - } } if (stop) { From 684bad358bbf77a7b6a534e750294eb845ba7ad1 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 28 Aug 2024 20:27:52 +0300 Subject: [PATCH 109/198] [boards] Enable debug build for posix boards Signed-off-by: Oleksandr Grytsov --- boards/native_posix.conf | 6 ++++++ boards/native_posix_64.conf | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/boards/native_posix.conf b/boards/native_posix.conf index 2b7b54cd..eecf39b4 100644 --- a/boards/native_posix.conf +++ b/boards/native_posix.conf @@ -20,6 +20,12 @@ CONFIG_LOG_BACKEND_NATIVE_POSIX=y CONFIG_SHELL_LOG_BACKEND=n CONFIG_LOG_MODE_IMMEDIATE=y +# Enable debugging + +CONFIG_NO_OPTIMIZATIONS=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG=y + # Slow down to real time CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME=y diff --git a/boards/native_posix_64.conf b/boards/native_posix_64.conf index 2b7b54cd..eecf39b4 100644 --- a/boards/native_posix_64.conf +++ b/boards/native_posix_64.conf @@ -20,6 +20,12 @@ CONFIG_LOG_BACKEND_NATIVE_POSIX=y CONFIG_SHELL_LOG_BACKEND=n CONFIG_LOG_MODE_IMMEDIATE=y +# Enable debugging + +CONFIG_NO_OPTIMIZATIONS=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG=y + # Slow down to real time CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME=y From a3550738a81a6dfc6d979b8aa975e90f483bd96f Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 28 Aug 2024 20:28:19 +0300 Subject: [PATCH 110/198] [logger] Guard logs with mutex for native app Signed-off-by: Oleksandr Grytsov --- src/logger/logger.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/logger/logger.cpp b/src/logger/logger.cpp index 0af29440..4d2cc253 100644 --- a/src/logger/logger.cpp +++ b/src/logger/logger.cpp @@ -7,6 +7,10 @@ #include +#ifdef CONFIG_NATIVE_APPLICATION +#include +#endif + #include "logger.hpp" namespace aos::zephyr::logger { @@ -112,6 +116,12 @@ void Logger::Init() void Logger::LogCallback(const char* module, LogLevel level, const String& message) { +#ifdef CONFIG_NATIVE_APPLICATION + static Mutex sMutex; + + LockGuard lock(sMutex); +#endif + String logModule(module); if (logModule == cLogModuleApp) { From f28b0237cdc1656ee670aaba375e5d1c7034aa20 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 28 Aug 2024 20:28:44 +0300 Subject: [PATCH 111/198] [smclient] Fix error checking in init functions Signed-off-by: Oleksandr Grytsov --- src/smclient/openhandler.cpp | 2 +- src/smclient/smclient.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/smclient/openhandler.cpp b/src/smclient/openhandler.cpp index 650188b5..8a5d893d 100644 --- a/src/smclient/openhandler.cpp +++ b/src/smclient/openhandler.cpp @@ -26,7 +26,7 @@ Error OpenHandler::Init(communication::ChannelItf& channel, clocksync::ClockSync return AOS_ERROR_WRAP(err); } - if (auto err = Start(); err.IsNone()) { + if (auto err = Start(); !err.IsNone()) { return AOS_ERROR_WRAP(err); } diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index cfd7212e..edc428c3 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -118,11 +118,11 @@ Error SMClient::Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvide return err; } - if (err = clockSync.Subscribe(*this); err.IsNone()) { + if (err = clockSync.Subscribe(*this); !err.IsNone()) { return AOS_ERROR_WRAP(err); } - if (err = mNodeInfoProvider->SubscribeNodeStatusChanged(*this); err.IsNone()) { + if (err = mNodeInfoProvider->SubscribeNodeStatusChanged(*this); !err.IsNone()) { return AOS_ERROR_WRAP(err); } From ba9821070d3b09d7e158659e5f764f977c06c9c3 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 28 Aug 2024 20:31:08 +0300 Subject: [PATCH 112/198] [domains] Suppress unread var in create_domains Signed-off-by: Oleksandr Grytsov --- src/domains/dom_runner.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/domains/dom_runner.c b/src/domains/dom_runner.c index 820b2a8a..24b66032 100644 --- a/src/domains/dom_runner.c +++ b/src/domains/dom_runner.c @@ -21,7 +21,7 @@ extern struct xen_domain_cfg domd_cfg; int create_domains(void) { - int rc = 0; + int rc = 0; // cppcheck-suppress unreadVariable #ifdef CONFIG_DOMD_ENABLE rc = domain_create(&domd_cfg, DOMID_DOMD); From 1086f158f52cfc48a3d1d6e24b47bad669e4e780 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 30 Aug 2024 14:02:53 +0300 Subject: [PATCH 113/198] [ci] Update build conditions Signed-off-by: Oleksandr Grytsov --- .github/workflows/build_test.yaml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_test.yaml b/.github/workflows/build_test.yaml index 822825b1..582061ec 100644 --- a/.github/workflows/build_test.yaml +++ b/.github/workflows/build_test.yaml @@ -52,28 +52,33 @@ jobs: touch src/prebuilt/rootca.pem - name: Build ${{ matrix.platform }} - if: "!startsWith(matrix.platform, 'native')" + if: ${{ !startsWith(matrix.platform, 'native') && matrix.platform != 'rpi_5' }} run: | west build -b ${{ matrix.platform }} -p always -S xen_dom0 - name: Build ${{ matrix.platform }} - if: startsWith(matrix.platform, 'native') + if: ${{ matrix.platform == 'rpi_5' }} + run: | + west build -b ${{ matrix.platform }} -p always + + - name: Build ${{ matrix.platform }} + if: ${{ startsWith(matrix.platform, 'native') }} run: | west build -b ${{ matrix.platform }} -p always - name: Test ${{ matrix.platform }} - if: matrix.platform == 'native_posix' + if: ${{ matrix.platform == 'native_posix' }} run: | west twister -c -v -p ${{ matrix.platform }} -T tests - name: Test ${{ matrix.platform }} - if: matrix.platform == 'native_posix_64' + if: ${{ matrix.platform == 'native_posix_64' }} run: | west twister -c -v -p ${{ matrix.platform }} --coverage --coverage-basedir src/ --coverage-tool gcovr -T tests gcovr twister-out/${{ matrix.platform }}/ -f src/ --xml-pretty > ./coverage.xml - name: Upload codecov report - if: startsWith(matrix.platform, 'native_posix_64') + if: ${{ startsWith(matrix.platform, 'native_posix_64') }} uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} From 8dc280c1b0274480a0644e704de61c09bc65ef54 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 30 Aug 2024 14:34:31 +0300 Subject: [PATCH 114/198] [tests,smclient] Add node info provider clear before each test Signed-off-by: Oleksandr Grytsov --- tests/smclient/src/main.cpp | 1 + tests/stubs/nodeinfoproviderstub.hpp | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/tests/smclient/src/main.cpp b/tests/smclient/src/main.cpp index 01134f42..107f0544 100644 --- a/tests/smclient/src/main.cpp +++ b/tests/smclient/src/main.cpp @@ -260,6 +260,7 @@ ZTEST_SUITE( smclientFixture->mLauncher.Clear(); smclientFixture->mDownloader.Clear(); smclientFixture->mClockSync.Clear(); + smclientFixture->mNodeInfoProvider.Clear(); smclientFixture->mSMClient.reset(new smclient::SMClient); }, [](void* fixture) { static_cast(fixture)->mSMClient.reset(); }, diff --git a/tests/stubs/nodeinfoproviderstub.hpp b/tests/stubs/nodeinfoproviderstub.hpp index 42b72d4f..79793cd1 100644 --- a/tests/stubs/nodeinfoproviderstub.hpp +++ b/tests/stubs/nodeinfoproviderstub.hpp @@ -70,6 +70,14 @@ class NodeInfoProviderStub : public aos::iam::nodeinfoprovider::NodeInfoProvider void SetNodeInfo(const aos::NodeInfo& nodeInfo) { mNodeInfo = nodeInfo; } + void Clear() + { + std::lock_guard lock(mMutex); + + mNodeInfo = {}; + mObservers.clear(); + } + private: aos::NodeInfo mNodeInfo; mutable std::mutex mMutex; From cc35dbc0a7a55bbd62ce54a4784af8ba5854f547 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Fri, 30 Aug 2024 07:40:26 +0300 Subject: [PATCH 115/198] [channel] Use lockguard instead of unique Signed-off-by: Mykola Solianko --- src/communication/channel.cpp | 19 +++++++++++++++---- src/communication/channel.hpp | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/communication/channel.cpp b/src/communication/channel.cpp index 40f63888..f9bc83f4 100644 --- a/src/communication/channel.cpp +++ b/src/communication/channel.cpp @@ -18,7 +18,7 @@ Channel::Channel(CommunicationItf* communication, int port) Error Channel::Connect() { - UniqueLock lock {mMutex}; + LockGuard lock {mMutex}; LOG_DBG() << "Connect channel: port=" << mPort; @@ -26,12 +26,14 @@ Error Channel::Connect() return err; } + mClose = false; + return ErrorEnum::eNone; } Error Channel::Close() { - UniqueLock lock {mMutex}; + LockGuard lock {mMutex}; LOG_DBG() << "Close channel: port=" << mPort; @@ -56,7 +58,10 @@ int Channel::Read(void* buffer, size_t size) mCondVar.NotifyAll(); - mCondVar.Wait(lock, [this] { return !mReadReady || mClose; }); + auto err = mCondVar.Wait(lock, [this] { return !mReadReady || mClose; }); + if (!err.IsNone()) { + return err.Errno(); + } if (mClose) { return -ECONNRESET; @@ -70,6 +75,10 @@ int Channel::Read(void* buffer, size_t size) int Channel::Write(const void* buffer, size_t size) { + LockGuard lock {mMutex}; + + LOG_DBG() << "Write channel: port=" << mPort << " size=" << size; + return mCommunication->Write(mPort, buffer, size); } @@ -96,7 +105,7 @@ Error Channel::WaitRead(void** buffer, size_t* size) Error Channel::ReadDone(size_t size) { - UniqueLock lock {mMutex}; + LockGuard lock {mMutex}; LOG_DBG() << "Read done: port=" << mPort << " size=" << size; @@ -110,6 +119,8 @@ Error Channel::ReadDone(size_t size) bool Channel::IsConnected() const { + LockGuard lock {mMutex}; + return mCommunication->IsConnected(); } diff --git a/src/communication/channel.hpp b/src/communication/channel.hpp index fc6e0527..b1197c56 100644 --- a/src/communication/channel.hpp +++ b/src/communication/channel.hpp @@ -171,7 +171,7 @@ class Channel : public ChannelItf { bool mClose {}; uint8_t* mBuffer {}; size_t mBufferLen {}; - Mutex mMutex; + mutable Mutex mMutex; ConditionalVariable mCondVar; }; From 4b1d58e38bfea18b68179827809f0bbbd769c6b4 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Fri, 30 Aug 2024 07:41:44 +0300 Subject: [PATCH 116/198] [channelmanager] Close transport in after read Signed-off-by: Mykola Solianko --- src/communication/channelmanager.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/communication/channelmanager.cpp b/src/communication/channelmanager.cpp index 6b211acc..a192a949 100644 --- a/src/communication/channelmanager.cpp +++ b/src/communication/channelmanager.cpp @@ -156,10 +156,9 @@ Error ChannelManager::Run() } if (auto err = TryConnect(); !err.IsNone()) { - LOG_ERR() << "Failed to connect: err=" << err.Message(); if (err = WaitTimeout(); !err.IsNone()) { - return err; + LOG_ERR() << "Failed to wait timeout: err=" << err; } continue; @@ -171,10 +170,12 @@ Error ChannelManager::Run() LOG_ERR() << "Failed to handle read: err=" << err.Message(); } + mTransport->Close(); + CloseChannels(); if (auto err = WaitTimeout(); !err.IsNone()) { - return err; + LOG_ERR() << "Failed to wait timeout: err=" << err; } } }); @@ -184,8 +185,9 @@ Error ChannelManager::WaitTimeout() { aos::UniqueLock lock {mMutex}; - if (auto err = mCondVar.Wait(lock, cReconnectPeriod, [this] { return mClose; }); !err.IsNone()) { - return err; + if (auto err = mCondVar.Wait(lock, cReconnectPeriod, [this] { return mClose; }); + !err.IsNone() && !err.Is(ErrorEnum::eTimeout)) { + return AOS_ERROR_WRAP(err); } return ErrorEnum::eNone; From 780df88ff94ce1edba40947ff7b84ecfaf2feaf0 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Fri, 30 Aug 2024 07:42:25 +0300 Subject: [PATCH 117/198] [channelmanager] Increase channel count Signed-off-by: Mykola Solianko --- src/communication/channelmanager.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/communication/channelmanager.hpp b/src/communication/channelmanager.hpp index a2b26fcd..4ad24c99 100644 --- a/src/communication/channelmanager.hpp +++ b/src/communication/channelmanager.hpp @@ -117,7 +117,7 @@ class ChannelManager : public ChannelManagerItf, public CommunicationItf { bool IsConnected() const override; private: - static constexpr int cMaxChannels = 3; + static constexpr int cMaxChannels = 4; static constexpr auto cChanAllocatorSize = cMaxChannels * sizeof(Channel); static constexpr auto cReconnectPeriod = 2 * Time::cSeconds; static constexpr size_t cReadBufferSize = 65 * 1024; // 65KB From dd80fbbb99d55c055531b05167df917db7b03ec5 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Fri, 30 Aug 2024 07:47:13 +0300 Subject: [PATCH 118/198] [pbhandler] Add reconnect timeout Signed-off-by: Mykola Solianko --- src/communication/pbhandler.cpp | 8 +++++++- src/communication/pbhandler.hpp | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/communication/pbhandler.cpp b/src/communication/pbhandler.cpp index 69aa1e27..97915c45 100644 --- a/src/communication/pbhandler.cpp +++ b/src/communication/pbhandler.cpp @@ -5,8 +5,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "pbhandler.hpp" +#include + #include "log.hpp" +#include "pbhandler.hpp" namespace aos::zephyr::communication { @@ -124,6 +126,8 @@ void PBHandler::Run() if (auto err = mChannel->Connect(); !err.IsNone()) { LOG_ERR() << "Failed to connect: name=" << mName << ", err=" << err; + sleep(cReconnectPeriod); + continue; } @@ -167,6 +171,8 @@ void PBHandler::Run() } OnDisconnect(); + + sleep(cReconnectPeriod); } } diff --git a/src/communication/pbhandler.hpp b/src/communication/pbhandler.hpp index 208c7217..95f3641a 100644 --- a/src/communication/pbhandler.hpp +++ b/src/communication/pbhandler.hpp @@ -97,6 +97,8 @@ class PBHandler { virtual Error ReceiveMessage(const Array& data) = 0; private: + static constexpr auto cReconnectPeriod = 2; + void Run(); StaticString<64> mName; From bd96247fa6314336a92240d1b5bc361be36e9757 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Fri, 30 Aug 2024 07:48:04 +0300 Subject: [PATCH 119/198] [pbhandler] Move mutex after CV Signed-off-by: Mykola Solianko --- src/communication/pbhandler.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/communication/pbhandler.hpp b/src/communication/pbhandler.hpp index 95f3641a..f4090a31 100644 --- a/src/communication/pbhandler.hpp +++ b/src/communication/pbhandler.hpp @@ -103,8 +103,8 @@ class PBHandler { StaticString<64> mName; ChannelItf* mChannel; - mutable Mutex mMutex; ConditionalVariable mCondVar; + mutable Mutex mMutex; Thread<> mThread; bool mStarted = false; aos::StaticBuffer mSendBuffer; From 9f372a6ab6d298ed1155ab09e8aa80e8644286f8 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Fri, 30 Aug 2024 07:49:38 +0300 Subject: [PATCH 120/198] [socket] Add mutex Signed-off-by: Mykola Solianko --- src/communication/socket.cpp | 26 ++++++++++++++++++++------ src/communication/socket.hpp | 4 +++- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/communication/socket.cpp b/src/communication/socket.cpp index a8e78354..821ac0f8 100644 --- a/src/communication/socket.cpp +++ b/src/communication/socket.cpp @@ -31,6 +31,8 @@ Error Socket::Init(const String& serverAddress, int serverPort) Error Socket::Open() { + LockGuard lock {mMutex}; + LOG_INF() << "Connecting socket to: address=" << mServerAddress << ", port=" << mServerPort; mSocketFd = socket(AF_INET, SOCK_STREAM, 0); @@ -49,8 +51,11 @@ Error Socket::Open() } if (connect(mSocketFd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { + LOG_ERR() << "Failed to connect to server: address=" << mServerAddress.CStr() << ", port=" << mServerPort; + close(mSocketFd); mSocketFd = -1; + return Error(ErrorEnum::eRuntime, "failed to connect to server"); } @@ -63,6 +68,8 @@ Error Socket::Open() Error Socket::Close() { + LockGuard lock {mMutex}; + if (mSocketFd != -1) { close(mSocketFd); mSocketFd = -1; @@ -73,6 +80,13 @@ Error Socket::Close() return ErrorEnum::eNone; } +bool Socket::IsOpened() const +{ + LockGuard lock {mMutex}; + + return mOpened; +} + int Socket::Read(void* data, size_t size) { LOG_DBG() << "Read from server: size=" << size; @@ -98,9 +112,6 @@ int Socket::ReadFromSocket(int fd, void* data, size_t size) while (readBytes < static_cast(size)) { ssize_t len = recv(fd, static_cast(data) + readBytes, size - readBytes, 0); if (len < 0) { - if (errno == EINTR) - continue; - return -errno; } @@ -124,10 +135,13 @@ int Socket::WriteToSocket(int fd, const void* data, size_t size) while (writtenBytes < static_cast(size)) { ssize_t len = send(fd, static_cast(data) + writtenBytes, size - writtenBytes, 0); if (len < 0) { - if (errno == EINTR) - continue; + return -errno; + } - return -1; + if (len == 0) { + LOG_DBG() << "Connection closed by peer"; + + return -ECONNRESET; } writtenBytes += len; diff --git a/src/communication/socket.hpp b/src/communication/socket.hpp index af4ff18e..ab9ddce9 100644 --- a/src/communication/socket.hpp +++ b/src/communication/socket.hpp @@ -9,6 +9,7 @@ #define SOCKET_HPP_ #include +#include #include "transport.hpp" @@ -40,7 +41,7 @@ class Socket : public TransportItf { * * @return bool. */ - bool IsOpened() const override { return mOpened; }; + bool IsOpened() const override; /** * Closes the pipes. @@ -75,6 +76,7 @@ class Socket : public TransportItf { int mServerPort {-1}; int mSocketFd {-1}; bool mOpened {}; + mutable Mutex mMutex; }; } // namespace aos::zephyr::communication From ca3d1ddd507a0594f655c2d6bcf234fc41c0aa7c Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Fri, 30 Aug 2024 07:51:23 +0300 Subject: [PATCH 121/198] [iamclient] Remove condition on send info Signed-off-by: Mykola Solianko --- src/iamclient/iamclient.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index f0f13501..5a47d402 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -95,20 +95,15 @@ Error IAMClient::OnNodeStatusChanged(const String& nodeID, const NodeStatus& sta return ErrorEnum::eNone; } - auto sendNodeInfo = true; - if (mNodeInfo.mStatus == NodeStatusEnum::eUnprovisioned || status == NodeStatusEnum::eUnprovisioned) { - sendNodeInfo = false; mSwitchChannel = true; mCondVar.NotifyOne(); } mNodeInfo.mStatus = status; - if (sendNodeInfo) { - if (auto err = SendNodeInfo(); !err.IsNone()) { - return err; - } + if (auto err = SendNodeInfo(); !err.IsNone()) { + return err; } return ErrorEnum::eNone; From 45820fa586198a7af5a4a58433d410f5daf192eb Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Mon, 2 Sep 2024 14:00:13 +0300 Subject: [PATCH 122/198] [Kconfig] Add node id file Signed-off-by: Mykhailo Lohvynenko --- Kconfig | 4 ++++ boards/native_posix.conf | 1 + boards/native_posix_64.conf | 1 + boards/rpi_5.conf | 1 + 4 files changed, 7 insertions(+) diff --git a/Kconfig b/Kconfig index 317e433e..f1a5ee74 100644 --- a/Kconfig +++ b/Kconfig @@ -47,6 +47,10 @@ config AOS_NODE_STATUS_FILE string "Path to provisioning state file." default "/lfs/aos/.nodestatus" +config AOS_NODE_ID_FILE + string "Path to node id file." + default "/lfs/aos/node-id" + config AOS_PKCS11_MODULE_PIN_FILE string "Path to PKCS11 module PIN file." default "/lfs/aos/.pkcs11pin" diff --git a/boards/native_posix.conf b/boards/native_posix.conf index eecf39b4..1571db09 100644 --- a/boards/native_posix.conf +++ b/boards/native_posix.conf @@ -87,6 +87,7 @@ CONFIG_AOS_SERVICES_DIR=".aos/services" CONFIG_AOS_NODE_CONFIG_FILE=".aos/node_config.cfg" CONFIG_AOS_HSM_DIR=".aos/hsm" CONFIG_AOS_NODE_STATUS_FILE=".aos/.nodestatus" +CONFIG_AOS_NODE_ID_FILE=".aos/node-id" CONFIG_AOS_PKCS11_MODULE_PIN_FILE=".aos/.pkcs11pin" # Disable OP-TEE driver and client libraries diff --git a/boards/native_posix_64.conf b/boards/native_posix_64.conf index eecf39b4..1571db09 100644 --- a/boards/native_posix_64.conf +++ b/boards/native_posix_64.conf @@ -87,6 +87,7 @@ CONFIG_AOS_SERVICES_DIR=".aos/services" CONFIG_AOS_NODE_CONFIG_FILE=".aos/node_config.cfg" CONFIG_AOS_HSM_DIR=".aos/hsm" CONFIG_AOS_NODE_STATUS_FILE=".aos/.nodestatus" +CONFIG_AOS_NODE_ID_FILE=".aos/node-id" CONFIG_AOS_PKCS11_MODULE_PIN_FILE=".aos/.pkcs11pin" # Disable OP-TEE driver and client libraries diff --git a/boards/rpi_5.conf b/boards/rpi_5.conf index b1a2559c..47670a22 100644 --- a/boards/rpi_5.conf +++ b/boards/rpi_5.conf @@ -29,5 +29,6 @@ CONFIG_AOS_SERVICES_DIR="/1:/aos/services" CONFIG_AOS_NODE_CONFIG_FILE="/1:/aos/node_config.cfg" CONFIG_AOS_DISK_MOUNT_POINT="/1:" CONFIG_AOS_NODE_STATUS_FILE="/1:/aos/.nodestatus" +CONFIG_AOS_NODE_ID_FILE="/1:/aos/node-id" CONFIG_AOS_PKCS11_MODULE_PIN_FILE="/1:/aos/.pkcs11pin" CONFIG_AOS_HSM_DIR="/1:/tee" From c55e61764b41537d9aaf7fd3aeef9b1101113aa9 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Mon, 2 Sep 2024 14:01:13 +0300 Subject: [PATCH 123/198] [nodeinfoprovider] Handle file node id Signed-off-by: Mykhailo Lohvynenko --- src/nodeinfoprovider/nodeinfoprovider.cpp | 31 +++++++++++++---------- src/nodeinfoprovider/nodeinfoprovider.hpp | 4 +-- tests/nodeinfoprovider/CMakeLists.txt | 1 + tests/nodeinfoprovider/Kconfig | 4 +++ tests/nodeinfoprovider/src/main.cpp | 31 +++++++++++++++++++++++ 5 files changed, 54 insertions(+), 17 deletions(-) diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp index efedd2e2..b4791dea 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "utils/utils.hpp" @@ -132,27 +133,29 @@ Error NodeInfoProvider::UnsubscribeNodeStatusChanged(iam::nodeinfoprovider::Node Error NodeInfoProvider::InitNodeID() { -#ifndef CONFIG_NATIVE_APPLICATION - char buffer[cNodeIDLen + 1] {}; - - auto ret = hwinfo_get_device_id(reinterpret_cast(buffer), sizeof(buffer) - 1); + if (auto err = FS::ReadFileToString(cNodeIDFile, mNodeInfo.mNodeID); !err.IsNone()) { + LOG_WRN() << "Failed to read node id: path=" << cNodeIDFile << ", err=" << err; + } else if (mNodeInfo.mNodeID.IsEmpty()) { + LOG_WRN() << "Node id is empty: path=" << cNodeIDFile; + } else { + mNodeInfo.mNodeID.Trim("\r\n"); - if (ret == -ENOSYS) { - LOG_WRN() << "hwinfo_get_device_id is not supported"; + LOG_DBG() << "Read node id: id=" << mNodeInfo.mNodeID << ", path=" << cNodeIDFile; - return ErrorEnum::eNotSupported; - } else if (ret < 0) { - return AOS_ERROR_WRAP(ret); + return ErrorEnum::eNone; } - mNodeInfo.mNodeID = utils::StringFromCStr(buffer); -#else - if (auto err = FS::ReadFileToString(cNodeIDFile, mNodeInfo.mNodeID); !err.IsNone()) { + LOG_DBG() << "Generate node id"; + + auto uuidStr = uuid::UUIDToString(uuid::CreateUUID()); + + if (auto err = FS::WriteStringToFile(cNodeIDFile, uuidStr, S_IRUSR | S_IWUSR); !err.IsNone()) { return AOS_ERROR_WRAP(err); } - mNodeInfo.mNodeID.Trim("\r\n"); -#endif + mNodeInfo.mNodeID = uuidStr; + + LOG_DBG() << "Store node id: id=" << uuidStr << ", path=" << cNodeIDFile; return ErrorEnum::eNone; } diff --git a/src/nodeinfoprovider/nodeinfoprovider.hpp b/src/nodeinfoprovider/nodeinfoprovider.hpp index 70be458e..cc0ac7be 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.hpp +++ b/src/nodeinfoprovider/nodeinfoprovider.hpp @@ -69,9 +69,7 @@ class NodeInfoProvider : public iam::nodeinfoprovider::NodeInfoProviderItf { static constexpr auto cNodeRunner = "xrun"; static constexpr auto cAosComponents = "iam,sm"; static constexpr auto cMaxNodeStatusSubscribers = 4; -#ifdef CONFIG_NATIVE_APPLICATION - static constexpr auto cNodeIDFile = "/etc/machine-id"; -#endif + static constexpr auto cNodeIDFile = CONFIG_AOS_NODE_ID_FILE; Error InitNodeID(); Error InitAttributes(); diff --git a/tests/nodeinfoprovider/CMakeLists.txt b/tests/nodeinfoprovider/CMakeLists.txt index acba899d..ccdd688b 100644 --- a/tests/nodeinfoprovider/CMakeLists.txt +++ b/tests/nodeinfoprovider/CMakeLists.txt @@ -35,6 +35,7 @@ zephyr_include_directories_ifdef(CONFIG_NATIVE_APPLICATION ${APPLICATION_SOURCE_ target_sources( app PRIVATE ../../src/nodeinfoprovider/nodeinfoprovider.cpp ../../src/utils/utils.cpp ../utils/log.cpp src/main.cpp + ${aoscore_source_dir}/src/common/tools/uuid.cpp ) target_sources_ifdef(CONFIG_NATIVE_APPLICATION app PRIVATE ${APPLICATION_SOURCE_DIR}/../../mocks/xstat/xstat.cpp) diff --git a/tests/nodeinfoprovider/Kconfig b/tests/nodeinfoprovider/Kconfig index 14b83304..f7d57296 100644 --- a/tests/nodeinfoprovider/Kconfig +++ b/tests/nodeinfoprovider/Kconfig @@ -25,4 +25,8 @@ config AOS_NODE_STATUS_FILE string "Path to provisioning state file." default ".aos/.nodestatus" +config AOS_NODE_ID_FILE + string "Path to node id file." + default ".aos/.nodeid" + source "Kconfig" diff --git a/tests/nodeinfoprovider/src/main.cpp b/tests/nodeinfoprovider/src/main.cpp index 2b51b019..c6e3a5c0 100644 --- a/tests/nodeinfoprovider/src/main.cpp +++ b/tests/nodeinfoprovider/src/main.cpp @@ -26,7 +26,9 @@ using namespace aos::zephyr; **********************************************************************************************************************/ static constexpr auto cNodeStatusFile = CONFIG_AOS_NODE_STATUS_FILE; +static constexpr auto cNodeIDFile = CONFIG_AOS_NODE_ID_FILE; static constexpr auto cUnprovisioned = "unprovisioned"; +static constexpr auto cTestNodeID = "test-id"; /*********************************************************************************************************************** * Static @@ -52,6 +54,9 @@ void before_test(void* data) { auto err = aos::FS::WriteStringToFile(cNodeStatusFile, cUnprovisioned, S_IRUSR | S_IWUSR); zassert_true(err.IsNone(), "Failed to create provisioning state file: %s", utils::ErrorToCStr(err)); + + err = aos::FS::WriteStringToFile(cNodeIDFile, cTestNodeID, S_IRUSR | S_IWUSR); + zassert_true(err.IsNone(), "Failed to create node id file: %s", utils::ErrorToCStr(err)); } /*********************************************************************************************************************** @@ -103,6 +108,8 @@ ZTEST(nodeinfoprovider, test_node_info) zassert_true(err.IsNone(), "Failed to get node info: %s", utils::ErrorToCStr(err)); + zassert_equal(nodeInfo.mNodeID, cTestNodeID, "Node ID mismatch"); + zassert_equal(nodeInfo.mStatus.GetValue(), aos::NodeStatusEnum::eUnprovisioned, "Node status mismatch"); zassert_equal(nodeInfo.mMaxDMIPS, CONFIG_AOS_MAX_CPU_DMIPS, "Max DMIPS mismatch"); @@ -132,6 +139,30 @@ ZTEST(nodeinfoprovider, test_node_info) zassert_equal(nodeInfo.mAttrs[1].mValue, "xrun", "Attribute value mismatch"); } +ZTEST(nodeinfoprovider, test_node_id_is_autogenerated) +{ + auto err = aos::FS::Remove(cNodeIDFile); + zassert_true(err.IsNone(), "Failed to remove node id file: %s", utils::ErrorToCStr(err)); + + aos::zephyr::nodeinfoprovider::NodeInfoProvider provider; + + err = provider.Init(); + zassert_true(err.IsNone(), "Failed to init node info provider: %s", utils::ErrorToCStr(err)); + + aos::StaticString nodeID; + + err = aos::FS::ReadFileToString(cNodeIDFile, nodeID); + zassert_true(err.IsNone(), "Failed to read node id from file: %s", utils::ErrorToCStr(err)); + + aos::NodeInfo nodeInfo; + + err = provider.GetNodeInfo(nodeInfo); + zassert_true(err.IsNone(), "Failed to get node info: %s", utils::ErrorToCStr(err)); + + zassert_false(nodeInfo.mNodeID.IsEmpty(), "Node ID is empty"); + zassert_equal(nodeInfo.mNodeID, nodeID, "Node ID mismatch"); +} + ZTEST(nodeinfoprovider, test_set_get_node_info) { aos::zephyr::nodeinfoprovider::NodeInfoProvider provider; From bf2f021521b6973d909dc978c7ea2d31e386a01d Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Mon, 2 Sep 2024 16:59:05 +0300 Subject: [PATCH 124/198] [iamclient] Fix finish provision and deprovision UT(s) Signed-off-by: Mykhailo Lohvynenko --- tests/iamclient/src/main.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/iamclient/src/main.cpp b/tests/iamclient/src/main.cpp index 605ecda5..f8f17a45 100644 --- a/tests/iamclient/src/main.cpp +++ b/tests/iamclient/src/main.cpp @@ -176,6 +176,10 @@ ZTEST_F(iamclient, test_FinishProvisioning) err = SendIAMIncomingMessage(channel, incomingMessage); zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + // node info is sent prior to finish provisioning response + nodeInfo.mStatus = aos::NodeStatusEnum::eProvisioned; + ReceiveNodeInfo(channel, nodeInfo); + // Receive finish provisioning response iamanager_v5_IAMOutgoingMessages outgoingMessage; @@ -228,6 +232,10 @@ ZTEST_F(iamclient, test_Deprovision) err = SendIAMIncomingMessage(channel, incomingMessage); zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); + // node info is sent prior to deprovision response + nodeInfo.mStatus = aos::NodeStatusEnum::eUnprovisioned; + ReceiveNodeInfo(channel, nodeInfo); + // Receive deprovision response iamanager_v5_IAMOutgoingMessages outgoingMessage; From 4b4e3b2780b3d5f273ee739533d5d2e8fd7224f6 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 1 Sep 2024 16:37:57 +0300 Subject: [PATCH 125/198] [communication] Remove aos:: namespace from TLS channel Signed-off-by: Oleksandr Grytsov --- src/communication/tlschannel.cpp | 30 +++++++++---------- src/communication/tlschannel.hpp | 50 ++++++++++++++++---------------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/communication/tlschannel.cpp b/src/communication/tlschannel.cpp index 232adb00..c60349b0 100644 --- a/src/communication/tlschannel.cpp +++ b/src/communication/tlschannel.cpp @@ -32,20 +32,20 @@ TLSChannel::~TLSChannel() Cleanup(); } -aos::Error TLSChannel::Init(aos::iam::certhandler::CertHandlerItf& certHandler, - aos::cryptoutils::CertLoaderItf& certLoader, ChannelItf& channel) +Error TLSChannel::Init( + iam::certhandler::CertHandlerItf& certHandler, cryptoutils::CertLoaderItf& certLoader, ChannelItf& channel) { mChannel = &channel; mCertHandler = &certHandler; mCertLoader = &certLoader; - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error TLSChannel::SetTLSConfig(const aos::String& certType) +Error TLSChannel::SetTLSConfig(const String& certType) { if (certType == mCertType) { - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } mCertType = certType; @@ -58,15 +58,15 @@ aos::Error TLSChannel::SetTLSConfig(const aos::String& certType) return err; } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } Cleanup(); - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } -aos::Error TLSChannel::Connect() +Error TLSChannel::Connect() { if (mCertType.IsEmpty()) { return mChannel->Connect(); @@ -80,7 +80,7 @@ aos::Error TLSChannel::Connect() return mbedtls_ssl_get_verify_result(&mSSL); } -aos::Error TLSChannel::Close() +Error TLSChannel::Close() { return mChannel->Close(); } @@ -112,7 +112,7 @@ int TLSChannel::Write(const void* data, size_t size) * Private **********************************************************************************************************************/ -aos::RetWithError TLSChannel::SetupOpaqueKey(mbedtls_pk_context& pk) +RetWithError TLSChannel::SetupOpaqueKey(mbedtls_pk_context& pk) { auto statusAddKey = AosPsaAddKey(*mPrivKey); if (!statusAddKey.mError.IsNone()) { @@ -126,10 +126,10 @@ aos::RetWithError TLSChannel::SetupOpaqueKey(mbedtls_pk_co return {statusAddKey.mValue.mKeyID, AOS_ERROR_WRAP(ret)}; } - return {statusAddKey.mValue.mKeyID, aos::ErrorEnum::eNone}; + return {statusAddKey.mValue.mKeyID, ErrorEnum::eNone}; } -aos::Error TLSChannel::TLSConnect() +Error TLSChannel::TLSConnect() { mbedtls_ssl_session_reset(&mSSL); @@ -158,7 +158,7 @@ void TLSChannel::Cleanup() } } -aos::Error TLSChannel::SetupSSLConfig(const aos::String& certType) +Error TLSChannel::SetupSSLConfig(const String& certType) { mbedtls_x509_crt_init(&mCertChain); mbedtls_x509_crt_init(&mCACert); @@ -168,9 +168,9 @@ aos::Error TLSChannel::SetupSSLConfig(const aos::String& certType) mbedtls_ssl_config_init(&mConf); mbedtls_ssl_init(&mSSL); - aos::iam::certhandler::CertInfo certInfo; + iam::certhandler::CertInfo certInfo; - auto err = mCertHandler->GetCertificate(certType, aos::Array(), aos::Array(), certInfo); + auto err = mCertHandler->GetCertificate(certType, Array(), Array(), certInfo); if (!err.IsNone()) { return AOS_ERROR_WRAP(err); } diff --git a/src/communication/tlschannel.hpp b/src/communication/tlschannel.hpp index 1b4d25ff..018435de 100644 --- a/src/communication/tlschannel.hpp +++ b/src/communication/tlschannel.hpp @@ -35,28 +35,28 @@ class TLSChannel : public ChannelItf { * @param certLoader certificate loader. * @param channel virtual channel. */ - aos::Error Init(aos::iam::certhandler::CertHandlerItf& certHandler, aos::cryptoutils::CertLoaderItf& certLoader, - ChannelItf& channel); + Error Init( + iam::certhandler::CertHandlerItf& certHandler, cryptoutils::CertLoaderItf& certLoader, ChannelItf& channel); /** * Set TLS config. * * @param certType certificate type. - * @return aos::Error + * @return Error */ - aos::Error SetTLSConfig(const aos::String& certType); + Error SetTLSConfig(const String& certType); /** * Connects to communication channel. * - * @return aos::Error. + * @return Error. */ - aos::Error Connect() override; + Error Connect() override; /** * Closes current connection. */ - aos::Error Close() override; + Error Close() override; /** * Returns if channel is connected. @@ -89,24 +89,24 @@ class TLSChannel : public ChannelItf { static int TLSWrite(void* ctx, const unsigned char* buf, size_t len); static int TLSRead(void* ctx, unsigned char* buf, size_t len); - aos::Error TLSConnect(); - aos::RetWithError SetupOpaqueKey(mbedtls_pk_context& pk); - void Cleanup(); - aos::Error SetupSSLConfig(const aos::String& certType); - - mbedtls_entropy_context mEntropy {}; - mbedtls_ctr_drbg_context mCtrDrbg {}; - mbedtls_x509_crt mCertChain {}; - mbedtls_x509_crt mCACert {}; - mbedtls_pk_context mPrivKeyCtx {}; - mbedtls_ssl_config mConf {}; - mbedtls_ssl_context mSSL {}; - mbedtls_svc_key_id_t mKeyID {}; - aos::SharedPtr mPrivKey {}; - ChannelItf* mChannel {}; - aos::iam::certhandler::CertHandlerItf* mCertHandler {}; - aos::cryptoutils::CertLoaderItf* mCertLoader {}; - aos::StaticString mCertType; + Error TLSConnect(); + RetWithError SetupOpaqueKey(mbedtls_pk_context& pk); + void Cleanup(); + Error SetupSSLConfig(const String& certType); + + mbedtls_entropy_context mEntropy {}; + mbedtls_ctr_drbg_context mCtrDrbg {}; + mbedtls_x509_crt mCertChain {}; + mbedtls_x509_crt mCACert {}; + mbedtls_pk_context mPrivKeyCtx {}; + mbedtls_ssl_config mConf {}; + mbedtls_ssl_context mSSL {}; + mbedtls_svc_key_id_t mKeyID {}; + SharedPtr mPrivKey {}; + ChannelItf* mChannel {}; + iam::certhandler::CertHandlerItf* mCertHandler {}; + cryptoutils::CertLoaderItf* mCertLoader {}; + StaticString mCertType; }; } // namespace aos::zephyr::communication From 2d8fd9726b7263eada8627e945a948898fcacbb1 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Sun, 1 Sep 2024 16:43:41 +0300 Subject: [PATCH 126/198] [communication] Add debug logs to TLS channel Signed-off-by: Oleksandr Grytsov --- src/communication/tlschannel.cpp | 14 ++++++++++++-- src/communication/tlschannel.hpp | 9 ++++++--- src/iamclient/iamclient.cpp | 2 +- src/smclient/smclient.cpp | 2 +- tests/communication/src/tlschannel.cpp | 2 +- 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/communication/tlschannel.cpp b/src/communication/tlschannel.cpp index c60349b0..13ccf4b1 100644 --- a/src/communication/tlschannel.cpp +++ b/src/communication/tlschannel.cpp @@ -16,6 +16,7 @@ extern "C" { #include #include +#include "log.hpp" #include "tlschannel.hpp" extern unsigned char __aos_root_ca_start[]; @@ -32,18 +33,23 @@ TLSChannel::~TLSChannel() Cleanup(); } -Error TLSChannel::Init( - iam::certhandler::CertHandlerItf& certHandler, cryptoutils::CertLoaderItf& certLoader, ChannelItf& channel) +Error TLSChannel::Init(const String& name, iam::certhandler::CertHandlerItf& certHandler, + cryptoutils::CertLoaderItf& certLoader, ChannelItf& channel) { + mName = name; mChannel = &channel; mCertHandler = &certHandler; mCertLoader = &certLoader; + LOG_DBG() << "Init TLS channel: name=" << mName; + return ErrorEnum::eNone; } Error TLSChannel::SetTLSConfig(const String& certType) { + LOG_DBG() << "Set TLS config: name=" << mName << ", certType=" << certType; + if (certType == mCertType) { return ErrorEnum::eNone; } @@ -68,6 +74,8 @@ Error TLSChannel::SetTLSConfig(const String& certType) Error TLSChannel::Connect() { + LOG_DBG() << "Connect TLS channel: name=" << mName; + if (mCertType.IsEmpty()) { return mChannel->Connect(); } @@ -82,6 +90,8 @@ Error TLSChannel::Connect() Error TLSChannel::Close() { + LOG_DBG() << "Close TLS channel: name=" << mName; + return mChannel->Close(); } diff --git a/src/communication/tlschannel.hpp b/src/communication/tlschannel.hpp index 018435de..f1d9ebab 100644 --- a/src/communication/tlschannel.hpp +++ b/src/communication/tlschannel.hpp @@ -31,12 +31,13 @@ class TLSChannel : public ChannelItf { /** * Initializes secure channel. * + * @param name TLS channel name. * @param certHandler certificate handler. * @param certLoader certificate loader. * @param channel virtual channel. */ - Error Init( - iam::certhandler::CertHandlerItf& certHandler, cryptoutils::CertLoaderItf& certLoader, ChannelItf& channel); + Error Init(const String& name, iam::certhandler::CertHandlerItf& certHandler, + cryptoutils::CertLoaderItf& certLoader, ChannelItf& channel); /** * Set TLS config. @@ -84,7 +85,8 @@ class TLSChannel : public ChannelItf { int Write(const void* data, size_t size) override; private: - static constexpr auto cPers = "tls_vchannel_client"; + static constexpr auto cPers = "tls_vchannel_client"; + static constexpr auto cNameLen = 64; static int TLSWrite(void* ctx, const unsigned char* buf, size_t len); static int TLSRead(void* ctx, unsigned char* buf, size_t len); @@ -94,6 +96,7 @@ class TLSChannel : public ChannelItf { void Cleanup(); Error SetupSSLConfig(const String& certType); + StaticString mName; mbedtls_entropy_context mEntropy {}; mbedtls_ctr_drbg_context mCtrDrbg {}; mbedtls_x509_crt mCertChain {}; diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index 5a47d402..fbacc86c 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -200,7 +200,7 @@ Error IAMClient::SetupChannel() mCurrentPort = cSecurePort; #ifndef CONFIG_ZTEST - if (err = mTLSChannel.Init(*mCertHandler, *mCertLoader, *channel); !err.IsNone()) { + if (err = mTLSChannel.Init("iam", *mCertHandler, *mCertLoader, *channel); !err.IsNone()) { return AOS_ERROR_WRAP(err); } diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index edc428c3..693d28bc 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -601,7 +601,7 @@ void SMClient::UpdatePBHandlerState() } #ifndef CONFIG_ZTEST - if (err = mTLSChannel.Init(*mCertHandler, *mCertLoader, *channel); !err.IsNone()) { + if (err = mTLSChannel.Init("sm", *mCertHandler, *mCertLoader, *channel); !err.IsNone()) { LOG_ERR() << "Failed to init TLS channel: err=" << err; return; } diff --git a/tests/communication/src/tlschannel.cpp b/tests/communication/src/tlschannel.cpp index 20380035..918bff22 100644 --- a/tests/communication/src/tlschannel.cpp +++ b/tests/communication/src/tlschannel.cpp @@ -243,7 +243,7 @@ ZTEST_F(tlschannel, test_TLSChannelConnect) communication::TLSChannel channel; - auto err = channel.Init(certHandler, certLoader, vChannel); + auto err = channel.Init("test", certHandler, certLoader, vChannel); zassert_equal(err, aos::ErrorEnum::eNone, "test failed"); err = channel.SetTLSConfig("client"); From 683bf38db99b3a7cf11fb61b5e18fabbd16478e3 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 2 Sep 2024 11:39:28 +0300 Subject: [PATCH 127/198] Revert "[pbhandler] Move mutex after CV" This reverts commit 5b99c24df66c3c5f340ec2320860cecf9f902737. It fixes nothing. Remove as unneeded. --- src/communication/pbhandler.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/communication/pbhandler.hpp b/src/communication/pbhandler.hpp index f4090a31..95f3641a 100644 --- a/src/communication/pbhandler.hpp +++ b/src/communication/pbhandler.hpp @@ -103,8 +103,8 @@ class PBHandler { StaticString<64> mName; ChannelItf* mChannel; - ConditionalVariable mCondVar; mutable Mutex mMutex; + ConditionalVariable mCondVar; Thread<> mThread; bool mStarted = false; aos::StaticBuffer mSendBuffer; From 0a860c6eda65ab91888349069f53c82dd807f83d Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 2 Sep 2024 11:40:16 +0300 Subject: [PATCH 128/198] Revert "[pbhandler] Add reconnect timeout" This reverts commit d20c9df29f71278736ad6b0f4f55d242b6d7ce48. Reconnect timeout should be handled in one place: channel manager. --- src/communication/pbhandler.cpp | 8 +------- src/communication/pbhandler.hpp | 2 -- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/communication/pbhandler.cpp b/src/communication/pbhandler.cpp index 97915c45..69aa1e27 100644 --- a/src/communication/pbhandler.cpp +++ b/src/communication/pbhandler.cpp @@ -5,10 +5,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - -#include "log.hpp" #include "pbhandler.hpp" +#include "log.hpp" namespace aos::zephyr::communication { @@ -126,8 +124,6 @@ void PBHandler::Run() if (auto err = mChannel->Connect(); !err.IsNone()) { LOG_ERR() << "Failed to connect: name=" << mName << ", err=" << err; - sleep(cReconnectPeriod); - continue; } @@ -171,8 +167,6 @@ void PBHandler::Run() } OnDisconnect(); - - sleep(cReconnectPeriod); } } diff --git a/src/communication/pbhandler.hpp b/src/communication/pbhandler.hpp index 95f3641a..208c7217 100644 --- a/src/communication/pbhandler.hpp +++ b/src/communication/pbhandler.hpp @@ -97,8 +97,6 @@ class PBHandler { virtual Error ReceiveMessage(const Array& data) = 0; private: - static constexpr auto cReconnectPeriod = 2; - void Run(); StaticString<64> mName; From 5d78d33fe76cb03b606b1a0a31225e9f8e36ca9d Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 2 Sep 2024 12:07:36 +0300 Subject: [PATCH 129/198] [communication] Remove duplicated logs and fix error output Signed-off-by: Oleksandr Grytsov --- src/communication/channelmanager.cpp | 9 +++++---- src/communication/socket.cpp | 10 ---------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/communication/channelmanager.cpp b/src/communication/channelmanager.cpp index a192a949..7c8038fc 100644 --- a/src/communication/channelmanager.cpp +++ b/src/communication/channelmanager.cpp @@ -101,8 +101,6 @@ Error ChannelManager::Close() int ChannelManager::Write(uint32_t port, const void* data, size_t size) { - LOG_DBG() << "Write channel: port=" << port << " size=" << size; - auto header = PrepareHeader(port, aos::Array(reinterpret_cast(data), size)); if (!header.mError.IsNone()) { LOG_ERR() << "Failed to prepare header: err=" << header.mError.Message(); @@ -150,12 +148,15 @@ Error ChannelManager::Run() while (true) { { aos::UniqueLock lock {mMutex}; + if (mClose) { return aos::Error(aos::ErrorEnum::eNone); } } if (auto err = TryConnect(); !err.IsNone()) { + LOG_ERR() << "Transport connect error: err=" << err; + LOG_DBG() << "Reconnect in " << cReconnectPeriod / 1000000 << " ms"; if (err = WaitTimeout(); !err.IsNone()) { LOG_ERR() << "Failed to wait timeout: err=" << err; @@ -167,7 +168,7 @@ Error ChannelManager::Run() mCondVar.NotifyAll(); if (auto err = HandleRead(); !err.IsNone()) { - LOG_ERR() << "Failed to handle read: err=" << err.Message(); + LOG_ERR() << "Failed to handle read: err=" << err; } mTransport->Close(); @@ -212,7 +213,7 @@ Error ChannelManager::HandleRead() } if (auto err = ProcessData(header); !err.IsNone()) { - LOG_ERR() << "Failed to process data: err=" << err.Message(); + LOG_ERR() << "Failed to process data: err=" << err; } } } diff --git a/src/communication/socket.cpp b/src/communication/socket.cpp index 821ac0f8..29e1d256 100644 --- a/src/communication/socket.cpp +++ b/src/communication/socket.cpp @@ -51,8 +51,6 @@ Error Socket::Open() } if (connect(mSocketFd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { - LOG_ERR() << "Failed to connect to server: address=" << mServerAddress.CStr() << ", port=" << mServerPort; - close(mSocketFd); mSocketFd = -1; @@ -89,15 +87,11 @@ bool Socket::IsOpened() const int Socket::Read(void* data, size_t size) { - LOG_DBG() << "Read from server: size=" << size; - return ReadFromSocket(mSocketFd, data, size); } int Socket::Write(const void* data, size_t size) { - LOG_DBG() << "Write to server: size=" << size; - return WriteToSocket(mSocketFd, data, size); } @@ -124,8 +118,6 @@ int Socket::ReadFromSocket(int fd, void* data, size_t size) readBytes += len; } - LOG_DBG() << "Read from socket: readBytes=" << readBytes; - return readBytes; } @@ -147,8 +139,6 @@ int Socket::WriteToSocket(int fd, const void* data, size_t size) writtenBytes += len; } - LOG_DBG() << "Written to socket: writtenBytes=" << writtenBytes; - return writtenBytes; } From 9a8cdd52a88f7e565ebc01647e1ad17119e7dd43 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 2 Sep 2024 12:08:19 +0300 Subject: [PATCH 130/198] [mbedtls] Configure to support multi threads Signed-off-by: Oleksandr Grytsov --- src/aosmbedtlsconfig.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/aosmbedtlsconfig.h b/src/aosmbedtlsconfig.h index 815b2f7c..790d569b 100644 --- a/src/aosmbedtlsconfig.h +++ b/src/aosmbedtlsconfig.h @@ -8,6 +8,8 @@ #ifndef AOSMBEDTLSCONFIG_H_ #define AOSMBEDTLSCONFIG_H_ +#define MBEDTLS_THREADING_PTHREAD +#define MBEDTLS_THREADING_C #define MBEDTLS_PEM_WRITE_C #define MBEDTLS_PK_HAVE_ECC_KEYS #define MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS From d1badc7c1129583ef4383fbff0efa62121efd330 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 2 Sep 2024 12:09:51 +0300 Subject: [PATCH 131/198] [app] Initialize communication after IAM Signed-off-by: Oleksandr Grytsov --- src/app/app.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index e6c413ef..a0f34646 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -40,6 +40,10 @@ Error App::Init() return err; } + if (auto err = InitCommunication(); !err.IsNone()) { + return err; + } + return ErrorEnum::eNone; } @@ -163,10 +167,6 @@ Error App::InitZephyr() return AOS_ERROR_WRAP(err); } - if (auto err = InitCommunication(); !err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - if (auto err = mDownloader.Init(mSMClient); !err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -183,18 +183,6 @@ Error App::InitZephyr() return AOS_ERROR_WRAP(err); } - if (auto err - = mIAMClient.Init(mClockSync, mNodeInfoProvider, mProvisionManager, mChannelManager, mCertHandler, mCertLoader); - !err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - if (auto err = mSMClient.Init(mNodeInfoProvider, mLauncher, mResourceManager, mResourceMonitor, mDownloader, - mClockSync, mChannelManager, mCertHandler, mCertLoader); - !err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - return ErrorEnum::eNone; } @@ -216,6 +204,18 @@ Error App::InitCommunication() return AOS_ERROR_WRAP(err); } + if (auto err + = mIAMClient.Init(mClockSync, mNodeInfoProvider, mProvisionManager, mChannelManager, mCertHandler, mCertLoader); + !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + if (auto err = mSMClient.Init(mNodeInfoProvider, mLauncher, mResourceManager, mResourceMonitor, mDownloader, + mClockSync, mChannelManager, mCertHandler, mCertLoader); + !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + return ErrorEnum::eNone; } From 58c16d98fc1850a70bd30c967fdc9c365867b08d Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 2 Sep 2024 16:04:42 +0300 Subject: [PATCH 132/198] [Kconfig] Add configurable stack size for pb handler and launcher Signed-off-by: Oleksandr Grytsov --- Kconfig | 8 ++++++++ boards/native_posix.conf | 2 ++ boards/native_posix_64.conf | 2 ++ src/aoscoreconfig.hpp | 23 +++++++++++++++++++++++ src/communication/pbhandler.cpp | 9 +++++++++ src/communication/pbhandler.hpp | 4 +++- tests/iamclient/Kconfig | 4 ++++ tests/smclient/Kconfig | 8 ++++++++ tests/storage/Kconfig | 4 ++++ 9 files changed, 63 insertions(+), 1 deletion(-) diff --git a/Kconfig b/Kconfig index f1a5ee74..9698900b 100644 --- a/Kconfig +++ b/Kconfig @@ -113,6 +113,14 @@ config AOS_SOCKET_SERVER_PORT depends on NATIVE_APPLICATION default 30001 +config AOS_PBHANDLER_THREAD_STACK_SIZE + int "Aos PB handler stack size" + default 16384 + +config AOS_LAUNCHER_THREAD_STACK_SIZE + int "Aos launcher stack size" + default 16384 + config DOMD_ENABLE bool "Enable Domain-D creation" default y diff --git a/boards/native_posix.conf b/boards/native_posix.conf index 1571db09..eb31c679 100644 --- a/boards/native_posix.conf +++ b/boards/native_posix.conf @@ -89,6 +89,8 @@ CONFIG_AOS_HSM_DIR=".aos/hsm" CONFIG_AOS_NODE_STATUS_FILE=".aos/.nodestatus" CONFIG_AOS_NODE_ID_FILE=".aos/node-id" CONFIG_AOS_PKCS11_MODULE_PIN_FILE=".aos/.pkcs11pin" +CONFIG_AOS_PBHANDLER_THREAD_STACK_SIZE=32768 +CONFIG_AOS_LAUNCHER_THREAD_STACK_SIZE=32768 # Disable OP-TEE driver and client libraries # TEE is not supported by this platform diff --git a/boards/native_posix_64.conf b/boards/native_posix_64.conf index 1571db09..eb31c679 100644 --- a/boards/native_posix_64.conf +++ b/boards/native_posix_64.conf @@ -89,6 +89,8 @@ CONFIG_AOS_HSM_DIR=".aos/hsm" CONFIG_AOS_NODE_STATUS_FILE=".aos/.nodestatus" CONFIG_AOS_NODE_ID_FILE=".aos/node-id" CONFIG_AOS_PKCS11_MODULE_PIN_FILE=".aos/.pkcs11pin" +CONFIG_AOS_PBHANDLER_THREAD_STACK_SIZE=32768 +CONFIG_AOS_LAUNCHER_THREAD_STACK_SIZE=32768 # Disable OP-TEE driver and client libraries # TEE is not supported by this platform diff --git a/src/aoscoreconfig.hpp b/src/aoscoreconfig.hpp index bfa3f6fc..fca0358d 100644 --- a/src/aoscoreconfig.hpp +++ b/src/aoscoreconfig.hpp @@ -45,6 +45,18 @@ */ #define AOS_CONFIG_CRYPTOUTILS_DEFAULT_PKCS11_LIB "libckteec" +#else + +/** + * Set default thread stack size. + */ +#define AOS_CONFIG_THREAD_DEFAULT_STACK_SIZE 32768 + +/** + * Configures thread stack guard size. + */ +#define AOS_CONFIG_THREAD_STACK_GUARD_SIZE 4096 + #endif // CONFIG_NATIVE_APPLICATION // This config also used to generate proto options file. Using Aos new operator causes redefinition error. @@ -72,4 +84,15 @@ */ #define AOS_CONFIG_SERVICEMANAGER_SERVICES_DIR CONFIG_AOS_SERVICES_DIR +/** + * Set launcher thread stack size. + */ + +#define AOS_CONFIG_LAUNCHER_THREAD_STACK_SIZE CONFIG_AOS_LAUNCHER_THREAD_STACK_SIZE + +/** + * Configures thread stack usage logging. + */ +#define AOS_CONFIG_THREAD_STACK_USAGE 1 + #endif diff --git a/src/communication/pbhandler.cpp b/src/communication/pbhandler.cpp index 69aa1e27..7a85c081 100644 --- a/src/communication/pbhandler.cpp +++ b/src/communication/pbhandler.cpp @@ -113,6 +113,10 @@ Error PBHandler::SendMessage(const void* me template void PBHandler::Run() { +#if AOS_CONFIG_THREAD_STACK_USAGE + LOG_DBG() << "Stack usage: name=" << mName << ", size=" << mThread.GetStackUsage(); +#endif + while (true) { { LockGuard lock {mMutex}; @@ -124,6 +128,7 @@ void PBHandler::Run() if (auto err = mChannel->Connect(); !err.IsNone()) { LOG_ERR() << "Failed to connect: name=" << mName << ", err=" << err; + continue; } @@ -132,6 +137,10 @@ void PBHandler::Run() AosProtobufHeader header; while (true) { +#if AOS_CONFIG_THREAD_STACK_USAGE + LOG_DBG() << "Stack usage: name=" << mName << ", size=" << mThread.GetStackUsage(); +#endif + auto ret = mChannel->Read(&header, sizeof(header)); if (ret < 0) { LOG_ERR() << "Failed to read channel: name=" << mName << ", ret=" << ret << ", err=" << strerror(errno); diff --git a/src/communication/pbhandler.hpp b/src/communication/pbhandler.hpp index 208c7217..d28868b9 100644 --- a/src/communication/pbhandler.hpp +++ b/src/communication/pbhandler.hpp @@ -97,13 +97,15 @@ class PBHandler { virtual Error ReceiveMessage(const Array& data) = 0; private: + static constexpr auto cThreadStackSize = CONFIG_AOS_PBHANDLER_THREAD_STACK_SIZE; + void Run(); StaticString<64> mName; ChannelItf* mChannel; mutable Mutex mMutex; ConditionalVariable mCondVar; - Thread<> mThread; + Thread mThread; bool mStarted = false; aos::StaticBuffer mSendBuffer; aos::StaticBuffer mReceiveBuffer; diff --git a/tests/iamclient/Kconfig b/tests/iamclient/Kconfig index a10b40d2..ebf63262 100644 --- a/tests/iamclient/Kconfig +++ b/tests/iamclient/Kconfig @@ -25,4 +25,8 @@ config AOS_IAM_SECURE_PORT int "Aos SM secure port" default 2 +config AOS_PBHANDLER_THREAD_STACK_SIZE + int "Aos PB handler stack size" + default 16384 + source "Kconfig" diff --git a/tests/smclient/Kconfig b/tests/smclient/Kconfig index cfcca898..831da47d 100644 --- a/tests/smclient/Kconfig +++ b/tests/smclient/Kconfig @@ -33,4 +33,12 @@ config AOS_SM_SECURE_PORT int "Aos SM secure port" default 2 +config AOS_PBHANDLER_THREAD_STACK_SIZE + int "Aos PB handler stack size" + default 16384 + +config AOS_LAUNCHER_THREAD_STACK_SIZE + int "Aos launcher stack size" + default 16384 + source "Kconfig" diff --git a/tests/storage/Kconfig b/tests/storage/Kconfig index 10e93fac..ed39114e 100644 --- a/tests/storage/Kconfig +++ b/tests/storage/Kconfig @@ -17,4 +17,8 @@ config AOS_SERVICES_DIR string "Aos services dir" default "services" +config AOS_LAUNCHER_THREAD_STACK_SIZE + int "Aos launcher stack size" + default 16384 + source "Kconfig" From 2bea89d1153838541a1bb169701d4a6d0c99ac07 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 2 Sep 2024 16:05:32 +0300 Subject: [PATCH 133/198] [communication] Fix setting TLS config for TLSChannel Signed-off-by: Oleksandr Grytsov --- src/communication/tlschannel.cpp | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/communication/tlschannel.cpp b/src/communication/tlschannel.cpp index 13ccf4b1..05e7a5c5 100644 --- a/src/communication/tlschannel.cpp +++ b/src/communication/tlschannel.cpp @@ -50,24 +50,17 @@ Error TLSChannel::SetTLSConfig(const String& certType) { LOG_DBG() << "Set TLS config: name=" << mName << ", certType=" << certType; - if (certType == mCertType) { + Cleanup(); + + if (certType.IsEmpty()) { return ErrorEnum::eNone; } - mCertType = certType; - - if (certType != "") { - auto err = SetupSSLConfig(certType); - if (!err.IsNone()) { - Cleanup(); - - return err; - } - - return ErrorEnum::eNone; + if (auto err = SetupSSLConfig(certType); !err.IsNone()) { + return err; } - Cleanup(); + mCertType = certType; return ErrorEnum::eNone; } @@ -187,7 +180,7 @@ Error TLSChannel::SetupSSLConfig(const String& certType) auto retCert = mCertLoader->LoadCertsChainByURL(certInfo.mCertURL); if (!retCert.mError.IsNone()) { - return retCert.mError; + return AOS_ERROR_WRAP(retCert.mError); } for (auto& cert : *retCert.mValue) { @@ -205,14 +198,14 @@ Error TLSChannel::SetupSSLConfig(const String& certType) auto retKey = mCertLoader->LoadPrivKeyByURL(certInfo.mKeyURL); if (!retKey.mError.IsNone()) { - return retKey.mError; + return AOS_ERROR_WRAP(retKey.mError); } mPrivKey = retKey.mValue; auto retOpaqueKey = SetupOpaqueKey(mPrivKeyCtx); if (!retOpaqueKey.mError.IsNone()) { - return retOpaqueKey.mError; + return AOS_ERROR_WRAP(retOpaqueKey.mError); } mKeyID = retOpaqueKey.mValue; @@ -244,7 +237,11 @@ Error TLSChannel::SetupSSLConfig(const String& certType) mbedtls_ssl_conf_dbg(&mConf, zephyr_mbedtls_debug, nullptr); #endif - return AOS_ERROR_WRAP(mbedtls_ssl_setup(&mSSL, &mConf)); + if (ret = mbedtls_ssl_setup(&mSSL, &mConf); ret != 0) { + return AOS_ERROR_WRAP(ret); + } + + return ErrorEnum::eNone; } /*********************************************************************************************************************** From ddcc2c836276708c56bea2fc19627e6921f2cb5c Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 2 Sep 2024 16:06:37 +0300 Subject: [PATCH 134/198] [iamclient] Send node info on each connect Signed-off-by: Oleksandr Grytsov --- src/iamclient/iamclient.cpp | 30 ++++-------------------------- src/iamclient/iamclient.hpp | 1 - 2 files changed, 4 insertions(+), 27 deletions(-) diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index fbacc86c..5152c056 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -138,8 +138,9 @@ void IAMClient::OnConnect() LOG_DBG() << "Channel connected: port=" << mCurrentPort; - mConnected = true; - mCondVar.NotifyOne(); + if (auto err = SendNodeInfo(); !err.IsNone()) { + LOG_ERR() << "Can't send node info: err=" << err; + } } void IAMClient::OnDisconnect() @@ -147,9 +148,6 @@ void IAMClient::OnDisconnect() LockGuard lock {mMutex}; LOG_DBG() << "Channel disconnected: port=" << mCurrentPort; - - mConnected = false; - mCondVar.NotifyOne(); } Error IAMClient::ReleaseChannel() @@ -233,17 +231,7 @@ bool IAMClient::WaitChannelSwitch(UniqueLock& lock) bool IAMClient::WaitClockSynced(UniqueLock& lock) { - if (mNodeInfo.mStatus != NodeStatusEnum::eUnprovisioned) { - mCondVar.Wait(lock, [this]() { return mClockSynced || mClose; }); - mClockSynced = false; - } - - return !mClose; -} - -bool IAMClient::WaitChannelConnected(UniqueLock& lock) -{ - mCondVar.Wait(lock, [this]() { return mConnected || mClose; }); + mCondVar.Wait(lock, [this]() { return mClockSynced || mClose; }); return !mClose; } @@ -273,16 +261,6 @@ void IAMClient::HandleChannels() continue; } - if (!WaitChannelConnected(lock)) { - continue; - } - - if (auto err = SendNodeInfo(); !err.IsNone()) { - LOG_ERR() << "Can't send node info: err=" << err; - - mSwitchChannel = true; - } - if (!WaitChannelSwitch(lock)) { continue; } diff --git a/src/iamclient/iamclient.hpp b/src/iamclient/iamclient.hpp index 4fa7c014..d675ecc0 100644 --- a/src/iamclient/iamclient.hpp +++ b/src/iamclient/iamclient.hpp @@ -124,7 +124,6 @@ class IAMClient bool mSwitchChannel = false; int mCurrentPort = 0; bool mClose = false; - bool mConnected = false; StaticAllocator mAllocator; }; From dc56ac92e686e538817ff98a1052006c6f950c8e Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 2 Sep 2024 17:39:58 +0300 Subject: [PATCH 135/198] [nodeinfoprovider] Refactor CONFIG_NATIVE_APPLICATION define usage Signed-off-by: Oleksandr Grytsov --- src/nodeinfoprovider/nodeinfoprovider.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp index b4791dea..ead6be73 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -7,10 +7,10 @@ #include #include -#ifndef CONFIG_NATIVE_APPLICATION -#include -#else +#ifdef CONFIG_NATIVE_APPLICATION #include +#else +#include #endif #include From d10c99b9367e274c2a687d6f003b00efa87c3c56 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 2 Sep 2024 17:40:57 +0300 Subject: [PATCH 136/198] [nodeinfoprovider] Add empty CPU info element to node status Cloud required this field to be mandatory. Add empty entry to satisfy cloud requirements. Signed-off-by: Oleksandr Grytsov --- src/nodeinfoprovider/nodeinfoprovider.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp index ead6be73..d273d601 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -48,6 +48,8 @@ Error NodeInfoProvider::Init() mNodeInfo.mNodeType = cNodeType; mNodeInfo.mMaxDMIPS = cMaxDMIPS; + mNodeInfo.mCPUs.PushBack(CPUInfo {}); + Error err; if (Tie(mNodeInfo.mStatus, err) = ReadNodeStatus(); !err.IsNone()) { From f56da027b5955d5d9a82972d89b6415f584bba28 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 2 Sep 2024 17:41:58 +0300 Subject: [PATCH 137/198] [nodeinfoprovider] Fix displaying node status in log Signed-off-by: Oleksandr Grytsov --- src/nodeinfoprovider/nodeinfoprovider.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp index d273d601..8be3a479 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -71,7 +71,7 @@ Error NodeInfoProvider::GetNodeInfo(NodeInfo& nodeInfo) const { LockGuard lock {mMutex}; - LOG_DBG() << "Get node info: status=" << nodeInfo.mStatus; + LOG_DBG() << "Get node info: status=" << mNodeInfo.mStatus; nodeInfo = mNodeInfo; From 968426700455bf22b8552ac8087dcce7c80a4575 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 2 Sep 2024 17:43:56 +0300 Subject: [PATCH 138/198] [monitoring] Use host fs stats for monitoring Signed-off-by: Oleksandr Grytsov --- src/monitoring/resourceusageprovider.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/monitoring/resourceusageprovider.cpp b/src/monitoring/resourceusageprovider.cpp index f4f5676c..1d05450a 100644 --- a/src/monitoring/resourceusageprovider.cpp +++ b/src/monitoring/resourceusageprovider.cpp @@ -8,7 +8,11 @@ #include #include +#ifdef CONFIG_NATIVE_APPLICATION +#include +#else #include +#endif #include "log.hpp" #include "resourceusageprovider.hpp" @@ -58,13 +62,19 @@ Error ResourceUsageProvider::GetNodeMonitoringData( mPrevTime = curTime; for (size_t i = 0; i < monitoringData.mDisk.Size(); ++i) { +#ifdef CONFIG_NATIVE_APPLICATION + struct statvfs sbuf; + + if (ret = statvfs(monitoringData.mDisk[i].mPath.CStr(), &sbuf); ret != 0) { + return ret; + } +#else struct fs_statvfs sbuf; - ret = fs_statvfs(monitoringData.mDisk[i].mPath.CStr(), &sbuf); - if (ret != 0) { + if (ret = fs_statvfs(monitoringData.mDisk[i].mPath.CStr(), &sbuf); ret != 0) { return AOS_ERROR_WRAP(ret); } - +#endif monitoringData.mDisk[i].mUsedSize = (uint64_t)(sbuf.f_blocks - sbuf.f_bfree) * (uint64_t)sbuf.f_bsize; LOG_DBG() << "Disk: " << monitoringData.mDisk[i].mName From 1d3110224ac32f9fca0e0f3251e85c0136a9da82 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Tue, 3 Sep 2024 11:30:36 +0300 Subject: [PATCH 139/198] [communication] Add reconnect for pbhandler Signed-off-by: Oleksandr Grytsov --- src/communication/pbhandler.cpp | 8 ++++++++ src/communication/pbhandler.hpp | 1 + 2 files changed, 9 insertions(+) diff --git a/src/communication/pbhandler.cpp b/src/communication/pbhandler.cpp index 7a85c081..9b4be10c 100644 --- a/src/communication/pbhandler.cpp +++ b/src/communication/pbhandler.cpp @@ -127,7 +127,15 @@ void PBHandler::Run() } if (auto err = mChannel->Connect(); !err.IsNone()) { + aos::UniqueLock lock {mMutex}; + LOG_ERR() << "Failed to connect: name=" << mName << ", err=" << err; + LOG_DBG() << "Reconnect in " << cReconnectPeriod / 1000000 << " ms"; + + if (err = mCondVar.Wait(lock, cReconnectPeriod, [this] { return !mStarted; }); + !err.IsNone() && !err.Is(ErrorEnum::eTimeout)) { + LOG_ERR() << "Failed to wait reconnect: name=" << mName << ", err=" << err; + } continue; } diff --git a/src/communication/pbhandler.hpp b/src/communication/pbhandler.hpp index d28868b9..579f8999 100644 --- a/src/communication/pbhandler.hpp +++ b/src/communication/pbhandler.hpp @@ -98,6 +98,7 @@ class PBHandler { private: static constexpr auto cThreadStackSize = CONFIG_AOS_PBHANDLER_THREAD_STACK_SIZE; + static constexpr auto cReconnectPeriod = 2 * Time::cSeconds; void Run(); From d5c04059f005a93ab3097185185e2a9a5bc80807 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Thu, 5 Sep 2024 12:09:58 +0300 Subject: [PATCH 140/198] [prj.conf] Increase mbedtls heap for handshake Signed-off-by: Mykola Solianko --- prj.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prj.conf b/prj.conf index 4503a1b6..53495ce5 100644 --- a/prj.conf +++ b/prj.conf @@ -76,7 +76,7 @@ CONFIG_MAX_THREAD_BYTES=3 CONFIG_MBEDTLS=y CONFIG_MBEDTLS_BUILTIN=y CONFIG_MBEDTLS_ENABLE_HEAP=y -CONFIG_MBEDTLS_HEAP_SIZE=131072 +CONFIG_MBEDTLS_HEAP_SIZE=262144 CONFIG_MBEDTLS_ZEPHYR_ENTROPY=y CONFIG_MBEDTLS_USER_CONFIG_ENABLE=y CONFIG_MBEDTLS_USER_CONFIG_FILE="aosmbedtlsconfig.h" From cb686fc9f89fae7ba5a38a58716bd83da990b600 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Thu, 19 Sep 2024 12:22:17 +0300 Subject: [PATCH 141/198] [west.yaml] Swith to develop repos Signed-off-by: Mykhailo Lohvynenko --- west.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/west.yml b/west.yml index 01cc6ae7..0e59b668 100644 --- a/west.yml +++ b/west.yml @@ -29,11 +29,11 @@ manifest: - name: aos_core_lib_cpp remote: aosedge - revision: "feature_dynamic_nodes" + revision: "develop" - name: aos_core_api remote: aosedge - revision: "feature_dynamic_nodes" + revision: "develop" - name: zephyr-xenlib remote: xen-troops From b3e1cff87254cf578a204aaac89fe10901b03a72 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Thu, 19 Sep 2024 12:37:24 +0300 Subject: [PATCH 142/198] [smclient] Rename pb monitoring field disk to partition Signed-off-by: Mykhailo Lohvynenko --- src/smclient/smclient.cpp | 18 +++++++++--------- tests/smclient/src/main.cpp | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index 693d28bc..7f7658ae 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -30,17 +30,17 @@ static google_protobuf_Timestamp TimestampToPB(const Time& time) static void MonitoringDataToPB(const monitoring::MonitoringData& monitoringData, const Time& timestamp, servicemanager_v4_MonitoringData& pbMonitoringData) { - pbMonitoringData.cpu = monitoringData.mCPU + 0.5; - pbMonitoringData.ram = monitoringData.mRAM; - pbMonitoringData.download = monitoringData.mDownload; - pbMonitoringData.upload = monitoringData.mUpload; - pbMonitoringData.disk_count = monitoringData.mDisk.Size(); - pbMonitoringData.has_timestamp = true; - pbMonitoringData.timestamp = TimestampToPB(timestamp); + pbMonitoringData.cpu = monitoringData.mCPU + 0.5; + pbMonitoringData.ram = monitoringData.mRAM; + pbMonitoringData.download = monitoringData.mDownload; + pbMonitoringData.upload = monitoringData.mUpload; + pbMonitoringData.partitions_count = monitoringData.mDisk.Size(); + pbMonitoringData.has_timestamp = true; + pbMonitoringData.timestamp = TimestampToPB(timestamp); for (size_t i = 0; i < monitoringData.mDisk.Size(); i++) { - utils::StringFromCStr(pbMonitoringData.disk[i].name) = monitoringData.mDisk[i].mName; - pbMonitoringData.disk[i].used_size = monitoringData.mDisk[i].mUsedSize; + utils::StringFromCStr(pbMonitoringData.partitions[i].name) = monitoringData.mDisk[i].mName; + pbMonitoringData.partitions[i].used_size = monitoringData.mDisk[i].mUsedSize; } } diff --git a/tests/smclient/src/main.cpp b/tests/smclient/src/main.cpp index 107f0544..28b0cebd 100644 --- a/tests/smclient/src/main.cpp +++ b/tests/smclient/src/main.cpp @@ -112,11 +112,11 @@ static void PBToMonitoringData( { aosMonitoring.mRAM = pbMonitoring.ram; aosMonitoring.mCPU = pbMonitoring.cpu; - aosMonitoring.mDisk.Resize(pbMonitoring.disk_count); + aosMonitoring.mDisk.Resize(pbMonitoring.partitions_count); - for (size_t i = 0; i < pbMonitoring.disk_count; i++) { - aosMonitoring.mDisk[i].mName = utils::StringFromCStr(pbMonitoring.disk[i].name); - aosMonitoring.mDisk[i].mUsedSize = pbMonitoring.disk[i].used_size; + for (size_t i = 0; i < pbMonitoring.partitions_count; i++) { + aosMonitoring.mDisk[i].mName = utils::StringFromCStr(pbMonitoring.partitions[i].name); + aosMonitoring.mDisk[i].mUsedSize = pbMonitoring.partitions[i].used_size; } aosMonitoring.mDownload = pbMonitoring.download; From 702d337bdf4a615dc0bf730491f43ed19efcd4d5 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Tue, 3 Sep 2024 17:06:28 +0300 Subject: [PATCH 143/198] [gitignore] Add .vscode Signed-off-by: Mykhailo Lohvynenko --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d13ad496..5ea77e24 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build/ .*/*\!.github twister-out* +.vscode From 27f3a8599dff07cc9bc352520908ae4465271681 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Tue, 3 Sep 2024 17:07:48 +0300 Subject: [PATCH 144/198] [smclient] Add start and stop methods Signed-off-by: Mykhailo Lohvynenko --- src/app/app.cpp | 20 +++++++++++++++++ src/app/app.hpp | 12 +++++++++++ src/main.cpp | 3 +++ src/smclient/openhandler.cpp | 4 ---- src/smclient/smclient.cpp | 42 ++++++++++++++++++++++++++---------- src/smclient/smclient.hpp | 14 ++++++++++-- tests/smclient/src/main.cpp | 12 ++++++++++- 7 files changed, 89 insertions(+), 18 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index a0f34646..3b0f3e3e 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -47,6 +47,26 @@ Error App::Init() return ErrorEnum::eNone; } +Error App::Start() +{ + LOG_INF() << "Start application"; + + if (auto err = mSMClient.Start(); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + return ErrorEnum::eNone; +} + +App::~App() +{ + LOG_INF() << "Stop application"; + + if (auto err = mSMClient.Stop(); !err.IsNone()) { + LOG_ERR() << "Failed to stop SM client: err=" << err; + } +} + /*********************************************************************************************************************** * Private **********************************************************************************************************************/ diff --git a/src/app/app.hpp b/src/app/app.hpp index 75fc65c9..b3b2762e 100644 --- a/src/app/app.hpp +++ b/src/app/app.hpp @@ -51,6 +51,18 @@ class App : private NonCopyable { */ Error Init(); + /** + * Starts application. + * + * @return Error + */ + Error Start(); + + /** + * Destructor. + */ + ~App(); + /** * Returns Aos application instance. * @return App& diff --git a/src/main.cpp b/src/main.cpp index 2a51a65d..1af88884 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -54,5 +54,8 @@ int main(void) auto err = app.Init(); __ASSERT(err.IsNone(), "Error initializing application: %s", utils::ErrorToCStr(err)); + err = app.Start(); + __ASSERT(err.IsNone(), "Error starting application: %s", utils::ErrorToCStr(err)); + return 0; } diff --git a/src/smclient/openhandler.cpp b/src/smclient/openhandler.cpp index 8a5d893d..0cf49c62 100644 --- a/src/smclient/openhandler.cpp +++ b/src/smclient/openhandler.cpp @@ -26,10 +26,6 @@ Error OpenHandler::Init(communication::ChannelItf& channel, clocksync::ClockSync return AOS_ERROR_WRAP(err); } - if (auto err = Start(); !err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - return ErrorEnum::eNone; } diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index 7f7658ae..07f63cfd 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -95,12 +95,29 @@ Error SMClient::Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvide mResourceManager = &resourceManager; mResourceMonitor = &resourceMonitor; mDownloader = &downloader; + mClockSync = &clockSync; mChannelManager = &channelManager; #ifndef CONFIG_ZTEST mCertHandler = &certHandler; mCertLoader = &certLoader; #endif + auto [openChannel, err] = mChannelManager->CreateChannel(cOpenPort); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + if (err = mOpenHandler.Init(*openChannel, *mClockSync); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + return ErrorEnum::eNone; +} + +Error SMClient::Start() +{ + LOG_DBG() << "Start SM client"; + auto nodeInfo = MakeUnique(&mAllocator); if (auto err = mNodeInfoProvider->GetNodeInfo(*nodeInfo); !err.IsNone()) { @@ -109,30 +126,29 @@ Error SMClient::Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvide mProvisioned = nodeInfo->mStatus != NodeStatusEnum::eUnprovisioned; - auto [openChannel, err] = mChannelManager->CreateChannel(cOpenPort); - if (!err.IsNone()) { + if (auto err = mClockSync->Subscribe(*this); !err.IsNone()) { return AOS_ERROR_WRAP(err); } - if (err = mOpenHandler.Init(*openChannel, clockSync); !err.IsNone()) { - return err; - } - - if (err = clockSync.Subscribe(*this); !err.IsNone()) { + if (auto err = mNodeInfoProvider->SubscribeNodeStatusChanged(*this); !err.IsNone()) { return AOS_ERROR_WRAP(err); } - if (err = mNodeInfoProvider->SubscribeNodeStatusChanged(*this); !err.IsNone()) { + if (auto err = mOpenHandler.Start(); !err.IsNone()) { return AOS_ERROR_WRAP(err); } return ErrorEnum::eNone; } -SMClient::~SMClient() +Error SMClient::Stop() { + LOG_DBG() << "Stop SM client"; + if (IsStarted()) { - if (auto err = Stop(); !err.IsNone()) { + if (auto err = communication::PBHandler::Stop(); + !err.IsNone()) { LOG_ERR() << "Failed to stop PB handler: err=" << err; } @@ -154,6 +170,8 @@ SMClient::~SMClient() LockGuard lock {mMutex}; mConnectionSubscribers.Clear(); + + return ErrorEnum::eNone; } Error SMClient::InstancesRunStatus(const Array& instances) @@ -619,7 +637,9 @@ void SMClient::UpdatePBHandlerState() return; } - if (err = Start(); !err.IsNone()) { + if (err = communication::PBHandler::Start(); + !err.IsNone()) { LOG_ERR() << "Failed to start PB handler: err=" << err; return; } diff --git a/src/smclient/smclient.hpp b/src/smclient/smclient.hpp index 299a35c6..7a739523 100644 --- a/src/smclient/smclient.hpp +++ b/src/smclient/smclient.hpp @@ -63,9 +63,18 @@ class SMClient : public communication::PBHandler InitSMClient(smclient_fixture* fixture, u fixture->mResourceMonitor, fixture->mDownloader, fixture->mClockSync, fixture->mChannelManager); zassert_true(err.IsNone(), "Can't initialize SM client: %s", utils::ErrorToCStr(err)); + err = fixture->mSMClient->Start(); + zassert_true(err.IsNone(), "Can't start SM client: %s", utils::ErrorToCStr(err)); + fixture->mSMClient->OnClockSynced(); auto channel = fixture->mChannelManager.GetChannel(port); @@ -263,7 +266,14 @@ ZTEST_SUITE( smclientFixture->mNodeInfoProvider.Clear(); smclientFixture->mSMClient.reset(new smclient::SMClient); }, - [](void* fixture) { static_cast(fixture)->mSMClient.reset(); }, + [](void* fixture) { + auto smclientFixture = static_cast(fixture); + + auto err = smclientFixture->mSMClient->Stop(); + zassert_true(err.IsNone(), "Can't stop SM client: %s", utils::ErrorToCStr(err)); + + smclientFixture->mSMClient.reset(); + }, [](void* fixture) { delete static_cast(fixture); }); /*********************************************************************************************************************** From f97fd4c4d4e26d4cdbc40196c4476b6c1ea54cce Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Tue, 3 Sep 2024 17:14:02 +0300 Subject: [PATCH 145/198] [iamclient] Add start and stop methods Signed-off-by: Mykhailo Lohvynenko --- src/app/app.cpp | 8 +++++ src/iamclient/iamclient.cpp | 67 ++++++++++++++++++++++-------------- src/iamclient/iamclient.hpp | 19 +++++++--- tests/iamclient/src/main.cpp | 12 ++++++- 4 files changed, 74 insertions(+), 32 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index 3b0f3e3e..75a27085 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -51,6 +51,10 @@ Error App::Start() { LOG_INF() << "Start application"; + if (auto err = mIAMClient.Start(); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + if (auto err = mSMClient.Start(); !err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -62,6 +66,10 @@ App::~App() { LOG_INF() << "Stop application"; + if (auto err = mIAMClient.Stop(); !err.IsNone()) { + LOG_ERR() << "Failed to stop IAM client: err=" << err; + } + if (auto err = mSMClient.Stop(); !err.IsNone()) { LOG_ERR() << "Failed to stop SM client: err=" << err; } diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index 5152c056..5e5a0530 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -39,11 +39,18 @@ Error IAMClient::Init(clocksync::ClockSyncItf& clockSync, iam::nodeinfoprovider: mCertLoader = &certLoader; #endif - if (auto err = clockSync.Subscribe(*this); !err.IsNone()) { + return ErrorEnum::eNone; +} + +Error IAMClient::Start() +{ + LOG_DBG() << "Start IAM client"; + + if (auto err = mClockSync->Subscribe(*this); !err.IsNone()) { return AOS_ERROR_WRAP(err); } - if (auto err = nodeInfoProvider.SubscribeNodeStatusChanged(*this); !err.IsNone()) { + if (auto err = mNodeInfoProvider->SubscribeNodeStatusChanged(*this); !err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -51,16 +58,39 @@ Error IAMClient::Init(clocksync::ClockSyncItf& clockSync, iam::nodeinfoprovider: return AOS_ERROR_WRAP(err); } + if (mNodeInfo.mStatus == NodeStatusEnum::eUnprovisioned) { + LOG_INF() << "Node is unprovisioned"; + } + auto err = mThread.Run([this](void*) { HandleChannels(); }); if (!err.IsNone()) { return AOS_ERROR_WRAP(err); } - if (mNodeInfo.mStatus == NodeStatusEnum::eUnprovisioned) { - LOG_INF() << "Node is unprovisioned"; + return ErrorEnum::eNone; +} + +Error IAMClient::Stop() +{ + LOG_DBG() << "Stop IAM client"; + + if (auto err = communication::PBHandler::Stop(); + !err.IsNone()) { + LOG_ERR() << "Can't stop IAM handler: err=" << err; } - return ErrorEnum::eNone; + mClockSync->Unsubscribe(*this); + mNodeInfoProvider->UnsubscribeNodeStatusChanged(*this); + + { + LockGuard lock {mMutex}; + + mClose = true; + mCondVar.NotifyOne(); + } + + return mThread.Join(); } void IAMClient::OnClockSynced() @@ -109,25 +139,6 @@ Error IAMClient::OnNodeStatusChanged(const String& nodeID, const NodeStatus& sta return ErrorEnum::eNone; } -IAMClient::~IAMClient() -{ - if (auto err = Stop(); !err.IsNone()) { - LOG_ERR() << "Can't stop IAM handler: err=" << err; - } - - mClockSync->Unsubscribe(*this); - mNodeInfoProvider->UnsubscribeNodeStatusChanged(*this); - - { - LockGuard lock {mMutex}; - - mClose = true; - mCondVar.NotifyOne(); - } - - mThread.Join(); -} - /*********************************************************************************************************************** * Private **********************************************************************************************************************/ @@ -160,7 +171,9 @@ Error IAMClient::ReleaseChannel() LOG_DBG() << "Release channel: port=" << mCurrentPort; - if (auto stopErr = Stop(); !stopErr.IsNone() && err.IsNone()) { + if (auto stopErr = communication::PBHandler::Stop(); + !stopErr.IsNone() && err.IsNone()) { err = AOS_ERROR_WRAP(stopErr); } @@ -214,7 +227,9 @@ Error IAMClient::SetupChannel() } } - if (err = Start(); !err.IsNone()) { + if (err = communication::PBHandler::Start(); + !err.IsNone()) { return AOS_ERROR_WRAP(err); } diff --git a/src/iamclient/iamclient.hpp b/src/iamclient/iamclient.hpp index d675ecc0..2837b97e 100644 --- a/src/iamclient/iamclient.hpp +++ b/src/iamclient/iamclient.hpp @@ -51,6 +51,20 @@ class IAMClient #endif ); + /** + * Starts IAM client. + * + * @return Error. + */ + Error Start(); + + /** + * Stops IAM client. + * + * @return Error. + */ + Error Stop(); + /** * Notifies subscriber clock is synced. */ @@ -70,11 +84,6 @@ class IAMClient */ Error OnNodeStatusChanged(const String& nodeID, const NodeStatus& status) override; - /** - * Destructor. - */ - ~IAMClient(); - private: static constexpr auto cOpenPort = CONFIG_AOS_IAM_OPEN_PORT; static constexpr auto cSecurePort = CONFIG_AOS_IAM_SECURE_PORT; diff --git a/tests/iamclient/src/main.cpp b/tests/iamclient/src/main.cpp index f8f17a45..2a5cb5ec 100644 --- a/tests/iamclient/src/main.cpp +++ b/tests/iamclient/src/main.cpp @@ -65,6 +65,9 @@ static void InitIAMClient(iamclient_fixture* fixture, const aos::NodeInfo& nodeI fixture->mClockSync, fixture->mNodeInfoProvider, fixture->mProvisionManager, fixture->mChannelManager); zassert_true(err.IsNone(), "Can't initialize IAM client: %s", utils::ErrorToCStr(err)); + err = fixture->mIAMClient->Start(); + zassert_true(err.IsNone(), "Can't start IAM client: %s", utils::ErrorToCStr(err)); + fixture->mIAMClient->OnClockSynced(); } @@ -99,7 +102,14 @@ ZTEST_SUITE( return fixture; }, [](void* fixture) { static_cast(fixture)->mIAMClient.reset(new iamclient::IAMClient); }, - [](void* fixture) { static_cast(fixture)->mIAMClient.reset(); }, + [](void* fixture) { + auto& iamClientFixture = static_cast(fixture)->mIAMClient; + + auto err = iamClientFixture->Stop(); + zassert_true(err.IsNone(), "Can't stop IAM client: %s", utils::ErrorToCStr(err)); + + iamClientFixture.reset(); + }, [](void* fixture) { delete static_cast(fixture); }); /*********************************************************************************************************************** From 0dea8de034f8b2cd85d33a3268521d693362b4b1 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Tue, 3 Sep 2024 17:19:36 +0300 Subject: [PATCH 146/198] [communication,channelmanager] Add start method Signed-off-by: Mykhailo Lohvynenko --- src/app/app.cpp | 4 ++++ src/communication/channelmanager.cpp | 7 +++++++ src/communication/channelmanager.hpp | 7 +++++++ tests/communication/src/channelmanager.cpp | 9 +++++++++ 4 files changed, 27 insertions(+) diff --git a/src/app/app.cpp b/src/app/app.cpp index 75a27085..e48a4c64 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -51,6 +51,10 @@ Error App::Start() { LOG_INF() << "Start application"; + if (auto err = mChannelManager.Start(); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + if (auto err = mIAMClient.Start(); !err.IsNone()) { return AOS_ERROR_WRAP(err); } diff --git a/src/communication/channelmanager.cpp b/src/communication/channelmanager.cpp index 7c8038fc..f7ba3e98 100644 --- a/src/communication/channelmanager.cpp +++ b/src/communication/channelmanager.cpp @@ -27,6 +27,13 @@ Error ChannelManager::Init(TransportItf& transport) mTransport = &transport; + return ErrorEnum::eNone; +} + +Error ChannelManager::Start() +{ + LOG_DBG() << "Start channel manager"; + return Run(); } diff --git a/src/communication/channelmanager.hpp b/src/communication/channelmanager.hpp index 4ad24c99..ecd100ee 100644 --- a/src/communication/channelmanager.hpp +++ b/src/communication/channelmanager.hpp @@ -69,6 +69,13 @@ class ChannelManager : public ChannelManagerItf, public CommunicationItf { */ Error Init(TransportItf& transport); + /** + * Starts channel manager. + * + * @return Error. + */ + Error Start(); + /** * Create channel with dedicated port. * diff --git a/tests/communication/src/channelmanager.cpp b/tests/communication/src/channelmanager.cpp index fad50c48..27c42551 100644 --- a/tests/communication/src/channelmanager.cpp +++ b/tests/communication/src/channelmanager.cpp @@ -63,6 +63,9 @@ ZTEST(channelmanager, test_message_exchange) auto err = channelManager.Init(transport); zassert_true(err.IsNone(), "Channel manager initialization failed"); + err = channelManager.Start(); + zassert_true(err.IsNone(), "Channel manager start failed"); + auto ret = channelManager.CreateChannel(8080); zassert_true(ret.mError.IsNone(), "Channel creation failed", ret.mError.Message()); zassert_true(ret.mValue != nullptr, "Channel creation failed"); @@ -111,6 +114,9 @@ ZTEST(channelmanager, test_read_message) auto err = channelManager.Init(transport); zassert_true(err.IsNone(), "Channel manager initialization failed"); + err = channelManager.Start(); + zassert_true(err.IsNone(), "Channel manager start failed"); + auto ret = channelManager.CreateChannel(8080); zassert_true(ret.mError.IsNone(), "Channel creation failed", ret.mError.Message()); zassert_true(ret.mValue != nullptr, "Channel creation failed"); @@ -150,6 +156,9 @@ ZTEST(channelmanager, test_read_message_in_chunks) auto err = channelManager.Init(transport); zassert_true(err.IsNone(), "Channel manager initialization failed"); + err = channelManager.Start(); + zassert_true(err.IsNone(), "Channel manager start failed"); + auto ret = channelManager.CreateChannel(8080); zassert_true(ret.mError.IsNone(), "Channel creation failed", ret.mError.Message()); zassert_true(ret.mValue != nullptr, "Channel creation failed"); From 231292e288a13f80b0dc27dff6aa6e878722f1e8 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Tue, 3 Sep 2024 18:37:31 +0300 Subject: [PATCH 147/198] [app] Start and stop resource monitoring Signed-off-by: Mykhailo Lohvynenko --- src/app/app.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/app/app.cpp b/src/app/app.cpp index e48a4c64..aaef094c 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -51,6 +51,10 @@ Error App::Start() { LOG_INF() << "Start application"; + if (auto err = mResourceMonitor.Start(); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + if (auto err = mChannelManager.Start(); !err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -70,6 +74,10 @@ App::~App() { LOG_INF() << "Stop application"; + if (auto err = mResourceMonitor.Stop(); !err.IsNone()) { + LOG_ERR() << "Failed to stop resource monitor: err=" << err; + } + if (auto err = mIAMClient.Stop(); !err.IsNone()) { LOG_ERR() << "Failed to stop IAM client: err=" << err; } From ec2319616b0a6d11a11075f84daacdb75872f157 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Wed, 4 Sep 2024 19:45:53 +0300 Subject: [PATCH 148/198] [communication] Shutdown socket on close Signed-off-by: Mykhailo Lohvynenko --- src/communication/socket.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/communication/socket.cpp b/src/communication/socket.cpp index 29e1d256..09fe3aaa 100644 --- a/src/communication/socket.cpp +++ b/src/communication/socket.cpp @@ -69,7 +69,14 @@ Error Socket::Close() LockGuard lock {mMutex}; if (mSocketFd != -1) { - close(mSocketFd); + if (auto ret = shutdown(mSocketFd, SHUT_RDWR); ret != 0) { + LOG_ERR() << "Failed to shutdown socket: err=" << ret; + } + + if (auto ret = close(mSocketFd); ret != 0) { + LOG_ERR() << "Failed to close socket: err=" << ret; + } + mSocketFd = -1; } From a44d2a1f112714bd25a7579fdeed4b173bfdff27 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Wed, 4 Sep 2024 19:47:43 +0300 Subject: [PATCH 149/198] [app] Start and stop launcher Signed-off-by: Mykhailo Lohvynenko --- src/app/app.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/app/app.cpp b/src/app/app.cpp index aaef094c..10291e49 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -51,6 +51,10 @@ Error App::Start() { LOG_INF() << "Start application"; + if (auto err = mLauncher.Start(); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + if (auto err = mResourceMonitor.Start(); !err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -74,6 +78,10 @@ App::~App() { LOG_INF() << "Stop application"; + if (auto err = mLauncher.Stop(); !err.IsNone()) { + LOG_ERR() << "Failed to stop launcher: err=" << err; + } + if (auto err = mResourceMonitor.Stop(); !err.IsNone()) { LOG_ERR() << "Failed to stop resource monitor: err=" << err; } From d14823d267857021ad55a9f564e8cfa0d2d0d1a5 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Wed, 4 Sep 2024 19:49:22 +0300 Subject: [PATCH 150/198] [clocksync] Add start and stop methods Signed-off-by: Mykhailo Lohvynenko --- src/app/app.cpp | 4 ++++ src/clocksync/clocksync.cpp | 26 ++++++++++++++------------ src/clocksync/clocksync.hpp | 12 +++++++----- tests/clocksync/src/main.cpp | 10 +++++++++- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index 10291e49..cfca62d0 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -86,6 +86,10 @@ App::~App() LOG_ERR() << "Failed to stop resource monitor: err=" << err; } + if (auto err = mClockSync.Stop(); !err.IsNone()) { + LOG_ERR() << "Failed to stop clock sync: err=" << err; + } + if (auto err = mIAMClient.Stop(); !err.IsNone()) { LOG_ERR() << "Failed to stop IAM client: err=" << err; } diff --git a/src/clocksync/clocksync.cpp b/src/clocksync/clocksync.cpp index a1966f26..93852976 100644 --- a/src/clocksync/clocksync.cpp +++ b/src/clocksync/clocksync.cpp @@ -81,6 +81,20 @@ Error ClockSync::Start() return ErrorEnum::eNone; } +Error ClockSync::Stop() +{ + { + LockGuard lock {mMutex}; + + LOG_DBG() << "Stop"; + + mClose = true; + mCondVar.NotifyOne(); + } + + return mThread.Join(); +} + Error ClockSync::Sync(const Time& time) { LockGuard lock {mMutex}; @@ -126,18 +140,6 @@ void ClockSync::Unsubscribe(ClockSyncSubscriberItf& subscriber) } } -ClockSync::~ClockSync() -{ - { - LockGuard lock {mMutex}; - - mClose = true; - mCondVar.NotifyOne(); - } - - mThread.Join(); -} - /*********************************************************************************************************************** * Private **********************************************************************************************************************/ diff --git a/src/clocksync/clocksync.hpp b/src/clocksync/clocksync.hpp index 0578d218..b3e9901a 100644 --- a/src/clocksync/clocksync.hpp +++ b/src/clocksync/clocksync.hpp @@ -93,11 +93,6 @@ class ClockSyncItf { */ class ClockSync : public ClockSyncItf { public: - /** - * Destructor. - */ - ~ClockSync(); - /** * Initializes clock sync instance. * @@ -113,6 +108,13 @@ class ClockSync : public ClockSyncItf { */ Error Start() override; + /** + * Stops clock sync. + * + * @return Error. + */ + Error Stop(); + /** * Synchronizes system clock. * diff --git a/tests/clocksync/src/main.cpp b/tests/clocksync/src/main.cpp index 036d64f6..ceac268c 100644 --- a/tests/clocksync/src/main.cpp +++ b/tests/clocksync/src/main.cpp @@ -59,7 +59,15 @@ ZTEST_SUITE( f->mSender.Clear(); }, - nullptr, [](void* fixture) { delete static_cast(fixture); }); + nullptr, + [](void* fixture) { + auto f = static_cast(fixture); + + auto err = f->mClockSync.Stop(); + zassert_true(err.IsNone(), "Can't stop clock sync: %s", utils::ErrorToCStr(err)); + + delete f; + }); /*********************************************************************************************************************** * Tests From a4ad93c2ddb69890fb2273e2d7a0581a5c0b2af0 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Wed, 4 Sep 2024 22:23:20 +0300 Subject: [PATCH 151/198] [app] Add stop method Signed-off-by: Mykhailo Lohvynenko --- src/app/app.cpp | 4 +++- src/app/app.hpp | 9 ++++++++- src/main.cpp | 13 +++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index cfca62d0..84abda80 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -74,7 +74,7 @@ Error App::Start() return ErrorEnum::eNone; } -App::~App() +Error App::Stop() { LOG_INF() << "Stop application"; @@ -97,6 +97,8 @@ App::~App() if (auto err = mSMClient.Stop(); !err.IsNone()) { LOG_ERR() << "Failed to stop SM client: err=" << err; } + + return ErrorEnum::eNone; } /*********************************************************************************************************************** diff --git a/src/app/app.hpp b/src/app/app.hpp index b3b2762e..fc5c9617 100644 --- a/src/app/app.hpp +++ b/src/app/app.hpp @@ -58,10 +58,17 @@ class App : private NonCopyable { */ Error Start(); + /** + * Stops application. + * + * @return Error + */ + Error Stop(); + /** * Destructor. */ - ~App(); + ~App() = default; /** * Returns Aos application instance. diff --git a/src/main.cpp b/src/main.cpp index 1af88884..a19f6d4c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -51,6 +51,19 @@ int main(void) auto& app = aos::zephyr::app::App::Get(); + atexit([]() { + auto err = aos::zephyr::app::App::Get().Stop(); + if (!err.IsNone()) { + printk("Error stopping application: %s\n", utils::ErrorToCStr(err)); + + _exit(1); + } + + printk("Application stopped\n"); + + _exit(0); + }); + auto err = app.Init(); __ASSERT(err.IsNone(), "Error initializing application: %s", utils::ErrorToCStr(err)); From e49f2e70c6f094ad758f8f50951197bacd35f15c Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Fri, 20 Sep 2024 14:01:57 +0300 Subject: [PATCH 152/198] [logger] Change module param to aos::String Signed-off-by: Mykhailo Lohvynenko --- src/logger/logger.cpp | 2 +- src/logger/logger.hpp | 2 +- tests/utils/log.cpp | 4 ++-- tests/utils/log.hpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/logger/logger.cpp b/src/logger/logger.cpp index 4d2cc253..1d290be8 100644 --- a/src/logger/logger.cpp +++ b/src/logger/logger.cpp @@ -114,7 +114,7 @@ void Logger::Init() * Public **********************************************************************************************************************/ -void Logger::LogCallback(const char* module, LogLevel level, const String& message) +void Logger::LogCallback(const String& module, LogLevel level, const String& message) { #ifdef CONFIG_NATIVE_APPLICATION static Mutex sMutex; diff --git a/src/logger/logger.hpp b/src/logger/logger.hpp index fda587ec..3ce1afe2 100644 --- a/src/logger/logger.hpp +++ b/src/logger/logger.hpp @@ -23,7 +23,7 @@ class Logger { static void Init(); private: - static void LogCallback(const char* module, LogLevel level, const String& message); + static void LogCallback(const String& module, LogLevel level, const String& message); }; } // namespace aos::zephyr::logger diff --git a/tests/utils/log.cpp b/tests/utils/log.cpp index 941ee015..59feba0f 100644 --- a/tests/utils/log.cpp +++ b/tests/utils/log.cpp @@ -11,7 +11,7 @@ #include "log.hpp" -void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message) +void TestLogCallback(const aos::String& module, aos::LogLevel level, const aos::String& message) { static std::mutex mutex; static auto startTime = std::chrono::steady_clock::now(); @@ -44,5 +44,5 @@ void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& break; } - printk("%0.3f (%s) [%s] %s\n", now, module, levelStr, message.CStr()); + printk("%0.3f (%s) [%s] %s\n", now, module.CStr(), levelStr, message.CStr()); } diff --git a/tests/utils/log.hpp b/tests/utils/log.hpp index 0cd4a60f..d2621a8a 100644 --- a/tests/utils/log.hpp +++ b/tests/utils/log.hpp @@ -10,6 +10,6 @@ #include -void TestLogCallback(const char* module, aos::LogLevel level, const aos::String& message); +void TestLogCallback(const aos::String& module, aos::LogLevel level, const aos::String& message); #endif From ff25b8840d12b50d71b07b6efd456c70576b2ee2 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 11 Sep 2024 13:52:14 +0300 Subject: [PATCH 153/198] [iamclient] Add cond var on reconnect Signed-off-by: Oleksandr Grytsov --- src/iamclient/iamclient.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index 5e5a0530..0938a494 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -270,8 +270,12 @@ void IAMClient::HandleChannels() if (auto err = SetupChannel(); !err.IsNone()) { LOG_ERR() << "Can't setup channel: err=" << err; + LOG_DBG() << "Reconnect in " << cReconnectInterval / 1000000 << " ms"; - usleep(cReconnectInterval / 1000); + if (err = mCondVar.Wait(lock, cReconnectInterval, [this] { return mClose; }); + !err.IsNone() && !err.Is(ErrorEnum::eTimeout)) { + LOG_ERR() << "Failed to wait reconnect: err=" << err; + } continue; } From 95d48f65f85996683e30f830d1e1c030a063c272 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 11 Sep 2024 13:52:58 +0300 Subject: [PATCH 154/198] [smclient] Move channel handling to separate thread Signed-off-by: Oleksandr Grytsov --- src/communication/pbhandler.cpp | 4 - src/smclient/smclient.cpp | 160 +++++++++++++++++--------------- src/smclient/smclient.hpp | 14 ++- tests/smclient/src/main.cpp | 2 +- 4 files changed, 95 insertions(+), 85 deletions(-) diff --git a/src/communication/pbhandler.cpp b/src/communication/pbhandler.cpp index 9b4be10c..fd26946e 100644 --- a/src/communication/pbhandler.cpp +++ b/src/communication/pbhandler.cpp @@ -113,10 +113,6 @@ Error PBHandler::SendMessage(const void* me template void PBHandler::Run() { -#if AOS_CONFIG_THREAD_STACK_USAGE - LOG_DBG() << "Stack usage: name=" << mName << ", size=" << mThread.GetStackUsage(); -#endif - while (true) { { LockGuard lock {mMutex}; diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index 07f63cfd..1f378bd5 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -138,6 +138,10 @@ Error SMClient::Start() return AOS_ERROR_WRAP(err); } + if (auto err = mThread.Run([this](void*) { HandleChannel(); }); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + return ErrorEnum::eNone; } @@ -145,18 +149,6 @@ Error SMClient::Stop() { LOG_DBG() << "Stop SM client"; - if (IsStarted()) { - if (auto err = communication::PBHandler::Stop(); - !err.IsNone()) { - LOG_ERR() << "Failed to stop PB handler: err=" << err; - } - - if (auto err = mChannelManager->DeleteChannel(cSecurePort); !err.IsNone()) { - LOG_ERR() << "Failed to delete channel: err=" << err; - } - } - if (mOpenHandler.IsStarted()) { if (auto err = mOpenHandler.Stop(); !err.IsNone()) { LOG_ERR() << "Failed to stop open handler: err=" << err; @@ -167,9 +159,16 @@ Error SMClient::Stop() } } - LockGuard lock {mMutex}; + { + LockGuard lock {mMutex}; + + mConnectionSubscribers.Clear(); + + mClose = true; + mCondVar.NotifyOne(); + } - mConnectionSubscribers.Clear(); + mThread.Join(); return ErrorEnum::eNone; } @@ -278,13 +277,10 @@ Error SMClient::OnNodeStatusChanged(const String& nodeID, const NodeStatus& stat { LOG_DBG() << "Node status changed: status=" << status; - { - LockGuard lock {mMutex}; - - mProvisioned = status != NodeStatusEnum::eUnprovisioned; - } + LockGuard lock {mMutex}; - UpdatePBHandlerState(); + mProvisioned = status != NodeStatusEnum::eUnprovisioned; + mCondVar.NotifyOne(); return ErrorEnum::eNone; } @@ -293,26 +289,20 @@ void SMClient::OnClockSynced() { LOG_DBG() << "Clock synced"; - { - LockGuard lock {mMutex}; - - mClockSynced = true; - } + LockGuard lock {mMutex}; - UpdatePBHandlerState(); + mClockSynced = true; + mCondVar.NotifyOne(); } void SMClient::OnClockUnsynced() { LOG_DBG() << "Clock unsynced"; - { - LockGuard lock {mMutex}; - - mClockSynced = false; - } + LockGuard lock {mMutex}; - UpdatePBHandlerState(); + mClockSynced = false; + mCondVar.NotifyOne(); } Error SMClient::SendClockSyncRequest() @@ -594,67 +584,85 @@ Error SMClient::SendNodeConfigStatus(const String& version, const Error& configE return SendMessage(outgoingMessage.Get(), &servicemanager_v4_SMOutgoingMessages_msg); } -void SMClient::UpdatePBHandlerState() +Error SMClient::SetupChannel() { - auto start = false; - auto stop = false; + auto [channel, err] = mChannelManager->CreateChannel(cSecurePort); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); + } - { - LockGuard lock {mMutex}; +#ifndef CONFIG_ZTEST + if (err = mTLSChannel.Init("sm", *mCertHandler, *mCertLoader, *channel); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } - if (mClockSynced && mProvisioned && !IsStarted()) { - start = true; - } + if (err = mTLSChannel.SetTLSConfig(cSMCertType); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } - if ((!mClockSynced || !mProvisioned) && IsStarted()) { - stop = true; - } + channel = &mTLSChannel; +#endif + + if (err = PBHandler::Init("SM secure", *channel); !err.IsNone()) { + return AOS_ERROR_WRAP(err); } - if (start) { - auto [channel, err] = mChannelManager->CreateChannel(cSecurePort); - if (!err.IsNone()) { - LOG_ERR() << "Failed to create channel: err=" << err; - return; - } + if (err = communication::PBHandler::Start(); + !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } -#ifndef CONFIG_ZTEST - if (err = mTLSChannel.Init("sm", *mCertHandler, *mCertLoader, *channel); !err.IsNone()) { - LOG_ERR() << "Failed to init TLS channel: err=" << err; - return; - } + return ErrorEnum::eNone; +} - if (err = mTLSChannel.SetTLSConfig(cSMCertType); !err.IsNone()) { - LOG_ERR() << "Failed to set TLS config: err=" << err; - return; - } +Error SMClient::ReleaseChannel() +{ + if (!IsStarted()) { + return ErrorEnum::eNone; + } - channel = &mTLSChannel; -#endif + if (auto err = communication::PBHandler::Stop(); + !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } - if (err = PBHandler::Init("SM secure", *channel); !err.IsNone()) { - LOG_ERR() << "Failed to init PB handler: err=" << err; - return; - } + if (auto err = mChannelManager->DeleteChannel(cSecurePort); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } - if (err = communication::PBHandler::Start(); - !err.IsNone()) { - LOG_ERR() << "Failed to start PB handler: err=" << err; - return; + return ErrorEnum::eNone; +} + +void SMClient::HandleChannel() +{ + while (true) { + if (auto err = ReleaseChannel(); !err.IsNone()) { + LOG_ERR() << "Can't release channel: err=" << err; } - } - if (stop) { - if (auto err = Stop(); !err.IsNone()) { - LOG_ERR() << "Failed to stop PB handler: err=" << err; + UniqueLock lock {mMutex}; + + mCondVar.Wait(lock, [this]() { return (mClockSynced && mProvisioned) || mClose; }); + + if (mClose) { return; } - if (auto err = mChannelManager->DeleteChannel(cSecurePort); !err.IsNone()) { - LOG_ERR() << "Failed to delete channel: err=" << err; - return; + if (auto err = SetupChannel(); !err.IsNone()) { + LOG_ERR() << "Can't setup channel: err=" << err; + LOG_DBG() << "Reconnect in " << cReconnectInterval / 1000000 << " ms"; + + if (err = mCondVar.Wait(lock, cReconnectInterval, [this] { return mClose; }); + !err.IsNone() && !err.Is(ErrorEnum::eTimeout)) { + LOG_ERR() << "Failed to wait reconnect: err=" << err; + } + + continue; } + + mCondVar.Wait(lock, [this]() { return !mClockSynced || !mProvisioned || mClose; }); } } diff --git a/src/smclient/smclient.hpp b/src/smclient/smclient.hpp index 7a739523..4018d7e7 100644 --- a/src/smclient/smclient.hpp +++ b/src/smclient/smclient.hpp @@ -153,6 +153,7 @@ class SMClient : public communication::PBHandler& data) override; - void UpdatePBHandlerState(); + Error ReleaseChannel(); + Error SetupChannel(); + void HandleChannel(); Error SendNodeConfigStatus(const String& version, const Error& configErr); Error ProcessGetNodeConfigStatus(const servicemanager_v4_GetNodeConfigStatus& pbGetNodeConfigStatus); Error ProcessCheckNodeConfig(const servicemanager_v4_CheckNodeConfig& pbCheckNodeConfig); @@ -180,9 +183,12 @@ class SMClient : public communication::PBHandler mThread; + ConditionalVariable mCondVar; + bool mClockSynced = false; + bool mProvisioned = false; + bool mClose = false; #ifndef CONFIG_ZTEST iam::certhandler::CertHandlerItf* mCertHandler {}; diff --git a/tests/smclient/src/main.cpp b/tests/smclient/src/main.cpp index 7d1be1bc..71a674e0 100644 --- a/tests/smclient/src/main.cpp +++ b/tests/smclient/src/main.cpp @@ -98,7 +98,7 @@ static aos::RetWithError InitSMClient(smclient_fixture* fixture, u fixture->mSMClient->OnClockSynced(); - auto channel = fixture->mChannelManager.GetChannel(port); + auto channel = fixture->mChannelManager.GetChannel(port, cWaitTimeout); if (!channel.mError.IsNone()) { return {nullptr, channel.mError}; } From 4641b94efb9679222e3b27a48b63a4df683ff7e3 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 11 Sep 2024 13:55:12 +0300 Subject: [PATCH 155/198] [nodeinfoprovider,monitoring] Use f_frsize instead of f_bsize for disk According to zephyr documentation f_frsize should be used for disk size estimation. Signed-off-by: Oleksandr Grytsov --- src/monitoring/resourceusageprovider.cpp | 2 +- src/nodeinfoprovider/nodeinfoprovider.cpp | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/monitoring/resourceusageprovider.cpp b/src/monitoring/resourceusageprovider.cpp index 1d05450a..17910425 100644 --- a/src/monitoring/resourceusageprovider.cpp +++ b/src/monitoring/resourceusageprovider.cpp @@ -75,7 +75,7 @@ Error ResourceUsageProvider::GetNodeMonitoringData( return AOS_ERROR_WRAP(ret); } #endif - monitoringData.mDisk[i].mUsedSize = (uint64_t)(sbuf.f_blocks - sbuf.f_bfree) * (uint64_t)sbuf.f_bsize; + monitoringData.mDisk[i].mUsedSize = (uint64_t)(sbuf.f_blocks - sbuf.f_bfree) * (uint64_t)sbuf.f_frsize; LOG_DBG() << "Disk: " << monitoringData.mDisk[i].mName << ", used size(K): " << (monitoringData.mDisk[i].mUsedSize / 1024); diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp index 8be3a479..b22bf9a8 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -178,8 +178,6 @@ Error NodeInfoProvider::InitAttributes() Error NodeInfoProvider::InitPartitionInfo() { - LOG_DBG() << "Init partition info"; - PartitionInfo partitionInfo; partitionInfo.mName = cDiskPartitionName; @@ -205,7 +203,7 @@ Error NodeInfoProvider::InitPartitionInfo() return ret; } #endif - partition.mTotalSize = sbuf.f_bsize * sbuf.f_blocks; + partition.mTotalSize = sbuf.f_frsize * sbuf.f_blocks; LOG_DBG() << "Init partition info: name=" << partition.mName << ", totalSize=" << partition.mTotalSize; } From 7e10b7b81eac9f56ea61c182bcc3d58d40bd477a Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 11 Sep 2024 13:56:20 +0300 Subject: [PATCH 156/198] [communication] Fix TLS config cleanup We should cleanup TLS config only on failure. Signed-off-by: Oleksandr Grytsov --- src/communication/tlschannel.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/communication/tlschannel.cpp b/src/communication/tlschannel.cpp index 05e7a5c5..98fe51c9 100644 --- a/src/communication/tlschannel.cpp +++ b/src/communication/tlschannel.cpp @@ -50,13 +50,9 @@ Error TLSChannel::SetTLSConfig(const String& certType) { LOG_DBG() << "Set TLS config: name=" << mName << ", certType=" << certType; - Cleanup(); - - if (certType.IsEmpty()) { - return ErrorEnum::eNone; - } - if (auto err = SetupSSLConfig(certType); !err.IsNone()) { + Cleanup(); + return err; } From c83bf4c4ff0eb21ba11553c1e1a937311aa90d13 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 11 Sep 2024 13:57:47 +0300 Subject: [PATCH 157/198] [communication] Add data size to log on receive Signed-off-by: Oleksandr Grytsov --- src/communication/pbhandler.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/communication/pbhandler.cpp b/src/communication/pbhandler.cpp index fd26946e..4b0c6e12 100644 --- a/src/communication/pbhandler.cpp +++ b/src/communication/pbhandler.cpp @@ -40,8 +40,7 @@ Error PBHandler::Start() return Error(ErrorEnum::eWrongState, "PB handler already started"); } - auto err = mThread.Run([this](void*) { Run(); }); - if (!err.IsNone()) { + if (auto err = mThread.Run([this](void*) { Run(); }); !err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -157,7 +156,7 @@ void PBHandler::Run() } if (header.mDataSize > mReceiveBuffer.Size()) { - LOG_ERR() << "Not enough mem in receive buffer: name=" << mName; + LOG_ERR() << "Not enough mem in receive buffer: name=" << mName << ", dataSize=" << header.mDataSize; continue; } From 62a4b963da5a3cca85b17676528e66cfa111264d Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 11 Sep 2024 13:59:07 +0300 Subject: [PATCH 158/198] [communication] Read/Write all requested data Signed-off-by: Oleksandr Grytsov --- src/communication/channelmanager.cpp | 97 +++++++++++++++++----------- src/communication/channelmanager.hpp | 3 +- 2 files changed, 63 insertions(+), 37 deletions(-) diff --git a/src/communication/channelmanager.cpp b/src/communication/channelmanager.cpp index f7ba3e98..805c0494 100644 --- a/src/communication/channelmanager.cpp +++ b/src/communication/channelmanager.cpp @@ -117,12 +117,19 @@ int ChannelManager::Write(uint32_t port, const void* data, size_t size) aos::UniqueLock lock {sWriteMutex}; - if (auto ret = mTransport->Write(&header.mValue, sizeof(AosProtocolHeader)); - ret < static_cast(sizeof(AosProtocolHeader))) { - return ret; + if (auto err = WriteTransport(&header.mValue, sizeof(AosProtocolHeader)); !err.IsNone()) { + LOG_ERR() << "Failed to write header: err=" << err; + + return -EIO; + } + + if (auto err = WriteTransport(data, size); !err.IsNone()) { + LOG_ERR() << "Failed to write header: err=" << err; + + return -EIO; } - return mTransport->Write(data, size); + return size; } bool ChannelManager::IsConnected() const @@ -215,49 +222,29 @@ Error ChannelManager::HandleRead() AosProtocolHeader header; - if (auto err = ReadFromTransport(header); !err.IsNone()) { + if (auto err = ReadTransport(&header, sizeof(AosProtocolHeader)); !err.IsNone()) { return err; } - if (auto err = ProcessData(header); !err.IsNone()) { - LOG_ERR() << "Failed to process data: err=" << err; + if (header.mDataSize > cReadBufferSize) { + return {ErrorEnum::eRuntime, "not enough memory in read buffer"}; } - } -} - -Error ChannelManager::ReadFromTransport(AosProtocolHeader& header) -{ - if (auto ret = mTransport->Read(&header, sizeof(AosProtocolHeader)); - ret < static_cast(sizeof(AosProtocolHeader))) { - return {ret, "failed to read header"}; - } - if (header.mDataSize > cReadBufferSize) { - return {ErrorEnum::eRuntime, "not enough memory in read buffer"}; - } - - LOG_DBG() << "Read channel: port=" << header.mPort << " size=" << header.mDataSize; - - size_t totalRead = 0; - - while (totalRead < header.mDataSize) { - size_t readSize = header.mDataSize - totalRead; - - if (auto ret = mTransport->Read(mTmpReadBuffer + totalRead, readSize); ret < static_cast(readSize)) { - return {ret, "failed to read data into local buffer"}; + if (auto err = ReadTransport(mTmpReadBuffer, header.mDataSize); !err.IsNone()) { + return err; } - totalRead += readSize; + if (auto err = ProcessData(header); !err.IsNone()) { + LOG_ERR() << "Failed to process data: err=" << err; + } } - - return ErrorEnum::eNone; } Error ChannelManager::ProcessData(const AosProtocolHeader& header) { UniqueLock lock {mMutex}; - LOG_DBG() << "Read channel: port=" << header.mPort << " size=" << header.mDataSize; + LOG_DBG() << "Process data: port=" << header.mPort << " size=" << header.mDataSize; auto [channel, err] = mChannels.At(header.mPort); if (!err.IsNone()) { @@ -274,8 +261,6 @@ Error ChannelManager::ProcessData(const AosProtocolHeader& header) return err; } - LOG_DBG() << "Request read channel: port=" << header.mPort << " size=" << size; - size = aos::Min(size, static_cast(header.mDataSize - processedSize)); memcpy(buffer, mTmpReadBuffer + processedSize, size); @@ -287,7 +272,47 @@ Error ChannelManager::ProcessData(const AosProtocolHeader& header) processedSize += size; } - LOG_DBG() << "Read channel done: port=" << header.mPort << " size=" << header.mDataSize; + return ErrorEnum::eNone; +} + +Error ChannelManager::ReadTransport(void* buffer, size_t size) +{ + size_t read = 0; + + LOG_DBG() << "Read transport: size=" << size; + + while (read < size) { + auto ret = mTransport->Read(&reinterpret_cast(buffer)[read], size - read); + if (ret < 0) { + return AOS_ERROR_WRAP(ret); + } + + read += ret; + } + + if (read != size) { + return AOS_ERROR_WRAP(Error(aos::ErrorEnum::eFailed, "read size mismatch")); + } + + return aos::ErrorEnum::eNone; +} + +Error ChannelManager::WriteTransport(const void* buffer, size_t size) +{ + size_t written = 0; + + while (written < size) { + auto ret = mTransport->Write(&reinterpret_cast(buffer)[written], size - written); + if (ret < 0) { + return AOS_ERROR_WRAP(ret); + } + + written += ret; + } + + if (written != size) { + return AOS_ERROR_WRAP(Error(aos::ErrorEnum::eFailed, "write size mismatch")); + } return ErrorEnum::eNone; } diff --git a/src/communication/channelmanager.hpp b/src/communication/channelmanager.hpp index ecd100ee..d3e42665 100644 --- a/src/communication/channelmanager.hpp +++ b/src/communication/channelmanager.hpp @@ -134,8 +134,9 @@ class ChannelManager : public ChannelManagerItf, public CommunicationItf { void CloseChannels(); Error TryConnect(); Error WaitTimeout(); - Error ReadFromTransport(AosProtocolHeader& header); Error ProcessData(const AosProtocolHeader& header); + Error ReadTransport(void* buffer, size_t size); + Error WriteTransport(const void* buffer, size_t size); aos::RetWithError PrepareHeader(uint32_t port, const aos::Array& data); From 1b37cd5fc9967ddfdfb191273aded07b5a8cbb34 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 11 Sep 2024 14:00:26 +0300 Subject: [PATCH 159/198] [app] Move storage initialization at the beginning Storage creates aos folders required to be exist for other modules. Signed-off-by: Oleksandr Grytsov --- src/app/app.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index 84abda80..9e939741 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -213,6 +213,10 @@ Error App::InitZephyr() } #endif + if (auto err = mStorage.Init(); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + if (auto err = mNodeInfoProvider.Init(); !err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -233,10 +237,6 @@ Error App::InitZephyr() return AOS_ERROR_WRAP(err); } - if (auto err = mStorage.Init(); !err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - return ErrorEnum::eNone; } From abd5d042e6ae8a3ee9c4db26f079c51ce8e26b6e Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 11 Sep 2024 14:15:36 +0300 Subject: [PATCH 160/198] [aoscoreconfig.hpp] Increase default stack size to 16k Signed-off-by: Oleksandr Grytsov --- src/aoscoreconfig.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aoscoreconfig.hpp b/src/aoscoreconfig.hpp index fca0358d..dacc227e 100644 --- a/src/aoscoreconfig.hpp +++ b/src/aoscoreconfig.hpp @@ -13,7 +13,7 @@ /** * Set thread stack size. */ -#define AOS_CONFIG_THREAD_DEFAULT_STACK_SIZE 8192 +#define AOS_CONFIG_THREAD_DEFAULT_STACK_SIZE 16384 /** * Set thread stack alignment. From ac55ae0deb8d26a4eec32c318f3721c2133ab7b4 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 11 Sep 2024 14:23:37 +0300 Subject: [PATCH 161/198] [boards] Enable little fs only for required it boards Now different boards support different fs's. Remove littlefs from common config. Signed-off-by: Oleksandr Grytsov --- boards/native_posix.conf | 4 ---- boards/native_posix_64.conf | 4 ---- boards/rcar_h3ulcb_ca57.conf | 21 ++++++++++++++++----- boards/rcar_salvator_xs_m3.conf | 21 ++++++++++++++++----- boards/rcar_spider_ca55.conf | 20 ++++++++++++++++---- prj.conf | 19 +------------------ 6 files changed, 49 insertions(+), 40 deletions(-) diff --git a/boards/native_posix.conf b/boards/native_posix.conf index eb31c679..b55a0137 100644 --- a/boards/native_posix.conf +++ b/boards/native_posix.conf @@ -47,10 +47,6 @@ CONFIG_MAX_PTHREAD_COUNT=0 CONFIG_MAX_PTHREAD_MUTEX_COUNT=0 CONFIG_MAX_THREAD_BYTES=0 -# Disable littlefs - -CONFIG_FILE_SYSTEM_LITTLEFS=n - # Disable cpu power management CONFIG_PM_CPU_OPS=n diff --git a/boards/native_posix_64.conf b/boards/native_posix_64.conf index eb31c679..b55a0137 100644 --- a/boards/native_posix_64.conf +++ b/boards/native_posix_64.conf @@ -47,10 +47,6 @@ CONFIG_MAX_PTHREAD_COUNT=0 CONFIG_MAX_PTHREAD_MUTEX_COUNT=0 CONFIG_MAX_THREAD_BYTES=0 -# Disable littlefs - -CONFIG_FILE_SYSTEM_LITTLEFS=n - # Disable cpu power management CONFIG_PM_CPU_OPS=n diff --git a/boards/rcar_h3ulcb_ca57.conf b/boards/rcar_h3ulcb_ca57.conf index f49effc2..e463d7a0 100644 --- a/boards/rcar_h3ulcb_ca57.conf +++ b/boards/rcar_h3ulcb_ca57.conf @@ -9,16 +9,27 @@ CONFIG_KERNEL_VM_SIZE=0x4000000 CONFIG_PARTIAL_DEVICE_TREE_SIZE=90000 -CONFIG_FS_LITTLEFS_FC_HEAP_SIZE=8192 -CONFIG_SHELL_STACK_SIZE=8192 - CONFIG_DISK_ACCESS=y CONFIG_DISK_DRIVERS=y CONFIG_DISK_DRIVER_MMC=y -CONFIG_FS_LITTLEFS_BLK_DEV=y - CONFIG_RCAR_MMC_SCC_SUPPORT=n CONFIG_SD_DATA_TIMEOUT=1000 CONFIG_XEN_DOM0=y + +# Configure LittleFS + +CONFIG_FILE_SYSTEM_LITTLEFS=y +CONFIG_FS_LITTLEFS_FC_HEAP_SIZE=8192 +CONFIG_FS_LITTLEFS_BLK_DEV=y +CONFIG_FS_LITTLEFS_CACHE_SIZE=512 +CONFIG_FS_LITTLEFS_LOOKAHEAD_SIZE=2048 +CONFIG_FS_LITTLEFS_NUM_FILES=8 + +# Enable FLASH + +CONFIG_FLASH=y +CONFIG_FLASH_SHELL=y +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_MAP=y diff --git a/boards/rcar_salvator_xs_m3.conf b/boards/rcar_salvator_xs_m3.conf index 2aba79cd..9fdf1809 100644 --- a/boards/rcar_salvator_xs_m3.conf +++ b/boards/rcar_salvator_xs_m3.conf @@ -9,16 +9,27 @@ CONFIG_KERNEL_VM_SIZE=0x4000000 CONFIG_PARTIAL_DEVICE_TREE_SIZE=70000 -CONFIG_FS_LITTLEFS_FC_HEAP_SIZE=8192 -CONFIG_SHELL_STACK_SIZE=8192 - CONFIG_DISK_ACCESS=y CONFIG_DISK_DRIVERS=y CONFIG_DISK_DRIVER_MMC=y -CONFIG_FS_LITTLEFS_BLK_DEV=y - CONFIG_RCAR_MMC_SCC_SUPPORT=n CONFIG_SD_DATA_TIMEOUT=1000 CONFIG_XEN_DOM0=y + +# Configure LittleFS + +CONFIG_FILE_SYSTEM_LITTLEFS=y +CONFIG_FS_LITTLEFS_FC_HEAP_SIZE=8192 +CONFIG_FS_LITTLEFS_BLK_DEV=y +CONFIG_FS_LITTLEFS_CACHE_SIZE=512 +CONFIG_FS_LITTLEFS_LOOKAHEAD_SIZE=2048 +CONFIG_FS_LITTLEFS_NUM_FILES=8 + +# Enable FLASH + +CONFIG_FLASH=y +CONFIG_FLASH_SHELL=y +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_MAP=y diff --git a/boards/rcar_spider_ca55.conf b/boards/rcar_spider_ca55.conf index 825d45a5..c45cab61 100644 --- a/boards/rcar_spider_ca55.conf +++ b/boards/rcar_spider_ca55.conf @@ -9,13 +9,25 @@ CONFIG_KERNEL_VM_SIZE=0x4000000 CONFIG_PARTIAL_DEVICE_TREE_SIZE=80000 -CONFIG_SHELL_STACK_SIZE=8192 - CONFIG_DISK_ACCESS=y -CONFIG_FS_LITTLEFS_BLK_DEV=y - CONFIG_RCAR_MMC_SCC_SUPPORT=n CONFIG_SD_DATA_TIMEOUT=1000 CONFIG_XEN_DOM0=y + +# Configure LittleFS + +CONFIG_FILE_SYSTEM_LITTLEFS=y +CONFIG_FS_LITTLEFS_FC_HEAP_SIZE=8192 +CONFIG_FS_LITTLEFS_BLK_DEV=y +CONFIG_FS_LITTLEFS_CACHE_SIZE=512 +CONFIG_FS_LITTLEFS_LOOKAHEAD_SIZE=2048 +CONFIG_FS_LITTLEFS_NUM_FILES=8 + +# Enable FLASH + +CONFIG_FLASH=y +CONFIG_FLASH_SHELL=y +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_MAP=y diff --git a/prj.conf b/prj.conf index 53495ce5..4a4a1dd8 100644 --- a/prj.conf +++ b/prj.conf @@ -116,28 +116,11 @@ CONFIG_SHELL_BACKEND_SERIAL=y CONFIG_FILE_SYSTEM=y CONFIG_FILE_SYSTEM_SHELL=y -CONFIG_FILE_SYSTEM_LITTLEFS=y - -# Configure - -CONFIG_FS_LITTLEFS_CACHE_SIZE=512 -CONFIG_FS_LITTLEFS_LOOKAHEAD_SIZE=2048 -CONFIG_FS_LITTLEFS_NUM_FILES=8 - -# Enable FLASH - -CONFIG_FLASH=y -CONFIG_FLASH_SHELL=y -CONFIG_FLASH_SIMULATOR=y -CONFIG_FLASH_MAP=y +CONFIG_FILE_SYSTEM_MKFS=y # Enable cpu power management - CONFIG_PM_CPU_OPS=y -# WA: Disable MMC_DMA to avoid z_mem_phys_add assertion -CONFIG_RCAR_MMC_DMA_SUPPORT=n - # Requires by mbedTLS for entropy. Need to be replaced with HW solution. CONFIG_TEST_RANDOM_GENERATOR=y From 019e765b2452d3483c12764ba0bb88d564022ff8 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 11 Sep 2024 14:58:59 +0300 Subject: [PATCH 162/198] [boards] Enable CONFIG_FS_FATFS_REENTRANT mode for FAT FS Signed-off-by: Oleksandr Grytsov --- boards/rpi_5.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boards/rpi_5.conf b/boards/rpi_5.conf index 47670a22..f689e993 100644 --- a/boards/rpi_5.conf +++ b/boards/rpi_5.conf @@ -14,10 +14,11 @@ CONFIG_FS_MULTI_PARTITION=y CONFIG_FILE_SYSTEM_LITTLEFS=n CONFIG_FAT_FILESYSTEM_ELM=y -CONFIG_FS_FATFS_MOUNT_MKFS=n CONFIG_FS_FATFS_EXFAT=y CONFIG_FS_FATFS_LBA64=y CONFIG_FS_FATFS_NUM_FILES=16 +CONFIG_FS_FATFS_REENTRANT=y +CONFIG_FS_FATFS_LFN_MODE_STACK=y CONFIG_DOMD_ENABLE=n From 13e3e9ca47c16dfaea61d3d911f50a27d09970c2 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 11 Sep 2024 15:05:14 +0300 Subject: [PATCH 163/198] [boards] Format rpi_5.overlay Signed-off-by: Oleksandr Grytsov --- boards/rpi_5.overlay | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/boards/rpi_5.overlay b/boards/rpi_5.overlay index d41b7eaa..798e59e0 100644 --- a/boards/rpi_5.overlay +++ b/boards/rpi_5.overlay @@ -12,21 +12,20 @@ #address-cells = <2>; #size-cells = <1>; - chosen { - zephyr,console = &xen_consoleio_hvc; - zephyr,shell-uart = &xen_consoleio_hvc; - }; - - psci { - compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci"; - method = "hvc"; - }; + chosen { + zephyr,console = &xen_consoleio_hvc; + zephyr,shell-uart = &xen_consoleio_hvc; + }; - xen_consoleio_hvc: hvc { - compatible = "xen,hvc-consoleio"; - status = "okay"; - }; + psci { + compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci"; + method = "hvc"; + }; + xen_consoleio_hvc: hvc { + compatible = "xen,hvc-consoleio"; + status = "okay"; + }; /* * This node may differs on different setups, please check @@ -62,14 +61,13 @@ reg = <0x00 0x10000000 DT_SIZE_M(128)>; }; - firmware { - tee { - compatible = "linaro,optee-tz"; - method = "smc"; - status = "okay"; + firmware { + tee { + compatible = "linaro,optee-tz"; + method = "smc"; + status = "okay"; + }; }; - }; - }; &uart10 { From 4c11d1f4c5b294fa4738eafb94bf11bdd9e5e9cb Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 11 Sep 2024 15:06:50 +0300 Subject: [PATCH 164/198] [prj.conf] Increase ISR stack to 8k Signed-off-by: Oleksandr Grytsov --- prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/prj.conf b/prj.conf index 4a4a1dd8..54228148 100644 --- a/prj.conf +++ b/prj.conf @@ -16,6 +16,7 @@ CONFIG_USERSPACE=y # Set stack size CONFIG_MAIN_STACK_SIZE=32768 +CONFIG_ISR_STACK_SIZE=8192 # Select libc CONFIG_PICOLIBC=y From 9ac64bd8716b4f6a75013fbd1966acec95312f7e Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 11 Sep 2024 15:07:30 +0300 Subject: [PATCH 165/198] [prj.conf] Disable HWINFO as not used Signed-off-by: Oleksandr Grytsov --- prj.conf | 3 --- 1 file changed, 3 deletions(-) diff --git a/prj.conf b/prj.conf index 54228148..78011191 100644 --- a/prj.conf +++ b/prj.conf @@ -24,9 +24,6 @@ CONFIG_PICOLIBC=y # Increase KOBJECT RODATA CONFIG_KOBJECT_RODATA_AREA_EXTRA_BYTES=2048 -# Enable hardware info -CONFIG_HWINFO=y - # ###################################################################################################################### # Enable C++ # ###################################################################################################################### From 9fbbc36bf2f51dabb09b74d73bf982c9f36bf7d6 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 11 Sep 2024 15:08:19 +0300 Subject: [PATCH 166/198] [prj.conf] Increase CONFIG_MAX_PTHREAD_MUTEX_COUNT to 128 Signed-off-by: Oleksandr Grytsov --- prj.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prj.conf b/prj.conf index 78011191..c7395bcc 100644 --- a/prj.conf +++ b/prj.conf @@ -61,7 +61,7 @@ CONFIG_PTHREAD_IPC=y CONFIG_POSIX_API=y CONFIG_POSIX_FS=y CONFIG_MAX_PTHREAD_COUNT=16 -CONFIG_MAX_PTHREAD_MUTEX_COUNT=64 +CONFIG_MAX_PTHREAD_MUTEX_COUNT=128 CONFIG_MAX_PTHREAD_COND_COUNT=32 CONFIG_MAX_THREAD_BYTES=3 From 2f052fc55612cdca49d4ffa2f380b65877eb3cd9 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 11 Sep 2024 15:09:54 +0300 Subject: [PATCH 167/198] [prj.conf] Increase shell stack and buffers Signed-off-by: Oleksandr Grytsov --- prj.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/prj.conf b/prj.conf index c7395bcc..fe2b8057 100644 --- a/prj.conf +++ b/prj.conf @@ -109,6 +109,9 @@ CONFIG_NANOPB=y CONFIG_SHELL=y CONFIG_SHELL_BACKEND_SERIAL=y +CONFIG_SHELL_CMD_BUFF_SIZE=512 +CONFIG_SHELL_STACK_SIZE=8192 +CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE=512 # Enable file system From 5dbaa230e2af18b49304263dce44cfab11a92e89 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 12 Sep 2024 10:04:29 +0300 Subject: [PATCH 168/198] [bsp] Mount tmpfs as second partition to /2: Signed-off-by: Oleksandr Grytsov --- boards/rpi_5.conf | 2 +- boards/rpi_5.overlay | 7 ++++++ src/bsp/mount_fatfs.c | 51 +++++++++++++++++++++++-------------------- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/boards/rpi_5.conf b/boards/rpi_5.conf index f689e993..520b5903 100644 --- a/boards/rpi_5.conf +++ b/boards/rpi_5.conf @@ -25,7 +25,7 @@ CONFIG_DOMD_ENABLE=n CONFIG_OPTEE_STORAGE_ROOT="/1:/tee" CONFIG_AOS_STORAGE_DIR="/1:/aos/storage" -CONFIG_AOS_RUNTIME_DIR="/1:/tmp/aos/runtime" +CONFIG_AOS_RUNTIME_DIR="/2:/tmp/aos/runtime" CONFIG_AOS_SERVICES_DIR="/1:/aos/services" CONFIG_AOS_NODE_CONFIG_FILE="/1:/aos/node_config.cfg" CONFIG_AOS_DISK_MOUNT_POINT="/1:" diff --git a/boards/rpi_5.overlay b/boards/rpi_5.overlay index 798e59e0..9b65fd5c 100644 --- a/boards/rpi_5.overlay +++ b/boards/rpi_5.overlay @@ -68,6 +68,13 @@ status = "okay"; }; }; + + ramdisk0 { + compatible = "zephyr,ram-disk"; + disk-name = "RAM"; + sector-size = <512>; + sector-count = <128>; + }; }; &uart10 { diff --git a/src/bsp/mount_fatfs.c b/src/bsp/mount_fatfs.c index eb75e25d..1500cfc4 100644 --- a/src/bsp/mount_fatfs.c +++ b/src/bsp/mount_fatfs.c @@ -8,21 +8,30 @@ #include "mount.h" -#define DISK_DRIVE_NAME CONFIG_SDMMC_VOLUME_NAME +#define DISK_DRIVE_NAME CONFIG_SDMMC_VOLUME_NAME +#define DISK_TMP_MOUNT_PT "/2:" -static FATFS fat_fs; +static FATFS fat_fs_aos; +static FATFS fat_fs_tmp; /* mounting info */ -static struct fs_mount_t mp = { - .type = FS_FATFS, - .fs_data = &fat_fs, +static struct fs_mount_t mp_aos = { + .type = FS_FATFS, + .fs_data = &fat_fs_aos, + .mnt_point = CONFIG_AOS_DISK_MOUNT_POINT, +}; + +static struct fs_mount_t mp_tmp = { + .type = FS_FATFS, + .fs_data = &fat_fs_tmp, + .mnt_point = DISK_TMP_MOUNT_PT, }; #if defined(CONFIG_FS_MULTI_PARTITION) PARTITION VolToPart[FF_VOLUMES] = { - [0] = {3, 1}, /* "0:" ==> 1st partition on the pd#0 */ - [1] = {3, 2}, /* "1:" ==> 2nd partition on the pd#0 */ - [2] = {0, -1}, /* "2:" ==> 3rd partition on the pd#0 */ + [0] = {3, 1}, /* "0:" ==> 1st partition on the pd#3 (SD) */ + [1] = {3, 2}, /* "1:" ==> 2nd partition on the pd#3 (SD) */ + [2] = {0, 0}, /* "2:" ==> 1rd partition on the pd#0 (RAM) */ [3] = {0, -1}, [4] = {0, -1}, [5] = {0, -1}, @@ -35,43 +44,37 @@ int fatfs_mount() { printk("Mounting fatfs..."); - uint32_t block_count; - uint32_t block_size; - int ret = disk_access_init(DISK_DRIVE_NAME); if (ret) { - printk("[fatfs] access init failed (%d)\n", ret); + printk("[fatfs] Access init failed (%d)\n", ret); return ret; } - ret = disk_access_ioctl(DISK_DRIVE_NAME, DISK_IOCTL_GET_SECTOR_COUNT, &block_count); + ret = fs_mount(&mp_aos); if (ret) { - printk("[fatfs] get sector count failed (%d)\n", ret); + printk("[fatfs] Aos disk mount failed (%d)\n", ret); return ret; } - ret = disk_access_ioctl(DISK_DRIVE_NAME, DISK_IOCTL_GET_SECTOR_SIZE, &block_size); + printk("[fatfs] Aos disk mounted at %s\n", CONFIG_AOS_DISK_MOUNT_POINT); + + ret = fs_mount(&mp_tmp); if (ret) { - printk("[fatfs] get sector size failed (%d)\n", ret); + printk("[fatfs] TMP disk mount failed (%d)\n", ret); return ret; } - mp.mnt_point = CONFIG_AOS_DISK_MOUNT_POINT; + printk("[fatfs] TMP disk mounted at %s\n", DISK_TMP_MOUNT_PT); - ret = fs_mount(&mp); + ret = fs_mkdir(DISK_TMP_MOUNT_PT "/tmp"); if (ret) { - printk("[fatfs] mount failed (%d)\n", ret); + printk("[fatfs] TMP folder create failed (%d)\n", ret); return ret; } - uint64_t memory_size_mb = (uint64_t)block_count * block_size; - - printk("[fatfs] Mounted %s, block count=%u, Sector size=%u, Memory Size(MB)=%u\n", CONFIG_AOS_DISK_MOUNT_POINT, - block_count, block_size, (uint32_t)(memory_size_mb >> 20)); - return 0; } From cf94fb64f705871c5aa463880e61be976c2bb5f8 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 13 Sep 2024 17:40:25 +0300 Subject: [PATCH 169/198] [Kconfig] Increase default stack size for launcher and pbhandler Signed-off-by: Oleksandr Grytsov --- Kconfig | 4 ++-- boards/native_posix.conf | 2 -- boards/native_posix_64.conf | 2 -- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Kconfig b/Kconfig index 9698900b..03647872 100644 --- a/Kconfig +++ b/Kconfig @@ -115,11 +115,11 @@ config AOS_SOCKET_SERVER_PORT config AOS_PBHANDLER_THREAD_STACK_SIZE int "Aos PB handler stack size" - default 16384 + default 32768 config AOS_LAUNCHER_THREAD_STACK_SIZE int "Aos launcher stack size" - default 16384 + default 32768 config DOMD_ENABLE bool "Enable Domain-D creation" diff --git a/boards/native_posix.conf b/boards/native_posix.conf index b55a0137..50eff750 100644 --- a/boards/native_posix.conf +++ b/boards/native_posix.conf @@ -85,8 +85,6 @@ CONFIG_AOS_HSM_DIR=".aos/hsm" CONFIG_AOS_NODE_STATUS_FILE=".aos/.nodestatus" CONFIG_AOS_NODE_ID_FILE=".aos/node-id" CONFIG_AOS_PKCS11_MODULE_PIN_FILE=".aos/.pkcs11pin" -CONFIG_AOS_PBHANDLER_THREAD_STACK_SIZE=32768 -CONFIG_AOS_LAUNCHER_THREAD_STACK_SIZE=32768 # Disable OP-TEE driver and client libraries # TEE is not supported by this platform diff --git a/boards/native_posix_64.conf b/boards/native_posix_64.conf index b55a0137..50eff750 100644 --- a/boards/native_posix_64.conf +++ b/boards/native_posix_64.conf @@ -85,8 +85,6 @@ CONFIG_AOS_HSM_DIR=".aos/hsm" CONFIG_AOS_NODE_STATUS_FILE=".aos/.nodestatus" CONFIG_AOS_NODE_ID_FILE=".aos/node-id" CONFIG_AOS_PKCS11_MODULE_PIN_FILE=".aos/.pkcs11pin" -CONFIG_AOS_PBHANDLER_THREAD_STACK_SIZE=32768 -CONFIG_AOS_LAUNCHER_THREAD_STACK_SIZE=32768 # Disable OP-TEE driver and client libraries # TEE is not supported by this platform From e2d0081ca8e22eec0fd5ee03cc1737f745544cd1 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 13 Sep 2024 17:41:24 +0300 Subject: [PATCH 170/198] [logger] Add possibility to configure Aos core log levels runtime Signed-off-by: Oleksandr Grytsov --- Kconfig | 4 ++ prj.conf | 7 +++ src/logger/logger.cpp | 131 +++++++++++++++++++++--------------------- src/logger/logger.hpp | 19 +++++- src/main.cpp | 5 +- 5 files changed, 98 insertions(+), 68 deletions(-) diff --git a/Kconfig b/Kconfig index 03647872..5d6ec90c 100644 --- a/Kconfig +++ b/Kconfig @@ -151,4 +151,8 @@ config DOMU_DTB_PATH config TA_DEPLOY_DIR string "Location of optee TA's deploy dir" +module = AOS_CORE +module-str = Aos core +source "subsys/logging/Kconfig.template.log_config" + source "Kconfig" diff --git a/prj.conf b/prj.conf index fe2b8057..439bea47 100644 --- a/prj.conf +++ b/prj.conf @@ -38,6 +38,7 @@ CONFIG_STD_CPP17=y # Enable logging CONFIG_LOG=y +CONFIG_LOG_CMDS=y CONFIG_LOG_FUNC_NAME_PREFIX_ERR=n CONFIG_LOG_FUNC_NAME_PREFIX_WRN=n CONFIG_LOG_FUNC_NAME_PREFIX_INF=n @@ -49,6 +50,12 @@ CONFIG_LOG_BUFFER_SIZE=8192 # Disable FS log to avoid errors duplication. We catch them by Aos errors. CONFIG_FS_LOG_LEVEL_OFF=y +# Disable pthread cond log. It displays error on cond wait with timeout. +CONFIG_PTHREAD_COND_LOG_LEVEL_OFF=y + +# Set Aos log level +CONFIG_AOS_CORE_LOG_LEVEL_DBG=y + # Enable assert for debugging purposes # TODO: remove for release CONFIG_ASSERT=y diff --git a/src/logger/logger.cpp b/src/logger/logger.cpp index 1d290be8..72891b66 100644 --- a/src/logger/logger.cpp +++ b/src/logger/logger.cpp @@ -7,7 +7,7 @@ #include -#ifdef CONFIG_NATIVE_APPLICATION +#if CONFIG_NATIVE_APPLICATION #include #endif @@ -16,28 +16,10 @@ namespace aos::zephyr::logger { /*********************************************************************************************************************** - * Consts + * Static **********************************************************************************************************************/ -static const String cLogModuleApp = "app"; -static const String cLogModuleClockSync = "clocksync"; -static const String cLogModuleCommunication = "communication"; -static const String cLogModuleDownloader = "downloader"; -static const String cLogModuleIAMClient = "iamclient"; -static const String cLogModuleNodeInfoProvider = "nodeinfoprovider"; -static const String cLogModuleOCISpec = "ocispec"; -static const String cLogModuleProvisionManager = "provisionmanager"; -static const String cLogModuleResourceManager = "resourcemanager"; -static const String cLogModuleRunner = "runner"; -static const String cLogModuleSMClient = "smclient"; -static const String cLogModuleStorage = "storage"; - -static const String cLogModuleCerthandler = "certhandler"; -static const String cLogModuleCrypto = "crypto"; -static const String cLogModuleLauncher = "launcher"; -static const String cLogModuleMonitoring = "monitoring"; -static const String cLogModulePKCS11 = "pkcs11"; -static const String cLogModuleServiceManager = "servicemanager"; +StaticMap Logger::sLogCallbacks; /*********************************************************************************************************************** * Log module callbacks @@ -46,7 +28,7 @@ static const String cLogModuleServiceManager = "servicemanager"; #define LOG_CALLBACK(name) \ namespace log_##name \ { \ - LOG_MODULE_REGISTER(name, CONFIG_LOG_DEFAULT_LEVEL); \ + LOG_MODULE_REGISTER(name, CONFIG_AOS_CORE_LOG_LEVEL); \ \ static void LogCallback(LogLevel level, const String& message) \ { \ @@ -105,13 +87,42 @@ LOG_CALLBACK(servicemanager); * Public **********************************************************************************************************************/ -void Logger::Init() +Error Logger::Init() { Log::SetCallback(LogCallback); + + sLogCallbacks.Set("app", &log_app::LogCallback); + sLogCallbacks.Set("certhandler", &log_certhandler::LogCallback); + sLogCallbacks.Set("clocksync", &log_clocksync::LogCallback); + sLogCallbacks.Set("communication", &log_communication::LogCallback); + sLogCallbacks.Set("crypto", &log_crypto::LogCallback); + sLogCallbacks.Set("downloader", &log_downloader::LogCallback); + sLogCallbacks.Set("iamclient", &log_iamclient::LogCallback); + sLogCallbacks.Set("launcher", &log_launcher::LogCallback); + sLogCallbacks.Set("monitoring", &log_monitoring::LogCallback); + sLogCallbacks.Set("nodeinfoprovider", &log_nodeinfoprovider::LogCallback); + sLogCallbacks.Set("ocispec", &log_ocispec::LogCallback); + sLogCallbacks.Set("pkcs11", &log_pkcs11::LogCallback); + sLogCallbacks.Set("provisionmanager", &log_provisionmanager::LogCallback); + sLogCallbacks.Set("resourcemanager", &log_resourcemanager::LogCallback); + sLogCallbacks.Set("runner", &log_runner::LogCallback); + sLogCallbacks.Set("servicemanager", &log_servicemanager::LogCallback); + sLogCallbacks.Set("smclient", &log_smclient::LogCallback); + sLogCallbacks.Set("storage", &log_storage::LogCallback); + +#if CONFIG_LOG_RUNTIME_FILTERING + for (auto& [module, _] : sLogCallbacks) { + if (auto err = SetLogLevel(module, cRuntimeLogLevel); !err.IsNone()) { + return err; + } + } +#endif + + return ErrorEnum::eNone; } /*********************************************************************************************************************** - * Public + * Private **********************************************************************************************************************/ void Logger::LogCallback(const String& module, LogLevel level, const String& message) @@ -122,48 +133,38 @@ void Logger::LogCallback(const String& module, LogLevel level, const String& mes LockGuard lock(sMutex); #endif - String logModule(module); - - if (logModule == cLogModuleApp) { - log_app::LogCallback(level, message); - } else if (logModule == cLogModuleCommunication) { - log_communication::LogCallback(level, message); - } else if (logModule == cLogModuleClockSync) { - log_clocksync::LogCallback(level, message); - } else if (logModule == cLogModuleDownloader) { - log_downloader::LogCallback(level, message); - } else if (logModule == cLogModuleOCISpec) { - log_ocispec::LogCallback(level, message); - } else if (logModule == cLogModuleProvisionManager) { - log_provisionmanager::LogCallback(level, message); - } else if (logModule == cLogModuleResourceManager) { - log_resourcemanager::LogCallback(level, message); - } else if (logModule == cLogModuleRunner) { - log_runner::LogCallback(level, message); - } else if (logModule == cLogModuleSMClient) { - log_smclient::LogCallback(level, message); - } else if (logModule == cLogModuleIAMClient) { - log_iamclient::LogCallback(level, message); - } else if (logModule == cLogModuleStorage) { - log_storage::LogCallback(level, message); - } else if (logModule == cLogModuleNodeInfoProvider) { - log_nodeinfoprovider::LogCallback(level, message); - } else if (logModule == cLogModuleCerthandler) { - log_certhandler::LogCallback(level, message); - } else if (logModule == cLogModuleCrypto) { - log_crypto::LogCallback(level, message); - } else if (logModule == cLogModuleLauncher) { - log_launcher::LogCallback(level, message); - } else if (logModule == cLogModuleMonitoring) { - log_monitoring::LogCallback(level, message); - } else if (logModule == cLogModuleServiceManager) { - log_servicemanager::LogCallback(level, message); - } else if (logModule == cLogModulePKCS11) { - log_pkcs11::LogCallback(level, message); - } else { - LOG_MODULE_WRN(cLogModuleCommunication.CStr()) - << "Log from unknown module received: module=" << module << ", level=" << level << ", message=" << message; + auto [callback, err] = sLogCallbacks.At(module); + if (!err.IsNone()) { + LOG_MODULE_WRN("app") << "Log from unknown module received: module=" << module << ", level=" << level + << ", message=" << message; + return; } + + callback(level, message); } +#if CONFIG_LOG_RUNTIME_FILTERING +Error Logger::SetLogLevel(const String& module, int level) +{ + auto sourceID = log_source_id_get(module.CStr()); + if (sourceID < 0) { + return AOS_ERROR_WRAP(ErrorEnum::eNotFound); + } + + for (int i = 0; i < log_backend_count_get(); i++) { + auto backend = log_backend_get(i); + + if (!log_backend_is_active(backend)) { + continue; + } + + if (auto ret = log_filter_set(backend, Z_LOG_LOCAL_DOMAIN_ID, sourceID, level); ret < 0) { + return AOS_ERROR_WRAP(ret); + } + } + + return ErrorEnum::eNone; +} +#endif + } // namespace aos::zephyr::logger diff --git a/src/logger/logger.hpp b/src/logger/logger.hpp index 3ce1afe2..5f2acc7c 100644 --- a/src/logger/logger.hpp +++ b/src/logger/logger.hpp @@ -8,7 +8,12 @@ #ifndef LOGGER_HPP_ #define LOGGER_HPP_ +#if CONFIG_LOG_RUNTIME_FILTERING +#include +#endif + #include +#include namespace aos::zephyr::logger { @@ -19,11 +24,23 @@ class Logger { public: /** * Inits logging system. + * + * return Error. */ - static void Init(); + static Error Init(); private: + static constexpr auto cMaxLogModules = 32; +#if CONFIG_LOG_RUNTIME_FILTERING + static constexpr auto cRuntimeLogLevel = LOG_LEVEL_INF; +#endif + static void LogCallback(const String& module, LogLevel level, const String& message); +#if CONFIG_LOG_RUNTIME_FILTERING + static Error SetLogLevel(const String& module, int level); +#endif + + static StaticMap sLogCallbacks; }; } // namespace aos::zephyr::logger diff --git a/src/main.cpp b/src/main.cpp index a19f6d4c..07aede4c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,7 +47,8 @@ int main(void) __ASSERT(ret == 0, "Error creating domains: %s [%d]", strerror(ret), ret); #endif - logger::Logger::Init(); + auto err = logger::Logger::Init(); + __ASSERT(err.IsNone(), "Error initializing logger: %s", utils::ErrorToCStr(err)); auto& app = aos::zephyr::app::App::Get(); @@ -64,7 +65,7 @@ int main(void) _exit(0); }); - auto err = app.Init(); + err = app.Init(); __ASSERT(err.IsNone(), "Error initializing application: %s", utils::ErrorToCStr(err)); err = app.Start(); From 1aad8a07a79d535103e966c4260ced2f346fd85b Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Mon, 23 Sep 2024 13:05:27 +0300 Subject: [PATCH 171/198] [smclient] Rename mDisk to mPartitions Signed-off-by: Mykhailo Lohvynenko --- src/smclient/smclient.cpp | 8 ++++---- tests/smclient/src/main.cpp | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index 1f378bd5..d2982b33 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -34,13 +34,13 @@ static void MonitoringDataToPB(const monitoring::MonitoringData& monitoringData, pbMonitoringData.ram = monitoringData.mRAM; pbMonitoringData.download = monitoringData.mDownload; pbMonitoringData.upload = monitoringData.mUpload; - pbMonitoringData.partitions_count = monitoringData.mDisk.Size(); + pbMonitoringData.partitions_count = monitoringData.mPartitions.Size(); pbMonitoringData.has_timestamp = true; pbMonitoringData.timestamp = TimestampToPB(timestamp); - for (size_t i = 0; i < monitoringData.mDisk.Size(); i++) { - utils::StringFromCStr(pbMonitoringData.partitions[i].name) = monitoringData.mDisk[i].mName; - pbMonitoringData.partitions[i].used_size = monitoringData.mDisk[i].mUsedSize; + for (size_t i = 0; i < monitoringData.mPartitions.Size(); i++) { + utils::StringFromCStr(pbMonitoringData.partitions[i].name) = monitoringData.mPartitions[i].mName; + pbMonitoringData.partitions[i].used_size = monitoringData.mPartitions[i].mUsedSize; } } diff --git a/tests/smclient/src/main.cpp b/tests/smclient/src/main.cpp index 71a674e0..66318ba3 100644 --- a/tests/smclient/src/main.cpp +++ b/tests/smclient/src/main.cpp @@ -115,11 +115,11 @@ static void PBToMonitoringData( { aosMonitoring.mRAM = pbMonitoring.ram; aosMonitoring.mCPU = pbMonitoring.cpu; - aosMonitoring.mDisk.Resize(pbMonitoring.partitions_count); + aosMonitoring.mPartitions.Resize(pbMonitoring.partitions_count); for (size_t i = 0; i < pbMonitoring.partitions_count; i++) { - aosMonitoring.mDisk[i].mName = utils::StringFromCStr(pbMonitoring.partitions[i].name); - aosMonitoring.mDisk[i].mUsedSize = pbMonitoring.partitions[i].used_size; + aosMonitoring.mPartitions[i].mName = utils::StringFromCStr(pbMonitoring.partitions[i].name); + aosMonitoring.mPartitions[i].mUsedSize = pbMonitoring.partitions[i].used_size; } aosMonitoring.mDownload = pbMonitoring.download; From 051953eccdfa017cdc3fe26c150a903e528dfd54 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Mon, 23 Sep 2024 13:05:42 +0300 Subject: [PATCH 172/198] [monitoring] Rename mDisk to mPartitions Signed-off-by: Mykhailo Lohvynenko --- src/monitoring/resourceusageprovider.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/monitoring/resourceusageprovider.cpp b/src/monitoring/resourceusageprovider.cpp index 17910425..4590dee7 100644 --- a/src/monitoring/resourceusageprovider.cpp +++ b/src/monitoring/resourceusageprovider.cpp @@ -61,24 +61,24 @@ Error ResourceUsageProvider::GetNodeMonitoringData( mPrevNodeCPUTime = domain.cpu_ns; mPrevTime = curTime; - for (size_t i = 0; i < monitoringData.mDisk.Size(); ++i) { + for (size_t i = 0; i < monitoringData.mPartitions.Size(); ++i) { #ifdef CONFIG_NATIVE_APPLICATION struct statvfs sbuf; - if (ret = statvfs(monitoringData.mDisk[i].mPath.CStr(), &sbuf); ret != 0) { + if (ret = statvfs(monitoringData.mPartitions[i].mPath.CStr(), &sbuf); ret != 0) { return ret; } #else struct fs_statvfs sbuf; - if (ret = fs_statvfs(monitoringData.mDisk[i].mPath.CStr(), &sbuf); ret != 0) { + if (ret = fs_statvfs(monitoringData.mPartitions[i].mPath.CStr(), &sbuf); ret != 0) { return AOS_ERROR_WRAP(ret); } #endif - monitoringData.mDisk[i].mUsedSize = (uint64_t)(sbuf.f_blocks - sbuf.f_bfree) * (uint64_t)sbuf.f_frsize; + monitoringData.mPartitions[i].mUsedSize = (uint64_t)(sbuf.f_blocks - sbuf.f_bfree) * (uint64_t)sbuf.f_frsize; - LOG_DBG() << "Disk: " << monitoringData.mDisk[i].mName - << ", used size(K): " << (monitoringData.mDisk[i].mUsedSize / 1024); + LOG_DBG() << "Partition: " << monitoringData.mPartitions[i].mName + << ", used size(K): " << (monitoringData.mPartitions[i].mUsedSize / 1024); } return ErrorEnum::eNone; From e189774e2295e53fc979ac4ec0d6871b17d0b90a Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Tue, 1 Oct 2024 15:31:21 +0300 Subject: [PATCH 173/198] [ci] Make tests output verbose Signed-off-by: Oleksandr Grytsov --- .github/workflows/build_test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_test.yaml b/.github/workflows/build_test.yaml index 582061ec..16640f95 100644 --- a/.github/workflows/build_test.yaml +++ b/.github/workflows/build_test.yaml @@ -69,12 +69,12 @@ jobs: - name: Test ${{ matrix.platform }} if: ${{ matrix.platform == 'native_posix' }} run: | - west twister -c -v -p ${{ matrix.platform }} -T tests + west twister -c -v -p ${{ matrix.platform }} -T tests -v - name: Test ${{ matrix.platform }} if: ${{ matrix.platform == 'native_posix_64' }} run: | - west twister -c -v -p ${{ matrix.platform }} --coverage --coverage-basedir src/ --coverage-tool gcovr -T tests + west twister -c -v -p ${{ matrix.platform }} --coverage --coverage-basedir src/ --coverage-tool gcovr -T tests -v gcovr twister-out/${{ matrix.platform }}/ -f src/ --xml-pretty > ./coverage.xml - name: Upload codecov report From 18a2e784efd254074f44797419bdba2ff1f42f82 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 2 Oct 2024 13:10:37 +0300 Subject: [PATCH 174/198] [ci] Use container zephyrprojectrtos/ci:v0.26.14 Latest release breaks the build. Signed-off-by: Oleksandr Grytsov --- .github/workflows/build_test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_test.yaml b/.github/workflows/build_test.yaml index 16640f95..a5b93ffd 100644 --- a/.github/workflows/build_test.yaml +++ b/.github/workflows/build_test.yaml @@ -13,7 +13,7 @@ on: jobs: build: runs-on: ubuntu-latest - container: zephyrprojectrtos/ci:latest + container: zephyrprojectrtos/ci:v0.26.14 env: CMAKE_PREFIX_PATH: /opt/toolchains From a43362b92221fdf55bf258a999b04b8fb7fd826e Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Mon, 7 Oct 2024 11:34:51 +0300 Subject: [PATCH 175/198] [ocispec] Parsed/encode memKB as uint64 Signed-off-by: Mykhailo Lohvynenko --- src/ocispec/ocispec.cpp | 29 ++++------------------------- src/ocispec/ocispec.hpp | 2 +- tests/ocispec/CMakeLists.txt | 2 +- tests/ocispec/src/main.cpp | 10 +++++++--- 4 files changed, 13 insertions(+), 30 deletions(-) diff --git a/src/ocispec/ocispec.cpp b/src/ocispec/ocispec.cpp index a28a8820..fa41ccbb 100644 --- a/src/ocispec/ocispec.cpp +++ b/src/ocispec/ocispec.cpp @@ -69,7 +69,7 @@ static const struct json_obj_descr VMHWConfigIOMEMDescr[] = { static const struct json_obj_descr VMHWConfigDescr[] = { JSON_OBJ_DESCR_PRIM(VMHWConfig, deviceTree, JSON_TOK_STRING), JSON_OBJ_DESCR_PRIM(VMHWConfig, vcpus, JSON_TOK_NUMBER), - JSON_OBJ_DESCR_PRIM(VMHWConfig, memKB, JSON_TOK_FLOAT), + JSON_OBJ_DESCR_PRIM(VMHWConfig, memKB, JSON_TOK_UINT64), JSON_OBJ_DESCR_ARRAY(VMHWConfig, dtdevs, oci::cMaxDTDevsCount, dtdevsLen, JSON_TOK_STRING), JSON_OBJ_DESCR_OBJ_ARRAY( VMHWConfig, iomems, oci::cMaxIOMEMsCount, iomemsLen, VMHWConfigIOMEMDescr, ARRAY_SIZE(VMHWConfigIOMEMDescr)), @@ -407,20 +407,7 @@ Error OCISpec::LoadRuntimeSpec(const String& path, oci::RuntimeSpec& runtimeSpec runtimeSpec.mVM->mHWConfig.mDeviceTree = jsonRuntimeSpec->vm.hwConfig.deviceTree; runtimeSpec.mVM->mHWConfig.mVCPUs = jsonRuntimeSpec->vm.hwConfig.vcpus; - - uint64_t memKB = 0; - - if (jsonRuntimeSpec->vm.hwConfig.memKB.start) { - auto result = String(jsonRuntimeSpec->vm.hwConfig.memKB.start, jsonRuntimeSpec->vm.hwConfig.memKB.length) - .ToUint64(); - if (!result.mError.IsNone()) { - return AOS_ERROR_WRAP(result.mError); - } - - memKB = result.mValue; - } - - runtimeSpec.mVM->mHWConfig.mMemKB = memKB; + runtimeSpec.mVM->mHWConfig.mMemKB = jsonRuntimeSpec->vm.hwConfig.memKB; for (size_t i = 0; i < jsonRuntimeSpec->vm.hwConfig.dtdevsLen; i++) { runtimeSpec.mVM->mHWConfig.mDTDevs.PushBack(jsonRuntimeSpec->vm.hwConfig.dtdevs[i]); @@ -503,15 +490,7 @@ Error OCISpec::SaveRuntimeSpec(const String& path, const oci::RuntimeSpec& runti jsonRuntimeSpec->vm.hwConfig.deviceTree = runtimeSpec.mVM->mHWConfig.mDeviceTree.CStr(); jsonRuntimeSpec->vm.hwConfig.vcpus = runtimeSpec.mVM->mHWConfig.mVCPUs; - - auto memKB = new (&mAllocator) StaticString<20>; - - auto err = memKB->Convert(runtimeSpec.mVM->mHWConfig.mMemKB); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - jsonRuntimeSpec->vm.hwConfig.memKB = {const_cast(memKB->CStr()), memKB->Size()}; + jsonRuntimeSpec->vm.hwConfig.memKB = runtimeSpec.mVM->mHWConfig.mMemKB; jsonRuntimeSpec->vm.hwConfig.dtdevsLen = runtimeSpec.mVM->mHWConfig.mDTDevs.Size(); @@ -526,7 +505,7 @@ Error OCISpec::SaveRuntimeSpec(const String& path, const oci::RuntimeSpec& runti auto firstGFN = new (&mAllocator) StaticString<20>; - err = firstGFN->Convert(iomem.mFirstGFN); + auto err = firstGFN->Convert(iomem.mFirstGFN); if (!err.IsNone()) { return AOS_ERROR_WRAP(err); } diff --git a/src/ocispec/ocispec.hpp b/src/ocispec/ocispec.hpp index 87aa2da2..270e5892 100644 --- a/src/ocispec/ocispec.hpp +++ b/src/ocispec/ocispec.hpp @@ -105,7 +105,7 @@ struct VMHWConfigIOMEM { struct VMHWConfig { const char* deviceTree; uint32_t vcpus; - json_obj_token memKB; + uint64_t memKB; const char* dtdevs[oci::cMaxDTDevsCount]; size_t dtdevsLen; VMHWConfigIOMEM iomems[oci::cMaxIOMEMsCount]; diff --git a/tests/ocispec/CMakeLists.txt b/tests/ocispec/CMakeLists.txt index 2daaaa5c..6b1de233 100644 --- a/tests/ocispec/CMakeLists.txt +++ b/tests/ocispec/CMakeLists.txt @@ -37,4 +37,4 @@ zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src) # Target # ###################################################################################################################### -target_sources(app PRIVATE src/main.cpp ../../src/ocispec/ocispec.cpp) +target_sources(app PRIVATE src/main.cpp ../../src/ocispec/ocispec.cpp ../utils/log.cpp) diff --git a/tests/ocispec/src/main.cpp b/tests/ocispec/src/main.cpp index 6a5b1bc8..be1e6b0b 100644 --- a/tests/ocispec/src/main.cpp +++ b/tests/ocispec/src/main.cpp @@ -12,6 +12,8 @@ #include +#include "utils/log.hpp" + using namespace aos::zephyr; /*********************************************************************************************************************** @@ -90,6 +92,8 @@ aos::Error WriteFile(const aos::String& path, const void* data, size_t size) static void* Setup(void) { + aos::Log::SetCallback(TestLogCallback); + zassert_true(aos::FS::MakeDirAll("/tmp/aos").IsNone(), "Can't create test folder"); return nullptr; @@ -485,7 +489,7 @@ ZTEST(ocispec, test_RuntimeSpec) { "path2", 3, - 5, + 18446744073709551615UL, aos::Array>(dtdevs, aos::ArraySize(dtdevs)), aos::Array(iomems, aos::ArraySize(iomems)), aos::Array(irqs, aos::ArraySize(irqs)), @@ -542,7 +546,7 @@ ZTEST(ocispec, test_RuntimeSpec) R"({"ociVersion":"1.0.0","vm":{)" R"("hypervisor":{"path":"path0","parameters":["hyp0","hyp1","hyp2"]},)" R"("kernel":{"path":"path1","parameters":["krnl0","krnl1"]},)" - R"("hwConfig":{"deviceTree":"path2","vcpus":3,"memKB":5,)" + R"("hwConfig":{"deviceTree":"path2","vcpus":3,"memKB":18446744073709551615,)" R"("dtdevs":["dev0","dev1","dev2","dev3"],)" R"("iomems":[{"firstGFN":0,"firstMFN":1,"nrMFNs":2},{"firstGFN":3,"firstMFN":4,"nrMFNs":5}],)" R"("irqs":[1,2,3,4,5]}}})", @@ -639,7 +643,7 @@ ZTEST(ocispec, test_RuntimeSpec) R"({"ociVersion":"1.0.0","vm":{)" R"("hypervisor":{"path":"path0","parameters":["hyp0","hyp1","hyp2"],"extraHypervisor":"1234"},)" R"("kernel":{"path":"path1","parameters":["krnl0","krnl1"],"extraKernel":"1234"},)" - R"("hwConfig":{"deviceTree":"path2","vcpus":3,"memKB":5,)" + R"("hwConfig":{"deviceTree":"path2","vcpus":3,"memKB":18446744073709551615,)" R"("dtdevs":["dev0","dev1","dev2","dev3"],)" R"("iomems":[{"firstGFN":0,"firstMFN":1,"nrMFNs":2},{"firstGFN":3,"firstMFN":4,"nrMFNs":5}],)" R"("irqs":[1,2,3,4,5]},"extraHWConfig":"1234"},)" From 8aeb0ac08a19c9e2082504d3f828bb8a7e2dc229 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Mon, 7 Oct 2024 11:42:21 +0300 Subject: [PATCH 176/198] [ocispec] Parsed/encode vm hw config iomem as uint64 Signed-off-by: Mykhailo Lohvynenko --- src/ocispec/ocispec.cpp | 66 +++++++---------------------------------- src/ocispec/ocispec.hpp | 6 ++-- 2 files changed, 14 insertions(+), 58 deletions(-) diff --git a/src/ocispec/ocispec.cpp b/src/ocispec/ocispec.cpp index fa41ccbb..a624acea 100644 --- a/src/ocispec/ocispec.cpp +++ b/src/ocispec/ocispec.cpp @@ -61,9 +61,9 @@ static const struct json_obj_descr VMKernelDescr[] = { }; static const struct json_obj_descr VMHWConfigIOMEMDescr[] = { - JSON_OBJ_DESCR_PRIM(VMHWConfigIOMEM, firstGFN, JSON_TOK_FLOAT), - JSON_OBJ_DESCR_PRIM(VMHWConfigIOMEM, firstMFN, JSON_TOK_FLOAT), - JSON_OBJ_DESCR_PRIM(VMHWConfigIOMEM, nrMFNs, JSON_TOK_FLOAT), + JSON_OBJ_DESCR_PRIM(VMHWConfigIOMEM, firstGFN, JSON_TOK_UINT64), + JSON_OBJ_DESCR_PRIM(VMHWConfigIOMEM, firstMFN, JSON_TOK_UINT64), + JSON_OBJ_DESCR_PRIM(VMHWConfigIOMEM, nrMFNs, JSON_TOK_UINT64), }; static const struct json_obj_descr VMHWConfigDescr[] = { @@ -415,34 +415,11 @@ Error OCISpec::LoadRuntimeSpec(const String& path, oci::RuntimeSpec& runtimeSpec for (size_t i = 0; i < jsonRuntimeSpec->vm.hwConfig.iomemsLen; i++) { oci::VMHWConfigIOMEM ioMem {}; - auto jsonIOMem = jsonRuntimeSpec->vm.hwConfig.iomems[i]; + auto& jsonIOMem = jsonRuntimeSpec->vm.hwConfig.iomems[i]; - if (jsonIOMem.firstGFN.start) { - auto result = String(jsonIOMem.firstGFN.start, jsonIOMem.firstGFN.length).ToUint64(); - if (!result.mError.IsNone()) { - return AOS_ERROR_WRAP(result.mError); - } - - ioMem.mFirstGFN = result.mValue; - } - - if (jsonIOMem.firstMFN.start) { - auto result = String(jsonIOMem.firstMFN.start, jsonIOMem.firstMFN.length).ToUint64(); - if (!result.mError.IsNone()) { - return AOS_ERROR_WRAP(result.mError); - } - - ioMem.mFirstMFN = result.mValue; - } - - if (jsonIOMem.nrMFNs.start) { - auto result = String(jsonIOMem.nrMFNs.start, jsonIOMem.nrMFNs.length).ToUint64(); - if (!result.mError.IsNone()) { - return AOS_ERROR_WRAP(result.mError); - } - - ioMem.mNrMFNs = result.mValue; - } + ioMem.mFirstGFN = jsonIOMem.firstGFN; + ioMem.mFirstMFN = jsonIOMem.firstMFN; + ioMem.mNrMFNs = jsonIOMem.nrMFNs; runtimeSpec.mVM->mHWConfig.mIOMEMs.PushBack(ioMem); } @@ -501,33 +478,12 @@ Error OCISpec::SaveRuntimeSpec(const String& path, const oci::RuntimeSpec& runti jsonRuntimeSpec->vm.hwConfig.iomemsLen = runtimeSpec.mVM->mHWConfig.mIOMEMs.Size(); for (size_t i = 0; i < jsonRuntimeSpec->vm.hwConfig.iomemsLen; i++) { - auto iomem = runtimeSpec.mVM->mHWConfig.mIOMEMs[i]; - - auto firstGFN = new (&mAllocator) StaticString<20>; - - auto err = firstGFN->Convert(iomem.mFirstGFN); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - auto firstMFN = new (&mAllocator) StaticString<20>; - - err = firstMFN->Convert(iomem.mFirstMFN); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - auto nrMFNs = new (&mAllocator) StaticString<20>; - - err = nrMFNs->Convert(iomem.mNrMFNs); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } + auto& iomem = runtimeSpec.mVM->mHWConfig.mIOMEMs[i]; jsonRuntimeSpec->vm.hwConfig.iomems[i] = { - {const_cast(firstGFN->CStr()), firstGFN->Size()}, - {const_cast(firstMFN->CStr()), firstMFN->Size()}, - {const_cast(nrMFNs->CStr()), nrMFNs->Size()}, + iomem.mFirstGFN, + iomem.mFirstMFN, + iomem.mNrMFNs, }; } diff --git a/src/ocispec/ocispec.hpp b/src/ocispec/ocispec.hpp index 270e5892..593ef68f 100644 --- a/src/ocispec/ocispec.hpp +++ b/src/ocispec/ocispec.hpp @@ -94,9 +94,9 @@ struct VMKernel { * Contains information about IOMEMs. */ struct VMHWConfigIOMEM { - json_obj_token firstGFN; - json_obj_token firstMFN; - json_obj_token nrMFNs; + uint64_t firstGFN; + uint64_t firstMFN; + uint64_t nrMFNs; }; /** From 7af641cf7aaa16dba233165eff2dc4ffab00ae16 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Mon, 7 Oct 2024 11:59:51 +0300 Subject: [PATCH 177/198] [ocispec] Parsed/encode content desc size as uint64 Signed-off-by: Mykhailo Lohvynenko --- src/ocispec/ocispec.cpp | 90 ++++++++++---------------------------- src/ocispec/ocispec.hpp | 6 +-- tests/ocispec/src/main.cpp | 2 +- 3 files changed, 27 insertions(+), 71 deletions(-) diff --git a/src/ocispec/ocispec.cpp b/src/ocispec/ocispec.cpp index a624acea..8cd43907 100644 --- a/src/ocispec/ocispec.cpp +++ b/src/ocispec/ocispec.cpp @@ -24,7 +24,7 @@ namespace aos::zephyr::ocispec { const struct json_obj_descr ContentDescriptorDescr[] = { JSON_OBJ_DESCR_PRIM(ContentDescriptor, mediaType, JSON_TOK_STRING), JSON_OBJ_DESCR_PRIM(ContentDescriptor, digest, JSON_TOK_STRING), - JSON_OBJ_DESCR_PRIM(ContentDescriptor, size, JSON_TOK_FLOAT), + JSON_OBJ_DESCR_PRIM(ContentDescriptor, size, JSON_TOK_UINT64), }; const struct json_obj_descr ImageManifestDescr[] = { @@ -125,35 +125,20 @@ Error OCISpec::LoadImageManifest(const String& path, oci::ImageManifest& manifes // config - int64_t size = 0; - - if (jsonImageManifest->config.size.start) { - auto configSize = String(jsonImageManifest->config.size.start, jsonImageManifest->config.size.length).ToInt64(); - if (!configSize.mError.IsNone()) { - return AOS_ERROR_WRAP(configSize.mError); - } - - size = configSize.mValue; - } - - manifest.mConfig = {jsonImageManifest->config.mediaType, jsonImageManifest->config.digest, size}; + manifest.mConfig = { + jsonImageManifest->config.mediaType, + jsonImageManifest->config.digest, + jsonImageManifest->config.size, + }; // layers for (size_t i = 0; i < jsonImageManifest->layersLen; i++) { - size = 0; - - if (jsonImageManifest->layers[i].size.start) { - auto layerSize - = String(jsonImageManifest->layers[i].size.start, jsonImageManifest->layers[i].size.length).ToInt64(); - if (!layerSize.mError.IsNone()) { - return AOS_ERROR_WRAP(layerSize.mError); - } - - size = layerSize.mValue; - } - - manifest.mLayers.PushBack({jsonImageManifest->layers[i].mediaType, jsonImageManifest->layers[i].digest, size}); + manifest.mLayers.PushBack({ + jsonImageManifest->layers[i].mediaType, + jsonImageManifest->layers[i].digest, + jsonImageManifest->layers[i].size, + }); } // aosService @@ -163,19 +148,11 @@ Error OCISpec::LoadImageManifest(const String& path, oci::ImageManifest& manifes return AOS_ERROR_WRAP(ErrorEnum::eNoMemory); } - size = 0; - - if (jsonImageManifest->aosService.size.start) { - auto serviceSize - = String(jsonImageManifest->aosService.size.start, jsonImageManifest->aosService.size.length).ToInt64(); - if (!serviceSize.mError.IsNone()) { - return AOS_ERROR_WRAP(serviceSize.mError); - } - - size = serviceSize.mValue; - } - - *manifest.mAosService = {jsonImageManifest->aosService.mediaType, jsonImageManifest->aosService.digest, size}; + *manifest.mAosService = { + jsonImageManifest->aosService.mediaType, + jsonImageManifest->aosService.digest, + jsonImageManifest->aosService.size, + }; } return ErrorEnum::eNone; @@ -201,44 +178,23 @@ Error OCISpec::SaveImageManifest(const String& path, const oci::ImageManifest& m // config - auto configSize = new (&mAllocator) StaticString<20>; - - auto err = configSize->Convert(manifest.mConfig.mSize); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - jsonImageManifest->config = {manifest.mConfig.mMediaType.CStr(), manifest.mConfig.mDigest.CStr(), - {const_cast(configSize->CStr()), configSize->Size()}}; + jsonImageManifest->config + = {manifest.mConfig.mMediaType.CStr(), manifest.mConfig.mDigest.CStr(), manifest.mConfig.mSize}; // layers jsonImageManifest->layersLen = manifest.mLayers.Size(); for (size_t i = 0; i < jsonImageManifest->layersLen; i++) { - auto layerSize = new (&mAllocator) StaticString<20>; - - err = layerSize->Convert(manifest.mLayers[i].mSize); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - jsonImageManifest->layers[i] = {manifest.mLayers[i].mMediaType.CStr(), manifest.mLayers[i].mDigest.CStr(), - {const_cast(layerSize->CStr()), layerSize->Size()}}; + jsonImageManifest->layers[i] + = {manifest.mLayers[i].mMediaType.CStr(), manifest.mLayers[i].mDigest.CStr(), manifest.mLayers[i].mSize}; } // aosService if (manifest.mAosService) { - auto serviceSize = new (&mAllocator) StaticString<20>; - - err = serviceSize->Convert(manifest.mAosService->mSize); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - jsonImageManifest->aosService = {manifest.mAosService->mMediaType.CStr(), manifest.mAosService->mDigest.CStr(), - {const_cast(serviceSize->CStr()), serviceSize->Size()}}; + jsonImageManifest->aosService = { + manifest.mAosService->mMediaType.CStr(), manifest.mAosService->mDigest.CStr(), manifest.mAosService->mSize}; } auto ret = json_obj_encode_buf(ImageManifestDescr, ARRAY_SIZE(ImageManifestDescr), jsonImageManifest, @@ -247,7 +203,7 @@ Error OCISpec::SaveImageManifest(const String& path, const oci::ImageManifest& m return AOS_ERROR_WRAP(ret); } - err = mJsonFileContent.Resize(strlen(mJsonFileContent.CStr())); + auto err = mJsonFileContent.Resize(strlen(mJsonFileContent.CStr())); if (!err.IsNone()) { return AOS_ERROR_WRAP(err); } diff --git a/src/ocispec/ocispec.hpp b/src/ocispec/ocispec.hpp index 593ef68f..62bd65a8 100644 --- a/src/ocispec/ocispec.hpp +++ b/src/ocispec/ocispec.hpp @@ -23,9 +23,9 @@ namespace aos::zephyr::ocispec { */ struct ContentDescriptor { - const char* mediaType; - const char* digest; - json_obj_token size; + const char* mediaType; + const char* digest; + uint64_t size; }; /** diff --git a/tests/ocispec/src/main.cpp b/tests/ocispec/src/main.cpp index be1e6b0b..cc2cc014 100644 --- a/tests/ocispec/src/main.cpp +++ b/tests/ocispec/src/main.cpp @@ -273,7 +273,7 @@ ZTEST(ocispec, test_ImageManifest) aos::oci::ImageManifest fullManifest = {1, "mediaType1", {"mediaType2", "digest2"}, {}, &fullAosService}; - for (auto i = 0; i < aos::cMaxNumLayers; i++) { + for (size_t i = 0; i < aos::cMaxNumLayers; i++) { fullManifest.mLayers.PushBack({"layerType", "layerDigest", i}); } From 393bd6b5c4b431dcfd2aef47366fdcda89f7614b Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Mon, 4 Nov 2024 11:37:44 +0200 Subject: [PATCH 178/198] [cmake] Update aos lib names Signed-off-by: Mykhailo Lohvynenko --- CMakeLists.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 192f564d..cbfb1fd0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -231,8 +231,8 @@ ExternalProject_Add( -DCMAKE_CXX_FLAGS=${aos_cxx_flags} -DWITH_MBEDTLS=OFF SOURCE_DIR ${aoscore_source_dir} - BUILD_BYPRODUCTS ${aoscore_build_dir}/lib/libaossmcpp.a ${aoscore_build_dir}/lib/libaosiamcpp.a - ${aoscore_build_dir}/lib/libaoscommoncpp.a + BUILD_BYPRODUCTS ${aoscore_build_dir}/lib/libaossm.a ${aoscore_build_dir}/lib/libaosiam.a + ${aoscore_build_dir}/lib/libaoscommon.a DEPENDS zephyr_interface ) @@ -244,7 +244,7 @@ add_library(aossm STATIC IMPORTED GLOBAL) add_dependencies(aossm aoscore) -set_target_properties(aossm PROPERTIES IMPORTED_LOCATION ${aoscore_build_dir}/lib/libaossmcpp.a) +set_target_properties(aossm PROPERTIES IMPORTED_LOCATION ${aoscore_build_dir}/lib/libaossm.a) set_target_properties(aossm PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${aoscore_build_dir}/include) target_link_libraries(app PUBLIC aossm) @@ -255,7 +255,7 @@ add_library(aosiam STATIC IMPORTED GLOBAL) add_dependencies(aosiam aoscore) -set_target_properties(aosiam PROPERTIES IMPORTED_LOCATION ${aoscore_build_dir}/lib/libaosiamcpp.a) +set_target_properties(aosiam PROPERTIES IMPORTED_LOCATION ${aoscore_build_dir}/lib/libaosiam.a) set_target_properties(aosiam PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${aoscore_build_dir}/include) target_link_libraries(app PUBLIC aosiam) @@ -266,7 +266,7 @@ add_library(aoscommon STATIC IMPORTED GLOBAL) add_dependencies(aoscommon aoscore) -set_target_properties(aoscommon PROPERTIES IMPORTED_LOCATION ${aoscore_build_dir}/lib/libaoscommoncpp.a) +set_target_properties(aoscommon PROPERTIES IMPORTED_LOCATION ${aoscore_build_dir}/lib/libaoscommon.a) set_target_properties(aoscommon PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${aoscore_build_dir}/include) target_link_libraries(app PUBLIC aoscommon) From bc3462b9d5ef95c96bbf5bddf8fd80e62c468311 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Mon, 4 Nov 2024 11:39:31 +0200 Subject: [PATCH 179/198] [tests,communication] Add cert changed methods Signed-off-by: Mykhailo Lohvynenko --- .../communication/src/stubs/certhandlerstub.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/communication/src/stubs/certhandlerstub.hpp b/tests/communication/src/stubs/certhandlerstub.hpp index 7c40c4a4..129a0702 100644 --- a/tests/communication/src/stubs/certhandlerstub.hpp +++ b/tests/communication/src/stubs/certhandlerstub.hpp @@ -79,6 +79,22 @@ class CertHandlerStub : public aos::iam::certhandler::CertHandlerItf { return aos::ErrorEnum::eNone; } + aos::Error SubscribeCertChanged( + const aos::String& certType, aos::iam::certhandler::CertReceiverItf& certReceiver) override + { + (void)certType; + (void)certReceiver; + + return aos::ErrorEnum::eNone; + } + + aos::Error UnsubscribeCertChanged(aos::iam::certhandler::CertReceiverItf& certReceiver) override + { + (void)certReceiver; + + return aos::ErrorEnum::eNone; + } + aos::Error CreateSelfSignedCert(const aos::String& certType, const aos::String& password) override { return aos::ErrorEnum::eNone; From 8fc697e00c2e8399c0636cf219848c49940be243 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Mon, 4 Nov 2024 11:39:52 +0200 Subject: [PATCH 180/198] [tests,iamclient] Add cert changed methods Signed-off-by: Mykhailo Lohvynenko --- .../iamclient/src/stubs/provisionmanagerstub.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/iamclient/src/stubs/provisionmanagerstub.hpp b/tests/iamclient/src/stubs/provisionmanagerstub.hpp index ef7bcc36..8b7b3652 100644 --- a/tests/iamclient/src/stubs/provisionmanagerstub.hpp +++ b/tests/iamclient/src/stubs/provisionmanagerstub.hpp @@ -48,6 +48,22 @@ class ProvisionManagerStub : public aos::iam::provisionmanager::ProvisionManager return aos::ErrorEnum::eNone; } + aos::Error SubscribeCertChanged( + const aos::String& certType, aos::iam::certhandler::CertReceiverItf& certReceiver) override + { + (void)certType; + (void)certReceiver; + + return aos::ErrorEnum::eNone; + } + + aos::Error UnsubscribeCertChanged(aos::iam::certhandler::CertReceiverItf& certReceiver) override + { + (void)certReceiver; + + return aos::ErrorEnum::eNone; + } + aos::Error FinishProvisioning(const aos::String& password) override { mPassword = password; From c272f1cb17b7f928f8af30dc5eee42310e028072 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Fri, 4 Oct 2024 14:26:46 +0300 Subject: [PATCH 181/198] [resourcemanager] Parse all node config JSON fields Signed-off-by: Mykhailo Lohvynenko --- src/resourcemanager/resourcemanager.cpp | 300 +++++++++++++++++++++++- src/resourcemanager/resourcemanager.hpp | 8 +- tests/resourcemanager/src/main.cpp | 244 +++++++++++++++++-- 3 files changed, 523 insertions(+), 29 deletions(-) diff --git a/src/resourcemanager/resourcemanager.cpp b/src/resourcemanager/resourcemanager.cpp index f109503d..470704e1 100644 --- a/src/resourcemanager/resourcemanager.cpp +++ b/src/resourcemanager/resourcemanager.cpp @@ -16,21 +16,292 @@ namespace aos::zephyr::resourcemanager { * Static **********************************************************************************************************************/ +namespace { + +/** + * Device. + */ +struct Device { + const char* name; + const char* hostDevices[aos::cMaxNumHostDevices]; + size_t hostDevicesLen; + int sharedCount; + const char* groups[aos::cMaxNumGroups]; + size_t groupsLen; +}; + +/** + * FS mount. + */ +struct FSMount { + const char* destination; + const char* source; + const char* type; + const char* options[aos::cFSMountMaxNumOptions]; + size_t optionsLen; +}; + +/** + * Host. + */ +struct Host { + const char* ip; + const char* hostName; +}; + +/** + * Resource. + */ +struct Resource { + const char* name; + const char* groups[aos::cMaxNumGroups]; + size_t groupsLen; + FSMount mounts[aos::cMaxNumFSMounts]; + size_t mountsLen; + const char* env[aos::cMaxNumEnvVariables]; + size_t envLen; + Host hosts[aos::cMaxNumHosts]; + size_t hostsLen; +}; + /** * Node config. */ struct NodeConfig { - const char* version = ""; - const char* nodeType = ""; - uint32_t priority = 0; + // cppcheck-suppress unusedStructMember + const char* version; + // cppcheck-suppress unusedStructMember + const char* nodeType; + Device devices[aos::cMaxNumDevices]; + size_t devicesLen; + Resource resources[aos::cMaxNumNodeResources]; + size_t resourcesLen; + // cppcheck-suppress unusedStructMember + const char* labels[aos::cMaxNumNodeLabels]; + // cppcheck-suppress unusedStructMember + size_t labelsLen; + // cppcheck-suppress unusedStructMember + uint32_t priority; }; +} // namespace + +/** + * Device json object descriptor. + */ +static const struct json_obj_descr cDeviceDescr[] = { + JSON_OBJ_DESCR_PRIM(Device, name, JSON_TOK_STRING), + JSON_OBJ_DESCR_ARRAY(Device, hostDevices, aos::cMaxNumHostDevices, hostDevicesLen, JSON_TOK_STRING), + JSON_OBJ_DESCR_PRIM(Device, sharedCount, JSON_TOK_NUMBER), + JSON_OBJ_DESCR_ARRAY(Device, groups, aos::cMaxNumGroups, groupsLen, JSON_TOK_STRING), +}; + +/** + * FS mount json object descriptor. + */ +static const struct json_obj_descr cFSMountDescr[] = { + JSON_OBJ_DESCR_PRIM(FSMount, destination, JSON_TOK_STRING), + JSON_OBJ_DESCR_PRIM(FSMount, source, JSON_TOK_STRING), + JSON_OBJ_DESCR_PRIM(FSMount, type, JSON_TOK_STRING), + JSON_OBJ_DESCR_ARRAY(FSMount, options, aos::cFSMountMaxNumOptions, optionsLen, JSON_TOK_STRING), +}; + +/** + * Host json object descriptor. + */ +static const struct json_obj_descr cHostDescr[] = { + JSON_OBJ_DESCR_PRIM(Host, ip, JSON_TOK_STRING), + JSON_OBJ_DESCR_PRIM(Host, hostName, JSON_TOK_STRING), +}; + +/** + * Resource json object descriptor. + */ +static const struct json_obj_descr cResourceDescr[] = { + JSON_OBJ_DESCR_PRIM(Resource, name, JSON_TOK_STRING), + JSON_OBJ_DESCR_ARRAY(Resource, groups, aos::cMaxNumGroups, groupsLen, JSON_TOK_STRING), + JSON_OBJ_DESCR_OBJ_ARRAY( + Resource, mounts, aos::cMaxNumFSMounts, mountsLen, cFSMountDescr, ARRAY_SIZE(cFSMountDescr)), + JSON_OBJ_DESCR_ARRAY(Resource, env, aos::cMaxNumEnvVariables, envLen, JSON_TOK_STRING), + JSON_OBJ_DESCR_OBJ_ARRAY(Resource, hosts, aos::cMaxNumHosts, hostsLen, cHostDescr, ARRAY_SIZE(cHostDescr)), +}; + +/** + * Node config json object descriptor. + */ static const struct json_obj_descr cNodeConfigDescr[] = { JSON_OBJ_DESCR_PRIM(NodeConfig, version, JSON_TOK_STRING), JSON_OBJ_DESCR_PRIM(NodeConfig, nodeType, JSON_TOK_STRING), + JSON_OBJ_DESCR_OBJ_ARRAY( + NodeConfig, devices, aos::cMaxNumDevices, devicesLen, cDeviceDescr, ARRAY_SIZE(cDeviceDescr)), + JSON_OBJ_DESCR_OBJ_ARRAY( + NodeConfig, resources, aos::cMaxNumNodeResources, resourcesLen, cResourceDescr, ARRAY_SIZE(cResourceDescr)), + JSON_OBJ_DESCR_ARRAY(NodeConfig, labels, aos::cMaxNumNodeLabels, labelsLen, JSON_TOK_STRING), JSON_OBJ_DESCR_PRIM(NodeConfig, priority, JSON_TOK_NUMBER), }; +/*********************************************************************************************************************** + * Private + **********************************************************************************************************************/ + +static void FillJSONStruct(const Array& inDevices, NodeConfig& jsonNodeConfig) +{ + jsonNodeConfig.devicesLen = inDevices.Size(); + + for (size_t i = 0; i < inDevices.Size(); ++i) { + const auto& inDevice = inDevices[i]; + auto& jsonDevice = jsonNodeConfig.devices[i]; + + jsonDevice.name = inDevice.mName.CStr(); + jsonDevice.sharedCount = inDevice.mSharedCount; + jsonDevice.groupsLen = inDevice.mGroups.Size(); + jsonDevice.hostDevicesLen = inDevice.mHostDevices.Size(); + + for (size_t j = 0; j < inDevice.mGroups.Size(); ++j) { + jsonDevice.groups[j] = inDevice.mGroups[j].CStr(); + } + + for (size_t j = 0; j < inDevice.mHostDevices.Size(); ++j) { + jsonDevice.hostDevices[j] = inDevice.mHostDevices[j].CStr(); + } + } +} + +static void FillJSONStruct(const Array& inResources, NodeConfig& jsonNodeConfig) +{ + jsonNodeConfig.resourcesLen = inResources.Size(); + + for (size_t i = 0; i < inResources.Size(); ++i) { + const auto& inResource = inResources[i]; + auto& jsonResource = jsonNodeConfig.resources[i]; + + jsonResource.name = inResource.mName.CStr(); + jsonResource.groupsLen = inResource.mGroups.Size(); + + for (size_t j = 0; j < inResource.mGroups.Size(); ++j) { + jsonResource.groups[j] = inResource.mGroups[j].CStr(); + } + + jsonResource.mountsLen = inResource.mMounts.Size(); + + for (size_t j = 0; j < inResource.mMounts.Size(); ++j) { + const auto& inMount = inResource.mMounts[j]; + auto& outMount = jsonResource.mounts[j]; + + outMount.destination = inMount.mDestination.CStr(); + outMount.source = inMount.mSource.CStr(); + outMount.type = inMount.mType.CStr(); + outMount.optionsLen = inMount.mOptions.Size(); + + for (size_t k = 0; k < inMount.mOptions.Size(); ++k) { + outMount.options[k] = inMount.mOptions[k].CStr(); + } + } + + jsonResource.envLen = inResource.mEnv.Size(); + + for (size_t j = 0; j < inResource.mEnv.Size(); ++j) { + jsonResource.env[j] = inResource.mEnv[j].CStr(); + } + + jsonResource.hostsLen = inResource.mHosts.Size(); + + for (size_t j = 0; j < inResource.mHosts.Size(); ++j) { + const auto& inHost = inResource.mHosts[j]; + auto& outHost = jsonResource.hosts[j]; + + outHost.ip = inHost.mIP.CStr(); + outHost.hostName = inHost.mHostname.CStr(); + } + } +} + +static Error FillAosStruct(const NodeConfig& in, Array& outDevices) +{ + if (auto err = outDevices.Resize(in.devicesLen); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + for (size_t i = 0; i < in.devicesLen; ++i) { + const auto& inDeviceInfo = in.devices[i]; + DeviceInfo& outDeviceInfo = outDevices[i]; + + outDeviceInfo.mName = inDeviceInfo.name; + outDeviceInfo.mSharedCount = inDeviceInfo.sharedCount; + + for (size_t j = 0; j < inDeviceInfo.groupsLen; ++j) { + if (auto err = outDeviceInfo.mGroups.PushBack(inDeviceInfo.groups[j]); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + } + + for (size_t j = 0; j < inDeviceInfo.hostDevicesLen; ++j) { + if (auto err = outDeviceInfo.mHostDevices.PushBack(inDeviceInfo.hostDevices[j]); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + } + } + + return ErrorEnum::eNone; +} + +static Error FillAosStruct(const NodeConfig& in, Array& outResources) +{ + if (auto err = outResources.Resize(in.resourcesLen); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + for (size_t i = 0; i < in.resourcesLen; ++i) { + const auto& inResourceInfo = in.resources[i]; + ResourceInfo& outResourceInfo = outResources[i]; + + outResourceInfo.mName = inResourceInfo.name; + + for (size_t j = 0; j < inResourceInfo.groupsLen; ++j) { + if (auto err = outResourceInfo.mGroups.PushBack(inResourceInfo.groups[j]); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + } + + if (auto err = outResourceInfo.mMounts.Resize(inResourceInfo.mountsLen); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + for (size_t j = 0; j < inResourceInfo.mountsLen; ++j) { + const auto& parsedMount = inResourceInfo.mounts[j]; + + aos::FileSystemMount& mount = outResourceInfo.mMounts[j]; + + mount.mDestination = parsedMount.destination; + mount.mType = parsedMount.type; + mount.mSource = parsedMount.source; + + for (size_t k = 0; k < parsedMount.optionsLen; ++k) { + if (auto err = mount.mOptions.PushBack(parsedMount.options[k]); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + } + } + + for (size_t j = 0; j < inResourceInfo.envLen; ++j) { + if (auto err = outResourceInfo.mEnv.PushBack(inResourceInfo.env[j]); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + } + + if (auto err = outResourceInfo.mHosts.Resize(inResourceInfo.hostsLen); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + for (size_t j = 0; j < inResourceInfo.hostsLen; ++j) { + outResourceInfo.mHosts[j].mIP = inResourceInfo.hosts[j].ip; + outResourceInfo.mHosts[j].mHostname = inResourceInfo.hosts[j].hostName; + } + } + + return ErrorEnum::eNone; +} + /*********************************************************************************************************************** * JSONProvider **********************************************************************************************************************/ @@ -48,6 +319,14 @@ Error JSONProvider::DumpNodeConfig(const sm::resourcemanager::NodeConfig& config jsonNodeConfig->nodeType = config.mNodeConfig.mNodeType.CStr(); jsonNodeConfig->priority = config.mNodeConfig.mPriority; + FillJSONStruct(config.mNodeConfig.mDevices, *jsonNodeConfig); + FillJSONStruct(config.mNodeConfig.mResources, *jsonNodeConfig); + + jsonNodeConfig->labelsLen = config.mNodeConfig.mLabels.Size(); + for (size_t i = 0; i < config.mNodeConfig.mLabels.Size(); ++i) { + jsonNodeConfig->labels[i] = config.mNodeConfig.mLabels[i].CStr(); + } + auto ret = json_obj_encode_buf( cNodeConfigDescr, ARRAY_SIZE(cNodeConfigDescr), jsonNodeConfig.Get(), json.Get(), json.MaxSize()); if (ret < 0) { @@ -70,6 +349,7 @@ Error JSONProvider::ParseNodeConfig(const String& json, sm::resourcemanager::Nod mJSONBuffer = json; auto parsedNodeConfig = MakeUnique(&mAllocator); + *parsedNodeConfig = {}; auto ret = json_obj_parse( mJSONBuffer.Get(), mJSONBuffer.Size(), cNodeConfigDescr, ARRAY_SIZE(cNodeConfigDescr), parsedNodeConfig.Get()); @@ -81,6 +361,20 @@ Error JSONProvider::ParseNodeConfig(const String& json, sm::resourcemanager::Nod config.mNodeConfig.mNodeType = parsedNodeConfig->nodeType; config.mNodeConfig.mPriority = parsedNodeConfig->priority; + if (auto err = FillAosStruct(*parsedNodeConfig, config.mNodeConfig.mDevices); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + if (auto err = FillAosStruct(*parsedNodeConfig, config.mNodeConfig.mResources); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + for (size_t i = 0; i < parsedNodeConfig->labelsLen; ++i) { + if (auto err = config.mNodeConfig.mLabels.PushBack(parsedNodeConfig->labels[i]); !err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + } + return ErrorEnum::eNone; } diff --git a/src/resourcemanager/resourcemanager.hpp b/src/resourcemanager/resourcemanager.hpp index 2159800c..f424ae69 100644 --- a/src/resourcemanager/resourcemanager.hpp +++ b/src/resourcemanager/resourcemanager.hpp @@ -39,11 +39,9 @@ class JSONProvider : public sm::resourcemanager::JSONProviderItf { Error ParseNodeConfig(const String& json, sm::resourcemanager::NodeConfig& config) const override; private: - static constexpr size_t cJsonMaxContentLen = 1024; - - mutable Mutex mMutex; - mutable StaticString mJSONBuffer; - mutable StaticAllocator mAllocator; + mutable Mutex mMutex; + mutable StaticString mJSONBuffer; + mutable StaticAllocator mAllocator; }; /** diff --git a/tests/resourcemanager/src/main.cpp b/tests/resourcemanager/src/main.cpp index 0a6d8598..65bdcd58 100644 --- a/tests/resourcemanager/src/main.cpp +++ b/tests/resourcemanager/src/main.cpp @@ -7,7 +7,6 @@ #include -#include #include #include @@ -22,42 +21,245 @@ using namespace aos::zephyr; * Consts **********************************************************************************************************************/ -static constexpr auto cTestNodeConfigJSON = R"({"nodeType":"mainType","priority":1,"version":"1.0.0"})"; +static constexpr auto cTestNodeConfigJSON = R"({ + "devices": [ + { + "groups": [ + "group1", + "group2" + ], + "hostDevices": [ + "hostDevice1", + "hostDevice2" + ], + "name": "device1", + "sharedCount": 1 + }, + { + "groups": [ + "group3", + "group4" + ], + "hostDevices": [ + "hostDevice3", + "hostDevice4" + ], + "name": "device2", + "sharedCount": 2 + } + ], + "resources": [ + { + "name": "resource1", + "groups": ["g1", "g2"], + "mounts": [ + { + "destination": "d1", + "type": "type1", + "source": "source1", + "options": ["option1", "option2"] + }, + { + "destination": "d2", + "type": "type2", + "source": "source2", + "options": ["option3", "option4"] + } + ], + "env": ["env1", "env2"], + "hosts": [ + { + "ip": "10.0.0.100", + "hostName": "host1" + }, + { + "ip": "10.0.0.101", + "hostName": "host2" + } + ] + }, + { + "name": "resource2", + "groups": ["g3", "g4"], + "mounts": [ + { + "destination": "d3", + "type": "type3", + "source": "source3", + "options": ["option5", "option6"] + }, + { + "destination": "d4", + "type": "type4", + "source": "source4", + "options": ["option7", "option8"] + } + ], + "env": ["env3", "env4"], + "hosts": [ + { + "ip": "10.0.0.102", + "hostName": "host3" + }, + { + "ip": "10.0.0.103", + "hostName": "host4" + } + ] + } + ], + "labels": [ + "mainNode" + ], + "nodeType": "mainType", + "priority": 1, + "version": "1.0.0" +} + +)"; + +/*********************************************************************************************************************** + * Static + **********************************************************************************************************************/ + +static aos::sm::resourcemanager::NodeConfig CreateNodeConfig() +{ + aos::sm::resourcemanager::NodeConfig nodeConfig; + + nodeConfig.mVersion = "1.0.0"; + nodeConfig.mNodeConfig.mPriority = 1; + nodeConfig.mNodeConfig.mNodeType = "mainType"; + + nodeConfig.mNodeConfig.mDevices.Resize(2); + + nodeConfig.mNodeConfig.mDevices[0].mName = "device1"; + nodeConfig.mNodeConfig.mDevices[0].mSharedCount = 1; + nodeConfig.mNodeConfig.mDevices[0].mGroups.PushBack("group1"); + nodeConfig.mNodeConfig.mDevices[0].mGroups.PushBack("group2"); + nodeConfig.mNodeConfig.mDevices[0].mHostDevices.PushBack("hostDevice1"); + nodeConfig.mNodeConfig.mDevices[0].mHostDevices.PushBack("hostDevice2"); + + nodeConfig.mNodeConfig.mDevices[1].mName = "device2"; + nodeConfig.mNodeConfig.mDevices[1].mSharedCount = 2; + nodeConfig.mNodeConfig.mDevices[1].mGroups.PushBack("group3"); + nodeConfig.mNodeConfig.mDevices[1].mGroups.PushBack("group4"); + nodeConfig.mNodeConfig.mDevices[1].mHostDevices.PushBack("hostDevice3"); + nodeConfig.mNodeConfig.mDevices[1].mHostDevices.PushBack("hostDevice4"); + + nodeConfig.mNodeConfig.mResources.Resize(2); + + nodeConfig.mNodeConfig.mResources[0].mName = "resource1"; + nodeConfig.mNodeConfig.mResources[0].mGroups.PushBack("g1"); + nodeConfig.mNodeConfig.mResources[0].mGroups.PushBack("g2"); + + nodeConfig.mNodeConfig.mResources[0].mMounts.Resize(2); + nodeConfig.mNodeConfig.mResources[0].mMounts[0].mDestination = "d1"; + nodeConfig.mNodeConfig.mResources[0].mMounts[0].mType = "type1"; + nodeConfig.mNodeConfig.mResources[0].mMounts[0].mSource = "source1"; + nodeConfig.mNodeConfig.mResources[0].mMounts[0].mOptions.PushBack("option1"); + nodeConfig.mNodeConfig.mResources[0].mMounts[0].mOptions.PushBack("option2"); + + nodeConfig.mNodeConfig.mResources[0].mMounts[1].mDestination = "d2"; + nodeConfig.mNodeConfig.mResources[0].mMounts[1].mType = "type2"; + nodeConfig.mNodeConfig.mResources[0].mMounts[1].mSource = "source2"; + nodeConfig.mNodeConfig.mResources[0].mMounts[1].mOptions.PushBack("option3"); + nodeConfig.mNodeConfig.mResources[0].mMounts[1].mOptions.PushBack("option4"); + + nodeConfig.mNodeConfig.mResources[0].mEnv.PushBack("env1"); + nodeConfig.mNodeConfig.mResources[0].mEnv.PushBack("env2"); + + nodeConfig.mNodeConfig.mResources[0].mHosts.Resize(2); + nodeConfig.mNodeConfig.mResources[0].mHosts[0].mIP = "10.0.0.100"; + nodeConfig.mNodeConfig.mResources[0].mHosts[0].mHostname = "host1"; + + nodeConfig.mNodeConfig.mResources[0].mHosts[1].mIP = "10.0.0.101"; + nodeConfig.mNodeConfig.mResources[0].mHosts[1].mHostname = "host2"; + + nodeConfig.mNodeConfig.mResources[1].mName = "resource2"; + nodeConfig.mNodeConfig.mResources[1].mGroups.PushBack("g3"); + nodeConfig.mNodeConfig.mResources[1].mGroups.PushBack("g4"); + + nodeConfig.mNodeConfig.mResources[1].mMounts.Resize(2); + nodeConfig.mNodeConfig.mResources[1].mMounts[0].mDestination = "d3"; + nodeConfig.mNodeConfig.mResources[1].mMounts[0].mType = "type3"; + nodeConfig.mNodeConfig.mResources[1].mMounts[0].mSource = "source3"; + nodeConfig.mNodeConfig.mResources[1].mMounts[0].mOptions.PushBack("option5"); + nodeConfig.mNodeConfig.mResources[1].mMounts[0].mOptions.PushBack("option6"); + + nodeConfig.mNodeConfig.mResources[1].mMounts[1].mDestination = "d4"; + nodeConfig.mNodeConfig.mResources[1].mMounts[1].mType = "type4"; + nodeConfig.mNodeConfig.mResources[1].mMounts[1].mSource = "source4"; + nodeConfig.mNodeConfig.mResources[1].mMounts[1].mOptions.PushBack("option7"); + nodeConfig.mNodeConfig.mResources[1].mMounts[1].mOptions.PushBack("option8"); + + nodeConfig.mNodeConfig.mResources[1].mEnv.PushBack("env3"); + nodeConfig.mNodeConfig.mResources[1].mEnv.PushBack("env4"); + + nodeConfig.mNodeConfig.mResources[1].mHosts.Resize(2); + nodeConfig.mNodeConfig.mResources[1].mHosts[0].mIP = "10.0.0.102"; + nodeConfig.mNodeConfig.mResources[1].mHosts[0].mHostname = "host3"; + nodeConfig.mNodeConfig.mResources[1].mHosts[1].mIP = "10.0.0.103"; + nodeConfig.mNodeConfig.mResources[1].mHosts[1].mHostname = "host4"; + + nodeConfig.mNodeConfig.mLabels.PushBack("mainNode"); + + return nodeConfig; +} + +static void CompareNodeConfig(const aos::sm::resourcemanager::NodeConfig& nodeConfig, + const aos::sm::resourcemanager::NodeConfig& expectedNodeConfig) +{ + zassert_equal(nodeConfig.mVersion, expectedNodeConfig.mVersion, "Version mismatch"); + zassert_equal(nodeConfig.mNodeConfig.mNodeType, expectedNodeConfig.mNodeConfig.mNodeType, "Node type mismatch"); + zassert_equal(nodeConfig.mNodeConfig.mPriority, expectedNodeConfig.mNodeConfig.mPriority, "Priority mismatch"); + + zassert_equal(nodeConfig.mNodeConfig.mDevices, expectedNodeConfig.mNodeConfig.mDevices, "Device info mismatch"); + zassert_equal(nodeConfig.mNodeConfig.mLabels, expectedNodeConfig.mNodeConfig.mLabels, "Node labels mismatch"); + + // Compare resources + + zassert_equal(nodeConfig.mNodeConfig.mResources.Size(), expectedNodeConfig.mNodeConfig.mResources.Size(), + "Resources size mismatch"); + + for (size_t i = 0; i < nodeConfig.mNodeConfig.mResources.Size(); ++i) { + const auto& resource = nodeConfig.mNodeConfig.mResources[i]; + const auto& expectedResource = expectedNodeConfig.mNodeConfig.mResources[i]; + + zassert_equal(resource.mName, expectedResource.mName, "Resource name mismatch"); + zassert_equal(resource.mGroups, expectedResource.mGroups, "Resource groups mismatch"); + zassert_equal(resource.mMounts, expectedResource.mMounts, "Resource mounts mismatch"); + zassert_equal(resource.mEnv, expectedResource.mEnv, "Resource envs mismatch"); + zassert_equal(resource.mHosts, expectedResource.mHosts, "Resource hosts mismatch"); + } +} /*********************************************************************************************************************** * Tests **********************************************************************************************************************/ -ZTEST_SUITE(resourcemanager, NULL, NULL, NULL, NULL, NULL); +ZTEST_SUITE( + resourcemanager, NULL, NULL, [](void*) { aos::Log::SetCallback(TestLogCallback); }, NULL, NULL); ZTEST(resourcemanager, test_JSONProviderParse) { - aos::Log::SetCallback(TestLogCallback); - aos::zephyr::resourcemanager::JSONProvider provider; - aos::sm::resourcemanager::NodeConfig nodeConfig; + aos::sm::resourcemanager::NodeConfig parsedNodeConfig; aos::String jsonStr(cTestNodeConfigJSON); - auto err = provider.ParseNodeConfig(jsonStr, nodeConfig); + auto err = provider.ParseNodeConfig(jsonStr, parsedNodeConfig); + + zassert_true(err.IsNone(), "Failed to parse node config: %s", utils::ErrorToCStr(err)); - zassert_true(err.IsNone(), "Failed to parse node config: %s", err.Message()); - zassert_equal(1, nodeConfig.mNodeConfig.mPriority, "Priority mismatch"); - zassert_equal(nodeConfig.mVersion, "1.0.0", "File content mismatch"); - zassert_equal(nodeConfig.mNodeConfig.mNodeType, "mainType", "Node type mismatch"); + CompareNodeConfig(parsedNodeConfig, CreateNodeConfig()); } ZTEST(resourcemanager, test_DumpNodeConfig) { - aos::Log::SetCallback(TestLogCallback); - aos::zephyr::resourcemanager::JSONProvider provider; - aos::sm::resourcemanager::NodeConfig nodeConfig; - nodeConfig.mNodeConfig.mPriority = 1; - nodeConfig.mVersion = "1.0.0"; - nodeConfig.mNodeConfig.mNodeType = "mainType"; + aos::sm::resourcemanager::NodeConfig nodeConfig = CreateNodeConfig(); - aos::StaticString<1024> jsonStr; - auto err = provider.DumpNodeConfig(nodeConfig, jsonStr); + aos::StaticString jsonStr; + auto err = provider.DumpNodeConfig(nodeConfig, jsonStr); zassert_true(err.IsNone(), "Failed to dump node config: %s", utils::ErrorToCStr(err)); zassert_false(jsonStr.IsEmpty(), "Empty json string"); @@ -66,6 +268,6 @@ ZTEST(resourcemanager, test_DumpNodeConfig) err = provider.ParseNodeConfig(jsonStr, parsedNodeConfig); zassert_true(err.IsNone(), "Failed to parse node config: %s", utils::ErrorToCStr(err)); - zassert_equal(nodeConfig.mNodeConfig, parsedNodeConfig.mNodeConfig, "Parsed node config mismatch"); - zassert_equal(nodeConfig.mVersion, parsedNodeConfig.mVersion, "Parsed unit config vendor version mismatch"); + + CompareNodeConfig(parsedNodeConfig, nodeConfig); } From de92ea754141fa44f848470aa593eebb7fb9dce3 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Thu, 17 Oct 2024 10:46:05 +0300 Subject: [PATCH 182/198] [communication] Cleanup tls config before set Signed-off-by: Mykhailo Lohvynenko --- src/communication/tlschannel.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/communication/tlschannel.cpp b/src/communication/tlschannel.cpp index 98fe51c9..9afbf474 100644 --- a/src/communication/tlschannel.cpp +++ b/src/communication/tlschannel.cpp @@ -50,6 +50,10 @@ Error TLSChannel::SetTLSConfig(const String& certType) { LOG_DBG() << "Set TLS config: name=" << mName << ", certType=" << certType; + if (!mCertType.IsEmpty()) { + Cleanup(); + } + if (auto err = SetupSSLConfig(certType); !err.IsNone()) { Cleanup(); @@ -155,6 +159,8 @@ void TLSChannel::Cleanup() if (mKeyID != 0) { AosPsaRemoveKey(mKeyID); } + + mCertType.Clear(); } Error TLSChannel::SetupSSLConfig(const String& certType) From 93457b93d9ce78daee0494f235f4169762153a52 Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Thu, 17 Oct 2024 10:46:21 +0300 Subject: [PATCH 183/198] [iamclient] Reconnect on cert change Signed-off-by: Mykhailo Lohvynenko --- src/iamclient/iamclient.cpp | 36 +++++++++++++++++++++++++++++++----- src/iamclient/iamclient.hpp | 18 +++++++++++++----- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index 0938a494..d7c46e92 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -83,6 +83,12 @@ Error IAMClient::Stop() mClockSync->Unsubscribe(*this); mNodeInfoProvider->UnsubscribeNodeStatusChanged(*this); +#ifndef CONFIG_ZTEST + if (auto err = mCertHandler->UnsubscribeCertChanged(*this); !err.IsNone()) { + LOG_ERR() << "Can't unsubscribe cert changed: err=" << err; + } +#endif + { LockGuard lock {mMutex}; @@ -126,7 +132,7 @@ Error IAMClient::OnNodeStatusChanged(const String& nodeID, const NodeStatus& sta } if (mNodeInfo.mStatus == NodeStatusEnum::eUnprovisioned || status == NodeStatusEnum::eUnprovisioned) { - mSwitchChannel = true; + mReconnect = true; mCondVar.NotifyOne(); } @@ -139,6 +145,16 @@ Error IAMClient::OnNodeStatusChanged(const String& nodeID, const NodeStatus& sta return ErrorEnum::eNone; } +void IAMClient::OnCertChanged(const iam::certhandler::CertInfo& info) +{ + LockGuard lock {mMutex}; + + LOG_DBG() << "Cert changed event received"; + + mReconnect = true; + mCondVar.NotifyOne(); +} + /*********************************************************************************************************************** * Private **********************************************************************************************************************/ @@ -181,6 +197,12 @@ Error IAMClient::ReleaseChannel() err = AOS_ERROR_WRAP(deleteErr); } +#ifndef CONFIG_ZTEST + if (auto unsubscribeErr = mCertHandler->UnsubscribeCertChanged(*this); !unsubscribeErr.IsNone() && err.IsNone()) { + err = AOS_ERROR_WRAP(Error(err, "can't unsubscribe from cert changed event")); + } +#endif + return err; } @@ -211,6 +233,10 @@ Error IAMClient::SetupChannel() mCurrentPort = cSecurePort; #ifndef CONFIG_ZTEST + if (err = mCertHandler->SubscribeCertChanged(cIAMCertType, *this); !err.IsNone()) { + return AOS_ERROR_WRAP(Error(err, "can't subscribe on cert changed event")); + } + if (err = mTLSChannel.Init("iam", *mCertHandler, *mCertLoader, *channel); !err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -236,10 +262,10 @@ Error IAMClient::SetupChannel() return ErrorEnum::eNone; } -bool IAMClient::WaitChannelSwitch(UniqueLock& lock) +bool IAMClient::WaitReconnect(UniqueLock& lock) { - mCondVar.Wait(lock, [this]() { return mSwitchChannel || mClose; }); - mSwitchChannel = false; + mCondVar.Wait(lock, [this]() { return mReconnect || mClose; }); + mReconnect = false; return !mClose; } @@ -280,7 +306,7 @@ void IAMClient::HandleChannels() continue; } - if (!WaitChannelSwitch(lock)) { + if (!WaitReconnect(lock)) { continue; } } diff --git a/src/iamclient/iamclient.hpp b/src/iamclient/iamclient.hpp index 2837b97e..12a81761 100644 --- a/src/iamclient/iamclient.hpp +++ b/src/iamclient/iamclient.hpp @@ -30,6 +30,7 @@ class IAMClient : public communication::PBHandler, public clocksync::ClockSyncSubscriberItf, public iam::nodeinfoprovider::NodeStatusObserverItf, + private aos::iam::certhandler::CertReceiverItf, private NonCopyable { public: /** @@ -84,6 +85,13 @@ class IAMClient */ Error OnNodeStatusChanged(const String& nodeID, const NodeStatus& status) override; + /** + * Processes certificate updates. + * + * @param info certificate info. + */ + void OnCertChanged(const aos::iam::certhandler::CertInfo& info) override; + private: static constexpr auto cOpenPort = CONFIG_AOS_IAM_OPEN_PORT; static constexpr auto cSecurePort = CONFIG_AOS_IAM_SECURE_PORT; @@ -98,7 +106,7 @@ class IAMClient Error ReleaseChannel(); Error SetupChannel(); - bool WaitChannelSwitch(UniqueLock& lock); + bool WaitReconnect(UniqueLock& lock); bool WaitClockSynced(UniqueLock& lock); bool WaitChannelConnected(UniqueLock& lock); void HandleChannels(); @@ -129,10 +137,10 @@ class IAMClient Mutex mMutex; Thread<> mThread; ConditionalVariable mCondVar; - bool mClockSynced = false; - bool mSwitchChannel = false; - int mCurrentPort = 0; - bool mClose = false; + bool mClockSynced = false; + bool mReconnect = false; + int mCurrentPort = 0; + bool mClose = false; StaticAllocator mAllocator; }; From ab948296f4ec3d3036d2b0c7531359214479ec4a Mon Sep 17 00:00:00 2001 From: Mykhailo Lohvynenko Date: Thu, 17 Oct 2024 10:46:31 +0300 Subject: [PATCH 184/198] [smclient] Reconnect on cert change Signed-off-by: Mykhailo Lohvynenko --- src/smclient/smclient.cpp | 28 +++++++++++++++++++++++++++- src/smclient/smclient.hpp | 16 +++++++++++++--- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index d2982b33..0941b415 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -305,6 +305,16 @@ void SMClient::OnClockUnsynced() mCondVar.NotifyOne(); } +void SMClient::OnCertChanged(const iam::certhandler::CertInfo& info) +{ + LockGuard lock {mMutex}; + + LOG_DBG() << "Cert changed event received"; + + mCertificateChanged = true; + mCondVar.NotifyOne(); +} + Error SMClient::SendClockSyncRequest() { return mOpenHandler.SendClockSyncRequest(); @@ -592,6 +602,10 @@ Error SMClient::SetupChannel() } #ifndef CONFIG_ZTEST + if (err = mCertHandler->SubscribeCertChanged(cSMCertType, *this); !err.IsNone()) { + return AOS_ERROR_WRAP(Error(err, "can't subscribe on cert changed event")); + } + if (err = mTLSChannel.Init("sm", *mCertHandler, *mCertLoader, *channel); !err.IsNone()) { return AOS_ERROR_WRAP(err); } @@ -618,6 +632,12 @@ Error SMClient::SetupChannel() Error SMClient::ReleaseChannel() { + { + LockGuard lock {mMutex}; + + mCertificateChanged = false; + } + if (!IsStarted()) { return ErrorEnum::eNone; } @@ -632,6 +652,12 @@ Error SMClient::ReleaseChannel() return AOS_ERROR_WRAP(err); } +#ifndef CONFIG_ZTEST + if (auto err = mCertHandler->UnsubscribeCertChanged(*this); !err.IsNone()) { + return AOS_ERROR_WRAP(Error(err, "can't unsubscribe from cert changed event")); + } +#endif + return ErrorEnum::eNone; } @@ -662,7 +688,7 @@ void SMClient::HandleChannel() continue; } - mCondVar.Wait(lock, [this]() { return !mClockSynced || !mProvisioned || mClose; }); + mCondVar.Wait(lock, [this]() { return !mClockSynced || !mProvisioned || mClose || mCertificateChanged; }); } } diff --git a/src/smclient/smclient.hpp b/src/smclient/smclient.hpp index 4018d7e7..28e6ad1a 100644 --- a/src/smclient/smclient.hpp +++ b/src/smclient/smclient.hpp @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -36,6 +37,7 @@ class SMClient : public communication::PBHandler mThread; ConditionalVariable mCondVar; - bool mClockSynced = false; - bool mProvisioned = false; - bool mClose = false; + bool mClockSynced = false; + bool mProvisioned = false; + bool mCertificateChanged = false; + bool mClose = false; #ifndef CONFIG_ZTEST iam::certhandler::CertHandlerItf* mCertHandler {}; From 7ff3d989fa77a4df526656080439a085da5466c3 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 7 Nov 2024 12:22:57 +0200 Subject: [PATCH 185/198] [Kconfig] Add CONFIG_AOS_CORE_RUNTIME_LOG_LEVEL to configure runtime log Signed-off-by: Oleksandr Grytsov --- Kconfig | 4 ++++ prj.conf | 6 ++++++ src/logger/logger.hpp | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Kconfig b/Kconfig index 5d6ec90c..1578646f 100644 --- a/Kconfig +++ b/Kconfig @@ -155,4 +155,8 @@ module = AOS_CORE module-str = Aos core source "subsys/logging/Kconfig.template.log_config" +module = AOS_CORE_RUNTIME +module-str = Aos core runtime +source "subsys/logging/Kconfig.template.log_config" + source "Kconfig" diff --git a/prj.conf b/prj.conf index 439bea47..065fae05 100644 --- a/prj.conf +++ b/prj.conf @@ -47,6 +47,9 @@ CONFIG_LOG_DEFAULT_LEVEL=3 CONFIG_LOG_MODE_DEFERRED=y CONFIG_LOG_BUFFER_SIZE=8192 +# Set kernel default log level +CONFIG_KERNEL_LOG_LEVEL_INF=y + # Disable FS log to avoid errors duplication. We catch them by Aos errors. CONFIG_FS_LOG_LEVEL_OFF=y @@ -56,6 +59,9 @@ CONFIG_PTHREAD_COND_LOG_LEVEL_OFF=y # Set Aos log level CONFIG_AOS_CORE_LOG_LEVEL_DBG=y +# Set Aos runtime log level +CONFIG_AOS_CORE_RUNTIME_LOG_LEVEL_INF=y + # Enable assert for debugging purposes # TODO: remove for release CONFIG_ASSERT=y diff --git a/src/logger/logger.hpp b/src/logger/logger.hpp index 5f2acc7c..5ee8aa0d 100644 --- a/src/logger/logger.hpp +++ b/src/logger/logger.hpp @@ -32,7 +32,7 @@ class Logger { private: static constexpr auto cMaxLogModules = 32; #if CONFIG_LOG_RUNTIME_FILTERING - static constexpr auto cRuntimeLogLevel = LOG_LEVEL_INF; + static constexpr auto cRuntimeLogLevel = CONFIG_AOS_CORE_RUNTIME_LOG_LEVEL; #endif static void LogCallback(const String& module, LogLevel level, const String& message); From fb8a64769ff6bcd660e60f88807202db19203be8 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 7 Nov 2024 13:11:04 +0200 Subject: [PATCH 186/198] [all] Update to changed aos_core_lib_cpp interface Signed-off-by: Oleksandr Grytsov --- src/app/app.hpp | 6 +++--- src/clocksync/clocksync.cpp | 5 +---- src/communication/tlschannel.cpp | 3 +-- src/communication/tlschannel.hpp | 9 ++++----- src/downloader/downloader.cpp | 2 +- src/iamclient/iamclient.cpp | 2 +- src/iamclient/iamclient.hpp | 4 ++-- src/monitoring/resourceusageprovider.cpp | 2 +- src/smclient/smclient.cpp | 6 ++---- src/smclient/smclient.hpp | 4 ++-- tests/communication/src/stubs/certhandlerstub.hpp | 3 ++- tests/communication/src/stubs/certloaderstub.hpp | 6 +++--- tests/communication/src/stubs/rsaprivatekey.hpp | 2 +- tests/iamclient/src/stubs/provisionmanagerstub.hpp | 4 ++-- 14 files changed, 26 insertions(+), 32 deletions(-) diff --git a/src/app/app.hpp b/src/app/app.hpp index fc5c9617..791a291e 100644 --- a/src/app/app.hpp +++ b/src/app/app.hpp @@ -9,7 +9,7 @@ #define APP_HPP_ #include -#include +#include #include #include #include @@ -77,7 +77,7 @@ class App : private NonCopyable { static App& Get() { return sApp; }; private: - static constexpr auto cPKCS11ModuleLibrary = AOS_CONFIG_CRYPTOUTILS_DEFAULT_PKCS11_LIB; + static constexpr auto cPKCS11ModuleLibrary = AOS_CONFIG_CRYPTO_DEFAULT_PKCS11_LIB; static constexpr auto cPKCS11ModuleTokenLabel = "aoscore"; static constexpr auto cPKCS11ModulePinFile = CONFIG_AOS_PKCS11_MODULE_PIN_FILE; static constexpr auto cNodeType = CONFIG_AOS_NODE_TYPE; @@ -96,7 +96,7 @@ class App : private NonCopyable { static App sApp; aos::crypto::MbedTLSCryptoProvider mCryptoProvider; - aos::cryptoutils::CertLoader mCertLoader; + aos::crypto::CertLoader mCertLoader; aos::monitoring::ResourceMonitor mResourceMonitor; aos::pkcs11::PKCS11Manager mPKCS11Manager; diff --git a/src/clocksync/clocksync.cpp b/src/clocksync/clocksync.cpp index 93852976..146e5f93 100644 --- a/src/clocksync/clocksync.cpp +++ b/src/clocksync/clocksync.cpp @@ -134,10 +134,7 @@ void ClockSync::Unsubscribe(ClockSyncSubscriberItf& subscriber) { LockGuard lock {mMutex}; - auto it = mConnectionSubscribers.Find(&subscriber); - if (it.mError.IsNone()) { - mConnectionSubscribers.Remove(it.mValue); - } + mConnectionSubscribers.Remove(&subscriber); } /*********************************************************************************************************************** diff --git a/src/communication/tlschannel.cpp b/src/communication/tlschannel.cpp index 9afbf474..acf3a6dd 100644 --- a/src/communication/tlschannel.cpp +++ b/src/communication/tlschannel.cpp @@ -13,7 +13,6 @@ extern "C" { #include #include -#include #include #include "log.hpp" @@ -34,7 +33,7 @@ TLSChannel::~TLSChannel() } Error TLSChannel::Init(const String& name, iam::certhandler::CertHandlerItf& certHandler, - cryptoutils::CertLoaderItf& certLoader, ChannelItf& channel) + crypto::CertLoaderItf& certLoader, ChannelItf& channel) { mName = name; mChannel = &channel; diff --git a/src/communication/tlschannel.hpp b/src/communication/tlschannel.hpp index f1d9ebab..bb931846 100644 --- a/src/communication/tlschannel.hpp +++ b/src/communication/tlschannel.hpp @@ -12,8 +12,7 @@ #include #include -#include -#include +#include #include #include @@ -36,8 +35,8 @@ class TLSChannel : public ChannelItf { * @param certLoader certificate loader. * @param channel virtual channel. */ - Error Init(const String& name, iam::certhandler::CertHandlerItf& certHandler, - cryptoutils::CertLoaderItf& certLoader, ChannelItf& channel); + Error Init(const String& name, iam::certhandler::CertHandlerItf& certHandler, crypto::CertLoaderItf& certLoader, + ChannelItf& channel); /** * Set TLS config. @@ -108,7 +107,7 @@ class TLSChannel : public ChannelItf { SharedPtr mPrivKey {}; ChannelItf* mChannel {}; iam::certhandler::CertHandlerItf* mCertHandler {}; - cryptoutils::CertLoaderItf* mCertLoader {}; + crypto::CertLoaderItf* mCertLoader {}; StaticString mCertType; }; diff --git a/src/downloader/downloader.cpp b/src/downloader/downloader.cpp index 08f6c3f9..669f2921 100644 --- a/src/downloader/downloader.cpp +++ b/src/downloader/downloader.cpp @@ -94,7 +94,7 @@ Error Downloader::ReceiveFileChunk(const FileChunk& chunk) LockGuard lock(mMutex); - auto downloadResult = mDownloadResults.Find( + auto downloadResult = mDownloadResults.FindIf( [&chunk](const DownloadResult& result) { return result.mRelativePath == chunk.mRelativePath; }); if (!downloadResult.mError.IsNone()) { diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index d7c46e92..b7b7395e 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -24,7 +24,7 @@ Error IAMClient::Init(clocksync::ClockSyncItf& clockSync, iam::nodeinfoprovider: iam::provisionmanager::ProvisionManagerItf& provisionManager, communication::ChannelManagerItf& channelManager #ifndef CONFIG_ZTEST , - iam::certhandler::CertHandlerItf& certHandler, cryptoutils::CertLoaderItf& certLoader + iam::certhandler::CertHandlerItf& certHandler, crypto::CertLoaderItf& certLoader #endif ) { diff --git a/src/iamclient/iamclient.hpp b/src/iamclient/iamclient.hpp index 12a81761..c46d29c6 100644 --- a/src/iamclient/iamclient.hpp +++ b/src/iamclient/iamclient.hpp @@ -48,7 +48,7 @@ class IAMClient iam::provisionmanager::ProvisionManagerItf& provisionManager, communication::ChannelManagerItf& channelManager #ifndef CONFIG_ZTEST , - iam::certhandler::CertHandlerItf& certHandler, cryptoutils::CertLoaderItf& certLoader + iam::certhandler::CertHandlerItf& certHandler, crypto::CertLoaderItf& certLoader #endif ); @@ -129,7 +129,7 @@ class IAMClient communication::ChannelManagerItf* mChannelManager {}; #ifndef CONFIG_ZTEST iam::certhandler::CertHandlerItf* mCertHandler {}; - cryptoutils::CertLoaderItf* mCertLoader {}; + crypto::CertLoaderItf* mCertLoader {}; communication::TLSChannel mTLSChannel; #endif diff --git a/src/monitoring/resourceusageprovider.cpp b/src/monitoring/resourceusageprovider.cpp index 4590dee7..f32e3cde 100644 --- a/src/monitoring/resourceusageprovider.cpp +++ b/src/monitoring/resourceusageprovider.cpp @@ -112,7 +112,7 @@ Error ResourceUsageProvider::GetInstanceMonitoringData( monitoringData.mRAM = domain.cur_mem; - auto findInstanceCPUTime = mPrevInstanceCPUTime.Find([&instanceID](const InstanceCPUData& instanceCpuData) { + auto findInstanceCPUTime = mPrevInstanceCPUTime.FindIf([&instanceID](const InstanceCPUData& instanceCpuData) { return instanceCpuData.mInstanceID == instanceID; }); diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index 0941b415..65c3482f 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -84,7 +84,7 @@ Error SMClient::Init(iam::nodeinfoprovider::NodeInfoProviderItf& nodeInfoProvide communication::ChannelManagerItf& channelManager #ifndef CONFIG_ZTEST , - iam::certhandler::CertHandlerItf& certHandler, cryptoutils::CertLoaderItf& certLoader + iam::certhandler::CertHandlerItf& certHandler, crypto::CertLoaderItf& certLoader #endif ) { @@ -268,9 +268,7 @@ void SMClient::Unsubscribe(ConnectionSubscriberItf& subscriber) { LockGuard lock(mMutex); - if (auto it = mConnectionSubscribers.Find(&subscriber); it.mError.IsNone()) { - mConnectionSubscribers.Remove(it.mValue); - } + mConnectionSubscribers.Remove(&subscriber); } Error SMClient::OnNodeStatusChanged(const String& nodeID, const NodeStatus& status) diff --git a/src/smclient/smclient.hpp b/src/smclient/smclient.hpp index 28e6ad1a..fb08805d 100644 --- a/src/smclient/smclient.hpp +++ b/src/smclient/smclient.hpp @@ -60,7 +60,7 @@ class SMClient : public communication::PBHandler>& certTypes) override + aos::Error GetCertTypes( + aos::Array>& certTypes) const override { std::lock_guard lock(mMutex); diff --git a/tests/communication/src/stubs/certloaderstub.hpp b/tests/communication/src/stubs/certloaderstub.hpp index 12ad88c7..b41295c0 100644 --- a/tests/communication/src/stubs/certloaderstub.hpp +++ b/tests/communication/src/stubs/certloaderstub.hpp @@ -16,12 +16,12 @@ #include #include -#include -#include +#include +#include #include "rsaprivatekey.hpp" -class CertLoaderStub : public aos::cryptoutils::CertLoaderItf { +class CertLoaderStub : public aos::crypto::CertLoaderItf { public: aos::RetWithError> LoadCertsChainByURL( const aos::String& url) override diff --git a/tests/communication/src/stubs/rsaprivatekey.hpp b/tests/communication/src/stubs/rsaprivatekey.hpp index 286dee48..0016bf67 100644 --- a/tests/communication/src/stubs/rsaprivatekey.hpp +++ b/tests/communication/src/stubs/rsaprivatekey.hpp @@ -14,7 +14,7 @@ #include #include -#include +#include class RSAPrivateKey : public aos::crypto::PrivateKeyItf { public: diff --git a/tests/iamclient/src/stubs/provisionmanagerstub.hpp b/tests/iamclient/src/stubs/provisionmanagerstub.hpp index 8b7b3652..30fd8bdf 100644 --- a/tests/iamclient/src/stubs/provisionmanagerstub.hpp +++ b/tests/iamclient/src/stubs/provisionmanagerstub.hpp @@ -19,7 +19,7 @@ class ProvisionManagerStub : public aos::iam::provisionmanager::ProvisionManager return aos::ErrorEnum::eNone; } - aos::RetWithError GetCertTypes() { return mCertTypes; } + aos::RetWithError GetCertTypes() const { return mCertTypes; } aos::Error CreateKey( const aos::String& certType, const aos::String& subject, const aos::String& password, aos::String& csr) override @@ -43,7 +43,7 @@ class ProvisionManagerStub : public aos::iam::provisionmanager::ProvisionManager } aos::Error GetCert(const aos::String& certType, const aos::Array& issuer, - const aos::Array& serial, aos::iam::certhandler::CertInfo& resCert) override + const aos::Array& serial, aos::iam::certhandler::CertInfo& resCert) const override { return aos::ErrorEnum::eNone; } From 24757cfb5e96b091a66ebf5b24aeecd051da4b75 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 7 Nov 2024 13:13:18 +0200 Subject: [PATCH 187/198] [communication] Add missing cond var notification on close Signed-off-by: Oleksandr Grytsov --- src/communication/pbhandler.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/communication/pbhandler.cpp b/src/communication/pbhandler.cpp index 4b0c6e12..f6f2b4db 100644 --- a/src/communication/pbhandler.cpp +++ b/src/communication/pbhandler.cpp @@ -63,11 +63,10 @@ Error PBHandler::Stop() mStarted = false; mChannel->Close(); + mCondVar.NotifyOne(); } - mThread.Join(); - - return ErrorEnum::eNone; + return mThread.Join(); } template From 2d93ef34aa3185e0940a2eb046438933e6de28a4 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 7 Nov 2024 13:15:22 +0200 Subject: [PATCH 188/198] [communication] Implement channel manager stop method * add missing channel manager stop method * refactor mutex wrappers usage * remove redundant aos:: namespace usage Signed-off-by: Oleksandr Grytsov --- src/app/app.cpp | 4 ++ src/communication/channelmanager.cpp | 83 +++++++++++----------- src/communication/channelmanager.hpp | 23 +++--- tests/communication/src/channelmanager.cpp | 6 +- tests/stubs/channelmanagerstub.hpp | 2 +- 5 files changed, 59 insertions(+), 59 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index 9e939741..f41e8dda 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -90,6 +90,10 @@ Error App::Stop() LOG_ERR() << "Failed to stop clock sync: err=" << err; } + if (auto err = mChannelManager.Stop(); !err.IsNone()) { + LOG_ERR() << "Failed to stop channel manager: err=" << err; + } + if (auto err = mIAMClient.Stop(); !err.IsNone()) { LOG_ERR() << "Failed to stop IAM client: err=" << err; } diff --git a/src/communication/channelmanager.cpp b/src/communication/channelmanager.cpp index 805c0494..3c95e420 100644 --- a/src/communication/channelmanager.cpp +++ b/src/communication/channelmanager.cpp @@ -32,14 +32,36 @@ Error ChannelManager::Init(TransportItf& transport) Error ChannelManager::Start() { + LockGuard lock {mMutex}; + LOG_DBG() << "Start channel manager"; return Run(); } +Error ChannelManager::Stop() +{ + { + LOG_DBG() << "Stop channel manager"; + + LockGuard lock {mMutex}; + + if (mTransport->IsOpened()) { + if (auto err = mTransport->Close(); !err.IsNone()) { + LOG_ERR() << "Failed to close transport: err=" << err; + } + } + + mClose = true; + mCondVar.NotifyAll(); + } + + return mThread.Join(); +} + RetWithError ChannelManager::CreateChannel(uint32_t port) { - UniqueLock lock {mMutex}; + LockGuard lock {mMutex}; auto findChannel = mChannels.At(port); if (findChannel.mError.IsNone()) { @@ -48,7 +70,7 @@ RetWithError ChannelManager::CreateChannel(uint32_t port) LOG_DBG() << "Create channel: port=" << port; - auto channel = aos::MakeShared(&mChanAllocator, static_cast(this), port); + auto channel = MakeShared(&mChanAllocator, static_cast(this), port); if (auto err = mChannels.Set(port, channel); !err.IsNone()) { return {nullptr, err}; @@ -61,7 +83,7 @@ RetWithError ChannelManager::CreateChannel(uint32_t port) Error ChannelManager::DeleteChannel(uint32_t port) { - UniqueLock lock {mMutex}; + LockGuard lock {mMutex}; LOG_DBG() << "Delete channel: port=" << port; @@ -84,38 +106,16 @@ Error ChannelManager::Connect() return ErrorEnum::eNone; } -Error ChannelManager::Close() -{ - { - UniqueLock lock {mMutex}; - - LOG_DBG() << "Close channel manager"; - - mClose = true; - mCondVar.NotifyAll(); - - if (!mTransport->IsOpened()) { - return ErrorEnum::eNone; - } - - if (auto err = mTransport->Close(); !err.IsNone()) { - return err; - } - } - - return mThread.Join(); -} - int ChannelManager::Write(uint32_t port, const void* data, size_t size) { - auto header = PrepareHeader(port, aos::Array(reinterpret_cast(data), size)); + auto header = PrepareHeader(port, Array(reinterpret_cast(data), size)); if (!header.mError.IsNone()) { LOG_ERR() << "Failed to prepare header: err=" << header.mError.Message(); return -EINVAL; } - aos::UniqueLock lock {sWriteMutex}; + LockGuard lock {sWriteMutex}; if (auto err = WriteTransport(&header.mValue, sizeof(AosProtocolHeader)); !err.IsNone()) { LOG_ERR() << "Failed to write header: err=" << err; @@ -134,6 +134,8 @@ int ChannelManager::Write(uint32_t port, const void* data, size_t size) bool ChannelManager::IsConnected() const { + LockGuard lock {mMutex}; + return mTransport->IsOpened(); } @@ -143,7 +145,7 @@ bool ChannelManager::IsConnected() const Error ChannelManager::TryConnect() { - UniqueLock lock {mMutex}; + LockGuard lock {mMutex}; if (mTransport->IsOpened()) { return ErrorEnum::eNone; @@ -161,10 +163,10 @@ Error ChannelManager::Run() return mThread.Run([this](void*) { while (true) { { - aos::UniqueLock lock {mMutex}; + LockGuard lock {mMutex}; if (mClose) { - return aos::Error(aos::ErrorEnum::eNone); + return ErrorEnum::eNone; } } @@ -198,7 +200,7 @@ Error ChannelManager::Run() Error ChannelManager::WaitTimeout() { - aos::UniqueLock lock {mMutex}; + UniqueLock lock {mMutex}; if (auto err = mCondVar.Wait(lock, cReconnectPeriod, [this] { return mClose; }); !err.IsNone() && !err.Is(ErrorEnum::eTimeout)) { @@ -212,7 +214,7 @@ Error ChannelManager::HandleRead() { while (true) { { - aos::UniqueLock lock {mMutex}; + UniqueLock lock {mMutex}; mCondVar.Wait(lock, [this] { return mChannels.Size() > 0 || mClose; }); if (mClose) { @@ -242,7 +244,7 @@ Error ChannelManager::HandleRead() Error ChannelManager::ProcessData(const AosProtocolHeader& header) { - UniqueLock lock {mMutex}; + LockGuard lock {mMutex}; LOG_DBG() << "Process data: port=" << header.mPort << " size=" << header.mDataSize; @@ -261,7 +263,7 @@ Error ChannelManager::ProcessData(const AosProtocolHeader& header) return err; } - size = aos::Min(size, static_cast(header.mDataSize - processedSize)); + size = Min(size, static_cast(header.mDataSize - processedSize)); memcpy(buffer, mTmpReadBuffer + processedSize, size); @@ -291,10 +293,10 @@ Error ChannelManager::ReadTransport(void* buffer, size_t size) } if (read != size) { - return AOS_ERROR_WRAP(Error(aos::ErrorEnum::eFailed, "read size mismatch")); + return AOS_ERROR_WRAP(Error(ErrorEnum::eFailed, "read size mismatch")); } - return aos::ErrorEnum::eNone; + return ErrorEnum::eNone; } Error ChannelManager::WriteTransport(const void* buffer, size_t size) @@ -311,7 +313,7 @@ Error ChannelManager::WriteTransport(const void* buffer, size_t size) } if (written != size) { - return AOS_ERROR_WRAP(Error(aos::ErrorEnum::eFailed, "write size mismatch")); + return AOS_ERROR_WRAP(Error(ErrorEnum::eFailed, "write size mismatch")); } return ErrorEnum::eNone; @@ -327,18 +329,19 @@ void ChannelManager::CloseChannels() } } -aos::RetWithError ChannelManager::PrepareHeader(uint32_t port, const aos::Array& data) +RetWithError ChannelManager::PrepareHeader(uint32_t port, const Array& data) { AosProtocolHeader header; + header.mPort = port; header.mDataSize = data.Size(); - auto ret = aos::zephyr::utils::CalculateSha256(data); + auto ret = zephyr::utils::CalculateSha256(data); if (!ret.mError.IsNone()) { return {header, AOS_ERROR_WRAP(ret.mError)}; } - aos::Array(reinterpret_cast(header.mCheckSum), aos::cSHA256Size) = ret.mValue; + Array(reinterpret_cast(header.mCheckSum), cSHA256Size) = ret.mValue; return header; } diff --git a/src/communication/channelmanager.hpp b/src/communication/channelmanager.hpp index d3e42665..0047c802 100644 --- a/src/communication/channelmanager.hpp +++ b/src/communication/channelmanager.hpp @@ -38,13 +38,6 @@ class ChannelManagerItf { */ virtual Error DeleteChannel(uint32_t port) = 0; - /** - * Closes communication channel. - * - * @return aos::Error. - */ - virtual Error Close() = 0; - /** * Destructor. */ @@ -76,6 +69,13 @@ class ChannelManager : public ChannelManagerItf, public CommunicationItf { */ Error Start(); + /** + * Stops communication channel. + * + * @return aos::Error. + */ + Error Stop(); + /** * Create channel with dedicated port. * @@ -92,13 +92,6 @@ class ChannelManager : public ChannelManagerItf, public CommunicationItf { */ Error DeleteChannel(uint32_t port) override; - /** - * Closes communication channel. - * - * @return aos::Error. - */ - Error Close() override; - /** * Connects to communication channel. * @@ -145,7 +138,7 @@ class ChannelManager : public ChannelManagerItf, public CommunicationItf { StaticMap, cMaxChannels> mChannels; aos::Thread<> mThread; - aos::Mutex mMutex; + mutable aos::Mutex mMutex; bool mClose {false}; ConditionalVariable mCondVar; static Mutex sWriteMutex; diff --git a/tests/communication/src/channelmanager.cpp b/tests/communication/src/channelmanager.cpp index 27c42551..43233014 100644 --- a/tests/communication/src/channelmanager.cpp +++ b/tests/communication/src/channelmanager.cpp @@ -99,7 +99,7 @@ ZTEST(channelmanager, test_message_exchange) pipe1.Close(); pipe2.Close(); - channelManager.Close(); + channelManager.Stop(); } ZTEST(channelmanager, test_read_message) @@ -141,7 +141,7 @@ ZTEST(channelmanager, test_read_message) pipe1.Close(); pipe2.Close(); - channelManager.Close(); + channelManager.Stop(); } ZTEST(channelmanager, test_read_message_in_chunks) @@ -191,5 +191,5 @@ ZTEST(channelmanager, test_read_message_in_chunks) pipe1.Close(); pipe2.Close(); - channelManager.Close(); + channelManager.Stop(); } diff --git a/tests/stubs/channelmanagerstub.hpp b/tests/stubs/channelmanagerstub.hpp index 7d58c549..569f19ac 100644 --- a/tests/stubs/channelmanagerstub.hpp +++ b/tests/stubs/channelmanagerstub.hpp @@ -60,7 +60,7 @@ class ChannelManagerStub : public aos::zephyr::communication::ChannelManagerItf return mChannels[port].get(); } - aos::Error Close() override + aos::Error Stop() { for (auto& [port, channel] : mChannels) { channel->Close(); From 6a189e429756aeb07458efc68a10a5fe3741a12f Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 7 Nov 2024 13:17:58 +0200 Subject: [PATCH 189/198] [resourcemanager] Remove redundant aos namespace usage Signed-off-by: Oleksandr Grytsov --- src/resourcemanager/resourcemanager.cpp | 44 ++++++++++++------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/src/resourcemanager/resourcemanager.cpp b/src/resourcemanager/resourcemanager.cpp index 470704e1..caf10a97 100644 --- a/src/resourcemanager/resourcemanager.cpp +++ b/src/resourcemanager/resourcemanager.cpp @@ -23,10 +23,10 @@ namespace { */ struct Device { const char* name; - const char* hostDevices[aos::cMaxNumHostDevices]; + const char* hostDevices[cMaxNumHostDevices]; size_t hostDevicesLen; int sharedCount; - const char* groups[aos::cMaxNumGroups]; + const char* groups[cMaxNumGroups]; size_t groupsLen; }; @@ -37,7 +37,7 @@ struct FSMount { const char* destination; const char* source; const char* type; - const char* options[aos::cFSMountMaxNumOptions]; + const char* options[cFSMountMaxNumOptions]; size_t optionsLen; }; @@ -54,13 +54,13 @@ struct Host { */ struct Resource { const char* name; - const char* groups[aos::cMaxNumGroups]; + const char* groups[cMaxNumGroups]; size_t groupsLen; - FSMount mounts[aos::cMaxNumFSMounts]; + FSMount mounts[cMaxNumFSMounts]; size_t mountsLen; - const char* env[aos::cMaxNumEnvVariables]; + const char* env[cMaxNumEnvVariables]; size_t envLen; - Host hosts[aos::cMaxNumHosts]; + Host hosts[cMaxNumHosts]; size_t hostsLen; }; @@ -72,12 +72,12 @@ struct NodeConfig { const char* version; // cppcheck-suppress unusedStructMember const char* nodeType; - Device devices[aos::cMaxNumDevices]; + Device devices[cMaxNumDevices]; size_t devicesLen; - Resource resources[aos::cMaxNumNodeResources]; + Resource resources[cMaxNumNodeResources]; size_t resourcesLen; // cppcheck-suppress unusedStructMember - const char* labels[aos::cMaxNumNodeLabels]; + const char* labels[cMaxNumNodeLabels]; // cppcheck-suppress unusedStructMember size_t labelsLen; // cppcheck-suppress unusedStructMember @@ -91,9 +91,9 @@ struct NodeConfig { */ static const struct json_obj_descr cDeviceDescr[] = { JSON_OBJ_DESCR_PRIM(Device, name, JSON_TOK_STRING), - JSON_OBJ_DESCR_ARRAY(Device, hostDevices, aos::cMaxNumHostDevices, hostDevicesLen, JSON_TOK_STRING), + JSON_OBJ_DESCR_ARRAY(Device, hostDevices, cMaxNumHostDevices, hostDevicesLen, JSON_TOK_STRING), JSON_OBJ_DESCR_PRIM(Device, sharedCount, JSON_TOK_NUMBER), - JSON_OBJ_DESCR_ARRAY(Device, groups, aos::cMaxNumGroups, groupsLen, JSON_TOK_STRING), + JSON_OBJ_DESCR_ARRAY(Device, groups, cMaxNumGroups, groupsLen, JSON_TOK_STRING), }; /** @@ -103,7 +103,7 @@ static const struct json_obj_descr cFSMountDescr[] = { JSON_OBJ_DESCR_PRIM(FSMount, destination, JSON_TOK_STRING), JSON_OBJ_DESCR_PRIM(FSMount, source, JSON_TOK_STRING), JSON_OBJ_DESCR_PRIM(FSMount, type, JSON_TOK_STRING), - JSON_OBJ_DESCR_ARRAY(FSMount, options, aos::cFSMountMaxNumOptions, optionsLen, JSON_TOK_STRING), + JSON_OBJ_DESCR_ARRAY(FSMount, options, cFSMountMaxNumOptions, optionsLen, JSON_TOK_STRING), }; /** @@ -119,11 +119,10 @@ static const struct json_obj_descr cHostDescr[] = { */ static const struct json_obj_descr cResourceDescr[] = { JSON_OBJ_DESCR_PRIM(Resource, name, JSON_TOK_STRING), - JSON_OBJ_DESCR_ARRAY(Resource, groups, aos::cMaxNumGroups, groupsLen, JSON_TOK_STRING), - JSON_OBJ_DESCR_OBJ_ARRAY( - Resource, mounts, aos::cMaxNumFSMounts, mountsLen, cFSMountDescr, ARRAY_SIZE(cFSMountDescr)), - JSON_OBJ_DESCR_ARRAY(Resource, env, aos::cMaxNumEnvVariables, envLen, JSON_TOK_STRING), - JSON_OBJ_DESCR_OBJ_ARRAY(Resource, hosts, aos::cMaxNumHosts, hostsLen, cHostDescr, ARRAY_SIZE(cHostDescr)), + JSON_OBJ_DESCR_ARRAY(Resource, groups, cMaxNumGroups, groupsLen, JSON_TOK_STRING), + JSON_OBJ_DESCR_OBJ_ARRAY(Resource, mounts, cMaxNumFSMounts, mountsLen, cFSMountDescr, ARRAY_SIZE(cFSMountDescr)), + JSON_OBJ_DESCR_ARRAY(Resource, env, cMaxNumEnvVariables, envLen, JSON_TOK_STRING), + JSON_OBJ_DESCR_OBJ_ARRAY(Resource, hosts, cMaxNumHosts, hostsLen, cHostDescr, ARRAY_SIZE(cHostDescr)), }; /** @@ -132,11 +131,10 @@ static const struct json_obj_descr cResourceDescr[] = { static const struct json_obj_descr cNodeConfigDescr[] = { JSON_OBJ_DESCR_PRIM(NodeConfig, version, JSON_TOK_STRING), JSON_OBJ_DESCR_PRIM(NodeConfig, nodeType, JSON_TOK_STRING), + JSON_OBJ_DESCR_OBJ_ARRAY(NodeConfig, devices, cMaxNumDevices, devicesLen, cDeviceDescr, ARRAY_SIZE(cDeviceDescr)), JSON_OBJ_DESCR_OBJ_ARRAY( - NodeConfig, devices, aos::cMaxNumDevices, devicesLen, cDeviceDescr, ARRAY_SIZE(cDeviceDescr)), - JSON_OBJ_DESCR_OBJ_ARRAY( - NodeConfig, resources, aos::cMaxNumNodeResources, resourcesLen, cResourceDescr, ARRAY_SIZE(cResourceDescr)), - JSON_OBJ_DESCR_ARRAY(NodeConfig, labels, aos::cMaxNumNodeLabels, labelsLen, JSON_TOK_STRING), + NodeConfig, resources, cMaxNumNodeResources, resourcesLen, cResourceDescr, ARRAY_SIZE(cResourceDescr)), + JSON_OBJ_DESCR_ARRAY(NodeConfig, labels, cMaxNumNodeLabels, labelsLen, JSON_TOK_STRING), JSON_OBJ_DESCR_PRIM(NodeConfig, priority, JSON_TOK_NUMBER), }; @@ -270,7 +268,7 @@ static Error FillAosStruct(const NodeConfig& in, Array& outResourc for (size_t j = 0; j < inResourceInfo.mountsLen; ++j) { const auto& parsedMount = inResourceInfo.mounts[j]; - aos::FileSystemMount& mount = outResourceInfo.mMounts[j]; + FileSystemMount& mount = outResourceInfo.mMounts[j]; mount.mDestination = parsedMount.destination; mount.mType = parsedMount.type; From 08eed5b6644b46de4a73743bac408b8054d233fb Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 7 Nov 2024 13:18:33 +0200 Subject: [PATCH 190/198] [tests,communication] Refactor transportstub.hpp mutex wrappers Signed-off-by: Oleksandr Grytsov --- tests/communication/src/stubs/transportstub.hpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/communication/src/stubs/transportstub.hpp b/tests/communication/src/stubs/transportstub.hpp index 2f2afe26..6c32d237 100644 --- a/tests/communication/src/stubs/transportstub.hpp +++ b/tests/communication/src/stubs/transportstub.hpp @@ -17,14 +17,15 @@ class Pipe { void Write(const uint8_t* data, size_t size) { - std::unique_lock lock(mMutex); + std::lock_guard lock {mMutex}; + mBuffer.insert(mBuffer.end(), data, data + size); mCondVar.notify_one(); } size_t Read(uint8_t* data, size_t size) { - std::unique_lock lock(mMutex); + std::unique_lock lock {mMutex}; mCondVar.wait(lock, [this] { return !mBuffer.empty() || mClosed; }); if (mClosed || mBuffer.empty()) { @@ -32,17 +33,17 @@ class Pipe { } size_t bytesRead = std::min(size, mBuffer.size()); + std::copy(mBuffer.begin(), mBuffer.begin() + bytesRead, data); mBuffer.erase(mBuffer.begin(), mBuffer.begin() + bytesRead); - std::cout << "Read " << bytesRead << " bytes" << std::endl; - return bytesRead; } void Close() { - std::unique_lock lock(mMutex); + std::lock_guard lock {mMutex}; + mClosed = true; mCondVar.notify_all(); } @@ -73,6 +74,7 @@ class TransportStub : public TransportItf { Error Close() override { mIsOpened.store(false); + return ErrorEnum::eNone; } From 986fb7e1da17d7364f4223f5788a3d951dcee93a Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Thu, 7 Nov 2024 13:19:20 +0200 Subject: [PATCH 191/198] [nodeinfoprovider] Use AOS_ERROR_WRAP for initial error Signed-off-by: Oleksandr Grytsov --- src/nodeinfoprovider/nodeinfoprovider.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nodeinfoprovider/nodeinfoprovider.cpp b/src/nodeinfoprovider/nodeinfoprovider.cpp index b22bf9a8..1802f7ad 100644 --- a/src/nodeinfoprovider/nodeinfoprovider.cpp +++ b/src/nodeinfoprovider/nodeinfoprovider.cpp @@ -34,7 +34,7 @@ Error NodeInfoProvider::Init() LOG_DBG() << "Init node info provider"; if (auto err = InitNodeID(); !err.IsNone() && !err.Is(ErrorEnum::eNotSupported)) { - return Error(AOS_ERROR_WRAP(err), "failed to init node id"); + return AOS_ERROR_WRAP(Error(err, "failed to init node id")); } xenstat xstat {}; From c5813042036619be585f220f66150409b3970bce Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 13 Nov 2024 14:33:49 +0200 Subject: [PATCH 192/198] [iamclient,smclient] Add stack usage log Signed-off-by: Oleksandr Grytsov --- src/iamclient/iamclient.cpp | 4 ++++ src/smclient/smclient.cpp | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index b7b7395e..dedeae8e 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -306,6 +306,10 @@ void IAMClient::HandleChannels() continue; } +#if AOS_CONFIG_THREAD_STACK_USAGE + LOG_DBG() << "Stack usage: size=" << mThread.GetStackUsage(); +#endif + if (!WaitReconnect(lock)) { continue; } diff --git a/src/smclient/smclient.cpp b/src/smclient/smclient.cpp index 65c3482f..0f1b1347 100644 --- a/src/smclient/smclient.cpp +++ b/src/smclient/smclient.cpp @@ -168,9 +168,7 @@ Error SMClient::Stop() mCondVar.NotifyOne(); } - mThread.Join(); - - return ErrorEnum::eNone; + return mThread.Join(); } Error SMClient::InstancesRunStatus(const Array& instances) @@ -686,6 +684,10 @@ void SMClient::HandleChannel() continue; } +#if AOS_CONFIG_THREAD_STACK_USAGE + LOG_DBG() << "Stack usage: size=" << mThread.GetStackUsage(); +#endif + mCondVar.Wait(lock, [this]() { return !mClockSynced || !mProvisioned || mClose || mCertificateChanged; }); } } From 75e52200da47008774505a0d875007f304cf3cb5 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 13 Nov 2024 14:41:34 +0200 Subject: [PATCH 193/198] Revert "[iamclient] Remove condition on send info" This reverts commit 79ee18308c9ea376f9d7faab2a5d17326df77206. These changes were done as WA to properly notify cloud. Now the issue is resolved in CM and WA can be removed. --- src/iamclient/iamclient.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index dedeae8e..59b9e7a9 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -131,15 +131,20 @@ Error IAMClient::OnNodeStatusChanged(const String& nodeID, const NodeStatus& sta return ErrorEnum::eNone; } + auto sendNodeInfo = true; + if (mNodeInfo.mStatus == NodeStatusEnum::eUnprovisioned || status == NodeStatusEnum::eUnprovisioned) { - mReconnect = true; + sendNodeInfo = false; + mReconnect = true; mCondVar.NotifyOne(); } mNodeInfo.mStatus = status; - if (auto err = SendNodeInfo(); !err.IsNone()) { - return err; + if (sendNodeInfo) { + if (auto err = SendNodeInfo(); !err.IsNone()) { + return err; + } } return ErrorEnum::eNone; From 4d6e894c7b96d2730365dfb11ac5a5173bb0d941 Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 15 Nov 2024 11:17:12 +0200 Subject: [PATCH 194/198] [prj.conf] Switch libc to newlibc picolibc has compilation issue with latest zephyr sdk 0.17. Switch to newlibc as it doesn't have this issue. Signed-off-by: Oleksandr Grytsov --- prj.conf | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/prj.conf b/prj.conf index 065fae05..30f91a6e 100644 --- a/prj.conf +++ b/prj.conf @@ -18,8 +18,9 @@ CONFIG_USERSPACE=y CONFIG_MAIN_STACK_SIZE=32768 CONFIG_ISR_STACK_SIZE=8192 -# Select libc -CONFIG_PICOLIBC=y +# Select lib +CONFIG_NEWLIB_LIBC=y +CONFIG_NEWLIB_LIBC_NANO=n # Increase KOBJECT RODATA CONFIG_KOBJECT_RODATA_AREA_EXTRA_BYTES=2048 From ce6f77306e49596e833b024dcaac8539349a8ced Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Wed, 20 Nov 2024 13:50:46 +0200 Subject: [PATCH 195/198] [tests,iamclient] Update test to reverted send node info functionality Signed-off-by: Oleksandr Grytsov --- tests/iamclient/src/main.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/iamclient/src/main.cpp b/tests/iamclient/src/main.cpp index 2a5cb5ec..af6d7ff6 100644 --- a/tests/iamclient/src/main.cpp +++ b/tests/iamclient/src/main.cpp @@ -186,10 +186,6 @@ ZTEST_F(iamclient, test_FinishProvisioning) err = SendIAMIncomingMessage(channel, incomingMessage); zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); - // node info is sent prior to finish provisioning response - nodeInfo.mStatus = aos::NodeStatusEnum::eProvisioned; - ReceiveNodeInfo(channel, nodeInfo); - // Receive finish provisioning response iamanager_v5_IAMOutgoingMessages outgoingMessage; @@ -242,10 +238,6 @@ ZTEST_F(iamclient, test_Deprovision) err = SendIAMIncomingMessage(channel, incomingMessage); zassert_true(err.IsNone(), "Error sending message: %s", utils::ErrorToCStr(err)); - // node info is sent prior to deprovision response - nodeInfo.mStatus = aos::NodeStatusEnum::eUnprovisioned; - ReceiveNodeInfo(channel, nodeInfo); - // Receive deprovision response iamanager_v5_IAMOutgoingMessages outgoingMessage; From b7490fb1c4c989501520dd625e23325bff410e3c Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Mon, 25 Nov 2024 16:48:22 +0200 Subject: [PATCH 196/198] [iamclient] Fix deadlock on cert change Signed-off-by: Mykola Solianko --- src/iamclient/iamclient.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/iamclient/iamclient.cpp b/src/iamclient/iamclient.cpp index 59b9e7a9..efb6515d 100644 --- a/src/iamclient/iamclient.cpp +++ b/src/iamclient/iamclient.cpp @@ -152,8 +152,6 @@ Error IAMClient::OnNodeStatusChanged(const String& nodeID, const NodeStatus& sta void IAMClient::OnCertChanged(const iam::certhandler::CertInfo& info) { - LockGuard lock {mMutex}; - LOG_DBG() << "Cert changed event received"; mReconnect = true; From 721670581f688581c4160fbdde1617d90b3b65a4 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Tue, 26 Nov 2024 10:58:13 +0200 Subject: [PATCH 197/198] [smclient] Update to new API Signed-off-by: Mykola Solianko --- tests/smclient/src/main.cpp | 8 +++---- tests/smclient/src/stubs/launcherstub.hpp | 29 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/tests/smclient/src/main.cpp b/tests/smclient/src/main.cpp index 66318ba3..cfafd6ed 100644 --- a/tests/smclient/src/main.cpp +++ b/tests/smclient/src/main.cpp @@ -213,10 +213,10 @@ static void GenerateLayersInfo(aos::Array& layers) static void GenerateInstancesInfo(aos::Array& instances) { - instances.EmplaceBack(aos::InstanceInfo {{"service1", "subject1", 1}, 1, 1, "storage1", "state1"}); - instances.EmplaceBack(aos::InstanceInfo {{"service2", "subject2", 2}, 2, 2, "storage2", "state2"}); - instances.EmplaceBack(aos::InstanceInfo {{"service3", "subject3", 3}, 3, 3, "storage3", "state3"}); - instances.EmplaceBack(aos::InstanceInfo {{"service4", "subject4", 4}, 4, 4, "storage4", "state4"}); + instances.EmplaceBack(aos::InstanceInfo {{"service1", "subject1", 1}, {}, 1, 1, "storage1", "state1"}); + instances.EmplaceBack(aos::InstanceInfo {{"service2", "subject2", 2}, {}, 2, 2, "storage2", "state2"}); + instances.EmplaceBack(aos::InstanceInfo {{"service3", "subject3", 3}, {}, 3, 3, "storage3", "state3"}); + instances.EmplaceBack(aos::InstanceInfo {{"service4", "subject4", 4}, {}, 4, 4, "storage4", "state4"}); } static void GenerateInstancesRunStatus(aos::Array& status) diff --git a/tests/smclient/src/stubs/launcherstub.hpp b/tests/smclient/src/stubs/launcherstub.hpp index 3cff0bf7..8ca48144 100644 --- a/tests/smclient/src/stubs/launcherstub.hpp +++ b/tests/smclient/src/stubs/launcherstub.hpp @@ -32,6 +32,35 @@ class LauncherStub : public aos::sm::launcher::LauncherItf { return aos::ErrorEnum::eNone; } + /** + * Overrides environment variables for specified instances. + * + * @param envVarsInfo environment variables info. + * @param statuses[out] environment variables statuses. + * @return Error + */ + aos::Error OverrideEnvVars(const aos::Array& envVarsInfo, + aos::cloudprotocol::EnvVarsInstanceStatusArray& statuses) override + { + (void)envVarsInfo; + (void)statuses; + + return aos::ErrorEnum::eNone; + } + + /** + * Sets cloud connection status. + * + * @param connected cloud connection status. + * @return Error + */ + aos::Error SetCloudConnection(bool connected) override + { + (void)connected; + + return aos::ErrorEnum::eNone; + } + aos::Error WaitEvent(const std::chrono::duration timeout) { std::unique_lock lock(mMutex); From 961ab4dcfc18683f1e88c63e2e605786124ed380 Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Tue, 26 Nov 2024 10:59:42 +0200 Subject: [PATCH 198/198] [storage] Update to new API Signed-off-by: Mykola Solianko --- src/storage/storage.cpp | 40 +++++++++++++++++++++++++++++++++ src/storage/storage.hpp | 46 ++++++++++++++++++++++++++++++++++++++ tests/storage/src/main.cpp | 4 ++-- 3 files changed, 88 insertions(+), 2 deletions(-) diff --git a/src/storage/storage.cpp b/src/storage/storage.cpp index c191d378..8a8698a6 100644 --- a/src/storage/storage.cpp +++ b/src/storage/storage.cpp @@ -279,6 +279,44 @@ Error Storage::GetCertInfo(const Array& issuer, const Array& s return ErrorEnum::eNone; } +RetWithError Storage::GetOperationVersion() const +{ + return RetWithError(0); +} + +Error Storage::SetOperationVersion(uint64_t version) +{ + (void)version; + + return ErrorEnum::eNone; +} + +Error Storage::GetOverrideEnvVars(cloudprotocol::EnvVarsInstanceInfoArray& envVarsInstanceInfos) const +{ + (void)envVarsInstanceInfos; + + return ErrorEnum::eNone; +} + +Error Storage::SetOverrideEnvVars(const cloudprotocol::EnvVarsInstanceInfoArray& envVarsInstanceInfos) +{ + (void)envVarsInstanceInfos; + + return ErrorEnum::eNone; +} + +RetWithError