From 735dbb0c3e54528a7d5656ab39e2e469cf02dc93 Mon Sep 17 00:00:00 2001 From: Jiacheng Guo Date: Sat, 11 Sep 2021 04:24:07 +0800 Subject: [PATCH 001/255] Refactor the server to organize as a class (#9200) * Refactor the server to organize as a class * Make Server combination of small objects * fix build on zephyr * add unit test * gn restyle * fix android build * add clean shutdown * resolve multithread race --- examples/all-clusters-app/esp32/main/main.cpp | 7 +- examples/bridge-app/esp32/main/main.cpp | 2 +- examples/bridge-app/linux/main.cpp | 2 +- examples/lighting-app/efr32/src/AppTask.cpp | 2 +- examples/lighting-app/k32w/main/AppTask.cpp | 5 +- examples/lighting-app/mbed/CMakeLists.txt | 1 + examples/lighting-app/mbed/main/AppTask.cpp | 2 +- .../lighting-app/nrfconnect/CMakeLists.txt | 1 + .../lighting-app/nrfconnect/main/AppTask.cpp | 6 +- examples/lighting-app/qpg/src/AppTask.cpp | 4 +- examples/lighting-app/telink/CMakeLists.txt | 1 + examples/lighting-app/telink/src/AppTask.cpp | 4 +- .../lock-app/cc13x2x7_26x2x7/main/AppTask.cpp | 5 +- examples/lock-app/efr32/src/AppTask.cpp | 2 +- examples/lock-app/esp32/main/main.cpp | 2 +- examples/lock-app/k32w/main/AppTask.cpp | 5 +- examples/lock-app/mbed/CMakeLists.txt | 1 + examples/lock-app/mbed/main/AppTask.cpp | 2 +- examples/lock-app/nrfconnect/CMakeLists.txt | 1 + examples/lock-app/nrfconnect/main/AppTask.cpp | 6 +- examples/lock-app/p6/src/AppTask.cpp | 2 +- examples/lock-app/qpg/src/AppTask.cpp | 5 +- examples/ota-provider-app/linux/main.cpp | 2 +- examples/platform/linux/AppMain.cpp | 10 +- .../linux/CommissioneeShellCommands.cpp | 2 +- .../pump-app/cc13x2x7_26x2x7/main/AppTask.cpp | 5 +- examples/pump-app/nrfconnect/CMakeLists.txt | 1 + examples/pump-app/nrfconnect/main/AppTask.cpp | 6 +- .../cc13x2x7_26x2x7/main/AppTask.cpp | 5 +- .../nrfconnect/CMakeLists.txt | 1 + .../nrfconnect/main/AppTask.cpp | 6 +- .../esp32/main/main.cpp | 2 +- examples/tv-casting-app/linux/main.cpp | 5 +- examples/window-app/common/src/WindowApp.cpp | 2 +- .../administrator-commissioning-server.cpp | 13 +- .../operational-credentials-server.cpp | 14 +- src/app/server/BUILD.gn | 2 + src/app/server/CommissionManager.cpp | 177 ++++++++ src/app/server/CommissionManager.h | 84 ++++ src/app/server/Mdns.cpp | 4 +- src/app/server/RendezvousServer.h | 4 +- src/app/server/Server.cpp | 410 ++++-------------- src/app/server/Server.h | 142 +++--- src/app/server/SessionManager.h | 24 - src/app/tests/BUILD.gn | 7 + src/app/tests/TestCommissionManager.cpp | 173 ++++++++ src/controller/CHIPDeviceController.h | 4 +- .../secure_channel/RendezvousParameters.h | 8 +- 48 files changed, 708 insertions(+), 473 deletions(-) create mode 100644 src/app/server/CommissionManager.cpp create mode 100644 src/app/server/CommissionManager.h delete mode 100644 src/app/server/SessionManager.h create mode 100644 src/app/tests/TestCommissionManager.cpp diff --git a/examples/all-clusters-app/esp32/main/main.cpp b/examples/all-clusters-app/esp32/main/main.cpp index 72f5f8545bfb9d..b03f796547d431 100644 --- a/examples/all-clusters-app/esp32/main/main.cpp +++ b/examples/all-clusters-app/esp32/main/main.cpp @@ -346,7 +346,7 @@ class SetupListModel : public ListScreen::Model if (i == 0) { ConnectivityMgr().ClearWiFiStationProvision(); - OpenBasicCommissioningWindow(ResetFabrics::kYes); + chip::Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow(ResetFabrics::kYes); } else if (i == 1) { @@ -355,7 +355,8 @@ class SetupListModel : public ListScreen::Model else if (i == 2) { app::Mdns::AdvertiseCommissionableNode(app::Mdns::CommissioningMode::kEnabledBasic); - OpenBasicCommissioningWindow(ResetFabrics::kYes, kNoCommissioningTimeout, PairingWindowAdvertisement::kMdns); + chip::Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow( + ResetFabrics::kYes, kNoCommissioningTimeout, CommissioningWindowAdvertisement::kMdns); } } @@ -627,7 +628,7 @@ extern "C" void app_main() // Init ZCL Data Model and CHIP App Server AppCallbacks callbacks; - InitServer(&callbacks); + chip::Server::GetInstance().Init(&callbacks); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/bridge-app/esp32/main/main.cpp b/examples/bridge-app/esp32/main/main.cpp index de1fb5ef3a860a..ad2420ded777ca 100644 --- a/examples/bridge-app/esp32/main/main.cpp +++ b/examples/bridge-app/esp32/main/main.cpp @@ -390,7 +390,7 @@ extern "C" void app_main() return; } - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/bridge-app/linux/main.cpp b/examples/bridge-app/linux/main.cpp index 17638f8ff51e14..9d4f08c1b07eb0 100644 --- a/examples/bridge-app/linux/main.cpp +++ b/examples/bridge-app/linux/main.cpp @@ -513,7 +513,7 @@ int main(int argc, char * argv[]) chip::DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(true); // Init ZCL Data Model and CHIP App Server - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/lighting-app/efr32/src/AppTask.cpp b/examples/lighting-app/efr32/src/AppTask.cpp index 4aadec1a576e09..728fe97e5d3c3f 100644 --- a/examples/lighting-app/efr32/src/AppTask.cpp +++ b/examples/lighting-app/efr32/src/AppTask.cpp @@ -108,7 +108,7 @@ CHIP_ERROR AppTask::Init() CHIP_ERROR err = CHIP_NO_ERROR; // Init ZCL Data Model - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/lighting-app/k32w/main/AppTask.cpp b/examples/lighting-app/k32w/main/AppTask.cpp index f5d6657e37d244..9e7428f26875a1 100644 --- a/examples/lighting-app/k32w/main/AppTask.cpp +++ b/examples/lighting-app/k32w/main/AppTask.cpp @@ -88,7 +88,7 @@ CHIP_ERROR AppTask::Init() CHIP_ERROR err = CHIP_NO_ERROR; // Init ZCL Data Model and start server - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -489,7 +489,8 @@ void AppTask::BleHandler(AppEvent * aEvent) { ConnectivityMgr().SetBLEAdvertisingEnabled(true); - if (OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) == CHIP_NO_ERROR) + if (chip::Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) == + CHIP_NO_ERROR) { K32W_LOG("Started BLE Advertising!"); } diff --git a/examples/lighting-app/mbed/CMakeLists.txt b/examples/lighting-app/mbed/CMakeLists.txt index b1e213d986e63f..09b957bc817706 100644 --- a/examples/lighting-app/mbed/CMakeLists.txt +++ b/examples/lighting-app/mbed/CMakeLists.txt @@ -74,6 +74,7 @@ target_sources(${APP_TARGET} PRIVATE ${CHIP_ROOT}/src/app/server/OnboardingCodesUtil.cpp ${CHIP_ROOT}/src/app/server/RendezvousServer.cpp ${CHIP_ROOT}/src/app/server/Server.cpp + ${CHIP_ROOT}/src/app/server/CommissionManager.cpp ${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp ${CHIP_ROOT}/src/app/clusters/basic/basic.cpp ${CHIP_ROOT}/src/app/clusters/bindings/bindings.cpp diff --git a/examples/lighting-app/mbed/main/AppTask.cpp b/examples/lighting-app/mbed/main/AppTask.cpp index 9c755869af8fa8..08f48fb5c11405 100644 --- a/examples/lighting-app/mbed/main/AppTask.cpp +++ b/examples/lighting-app/mbed/main/AppTask.cpp @@ -116,7 +116,7 @@ int AppTask::Init() chip::DeviceLayer::ConnectivityMgrImpl().StartWiFiManagement(); // Init ZCL Data Model and start server - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/lighting-app/nrfconnect/CMakeLists.txt b/examples/lighting-app/nrfconnect/CMakeLists.txt index 085aa62b850504..d9f311efc10e7d 100644 --- a/examples/lighting-app/nrfconnect/CMakeLists.txt +++ b/examples/lighting-app/nrfconnect/CMakeLists.txt @@ -94,6 +94,7 @@ target_sources(app PRIVATE ${CHIP_ROOT}/src/app/server/OnboardingCodesUtil.cpp ${CHIP_ROOT}/src/app/server/RendezvousServer.cpp ${CHIP_ROOT}/src/app/server/Server.cpp + ${CHIP_ROOT}/src/app/server/CommissionManager.cpp ${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp ${CHIP_ROOT}/src/app/clusters/basic/basic.cpp ${CHIP_ROOT}/src/app/clusters/bindings/bindings.cpp diff --git a/examples/lighting-app/nrfconnect/main/AppTask.cpp b/examples/lighting-app/nrfconnect/main/AppTask.cpp index ca4823182f89be..ad42a405433237 100644 --- a/examples/lighting-app/nrfconnect/main/AppTask.cpp +++ b/examples/lighting-app/nrfconnect/main/AppTask.cpp @@ -106,7 +106,7 @@ int AppTask::Init() LightingMgr().SetCallbacks(ActionInitiated, ActionCompleted); // Init ZCL Data Model and start server - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -352,7 +352,7 @@ void AppTask::StartThreadHandler(AppEvent * aEvent) if (aEvent->ButtonEvent.PinNo != THREAD_START_BUTTON) return; - if (AddTestCommissioning() != CHIP_NO_ERROR) + if (chip::Server::GetInstance().AddTestCommissioning() != CHIP_NO_ERROR) { LOG_ERR("Failed to add test pairing"); } @@ -386,7 +386,7 @@ void AppTask::StartBLEAdvertisementHandler(AppEvent * aEvent) return; } - if (OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) != CHIP_NO_ERROR) + if (chip::Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) != CHIP_NO_ERROR) { LOG_ERR("OpenBasicCommissioningWindow() failed"); } diff --git a/examples/lighting-app/qpg/src/AppTask.cpp b/examples/lighting-app/qpg/src/AppTask.cpp index 011a19fa4283a1..8cdf66e9ad1625 100644 --- a/examples/lighting-app/qpg/src/AppTask.cpp +++ b/examples/lighting-app/qpg/src/AppTask.cpp @@ -100,7 +100,7 @@ CHIP_ERROR AppTask::Init() qvCHIP_SetBtnCallback(ButtonEventHandler); // Init ZCL Data Model - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -111,7 +111,7 @@ CHIP_ERROR AppTask::Init() PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); // Enable BLE advertisements - OpenBasicCommissioningWindow(chip::ResetFabrics::kNo); + chip::Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow(chip::ResetFabrics::kNo); ChipLogProgress(NotSpecified, "BLE advertising started. Waiting for Pairing."); return err; diff --git a/examples/lighting-app/telink/CMakeLists.txt b/examples/lighting-app/telink/CMakeLists.txt index 435718cce09672..00a4502e868e2a 100644 --- a/examples/lighting-app/telink/CMakeLists.txt +++ b/examples/lighting-app/telink/CMakeLists.txt @@ -76,6 +76,7 @@ target_sources(app PRIVATE ${CHIP_ROOT}/src/app/server/OnboardingCodesUtil.cpp ${CHIP_ROOT}/src/app/server/RendezvousServer.cpp ${CHIP_ROOT}/src/app/server/Server.cpp + ${CHIP_ROOT}/src/app/server/CommissionManager.cpp ${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp ${CHIP_ROOT}/src/app/clusters/basic/basic.cpp ${CHIP_ROOT}/src/app/clusters/bindings/bindings.cpp diff --git a/examples/lighting-app/telink/src/AppTask.cpp b/examples/lighting-app/telink/src/AppTask.cpp index dc344e69d94c3a..652f07822ccdb6 100644 --- a/examples/lighting-app/telink/src/AppTask.cpp +++ b/examples/lighting-app/telink/src/AppTask.cpp @@ -98,7 +98,7 @@ CHIP_ERROR AppTask::Init() LightingMgr().SetCallbacks(ActionInitiated, ActionCompleted); // Init ZCL Data Model and start server - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -106,7 +106,7 @@ CHIP_ERROR AppTask::Init() ConfigurationMgr().LogDeviceConfig(); PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); - ret = AddTestCommissioning(); + ret = chip::Server::GetInstance().AddTestCommissioning(); if (ret != CHIP_NO_ERROR) { LOG_ERR("Failed to add test pairing"); diff --git a/examples/lock-app/cc13x2x7_26x2x7/main/AppTask.cpp b/examples/lock-app/cc13x2x7_26x2x7/main/AppTask.cpp index 16510c56dad81d..fe663af7ddadec 100644 --- a/examples/lock-app/cc13x2x7_26x2x7/main/AppTask.cpp +++ b/examples/lock-app/cc13x2x7_26x2x7/main/AppTask.cpp @@ -144,7 +144,7 @@ int AppTask::Init() // Init ZCL Data Model and start server PLAT_LOG("Initialize Server"); - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -333,7 +333,8 @@ void AppTask::DispatchEvent(AppEvent * aEvent) // Enable BLE advertisements if (!ConnectivityMgr().IsBLEAdvertisingEnabled()) { - if (OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) == CHIP_NO_ERROR) + if (chip::Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) == + CHIP_NO_ERROR) { PLAT_LOG("Enabled BLE Advertisement"); } diff --git a/examples/lock-app/efr32/src/AppTask.cpp b/examples/lock-app/efr32/src/AppTask.cpp index ce1712bdbbcb11..bfbfc3eee581a3 100644 --- a/examples/lock-app/efr32/src/AppTask.cpp +++ b/examples/lock-app/efr32/src/AppTask.cpp @@ -100,7 +100,7 @@ CHIP_ERROR AppTask::StartAppTask() CHIP_ERROR AppTask::Init() { // Init ZCL Data Model - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/lock-app/esp32/main/main.cpp b/examples/lock-app/esp32/main/main.cpp index 3a31d195180b89..15e00f649b623a 100644 --- a/examples/lock-app/esp32/main/main.cpp +++ b/examples/lock-app/esp32/main/main.cpp @@ -85,7 +85,7 @@ extern "C" void app_main() return; } - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/lock-app/k32w/main/AppTask.cpp b/examples/lock-app/k32w/main/AppTask.cpp index f50c5550ae63da..38c570972ad70e 100644 --- a/examples/lock-app/k32w/main/AppTask.cpp +++ b/examples/lock-app/k32w/main/AppTask.cpp @@ -87,7 +87,7 @@ CHIP_ERROR AppTask::Init() CHIP_ERROR err = CHIP_NO_ERROR; // Init ZCL Data Model and start server - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -528,7 +528,8 @@ void AppTask::BleHandler(void * aGenericEvent) { ConnectivityMgr().SetBLEAdvertisingEnabled(true); - if (OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) == CHIP_NO_ERROR) + if (chip::Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) == + CHIP_NO_ERROR) { K32W_LOG("Started BLE Advertising!"); } diff --git a/examples/lock-app/mbed/CMakeLists.txt b/examples/lock-app/mbed/CMakeLists.txt index 5400170fb73864..07f08335ac9658 100644 --- a/examples/lock-app/mbed/CMakeLists.txt +++ b/examples/lock-app/mbed/CMakeLists.txt @@ -73,6 +73,7 @@ target_sources(${APP_TARGET} PRIVATE ${CHIP_ROOT}/src/app/server/OnboardingCodesUtil.cpp ${CHIP_ROOT}/src/app/server/RendezvousServer.cpp ${CHIP_ROOT}/src/app/server/Server.cpp + ${CHIP_ROOT}/src/app/server/CommissionManager.cpp ${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp ${CHIP_ROOT}/src/app/clusters/basic/basic.cpp ${CHIP_ROOT}/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp diff --git a/examples/lock-app/mbed/main/AppTask.cpp b/examples/lock-app/mbed/main/AppTask.cpp index fe15f5b43f9771..33a96bb4946768 100644 --- a/examples/lock-app/mbed/main/AppTask.cpp +++ b/examples/lock-app/mbed/main/AppTask.cpp @@ -120,7 +120,7 @@ int AppTask::Init() chip::DeviceLayer::ConnectivityMgrImpl().StartWiFiManagement(); // Init ZCL Data Model and start server - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/lock-app/nrfconnect/CMakeLists.txt b/examples/lock-app/nrfconnect/CMakeLists.txt index 3e3406e4e65af5..37f2d81233b37e 100644 --- a/examples/lock-app/nrfconnect/CMakeLists.txt +++ b/examples/lock-app/nrfconnect/CMakeLists.txt @@ -92,6 +92,7 @@ target_sources(app PRIVATE ${CHIP_ROOT}/src/app/server/OnboardingCodesUtil.cpp ${CHIP_ROOT}/src/app/server/RendezvousServer.cpp ${CHIP_ROOT}/src/app/server/Server.cpp + ${CHIP_ROOT}/src/app/server/CommissionManager.cpp ${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp ${CHIP_ROOT}/src/app/clusters/basic/basic.cpp ${CHIP_ROOT}/src/app/clusters/bindings/bindings.cpp diff --git a/examples/lock-app/nrfconnect/main/AppTask.cpp b/examples/lock-app/nrfconnect/main/AppTask.cpp index 43364949d48fb7..b178d107b1d6a3 100644 --- a/examples/lock-app/nrfconnect/main/AppTask.cpp +++ b/examples/lock-app/nrfconnect/main/AppTask.cpp @@ -97,7 +97,7 @@ int AppTask::Init() BoltLockMgr().SetCallbacks(ActionInitiated, ActionCompleted); // Init ZCL Data Model and start server - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -352,7 +352,7 @@ void AppTask::StartThreadHandler(AppEvent * aEvent) if (aEvent->ButtonEvent.PinNo != THREAD_START_BUTTON) return; - if (AddTestCommissioning() != CHIP_NO_ERROR) + if (chip::Server::GetInstance().AddTestCommissioning() != CHIP_NO_ERROR) { LOG_ERR("Failed to add test pairing"); } @@ -386,7 +386,7 @@ void AppTask::StartBLEAdvertisementHandler(AppEvent * aEvent) return; } - if (OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) != CHIP_NO_ERROR) + if (chip::Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) != CHIP_NO_ERROR) { LOG_ERR("OpenBasicCommissioningWindow() failed"); } diff --git a/examples/lock-app/p6/src/AppTask.cpp b/examples/lock-app/p6/src/AppTask.cpp index a67598472228a3..746e3d4ae71210 100644 --- a/examples/lock-app/p6/src/AppTask.cpp +++ b/examples/lock-app/p6/src/AppTask.cpp @@ -102,7 +102,7 @@ CHIP_ERROR AppTask::Init() }, 0); // Init ZCL Data Model - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/lock-app/qpg/src/AppTask.cpp b/examples/lock-app/qpg/src/AppTask.cpp index 4496cf9cc67b01..b1f73f8d13392f 100644 --- a/examples/lock-app/qpg/src/AppTask.cpp +++ b/examples/lock-app/qpg/src/AppTask.cpp @@ -103,7 +103,7 @@ CHIP_ERROR AppTask::Init() qvCHIP_LedSet(LOCK_STATE_LED, !BoltLockMgr().IsUnlocked()); // Init ZCL Data Model - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -350,7 +350,8 @@ void AppTask::FunctionHandler(AppEvent * aEvent) if (!ConnectivityMgr().IsThreadProvisioned()) { // Enable BLE advertisements and pairing window - if (OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) == CHIP_NO_ERROR) + if (chip::Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) == + CHIP_NO_ERROR) { ChipLogProgress(NotSpecified, "BLE advertising started. Waiting for Pairing."); } diff --git a/examples/ota-provider-app/linux/main.cpp b/examples/ota-provider-app/linux/main.cpp index 0f5a771cf891e7..e94d96f6a993fc 100644 --- a/examples/ota-provider-app/linux/main.cpp +++ b/examples/ota-provider-app/linux/main.cpp @@ -121,7 +121,7 @@ int main(int argc, char * argv[]) } chip::DeviceLayer::ConfigurationMgr().LogDeviceConfig(); - InitServer(); + chip::Server::GetInstance().Init(); exchangeMgr = chip::ExchangeManager(); err = exchangeMgr->RegisterUnsolicitedMessageHandlerForProtocol(chip::Protocols::BDX::Id, &bdxServer); diff --git a/examples/platform/linux/AppMain.cpp b/examples/platform/linux/AppMain.cpp index 96252b465fcf7a..8b8ce6ff9e6cba 100644 --- a/examples/platform/linux/AppMain.cpp +++ b/examples/platform/linux/AppMain.cpp @@ -265,17 +265,17 @@ void ChipLinuxAppMainLoop() std::thread shellThread([]() { Engine::Root().RunMainLoop(); }); chip::Shell::RegisterCommissioneeCommands(); #endif + uint16_t securePort = CHIP_PORT; + uint16_t unsecurePort = CHIP_UDC_PORT; #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE // use a different service port to make testing possible with other sample devices running on same host - ServerConfigParams params; - params.securedServicePort = LinuxDeviceOptions::GetInstance().securedDevicePort; - params.unsecuredServicePort = LinuxDeviceOptions::GetInstance().unsecuredCommissionerPort; - SetServerConfig(params); + securePort = LinuxDeviceOptions::GetInstance().securedDevicePort; + unsecurePort = LinuxDeviceOptions::GetInstance().unsecuredCommissionerPort; #endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE // Init ZCL Data Model and CHIP App Server - InitServer(); + chip::Server::GetInstance().Init(nullptr, securePort, unsecurePort); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/platform/linux/CommissioneeShellCommands.cpp b/examples/platform/linux/CommissioneeShellCommands.cpp index bb356e7bbd806a..24bb09856ffe66 100644 --- a/examples/platform/linux/CommissioneeShellCommands.cpp +++ b/examples/platform/linux/CommissioneeShellCommands.cpp @@ -46,7 +46,7 @@ static CHIP_ERROR SendUDC(bool printHeader, chip::Transport::PeerAddress commiss streamer_printf(sout, "SendUDC: "); } - SendUserDirectedCommissioningRequest(commissioner); + Server::GetInstance().SendUserDirectedCommissioningRequest(commissioner); streamer_printf(sout, "done\r\n"); diff --git a/examples/pump-app/cc13x2x7_26x2x7/main/AppTask.cpp b/examples/pump-app/cc13x2x7_26x2x7/main/AppTask.cpp index ef76464d5f0132..dc98dac5b73ccc 100644 --- a/examples/pump-app/cc13x2x7_26x2x7/main/AppTask.cpp +++ b/examples/pump-app/cc13x2x7_26x2x7/main/AppTask.cpp @@ -146,7 +146,7 @@ int AppTask::Init() // Init ZCL Data Model and start server PLAT_LOG("Initialize Server"); - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -335,7 +335,8 @@ void AppTask::DispatchEvent(AppEvent * aEvent) // Enable BLE advertisements if (!ConnectivityMgr().IsBLEAdvertisingEnabled()) { - if (OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) == CHIP_NO_ERROR) + if (chip::Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) == + CHIP_NO_ERROR) { PLAT_LOG("Enabled BLE Advertisement"); } diff --git a/examples/pump-app/nrfconnect/CMakeLists.txt b/examples/pump-app/nrfconnect/CMakeLists.txt index f2e81074cdf1a5..11ccf3ea1cd0d7 100644 --- a/examples/pump-app/nrfconnect/CMakeLists.txt +++ b/examples/pump-app/nrfconnect/CMakeLists.txt @@ -92,6 +92,7 @@ target_sources(app PRIVATE ${CHIP_ROOT}/src/app/server/OnboardingCodesUtil.cpp ${CHIP_ROOT}/src/app/server/RendezvousServer.cpp ${CHIP_ROOT}/src/app/server/Server.cpp + ${CHIP_ROOT}/src/app/server/CommissionManager.cpp ${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp ${CHIP_ROOT}/src/app/clusters/basic/basic.cpp ${CHIP_ROOT}/src/app/clusters/bindings/bindings.cpp diff --git a/examples/pump-app/nrfconnect/main/AppTask.cpp b/examples/pump-app/nrfconnect/main/AppTask.cpp index f8ea7e8ed10f0f..5fceff922cbc29 100644 --- a/examples/pump-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-app/nrfconnect/main/AppTask.cpp @@ -97,7 +97,7 @@ int AppTask::Init() PumpMgr().SetCallbacks(ActionInitiated, ActionCompleted); // Init ZCL Data Model and start server - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -352,7 +352,7 @@ void AppTask::StartThreadHandler(AppEvent * aEvent) if (aEvent->ButtonEvent.PinNo != THREAD_START_BUTTON) return; - if (AddTestCommissioning() != CHIP_NO_ERROR) + if (chip::Server::GetInstance().AddTestCommissioning() != CHIP_NO_ERROR) { LOG_ERR("Failed to add test pairing"); } @@ -386,7 +386,7 @@ void AppTask::StartBLEAdvertisementHandler(AppEvent * aEvent) return; } - if (OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) != CHIP_NO_ERROR) + if (chip::Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) != CHIP_NO_ERROR) { LOG_ERR("OpenBasicCommissioningWindow() failed"); } diff --git a/examples/pump-controller-app/cc13x2x7_26x2x7/main/AppTask.cpp b/examples/pump-controller-app/cc13x2x7_26x2x7/main/AppTask.cpp index c5141dd07c60fd..f575e9a371581c 100644 --- a/examples/pump-controller-app/cc13x2x7_26x2x7/main/AppTask.cpp +++ b/examples/pump-controller-app/cc13x2x7_26x2x7/main/AppTask.cpp @@ -146,7 +146,7 @@ int AppTask::Init() // Init ZCL Data Model and start server PLAT_LOG("Initialize Server"); - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -335,7 +335,8 @@ void AppTask::DispatchEvent(AppEvent * aEvent) // Enable BLE advertisements if (!ConnectivityMgr().IsBLEAdvertisingEnabled()) { - if (OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) == CHIP_NO_ERROR) + if (chip::Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) == + CHIP_NO_ERROR) { PLAT_LOG("Enabled BLE Advertisement"); } diff --git a/examples/pump-controller-app/nrfconnect/CMakeLists.txt b/examples/pump-controller-app/nrfconnect/CMakeLists.txt index e0546b3e3f62da..8e34f835ec2030 100644 --- a/examples/pump-controller-app/nrfconnect/CMakeLists.txt +++ b/examples/pump-controller-app/nrfconnect/CMakeLists.txt @@ -92,6 +92,7 @@ target_sources(app PRIVATE ${CHIP_ROOT}/src/app/server/OnboardingCodesUtil.cpp ${CHIP_ROOT}/src/app/server/RendezvousServer.cpp ${CHIP_ROOT}/src/app/server/Server.cpp + ${CHIP_ROOT}/src/app/server/CommissionManager.cpp ${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp ${CHIP_ROOT}/src/app/clusters/basic/basic.cpp ${CHIP_ROOT}/src/app/clusters/bindings/bindings.cpp diff --git a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp index f8ea7e8ed10f0f..5fceff922cbc29 100644 --- a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp @@ -97,7 +97,7 @@ int AppTask::Init() PumpMgr().SetCallbacks(ActionInitiated, ActionCompleted); // Init ZCL Data Model and start server - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -352,7 +352,7 @@ void AppTask::StartThreadHandler(AppEvent * aEvent) if (aEvent->ButtonEvent.PinNo != THREAD_START_BUTTON) return; - if (AddTestCommissioning() != CHIP_NO_ERROR) + if (chip::Server::GetInstance().AddTestCommissioning() != CHIP_NO_ERROR) { LOG_ERR("Failed to add test pairing"); } @@ -386,7 +386,7 @@ void AppTask::StartBLEAdvertisementHandler(AppEvent * aEvent) return; } - if (OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) != CHIP_NO_ERROR) + if (chip::Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow(chip::ResetFabrics::kNo) != CHIP_NO_ERROR) { LOG_ERR("OpenBasicCommissioningWindow() failed"); } diff --git a/examples/temperature-measurement-app/esp32/main/main.cpp b/examples/temperature-measurement-app/esp32/main/main.cpp index 4529eaba8b13d0..df3072eac0cab0 100644 --- a/examples/temperature-measurement-app/esp32/main/main.cpp +++ b/examples/temperature-measurement-app/esp32/main/main.cpp @@ -80,7 +80,7 @@ extern "C" void app_main() return; } - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/tv-casting-app/linux/main.cpp b/examples/tv-casting-app/linux/main.cpp index 9ba381230b0f82..542c46a37329d8 100644 --- a/examples/tv-casting-app/linux/main.cpp +++ b/examples/tv-casting-app/linux/main.cpp @@ -42,8 +42,9 @@ chip::System::SocketWatchToken token; void PrepareForCommissioning(const Mdns::DiscoveredNodeData * selectedCommissioner = nullptr) { // Enter commissioning mode, open commissioning window - InitServer(); - ReturnOnFailure(OpenBasicCommissioningWindow(ResetFabrics::kYes, commissioningWindowTimeoutInSec)); + Server::GetInstance().Init(); + ReturnOnFailure(Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow(ResetFabrics::kYes, + commissioningWindowTimeoutInSec)); // Display onboarding payload chip::DeviceLayer::ConfigurationMgr().LogDeviceConfig(); diff --git a/examples/window-app/common/src/WindowApp.cpp b/examples/window-app/common/src/WindowApp.cpp index ea4d0e26fb8468..afe6c5b48c0148 100644 --- a/examples/window-app/common/src/WindowApp.cpp +++ b/examples/window-app/common/src/WindowApp.cpp @@ -69,7 +69,7 @@ WindowApp::Cover * WindowApp::GetCover(chip::EndpointId endpoint) CHIP_ERROR WindowApp::Init() { // Init ZCL Data Model - InitServer(); + chip::Server::GetInstance().Init(); // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp b/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp index fe35b8955cc160..d00de79d158dfc 100644 --- a/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp +++ b/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp @@ -43,7 +43,7 @@ bool emberAfAdministratorCommissioningClusterOpenCommissioningWindowCallback(End ChipLogProgress(Zcl, "Received command to open commissioning window"); - VerifyOrExit(!IsPairingWindowOpen(), status = EMBER_ZCL_STATUS_FAILURE); + VerifyOrExit(!Server::GetInstance().GetCommissionManager().IsPairingWindowOpen(), status = EMBER_ZCL_STATUS_FAILURE); VerifyOrExit(sizeof(verifier) == pakeVerifier.size(), status = EMBER_ZCL_STATUS_FAILURE); VerifyOrExit(iterations >= kPBKDFMinimumIterations, status = EMBER_ZCL_STATUS_FAILURE); VerifyOrExit(iterations <= kPBKDFMaximumIterations, status = EMBER_ZCL_STATUS_FAILURE); @@ -55,8 +55,8 @@ bool emberAfAdministratorCommissioningClusterOpenCommissioningWindowCallback(End memcpy(verifier.mW0, &verifierData[0], kSpake2p_WS_Length); memcpy(verifier.mL, &verifierData[kSpake2p_WS_Length], kSpake2p_WS_Length); - VerifyOrExit(OpenEnhancedCommissioningWindow(commissioningTimeout, discriminator, verifier, iterations, salt, passcodeID) == - CHIP_NO_ERROR, + VerifyOrExit(Server::GetInstance().GetCommissionManager().OpenEnhancedCommissioningWindow( + commissioningTimeout, discriminator, verifier, iterations, salt, passcodeID) == CHIP_NO_ERROR, status = EMBER_ZCL_STATUS_FAILURE); ChipLogProgress(Zcl, "Commissioning window is now open"); @@ -75,9 +75,10 @@ bool emberAfAdministratorCommissioningClusterOpenBasicCommissioningWindowCallbac { EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS; ChipLogProgress(Zcl, "Received command to open basic commissioning window"); - VerifyOrExit(!IsPairingWindowOpen(), status = EMBER_ZCL_STATUS_FAILURE); + VerifyOrExit(!Server::GetInstance().GetCommissionManager().IsPairingWindowOpen(), status = EMBER_ZCL_STATUS_FAILURE); VerifyOrExit(commissioningTimeout <= kMaxCommissionioningTimeoutSeconds, status = EMBER_ZCL_STATUS_FAILURE); - VerifyOrExit(OpenBasicCommissioningWindow(ResetFabrics::kNo, commissioningTimeout) == CHIP_NO_ERROR, + VerifyOrExit(Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow(ResetFabrics::kNo, + commissioningTimeout) == CHIP_NO_ERROR, status = EMBER_ZCL_STATUS_FAILURE); ChipLogProgress(Zcl, "Commissioning window is now open"); @@ -93,7 +94,7 @@ bool emberAfAdministratorCommissioningClusterOpenBasicCommissioningWindowCallbac bool emberAfAdministratorCommissioningClusterRevokeCommissioningCallback(EndpointId endpoint, app::CommandHandler * commandObj) { ChipLogProgress(Zcl, "Received command to close commissioning window"); - ClosePairingWindow(); + Server::GetInstance().GetCommissionManager().CloseCommissioningWindow(); ChipLogProgress(Zcl, "Commissioning window is now closed"); emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS); return true; diff --git a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp index 434b2b28efeeac..d61676e531a728 100644 --- a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp +++ b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp @@ -121,7 +121,7 @@ CHIP_ERROR writeFabricsIntoFabricsListAttribute() // Loop through fabrics uint8_t fabricIndex = 0; - for (auto & fabricInfo : GetGlobalFabricTable()) + for (auto & fabricInfo : Server::GetInstance().GetFabricTable()) { NodeId nodeId = fabricInfo.GetPeerId().GetNodeId(); uint64_t fabricId = fabricInfo.GetFabricId(); @@ -187,7 +187,7 @@ static FabricInfo * retrieveCurrentFabric() FabricIndex index = emberAfCurrentCommand()->source->GetSecureSession().GetFabricIndex(); emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: Finding fabric with fabricIndex %d", index); - return GetGlobalFabricTable().FindFabricWithIndex(index); + return Server::GetInstance().GetFabricTable().FindFabricWithIndex(index); } // TODO: The code currently has two sources of truths for fabrics, the fabricInfo table + the attributes. There should only be one, @@ -234,7 +234,7 @@ OpCredsFabricTableDelegate gFabricDelegate; void emberAfPluginOperationalCredentialsServerInitCallback(void) { emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: Initiating OpCreds cluster by writing fabrics list from fabric table."); - GetGlobalFabricTable().SetFabricDelegate(&gFabricDelegate); + Server::GetInstance().GetFabricTable().SetFabricDelegate(&gFabricDelegate); writeFabricsIntoFabricsListAttribute(); } @@ -244,7 +244,7 @@ bool emberAfOperationalCredentialsClusterRemoveFabricCallback(EndpointId endpoin emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: RemoveFabric"); // TODO: Generate emberAfFabricClusterPrintln EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS; - CHIP_ERROR err = GetGlobalFabricTable().Delete(fabricIndex); + CHIP_ERROR err = Server::GetInstance().GetFabricTable().Delete(fabricIndex); VerifyOrExit(err == CHIP_NO_ERROR, status = EMBER_ZCL_STATUS_FAILURE); exit: @@ -270,7 +270,7 @@ bool emberAfOperationalCredentialsClusterUpdateFabricLabelCallback(EndpointId en VerifyOrExit(err == CHIP_NO_ERROR, status = EMBER_ZCL_STATUS_FAILURE); // Persist updated fabric - err = GetGlobalFabricTable().Store(fabric->GetFabricIndex()); + err = Server::GetInstance().GetFabricTable().Store(fabric->GetFabricIndex()); VerifyOrExit(err == CHIP_NO_ERROR, status = EMBER_ZCL_STATUS_FAILURE); exit: @@ -359,10 +359,10 @@ bool emberAfOperationalCredentialsClusterAddNOCCallback(EndpointId endpoint, app gFabricBeingCommissioned.SetVendorId(adminVendorId); - err = GetGlobalFabricTable().AddNewFabric(gFabricBeingCommissioned, &fabricIndex); + err = Server::GetInstance().GetFabricTable().AddNewFabric(gFabricBeingCommissioned, &fabricIndex); VerifyOrExit(err == CHIP_NO_ERROR, nocResponse = ConvertToNOCResponseStatus(err)); - err = GetGlobalFabricTable().Store(fabricIndex); + err = Server::GetInstance().GetFabricTable().Store(fabricIndex); VerifyOrExit(err == CHIP_NO_ERROR, nocResponse = ConvertToNOCResponseStatus(err)); // We might have a new operational identity, so we should start advertising it right away. diff --git a/src/app/server/BUILD.gn b/src/app/server/BUILD.gn index 2d5c3fa6dfde66..508f3a703a4d30 100644 --- a/src/app/server/BUILD.gn +++ b/src/app/server/BUILD.gn @@ -27,6 +27,8 @@ static_library("server") { output_name = "libCHIPAppServer" sources = [ + "CommissionManager.cpp", + "CommissionManager.h", "EchoHandler.cpp", "EchoHandler.h", "Mdns.cpp", diff --git a/src/app/server/CommissionManager.cpp b/src/app/server/CommissionManager.cpp new file mode 100644 index 00000000000000..436416f464d16f --- /dev/null +++ b/src/app/server/CommissionManager.cpp @@ -0,0 +1,177 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +namespace { + +void HandleCommissioningWindowTimeout(chip::System::Layer * aSystemLayer, void * aAppState) +{ + chip::CommissionManager * commissionMgr = static_cast(aAppState); + commissionMgr->CloseCommissioningWindow(); +} + +} // namespace + +namespace chip { + +CHIP_ERROR CommissionManager::OpenBasicCommissioningWindow(ResetFabrics resetFabrics, uint16_t commissioningTimeoutSeconds, + CommissioningWindowAdvertisement advertisementMode) +{ + // TODO(cecille): If this is re-called when the window is already open, what should happen? + RestoreDiscriminator(); + + uint32_t pinCode; + ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetSetupPinCode(pinCode)); + + RendezvousParameters params; + + params.SetSetupPINCode(pinCode); + params.SetAdvertisementDelegate(this); +#if CONFIG_NETWORK_LAYER_BLE + SetBLE(advertisementMode == chip::CommissioningWindowAdvertisement::kBle); + if (advertisementMode == chip::CommissioningWindowAdvertisement::kBle) + { + params.SetBleLayer(DeviceLayer::ConnectivityMgr().GetBleLayer()).SetPeerAddress(Transport::PeerAddress::BLE()); + } +#else + SetBLE(false); +#endif // CONFIG_NETWORK_LAYER_BLE + + if (resetFabrics == ResetFabrics::kYes) + { + mServer->GetFabricTable().DeleteAllFabrics(); + // Only resetting gNextAvailableFabricIndex at reboot otherwise previously paired device with fabricID 0 + // can continue sending messages to accessory as next available fabric will also be 0. + // This logic is not up to spec, will be implemented up to spec once AddOptCert is implemented. + mServer->GetFabricTable().Reset(); + } + + ReturnErrorOnFailure(mServer->GetRendezvousServer().WaitForPairing( + std::move(params), kSpake2p_Iteration_Count, + ByteSpan(reinterpret_cast(kSpake2pKeyExchangeSalt), strlen(kSpake2pKeyExchangeSalt)), 0, + &mServer->GetExchangManager(), &mServer->GetTransportManager(), &mServer->GetSecureSessionManager())); + + if (commissioningTimeoutSeconds != kNoCommissioningTimeout) + { + ReturnErrorOnFailure( + DeviceLayer::SystemLayer().StartTimer(commissioningTimeoutSeconds * 1000, HandleCommissioningWindowTimeout, this)); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR CommissionManager::OpenEnhancedCommissioningWindow(uint16_t commissioningTimeoutSeconds, uint16_t discriminator, + PASEVerifier & verifier, uint32_t iterations, ByteSpan salt, + uint16_t passcodeID) +{ + RendezvousParameters params; + + ReturnErrorOnFailure(SetTemporaryDiscriminator(discriminator)); + + params.SetAdvertisementDelegate(this); +#if CONFIG_NETWORK_LAYER_BLE + SetBLE(true); + params.SetBleLayer(DeviceLayer::ConnectivityMgr().GetBleLayer()).SetPeerAddress(Transport::PeerAddress::BLE()); +#else + SetBLE(false); +#endif + + params.SetPASEVerifier(verifier).SetAdvertisementDelegate(this); + + ReturnErrorOnFailure(mServer->GetRendezvousServer().WaitForPairing( + std::move(params), iterations, salt, passcodeID, &mServer->GetExchangManager(), &mServer->GetTransportManager(), + &mServer->GetSecureSessionManager())); + + if (commissioningTimeoutSeconds != kNoCommissioningTimeout) + { + ReturnErrorOnFailure( + DeviceLayer::SystemLayer().StartTimer(commissioningTimeoutSeconds * 1000, HandleCommissioningWindowTimeout, this)); + } + + return CHIP_NO_ERROR; +} + +void CommissionManager::CloseCommissioningWindow() +{ + if (mCommissioningWindowOpen) + { + ChipLogProgress(AppServer, "Closing pairing window"); + mServer->GetRendezvousServer().Cleanup(); + } +} + +CHIP_ERROR CommissionManager::StartAdvertisement() +{ + if (mIsBLE) + { + ReturnErrorOnFailure(chip::DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(true)); + } + if (mAppDelegate != nullptr) + { + mAppDelegate->OnPairingWindowOpened(); + } + mCommissioningWindowOpen = true; + return CHIP_NO_ERROR; +} + +CHIP_ERROR CommissionManager::StopAdvertisement() +{ + RestoreDiscriminator(); + + mCommissioningWindowOpen = false; + + if (mIsBLE) + { + ReturnErrorOnFailure(chip::DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(false)); + } + + if (mAppDelegate != nullptr) + { + mAppDelegate->OnPairingWindowClosed(); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR CommissionManager::SetTemporaryDiscriminator(uint16_t discriminator) +{ + if (!mOriginalDiscriminatorCached) + { + // Cache the original discriminator + ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetSetupDiscriminator(mOriginalDiscriminator)); + mOriginalDiscriminatorCached = true; + } + + return DeviceLayer::ConfigurationMgr().StoreSetupDiscriminator(discriminator); +} + +CHIP_ERROR CommissionManager::RestoreDiscriminator() +{ + if (mOriginalDiscriminatorCached) + { + // Restore the original discriminator + ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().StoreSetupDiscriminator(mOriginalDiscriminator)); + mOriginalDiscriminatorCached = false; + } + + return CHIP_NO_ERROR; +} + +} // namespace chip diff --git a/src/app/server/CommissionManager.h b/src/app/server/CommissionManager.h new file mode 100644 index 00000000000000..288dd0d2cb02da --- /dev/null +++ b/src/app/server/CommissionManager.h @@ -0,0 +1,84 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace chip { + +enum class ResetFabrics +{ + kYes, + kNo, +}; + +constexpr uint16_t kNoCommissioningTimeout = UINT16_MAX; + +enum class CommissioningWindowAdvertisement +{ + kBle, + kMdns, +}; + +class Server; + +class CommissionManager : public RendezvousAdvertisementDelegate +{ +public: + CommissionManager(Server * server) : mAppDelegate(nullptr), mServer(server) {} + + void SetAppDelegate(AppDelegate * delegate) { mAppDelegate = delegate; } + + void SetBLE(bool ble) { mIsBLE = ble; } + + /** + * Open the pairing window using default configured parameters. + */ + CHIP_ERROR + OpenBasicCommissioningWindow(ResetFabrics resetFabrics, uint16_t commissioningTimeoutSeconds = kNoCommissioningTimeout, + CommissioningWindowAdvertisement advertisementMode = chip::CommissioningWindowAdvertisement::kBle); + + CHIP_ERROR OpenEnhancedCommissioningWindow(uint16_t commissioningTimeoutSeconds, uint16_t discriminator, + PASEVerifier & verifier, uint32_t iterations, chip::ByteSpan salt, + uint16_t passcodeID); + + void CloseCommissioningWindow(); + + bool IsPairingWindowOpen() { return mCommissioningWindowOpen; } + + CHIP_ERROR StartAdvertisement() override; + + CHIP_ERROR StopAdvertisement() override; + +private: + CHIP_ERROR SetTemporaryDiscriminator(uint16_t discriminator); + + CHIP_ERROR RestoreDiscriminator(); + + AppDelegate * mAppDelegate = nullptr; + Server * mServer = nullptr; + + bool mCommissioningWindowOpen = false; + bool mIsBLE = true; + + bool mOriginalDiscriminatorCached = false; + uint16_t mOriginalDiscriminator = 0; +}; + +} // namespace chip diff --git a/src/app/server/Mdns.cpp b/src/app/server/Mdns.cpp index f47230e37190b2..92d03782307a2e 100644 --- a/src/app/server/Mdns.cpp +++ b/src/app/server/Mdns.cpp @@ -42,7 +42,7 @@ namespace { bool HaveOperationalCredentials() { // Look for any fabric info that has a useful operational identity. - for (const Transport::FabricInfo & fabricInfo : GetGlobalFabricTable()) + for (const Transport::FabricInfo & fabricInfo : Server::GetInstance().GetFabricTable()) { if (fabricInfo.IsInitialized()) { @@ -110,7 +110,7 @@ CHIP_ERROR GetCommissionableInstanceName(char * buffer, size_t bufferLen) /// Set MDNS operational advertisement CHIP_ERROR AdvertiseOperational() { - for (const Transport::FabricInfo & fabricInfo : GetGlobalFabricTable()) + for (const Transport::FabricInfo & fabricInfo : Server::GetInstance().GetFabricTable()) { if (fabricInfo.IsInitialized()) { diff --git a/src/app/server/RendezvousServer.h b/src/app/server/RendezvousServer.h index b0a27120fe09a8..4a73a0ae00acc4 100644 --- a/src/app/server/RendezvousServer.h +++ b/src/app/server/RendezvousServer.h @@ -61,10 +61,10 @@ class RendezvousServer : public SessionEstablishmentDelegate SessionIDAllocator * mIDAllocator = nullptr; - const RendezvousAdvertisementDelegate * mAdvDelegate; + RendezvousAdvertisementDelegate * mAdvDelegate; bool HasAdvertisementDelegate() const { return mAdvDelegate != nullptr; } - const RendezvousAdvertisementDelegate * GetAdvertisementDelegate() const { return mAdvDelegate; } + RendezvousAdvertisementDelegate * GetAdvertisementDelegate() { return mAdvDelegate; } }; } // namespace chip diff --git a/src/app/server/Server.cpp b/src/app/server/Server.cpp index 1a8a6ebeb5c7b4..8582271f92118a 100644 --- a/src/app/server/Server.cpp +++ b/src/app/server/Server.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2021 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,11 @@ * limitations under the License. */ -#include - #include #include #include +#include #include #include @@ -29,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -45,19 +45,13 @@ #include #include -#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT || CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE -#include -#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT || CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE - -#if CHIP_DEVICE_CONFIG_ENABLE_MDNS -#include -#endif - -using namespace ::chip; -using namespace ::chip::Inet; -using namespace ::chip::Transport; -using namespace ::chip::DeviceLayer; -using namespace ::chip::Messaging; +using chip::RendezvousInformationFlag; +using chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr; +using chip::Inet::IPAddressType; +using chip::Transport::BleListenParameters; +using chip::Transport::kMinValidFabricIndex; +using chip::Transport::PeerAddress; +using chip::Transport::UdpListenParameters; namespace { @@ -72,327 +66,66 @@ constexpr bool isRendezvousBypassed() #endif } -constexpr bool useTestPairing() -{ - // Use the test pairing whenever rendezvous is bypassed. Otherwise, there wouldn't be - // any way to communicate with the device using CHIP protocol. - // This is used to bypass BLE in the cirque test. - // Only in the cirque test this is enabled with --args='bypass_rendezvous=true'. - return isRendezvousBypassed(); -} - -class ServerStorageDelegate : public PersistentStorageDelegate -{ - CHIP_ERROR SyncGetKeyValue(const char * key, void * buffer, uint16_t & size) override - { - ChipLogProgress(AppServer, "Retrieved value from server storage."); - return PersistedStorage::KeyValueStoreMgr().Get(key, buffer, size); - } - - CHIP_ERROR SyncSetKeyValue(const char * key, const void * value, uint16_t size) override - { - ChipLogProgress(AppServer, "Stored value in server storage"); - return PersistedStorage::KeyValueStoreMgr().Put(key, value, size); - } - - CHIP_ERROR SyncDeleteKeyValue(const char * key) override - { - ChipLogProgress(AppServer, "Delete value in server storage"); - return PersistedStorage::KeyValueStoreMgr().Delete(key); - } -}; - -ServerStorageDelegate gServerStorage; -SessionIDAllocator gSessionIDAllocator; - -// TODO: The following class is setting the discriminator in Persistent Storage. This is -// is needed since BLE reads the discriminator using ConfigurationMgr APIs. The -// better solution will be to pass the discriminator to BLE without changing it -// in the persistent storage. -// https://github.com/project-chip/connectedhomeip/issues/4767 -class DeviceDiscriminatorCache -{ -public: - CHIP_ERROR UpdateDiscriminator(uint16_t discriminator) - { - if (!mOriginalDiscriminatorCached) - { - // Cache the original discriminator - ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetSetupDiscriminator(mOriginalDiscriminator)); - mOriginalDiscriminatorCached = true; - } - - return DeviceLayer::ConfigurationMgr().StoreSetupDiscriminator(discriminator); - } - - CHIP_ERROR RestoreDiscriminator() - { - if (mOriginalDiscriminatorCached) - { - // Restore the original discriminator - ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().StoreSetupDiscriminator(mOriginalDiscriminator)); - mOriginalDiscriminatorCached = false; - } - - return CHIP_NO_ERROR; - } - -private: - bool mOriginalDiscriminatorCached = false; - uint16_t mOriginalDiscriminator = 0; -}; - -DeviceDiscriminatorCache gDeviceDiscriminatorCache; -FabricTable gFabrics; -bool gPairingWindowOpen = false; - -class ServerRendezvousAdvertisementDelegate : public RendezvousAdvertisementDelegate -{ -public: - CHIP_ERROR StartAdvertisement() const override - { - if (isBLE) - { - ReturnErrorOnFailure(chip::DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(true)); - } - if (mDelegate != nullptr) - { - mDelegate->OnPairingWindowOpened(); - } - gPairingWindowOpen = true; - return CHIP_NO_ERROR; - } - CHIP_ERROR StopAdvertisement() const override - { - gDeviceDiscriminatorCache.RestoreDiscriminator(); - - gPairingWindowOpen = false; - - if (isBLE) - { - ReturnErrorOnFailure(chip::DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(false)); - } - - if (mDelegate != nullptr) - { - mDelegate->OnPairingWindowClosed(); - } - - return CHIP_NO_ERROR; - } - - void SetDelegate(AppDelegate * delegate) { mDelegate = delegate; } - void SetBLE(bool ble) { isBLE = ble; } - void SetFabricIndex(FabricIndex id) { mFabric = id; } - -private: - AppDelegate * mDelegate = nullptr; - FabricIndex mFabric; - bool isBLE = true; -}; - -DemoTransportMgr gTransports; -SecureSessionMgr gSessions; -RendezvousServer gRendezvousServer; -CASEServer gCASEServer; -Messaging::ExchangeManager gExchangeMgr; -ServerRendezvousAdvertisementDelegate gAdvDelegate; - -class ServerCallback : public ExchangeDelegate -{ -public: - CHIP_ERROR OnMessageReceived(Messaging::ExchangeContext * exchangeContext, const PayloadHeader & payloadHeader, - System::PacketBufferHandle && buffer) override - { - CHIP_ERROR err = CHIP_NO_ERROR; - // as soon as a client connects, assume it is connected - VerifyOrExit(!buffer.IsNull(), ChipLogError(AppServer, "Received data but couldn't process it...")); - VerifyOrExit(mSessionMgr != nullptr, ChipLogError(AppServer, "SecureSessionMgr is not initilized yet")); - HandleDataModelMessage(exchangeContext, std::move(buffer)); - - exit: - return err; - } - - void OnResponseTimeout(ExchangeContext * ec) override - { - ChipLogProgress(AppServer, "Failed to receive response"); - if (mDelegate != nullptr) - { - mDelegate->OnReceiveError(); - } - } - - void SetDelegate(AppDelegate * delegate) { mDelegate = delegate; } - void SetSessionMgr(SecureSessionMgr * mgr) { mSessionMgr = mgr; } - -private: - AppDelegate * mDelegate = nullptr; - SecureSessionMgr * mSessionMgr = nullptr; -}; - -secure_channel::MessageCounterManager gMessageCounterManager; -ServerCallback gCallbacks; -SecurePairingUsingTestSecret gTestPairing; - -#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT - -chip::Protocols::UserDirectedCommissioning::UserDirectedCommissioningClient gUDCClient; - -#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT - -void HandlePairingWindowTimeout(System::Layer * aSystemLayer, void * aAppState) -{ - ClosePairingWindow(); -} - } // namespace -CHIP_ERROR OpenBasicCommissioningWindow(ResetFabrics resetFabrics, uint16_t commissioningTimeoutSeconds, - chip::PairingWindowAdvertisement advertisementMode) -{ - // TODO(cecille): If this is re-called when the window is already open, what should happen? - gDeviceDiscriminatorCache.RestoreDiscriminator(); - - uint32_t pinCode; - ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetSetupPinCode(pinCode)); - - RendezvousParameters params; - - params.SetSetupPINCode(pinCode); -#if CONFIG_NETWORK_LAYER_BLE - gAdvDelegate.SetBLE(advertisementMode == chip::PairingWindowAdvertisement::kBle); - params.SetAdvertisementDelegate(&gAdvDelegate); - if (advertisementMode == chip::PairingWindowAdvertisement::kBle) - { - params.SetBleLayer(DeviceLayer::ConnectivityMgr().GetBleLayer()).SetPeerAddress(Transport::PeerAddress::BLE()); - } -#endif // CONFIG_NETWORK_LAYER_BLE - - if (resetFabrics == ResetFabrics::kYes) - { - gFabrics.DeleteAllFabrics(); - // Only resetting gNextAvailableFabricIndex at reboot otherwise previously paired device with fabricID 0 - // can continue sending messages to accessory as next available fabric will also be 0. - // This logic is not up to spec, will be implemented up to spec once AddOptCert is implemented. - gFabrics.Reset(); - } - - ReturnErrorOnFailure(gRendezvousServer.WaitForPairing( - std::move(params), kSpake2p_Iteration_Count, - ByteSpan(reinterpret_cast(kSpake2pKeyExchangeSalt), strlen(kSpake2pKeyExchangeSalt)), 0, &gExchangeMgr, - &gTransports, &gSessions)); - - if (commissioningTimeoutSeconds != kNoCommissioningTimeout) - { - ReturnErrorOnFailure( - DeviceLayer::SystemLayer().StartTimer(commissioningTimeoutSeconds * 1000, HandlePairingWindowTimeout, nullptr)); - } - - return CHIP_NO_ERROR; -} - -CHIP_ERROR OpenEnhancedCommissioningWindow(uint16_t commissioningTimeoutSeconds, uint16_t discriminator, PASEVerifier & verifier, - uint32_t iterations, ByteSpan salt, uint16_t passcodeID) -{ - RendezvousParameters params; - - ReturnErrorOnFailure(gDeviceDiscriminatorCache.UpdateDiscriminator(discriminator)); - -// TODO: Do not turn on BLE when opening the Enhanced Commissioning Window. -#if CONFIG_NETWORK_LAYER_BLE - gAdvDelegate.SetBLE(true); - params.SetAdvertisementDelegate(&gAdvDelegate); - params.SetBleLayer(DeviceLayer::ConnectivityMgr().GetBleLayer()).SetPeerAddress(Transport::PeerAddress::BLE()); -#endif // CONFIG_NETWORK_LAYER_BLE - params.SetPASEVerifier(verifier).SetAdvertisementDelegate(&gAdvDelegate); - - ReturnErrorOnFailure( - gRendezvousServer.WaitForPairing(std::move(params), iterations, salt, passcodeID, &gExchangeMgr, &gTransports, &gSessions)); - - if (commissioningTimeoutSeconds != kNoCommissioningTimeout) - { - ReturnErrorOnFailure( - DeviceLayer::SystemLayer().StartTimer(commissioningTimeoutSeconds * 1000, HandlePairingWindowTimeout, nullptr)); - } - - return CHIP_NO_ERROR; -} - -void ClosePairingWindow() -{ - if (gPairingWindowOpen) - { - ChipLogProgress(AppServer, "Closing pairing window"); - gRendezvousServer.Cleanup(); - } -} - -bool IsPairingWindowOpen() -{ - return gPairingWindowOpen; -} +namespace chip { -uint16_t gSecuredServicePort = CHIP_PORT; -uint16_t gUnsecuredServicePort = CHIP_UDC_PORT; +Server Server::sServer; -void SetServerConfig(ServerConfigParams params) +CHIP_ERROR Server::Init(AppDelegate * delegate, uint16_t secureServicePort, uint16_t unsecureServicePort) { - gSecuredServicePort = params.securedServicePort; - gUnsecuredServicePort = params.unsecuredServicePort; -} + mAppDelegate = delegate; + mSecuredServicePort = secureServicePort; + mUnsecuredServicePort = unsecureServicePort; -// The function will initialize datamodel handler and then start the server -// The server assumes the platform's networking has been setup already -void InitServer(AppDelegate * delegate) -{ CHIP_ERROR err = CHIP_NO_ERROR; chip::Platform::MemoryInit(); - InitDataModelHandler(&gExchangeMgr); - gCallbacks.SetDelegate(delegate); + mCommissionManager.SetAppDelegate(delegate); + InitDataModelHandler(&mExchangeMgr); #if CHIP_DEVICE_LAYER_TARGET_DARWIN - err = PersistedStorage::KeyValueStoreMgrImpl().Init("chip.store"); + err = DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init("chip.store"); SuccessOrExit(err); #elif CHIP_DEVICE_LAYER_TARGET_LINUX - PersistedStorage::KeyValueStoreMgrImpl().Init(CHIP_CONFIG_KVS_PATH); + DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init(CHIP_CONFIG_KVS_PATH); #endif - err = gRendezvousServer.Init(delegate, &gSessionIDAllocator); + err = mRendezvousServer.Init(mAppDelegate, &mSessionIDAllocator); SuccessOrExit(err); - gAdvDelegate.SetDelegate(delegate); - - err = gFabrics.Init(&gServerStorage); + err = mFabrics.Init(&mServerStorage); SuccessOrExit(err); // Init transport before operations with secure session mgr. - err = gTransports.Init( - UdpListenParameters(&DeviceLayer::InetLayer).SetAddressType(kIPAddressType_IPv6).SetListenPort(gSecuredServicePort) + err = mTransports.Init(UdpListenParameters(&DeviceLayer::InetLayer) + .SetAddressType(IPAddressType::kIPAddressType_IPv6) + .SetListenPort(mSecuredServicePort) #if INET_CONFIG_ENABLE_IPV4 - , - UdpListenParameters(&DeviceLayer::InetLayer).SetAddressType(kIPAddressType_IPv4).SetListenPort(gSecuredServicePort) + , + UdpListenParameters(&DeviceLayer::InetLayer) + .SetAddressType(IPAddressType::kIPAddressType_IPv4) + .SetListenPort(mSecuredServicePort) #endif #if CONFIG_NETWORK_LAYER_BLE - , - BleListenParameters(DeviceLayer::ConnectivityMgr().GetBleLayer()) + , + BleListenParameters(DeviceLayer::ConnectivityMgr().GetBleLayer()) #endif ); SuccessOrExit(err); - err = gSessions.Init(&DeviceLayer::SystemLayer(), &gTransports, &gFabrics, &gMessageCounterManager); + err = mSessions.Init(&DeviceLayer::SystemLayer(), &mTransports, &mFabrics, &mMessageCounterManager); SuccessOrExit(err); - err = gExchangeMgr.Init(&gSessions); + err = mExchangeMgr.Init(&mSessions); SuccessOrExit(err); - err = gMessageCounterManager.Init(&gExchangeMgr); + err = mMessageCounterManager.Init(&mExchangeMgr); SuccessOrExit(err); - err = chip::app::InteractionModelEngine::GetInstance()->Init(&gExchangeMgr, nullptr); + err = chip::app::InteractionModelEngine::GetInstance()->Init(&mExchangeMgr, nullptr); SuccessOrExit(err); #if defined(CHIP_APP_USE_ECHO) @@ -400,7 +133,7 @@ void InitServer(AppDelegate * delegate) SuccessOrExit(err); #endif - if (useTestPairing()) + if (isRendezvousBypassed()) { ChipLogProgress(AppServer, "Rendezvous and secure pairing skipped"); SuccessOrExit(err = AddTestCommissioning()); @@ -414,32 +147,34 @@ void InitServer(AppDelegate * delegate) else { #if CHIP_DEVICE_CONFIG_ENABLE_PAIRING_AUTOSTART - SuccessOrExit(err = OpenBasicCommissioningWindow(ResetFabrics::kYes)); + SuccessOrExit(err = mCommissionManager.OpenBasicCommissioningWindow(ResetFabrics::kYes)); #endif } #if CHIP_DEVICE_CONFIG_ENABLE_MDNS - app::Mdns::SetSecuredPort(gSecuredServicePort); - app::Mdns::SetUnsecuredPort(gUnsecuredServicePort); + app::Mdns::SetSecuredPort(mSecuredServicePort); + app::Mdns::SetUnsecuredPort(mUnsecuredServicePort); #endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS -// ESP32 and Mbed OS examples have a custom logic for enabling DNS-SD + + // TODO @bzbarsky-apple @cecille Move to examples + // ESP32 and Mbed OS examples have a custom logic for enabling DNS-SD #if CHIP_DEVICE_CONFIG_ENABLE_MDNS && !CHIP_DEVICE_LAYER_TARGET_ESP32 && !CHIP_DEVICE_LAYER_TARGET_MBED // StartServer only enables commissioning mode if device has not been commissioned app::Mdns::StartServer(); #endif - gCallbacks.SetSessionMgr(&gSessions); - + // TODO @pan-apple Use IM protocol ID. // Register to receive unsolicited legacy ZCL messages from the exchange manager. - err = gExchangeMgr.RegisterUnsolicitedMessageHandlerForProtocol(Protocols::TempZCL::Id, &gCallbacks); + err = mExchangeMgr.RegisterUnsolicitedMessageHandlerForProtocol(Protocols::TempZCL::Id, this); SuccessOrExit(err); + // TODO @pan-apple Remove service provisioniong, maybe multi-admin? // Register to receive unsolicited Service Provisioning messages from the exchange manager. - err = gExchangeMgr.RegisterUnsolicitedMessageHandlerForProtocol(Protocols::ServiceProvisioning::Id, &gCallbacks); + err = mExchangeMgr.RegisterUnsolicitedMessageHandlerForProtocol(Protocols::ServiceProvisioning::Id, this); SuccessOrExit(err); - err = gCASEServer.ListenForSessionEstablishment(&gExchangeMgr, &gTransports, chip::DeviceLayer::ConnectivityMgr().GetBleLayer(), - &gSessions, &GetGlobalFabricTable(), &gSessionIDAllocator); + err = mCASEServer.ListenForSessionEstablishment(&mExchangeMgr, &mTransports, chip::DeviceLayer::ConnectivityMgr().GetBleLayer(), + &mSessions, &mFabrics, &mSessionIDAllocator); SuccessOrExit(err); exit: @@ -451,14 +186,25 @@ void InitServer(AppDelegate * delegate) { ChipLogProgress(AppServer, "Server Listening..."); } + return err; +} + +void Server::Shutdown() +{ + chip::Mdns::ServiceAdvertiser::Instance().StopPublishDevice(); + chip::app::InteractionModelEngine::GetInstance()->Shutdown(); + mExchangeMgr.Shutdown(); + mSessions.Shutdown(); + mTransports.Close(); + mRendezvousServer.Cleanup(); + chip::Platform::MemoryShutdown(); } #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT // NOTE: UDC client is located in Server.cpp because it really only makes sense // to send UDC from a Matter device. The UDC message payload needs to include the device's // randomly generated service name. - -CHIP_ERROR SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress commissioner) +CHIP_ERROR Server::SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress commissioner) { ChipLogDetail(AppServer, "SendUserDirectedCommissioningRequest2"); @@ -479,7 +225,7 @@ CHIP_ERROR SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress com return CHIP_ERROR_NO_MEMORY; } - err = gUDCClient.SendUDCMessage(&gTransports, std::move(payloadBuf), commissioner); + err = gUDCClient.SendUDCMessage(&mTransports, std::move(payloadBuf), commissioner); if (err == CHIP_NO_ERROR) { ChipLogDetail(AppServer, "Send UDC request success"); @@ -490,20 +236,19 @@ CHIP_ERROR SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress com } return err; } - #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT -CHIP_ERROR AddTestCommissioning() +CHIP_ERROR Server::AddTestCommissioning() { CHIP_ERROR err = CHIP_NO_ERROR; PASESession * testSession = nullptr; PASESessionSerializable serializedTestSession; - gTestPairing.ToSerializable(serializedTestSession); + mTestPairing.ToSerializable(serializedTestSession); testSession = chip::Platform::New(); testSession->FromSerializable(serializedTestSession); - SuccessOrExit(err = gSessions.NewPairing(Optional{ PeerAddress::Uninitialized() }, chip::kTestControllerNodeId, + SuccessOrExit(err = mSessions.NewPairing(Optional{ PeerAddress::Uninitialized() }, chip::kTestControllerNodeId, testSession, SecureSession::SessionRole::kResponder, kMinValidFabricIndex)); exit: @@ -514,11 +259,30 @@ CHIP_ERROR AddTestCommissioning() } if (err != CHIP_NO_ERROR) - gFabrics.ReleaseFabricIndex(kMinValidFabricIndex); + { + mFabrics.ReleaseFabricIndex(kMinValidFabricIndex); + } return err; } -FabricTable & GetGlobalFabricTable() +CHIP_ERROR Server::OnMessageReceived(Messaging::ExchangeContext * exchangeContext, const PayloadHeader & payloadHeader, + System::PacketBufferHandle && buffer) { - return gFabrics; + CHIP_ERROR err = CHIP_NO_ERROR; + VerifyOrReturnError(!buffer.IsNull(), err = CHIP_ERROR_INVALID_ARGUMENT); + // TODO: BDX messages will also be possible in the future. + HandleDataModelMessage(exchangeContext, std::move(buffer)); + + return err; } + +void Server::OnResponseTimeout(Messaging::ExchangeContext * ec) +{ + ChipLogProgress(AppServer, "Failed to receive response"); + if (mAppDelegate != nullptr) + { + mAppDelegate->OnReceiveError(); + } +} + +} // namespace chip diff --git a/src/app/server/Server.h b/src/app/server/Server.h index 6ff2d315592aeb..4dbf09429dc3ab 100644 --- a/src/app/server/Server.h +++ b/src/app/server/Server.h @@ -18,87 +18,123 @@ #pragma once #include +#include +#include #include #include +#include +#include +#include #include +#include +#include #include #include #include +#include #include #include -struct ServerConfigParams -{ - uint16_t securedServicePort = CHIP_PORT; - uint16_t unsecuredServicePort = CHIP_UDC_PORT; -}; +namespace chip { constexpr size_t kMaxBlePendingPackets = 1; -using DemoTransportMgr = chip::TransportMgr + , + chip::Transport::BLE #endif - >; -/** - * Currently, this method must be called BEFORE InitServer. - * In the future, it would be nice to be able to call it - * at any time but that requires handling for changes to every - * field on ServerConfigParams (restarting port listener, etc). - * - */ -void SetServerConfig(ServerConfigParams params); + >; -/** - * Initialize DataModelHandler and start CHIP datamodel server, the server - * assumes the platform's networking has been setup already. - * - * @param [in] delegate An optional AppDelegate - */ -void InitServer(AppDelegate * delegate = nullptr); +class Server : public Messaging::ExchangeDelegate +{ +public: + CHIP_ERROR Init(AppDelegate * delegate = nullptr, uint16_t secureServicePort = CHIP_PORT, + uint16_t unsecureServicePort = CHIP_UDC_PORT); #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT -CHIP_ERROR SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress commissioner); + CHIP_ERROR SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress commissioner); #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT -CHIP_ERROR AddTestCommissioning(); + CHIP_ERROR AddTestCommissioning(); -chip::Transport::FabricTable & GetGlobalFabricTable(); + void SetFabricIndex(FabricIndex id) { mFabricIndex = id; } -namespace chip { + Transport::FabricTable & GetFabricTable() { return mFabrics; } -enum class ResetFabrics -{ - kYes, - kNo, -}; + Messaging::ExchangeManager & GetExchangManager() { return mExchangeMgr; } -enum class PairingWindowAdvertisement -{ - kBle, - kMdns, -}; + SessionIDAllocator & GetSessionIDAllocator() { return mSessionIDAllocator; } -} // namespace chip + SecureSessionMgr & GetSecureSessionManager() { return mSessions; } -constexpr uint16_t kNoCommissioningTimeout = UINT16_MAX; + RendezvousServer & GetRendezvousServer() { return mRendezvousServer; } -/** - * Open the pairing window using default configured parameters. - */ -CHIP_ERROR -OpenBasicCommissioningWindow(chip::ResetFabrics resetFabrics, uint16_t commissioningTimeoutSeconds = kNoCommissioningTimeout, - chip::PairingWindowAdvertisement advertisementMode = chip::PairingWindowAdvertisement::kBle); + TransportMgrBase & GetTransportManager() { return mTransports; } -CHIP_ERROR OpenEnhancedCommissioningWindow(uint16_t commissioningTimeoutSeconds, uint16_t discriminator, - chip::PASEVerifier & verifier, uint32_t iterations, chip::ByteSpan salt, - uint16_t passcodeID); + CommissionManager & GetCommissionManager() { return mCommissionManager; } -void ClosePairingWindow(); + void Shutdown(); -bool IsPairingWindowOpen(); + static Server & GetInstance() { return sServer; } + +private: + Server() : mCommissionManager(this) {} + + static Server sServer; + + class ServerStorageDelegate : public PersistentStorageDelegate + { + CHIP_ERROR SyncGetKeyValue(const char * key, void * buffer, uint16_t & size) override + { + ChipLogProgress(AppServer, "Retrieved value from server storage."); + return DeviceLayer::PersistedStorage::KeyValueStoreMgr().Get(key, buffer, size); + } + + CHIP_ERROR SyncSetKeyValue(const char * key, const void * value, uint16_t size) override + { + ChipLogProgress(AppServer, "Stored value in server storage"); + return DeviceLayer::PersistedStorage::KeyValueStoreMgr().Put(key, value, size); + } + + CHIP_ERROR SyncDeleteKeyValue(const char * key) override + { + ChipLogProgress(AppServer, "Delete value in server storage"); + return DeviceLayer::PersistedStorage::KeyValueStoreMgr().Delete(key); + } + }; + + // Messaging::ExchangeDelegate + CHIP_ERROR OnMessageReceived(Messaging::ExchangeContext * exchangeContext, const PayloadHeader & payloadHeader, + System::PacketBufferHandle && buffer) override; + void OnResponseTimeout(Messaging::ExchangeContext * ec) override; + + AppDelegate * mAppDelegate = nullptr; + + ServerTransportMgr mTransports; + SecureSessionMgr mSessions; + RendezvousServer mRendezvousServer; + CASEServer mCASEServer; + Messaging::ExchangeManager mExchangeMgr; + Transport::FabricTable mFabrics; + SessionIDAllocator mSessionIDAllocator; + secure_channel::MessageCounterManager mMessageCounterManager; +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT + chip::Protocols::UserDirectedCommissioning::UserDirectedCommissioningClient gUDCClient; +#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT + SecurePairingUsingTestSecret mTestPairing; + + ServerStorageDelegate mServerStorage; + CommissionManager mCommissionManager; + + // TODO @ceille: Maybe use OperationalServicePort and CommissionableServicePort + uint16_t mSecuredServicePort; + uint16_t mUnsecuredServicePort; + FabricIndex mFabricIndex; +}; + +} // namespace chip diff --git a/src/app/server/SessionManager.h b/src/app/server/SessionManager.h deleted file mode 100644 index 17d78a987de5ab..00000000000000 --- a/src/app/server/SessionManager.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -namespace chip { -SecureSessionMgr & SessionManager(); -} // namespace chip diff --git a/src/app/tests/BUILD.gn b/src/app/tests/BUILD.gn index 53053889538fb6..aafac491c33878 100644 --- a/src/app/tests/BUILD.gn +++ b/src/app/tests/BUILD.gn @@ -17,6 +17,7 @@ import("//build_overrides/chip.gni") import("//build_overrides/nlunit_test.gni") import("${chip_root}/build/chip/chip_test_suite.gni") +import("${chip_root}/src/platform/device.gni") chip_test_suite("tests") { output_name = "libAppTests" @@ -46,4 +47,10 @@ chip_test_suite("tests") { "${chip_root}/src/transport/raw/tests:helpers", "${nlunit_test_root}:nlunit-test", ] + + if (chip_config_network_layer_ble && + (chip_device_platform == "linux" || chip_device_platform == "Darwin")) { + test_sources += [ "TestCommissionManager.cpp" ] + public_deps += [ "${chip_root}/src/app/server" ] + } } diff --git a/src/app/tests/TestCommissionManager.cpp b/src/app/tests/TestCommissionManager.cpp new file mode 100644 index 00000000000000..1bc33ea491c4ad --- /dev/null +++ b/src/app/tests/TestCommissionManager.cpp @@ -0,0 +1,173 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using chip::CommissioningWindowAdvertisement; +using chip::CommissionManager; +using chip::kNoCommissioningTimeout; +using chip::ResetFabrics; +using chip::Server; + +// Mock function for linking +void InitDataModelHandler(chip::Messaging::ExchangeManager * exchangeMgr) {} +void HandleDataModelMessage(chip::Messaging::ExchangeContext * exchange, chip::System::PacketBufferHandle && buffer) {} + +namespace { + +static constexpr int kTestTaskWaitSeconds = 2; + +void InitializeChip(nlTestSuite * suite) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + err = chip::Platform::MemoryInit(); + NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR); + err = chip::DeviceLayer::PlatformMgr().InitChipStack(); + NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR); + err = Server::GetInstance().Init(); + chip::DeviceLayer::PlatformMgr().StartEventLoopTask(); + NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR); +} + +void CheckCommissionManagerBasicWindowOpenCloseTask(intptr_t context) +{ + nlTestSuite * suite = reinterpret_cast(context); + CommissionManager & commissionMgr = Server::GetInstance().GetCommissionManager(); + CHIP_ERROR err = commissionMgr.OpenBasicCommissioningWindow(ResetFabrics::kNo, kNoCommissioningTimeout, + CommissioningWindowAdvertisement::kMdns); + NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(suite, commissionMgr.IsPairingWindowOpen()); + commissionMgr.CloseCommissioningWindow(); + NL_TEST_ASSERT(suite, !commissionMgr.IsPairingWindowOpen()); +} + +void CheckCommissionManagerBasicWindowOpenClose(nlTestSuite * suite, void *) +{ + chip::DeviceLayer::PlatformMgr().ScheduleWork(CheckCommissionManagerBasicWindowOpenCloseTask, + reinterpret_cast(suite)); + sleep(kTestTaskWaitSeconds); +} + +void CheckCommissionManagerWindowClosedTask(chip::System::Layer *, void * context) +{ + nlTestSuite * suite = static_cast(context); + CommissionManager & commissionMgr = Server::GetInstance().GetCommissionManager(); + NL_TEST_ASSERT(suite, !commissionMgr.IsPairingWindowOpen()); +} + +void CheckCommissionManagerWindowTimeoutTask(intptr_t context) +{ + nlTestSuite * suite = reinterpret_cast(context); + CommissionManager & commissionMgr = Server::GetInstance().GetCommissionManager(); + constexpr uint16_t kTimeoutSeconds = 1; + constexpr uint16_t kTimeoutMs = 1000; + constexpr unsigned kSleepPadding = 100; + CHIP_ERROR err = + commissionMgr.OpenBasicCommissioningWindow(ResetFabrics::kNo, kTimeoutSeconds, CommissioningWindowAdvertisement::kMdns); + NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(suite, commissionMgr.IsPairingWindowOpen()); + chip::DeviceLayer::SystemLayer().StartTimer(kTimeoutMs + kSleepPadding, CheckCommissionManagerWindowClosedTask, suite); +} + +void CheckCommissionManagerWindowTimeout(nlTestSuite * suite, void *) +{ + chip::DeviceLayer::PlatformMgr().ScheduleWork(CheckCommissionManagerWindowTimeoutTask, reinterpret_cast(suite)); + sleep(kTestTaskWaitSeconds); +} + +void CheckCommissionManagerEnhancedWindowTask(intptr_t context) +{ + nlTestSuite * suite = reinterpret_cast(context); + CommissionManager & commissionMgr = Server::GetInstance().GetCommissionManager(); + uint16_t originDiscriminator; + CHIP_ERROR err = chip::DeviceLayer::ConfigurationMgr().GetSetupDiscriminator(originDiscriminator); + NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR); + uint16_t newDiscriminator = static_cast(originDiscriminator + 1); + chip::PASEVerifier verifier; + constexpr uint32_t kIterations = chip::kPBKDFMinimumIterations; + uint8_t salt[chip::kPBKDFMinimumSaltLen]; + chip::ByteSpan saltData(salt); + constexpr uint16_t kPasscodeID = 1; + uint16_t currentDiscriminator; + + err = commissionMgr.OpenEnhancedCommissioningWindow(kNoCommissioningTimeout, newDiscriminator, verifier, kIterations, saltData, + kPasscodeID); + NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(suite, commissionMgr.IsPairingWindowOpen()); + err = chip::DeviceLayer::ConfigurationMgr().GetSetupDiscriminator(currentDiscriminator); + NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(suite, currentDiscriminator == newDiscriminator); + + commissionMgr.CloseCommissioningWindow(); + NL_TEST_ASSERT(suite, !commissionMgr.IsPairingWindowOpen()); + err = chip::DeviceLayer::ConfigurationMgr().GetSetupDiscriminator(currentDiscriminator); + NL_TEST_ASSERT(suite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(suite, currentDiscriminator == originDiscriminator); +} + +void CheckCommissionManagerEnhancedWindow(nlTestSuite * suite, void *) +{ + chip::DeviceLayer::PlatformMgr().ScheduleWork(CheckCommissionManagerEnhancedWindowTask, reinterpret_cast(suite)); + sleep(kTestTaskWaitSeconds); +} + +void TearDownTask(intptr_t context) +{ + chip::Server::GetInstance().Shutdown(); + chip::DeviceLayer::PlatformMgr().Shutdown(); +} + +const nlTest sTests[] = { NL_TEST_DEF("CheckCommissionManagerEnhancedWindow", CheckCommissionManagerEnhancedWindow), + NL_TEST_DEF("CheckCommissionManagerBasicWindowOpenClose", CheckCommissionManagerBasicWindowOpenClose), + NL_TEST_DEF("CheckCommissionManagerWindowTimeout", CheckCommissionManagerWindowTimeout), + NL_TEST_SENTINEL() }; + +} // namespace + +int TestCommissionManager() +{ + // clang-format off + nlTestSuite theSuite = + { + "CommissionManager", + &sTests[0], + nullptr, + nullptr + }; + // clang-format on + + InitializeChip(&theSuite); + nlTestRunner(&theSuite, nullptr); + + // TODO: The platform memory was intentionally left not deinitialized so that minimal mdns can destruct + chip::DeviceLayer::PlatformMgr().ScheduleWork(TearDownTask, 0); + sleep(kTestTaskWaitSeconds); + + return (nlTestRunnerStats(&theSuite)); +} + +CHIP_REGISTER_TEST_SUITE(TestCommissionManager) diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index e599cb465a3b37..e9f16b07f06eb9 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -397,13 +397,13 @@ class DeviceCommissionerRendezvousAdvertisementDelegate : public RendezvousAdver * @brief * Starts advertisement of the device for rendezvous availability. */ - CHIP_ERROR StartAdvertisement() const override { return CHIP_NO_ERROR; } + CHIP_ERROR StartAdvertisement() override { return CHIP_NO_ERROR; } /** * @brief * Stops advertisement of the device for rendezvous availability. */ - CHIP_ERROR StopAdvertisement() const override { return CHIP_NO_ERROR; } + CHIP_ERROR StopAdvertisement() override { return CHIP_NO_ERROR; } }; /** diff --git a/src/protocols/secure_channel/RendezvousParameters.h b/src/protocols/secure_channel/RendezvousParameters.h index 17bb455d49e7f0..6dfab892b5fa24 100644 --- a/src/protocols/secure_channel/RendezvousParameters.h +++ b/src/protocols/secure_channel/RendezvousParameters.h @@ -35,13 +35,13 @@ class DLL_EXPORT RendezvousAdvertisementDelegate { public: /// called to start advertising that rendezvous is possible (commisioning available) - virtual CHIP_ERROR StartAdvertisement() const { return CHIP_ERROR_NOT_IMPLEMENTED; } + virtual CHIP_ERROR StartAdvertisement() { return CHIP_ERROR_NOT_IMPLEMENTED; } /// called when advertisement is not needed for Rendezvous (e.g. got a BLE connection) - virtual CHIP_ERROR StopAdvertisement() const { return CHIP_ERROR_NOT_IMPLEMENTED; } + virtual CHIP_ERROR StopAdvertisement() { return CHIP_ERROR_NOT_IMPLEMENTED; } /// Called when a rendezvous operation is complete - virtual void RendezvousComplete() const {} + virtual void RendezvousComplete() {} virtual ~RendezvousAdvertisementDelegate() {} }; @@ -113,7 +113,7 @@ class RendezvousParameters bool HasAdvertisementDelegate() const { return mAdvDelegate != nullptr; } - const RendezvousAdvertisementDelegate * GetAdvertisementDelegate() const { return mAdvDelegate; } + RendezvousAdvertisementDelegate * GetAdvertisementDelegate() const { return mAdvDelegate; } RendezvousParameters & SetAdvertisementDelegate(RendezvousAdvertisementDelegate * delegate) { From eda07d58043749f40f00233639a1c5b68777bca5 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Fri, 10 Sep 2021 13:39:19 -0700 Subject: [PATCH 002/255] [TE6] Read Ethernet Network Diagnostic attributes from platform at run-time (#9587) * Read ethernet network diagnostic attributes from platform at run-time * Update zap file for lighting-app * Update gen folder --- .../lighting-common/lighting-app.zap | 13 ++- examples/lighting-app/linux/main.cpp | 99 +++++++++++++++++ src/include/platform/CHIPDeviceConfig.h | 12 ++ src/include/platform/ConnectivityManager.h | 32 ++++++ .../GenericConnectivityManagerImpl_NoWiFi.h | 35 ++++++ .../GenericConnectivityManagerImpl_WiFi.h | 35 ++++++ .../Linux/ConnectivityManagerImpl.cpp | 105 +++++++++++++++++- src/platform/Linux/ConnectivityManagerImpl.h | 6 + .../zap-generated/endpoint_config.h | 16 ++- 9 files changed, 339 insertions(+), 14 deletions(-) diff --git a/examples/lighting-app/lighting-common/lighting-app.zap b/examples/lighting-app/lighting-common/lighting-app.zap index 6029fd790c5349..00b1d1c5f1cf73 100644 --- a/examples/lighting-app/lighting-common/lighting-app.zap +++ b/examples/lighting-app/lighting-common/lighting-app.zap @@ -2810,7 +2810,7 @@ "mfgCode": null, "side": "server", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, "defaultValue": "0x0000000000000000", @@ -2825,7 +2825,7 @@ "mfgCode": null, "side": "server", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, "defaultValue": "0x0000000000000000", @@ -2840,7 +2840,7 @@ "mfgCode": null, "side": "server", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, "defaultValue": "0x0000000000000000", @@ -2855,7 +2855,7 @@ "mfgCode": null, "side": "server", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, "defaultValue": "0x0000000000000000", @@ -2870,7 +2870,7 @@ "mfgCode": null, "side": "server", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, "defaultValue": "0x0000000000000000", @@ -5490,5 +5490,6 @@ "endpointVersion": 1, "deviceIdentifier": 259 } - ] + ], + "log": [] } \ No newline at end of file diff --git a/examples/lighting-app/linux/main.cpp b/examples/lighting-app/linux/main.cpp index 3bd618d0b42502..a0e88791bc0ac9 100644 --- a/examples/lighting-app/linux/main.cpp +++ b/examples/lighting-app/linux/main.cpp @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include #include @@ -87,6 +89,103 @@ void emberAfOnOffClusterInitCallback(EndpointId endpoint) // TODO: implement any additional Cluster Server init actions } +EmberAfStatus HandleReadEthernetNetworkDiagnosticsAttribute(chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength) +{ + EmberAfStatus ret = EMBER_ZCL_STATUS_FAILURE; + + switch (attributeId) + { + case ZCL_PACKET_RX_COUNT_ATTRIBUTE_ID: + if (maxReadLength == sizeof(uint64_t)) + { + uint64_t packetRxCount; + + if (ConnectivityMgr().GetEthPacketRxCount(packetRxCount) == CHIP_NO_ERROR) + { + memcpy(buffer, &packetRxCount, maxReadLength); + ret = EMBER_ZCL_STATUS_SUCCESS; + } + } + break; + case ZCL_PACKET_TX_COUNT_ATTRIBUTE_ID: + if (maxReadLength == sizeof(uint64_t)) + { + uint64_t packetTxCount; + + if (ConnectivityMgr().GetEthPacketTxCount(packetTxCount) == CHIP_NO_ERROR) + { + memcpy(buffer, &packetTxCount, maxReadLength); + ret = EMBER_ZCL_STATUS_SUCCESS; + } + } + break; + case ZCL_TX_ERR_COUNT_ATTRIBUTE_ID: + if (maxReadLength == sizeof(uint64_t)) + { + uint64_t txErrCount; + + if (ConnectivityMgr().GetEthTxErrCount(txErrCount) == CHIP_NO_ERROR) + { + memcpy(buffer, &txErrCount, maxReadLength); + ret = EMBER_ZCL_STATUS_SUCCESS; + } + } + break; + case ZCL_COLLISION_COUNT_ATTRIBUTE_ID: + if (maxReadLength == sizeof(uint64_t)) + { + uint64_t collisionCount; + + if (ConnectivityMgr().GetEthCollisionCount(collisionCount) == CHIP_NO_ERROR) + { + memcpy(buffer, &collisionCount, maxReadLength); + ret = EMBER_ZCL_STATUS_SUCCESS; + } + } + break; + case ZCL_ETHERNET_OVERRUN_COUNT_ATTRIBUTE_ID: + if (maxReadLength == sizeof(uint64_t)) + { + uint64_t overrunCount; + + if (ConnectivityMgr().GetEthOverrunCount(overrunCount) == CHIP_NO_ERROR) + { + memcpy(buffer, &overrunCount, maxReadLength); + ret = EMBER_ZCL_STATUS_SUCCESS; + } + } + break; + default: + ChipLogProgress(Zcl, "Unhandled attribute ID: %d", attributeId); + break; + } + + return ret; +} + +EmberAfStatus emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId, + EmberAfAttributeMetadata * attributeMetadata, uint16_t manufacturerCode, + uint8_t * buffer, uint16_t maxReadLength, int32_t index) +{ + EmberAfStatus ret = EMBER_ZCL_STATUS_FAILURE; + + ChipLogProgress(Zcl, + "emberAfExternalAttributeReadCallback - Cluster ID: '0x%04x', EndPoint ID: '0x%02x', Attribute ID: '0x%04x'", + clusterId, endpoint, attributeMetadata->attributeId); + + switch (clusterId) + { + case ZCL_ETHERNET_NETWORK_DIAGNOSTICS_CLUSTER_ID: + ret = HandleReadEthernetNetworkDiagnosticsAttribute(attributeMetadata->attributeId, buffer, maxReadLength); + break; + default: + ChipLogError(Zcl, "Unhandled cluster ID: %d", clusterId); + break; + } + + return ret; +} + int main(int argc, char * argv[]) { if (ChipLinuxAppInit(argc, argv) != 0) diff --git a/src/include/platform/CHIPDeviceConfig.h b/src/include/platform/CHIPDeviceConfig.h index f0a80ab3c2a161..a0dec8aa5c0a42 100644 --- a/src/include/platform/CHIPDeviceConfig.h +++ b/src/include/platform/CHIPDeviceConfig.h @@ -826,6 +826,18 @@ #define CHIP_DEVICE_CONFIG_DEFAULT_TELEMETRY_INTERVAL_MS 90000 #endif +/** + * @def CHIP_DEVICE_CONFIG_ETHERNET_IF_NAME + * + * @brief + * Default ethernet network interface name used to centralize all metrics that are + * relevant to a potential Ethernet connection to a Node. + * + */ +#ifndef CHIP_DEVICE_CONFIG_ETHERNET_IF_NAME +#define CHIP_DEVICE_CONFIG_ETHERNET_IF_NAME "enp0s25" +#endif + // -------------------- Event Logging Configuration -------------------- /** diff --git a/src/include/platform/ConnectivityManager.h b/src/include/platform/ConnectivityManager.h index 27c72643bc82e3..042940b993d01d 100644 --- a/src/include/platform/ConnectivityManager.h +++ b/src/include/platform/ConnectivityManager.h @@ -170,6 +170,13 @@ class ConnectivityManager // Service connectivity methods bool HaveServiceConnectivity(); + // Ethernet network diagnostics methods + CHIP_ERROR GetEthPacketRxCount(uint64_t & packetRxCount); + CHIP_ERROR GetEthPacketTxCount(uint64_t & packetTxCount); + CHIP_ERROR GetEthTxErrCount(uint64_t & txErrCount); + CHIP_ERROR GetEthCollisionCount(uint64_t & collisionCount); + CHIP_ERROR GetEthOverrunCount(uint64_t & overrunCount); + // CHIPoBLE service methods Ble::BleLayer * GetBleLayer(); CHIPoBLEServiceMode GetCHIPoBLEServiceMode(); @@ -381,6 +388,31 @@ inline bool ConnectivityManager::HaveServiceConnectivity() return static_cast(this)->_HaveServiceConnectivity(); } +inline CHIP_ERROR ConnectivityManager::GetEthPacketRxCount(uint64_t & packetRxCount) +{ + return static_cast(this)->_GetEthPacketRxCount(packetRxCount); +} + +inline CHIP_ERROR ConnectivityManager::GetEthPacketTxCount(uint64_t & packetTxCount) +{ + return static_cast(this)->_GetEthPacketTxCount(packetTxCount); +} + +inline CHIP_ERROR ConnectivityManager::GetEthTxErrCount(uint64_t & txErrCount) +{ + return static_cast(this)->_GetEthTxErrCount(txErrCount); +} + +inline CHIP_ERROR ConnectivityManager::GetEthCollisionCount(uint64_t & collisionCount) +{ + return static_cast(this)->_GetEthCollisionCount(collisionCount); +} + +inline CHIP_ERROR ConnectivityManager::GetEthOverrunCount(uint64_t & overrunCount) +{ + return static_cast(this)->_GetEthOverrunCount(overrunCount); +} + inline ConnectivityManager::ThreadMode ConnectivityManager::GetThreadMode() { return static_cast(this)->_GetThreadMode(); diff --git a/src/include/platform/internal/GenericConnectivityManagerImpl_NoWiFi.h b/src/include/platform/internal/GenericConnectivityManagerImpl_NoWiFi.h index af744bbf4da9fd..33b5e1405d908d 100644 --- a/src/include/platform/internal/GenericConnectivityManagerImpl_NoWiFi.h +++ b/src/include/platform/internal/GenericConnectivityManagerImpl_NoWiFi.h @@ -73,6 +73,11 @@ class GenericConnectivityManagerImpl_NoWiFi uint32_t _GetWiFiAPIdleTimeoutMS(void); void _SetWiFiAPIdleTimeoutMS(uint32_t val); CHIP_ERROR _GetAndLogWifiStatsCounters(void); + CHIP_ERROR _GetEthPacketRxCount(uint64_t & packetRxCount); + CHIP_ERROR _GetEthPacketTxCount(uint64_t & packetTxCount); + CHIP_ERROR _GetEthTxErrCount(uint64_t & txErrCount); + CHIP_ERROR _GetEthCollisionCount(uint64_t & collisionCount); + CHIP_ERROR _GetEthOverrunCount(uint64_t & overrunCount); bool _CanStartWiFiScan(); void _OnWiFiScanDone(); void _OnWiFiStationProvisionChange(); @@ -235,6 +240,36 @@ inline const char * GenericConnectivityManagerImpl_NoWiFi::_WiFiAPSta return NULL; } +template +inline CHIP_ERROR GenericConnectivityManagerImpl_NoWiFi::_GetEthPacketRxCount(uint64_t & packetRxCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +template +inline CHIP_ERROR GenericConnectivityManagerImpl_NoWiFi::_GetEthPacketTxCount(uint64_t & packetTxCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +template +inline CHIP_ERROR GenericConnectivityManagerImpl_NoWiFi::_GetEthTxErrCount(uint64_t & txErrCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +template +inline CHIP_ERROR GenericConnectivityManagerImpl_NoWiFi::_GetEthCollisionCount(uint64_t & collisionCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +template +inline CHIP_ERROR GenericConnectivityManagerImpl_NoWiFi::_GetEthOverrunCount(uint64_t & overrunCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + } // namespace Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/include/platform/internal/GenericConnectivityManagerImpl_WiFi.h b/src/include/platform/internal/GenericConnectivityManagerImpl_WiFi.h index 9fe2fd66437050..36431caa1b41e5 100644 --- a/src/include/platform/internal/GenericConnectivityManagerImpl_WiFi.h +++ b/src/include/platform/internal/GenericConnectivityManagerImpl_WiFi.h @@ -73,6 +73,11 @@ class GenericConnectivityManagerImpl_WiFi uint32_t _GetWiFiAPIdleTimeoutMS(); void _SetWiFiAPIdleTimeoutMS(uint32_t val); CHIP_ERROR _GetAndLogWifiStatsCounters(); + CHIP_ERROR _GetEthPacketRxCount(uint64_t & packetRxCount); + CHIP_ERROR _GetEthPacketTxCount(uint64_t & packetTxCount); + CHIP_ERROR _GetEthTxErrCount(uint64_t & txErrCount); + CHIP_ERROR _GetEthCollisionCount(uint64_t & collisionCount); + CHIP_ERROR _GetEthOverrunCount(uint64_t & overrunCount); bool _CanStartWiFiScan(); void _OnWiFiScanDone(); void _OnWiFiStationProvisionChange(); @@ -181,6 +186,36 @@ template inline void GenericConnectivityManagerImpl_WiFi::_OnWiFiStationProvisionChange() {} +template +inline CHIP_ERROR GenericConnectivityManagerImpl_WiFi::_GetEthPacketRxCount(uint64_t & packetRxCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +template +inline CHIP_ERROR GenericConnectivityManagerImpl_WiFi::_GetEthPacketTxCount(uint64_t & packetTxCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +template +inline CHIP_ERROR GenericConnectivityManagerImpl_WiFi::_GetEthTxErrCount(uint64_t & txErrCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +template +inline CHIP_ERROR GenericConnectivityManagerImpl_WiFi::_GetEthCollisionCount(uint64_t & collisionCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +template +inline CHIP_ERROR GenericConnectivityManagerImpl_WiFi::_GetEthOverrunCount(uint64_t & overrunCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + } // namespace Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/Linux/ConnectivityManagerImpl.cpp b/src/platform/Linux/ConnectivityManagerImpl.cpp index f2a82511b0dc64..1aa807a8802c8e 100644 --- a/src/platform/Linux/ConnectivityManagerImpl.cpp +++ b/src/platform/Linux/ConnectivityManagerImpl.cpp @@ -24,6 +24,10 @@ #include #include +#include +#include +#include + #include #include @@ -47,8 +51,18 @@ using namespace ::chip; using namespace ::chip::TLV; using namespace ::chip::DeviceLayer::Internal; -#if CHIP_DEVICE_CONFIG_ENABLE_WPA namespace { + +enum class EthernetStatsCountType +{ + kEthPacketRxCount, + kEthPacketTxCount, + kEthTxErrCount, + kEthCollisionCount, + kEthOverrunCount +}; + +#if CHIP_DEVICE_CONFIG_ENABLE_WPA const char kWpaSupplicantServiceName[] = "fi.w1.wpa_supplicant1"; const char kWpaSupplicantObjectPath[] = "/fi/w1/wpa_supplicant1"; @@ -224,9 +238,71 @@ static uint16_t MapFrequency(const uint16_t inBand, const uint8_t inChannel) return frequency; } -} // namespace #endif +CHIP_ERROR GetEthernetStatsCount(EthernetStatsCountType type, uint64_t & count) +{ + CHIP_ERROR ret = CHIP_ERROR_READ_FAILED; + struct ifaddrs * ifaddr = nullptr; + + if (getifaddrs(&ifaddr) == -1) + { + ChipLogError(DeviceLayer, "Failed to get network interfaces"); + } + else + { + struct ifaddrs * ifa = nullptr; + + /* Walk through linked list, maintaining head pointer so we + can free list later */ + for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) + { + if (strcmp(ifa->ifa_name, CHIP_DEVICE_CONFIG_ETHERNET_IF_NAME) == 0) + break; + } + + if (ifa != nullptr) + { + if (ifa->ifa_addr->sa_family == AF_PACKET && ifa->ifa_data != nullptr) + { + struct rtnl_link_stats * stats = (struct rtnl_link_stats *) ifa->ifa_data; + switch (type) + { + case EthernetStatsCountType::kEthPacketRxCount: + count = stats->rx_packets; + ret = CHIP_NO_ERROR; + break; + case EthernetStatsCountType::kEthPacketTxCount: + count = stats->tx_packets; + ret = CHIP_NO_ERROR; + break; + case EthernetStatsCountType::kEthTxErrCount: + count = stats->tx_errors; + ret = CHIP_NO_ERROR; + break; + case EthernetStatsCountType::kEthCollisionCount: + count = stats->collisions; + ret = CHIP_NO_ERROR; + break; + case EthernetStatsCountType::kEthOverrunCount: + count = stats->rx_over_errors; + ret = CHIP_NO_ERROR; + break; + default: + ChipLogError(DeviceLayer, "Unknown Ethernet statistic metric type"); + break; + } + } + } + + freeifaddrs(ifaddr); + } + + return ret; +} + +} // namespace + namespace chip { namespace DeviceLayer { @@ -456,6 +532,31 @@ void ConnectivityManagerImpl::_SetWiFiAPIdleTimeoutMS(uint32_t val) DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, NULL); } +CHIP_ERROR ConnectivityManagerImpl::_GetEthPacketRxCount(uint64_t & packetRxCount) +{ + return GetEthernetStatsCount(EthernetStatsCountType::kEthPacketRxCount, packetRxCount); +} + +CHIP_ERROR ConnectivityManagerImpl::_GetEthPacketTxCount(uint64_t & packetTxCount) +{ + return GetEthernetStatsCount(EthernetStatsCountType::kEthPacketTxCount, packetTxCount); +} + +CHIP_ERROR ConnectivityManagerImpl::_GetEthTxErrCount(uint64_t & txErrCount) +{ + return GetEthernetStatsCount(EthernetStatsCountType::kEthTxErrCount, txErrCount); +} + +CHIP_ERROR ConnectivityManagerImpl::_GetEthCollisionCount(uint64_t & collisionCount) +{ + return GetEthernetStatsCount(EthernetStatsCountType::kEthCollisionCount, collisionCount); +} + +CHIP_ERROR ConnectivityManagerImpl::_GetEthOverrunCount(uint64_t & overrunCount) +{ + return GetEthernetStatsCount(EthernetStatsCountType::kEthOverrunCount, overrunCount); +} + void ConnectivityManagerImpl::_OnWpaInterfaceProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data) { GError * err = nullptr; diff --git a/src/platform/Linux/ConnectivityManagerImpl.h b/src/platform/Linux/ConnectivityManagerImpl.h index e2ef99d64b0438..a6b48d57489bf5 100644 --- a/src/platform/Linux/ConnectivityManagerImpl.h +++ b/src/platform/Linux/ConnectivityManagerImpl.h @@ -142,6 +142,12 @@ class ConnectivityManagerImpl final : public ConnectivityManager, uint32_t _GetWiFiAPIdleTimeoutMS(); void _SetWiFiAPIdleTimeoutMS(uint32_t val); + CHIP_ERROR _GetEthPacketRxCount(uint64_t & packetRxCount); + CHIP_ERROR _GetEthPacketTxCount(uint64_t & packetTxCount); + CHIP_ERROR _GetEthTxErrCount(uint64_t & txErrCount); + CHIP_ERROR _GetEthCollisionCount(uint64_t & collisionCount); + CHIP_ERROR _GetEthOverrunCount(uint64_t & overrunCount); + static void _OnWpaProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data); static void _OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * proxy, const gchar * path, GVariant * properties, gpointer user_data); diff --git a/zzz_generated/lighting-app/zap-generated/endpoint_config.h b/zzz_generated/lighting-app/zap-generated/endpoint_config.h index 6ddd9854c45eac..805d390c358ba3 100644 --- a/zzz_generated/lighting-app/zap-generated/endpoint_config.h +++ b/zzz_generated/lighting-app/zap-generated/endpoint_config.h @@ -849,12 +849,16 @@ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 0, Cluster: Ethernet Network Diagnostics (server) */ \ - { 0x0002, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(1891) }, /* PacketRxCount */ \ - { 0x0003, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(1899) }, /* PacketTxCount */ \ - { 0x0004, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(1907) }, /* TxErrCount */ \ - { 0x0005, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(1915) }, /* CollisionCount */ \ - { 0x0006, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(1923) }, /* OverrunCount */ \ - { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ + { 0x0002, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_LONG_DEFAULTS_INDEX(1891) }, /* PacketRxCount */ \ + { 0x0003, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_LONG_DEFAULTS_INDEX(1899) }, /* PacketTxCount */ \ + { 0x0004, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_LONG_DEFAULTS_INDEX(1907) }, /* TxErrCount */ \ + { 0x0005, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_LONG_DEFAULTS_INDEX(1915) }, /* CollisionCount */ \ + { 0x0006, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_LONG_DEFAULTS_INDEX(1923) }, /* OverrunCount */ \ + { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 0, Cluster: AdministratorCommissioning (server) */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ From aea81e34c43a059493531a33e69b5e7fda649b7b Mon Sep 17 00:00:00 2001 From: Song GUO Date: Sat, 11 Sep 2021 12:07:22 +0800 Subject: [PATCH 003/255] [build] Add sysroot / system_libdir support (#9352) * [build] Add sysroot config * Fix Clang build * Update src/app/clusters/thermostat-server/thermostat-server.cpp Co-authored-by: Boris Zbarsky --- build/chip/linux/gen_gdbus_wrapper.py | 3 +++ build/chip/tests.gni | 4 +++- build/config/compiler/BUILD.gn | 5 +++++ build/config/linux/pkg-config.py | 6 ------ build/config/linux/pkg_config.gni | 17 +++++++++++++++++ build/config/sysroot.gni | 17 +++++++++++++++++ .../thermostat-server/thermostat-server.cpp | 1 + src/tools/chip-cert/GeneralUtils.cpp | 2 +- 8 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 build/config/sysroot.gni diff --git a/build/chip/linux/gen_gdbus_wrapper.py b/build/chip/linux/gen_gdbus_wrapper.py index 263d5b72c37aff..8657d06693d222 100755 --- a/build/chip/linux/gen_gdbus_wrapper.py +++ b/build/chip/linux/gen_gdbus_wrapper.py @@ -66,6 +66,9 @@ def main(argv): subprocess.check_call(gdbus_args) sed_args = ["sed", "-i", "s/config\.h/BuildConfig.h/g", options.output_c] + if sys.platform == "darwin": + sed_args = ["sed", "-i", "", + "s/config\.h/BuildConfig.h/g", options.output_c] subprocess.check_call(sed_args) if options.output_h: diff --git a/build/chip/tests.gni b/build/chip/tests.gni index 137cc0122eda93..9d4089874027e9 100644 --- a/build/chip/tests.gni +++ b/build/chip/tests.gni @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import("//build_overrides/build.gni") import("//build_overrides/chip.gni") import("${chip_root}/src/platform/device.gni") @@ -27,7 +28,8 @@ declare_args() { declare_args() { # Build executables for running individual tests. chip_link_tests = - chip_build_tests && (current_os == "linux" || current_os == "mac") + chip_build_tests && (current_os == "linux" || current_os == "mac") && + current_cpu == target_cpu # Use source_set instead of static_lib for tests. chip_build_test_static_libraries = chip_device_platform != "efr32" diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index a7e1fda362b0c1..02794d900e991a 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn @@ -16,6 +16,7 @@ import("//build_overrides/build.gni") import("//build_overrides/pigweed.gni") import("${build_root}/config/compiler/compiler.gni") +import("${build_root}/config/sysroot.gni") import("${build_root}/config/target.gni") if (current_os == "mac") { @@ -274,6 +275,10 @@ config("runtime_default") { "rt", ] } + if (sysroot != "") { + cflags = [ "--sysroot=${sysroot}" ] + ldflags = [ "--sysroot=${sysroot}" ] + } } # To use different sanitizer options, use `gn args .` in the out folder and diff --git a/build/config/linux/pkg-config.py b/build/config/linux/pkg-config.py index 2458ebe41dccb7..510a0827054262 100755 --- a/build/config/linux/pkg-config.py +++ b/build/config/linux/pkg-config.py @@ -78,12 +78,6 @@ def SetConfigPath(options): sysroot = options.sysroot assert sysroot - # Compute the library path name based on the architecture. - arch = options.arch - if sysroot and not arch: - print("You must specify an architecture via -a if using a sysroot.") - sys.exit(1) - libdir = sysroot + '/usr/' + options.system_libdir + '/pkgconfig' libdir += ':' + sysroot + '/usr/share/pkgconfig' os.environ['PKG_CONFIG_LIBDIR'] = libdir diff --git a/build/config/linux/pkg_config.gni b/build/config/linux/pkg_config.gni index cabb64708ef684..fb8f5aab32d703 100644 --- a/build/config/linux/pkg_config.gni +++ b/build/config/linux/pkg_config.gni @@ -48,6 +48,7 @@ # ignore_libs = true import("//build_overrides/build.gni") +import("${build_root}/config/sysroot.gni") declare_args() { # A pkg-config wrapper to call instead of trying to find and call the right @@ -59,6 +60,8 @@ declare_args() { # A optional pkg-config wrapper to use for tools built on the host. host_pkg_config = "" + + system_libdir = "lib" } pkg_config_script = "${build_root}/config/linux/pkg-config.py" @@ -83,6 +86,20 @@ if (host_pkg_config != "") { host_pkg_config_args = pkg_config_args } +if (sysroot != "") { + pkg_config_args += [ + "-s", + sysroot, + ] + + if (system_libdir != "") { + pkg_config_args += [ + "--system_libdir", + system_libdir, + ] + } +} + template("pkg_config") { assert(defined(invoker.packages), "Variable |packages| must be defined to be a list in pkg_config.") diff --git a/build/config/sysroot.gni b/build/config/sysroot.gni new file mode 100644 index 00000000000000..d022c7e8f07841 --- /dev/null +++ b/build/config/sysroot.gni @@ -0,0 +1,17 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +declare_args() { + sysroot = "" +} diff --git a/src/app/clusters/thermostat-server/thermostat-server.cpp b/src/app/clusters/thermostat-server/thermostat-server.cpp index 854d89229715f9..53476f683de283 100644 --- a/src/app/clusters/thermostat-server/thermostat-server.cpp +++ b/src/app/clusters/thermostat-server/thermostat-server.cpp @@ -244,6 +244,7 @@ EmberAfStatus emberAfThermostatClusterServerPreAttributeChangedCallback(chip::En break; } } + break; } default: break; diff --git a/src/tools/chip-cert/GeneralUtils.cpp b/src/tools/chip-cert/GeneralUtils.cpp index e9623b2a3c31e9..8641a6e9c59dde 100644 --- a/src/tools/chip-cert/GeneralUtils.cpp +++ b/src/tools/chip-cert/GeneralUtils.cpp @@ -257,7 +257,7 @@ bool ReadFileIntoMem(const char * fileName, uint8_t * data, uint32_t & dataLen) ExitNow(res = false); } - VerifyOrExit(fileLen <= UINT32_MAX, res = false); + VerifyOrExit(chip::CanCastTo(fileLen), res = false); dataLen = static_cast(fileLen); From 5a9c063c83d039fe284fdb5afb1b7c5b5e1791b0 Mon Sep 17 00:00:00 2001 From: Zang MingJie Date: Sat, 11 Sep 2021 12:30:48 +0800 Subject: [PATCH 004/255] Rename Local and Peer in message tests into Alice and Bob (#9561) --- src/app/tests/TestReadInteraction.cpp | 12 +++--- src/app/tests/TestWriteInteraction.cpp | 11 +++-- src/messaging/tests/MessagingContext.cpp | 20 ++++----- src/messaging/tests/MessagingContext.h | 42 +++++++++---------- src/messaging/tests/TestExchangeMgr.cpp | 20 ++++----- .../tests/TestReliableMessageProtocol.cpp | 38 ++++++++--------- .../secure_channel/tests/TestCASESession.cpp | 18 ++++---- .../tests/TestMessageCounterManager.cpp | 8 ++-- .../secure_channel/tests/TestPASESession.cpp | 16 +++---- 9 files changed, 92 insertions(+), 93 deletions(-) diff --git a/src/app/tests/TestReadInteraction.cpp b/src/app/tests/TestReadInteraction.cpp index 6dfe57bf4872c5..be52e93a774dcf 100644 --- a/src/app/tests/TestReadInteraction.cpp +++ b/src/app/tests/TestReadInteraction.cpp @@ -322,7 +322,7 @@ void TestReadInteraction::TestReadClient(nlTestSuite * apSuite, void * apContext System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); err = readClient.Init(&ctx.GetExchangeManager(), &delegate, 0 /* application identifier */); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ReadPrepareParams readPrepareParams(ctx.GetSessionLocalToPeer()); + ReadPrepareParams readPrepareParams(ctx.GetSessionBobToAlice()); err = readClient.SendReadRequest(readPrepareParams); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); @@ -347,7 +347,7 @@ void TestReadInteraction::TestReadHandler(nlTestSuite * apSuite, void * apContex auto * engine = chip::app::InteractionModelEngine::GetInstance(); err = engine->Init(&ctx.GetExchangeManager(), &delegate); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - Messaging::ExchangeContext * exchangeCtx = ctx.NewExchangeToPeer(nullptr); + Messaging::ExchangeContext * exchangeCtx = ctx.NewExchangeToAlice(nullptr); readHandler.Init(&ctx.GetExchangeManager(), nullptr, exchangeCtx); GenerateReportData(apSuite, apContext, reportDatabuf); @@ -449,7 +449,7 @@ void TestReadInteraction::TestReadClientInvalidReport(nlTestSuite * apSuite, voi err = readClient.Init(&ctx.GetExchangeManager(), &delegate, 0 /* application identifier */); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - ReadPrepareParams readPrepareParams(ctx.GetSessionLocalToPeer()); + ReadPrepareParams readPrepareParams(ctx.GetSessionBobToAlice()); err = readClient.SendReadRequest(readPrepareParams); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); @@ -475,7 +475,7 @@ void TestReadInteraction::TestReadHandlerInvalidAttributePath(nlTestSuite * apSu auto * engine = chip::app::InteractionModelEngine::GetInstance(); err = engine->Init(&ctx.GetExchangeManager(), &delegate); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - Messaging::ExchangeContext * exchangeCtx = ctx.NewExchangeToPeer(nullptr); + Messaging::ExchangeContext * exchangeCtx = ctx.NewExchangeToAlice(nullptr); readHandler.Init(&ctx.GetExchangeManager(), nullptr, exchangeCtx); GenerateReportData(apSuite, apContext, reportDatabuf); @@ -656,7 +656,7 @@ void TestReadInteraction::TestReadRoundtrip(nlTestSuite * apSuite, void * apCont attributePathParams[1].mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); attributePathParams[1].mFlags.Set(chip::app::AttributePathParams::Flags::kListIndexValid); - ReadPrepareParams readPrepareParams(ctx.GetSessionLocalToPeer()); + ReadPrepareParams readPrepareParams(ctx.GetSessionBobToAlice()); readPrepareParams.mpEventPathParamsList = eventPathParams; readPrepareParams.mEventPathParamsListSize = 2; readPrepareParams.mpAttributePathParamsList = attributePathParams; @@ -701,7 +701,7 @@ void TestReadInteraction::TestReadInvalidAttributePathRoundtrip(nlTestSuite * ap attributePathParams[0].mListIndex = 0; attributePathParams[0].mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); - ReadPrepareParams readPrepareParams(ctx.GetSessionLocalToPeer()); + ReadPrepareParams readPrepareParams(ctx.GetSessionBobToAlice()); readPrepareParams.mpAttributePathParamsList = attributePathParams; readPrepareParams.mAttributePathParamsListSize = 1; err = chip::app::InteractionModelEngine::GetInstance()->SendReadRequest(readPrepareParams); diff --git a/src/app/tests/TestWriteInteraction.cpp b/src/app/tests/TestWriteInteraction.cpp index 81b955212491ba..9d8802a6c85d17 100644 --- a/src/app/tests/TestWriteInteraction.cpp +++ b/src/app/tests/TestWriteInteraction.cpp @@ -216,9 +216,8 @@ void TestWriteInteraction::TestWriteClient(nlTestSuite * apSuite, void * apConte NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); AddAttributeDataElement(apSuite, apContext, writeClientHandle); - SessionHandle session = ctx.GetSessionLocalToPeer(); - err = writeClientHandle.SendWriteRequest(ctx.GetDestinationNodeId(), ctx.GetFabricIndex(), - Optional::Value(session)); + SessionHandle session = ctx.GetSessionBobToAlice(); + err = writeClientHandle.SendWriteRequest(ctx.GetAliceNodeId(), ctx.GetFabricIndex(), Optional::Value(session)); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); // The internal WriteClient should be nullptr once we SendWriteRequest. NL_TEST_ASSERT(apSuite, nullptr == writeClientHandle.mpWriteClient); @@ -249,7 +248,7 @@ void TestWriteInteraction::TestWriteHandler(nlTestSuite * apSuite, void * apCont GenerateWriteRequest(apSuite, apContext, buf); TestExchangeDelegate delegate; - Messaging::ExchangeContext * exchange = ctx.NewExchangeToLocal(&delegate); + Messaging::ExchangeContext * exchange = ctx.NewExchangeToBob(&delegate); err = writeHandler.OnWriteRequest(exchange, std::move(buf)); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); @@ -305,9 +304,9 @@ void TestWriteInteraction::TestWriteRoundtrip(nlTestSuite * apSuite, void * apCo NL_TEST_ASSERT(apSuite, !delegate.mGotResponse); - SessionHandle session = ctx.GetSessionLocalToPeer(); + SessionHandle session = ctx.GetSessionBobToAlice(); - err = writeClient.SendWriteRequest(ctx.GetDestinationNodeId(), ctx.GetFabricIndex(), Optional::Value(session)); + err = writeClient.SendWriteRequest(ctx.GetAliceNodeId(), ctx.GetFabricIndex(), Optional::Value(session)); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); NL_TEST_ASSERT(apSuite, delegate.mGotResponse); diff --git a/src/messaging/tests/MessagingContext.cpp b/src/messaging/tests/MessagingContext.cpp index 10c2ceca50d4a6..dc96e07fb9146e 100644 --- a/src/messaging/tests/MessagingContext.cpp +++ b/src/messaging/tests/MessagingContext.cpp @@ -37,10 +37,10 @@ CHIP_ERROR MessagingContext::Init(nlTestSuite * suite, TransportMgrBase * transp ReturnErrorOnFailure(mExchangeManager.Init(&mSecureSessionMgr)); ReturnErrorOnFailure(mMessageCounterManager.Init(&mExchangeManager)); - ReturnErrorOnFailure(mSecureSessionMgr.NewPairing(mPeer, GetDestinationNodeId(), &mPairingLocalToPeer, + ReturnErrorOnFailure(mSecureSessionMgr.NewPairing(mAddress, GetAliceNodeId(), &mPairingBobToAlice, SecureSession::SessionRole::kInitiator, mSrcFabricIndex)); - return mSecureSessionMgr.NewPairing(mPeer, GetSourceNodeId(), &mPairingPeerToLocal, SecureSession::SessionRole::kResponder, + return mSecureSessionMgr.NewPairing(mAddress, GetBobNodeId(), &mPairingAliceToBob, SecureSession::SessionRole::kResponder, mDestFabricIndex); } @@ -55,28 +55,28 @@ CHIP_ERROR MessagingContext::Shutdown() return CHIP_NO_ERROR; } -SessionHandle MessagingContext::GetSessionLocalToPeer() +SessionHandle MessagingContext::GetSessionBobToAlice() { // TODO: temporarily create a SessionHandle from node id, will be fixed in PR 3602 - return SessionHandle(GetDestinationNodeId(), GetLocalKeyId(), GetPeerKeyId(), GetFabricIndex()); + return SessionHandle(GetAliceNodeId(), GetBobKeyId(), GetAliceKeyId(), GetFabricIndex()); } -SessionHandle MessagingContext::GetSessionPeerToLocal() +SessionHandle MessagingContext::GetSessionAliceToBob() { // TODO: temporarily create a SessionHandle from node id, will be fixed in PR 3602 - return SessionHandle(GetSourceNodeId(), GetPeerKeyId(), GetLocalKeyId(), mDestFabricIndex); + return SessionHandle(GetBobNodeId(), GetAliceKeyId(), GetBobKeyId(), mDestFabricIndex); } -Messaging::ExchangeContext * MessagingContext::NewExchangeToPeer(Messaging::ExchangeDelegate * delegate) +Messaging::ExchangeContext * MessagingContext::NewExchangeToAlice(Messaging::ExchangeDelegate * delegate) { // TODO: temprary create a SessionHandle from node id, will be fix in PR 3602 - return mExchangeManager.NewContext(GetSessionLocalToPeer(), delegate); + return mExchangeManager.NewContext(GetSessionBobToAlice(), delegate); } -Messaging::ExchangeContext * MessagingContext::NewExchangeToLocal(Messaging::ExchangeDelegate * delegate) +Messaging::ExchangeContext * MessagingContext::NewExchangeToBob(Messaging::ExchangeDelegate * delegate) { // TODO: temprary create a SessionHandle from node id, will be fix in PR 3602 - return mExchangeManager.NewContext(GetSessionPeerToLocal(), delegate); + return mExchangeManager.NewContext(GetSessionAliceToBob(), delegate); } } // namespace Test diff --git a/src/messaging/tests/MessagingContext.h b/src/messaging/tests/MessagingContext.h index fc441646d8d041..6bb4e70df69eb0 100644 --- a/src/messaging/tests/MessagingContext.h +++ b/src/messaging/tests/MessagingContext.h @@ -37,8 +37,8 @@ class MessagingContext { public: MessagingContext() : - mInitialized(false), mPeer(Transport::PeerAddress::UDP(GetAddress(), CHIP_PORT)), - mPairingPeerToLocal(GetLocalKeyId(), GetPeerKeyId()), mPairingLocalToPeer(GetPeerKeyId(), GetLocalKeyId()) + mInitialized(false), mAddress(Transport::PeerAddress::UDP(GetAddress(), CHIP_PORT)), + mPairingAliceToBob(GetBobKeyId(), GetAliceKeyId()), mPairingBobToAlice(GetAliceKeyId(), GetBobKeyId()) {} ~MessagingContext() { VerifyOrDie(mInitialized == false); } @@ -54,17 +54,17 @@ class MessagingContext Inet::IPAddress::FromString("127.0.0.1", addr); return addr; } - NodeId GetSourceNodeId() const { return mSourceNodeId; } - NodeId GetDestinationNodeId() const { return mDestinationNodeId; } + NodeId GetBobNodeId() const { return mBobNodeId; } + NodeId GetAliceNodeId() const { return mAliceNodeId; } - void SetSourceNodeId(NodeId nodeId) { mSourceNodeId = nodeId; } - void SetDestinationNodeId(NodeId nodeId) { mDestinationNodeId = nodeId; } + void SetBobNodeId(NodeId nodeId) { mBobNodeId = nodeId; } + void SetAliceNodeId(NodeId nodeId) { mAliceNodeId = nodeId; } - uint16_t GetLocalKeyId() const { return mLocalKeyId; } - uint16_t GetPeerKeyId() const { return mPeerKeyId; } + uint16_t GetBobKeyId() const { return mBobKeyId; } + uint16_t GetAliceKeyId() const { return mAliceKeyId; } - void SetLocalKeyId(uint16_t id) { mLocalKeyId = id; } - void SetPeerKeyId(uint16_t id) { mPeerKeyId = id; } + void SetBobKeyId(uint16_t id) { mBobKeyId = id; } + void SetAliceKeyId(uint16_t id) { mAliceKeyId = id; } FabricIndex GetFabricIndex() const { return mSrcFabricIndex; } void SetFabricIndex(FabricIndex id) @@ -77,11 +77,11 @@ class MessagingContext Messaging::ExchangeManager & GetExchangeManager() { return mExchangeManager; } secure_channel::MessageCounterManager & GetMessageCounterManager() { return mMessageCounterManager; } - SessionHandle GetSessionLocalToPeer(); - SessionHandle GetSessionPeerToLocal(); + SessionHandle GetSessionBobToAlice(); + SessionHandle GetSessionAliceToBob(); - Messaging::ExchangeContext * NewExchangeToPeer(Messaging::ExchangeDelegate * delegate); - Messaging::ExchangeContext * NewExchangeToLocal(Messaging::ExchangeDelegate * delegate); + Messaging::ExchangeContext * NewExchangeToAlice(Messaging::ExchangeDelegate * delegate); + Messaging::ExchangeContext * NewExchangeToBob(Messaging::ExchangeDelegate * delegate); Credentials::OperationalCredentialSet & GetOperationalCredentialSet() { return mOperationalCredentialSet; } @@ -94,13 +94,13 @@ class MessagingContext secure_channel::MessageCounterManager mMessageCounterManager; IOContext * mIOContext; - NodeId mSourceNodeId = 123654; - NodeId mDestinationNodeId = 111222333; - uint16_t mLocalKeyId = 1; - uint16_t mPeerKeyId = 2; - Optional mPeer; - SecurePairingUsingTestSecret mPairingPeerToLocal; - SecurePairingUsingTestSecret mPairingLocalToPeer; + NodeId mBobNodeId = 123654; + NodeId mAliceNodeId = 111222333; + uint16_t mBobKeyId = 1; + uint16_t mAliceKeyId = 2; + Optional mAddress; + SecurePairingUsingTestSecret mPairingAliceToBob; + SecurePairingUsingTestSecret mPairingBobToAlice; Transport::FabricTable mFabrics; FabricIndex mSrcFabricIndex = 0; FabricIndex mDestFabricIndex = 0; diff --git a/src/messaging/tests/TestExchangeMgr.cpp b/src/messaging/tests/TestExchangeMgr.cpp index ae58e04a068f26..7733d5becd9a09 100644 --- a/src/messaging/tests/TestExchangeMgr.cpp +++ b/src/messaging/tests/TestExchangeMgr.cpp @@ -95,21 +95,21 @@ void CheckNewContextTest(nlTestSuite * inSuite, void * inContext) TestContext & ctx = *reinterpret_cast(inContext); MockAppDelegate mockAppDelegate; - ExchangeContext * ec1 = ctx.NewExchangeToLocal(&mockAppDelegate); + ExchangeContext * ec1 = ctx.NewExchangeToBob(&mockAppDelegate); NL_TEST_ASSERT(inSuite, ec1 != nullptr); NL_TEST_ASSERT(inSuite, ec1->IsInitiator() == true); NL_TEST_ASSERT(inSuite, ec1->GetExchangeId() != 0); auto sessionPeerToLocal = ctx.GetSecureSessionManager().GetPeerConnectionState(ec1->GetSecureSession()); - NL_TEST_ASSERT(inSuite, sessionPeerToLocal->GetPeerNodeId() == ctx.GetSourceNodeId()); - NL_TEST_ASSERT(inSuite, sessionPeerToLocal->GetPeerKeyID() == ctx.GetLocalKeyId()); + NL_TEST_ASSERT(inSuite, sessionPeerToLocal->GetPeerNodeId() == ctx.GetBobNodeId()); + NL_TEST_ASSERT(inSuite, sessionPeerToLocal->GetPeerKeyID() == ctx.GetBobKeyId()); NL_TEST_ASSERT(inSuite, ec1->GetDelegate() == &mockAppDelegate); - ExchangeContext * ec2 = ctx.NewExchangeToPeer(&mockAppDelegate); + ExchangeContext * ec2 = ctx.NewExchangeToAlice(&mockAppDelegate); NL_TEST_ASSERT(inSuite, ec2 != nullptr); NL_TEST_ASSERT(inSuite, ec2->GetExchangeId() > ec1->GetExchangeId()); auto sessionLocalToPeer = ctx.GetSecureSessionManager().GetPeerConnectionState(ec2->GetSecureSession()); - NL_TEST_ASSERT(inSuite, sessionLocalToPeer->GetPeerNodeId() == ctx.GetDestinationNodeId()); - NL_TEST_ASSERT(inSuite, sessionLocalToPeer->GetPeerKeyID() == ctx.GetPeerKeyId()); + NL_TEST_ASSERT(inSuite, sessionLocalToPeer->GetPeerNodeId() == ctx.GetAliceNodeId()); + NL_TEST_ASSERT(inSuite, sessionLocalToPeer->GetPeerKeyID() == ctx.GetAliceKeyId()); ec1->Close(); ec2->Close(); @@ -120,7 +120,7 @@ void CheckSessionExpirationBasics(nlTestSuite * inSuite, void * inContext) TestContext & ctx = *reinterpret_cast(inContext); MockAppDelegate sendDelegate; - ExchangeContext * ec1 = ctx.NewExchangeToLocal(&sendDelegate); + ExchangeContext * ec1 = ctx.NewExchangeToBob(&sendDelegate); // Expire the session this exchange is supposedly on. ctx.GetExchangeManager().OnConnectionExpired(ec1->GetSecureSession()); @@ -145,7 +145,7 @@ void CheckSessionExpirationTimeout(nlTestSuite * inSuite, void * inContext) TestContext & ctx = *reinterpret_cast(inContext); WaitForTimeoutDelegate sendDelegate; - ExchangeContext * ec1 = ctx.NewExchangeToLocal(&sendDelegate); + ExchangeContext * ec1 = ctx.NewExchangeToBob(&sendDelegate); ec1->SendMessage(Protocols::BDX::Id, kMsgType_TEST1, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize), SendFlags(Messaging::SendMessageFlags::kExpectResponse).Set(Messaging::SendMessageFlags::kNoAutoRequestAck)); @@ -191,7 +191,7 @@ void CheckExchangeMessages(nlTestSuite * inSuite, void * inContext) // create solicited exchange MockAppDelegate mockSolicitedAppDelegate; - ExchangeContext * ec1 = ctx.NewExchangeToPeer(&mockSolicitedAppDelegate); + ExchangeContext * ec1 = ctx.NewExchangeToAlice(&mockSolicitedAppDelegate); // create unsolicited exchange MockAppDelegate mockUnsolicitedAppDelegate; @@ -204,7 +204,7 @@ void CheckExchangeMessages(nlTestSuite * inSuite, void * inContext) SendFlags(Messaging::SendMessageFlags::kNoAutoRequestAck)); NL_TEST_ASSERT(inSuite, !mockUnsolicitedAppDelegate.IsOnMessageReceivedCalled); - ec1 = ctx.NewExchangeToPeer(&mockSolicitedAppDelegate); + ec1 = ctx.NewExchangeToAlice(&mockSolicitedAppDelegate); // send a good packet ec1->SendMessage(Protocols::BDX::Id, kMsgType_TEST1, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize), diff --git a/src/messaging/tests/TestReliableMessageProtocol.cpp b/src/messaging/tests/TestReliableMessageProtocol.cpp index 45af7707f7253a..1f5a4b94ab217f 100644 --- a/src/messaging/tests/TestReliableMessageProtocol.cpp +++ b/src/messaging/tests/TestReliableMessageProtocol.cpp @@ -192,7 +192,7 @@ void CheckAddClearRetrans(nlTestSuite * inSuite, void * inContext) TestContext & ctx = *reinterpret_cast(inContext); MockAppDelegate mockAppDelegate; - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockAppDelegate); + ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockAppDelegate); NL_TEST_ASSERT(inSuite, exchange != nullptr); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); @@ -215,7 +215,7 @@ void CheckFailRetrans(nlTestSuite * inSuite, void * inContext) TestContext & ctx = *reinterpret_cast(inContext); MockAppDelegate mockAppDelegate; - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockAppDelegate); + ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockAppDelegate); NL_TEST_ASSERT(inSuite, exchange != nullptr); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); @@ -243,7 +243,7 @@ void CheckResendApplicationMessage(nlTestSuite * inSuite, void * inContext) MockAppDelegate mockSender; // TODO: temporarily create a SessionHandle from node id, will be fix in PR 3602 - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockSender); + ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); @@ -308,7 +308,7 @@ void CheckCloseExchangeAndResendApplicationMessage(nlTestSuite * inSuite, void * MockAppDelegate mockSender; // TODO: temporarily create a SessionHandle from node id, will be fixed in PR 3602 - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockSender); + ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); @@ -367,7 +367,7 @@ void CheckFailedMessageRetainOnSend(nlTestSuite * inSuite, void * inContext) CHIP_ERROR err = CHIP_NO_ERROR; MockSessionEstablishmentDelegate mockSender; - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockSender); + ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); @@ -421,7 +421,7 @@ void CheckUnencryptedMessageReceiveFailure(nlTestSuite * inSuite, void * inConte mockReceiver.mMessageDispatch.mRequireEncryption = true; MockSessionEstablishmentDelegate mockSender; - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockSender); + ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); @@ -463,7 +463,7 @@ void CheckResendApplicationMessageWithPeerExchange(nlTestSuite * inSuite, void * mockReceiver.mTestSuite = inSuite; MockAppDelegate mockSender; - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockSender); + ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); @@ -525,7 +525,7 @@ void CheckDuplicateMessageClosedExchange(nlTestSuite * inSuite, void * inContext mockReceiver.mTestSuite = inSuite; MockAppDelegate mockSender; - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockSender); + ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); @@ -584,10 +584,10 @@ void CheckResendSessionEstablishmentMessageWithPeerExchange(nlTestSuite * inSuit CHIP_ERROR err = ctx.Init(inSuite, &gTransportMgr, &gIOContext); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.SetSourceNodeId(kPlaceholderNodeId); - ctx.SetDestinationNodeId(kPlaceholderNodeId); - ctx.SetLocalKeyId(0); - ctx.SetPeerKeyId(0); + ctx.SetBobNodeId(kPlaceholderNodeId); + ctx.SetAliceNodeId(kPlaceholderNodeId); + ctx.SetBobKeyId(0); + ctx.SetAliceKeyId(0); ctx.SetFabricIndex(kUndefinedFabricIndex); chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); @@ -600,7 +600,7 @@ void CheckResendSessionEstablishmentMessageWithPeerExchange(nlTestSuite * inSuit mockReceiver.mTestSuite = inSuite; MockSessionEstablishmentDelegate mockSender; - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockSender); + ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); @@ -676,7 +676,7 @@ void CheckDuplicateMessage(nlTestSuite * inSuite, void * inContext) mockReceiver.mTestSuite = inSuite; MockAppDelegate mockSender; - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockSender); + ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); @@ -746,7 +746,7 @@ void CheckReceiveAfterStandaloneAck(nlTestSuite * inSuite, void * inContext) mockReceiver.mTestSuite = inSuite; MockAppDelegate mockSender; - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockSender); + ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); mockSender.mTestSuite = inSuite; @@ -831,7 +831,7 @@ void CheckNoPiggybackAfterPiggyback(nlTestSuite * inSuite, void * inContext) mockReceiver.mTestSuite = inSuite; MockAppDelegate mockSender; - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockSender); + ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); mockSender.mTestSuite = inSuite; @@ -958,7 +958,7 @@ void CheckSendUnsolicitedStandaloneAckMessage(nlTestSuite * inSuite, void * inCo CHIP_ERROR err = CHIP_NO_ERROR; MockAppDelegate mockSender; - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockSender); + ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); mockSender.mTestSuite = inSuite; @@ -994,7 +994,7 @@ void CheckSendStandaloneAckMessage(nlTestSuite * inSuite, void * inContext) TestContext & ctx = *reinterpret_cast(inContext); MockAppDelegate mockAppDelegate; - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockAppDelegate); + ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockAppDelegate); NL_TEST_ASSERT(inSuite, exchange != nullptr); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); @@ -1038,7 +1038,7 @@ void CheckMessageAfterClosed(nlTestSuite * inSuite, void * inContext) mockReceiver.mTestSuite = inSuite; MockAppDelegate mockSender; - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockSender); + ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); mockSender.mTestSuite = inSuite; diff --git a/src/protocols/secure_channel/tests/TestCASESession.cpp b/src/protocols/secure_channel/tests/TestCASESession.cpp index a568e9ed9ad841..2868e7373ded63 100644 --- a/src/protocols/secure_channel/tests/TestCASESession.cpp +++ b/src/protocols/secure_channel/tests/TestCASESession.cpp @@ -177,7 +177,7 @@ void CASE_SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, fabric != nullptr); NL_TEST_ASSERT(inSuite, pairing.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - ExchangeContext * context = ctx.NewExchangeToLocal(&pairing); + ExchangeContext * context = ctx.NewExchangeToBob(&pairing); NL_TEST_ASSERT(inSuite, pairing.EstablishSession(Transport::PeerAddress(Transport::Type::kBle), nullptr, Node01_01, 0, nullptr, @@ -198,7 +198,7 @@ void CASE_SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) gLoopback.mSentMessageCount = 0; gLoopback.mMessageSendError = CHIP_ERROR_BAD_REQUEST; - ExchangeContext * context1 = ctx.NewExchangeToLocal(&pairing1); + ExchangeContext * context1 = ctx.NewExchangeToBob(&pairing1); NL_TEST_ASSERT(inSuite, pairing1.EstablishSession(Transport::PeerAddress(Transport::Type::kBle), fabric, Node01_01, 0, context1, @@ -225,7 +225,7 @@ void CASE_SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inConte ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType( Protocols::SecureChannel::MsgType::CASE_SigmaR1, &pairingAccessory) == CHIP_NO_ERROR); - ExchangeContext * contextCommissioner = ctx.NewExchangeToLocal(&pairingCommissioner); + ExchangeContext * contextCommissioner = ctx.NewExchangeToBob(&pairingCommissioner); FabricInfo * fabric = gCommissionerFabrics.FindFabricWithIndex(gCommissionerFabricIndex); NL_TEST_ASSERT(inSuite, fabric != nullptr); @@ -353,7 +353,7 @@ void CASE_SecurePairingHandshakeServerTest(nlTestSuite * inSuite, void * inConte &ctx.GetSecureSessionManager(), &gDeviceFabrics, &idAllocator) == CHIP_NO_ERROR); - ExchangeContext * contextCommissioner = ctx.NewExchangeToLocal(pairingCommissioner); + ExchangeContext * contextCommissioner = ctx.NewExchangeToBob(pairingCommissioner); FabricInfo * fabric = gCommissionerFabrics.FindFabricWithIndex(gCommissionerFabricIndex); NL_TEST_ASSERT(inSuite, fabric != nullptr); @@ -367,7 +367,7 @@ void CASE_SecurePairingHandshakeServerTest(nlTestSuite * inSuite, void * inConte auto * pairingCommissioner1 = chip::Platform::New(); NL_TEST_ASSERT(inSuite, pairingCommissioner1->MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - ExchangeContext * contextCommissioner1 = ctx.NewExchangeToLocal(pairingCommissioner1); + ExchangeContext * contextCommissioner1 = ctx.NewExchangeToBob(pairingCommissioner1); NL_TEST_ASSERT(inSuite, pairingCommissioner1->EstablishSession(Transport::PeerAddress(Transport::Type::kBle), fabric, Node01_01, 0, @@ -480,10 +480,10 @@ CHIP_ERROR CASETestSecurePairingSetup(void * inContext) ReturnErrorOnFailure(ctx.Init(&sSuite, &gTransportMgr, &gIOContext)); - ctx.SetSourceNodeId(kPlaceholderNodeId); - ctx.SetDestinationNodeId(kPlaceholderNodeId); - ctx.SetLocalKeyId(0); - ctx.SetPeerKeyId(0); + ctx.SetBobNodeId(kPlaceholderNodeId); + ctx.SetAliceNodeId(kPlaceholderNodeId); + ctx.SetBobKeyId(0); + ctx.SetAliceKeyId(0); ctx.SetFabricIndex(kUndefinedFabricIndex); gTransportMgr.SetSecureSessionMgr(&ctx.GetSecureSessionManager()); diff --git a/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp b/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp index 699a488788b212..1548d78e4bf37b 100644 --- a/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp +++ b/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp @@ -78,8 +78,8 @@ void MessageCounterSyncProcess(nlTestSuite * inSuite, void * inContext) CHIP_ERROR err = CHIP_NO_ERROR; - SessionHandle localSession = ctx.GetSessionLocalToPeer(); - SessionHandle peerSession = ctx.GetSessionPeerToLocal(); + SessionHandle localSession = ctx.GetSessionBobToAlice(); + SessionHandle peerSession = ctx.GetSessionAliceToBob(); Transport::PeerConnectionState * localState = ctx.GetSecureSessionManager().GetPeerConnectionState(localSession); Transport::PeerConnectionState * peerState = ctx.GetSecureSessionManager().GetPeerConnectionState(peerSession); @@ -99,7 +99,7 @@ void CheckReceiveMessage(nlTestSuite * inSuite, void * inContext) TestContext & ctx = *reinterpret_cast(inContext); CHIP_ERROR err = CHIP_NO_ERROR; - SessionHandle peerSession = ctx.GetSessionPeerToLocal(); + SessionHandle peerSession = ctx.GetSessionAliceToBob(); Transport::PeerConnectionState * peerState = ctx.GetSecureSessionManager().GetPeerConnectionState(peerSession); peerState->GetSessionMessageCounter().GetPeerMessageCounter().Reset(); @@ -110,7 +110,7 @@ void CheckReceiveMessage(nlTestSuite * inSuite, void * inContext) System::PacketBufferHandle msgBuf = MessagePacketBuffer::NewWithData(PAYLOAD, payload_len); NL_TEST_ASSERT(inSuite, !msgBuf.IsNull()); - Messaging::ExchangeContext * ec = ctx.NewExchangeToPeer(nullptr); + Messaging::ExchangeContext * ec = ctx.NewExchangeToAlice(nullptr); NL_TEST_ASSERT(inSuite, ec != nullptr); err = ec->SendMessage(chip::Protocols::Echo::MsgType::EchoRequest, std::move(msgBuf), diff --git a/src/protocols/secure_channel/tests/TestPASESession.cpp b/src/protocols/secure_channel/tests/TestPASESession.cpp index 330299c655e4dc..417b5bd3a212a3 100644 --- a/src/protocols/secure_channel/tests/TestPASESession.cpp +++ b/src/protocols/secure_channel/tests/TestPASESession.cpp @@ -123,7 +123,7 @@ void SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) gLoopback.Reset(); NL_TEST_ASSERT(inSuite, pairing.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - ExchangeContext * context = ctx.NewExchangeToLocal(&pairing); + ExchangeContext * context = ctx.NewExchangeToBob(&pairing); NL_TEST_ASSERT(inSuite, pairing.Pair(Transport::PeerAddress(Transport::Type::kBle), 1234, 0, nullptr, nullptr) != CHIP_NO_ERROR); @@ -140,7 +140,7 @@ void SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) PASESession pairing1; NL_TEST_ASSERT(inSuite, pairing1.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - ExchangeContext * context1 = ctx.NewExchangeToLocal(&pairing1); + ExchangeContext * context1 = ctx.NewExchangeToBob(&pairing1); NL_TEST_ASSERT(inSuite, pairing1.Pair(Transport::PeerAddress(Transport::Type::kBle), 1234, 0, context1, &delegate) == CHIP_ERROR_BAD_REQUEST); @@ -160,7 +160,7 @@ void SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inContext, P NL_TEST_ASSERT(inSuite, pairingCommissioner.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, pairingAccessory.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - ExchangeContext * contextCommissioner = ctx.NewExchangeToLocal(&pairingCommissioner); + ExchangeContext * contextCommissioner = ctx.NewExchangeToBob(&pairingCommissioner); if (gLoopback.mNumMessagesToDrop != 0) { @@ -234,7 +234,7 @@ void SecurePairingFailedHandshake(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, pairingAccessory.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); TestContext & ctx = *reinterpret_cast(inContext); - ExchangeContext * contextCommissioner = ctx.NewExchangeToLocal(&pairingCommissioner); + ExchangeContext * contextCommissioner = ctx.NewExchangeToBob(&pairingCommissioner); pairingCommissioner.MessageDispatch().SetPeerAddress(PeerAddress(Type::kUdp)); pairingAccessory.MessageDispatch().SetPeerAddress(PeerAddress(Type::kUdp)); @@ -376,10 +376,10 @@ int TestSecurePairing_Setup(void * inContext) auto & ctx = *static_cast(inContext); VerifyOrReturnError(ctx.Init(&sSuite, &gTransportMgr, &gIOContext) == CHIP_NO_ERROR, FAILURE); - ctx.SetSourceNodeId(kPlaceholderNodeId); - ctx.SetDestinationNodeId(kPlaceholderNodeId); - ctx.SetLocalKeyId(0); - ctx.SetPeerKeyId(0); + ctx.SetBobNodeId(kPlaceholderNodeId); + ctx.SetAliceNodeId(kPlaceholderNodeId); + ctx.SetBobKeyId(0); + ctx.SetAliceKeyId(0); ctx.SetFabricIndex(kUndefinedFabricIndex); gTransportMgr.SetSecureSessionMgr(&ctx.GetSecureSessionManager()); From e945d1659445642ab1df8f992958129d3cf5ba69 Mon Sep 17 00:00:00 2001 From: Wootak Jung Date: Mon, 13 Sep 2021 10:39:32 +0900 Subject: [PATCH 005/255] Add Tizen OS port (#8988) * Add Tizen OS chip platform The platform supports the following features: - Bluetooth - WiFi - Mdns - Key/Value store The integration with network is made with the Tizen API * Add Tizen OS target config/build files * Add example build files based on Tizen OS * Integrate Tizen OS into chip build system * Add workflow to build Tizen OS examples * Add VSCode task to build Tizen OS examples * Add tizen.py to build Tizen OS examples replace gn_tizen_example.sh to build_exmaples.py remove unused gn_tizen_example.sh * Apply restyle script * Apply comments * Change tizen.py * Add tizen toolchain * Rename tizen_home to tizen_sdk and apply comments * Modify lib/ files full path * Modify sysroot setting logic --- .github/workflows/examples-tizen.yaml | 44 +++++ .vscode/tasks.json | 3 +- build/config/BUILDCONFIG.gn | 3 + build/config/compiler/BUILD.gn | 4 +- build/toolchain/tizen/BUILD.gn | 22 +++ build/toolchain/tizen/tizen_toolchain.gni | 36 ++++ config/tizen/chip-gn/BUILD.gn | 36 ++++ config/tizen/chip-gn/args.gni | 27 +++ config/tizen/chip-gn/platform/BUILD.gn | 80 ++++++++ config/tizen/scripts/install_sdk.sh | 88 +++++++++ examples/build_overrides/tizen.gni | 18 ++ examples/lighting-app/linux/with_tizen.gni | 22 +++ scripts/build/build/factory.py | 6 + scripts/build/build/targets.py | 3 +- scripts/build/builders/tizen.py | 102 ++++++++++ .../build/expected_all_platform_commands.txt | 6 + scripts/build/test.py | 1 + src/platform/BUILD.gn | 15 +- src/platform/Tizen/BLEManagerImpl.cpp | 133 +++++++++++++ src/platform/Tizen/BLEManagerImpl.h | 140 ++++++++++++++ src/platform/Tizen/BUILD.gn | 67 +++++++ src/platform/Tizen/BlePlatformConfig.h | 31 +++ src/platform/Tizen/CHIPDevicePlatformConfig.h | 54 ++++++ src/platform/Tizen/CHIPDevicePlatformEvent.h | 63 +++++++ src/platform/Tizen/CHIPPlatformConfig.h | 107 +++++++++++ .../Tizen/ConfigurationManagerImpl.cpp | 72 +++++++ src/platform/Tizen/ConfigurationManagerImpl.h | 94 ++++++++++ .../Tizen/ConnectivityManagerImpl.cpp | 137 ++++++++++++++ src/platform/Tizen/ConnectivityManagerImpl.h | 176 ++++++++++++++++++ .../DeviceNetworkProvisioningDelegateImpl.cpp | 32 ++++ .../DeviceNetworkProvisioningDelegateImpl.h | 43 +++++ src/platform/Tizen/InetPlatformConfig.h | 39 ++++ .../Tizen/KeyValueStoreManagerImpl.cpp | 50 +++++ src/platform/Tizen/KeyValueStoreManagerImpl.h | 73 ++++++++ src/platform/Tizen/Logging.cpp | 58 ++++++ src/platform/Tizen/MdnsImpl.cpp | 65 +++++++ src/platform/Tizen/PlatformManagerImpl.cpp | 44 +++++ src/platform/Tizen/PlatformManagerImpl.h | 86 +++++++++ src/platform/Tizen/PosixConfig.cpp | 166 +++++++++++++++++ src/platform/Tizen/PosixConfig.h | 124 ++++++++++++ src/platform/Tizen/SystemPlatformConfig.h | 49 +++++ src/platform/Tizen/SystemTimeSupport.cpp | 69 +++++++ src/platform/device.gni | 13 +- 43 files changed, 2491 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/examples-tizen.yaml create mode 100644 build/toolchain/tizen/BUILD.gn create mode 100644 build/toolchain/tizen/tizen_toolchain.gni create mode 100644 config/tizen/chip-gn/BUILD.gn create mode 100644 config/tizen/chip-gn/args.gni create mode 100644 config/tizen/chip-gn/platform/BUILD.gn create mode 100755 config/tizen/scripts/install_sdk.sh create mode 100644 examples/build_overrides/tizen.gni create mode 100644 examples/lighting-app/linux/with_tizen.gni create mode 100644 scripts/build/builders/tizen.py create mode 100644 src/platform/Tizen/BLEManagerImpl.cpp create mode 100644 src/platform/Tizen/BLEManagerImpl.h create mode 100644 src/platform/Tizen/BUILD.gn create mode 100644 src/platform/Tizen/BlePlatformConfig.h create mode 100644 src/platform/Tizen/CHIPDevicePlatformConfig.h create mode 100644 src/platform/Tizen/CHIPDevicePlatformEvent.h create mode 100644 src/platform/Tizen/CHIPPlatformConfig.h create mode 100644 src/platform/Tizen/ConfigurationManagerImpl.cpp create mode 100644 src/platform/Tizen/ConfigurationManagerImpl.h create mode 100644 src/platform/Tizen/ConnectivityManagerImpl.cpp create mode 100644 src/platform/Tizen/ConnectivityManagerImpl.h create mode 100644 src/platform/Tizen/DeviceNetworkProvisioningDelegateImpl.cpp create mode 100644 src/platform/Tizen/DeviceNetworkProvisioningDelegateImpl.h create mode 100644 src/platform/Tizen/InetPlatformConfig.h create mode 100644 src/platform/Tizen/KeyValueStoreManagerImpl.cpp create mode 100644 src/platform/Tizen/KeyValueStoreManagerImpl.h create mode 100644 src/platform/Tizen/Logging.cpp create mode 100644 src/platform/Tizen/MdnsImpl.cpp create mode 100644 src/platform/Tizen/PlatformManagerImpl.cpp create mode 100644 src/platform/Tizen/PlatformManagerImpl.h create mode 100644 src/platform/Tizen/PosixConfig.cpp create mode 100644 src/platform/Tizen/PosixConfig.h create mode 100644 src/platform/Tizen/SystemPlatformConfig.h create mode 100644 src/platform/Tizen/SystemTimeSupport.cpp diff --git a/.github/workflows/examples-tizen.yaml b/.github/workflows/examples-tizen.yaml new file mode 100644 index 00000000000000..879baa17101d22 --- /dev/null +++ b/.github/workflows/examples-tizen.yaml @@ -0,0 +1,44 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Build example - Tizen + +on: + push: + pull_request: + +jobs: + tizen: + name: Tizen + env: + BUILD_TYPE: tizen + + runs-on: ubuntu-latest + if: github.actor != 'restyled-io[bot]' + + container: + image: connectedhomeip/chip-build-tizen:latest + options: --user root + volumes: + - "/tmp/bloat_reports:/tmp/bloat_reports" + - "/tmp/output_binaries:/tmp/output_binaries" + + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + submodules: true + - name: Build example Tizen lighting app + run: + scripts/run_in_build_env.sh "./scripts/build/build_examples.py --platform tizen build" diff --git a/.vscode/tasks.json b/.vscode/tasks.json index e016cb92af88c6..198ae68b91685b 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -278,7 +278,8 @@ "nrf", "qpg", "infineon", - "telink" + "telink", + "tizen" ], "default": "build" }, diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 298bf1846f27f5..2592b62be53a49 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn @@ -96,6 +96,9 @@ if (_chip_defaults.custom_toolchain != "") { } else if (target_os == "ios") { _default_toolchain = "${_build_overrides.build_root}/toolchain/ios:ios_${target_cpu}" +} else if (target_os == "tizen") { + _default_toolchain = + "${_build_overrides.build_root}/toolchain/tizen:tizen_${target_cpu}" } else { assert(false, "No toolchain specified, please specify custom_toolchain") } diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 02794d900e991a..9101fbb69746ae 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn @@ -191,7 +191,7 @@ config("warnings_common") { } if (current_os != "mac" && current_os != "ios" && current_os != "linux" && - current_os != "win") { + current_os != "win" && current_os != "tizen") { cflags += [ "-Wstack-usage=8192" ] } } @@ -268,7 +268,7 @@ config("runtime_default") { "$dir_pw_toolchain/host_clang:xcode_sysroot", ] } - if (current_os == "linux") { + if (current_os == "linux" || current_os == "tizen") { libs = [ "dl", "pthread", diff --git a/build/toolchain/tizen/BUILD.gn b/build/toolchain/tizen/BUILD.gn new file mode 100644 index 00000000000000..c8c80098f98d5d --- /dev/null +++ b/build/toolchain/tizen/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("tizen_toolchain.gni") + +tizen_toolchain("tizen_arm") { + toolchain_args = { + current_cpu = "arm" + arm_arch = "armv7-a" + } +} diff --git a/build/toolchain/tizen/tizen_toolchain.gni b/build/toolchain/tizen/tizen_toolchain.gni new file mode 100644 index 00000000000000..9f88753925a4dc --- /dev/null +++ b/build/toolchain/tizen/tizen_toolchain.gni @@ -0,0 +1,36 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") + +import("${build_root}/config/sysroot.gni") +import("${build_root}/toolchain/gcc_toolchain.gni") + +template("tizen_toolchain") { + _invoker_toolchain_args = invoker.toolchain_args + + _tizen_toolchain_args = { + current_os = "tizen" + is_clang = true + + forward_variables_from(_invoker_toolchain_args, "*") + } + + gcc_toolchain(target_name) { + toolchain_args = _tizen_toolchain_args + ar = "$sysroot/bin/arm-linux-gnueabi-ar" + cc = "$sysroot/bin/arm-linux-gnueabi-gcc" + cxx = "$sysroot/bin/arm-linux-gnueabi-g++" + } +} diff --git a/config/tizen/chip-gn/BUILD.gn b/config/tizen/chip-gn/BUILD.gn new file mode 100644 index 00000000000000..d3b3cbf05345c6 --- /dev/null +++ b/config/tizen/chip-gn/BUILD.gn @@ -0,0 +1,36 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +import("${build_root}/chip/tests.gni") + +assert(current_os == "tizen") + +declare_args() { + chip_build_pw_rpc_lib = false +} + +group("tizen") { + deps = [ "${chip_root}/src/lib" ] + + if (chip_build_tests) { + deps += [ "${chip_root}/src:tests" ] + } +} + +group("default") { + deps = [ ":tizen" ] +} diff --git a/config/tizen/chip-gn/args.gni b/config/tizen/chip-gn/args.gni new file mode 100644 index 00000000000000..b344bf8ff37db7 --- /dev/null +++ b/config/tizen/chip-gn/args.gni @@ -0,0 +1,27 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") + +declare_args() { + # Location of the Tizen SDK. + tizen_sdk_root = "" +} + +chip_device_platform = "tizen" + +chip_build_tests = false + +chip_inet_config_enable_raw_endpoint = false +chip_inet_config_enable_dns_resolver = false diff --git a/config/tizen/chip-gn/platform/BUILD.gn b/config/tizen/chip-gn/platform/BUILD.gn new file mode 100644 index 00000000000000..9a4b9f3c803173 --- /dev/null +++ b/config/tizen/chip-gn/platform/BUILD.gn @@ -0,0 +1,80 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/tizen.gni") +import("${chip_root}/config/tizen/chip-gn/args.gni") + +import("${build_root}/config/linux/pkg_config.gni") +import("${chip_root}/src/platform/device.gni") + +pkg_config("dlog") { + packages = [ "dlog" ] +} + +pkg_config("capi-appfw-preference") { + packages = [ "capi-appfw-preference" ] +} + +pkg_config("glib") { + packages = [ + "glib-2.0", + "gio-unix-2.0", + ] +} + +if (chip_mdns == "platform") { + pkg_config("nsd-dns-sd") { + packages = [ "nsd-dns-sd" ] + } +} + +if (chip_enable_wifi) { + pkg_config("capi-network-wifi-manager") { + packages = [ "capi-network-wifi-manager" ] + } + pkg_config("capi-network-softap") { + packages = [ "capi-network-softap" ] + } +} + +if (chip_enable_ble) { + pkg_config("capi-network-bluetooth") { + packages = [ "capi-network-bluetooth" ] + } +} + +source_set("tizen") { + public_configs = [ + ":dlog", + ":glib", + ":capi-appfw-preference", + ] + + if (chip_mdns == "platform") { + public_configs += [ ":nsd-dns-sd" ] + } + + if (chip_enable_wifi) { + public_configs += [ + ":capi-network-wifi-manager", + ":capi-network-softap", + ] + } + + if (chip_enable_ble) { + public_configs += [ ":capi-network-bluetooth" ] + } +} diff --git a/config/tizen/scripts/install_sdk.sh b/config/tizen/scripts/install_sdk.sh new file mode 100755 index 00000000000000..7d9facad97a239 --- /dev/null +++ b/config/tizen/scripts/install_sdk.sh @@ -0,0 +1,88 @@ +#!/bin/bash + +ROOTSTRAP_PATH="$1" +CHIPROOT=$(git rev-parse --show-toplevel) + +NSD_DNS_LIBS="libnsd-dns-sd.so*" + +echo "$ROOTSTRAP_PATH" + +if [ -z "$ROOTSTRAP_PATH" ]; then + echo "ROOTSTRAP_PATH should be input" + exit 1 +fi + +if [[ ! -d $ROOTSTRAP_PATH ]]; then + echo "Can't find the rootstrap dir, please make dir and run this script again" + exit 1 +fi + +cd "$ROOTSTRAP_PATH" + +# Get Tizen rootstrap +if [[ ! -f mobile-6.0-rs-device.core_0.0.123_ubuntu-64.zip ]]; then + echo "Getting tizen rootstrap..." + wget http://download.tizen.org/sdk/tizenstudio/official/binary/mobile-6.0-rs-device.core_0.0.123_ubuntu-64.zip +fi +unzip mobile-6.0-rs-device.core_0.0.123_ubuntu-64.zip +mv data/platforms/tizen-6.0/mobile/rootstraps/mobile-6.0-device.core/usr . +mv data/platforms/tizen-6.0/mobile/rootstraps/mobile-6.0-device.core/lib . + +# Clean files +rm -rf data +rm -rf mobile-6.0-rs-device.* +rm pkginfo.manifest + +# Copy internal dns-sd header into rootstrap +# After finishing ACR for internal APIs, we will remove this. + +rm "$ROOTSTRAP_PATH/usr/lib/$NSD_DNS_LIBS" + +# Get tizen packages +function download_pkg() { + if [ "$2" = "snapshots" ]; then + wget -r -nd --no-parent -A "$1" "http://download.tizen.org/snapshots/tizen/unified/latest/repos/standard/packages/armv7l/" + else + wget -r -nd --no-parent -A "$1" "http://download.tizen.org/releases/milestone/tizen/${2:-base}/latest/repos/standard/packages/armv7l/" + fi +} + +# Base package +for pkg in 'pcre-devel-*.armv7l.rpm' 'libffi-devel-*.armv7l.rpm' 'libmount-devel-*.armv7l.rpm' \ + 'libblkid-devel-*.armv7l.rpm' 'libcap-*.armv7l.rpm' 'liblzma-*.armv7l.rpm'; do + download_pkg "$pkg" +done + +# Unified package +for pkg in 'vconf-compat-*.armv7l.rpm' 'libcynara-commons-*.armv7l.rpm' 'cynara-devel-*.armv7l.rpm' \ + 'libcynara-client-*.armv7l.rpm' 'dbus-1*.armv7l.rpm' 'dbus-devel-*.armv7l.rpm' \ + 'dbus-libs-1*.armv7l.rpm' 'glib2-devel-2*.armv7l.rpm' 'libdns_sd-*.armv7l.rpm' \ + 'buxton2-*.armv7l.rpm' 'libsystemd-*.armv7l.rpm'; do + download_pkg "$pkg" unified +done + +# Latest snapshots package (For nsd) +for pkg in 'capi-network-nsd-0*.armv7l.rpm' 'capi-network-nsd-devel*.armv7l.rpm' 'libnsd-dns-sd*.armv7l.rpm' 'libdns_sd-*.armv7l.rpm'; do + download_pkg "$pkg" snapshots +done + +unrpm *.rpm + +cp usr/lib/pkgconfig/openssl1.1.pc usr/lib/pkgconfig/openssl.pc + +rm usr/lib/libdns_sd.so +cp usr/lib/libdns_sd.so.878.* usr/lib/libdns_sd.so + +rm *.rpm + +# Get toolchain +wget http://download.tizen.org/sdk/tizenstudio/official/binary/cross-arm-gcc-9.2_0.1.9_ubuntu-64.zip +unzip cross-arm-gcc-9.2_0.1.9_ubuntu-64.zip + +cp -rf data/tools/arm-linux-gnueabi-gcc-9.2/* . + +rm pkginfo.manifest +rm changelog +rm -rf data + +rm cross-arm-gcc-9.2_0.1.9_ubuntu-64.zip diff --git a/examples/build_overrides/tizen.gni b/examples/build_overrides/tizen.gni new file mode 100644 index 00000000000000..29a2771956f249 --- /dev/null +++ b/examples/build_overrides/tizen.gni @@ -0,0 +1,18 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +declare_args() { + # Root directory for tizen. + tizen_root = "//third_party/connectedhomeip/config/tizen/chip-gn/platform" +} diff --git a/examples/lighting-app/linux/with_tizen.gni b/examples/lighting-app/linux/with_tizen.gni new file mode 100644 index 00000000000000..4df278857387ff --- /dev/null +++ b/examples/lighting-app/linux/with_tizen.gni @@ -0,0 +1,22 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# add this gni as import in your build args to use tizen in the example +# 'import("//with_tizen.gni")' + +import("//build_overrides/chip.gni") + +import("${chip_root}/config/tizen/chip-gn/args.gni") + +current_os = "tizen" diff --git a/scripts/build/build/factory.py b/scripts/build/build/factory.py index 5994e154481256..9e7f65da5d56b1 100644 --- a/scripts/build/build/factory.py +++ b/scripts/build/build/factory.py @@ -22,6 +22,7 @@ from builders.qpg import QpgBuilder from builders.infineon import InfineonBuilder, InfineonApp, InfineonBoard from builders.telink import TelinkApp, TelinkBoard, TelinkBuilder +from builders.tizen import TizenApp, TizenBoard, TizenBuilder from .targets import Application, Board, Platform @@ -87,6 +88,7 @@ def Create(self, runner, __board_key: Board, __app_key: Application, Platform.ANDROID: Matcher(AndroidBuilder), Platform.INFINEON: Matcher(InfineonBuilder), Platform.TELINK: Matcher(TelinkBuilder), + Platform.TIZEN: Matcher(TizenBuilder), } # Matrix of what can be compiled and what build options are required @@ -150,6 +152,10 @@ def Create(self, runner, __board_key: Board, __app_key: Application, _MATCHERS[Platform.INFINEON].AcceptBoard( Board.P6BOARD, board=InfineonBoard.P6BOARD) +_MATCHERS[Platform.TIZEN].AcceptBoard(Board.ARM, board=TizenBoard.ARM) +_MATCHERS[Platform.TIZEN].AcceptApplication( + Application.LIGHT, app=TizenApp.LIGHT) + class BuilderFactory: """Creates application builders.""" diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index b387b9b40ba5e4..272f4efb477268 100644 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -25,6 +25,7 @@ class Platform(IntEnum): ANDROID = auto() INFINEON = auto() TELINK = auto() + TIZEN = auto() @property def ArgName(self): @@ -61,7 +62,7 @@ class Board(IntEnum): # Telink platform TLSR9518ADK80D = auto() - # Android platform + # Android, Tizen platform ARM = auto() ARM64 = auto() X64 = auto() diff --git a/scripts/build/builders/tizen.py b/scripts/build/builders/tizen.py new file mode 100644 index 00000000000000..b8289f4bd5b6fe --- /dev/null +++ b/scripts/build/builders/tizen.py @@ -0,0 +1,102 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +import os + +from enum import Enum, auto + +from .builder import Builder + + +class TizenApp(Enum): + LIGHT = auto() + + def ExampleName(self): + if self == TizenApp.LIGHT: + return 'lighting-app' + else: + raise Exception('Unknown app type: %r' % self) + + def AppNamePrefix(self): + if self == TizenApp.LIGHT: + return 'chip-tizen-lighting-example' + else: + raise Exception('Unknown app type: %r' % self) + + +class TizenBoard(Enum): + ARM = auto() + + def TargetCpuName(self): + if self == TizenBoard.ARM: + return 'arm' + else: + raise Exception('Unknown board type: %r' % self) + + +class TizenBuilder(Builder): + + def __init__(self, + root, + runner, + output_prefix: str, + app: TizenApp = TizenApp.LIGHT, + board: TizenBoard = TizenBoard.ARM): + super(TizenBuilder, self).__init__( + root=os.path.join(root, 'examples', app.ExampleName(), 'linux'), + runner=runner, + output_prefix=output_prefix) + self.app = app + self.board = board + + def generate(self): + if not os.path.exists(self.output_dir): + if not self._runner.dry_run: + if 'TIZEN_HOME' not in os.environ: + raise Exception( + "Environment TIZEN_HOME missing, cannot build tizen libraries") + + cmd = '''\ +gn gen --check --fail-on-unused-args --root=%s '--args=''' % self.root + + gn_args = {} + gn_args['target_os'] = 'tizen' + gn_args['target_cpu'] = self.board.TargetCpuName() + gn_args['sysroot'] = os.environ['TIZEN_HOME'] + + cmd += ' %s\' %s' % (' '.join([ + '%s="%s"' % (key, value) + for key, value in gn_args.items()]), self.output_dir) + + self._Execute(['bash', '-c', cmd], + title='Generating ' + self.identifier) + + def _build(self): + logging.info('Compiling Tizen at %s', self.output_dir) + + self._Execute(['ninja', '-C', self.output_dir], + title='Building ' + self.identifier) + + def build_outputs(self): + items = { + '%s.out' % self.app.AppNamePrefix(): + os.path.join(self.output_dir, '%s.out' % + self.app.AppNamePrefix()), + '%s.out.map' % self.app.AppNamePrefix(): + os.path.join(self.output_dir, + '%s.out.map' % self.app.AppNamePrefix()), + } + + return items diff --git a/scripts/build/expected_all_platform_commands.txt b/scripts/build/expected_all_platform_commands.txt index ea46522dd91431..3b3f5f78c71abf 100644 --- a/scripts/build/expected_all_platform_commands.txt +++ b/scripts/build/expected_all_platform_commands.txt @@ -132,6 +132,9 @@ export ZEPHYR_SDK_INSTALL_DIR="$ZEPHYR_BASE/../../zephyr-sdk-0.13.0" source "$ZEPHYR_BASE/zephyr-env.sh"; west build --cmake-only -d {out}/telink-tlsr9518adk80d-light -b tlsr9518adk80d {root}/examples/lighting-app/telink' +# Generating tizen-arm-light +bash -c 'gn gen --check --fail-on-unused-args --root={root}/examples/lighting-app/linux '"'"'--args= target_os="tizen" target_cpu="arm" sysroot="TEST_TIZEN_HOME"'"'"' {out}/tizen-arm-light' + # Building {real_platform}-native-all_clusters ninja -C {out}/{real_platform}-native-all_clusters @@ -255,4 +258,7 @@ ninja -C {out}/infineon-p6board-lock # Building telink-tlsr9518adk80d-light ninja -C {out}/telink-tlsr9518adk80d-light +# Building tizen-arm-light +ninja -C {out}/tizen-arm-light + diff --git a/scripts/build/test.py b/scripts/build/test.py index 2266e8fac5a4f5..b6f7a6d94a7ea6 100644 --- a/scripts/build/test.py +++ b/scripts/build/test.py @@ -46,6 +46,7 @@ def build_actual_output(root: str, out: str) -> List[str]: 'PW_PROJECT_ROOT': root, 'ANDROID_NDK_HOME': 'TEST_ANDROID_NDK_HOME', 'ANDROID_HOME': 'TEST_ANDROID_HOME', + 'TIZEN_HOME': 'TEST_TIZEN_HOME', }) retval = subprocess.run([ diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index 922d501fe6212b..9e1de6c6cd129e 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -61,7 +61,7 @@ if (chip_device_platform != "none") { } if (chip_stack_lock_tracking == "auto") { - if (chip_device_platform == "linux") { + if (chip_device_platform == "linux" || chip_device_platform == "tizen") { # TODO: should be fatal for development. Change once bugs are fixed chip_stack_lock_tracking = "log" } else { @@ -102,7 +102,8 @@ if (chip_device_platform != "none") { "CHIP_ENABLE_ROTATING_DEVICE_ID=${chip_enable_rotating_device_id}", ] - if (chip_device_platform == "linux" || chip_device_platform == "darwin") { + if (chip_device_platform == "linux" || chip_device_platform == "darwin" || + chip_device_platform == "tizen") { defines += [ "CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE=${chip_enable_ble}" ] } @@ -154,6 +155,14 @@ if (chip_device_platform != "none") { "CHIP_DEVICE_LAYER_TARGET_LINUX=1", "CHIP_DEVICE_LAYER_TARGET=Linux", ] + } else if (chip_device_platform == "tizen") { + defines += [ + "CHIP_DEVICE_LAYER_TARGET_TIZEN=1", + "CHIP_DEVICE_LAYER_TARGET=Tizen", + "CHIP_DEVICE_CONFIG_ENABLE_WIFI=${chip_enable_wifi}", + ] + defines -= + [ "CHIP_DEVICE_CONFIG_ENABLE_WPA=${chip_device_config_enable_wpa}" ] } else if (chip_device_platform == "nrfconnect") { defines += [ "CHIP_DEVICE_LAYER_TARGET_NRFCONNECT=1", @@ -295,6 +304,8 @@ if (chip_device_platform != "none") { _platform_target = "telink" } else if (chip_device_platform == "mbed") { _platform_target = "mbed" + } else if (chip_device_platform == "tizen") { + _platform_target = "Tizen" } else if (chip_device_platform == "external") { _platform_target = chip_platform_target } else if (chip_device_platform == "p6") { diff --git a/src/platform/Tizen/BLEManagerImpl.cpp b/src/platform/Tizen/BLEManagerImpl.cpp new file mode 100644 index 00000000000000..86c22200b6ada9 --- /dev/null +++ b/src/platform/Tizen/BLEManagerImpl.cpp @@ -0,0 +1,133 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * Copyright (c) 2018 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the BLEManager singleton object + * for Tizen platforms. + */ +#include + +#include +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +using namespace ::chip; +using namespace ::chip::Ble; + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +BLEManagerImpl BLEManagerImpl::sInstance; + +CHIP_ERROR BLEManagerImpl::_Init(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + return err; +} + +CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR BLEManagerImpl::_SetDeviceName(const char * deviceName) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +uint16_t BLEManagerImpl::_NumConnections(void) +{ + return 0; +} + +CHIP_ERROR BLEManagerImpl::ConfigureBle(uint32_t aAdapterId, bool aIsCentral) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) {} + +uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const +{ + return false; +} + +bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + return false; +} + +bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + return false; +} + +bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId) +{ + return false; +} + +bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, + chip::System::PacketBufferHandle pBuf) +{ + return false; +} + +bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, + chip::System::PacketBufferHandle pBuf) +{ + return false; +} + +bool BLEManagerImpl::SendReadRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, + chip::System::PacketBufferHandle pBuf) +{ + return false; +} + +bool BLEManagerImpl::SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, + const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId) +{ + return false; +} + +void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) {} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/Tizen/BLEManagerImpl.h b/src/platform/Tizen/BLEManagerImpl.h new file mode 100644 index 00000000000000..8db46b595c0288 --- /dev/null +++ b/src/platform/Tizen/BLEManagerImpl.h @@ -0,0 +1,140 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the BLEManager singleton object + * for the Tizen platforms. + */ + +#pragma once + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +using namespace chip::Ble; + +/** + * Concrete implementation of the BLEManagerImpl singleton object for the Tizen platforms. + */ +class BLEManagerImpl final : public BLEManager, + private Ble::BleLayer, + private Ble::BlePlatformDelegate, + private Ble::BleApplicationDelegate +{ + // Allow the BLEManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend BLEManager; + +public: + CHIP_ERROR ConfigureBle(uint32_t aAdapterId, bool aIsCentral); + +private: + // ===== Members that implement the BLEManager internal interface. + + CHIP_ERROR _Init(void); + CHIPoBLEServiceMode _GetCHIPoBLEServiceMode(void); + CHIP_ERROR _SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val); + bool _IsAdvertisingEnabled(void); + CHIP_ERROR _SetAdvertisingEnabled(bool val); + bool _IsAdvertising(void); + CHIP_ERROR _SetAdvertisingMode(BLEAdvertisingMode mode); + CHIP_ERROR _GetDeviceName(char * buf, size_t bufSize); + CHIP_ERROR _SetDeviceName(const char * deviceName); + uint16_t _NumConnections(void); + void _OnPlatformEvent(const ChipDeviceEvent * event); + BleLayer * _GetBleLayer(void); + + // ===== Members that implement virtual methods on BlePlatformDelegate. + + bool SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, + const Ble::ChipBleUUID * charId) override; + bool UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, + const Ble::ChipBleUUID * charId) override; + bool CloseConnection(BLE_CONNECTION_OBJECT conId) override; + uint16_t GetMTU(BLE_CONNECTION_OBJECT conId) const override; + bool SendIndication(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, + System::PacketBufferHandle pBuf) override; + bool SendWriteRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, + System::PacketBufferHandle pBuf) override; + bool SendReadRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, + System::PacketBufferHandle pBuf) override; + bool SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, const Ble::ChipBleUUID * svcId, + const Ble::ChipBleUUID * charId) override; + + // ===== Members that implement virtual methods on BleApplicationDelegate. + + void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) override; + + // ===== Members for internal use by the following friends. + + friend BLEManager & BLEMgr(void); + friend BLEManagerImpl & BLEMgrImpl(void); + + static BLEManagerImpl sInstance; +}; + +/** + * Returns a reference to the public interface of the BLEManager singleton object. + * + * Internal components should use this to access features of the BLEManager object + * that are common to all platforms. + */ +inline BLEManager & BLEMgr(void) +{ + return BLEManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the BLEManager singleton object. + * + * Internal components can use this to gain access to features of the BLEManager + * that are specific to the Tizen platforms. + */ +inline BLEManagerImpl & BLEMgrImpl(void) +{ + return BLEManagerImpl::sInstance; +} + +inline Ble::BleLayer * BLEManagerImpl::_GetBleLayer() +{ + return this; +} + +inline BLEManager::CHIPoBLEServiceMode BLEManagerImpl::_GetCHIPoBLEServiceMode() +{ + return ConnectivityManager::kCHIPoBLEServiceMode_NotSupported; +} + +inline bool BLEManagerImpl::_IsAdvertisingEnabled() +{ + return false; +} + +inline bool BLEManagerImpl::_IsAdvertising() +{ + return false; +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/Tizen/BUILD.gn b/src/platform/Tizen/BUILD.gn new file mode 100644 index 00000000000000..29488bfc390787 --- /dev/null +++ b/src/platform/Tizen/BUILD.gn @@ -0,0 +1,67 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/tizen.gni") + +import("${build_root}/config/linux/pkg_config.gni") + +import("${chip_root}/src/platform/device.gni") + +assert(chip_device_platform == "tizen") + +static_library("Tizen") { + sources = [ + "../DeviceSafeQueue.cpp", + "../DeviceSafeQueue.h", + "BLEManagerImpl.cpp", + "BLEManagerImpl.h", + "BlePlatformConfig.h", + "CHIPDevicePlatformConfig.h", + "CHIPDevicePlatformEvent.h", + "CHIPPlatformConfig.h", + "ConfigurationManagerImpl.cpp", + "ConfigurationManagerImpl.h", + "ConnectivityManagerImpl.cpp", + "ConnectivityManagerImpl.h", + "DeviceNetworkProvisioningDelegateImpl.cpp", + "DeviceNetworkProvisioningDelegateImpl.h", + "InetPlatformConfig.h", + "KeyValueStoreManagerImpl.cpp", + "KeyValueStoreManagerImpl.h", + "Logging.cpp", + "PlatformManagerImpl.cpp", + "PlatformManagerImpl.h", + "PosixConfig.cpp", + "PosixConfig.h", + "SystemPlatformConfig.h", + "SystemTimeSupport.cpp", + ] + + deps = [ "${chip_root}/src/setup_payload" ] + + public_deps = [ + "${chip_root}/src/platform:platform_base", + "${tizen_root}:tizen", + ] + + public_configs = [] + + if (chip_mdns == "platform") { + sources += [ "MdnsImpl.cpp" ] + + deps += [ "${chip_root}/src/lib/mdns:platform_header" ] + } +} diff --git a/src/platform/Tizen/BlePlatformConfig.h b/src/platform/Tizen/BlePlatformConfig.h new file mode 100644 index 00000000000000..7877788afc5460 --- /dev/null +++ b/src/platform/Tizen/BlePlatformConfig.h @@ -0,0 +1,31 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP BLE + * Layer on Tizen platforms. + * + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +// ========== Platform-specific Configuration Overrides ========= + +/* none so far */ diff --git a/src/platform/Tizen/CHIPDevicePlatformConfig.h b/src/platform/Tizen/CHIPDevicePlatformConfig.h new file mode 100644 index 00000000000000..dac49181253831 --- /dev/null +++ b/src/platform/Tizen/CHIPDevicePlatformConfig.h @@ -0,0 +1,54 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the chip Device Layer + * on Tizen platforms. + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION 0 +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP 0 + +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD 0 + +#ifndef CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 +#endif + +#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0 + +#define CHIP_DEVICE_CONFIG_PERSISTED_STORAGE_CRIT_EIDC_KEY 2 +#define CHIP_DEVICE_CONFIG_PERSISTED_STORAGE_PROD_EIDC_KEY 3 +#define CHIP_DEVICE_CONFIG_PERSISTED_STORAGE_INFO_EIDC_KEY 4 +#define CHIP_DEVICE_CONFIG_PERSISTED_STORAGE_DEBUG_EIDC_KEY 5 + +// ========== Platform-specific Configuration ========= + +// These are configuration options that are unique to Tizen platforms. +// These can be overridden by the application as needed. + +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_TELEMETRY 0 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_TELEMETRY 0 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_TELEMETRY_FULL 0 + +#define CHIP_DEVICE_CONFIG_LOG_PROVISIONING_HASH 0 diff --git a/src/platform/Tizen/CHIPDevicePlatformEvent.h b/src/platform/Tizen/CHIPDevicePlatformEvent.h new file mode 100644 index 00000000000000..26deed4ca3a96c --- /dev/null +++ b/src/platform/Tizen/CHIPDevicePlatformEvent.h @@ -0,0 +1,63 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Defines platform-specific event types and data for the chip + * Device Layer on Tizen platforms. + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { + +namespace DeviceEventType { + +/** + * Enumerates Tizen platform-specific event types that are visible to the application. + */ +enum PublicPlatformSpecificEventTypes +{ + /* None currently defined */ +}; + +/** + * Enumerates Tizen platform-specific event types that are internal to the chip Device Layer. + */ +enum InternalPlatformSpecificEventTypes +{ + /* None currently defined */ +}; + +} // namespace DeviceEventType + +/** + * Represents platform-specific event information for Tizen platforms. + */ +struct ChipDevicePlatformEvent +{ + union + { + /* None currently defined */ + }; +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Tizen/CHIPPlatformConfig.h b/src/platform/Tizen/CHIPPlatformConfig.h new file mode 100644 index 00000000000000..7067e0876fcded --- /dev/null +++ b/src/platform/Tizen/CHIPPlatformConfig.h @@ -0,0 +1,107 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for CHIP on + * Tizen platforms. + */ + +#pragma once + +// ==================== General Platform Adaptations ==================== + +#define ChipDie() abort() + +#define CHIP_CONFIG_ENABLE_FABRIC_STATE 0 + +#define CHIP_CONFIG_TIME_ENABLE_CLIENT 1 +#define CHIP_CONFIG_TIME_ENABLE_SERVER 0 + +// ==================== Security Adaptations ==================== + +#define CHIP_CONFIG_USE_OPENSSL_ECC 0 +#define CHIP_CONFIG_USE_MICRO_ECC 0 + +#define CHIP_CONFIG_HASH_IMPLEMENTATION_OPENSSL 0 +#define CHIP_CONFIG_HASH_IMPLEMENTATION_MINCRYPT 1 +#define CHIP_CONFIG_HASH_IMPLEMENTATION_MBEDTLS 0 +#define CHIP_CONFIG_HASH_IMPLEMENTATION_PLATFORM 0 + +#define CHIP_CONFIG_AES_IMPLEMENTATION_OPENSSL 0 +#define CHIP_CONFIG_AES_IMPLEMENTATION_AESNI 0 +#define CHIP_CONFIG_AES_IMPLEMENTATION_MBEDTLS 1 +#define CHIP_CONFIG_AES_IMPLEMENTATION_PLATFORM 0 + +#define CHIP_CONFIG_RNG_IMPLEMENTATION_OPENSSL 0 +#define CHIP_CONFIG_RNG_IMPLEMENTATION_CHIPDRBG 1 +#define CHIP_CONFIG_RNG_IMPLEMENTATION_PLATFORM 0 + +#define CHIP_CONFIG_ENABLE_PASE_INITIATOR 0 +#define CHIP_CONFIG_ENABLE_PASE_RESPONDER 1 +#define CHIP_CONFIG_ENABLE_CASE_INITIATOR 1 + +#define CHIP_CONFIG_SUPPORT_PASE_CONFIG0 0 +#define CHIP_CONFIG_SUPPORT_PASE_CONFIG1 0 +#define CHIP_CONFIG_SUPPORT_PASE_CONFIG2 0 +#define CHIP_CONFIG_SUPPORT_PASE_CONFIG3 0 +#define CHIP_CONFIG_SUPPORT_PASE_CONFIG4 1 + +#define CHIP_CONFIG_ENABLE_KEY_EXPORT_INITIATOR 0 + +#define CHIP_CONFIG_ENABLE_PROVISIONING_BUNDLE_SUPPORT 0 + +// ==================== General Configuration Overrides ==================== + +#ifndef CHIP_CONFIG_MAX_PEER_NODES +#define CHIP_CONFIG_MAX_PEER_NODES 16 +#endif // CHIP_CONFIG_MAX_PEER_NODES + +#ifndef CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS +#define CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS 16 +#endif // CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS + +#ifndef CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS +#define CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS 8 +#endif // CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS + +#ifndef CHIP_CONFIG_RMP_TIMER_DEFAULT_PERIOD_SHIFT +#define CHIP_CONFIG_RMP_TIMER_DEFAULT_PERIOD_SHIFT 6 +#endif // CHIP_CONFIG_RMP_TIMER_DEFAULT_PERIOD_SHIFT + +#ifndef CHIP_LOG_FILTERING +#define CHIP_LOG_FILTERING 0 +#endif // CHIP_LOG_FILTERING + +#ifndef CHIP_CONFIG_BDX_MAX_NUM_TRANSFERS +#define CHIP_CONFIG_BDX_MAX_NUM_TRANSFERS 1 +#endif // CHIP_CONFIG_BDX_MAX_NUM_TRANSFERS + +// ==================== Security Configuration Overrides ==================== + +#ifndef CHIP_CONFIG_MAX_APPLICATION_GROUPS +#define CHIP_CONFIG_MAX_APPLICATION_GROUPS 4 +#endif // CHIP_CONFIG_MAX_APPLICATION_GROUPS + +#ifndef CHIP_CONFIG_DEBUG_CERT_VALIDATION +#define CHIP_CONFIG_DEBUG_CERT_VALIDATION 0 +#endif // CHIP_CONFIG_DEBUG_CERT_VALIDATION + +#ifndef CHIP_CONFIG_ENABLE_CASE_RESPONDER +#define CHIP_CONFIG_ENABLE_CASE_RESPONDER 1 +#endif // CHIP_CONFIG_ENABLE_CASE_RESPONDER diff --git a/src/platform/Tizen/ConfigurationManagerImpl.cpp b/src/platform/Tizen/ConfigurationManagerImpl.cpp new file mode 100644 index 00000000000000..7f41bb79b41d45 --- /dev/null +++ b/src/platform/Tizen/ConfigurationManagerImpl.cpp @@ -0,0 +1,72 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2018 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides the implementation of the Device Layer ConfigurationManager object + * for Tizen platforms. + */ + +#include + +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { + +using namespace ::chip::DeviceLayer::Internal; + +/** Singleton instance of the ConfigurationManager implementation object. + */ +ConfigurationManagerImpl ConfigurationManagerImpl::sInstance; + +CHIP_ERROR ConfigurationManagerImpl::_Init(void) +{ + return Internal::GenericConfigurationManagerImpl::_Init(); +} + +CHIP_ERROR ConfigurationManagerImpl::_GetPrimaryWiFiMACAddress(uint8_t * buf) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +bool ConfigurationManagerImpl::_CanFactoryReset(void) +{ + return true; +} + +void ConfigurationManagerImpl::_InitiateFactoryReset(void) {} + +CHIP_ERROR ConfigurationManagerImpl::_ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR ConfigurationManagerImpl::_WritePersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t value) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Tizen/ConfigurationManagerImpl.h b/src/platform/Tizen/ConfigurationManagerImpl.h new file mode 100644 index 00000000000000..8fdbf871bca607 --- /dev/null +++ b/src/platform/Tizen/ConfigurationManagerImpl.h @@ -0,0 +1,94 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the ConfigurationManager object + * for Tizen platforms. + */ + +#pragma once + +#include + +#include + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the ConfigurationManager singleton object for the Tizen platform. + */ +class ConfigurationManagerImpl final : public ConfigurationManager, + public Internal::GenericConfigurationManagerImpl, + private Internal::PosixConfig +{ + // Allow the ConfigurationManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend class ConfigurationManager; + + // Allow the GenericConfigurationManagerImpl base class to access helper methods and types + // defined on this class. +#ifndef DOXYGEN_SHOULD_SKIP_THIS + friend class Internal::GenericConfigurationManagerImpl; +#endif + +private: + // ===== Members that implement the ConfigurationManager public interface. + + CHIP_ERROR _Init(void); + CHIP_ERROR _GetPrimaryWiFiMACAddress(uint8_t * buf); + bool _CanFactoryReset(void); + void _InitiateFactoryReset(void); + CHIP_ERROR _ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value); + CHIP_ERROR _WritePersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t value); + + // NOTE: Other public interface methods are implemented by GenericConfigurationManagerImpl<>. + + // ===== Members for internal use by the following friends. + + friend ConfigurationManager & ConfigurationMgr(void); + friend ConfigurationManagerImpl & ConfigurationMgrImpl(void); + + static ConfigurationManagerImpl sInstance; +}; + +/** + * Returns the public interface of the ConfigurationManager singleton object. + * + * Chip applications should use this to access features of the ConfigurationManager object + * that are common to all platforms. + */ +inline ConfigurationManager & ConfigurationMgr(void) +{ + return ConfigurationManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the ConfigurationManager singleton object. + * + * Chip applications can use this to gain access to features of the ConfigurationManager + * that are specific to the Tizen platform. + */ +inline ConfigurationManagerImpl & ConfigurationMgrImpl(void) +{ + return ConfigurationManagerImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Tizen/ConnectivityManagerImpl.cpp b/src/platform/Tizen/ConnectivityManagerImpl.cpp new file mode 100644 index 00000000000000..dc8a721296a88b --- /dev/null +++ b/src/platform/Tizen/ConnectivityManagerImpl.cpp @@ -0,0 +1,137 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include + +#include + +#include +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#include +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#include +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI +#include +#endif + +using namespace ::chip; +using namespace ::chip::TLV; +using namespace ::chip::DeviceLayer::Internal; + +namespace chip { +namespace DeviceLayer { + +ConnectivityManagerImpl ConnectivityManagerImpl::sInstance; + +CHIP_ERROR ConnectivityManagerImpl::_Init(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + return err; +} + +void ConnectivityManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) {} + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI +bool ConnectivityManagerImpl::_HaveIPv4InternetConnectivity(void) +{ + return false; +} + +bool ConnectivityManagerImpl::_HaveIPv6InternetConnectivity(void) +{ + return false; +} + +ConnectivityManager::WiFiStationMode ConnectivityManagerImpl::_GetWiFiStationMode(void) +{ + return ConnectivityManager::kWiFiStationMode_NotSupported; +} + +CHIP_ERROR ConnectivityManagerImpl::_SetWiFiStationMode(ConnectivityManager::WiFiStationMode val) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +uint32_t ConnectivityManagerImpl::_GetWiFiStationReconnectIntervalMS(void) +{ + return 0; +} + +CHIP_ERROR ConnectivityManagerImpl::_SetWiFiStationReconnectIntervalMS(uint32_t val) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +bool ConnectivityManagerImpl::_IsWiFiStationEnabled(void) +{ + return false; +} + +bool ConnectivityManagerImpl::_IsWiFiStationConnected(void) +{ + return false; +} + +bool ConnectivityManagerImpl::_IsWiFiStationApplicationControlled(void) +{ + return false; +} + +bool ConnectivityManagerImpl::_IsWiFiStationProvisioned(void) +{ + return false; +} + +void ConnectivityManagerImpl::_ClearWiFiStationProvision(void) {} + +bool ConnectivityManagerImpl::_CanStartWiFiScan(void) +{ + return false; +} + +CHIP_ERROR ConnectivityManagerImpl::_SetWiFiAPMode(WiFiAPMode val) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +void ConnectivityManagerImpl::_DemandStartWiFiAP(void) {} + +void ConnectivityManagerImpl::_StopOnDemandWiFiAP(void) {} + +void ConnectivityManagerImpl::_MaintainOnDemandWiFiAP(void) {} + +void ConnectivityManagerImpl::_SetWiFiAPIdleTimeoutMS(uint32_t val) {} +#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI + +CHIP_ERROR ConnectivityManagerImpl::ProvisionWiFiNetwork(const char * ssid, const char * key) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Tizen/ConnectivityManagerImpl.h b/src/platform/Tizen/ConnectivityManagerImpl.h new file mode 100644 index 00000000000000..cf88f4c0de1cf9 --- /dev/null +++ b/src/platform/Tizen/ConnectivityManagerImpl.h @@ -0,0 +1,176 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * Copyright (c) 2018 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#include +#else +#include +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#include +#else +#include +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI +#include +#else +#include +#endif + +namespace chip { +namespace Inet { +class IPAddress; +} // namespace Inet +} // namespace chip + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the ConnectivityManager singleton object for Tizen platforms. + */ +class ConnectivityManagerImpl final : public ConnectivityManager, +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + public Internal::GenericConnectivityManagerImpl_BLE, +#else + public Internal::GenericConnectivityManagerImpl_NoBLE, +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + public Internal::GenericConnectivityManagerImpl_Thread, +#else + public Internal::GenericConnectivityManagerImpl_NoThread, +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI + public Internal::GenericConnectivityManagerImpl_WiFi, +#else + public Internal::GenericConnectivityManagerImpl_NoWiFi, +#endif + public Internal::GenericConnectivityManagerImpl +{ + // Allow the ConnectivityManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend class ConnectivityManager; + +public: + CHIP_ERROR ProvisionWiFiNetwork(const char * ssid, const char * key); + +private: + // ===== Members that implement the ConnectivityManager abstract interface. + + bool _HaveIPv4InternetConnectivity(void); + bool _HaveIPv6InternetConnectivity(void); + bool _HaveServiceConnectivity(void); + CHIP_ERROR _Init(void); + void _OnPlatformEvent(const ChipDeviceEvent * event); + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI + WiFiStationMode _GetWiFiStationMode(void); + CHIP_ERROR _SetWiFiStationMode(ConnectivityManager::WiFiStationMode val); + uint32_t _GetWiFiStationReconnectIntervalMS(void); + CHIP_ERROR _SetWiFiStationReconnectIntervalMS(uint32_t val); + bool _IsWiFiStationEnabled(void); + bool _IsWiFiStationConnected(void); + bool _IsWiFiStationApplicationControlled(void); + bool _IsWiFiStationProvisioned(void); + void _ClearWiFiStationProvision(void); + bool _CanStartWiFiScan(void); + + WiFiAPMode _GetWiFiAPMode(void); + CHIP_ERROR _SetWiFiAPMode(WiFiAPMode val); + bool _IsWiFiAPActive(void); + bool _IsWiFiAPApplicationControlled(void); + void _DemandStartWiFiAP(void); + void _StopOnDemandWiFiAP(void); + void _MaintainOnDemandWiFiAP(void); + uint32_t _GetWiFiAPIdleTimeoutMS(void); + void _SetWiFiAPIdleTimeoutMS(uint32_t val); +#endif + + // ===== Members for internal use by the following friends. + + friend ConnectivityManager & ConnectivityMgr(void); + friend ConnectivityManagerImpl & ConnectivityMgrImpl(void); + + static ConnectivityManagerImpl sInstance; + + // ===== Private members reserved for use by this class only. + + ConnectivityManager::WiFiStationMode mWiFiStationMode; + ConnectivityManager::WiFiAPMode mWiFiAPMode; + WiFiAPState mWiFiAPState; + uint64_t mLastAPDemandTime; + uint32_t mWiFiStationReconnectIntervalMS; + uint32_t mWiFiAPIdleTimeoutMS; +}; + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI +inline ConnectivityManager::WiFiAPMode ConnectivityManagerImpl::_GetWiFiAPMode() +{ + return ConnectivityManager::kWiFiAPMode_NotSupported; +} + +inline bool ConnectivityManagerImpl::_IsWiFiAPActive() +{ + return false; +} + +inline bool ConnectivityManagerImpl::_IsWiFiAPApplicationControlled() +{ + return false; +} + +inline uint32_t ConnectivityManagerImpl::_GetWiFiAPIdleTimeoutMS() +{ + return 0; +} + +inline bool ConnectivityManagerImpl::_HaveServiceConnectivity() +{ + return _HaveServiceConnectivityViaThread(); +} +#endif + +/** + * Returns the public interface of the ConnectivityManager singleton object. + * + * chip applications should use this to access features of the ConnectivityManager object + * that are common to all platforms. + */ +inline ConnectivityManager & ConnectivityMgr() +{ + return ConnectivityManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the ConnectivityManager singleton object. + * + * chip applications can use this to gain access to features of the ConnectivityManager + * that are specific to the ESP32 platform. + */ +inline ConnectivityManagerImpl & ConnectivityMgrImpl() +{ + return ConnectivityManagerImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Tizen/DeviceNetworkProvisioningDelegateImpl.cpp b/src/platform/Tizen/DeviceNetworkProvisioningDelegateImpl.cpp new file mode 100644 index 00000000000000..21f0c0fe3c9741 --- /dev/null +++ b/src/platform/Tizen/DeviceNetworkProvisioningDelegateImpl.cpp @@ -0,0 +1,32 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "DeviceNetworkProvisioningDelegateImpl.h" + +namespace chip { +namespace DeviceLayer { + +CHIP_ERROR DeviceNetworkProvisioningDelegateImpl::_ProvisionWiFiNetwork(const char * ssid, const char * key) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Tizen/DeviceNetworkProvisioningDelegateImpl.h b/src/platform/Tizen/DeviceNetworkProvisioningDelegateImpl.h new file mode 100644 index 00000000000000..b1d7d8d152dd1c --- /dev/null +++ b/src/platform/Tizen/DeviceNetworkProvisioningDelegateImpl.h @@ -0,0 +1,43 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { + +namespace Internal { + +template +class GenericDeviceNetworkProvisioningDelegateImpl; + +} // namespace Internal + +class DeviceNetworkProvisioningDelegateImpl final + : public Internal::GenericDeviceNetworkProvisioningDelegateImpl +{ + friend class GenericDeviceNetworkProvisioningDelegateImpl; + +private: + CHIP_ERROR _ProvisionWiFiNetwork(const char * ssid, const char * passwd); + CHIP_ERROR _ProvisionThreadNetwork(ByteSpan threadData) { return CHIP_ERROR_NOT_IMPLEMENTED; } +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Tizen/InetPlatformConfig.h b/src/platform/Tizen/InetPlatformConfig.h new file mode 100644 index 00000000000000..4510d3e8638b11 --- /dev/null +++ b/src/platform/Tizen/InetPlatformConfig.h @@ -0,0 +1,39 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP Inet + * Layer on Tizen platforms. + * + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +#define INET_CONFIG_ENABLE_IPV4 1 + +// ========== Platform-specific Configuration Overrides ========= + +#ifndef INET_CONFIG_NUM_TCP_ENDPOINTS +#define INET_CONFIG_NUM_TCP_ENDPOINTS 32 +#endif // INET_CONFIG_NUM_TCP_ENDPOINTS + +#ifndef INET_CONFIG_NUM_UDP_ENDPOINTS +#define INET_CONFIG_NUM_UDP_ENDPOINTS 32 +#endif // INET_CONFIG_NUM_UDP_ENDPOINTS diff --git a/src/platform/Tizen/KeyValueStoreManagerImpl.cpp b/src/platform/Tizen/KeyValueStoreManagerImpl.cpp new file mode 100644 index 00000000000000..bc2a82caceca04 --- /dev/null +++ b/src/platform/Tizen/KeyValueStoreManagerImpl.cpp @@ -0,0 +1,50 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific key value storage implementation for Tizen. + */ + +#include + +namespace chip { +namespace DeviceLayer { +namespace PersistedStorage { + +KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; + +CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size, + size_t offset_bytes) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, size_t value_size) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +} // namespace PersistedStorage +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Tizen/KeyValueStoreManagerImpl.h b/src/platform/Tizen/KeyValueStoreManagerImpl.h new file mode 100644 index 00000000000000..e56fb37aca5bb5 --- /dev/null +++ b/src/platform/Tizen/KeyValueStoreManagerImpl.h @@ -0,0 +1,73 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific key value storage implementation for Tizen. + */ + +#pragma once + +namespace chip { +namespace DeviceLayer { +namespace PersistedStorage { + +class KeyValueStoreManagerImpl final : public KeyValueStoreManager +{ + // Allow the KeyValueStoreManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend class KeyValueStoreManager; + +public: + CHIP_ERROR _Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size = nullptr, size_t offset = 0); + CHIP_ERROR _Delete(const char * key); + CHIP_ERROR _Put(const char * key, const void * value, size_t value_size); + +private: + // ===== Members for internal use by the following friends. + friend KeyValueStoreManager & KeyValueStoreMgr(); + friend KeyValueStoreManagerImpl & KeyValueStoreMgrImpl(); + + static KeyValueStoreManagerImpl sInstance; +}; + +/** + * Returns the public interface of the KeyValueStoreManager singleton object. + * + * Chip applications should use this to access features of the KeyValueStoreManager object + * that are common to all platforms. + */ +inline KeyValueStoreManager & KeyValueStoreMgr(void) +{ + return KeyValueStoreManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the KeyValueStoreManager singleton object. + * + * Chip applications can use this to gain access to features of the KeyValueStoreManager + * that are specific to the Tizen platform. + */ +inline KeyValueStoreManagerImpl & KeyValueStoreMgrImpl(void) +{ + return KeyValueStoreManagerImpl::sInstance; +} + +} // namespace PersistedStorage +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Tizen/Logging.cpp b/src/platform/Tizen/Logging.cpp new file mode 100644 index 00000000000000..7c8865f1e09d73 --- /dev/null +++ b/src/platform/Tizen/Logging.cpp @@ -0,0 +1,58 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include + +#include +#include + +namespace chip { +namespace Logging { +namespace Platform { + +/** + * CHIP log output functions. + */ +void LogV(const char * module, uint8_t category, const char * msg, va_list v) +{ + constexpr const char * kLogTag = "CHIP"; + char msgBuf[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE] = { + 0, + }; + vsnprintf(msgBuf, sizeof(msgBuf), msg, v); + + switch (category) + { + case kLogCategory_Error: + dlog_print(DLOG_ERROR, kLogTag, "%s: %s", module, msgBuf); + break; + case kLogCategory_Detail: + dlog_print(DLOG_DEBUG, kLogTag, "%s: %s", module, msgBuf); + break; + case kLogCategory_Progress: + default: + dlog_print(DLOG_INFO, kLogTag, "%s: %s", module, msgBuf); + break; + } +} + +} // namespace Platform +} // namespace Logging +} // namespace chip diff --git a/src/platform/Tizen/MdnsImpl.cpp b/src/platform/Tizen/MdnsImpl.cpp new file mode 100644 index 00000000000000..db50f0b1c4295c --- /dev/null +++ b/src/platform/Tizen/MdnsImpl.cpp @@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lib/mdns/platform/Mdns.h" + +using namespace chip::Mdns; + +namespace { + +} // namespace + +namespace chip { +namespace Mdns { + +CHIP_ERROR ChipMdnsInit(MdnsAsyncReturnCallback successCallback, MdnsAsyncReturnCallback errorCallback, void * context) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR ChipMdnsSetHostname(const char * hostname) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR ChipMdnsPublishService(const MdnsService * service) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR ChipMdnsStopPublish() +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR ChipMdnsBrowse(const char * type, MdnsServiceProtocol protocol, chip::Inet::IPAddressType addressType, + chip::Inet::InterfaceId interface, MdnsBrowseCallback callback, void * context) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR ChipMdnsResolve(MdnsService * service, chip::Inet::InterfaceId interface, MdnsResolveCallback callback, void * context) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +void GetMdnsTimeout(timeval & timeout) {} + +void HandleMdnsTimeout() {} + +} // namespace Mdns +} // namespace chip diff --git a/src/platform/Tizen/PlatformManagerImpl.cpp b/src/platform/Tizen/PlatformManagerImpl.cpp new file mode 100644 index 00000000000000..f4a1dc50d08328 --- /dev/null +++ b/src/platform/Tizen/PlatformManagerImpl.cpp @@ -0,0 +1,44 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2018 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the PlatformManager object + * for Tizen platforms. + */ + +#include + +#include +#include + +namespace chip { +namespace DeviceLayer { + +PlatformManagerImpl PlatformManagerImpl::sInstance; + +CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) +{ + ReturnErrorOnFailure(Internal::PosixConfig::Init()); + + return Internal::GenericPlatformManagerImpl_POSIX::_InitChipStack(); +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Tizen/PlatformManagerImpl.h b/src/platform/Tizen/PlatformManagerImpl.h new file mode 100644 index 00000000000000..f21cfeae29e565 --- /dev/null +++ b/src/platform/Tizen/PlatformManagerImpl.h @@ -0,0 +1,86 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2018 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the PlatformManager object. + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the PlatformManager singleton object for Tizen platforms. + */ +class PlatformManagerImpl final : public PlatformManager, public Internal::GenericPlatformManagerImpl_POSIX +{ + // Allow the PlatformManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend PlatformManager; + + // Allow the generic implementation base class to call helper methods on + // this class. +#ifndef DOXYGEN_SHOULD_SKIP_THIS + friend Internal::GenericPlatformManagerImpl_POSIX; +#endif + +public: + // ===== Platform-specific members that may be accessed directly by the application. + +private: + // ===== Methods that implement the PlatformManager abstract interface. + + CHIP_ERROR _InitChipStack(void); + + // ===== Members for internal use by the following friends. + + friend PlatformManager & PlatformMgr(void); + friend PlatformManagerImpl & PlatformMgrImpl(void); + friend class Internal::BLEManagerImpl; + + static PlatformManagerImpl sInstance; +}; + +/** + * Returns the public interface of the PlatformManager singleton object. + * + * Chip applications should use this to access features of the PlatformManager object + * that are common to all platforms. + */ +inline PlatformManager & PlatformMgr(void) +{ + return PlatformManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the PlatformManager singleton object. + * + * Chip applications can use this to gain access to features of the PlatformManager + * that are specific to Tizen platform. + */ +inline PlatformManagerImpl & PlatformMgrImpl(void) +{ + return PlatformManagerImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Tizen/PosixConfig.cpp b/src/platform/Tizen/PosixConfig.cpp new file mode 100644 index 00000000000000..146c0225a856a8 --- /dev/null +++ b/src/platform/Tizen/PosixConfig.cpp @@ -0,0 +1,166 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019-2020 Google LLC. + * Copyright (c) 2018 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Utilities for interacting with multiple file partitions and maps + * key-value config calls to the correct partition. + */ + +#include +#include + +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +// *** CAUTION ***: Changing the names or namespaces of these values will *break* existing devices. + +// NVS namespaces used to store device configuration information. +const char PosixConfig::kConfigNamespace_ChipFactory[] = "chip-factory"; +const char PosixConfig::kConfigNamespace_ChipConfig[] = "chip-config"; +const char PosixConfig::kConfigNamespace_ChipCounters[] = "chip-counters"; + +// Keys stored in the Chip-factory namespace +const PosixConfig::Key PosixConfig::kConfigKey_SerialNum = { kConfigNamespace_ChipFactory, "serial-num" }; +const PosixConfig::Key PosixConfig::kConfigKey_MfrDeviceId = { kConfigNamespace_ChipFactory, "device-id" }; +const PosixConfig::Key PosixConfig::kConfigKey_MfrDeviceCert = { kConfigNamespace_ChipFactory, "device-cert" }; +const PosixConfig::Key PosixConfig::kConfigKey_MfrDeviceICACerts = { kConfigNamespace_ChipFactory, "device-ca-certs" }; +const PosixConfig::Key PosixConfig::kConfigKey_MfrDevicePrivateKey = { kConfigNamespace_ChipFactory, "device-key" }; +const PosixConfig::Key PosixConfig::kConfigKey_ProductRevision = { kConfigNamespace_ChipFactory, "product-rev" }; +const PosixConfig::Key PosixConfig::kConfigKey_ManufacturingDate = { kConfigNamespace_ChipFactory, "mfg-date" }; +const PosixConfig::Key PosixConfig::kConfigKey_SetupPinCode = { kConfigNamespace_ChipFactory, "pin-code" }; +const PosixConfig::Key PosixConfig::kConfigKey_SetupDiscriminator = { kConfigNamespace_ChipFactory, "discriminator" }; + +// Keys stored in the Chip-config namespace +const PosixConfig::Key PosixConfig::kConfigKey_FabricId = { kConfigNamespace_ChipConfig, "fabric-id" }; +const PosixConfig::Key PosixConfig::kConfigKey_ServiceConfig = { kConfigNamespace_ChipConfig, "service-config" }; +const PosixConfig::Key PosixConfig::kConfigKey_PairedAccountId = { kConfigNamespace_ChipConfig, "account-id" }; +const PosixConfig::Key PosixConfig::kConfigKey_ServiceId = { kConfigNamespace_ChipConfig, "service-id" }; +const PosixConfig::Key PosixConfig::kConfigKey_FabricSecret = { kConfigNamespace_ChipConfig, "fabric-secret" }; +const PosixConfig::Key PosixConfig::kConfigKey_GroupKeyIndex = { kConfigNamespace_ChipConfig, "group-key-index" }; +const PosixConfig::Key PosixConfig::kConfigKey_LastUsedEpochKeyId = { kConfigNamespace_ChipConfig, "last-ek-id" }; +const PosixConfig::Key PosixConfig::kConfigKey_FailSafeArmed = { kConfigNamespace_ChipConfig, "fail-safe-armed" }; +const PosixConfig::Key PosixConfig::kConfigKey_WiFiStationSecType = { kConfigNamespace_ChipConfig, "sta-sec-type" }; +const PosixConfig::Key PosixConfig::kConfigKey_OperationalDeviceId = { kConfigNamespace_ChipConfig, "op-device-id" }; +const PosixConfig::Key PosixConfig::kConfigKey_OperationalDeviceCert = { kConfigNamespace_ChipConfig, "op-device-cert" }; +const PosixConfig::Key PosixConfig::kConfigKey_OperationalDeviceICACerts = { kConfigNamespace_ChipConfig, "op-device-ca-certs" }; +const PosixConfig::Key PosixConfig::kConfigKey_OperationalDevicePrivateKey = { kConfigNamespace_ChipConfig, "op-device-key" }; +const PosixConfig::Key PosixConfig::kConfigKey_RegulatoryLocation = { kConfigNamespace_ChipConfig, "regulatory-location" }; +const PosixConfig::Key PosixConfig::kConfigKey_CountryCode = { kConfigNamespace_ChipConfig, "country-code" }; +const PosixConfig::Key PosixConfig::kConfigKey_Breadcrumb = { kConfigNamespace_ChipConfig, "breadcrumb" }; + +// Prefix used for NVS keys that contain Chip group encryption keys. +const char PosixConfig::kGroupKeyNamePrefix[] = "gk-"; + +CHIP_ERROR PosixConfig::Init() +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR PosixConfig::ReadConfigValue(Key key, bool & val) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR PosixConfig::ReadConfigValue(Key key, uint32_t & val) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR PosixConfig::ReadConfigValue(Key key, uint64_t & val) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR PosixConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR PosixConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR PosixConfig::WriteConfigValue(Key key, bool val) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR PosixConfig::WriteConfigValue(Key key, uint32_t val) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR PosixConfig::WriteConfigValue(Key key, uint64_t val) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR PosixConfig::WriteConfigValueStr(Key key, const char * str) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR PosixConfig::WriteConfigValueStr(Key key, const char * str, size_t strLen) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR PosixConfig::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR PosixConfig::ClearConfigValue(Key key) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +bool PosixConfig::ConfigValueExists(Key key) +{ + return false; +} + +CHIP_ERROR PosixConfig::EnsureNamespace(const char * ns) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR PosixConfig::ClearNamespace(const char * ns) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR PosixConfig::FactoryResetConfig() +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +void PosixConfig::RunConfigUnitTest() {} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Tizen/PosixConfig.h b/src/platform/Tizen/PosixConfig.h new file mode 100644 index 00000000000000..3b52637b91546f --- /dev/null +++ b/src/platform/Tizen/PosixConfig.h @@ -0,0 +1,124 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Utilities for accessing persisted device configuration on + * Tizen platforms. + */ + +#pragma once + +#include +#include + +#include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +/** + * Provides functions and definitions for accessing device configuration information on the Posix. + * + * This class is designed to be mixed-in to concrete implementation classes as a means to + * provide access to configuration information to generic base classes. + */ +class PosixConfig +{ +public: + struct Key; + + // Maximum length of an NVS key name. + static constexpr size_t kMaxConfigKeyNameLength = 15; + + // NVS namespaces used to store device configuration information. + static const char kConfigNamespace_ChipFactory[]; + static const char kConfigNamespace_ChipConfig[]; + static const char kConfigNamespace_ChipCounters[]; + + // Key definitions for well-known keys. + static const Key kConfigKey_SerialNum; + static const Key kConfigKey_MfrDeviceId; + static const Key kConfigKey_MfrDeviceCert; + static const Key kConfigKey_MfrDeviceICACerts; + static const Key kConfigKey_MfrDevicePrivateKey; + static const Key kConfigKey_ProductRevision; + static const Key kConfigKey_ManufacturingDate; + static const Key kConfigKey_SetupPinCode; + static const Key kConfigKey_FabricId; + static const Key kConfigKey_ServiceConfig; + static const Key kConfigKey_PairedAccountId; + static const Key kConfigKey_ServiceId; + static const Key kConfigKey_FabricSecret; + static const Key kConfigKey_GroupKeyIndex; + static const Key kConfigKey_LastUsedEpochKeyId; + static const Key kConfigKey_FailSafeArmed; + static const Key kConfigKey_WiFiStationSecType; + static const Key kConfigKey_OperationalDeviceId; + static const Key kConfigKey_OperationalDeviceCert; + static const Key kConfigKey_OperationalDeviceICACerts; + static const Key kConfigKey_OperationalDevicePrivateKey; + static const Key kConfigKey_SetupDiscriminator; + static const Key kConfigKey_RegulatoryLocation; + static const Key kConfigKey_CountryCode; + static const Key kConfigKey_Breadcrumb; + + static const char kGroupKeyNamePrefix[]; + + static CHIP_ERROR Init(void); + + // Config value accessors. + static CHIP_ERROR ReadConfigValue(Key key, bool & val); + static CHIP_ERROR ReadConfigValue(Key key, uint32_t & val); + static CHIP_ERROR ReadConfigValue(Key key, uint64_t & val); + static CHIP_ERROR ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen); + static CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen); + static CHIP_ERROR WriteConfigValue(Key key, bool val); + static CHIP_ERROR WriteConfigValue(Key key, uint32_t val); + static CHIP_ERROR WriteConfigValue(Key key, uint64_t val); + static CHIP_ERROR WriteConfigValueStr(Key key, const char * str); + static CHIP_ERROR WriteConfigValueStr(Key key, const char * str, size_t strLen); + static CHIP_ERROR WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen); + static CHIP_ERROR ClearConfigValue(Key key); + static bool ConfigValueExists(Key key); + static CHIP_ERROR FactoryResetConfig(void); + + static void RunConfigUnitTest(void); + +protected: + // NVS Namespace helper functions. + static CHIP_ERROR EnsureNamespace(const char * ns); + static CHIP_ERROR ClearNamespace(const char * ns); +}; + +struct PosixConfig::Key +{ + const char * Namespace; + const char * Name; + + bool operator==(const Key & other) const; +}; + +inline bool PosixConfig::Key::operator==(const Key & other) const +{ + return strcmp(Namespace, other.Namespace) == 0 && strcmp(Name, other.Name) == 0; +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Tizen/SystemPlatformConfig.h b/src/platform/Tizen/SystemPlatformConfig.h new file mode 100644 index 00000000000000..f895bff0b9c972 --- /dev/null +++ b/src/platform/Tizen/SystemPlatformConfig.h @@ -0,0 +1,49 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP System + * Layer on Tizen platforms. + * + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { +struct ChipDeviceEvent; +} // namespace DeviceLayer +} // namespace chip + +// ==================== Platform Adaptations ==================== + +#define CHIP_SYSTEM_CONFIG_POSIX_LOCKING 1 +#define CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING 0 +#define CHIP_SYSTEM_CONFIG_NO_LOCKING 0 +#define CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS 1 +#define CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME 0 + +#define CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS 1 + +// ========== Platform-specific Configuration Overrides ========= + +#ifndef CHIP_SYSTEM_CONFIG_NUM_TIMERS +#define CHIP_SYSTEM_CONFIG_NUM_TIMERS 16 +#endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS diff --git a/src/platform/Tizen/SystemTimeSupport.cpp b/src/platform/Tizen/SystemTimeSupport.cpp new file mode 100644 index 00000000000000..70b473eb1a5cd4 --- /dev/null +++ b/src/platform/Tizen/SystemTimeSupport.cpp @@ -0,0 +1,69 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2018 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides implementations of the CHIP System Layer platform + * time/clock functions that are suitable for use on the Tizen platform. + */ + +#include + +#include +#include + +namespace chip { +namespace System { +namespace Platform { +namespace Layer { + +uint64_t GetClock_Monotonic() +{ + return static_cast(0); +} + +uint64_t GetClock_MonotonicMS() +{ + return static_cast(0); +} + +uint64_t GetClock_MonotonicHiRes() +{ + return static_cast(0); +} + +CHIP_ERROR GetClock_RealTime(uint64_t & curTime) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR GetClock_RealTimeMS(uint64_t & curTime) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR SetClock_RealTime(uint64_t newCurTime) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +} // namespace Layer +} // namespace Platform +} // namespace System +} // namespace chip diff --git a/src/platform/device.gni b/src/platform/device.gni index cf10cbd4f3d2b4..b4b0758c27e069 100644 --- a/src/platform/device.gni +++ b/src/platform/device.gni @@ -16,7 +16,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/ble/ble.gni") declare_args() { - # Device platform layer: cc13x2_26x2, darwin, efr32, esp32, external, freertos, linux, nrfconnect, k32w, qpg, none. + # Device platform layer: cc13x2_26x2, darwin, efr32, esp32, external, freertos, linux, nrfconnect, k32w, qpg, tizen, none. chip_device_platform = "auto" chip_platform_target = "" @@ -31,6 +31,8 @@ if (chip_device_platform == "auto") { chip_device_platform = "darwin" } else if (current_os == "linux") { chip_device_platform = "linux" + } else if (current_os == "tizen") { + chip_device_platform = "tizen" } else { chip_device_platform = "none" } @@ -45,7 +47,7 @@ declare_args() { # Enable wifi support. chip_enable_wifi = chip_device_platform == "linux" || chip_device_platform == "esp32" || - chip_device_platform == "mbed" + chip_device_platform == "mbed" || chip_device_platform == "tizen" # Enable ble support. if (chip_device_platform == "fake") { @@ -63,7 +65,8 @@ declare_args() { chip_mdns = "minimal" } else if (chip_device_platform == "darwin" || chip_device_platform == "cc13x2_26x2" || current_os == "android" || - chip_device_platform == "fake") { + chip_device_platform == "fake" || + chip_device_platform == "tizen") { chip_mdns = "platform" } else { chip_mdns = "none" @@ -84,6 +87,8 @@ if (chip_device_platform == "cc13x2_26x2") { _chip_device_layer = "ESP32" } else if (chip_device_platform == "linux") { _chip_device_layer = "Linux" +} else if (chip_device_platform == "tizen") { + _chip_device_layer = "Tizen" } else if (chip_device_platform == "nrfconnect") { _chip_device_layer = "nrfconnect" } else if (chip_device_platform == "qpg") { @@ -133,7 +138,7 @@ assert( chip_device_platform == "cc13x2_26x2" || chip_device_platform == "darwin" || chip_device_platform == "efr32" || chip_device_platform == "esp32" || chip_device_platform == "external" || - chip_device_platform == "linux" || + chip_device_platform == "linux" || chip_device_platform == "tizen" || chip_device_platform == "nrfconnect" || chip_device_platform == "k32w" || chip_device_platform == "qpg" || chip_device_platform == "telink" || chip_device_platform == "mbed" || From 499d6a3783252429a80c03e03de0bdd361b5bc85 Mon Sep 17 00:00:00 2001 From: Michael Spang Date: Mon, 13 Sep 2021 09:54:11 -0400 Subject: [PATCH 006/255] Fix naming of public key param of ExampleOperationalCredentialsIssuer (#9629) The public key field is named "ephemeralKey" which is presumably a copy paste error from chip-tool which generates a new credential every time it runs. Fix it to "pubkey" which matches the definition. --- src/controller/ExampleOperationalCredentialsIssuer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controller/ExampleOperationalCredentialsIssuer.h b/src/controller/ExampleOperationalCredentialsIssuer.h index 7f07db382df456..c196b2e954b5b3 100644 --- a/src/controller/ExampleOperationalCredentialsIssuer.h +++ b/src/controller/ExampleOperationalCredentialsIssuer.h @@ -89,7 +89,7 @@ class DLL_EXPORT ExampleOperationalCredentialsIssuer : public OperationalCredent * This method is expected to be called once all the checks (e.g. device attestation, CSR verification etc) * have been completed, or not required (e.g. for self trusted devices such as commissioner apps). */ - CHIP_ERROR GenerateNOCChainAfterValidation(NodeId nodeId, FabricId fabricId, const Crypto::P256PublicKey & ephemeralKey, + CHIP_ERROR GenerateNOCChainAfterValidation(NodeId nodeId, FabricId fabricId, const Crypto::P256PublicKey & pubkey, MutableByteSpan & rcac, MutableByteSpan & icac, MutableByteSpan & noc); private: From 5c864e44edb0cb11ddd586bbea5882b77cfa914a Mon Sep 17 00:00:00 2001 From: Michael Spang Date: Mon, 13 Sep 2021 09:54:41 -0400 Subject: [PATCH 007/255] Fix ChipError scope resolution (#9627) Make sure to unambiguously specify the chip namespace in macros as they can be evaluated in places where 'chip::' is ambiguous. --- src/lib/core/CHIPError.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib/core/CHIPError.h b/src/lib/core/CHIPError.h index 971057bd29d584..c4a7d63fd86157 100644 --- a/src/lib/core/CHIPError.h +++ b/src/lib/core/CHIPError.h @@ -146,9 +146,10 @@ class ChipError * (In C++20 this could be replaced by a consteval constructor.) */ #if CHIP_CONFIG_ERROR_SOURCE -#define CHIP_SDK_ERROR(part, code) (::chip::ChipError(chip::ChipError::SdkErrorConstant<(part), (code)>::value, __FILE__, __LINE__)) +#define CHIP_SDK_ERROR(part, code) \ + (::chip::ChipError(::chip::ChipError::SdkErrorConstant<(part), (code)>::value, __FILE__, __LINE__)) #else // CHIP_CONFIG_ERROR_SOURCE -#define CHIP_SDK_ERROR(part, code) (::chip::ChipError(chip::ChipError::SdkErrorConstant<(part), (code)>::value)) +#define CHIP_SDK_ERROR(part, code) (::chip::ChipError(::chip::ChipError::SdkErrorConstant<(part), (code)>::value)) #endif // CHIP_CONFIG_ERROR_SOURCE /** From f9de0af11865ce00ba1f2d53b8e7ebfeff0341f7 Mon Sep 17 00:00:00 2001 From: Devendra Tewari Date: Mon, 13 Sep 2021 11:56:24 -0300 Subject: [PATCH 008/255] Change temperature delta label to degrees Celsius (#9427) * Change temperature delta label to degrees celsius * Rename Fahrenheit in identifiers to Celsius * Restyled by clang-format Co-authored-by: Restyled.io --- .../TemperatureSensorViewController.m | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/Temperature Sensor/TemperatureSensorViewController.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/Temperature Sensor/TemperatureSensorViewController.m index 56b3ea298ba930..b81ada3eb01bb0 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/Temperature Sensor/TemperatureSensorViewController.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/Temperature Sensor/TemperatureSensorViewController.m @@ -14,7 +14,7 @@ @interface TemperatureSensorViewController () @property (nonatomic, strong) UILabel * temperatureLabel; @property (nonatomic, strong) UITextField * minIntervalInSecondsTextField; @property (nonatomic, strong) UITextField * maxIntervalInSecondsTextField; -@property (nonatomic, strong) UITextField * deltaInFahrenheitTextField; +@property (nonatomic, strong) UITextField * deltaInCelsiusTextField; @property (nonatomic, strong) UIButton * sendReportingSetup; @end @@ -51,7 +51,7 @@ - (void)dismissKeyboard { [_minIntervalInSecondsTextField resignFirstResponder]; [_maxIntervalInSecondsTextField resignFirstResponder]; - [_deltaInFahrenheitTextField resignFirstResponder]; + [_deltaInCelsiusTextField resignFirstResponder]; } - (void)setupUI @@ -120,15 +120,15 @@ - (void)setupUI [maxIntervalInSecondsView.trailingAnchor constraintEqualToAnchor:stackView.trailingAnchor].active = YES; // Delta - _deltaInFahrenheitTextField = [UITextField new]; - _deltaInFahrenheitTextField.keyboardType = UIKeyboardTypeNumberPad; - UILabel * deltaInFahrenheitLabel = [UILabel new]; - [deltaInFahrenheitLabel setText:@"Delta (F):"]; - UIView * deltaInFahrenheitView = [CHIPUIViewUtils viewWithLabel:deltaInFahrenheitLabel textField:_deltaInFahrenheitTextField]; - [stackView addArrangedSubview:deltaInFahrenheitView]; + _deltaInCelsiusTextField = [UITextField new]; + _deltaInCelsiusTextField.keyboardType = UIKeyboardTypeNumberPad; + UILabel * deltaInCelsiusLabel = [UILabel new]; + [deltaInCelsiusLabel setText:@"Delta (°C):"]; + UIView * deltaInCelsiusView = [CHIPUIViewUtils viewWithLabel:deltaInCelsiusLabel textField:_deltaInCelsiusTextField]; + [stackView addArrangedSubview:deltaInCelsiusView]; - deltaInFahrenheitView.translatesAutoresizingMaskIntoConstraints = false; - [deltaInFahrenheitView.trailingAnchor constraintEqualToAnchor:stackView.trailingAnchor].active = YES; + deltaInCelsiusView.translatesAutoresizingMaskIntoConstraints = false; + [deltaInCelsiusView.trailingAnchor constraintEqualToAnchor:stackView.trailingAnchor].active = YES; // Reporting button _sendReportingSetup = [UIButton new]; @@ -194,10 +194,10 @@ - (void)reportFromUserEnteredSettings { int minIntervalSeconds = [_minIntervalInSecondsTextField.text intValue]; int maxIntervalSeconds = [_maxIntervalInSecondsTextField.text intValue]; - int deltaInFahrenheit = [_deltaInFahrenheitTextField.text intValue]; + int deltaInCelsius = [_deltaInCelsiusTextField.text intValue]; - NSLog(@"Sending temp reporting values: min %@ max %@ value %@", @(minIntervalSeconds), @(maxIntervalSeconds), - @(deltaInFahrenheit)); + NSLog( + @"Sending temp reporting values: min %@ max %@ value %@", @(minIntervalSeconds), @(maxIntervalSeconds), @(deltaInCelsius)); if (CHIPGetConnectedDevice(^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { if (chipDevice) { @@ -207,7 +207,7 @@ - (void)reportFromUserEnteredSettings [cluster configureAttributeMeasuredValueWithMinInterval:minIntervalSeconds maxInterval:maxIntervalSeconds - change:deltaInFahrenheit + change:deltaInCelsius responseHandler:^(NSError * error, NSDictionary * values) { if (error == nil) return; From b8e7596dd3a05a2eccfe65a82a6a552e4d4d4424 Mon Sep 17 00:00:00 2001 From: Zang MingJie Date: Mon, 13 Sep 2021 23:00:26 +0800 Subject: [PATCH 009/255] Remove dead codes PeerConnectionState::Reset (#9422) --- src/transport/MessageCounter.h | 10 ---------- src/transport/PeerConnectionState.h | 12 ------------ src/transport/SecureSession.cpp | 6 ------ src/transport/SecureSession.h | 5 ----- src/transport/SessionMessageCounter.h | 6 ------ 5 files changed, 39 deletions(-) diff --git a/src/transport/MessageCounter.h b/src/transport/MessageCounter.h index 7e6d1298d14f05..a292bd384fe66d 100644 --- a/src/transport/MessageCounter.h +++ b/src/transport/MessageCounter.h @@ -48,7 +48,6 @@ class MessageCounter virtual ~MessageCounter() = 0; virtual Type GetType() = 0; - virtual void Reset() = 0; virtual uint32_t Value() = 0; /** Get current value */ virtual CHIP_ERROR Advance() = 0; /** Advance the counter */ virtual CHIP_ERROR SetCounter(uint32_t count) = 0; /** Set the counter to the specified value */ @@ -63,9 +62,6 @@ class GlobalUnencryptedMessageCounter : public MessageCounter ~GlobalUnencryptedMessageCounter() override {} Type GetType() override { return GlobalUnencrypted; } - void Reset() override - { /* null op */ - } uint32_t Value() override { return value; } CHIP_ERROR Advance() override { @@ -74,7 +70,6 @@ class GlobalUnencryptedMessageCounter : public MessageCounter } CHIP_ERROR SetCounter(uint32_t count) override { - Reset(); value = count; return CHIP_NO_ERROR; } @@ -91,9 +86,6 @@ class GlobalEncryptedMessageCounter : public MessageCounter CHIP_ERROR Init(); Type GetType() override { return GlobalEncrypted; } - void Reset() override - { /* null op */ - } uint32_t Value() override { return persisted.GetValue(); } CHIP_ERROR Advance() override { return persisted.Advance(); } CHIP_ERROR SetCounter(uint32_t count) override { return CHIP_ERROR_NOT_IMPLEMENTED; } @@ -128,7 +120,6 @@ class LocalSessionMessageCounter : public MessageCounter ~LocalSessionMessageCounter() override {} Type GetType() override { return Session; } - void Reset() override { value = kInitialValue; } uint32_t Value() override { return value; } CHIP_ERROR Advance() override { @@ -137,7 +128,6 @@ class LocalSessionMessageCounter : public MessageCounter } CHIP_ERROR SetCounter(uint32_t count) override { - Reset(); value = count; return CHIP_NO_ERROR; } diff --git a/src/transport/PeerConnectionState.h b/src/transport/PeerConnectionState.h index a0f22b7b073c74..dee71a1948960c 100644 --- a/src/transport/PeerConnectionState.h +++ b/src/transport/PeerConnectionState.h @@ -86,18 +86,6 @@ class PeerConnectionState mLocalKeyID != UINT16_MAX); } - /** - * Reset the connection state to a completely uninitialized status. - */ - void Reset() - { - mPeerAddress = PeerAddress::Uninitialized(); - mPeerNodeId = kUndefinedNodeId; - mLastActivityTimeMs = 0; - mSecureSession.Reset(); - mSessionMessageCounter.Reset(); - } - CHIP_ERROR EncryptBeforeSend(const uint8_t * input, size_t input_length, uint8_t * output, PacketHeader & header, MessageAuthenticationCode & mac) const { diff --git a/src/transport/SecureSession.cpp b/src/transport/SecureSession.cpp index 8229f53b06c6f2..0c78ca0ae61bb2 100644 --- a/src/transport/SecureSession.cpp +++ b/src/transport/SecureSession.cpp @@ -94,12 +94,6 @@ CHIP_ERROR SecureSession::Init(const Crypto::P256Keypair & local_keypair, const return InitFromSecret(ByteSpan(secret, secret.Length()), salt, infoType, role); } -void SecureSession::Reset() -{ - mKeyAvailable = false; - memset(mKeys, 0, sizeof(mKeys)); -} - CHIP_ERROR SecureSession::GetIV(const PacketHeader & header, uint8_t * iv, size_t len) { diff --git a/src/transport/SecureSession.h b/src/transport/SecureSession.h index 2b31fdeed7eb57..e79b51d2553188 100644 --- a/src/transport/SecureSession.h +++ b/src/transport/SecureSession.h @@ -122,11 +122,6 @@ class DLL_EXPORT SecureSession */ size_t EncryptionOverhead(); - /** - * Clears the internal state of secure session back to the state of a new object. - */ - void Reset(); - private: static constexpr size_t kAES_CCM128_Key_Length = 16; diff --git a/src/transport/SessionMessageCounter.h b/src/transport/SessionMessageCounter.h index 6a6232206a36ac..acc79779cb081a 100644 --- a/src/transport/SessionMessageCounter.h +++ b/src/transport/SessionMessageCounter.h @@ -34,12 +34,6 @@ namespace Transport { class SessionMessageCounter { public: - void Reset() - { - mLocalMessageCounter.Reset(); - mPeerMessageCounter.Reset(); - } - MessageCounter & GetLocalMessageCounter() { return mLocalMessageCounter; } PeerMessageCounter & GetPeerMessageCounter() { return mPeerMessageCounter; } From 3da26cfa879282c06fea97b7c98db371d0d018a7 Mon Sep 17 00:00:00 2001 From: Zang MingJie Date: Mon, 13 Sep 2021 23:10:52 +0800 Subject: [PATCH 010/255] Add mDNS shutdown (#9621) --- src/controller/CHIPDeviceController.cpp | 4 ++++ src/controller/tests/TestCommissionableNodeController.cpp | 1 + src/lib/mdns/Discovery_ImplPlatform.h | 1 + src/lib/mdns/MinimalMdnsServer.cpp | 5 +++++ src/lib/mdns/MinimalMdnsServer.h | 1 + src/lib/mdns/Resolver.h | 1 + src/lib/mdns/Resolver_ImplMinimalMdns.cpp | 6 ++++++ src/lib/mdns/Resolver_ImplNone.cpp | 1 + src/platform/fake/MdnsImpl.cpp | 5 +++++ 9 files changed, 25 insertions(+) diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 900262dffab078..1c497ece4e92a3 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -266,6 +266,10 @@ CHIP_ERROR DeviceController::Shutdown() // manager. app::InteractionModelEngine::GetInstance()->Shutdown(); +#if CHIP_DEVICE_CONFIG_ENABLE_MDNS + Mdns::Resolver::Instance().ShutdownResolver(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS + // TODO(#6668): Some exchange has leak, shutting down ExchangeManager will cause a assert fail. // if (mExchangeMgr != nullptr) // { diff --git a/src/controller/tests/TestCommissionableNodeController.cpp b/src/controller/tests/TestCommissionableNodeController.cpp index 43aa5917d35fee..d0df594c6d2068 100644 --- a/src/controller/tests/TestCommissionableNodeController.cpp +++ b/src/controller/tests/TestCommissionableNodeController.cpp @@ -33,6 +33,7 @@ class MockResolver : public Resolver public: CHIP_ERROR SetResolverDelegate(ResolverDelegate *) override { return SetResolverDelegateStatus; } CHIP_ERROR StartResolver(chip::Inet::InetLayer * inetLayer, uint16_t port) override { return StartResolverStatus; } + void ShutdownResolver() override {} CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type) override { return ResolveNodeIdStatus; } CHIP_ERROR FindCommissioners(DiscoveryFilter filter = DiscoveryFilter()) override { return FindCommissionersStatus; } CHIP_ERROR FindCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter()) override { return CHIP_ERROR_NOT_IMPLEMENTED; } diff --git a/src/lib/mdns/Discovery_ImplPlatform.h b/src/lib/mdns/Discovery_ImplPlatform.h index c0bc89d1168831..0db90a695a1c62 100644 --- a/src/lib/mdns/Discovery_ImplPlatform.h +++ b/src/lib/mdns/Discovery_ImplPlatform.h @@ -43,6 +43,7 @@ class DiscoveryImplPlatform : public ServiceAdvertiser, public Resolver /// Starts the service resolver if not yet started CHIP_ERROR StartResolver(Inet::InetLayer * inetLayer, uint16_t port) override { return Init(); } + void ShutdownResolver() override { ChipMdnsShutdown(); } /// Advertises the CHIP node as an operational node CHIP_ERROR Advertise(const OperationalAdvertisingParameters & params) override; diff --git a/src/lib/mdns/MinimalMdnsServer.cpp b/src/lib/mdns/MinimalMdnsServer.cpp index 3044547126ede0..7bd268bb72eb8c 100644 --- a/src/lib/mdns/MinimalMdnsServer.cpp +++ b/src/lib/mdns/MinimalMdnsServer.cpp @@ -107,5 +107,10 @@ CHIP_ERROR GlobalMinimalMdnsServer::StartServer(chip::Inet::InetLayer * inetLaye return GlobalMinimalMdnsServer::Server().Listen(inetLayer, &allInterfaces, port); } +void GlobalMinimalMdnsServer::ShutdownServer() +{ + GlobalMinimalMdnsServer::Server().Shutdown(); +} + } // namespace Mdns } // namespace chip diff --git a/src/lib/mdns/MinimalMdnsServer.h b/src/lib/mdns/MinimalMdnsServer.h index e42342073fa5a4..e84cff5205a43e 100644 --- a/src/lib/mdns/MinimalMdnsServer.h +++ b/src/lib/mdns/MinimalMdnsServer.h @@ -90,6 +90,7 @@ class GlobalMinimalMdnsServer : public mdns::Minimal::ServerDelegate /// Calls Server().Listen() on all available interfaces CHIP_ERROR StartServer(chip::Inet::InetLayer * inetLayer, uint16_t port); + void ShutdownServer(); void SetQueryDelegate(MdnsPacketDelegate * delegate) { mQueryDelegate = delegate; } void SetResponseDelegate(MdnsPacketDelegate * delegate) { mResponseDelegate = delegate; } diff --git a/src/lib/mdns/Resolver.h b/src/lib/mdns/Resolver.h index 47faa4eaa7ace0..f8badf5ba10521 100644 --- a/src/lib/mdns/Resolver.h +++ b/src/lib/mdns/Resolver.h @@ -260,6 +260,7 @@ class Resolver /// /// Unsual name to allow base MDNS classes to implement both Advertiser and Resolver interfaces. virtual CHIP_ERROR StartResolver(chip::Inet::InetLayer * inetLayer, uint16_t port) = 0; + virtual void ShutdownResolver() = 0; /// Registers a resolver delegate if none has been registered before virtual CHIP_ERROR SetResolverDelegate(ResolverDelegate * delegate) = 0; diff --git a/src/lib/mdns/Resolver_ImplMinimalMdns.cpp b/src/lib/mdns/Resolver_ImplMinimalMdns.cpp index d73fb1cabb0fdf..599cb9269fe4e3 100644 --- a/src/lib/mdns/Resolver_ImplMinimalMdns.cpp +++ b/src/lib/mdns/Resolver_ImplMinimalMdns.cpp @@ -335,6 +335,7 @@ class MinMdnsResolver : public Resolver, public MdnsPacketDelegate ///// Resolver implementation CHIP_ERROR StartResolver(chip::Inet::InetLayer * inetLayer, uint16_t port) override; + void ShutdownResolver() override; CHIP_ERROR SetResolverDelegate(ResolverDelegate * delegate) override; CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type) override; CHIP_ERROR FindCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter()) override; @@ -394,6 +395,11 @@ CHIP_ERROR MinMdnsResolver::StartResolver(chip::Inet::InetLayer * inetLayer, uin return GlobalMinimalMdnsServer::Instance().StartServer(inetLayer, port); } +void MinMdnsResolver::ShutdownResolver() +{ + GlobalMinimalMdnsServer::Instance().ShutdownServer(); +} + CHIP_ERROR MinMdnsResolver::SetResolverDelegate(ResolverDelegate * delegate) { mDelegate = delegate; diff --git a/src/lib/mdns/Resolver_ImplNone.cpp b/src/lib/mdns/Resolver_ImplNone.cpp index 8f1cb81b7298dd..bd0f097622327d 100644 --- a/src/lib/mdns/Resolver_ImplNone.cpp +++ b/src/lib/mdns/Resolver_ImplNone.cpp @@ -29,6 +29,7 @@ class NoneResolver : public Resolver CHIP_ERROR SetResolverDelegate(ResolverDelegate *) override { return CHIP_NO_ERROR; } CHIP_ERROR StartResolver(chip::Inet::InetLayer * inetLayer, uint16_t port) override { return CHIP_NO_ERROR; } + void ShutdownResolver() override {} CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type) override { diff --git a/src/platform/fake/MdnsImpl.cpp b/src/platform/fake/MdnsImpl.cpp index 30bb388066e5a3..9eb7379c799efb 100644 --- a/src/platform/fake/MdnsImpl.cpp +++ b/src/platform/fake/MdnsImpl.cpp @@ -95,6 +95,11 @@ CHIP_ERROR ChipMdnsInit(MdnsAsyncReturnCallback initCallback, MdnsAsyncReturnCal return CHIP_NO_ERROR; } +CHIP_ERROR ChipMdnsShutdown() +{ + return CHIP_NO_ERROR; +} + CHIP_ERROR ChipMdnsPublishService(const MdnsService * service) { return test::CheckExpected(test::CallType::kStart, service); From 47aed242806e3771a4639f07efd8a22b16dda522 Mon Sep 17 00:00:00 2001 From: Victor Morales Date: Mon, 13 Sep 2021 08:31:02 -0700 Subject: [PATCH 011/255] Use pythonic way in Chip Bluez Manager and Utility (#9613) Signed-off-by: Victor Morales --- src/controller/python/chip/ChipBluezMgr.py | 4 ++-- src/controller/python/chip/ChipUtility.py | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/controller/python/chip/ChipBluezMgr.py b/src/controller/python/chip/ChipBluezMgr.py index da201bc24f5021..13b8b28cdb9452 100644 --- a/src/controller/python/chip/ChipBluezMgr.py +++ b/src/controller/python/chip/ChipBluezMgr.py @@ -844,9 +844,9 @@ def ble_adapter_print(self): self.bluez, self.bus, ADAPTER_INTERFACE, "/org/bluez" ) ] - for i in range(len(adapters)): + for adapter in adapters: self.logger.info("AdapterName: %s AdapterAddress: %s" % ( - adapters[i].path.replace("/org/bluez/", ""), adapters[i].Address)) + adapter.path.replace("/org/bluez/", ""), adapter.Address)) except dbus.exceptions.DBusException as ex: self.logger.debug(str(ex)) diff --git a/src/controller/python/chip/ChipUtility.py b/src/controller/python/chip/ChipUtility.py index bbbe88d79e145f..1be9c5feb1bf9c 100644 --- a/src/controller/python/chip/ChipUtility.py +++ b/src/controller/python/chip/ChipUtility.py @@ -38,8 +38,7 @@ def VoidPtrToByteArray(ptr, len): v = bytearray(len) memmove((c_byte * len).from_buffer(v), ptr, len) return v - else: - return None + return None @staticmethod def ByteArrayToVoidPtr(array): @@ -47,13 +46,12 @@ def ByteArrayToVoidPtr(array): if not (isinstance(array, bytes) or isinstance(array, bytearray)): raise TypeError("Array must be an str or a bytearray") return cast((c_byte * len(array)).from_buffer_copy(array), c_void_p) - else: - return c_void_p(0) + return c_void_p(0) @staticmethod def IsByteArrayAllZeros(array): - for i in range(len(array)): - if array[i] != 0: + for i in array: + if i != 0: return False return True From 23ac3c00503dca6aca2f57ca7e08868d62d31468 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 13 Sep 2021 11:36:18 -0400 Subject: [PATCH 012/255] Remove RawEndPoint. (#9614) This is unused in Matter. The only use case is ICMP, and Matter doesn't do ICMP. --- config/mbed/chip-gn/args.gni | 1 - config/nrfconnect/chip-module/CMakeLists.txt | 1 - config/standalone/args.gni | 1 - config/telink/chip-module/CMakeLists.txt | 1 - examples/platform/k32w/app/args.gni | 1 - examples/platform/k32w/args.gni | 1 - src/inet/BUILD.gn | 8 - src/inet/EndPointBasis.h | 6 - src/inet/IPEndPointBasis.cpp | 12 - src/inet/Inet.h | 4 - src/inet/InetConfig.h | 27 - src/inet/InetLayer.cpp | 66 -- src/inet/InetLayer.h | 15 - src/inet/RawEndPoint.cpp | 1044 ----------------- src/inet/RawEndPoint.h | 124 -- src/inet/inet.gni | 3 - src/inet/tests/TestInetEndPoint.cpp | 107 -- src/inet/tests/TestInetLayer.cpp | 203 +--- src/inet/tests/TestInetLayerCommon.hpp | 11 - src/inet/tests/TestInetLayerMulticast.cpp | 156 +-- src/lwip/k32w/lwipopts.h | 5 - src/lwip/qpg/lwipopts.h | 5 - src/platform/K32W/args.gni | 1 - src/platform/qpg/args.gni | 1 - src/system/SystemLayerImplSelect.h | 3 +- src/system/SystemPacketBuffer.h | 2 - src/system/SystemStats.cpp | 3 - src/system/SystemStats.h | 3 - .../happy/test-templates/ChipInetMulticast.py | 6 +- .../test_inet_multicast_five_nodes_on_wifi.py | 2 +- 30 files changed, 37 insertions(+), 1786 deletions(-) delete mode 100644 src/inet/RawEndPoint.cpp delete mode 100644 src/inet/RawEndPoint.h diff --git a/config/mbed/chip-gn/args.gni b/config/mbed/chip-gn/args.gni index 6277f2a765cb92..b458740c9512b5 100644 --- a/config/mbed/chip-gn/args.gni +++ b/config/mbed/chip-gn/args.gni @@ -20,7 +20,6 @@ chip_project_config_include = "" chip_system_project_config_include = "" chip_device_project_config_include = "" -chip_inet_config_enable_raw_endpoint = false chip_inet_config_enable_udp_endpoint = true chip_inet_config_enable_tcp_endpoint = true chip_inet_config_enable_dns_resolver = true diff --git a/config/nrfconnect/chip-module/CMakeLists.txt b/config/nrfconnect/chip-module/CMakeLists.txt index fb308760159415..87a54154e22c1d 100644 --- a/config/nrfconnect/chip-module/CMakeLists.txt +++ b/config/nrfconnect/chip-module/CMakeLists.txt @@ -198,7 +198,6 @@ chip_gn_arg_bool ("chip_inet_config_enable_ipv4" CONFIG_NET_IPV4) chip_gn_arg_bool ("chip_enable_nfc" CONFIG_CHIP_NFC_COMMISSIONING) chip_gn_arg_bool ("chip_build_tests" CONFIG_CHIP_BUILD_TESTS) chip_gn_arg_bool ("chip_monolithic_tests" CONFIG_CHIP_BUILD_TESTS) -chip_gn_arg_bool ("chip_inet_config_enable_raw_endpoint" CONFIG_CHIP_BUILD_TESTS) chip_gn_arg_bool ("chip_inet_config_enable_tcp_endpoint" CONFIG_CHIP_BUILD_TESTS) chip_gn_arg_bool ("chip_inet_config_enable_dns_resolver" CONFIG_CHIP_BUILD_TESTS) chip_gn_arg_bool ("chip_build_libshell" CONFIG_CHIP_LIB_SHELL) diff --git a/config/standalone/args.gni b/config/standalone/args.gni index 594158f7acfb29..40caf42ee37b50 100644 --- a/config/standalone/args.gni +++ b/config/standalone/args.gni @@ -15,5 +15,4 @@ # Options from standalone-chip.mk that differ from configure defaults. These # options are used from examples/. chip_build_tests = false -chip_inet_config_enable_raw_endpoint = false chip_inet_config_enable_dns_resolver = false diff --git a/config/telink/chip-module/CMakeLists.txt b/config/telink/chip-module/CMakeLists.txt index 3e91af6b4145c8..9afb00b6269e83 100644 --- a/config/telink/chip-module/CMakeLists.txt +++ b/config/telink/chip-module/CMakeLists.txt @@ -196,7 +196,6 @@ chip_gn_arg_bool ("is_debug" CONFIG_DEBUG) chip_gn_arg_bool ("chip_enable_openthread" CONFIG_NET_L2_OPENTHREAD) chip_gn_arg_bool ("chip_inet_config_enable_ipv4" CONFIG_NET_IPV4) chip_gn_arg_bool ("chip_build_tests" CONFIG_CHIP_BUILD_TESTS) -chip_gn_arg_bool ("chip_inet_config_enable_raw_endpoint" CONFIG_CHIP_BUILD_TESTS) chip_gn_arg_bool ("chip_inet_config_enable_tcp_endpoint" CONFIG_CHIP_BUILD_TESTS) chip_gn_arg_bool ("chip_inet_config_enable_dns_resolver" CONFIG_CHIP_BUILD_TESTS) chip_gn_arg_bool ("chip_build_libshell" CONFIG_CHIP_LIB_SHELL) diff --git a/examples/platform/k32w/app/args.gni b/examples/platform/k32w/app/args.gni index 19b7d20a1cf122..5728bf319f542a 100644 --- a/examples/platform/k32w/app/args.gni +++ b/examples/platform/k32w/app/args.gni @@ -28,5 +28,4 @@ chip_inet_project_config_include = "" chip_system_project_config_include = "" chip_system_config_provide_statistics = false -chip_inet_config_enable_raw_endpoint = false chip_with_nlfaultinjection = true diff --git a/examples/platform/k32w/args.gni b/examples/platform/k32w/args.gni index 79a0f50c3f926e..26465096ca5d97 100644 --- a/examples/platform/k32w/args.gni +++ b/examples/platform/k32w/args.gni @@ -30,5 +30,4 @@ chip_inet_project_config_include = "" chip_system_project_config_include = "" chip_system_config_provide_statistics = false -chip_inet_config_enable_raw_endpoint = false chip_with_nlfaultinjection = true diff --git a/src/inet/BUILD.gn b/src/inet/BUILD.gn index 811ac5d5c5fb96..f432dc48c4ec52 100644 --- a/src/inet/BUILD.gn +++ b/src/inet/BUILD.gn @@ -38,7 +38,6 @@ buildconfig_header("inet_buildconfig") { "INET_CONFIG_ENABLE_IPV4=${chip_inet_config_enable_ipv4}", "INET_CONFIG_ENABLE_DNS_RESOLVER=${chip_inet_config_enable_dns_resolver}", "INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS=${chip_inet_config_enable_async_dns_sockets}", - "INET_CONFIG_ENABLE_RAW_ENDPOINT=${chip_inet_config_enable_raw_endpoint}", "INET_CONFIG_ENABLE_TCP_ENDPOINT=${chip_inet_config_enable_tcp_endpoint}", "INET_CONFIG_ENABLE_UDP_ENDPOINT=${chip_inet_config_enable_udp_endpoint}", "HAVE_LWIP_RAW_BIND_NETIF=true", @@ -107,13 +106,6 @@ static_library("inet") { public_deps += [ "${chip_root}/src/lwip" ] } - if (chip_inet_config_enable_raw_endpoint) { - sources += [ - "RawEndPoint.cpp", - "RawEndPoint.h", - ] - } - if (chip_inet_config_enable_tcp_endpoint) { sources += [ "TCPEndPoint.cpp", diff --git a/src/inet/EndPointBasis.h b/src/inet/EndPointBasis.h index 0f8a4148bd344d..31ed82ca41d2d9 100644 --- a/src/inet/EndPointBasis.h +++ b/src/inet/EndPointBasis.h @@ -44,9 +44,6 @@ //--- Declaration of LWIP protocol control buffer structure names #if CHIP_SYSTEM_CONFIG_USE_LWIP -#if INET_CONFIG_ENABLE_RAW_ENDPOINT -struct raw_pcb; -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT #if INET_CONFIG_ENABLE_UDP_ENDPOINT struct udp_pcb; #endif // INET_CONFIG_ENABLE_UDP_ENDPOINT @@ -107,9 +104,6 @@ class DLL_EXPORT EndPointBasis : public InetLayerBasis union { const void * mVoid; /**< An untyped protocol control buffer reference */ -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - raw_pcb * mRaw; /**< Raw network interface protocol control */ -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT #if INET_CONFIG_ENABLE_UDP_ENDPOINT udp_pcb * mUDP; /**< User datagram protocol (UDP) control */ #endif // INET_CONFIG_ENABLE_UDP_ENDPOINT diff --git a/src/inet/IPEndPointBasis.cpp b/src/inet/IPEndPointBasis.cpp index 7ebecf1c1f2b13..fdb47db8976ef7 100644 --- a/src/inet/IPEndPointBasis.cpp +++ b/src/inet/IPEndPointBasis.cpp @@ -344,12 +344,6 @@ CHIP_ERROR IPEndPointBasis::SetMulticastLoopback(IPVersion aIPVersion, bool aLoo switch (mLwIPEndPointType) { -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - case kLwIPEndPointType_Raw: - raw_set_flags(mRaw, RAW_FLAGS_MULTICAST_LOOP); - break; -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - #if INET_CONFIG_ENABLE_UDP_ENDPOINT case kLwIPEndPointType_UDP: udp_set_flags(mUDP, UDP_FLAGS_MULTICAST_LOOP); @@ -366,12 +360,6 @@ CHIP_ERROR IPEndPointBasis::SetMulticastLoopback(IPVersion aIPVersion, bool aLoo switch (mLwIPEndPointType) { -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - case kLwIPEndPointType_Raw: - raw_clear_flags(mRaw, RAW_FLAGS_MULTICAST_LOOP); - break; -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - #if INET_CONFIG_ENABLE_UDP_ENDPOINT case kLwIPEndPointType_UDP: udp_clear_flags(mUDP, UDP_FLAGS_MULTICAST_LOOP); diff --git a/src/inet/Inet.h b/src/inet/Inet.h index 84566fd0c91ce1..60eae475acf536 100644 --- a/src/inet/Inet.h +++ b/src/inet/Inet.h @@ -38,10 +38,6 @@ #include #endif // INET_CONFIG_ENABLE_DNS_RESOLVER -#if INET_CONFIG_ENABLE_RAW_ENDPOINT -#include -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - #if INET_CONFIG_ENABLE_TCP_ENDPOINT #include #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT diff --git a/src/inet/InetConfig.h b/src/inet/InetConfig.h index 00fdcdbad94299..32f0a132480f35 100644 --- a/src/inet/InetConfig.h +++ b/src/inet/InetConfig.h @@ -153,21 +153,6 @@ #define INET_CONFIG_MAX_DROPPABLE_EVENTS 0 #endif // INET_CONFIG_MAX_DROPPABLE_EVENTS -/** - * @def INET_CONFIG_NUM_RAW_ENDPOINTS - * - * @brief - * This is the total number of "raw" (direct-IP, non-TCP/-UDP) end - * point context structures. - * - * Up to this many outstanding "raw" communication flows may be in - * use. - * - */ -#ifndef INET_CONFIG_NUM_RAW_ENDPOINTS -#define INET_CONFIG_NUM_RAW_ENDPOINTS 8 -#endif // INET_CONFIG_NUM_RAW_ENDPOINTS - /** * @def INET_CONFIG_NUM_TCP_ENDPOINTS * @@ -246,18 +231,6 @@ #define INET_CONFIG_ENABLE_DNS_RESOLVER 0 #endif // INET_CONFIG_ENABLE_DNS_RESOLVER -/** - * @def INET_CONFIG_ENABLE_RAW_ENDPOINT - * - * @brief - * Defines whether (1) or not (0) to enable the ability - * to instantiate a Raw endpoint. - * - */ -#ifndef INET_CONFIG_ENABLE_RAW_ENDPOINT -#define INET_CONFIG_ENABLE_RAW_ENDPOINT 0 -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - /** * @def INET_CONFIG_ENABLE_TCP_ENDPOINT * diff --git a/src/inet/InetLayer.cpp b/src/inet/InetLayer.cpp index a449372b4ea23d..0f3c1980aefac5 100644 --- a/src/inet/InetLayer.cpp +++ b/src/inet/InetLayer.cpp @@ -93,10 +93,6 @@ void InetLayer::UpdateSnapshot(chip::System::Stats::Snapshot & aSnapshot) UDPEndPoint::sPool.GetStatistics(aSnapshot.mResourcesInUse[chip::System::Stats::kInetLayer_NumUDPEps], aSnapshot.mHighWatermarks[chip::System::Stats::kInetLayer_NumUDPEps]); #endif // INET_CONFIG_ENABLE_UDP_ENDPOINT -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - RawEndPoint::sPool.GetStatistics(aSnapshot.mResourcesInUse[chip::System::Stats::kInetLayer_NumRawEps], - aSnapshot.mHighWatermarks[chip::System::Stats::kInetLayer_NumRawEps]); -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT } /** @@ -332,17 +328,6 @@ CHIP_ERROR InetLayer::Shutdown() #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS #endif // INET_CONFIG_ENABLE_DNS_RESOLVER -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - // Close all raw endpoints owned by this Inet layer instance. - RawEndPoint::sPool.ForEachActiveObject([&](RawEndPoint * lEndPoint) { - if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this)) - { - lEndPoint->Close(); - } - return true; - }); -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - #if INET_CONFIG_ENABLE_TCP_ENDPOINT // Abort all TCP endpoints owned by this instance. TCPEndPoint::sPool.ForEachActiveObject([&](TCPEndPoint * lEndPoint) { @@ -502,50 +487,6 @@ CHIP_ERROR InetLayer::GetLinkLocalAddr(InterfaceId link, IPAddress * llAddr) return CHIP_NO_ERROR; } -#if INET_CONFIG_ENABLE_RAW_ENDPOINT -/** - * Creates a new RawEndPoint object for a specific IP version and protocol. - * - * @note - * This function gets a free RawEndPoint object from a pre-allocated pool - * and also calls the explicit initializer on the new object. - * - * @param[in] ipVer IPv4 or IPv6. - * - * @param[in] ipProto A protocol within the IP family (e.g., ICMPv4 or ICMPv6). - * - * @param[in,out] retEndPoint A pointer to a pointer of the RawEndPoint object that is - * a return parameter upon completion of the object creation. - * *retEndPoint is NULL if creation fails. - * - * @retval #CHIP_ERROR_INCORRECT_STATE If the InetLayer object is not initialized. - * @retval #CHIP_ERROR_ENDPOINT_POOL_FULL If the InetLayer RawEndPoint pool is full and no new - * endpoints can be created. - * @retval #CHIP_NO_ERROR On success. - * - */ -CHIP_ERROR InetLayer::NewRawEndPoint(IPVersion ipVer, IPProtocol ipProto, RawEndPoint ** retEndPoint) -{ - assertChipStackLockedByCurrentThread(); - - *retEndPoint = nullptr; - - VerifyOrReturnError(State == kState_Initialized, CHIP_ERROR_INCORRECT_STATE); - - *retEndPoint = RawEndPoint::sPool.TryCreate(); - if (*retEndPoint == nullptr) - { - ChipLogError(Inet, "%s endpoint pool FULL", "Raw"); - return CHIP_ERROR_ENDPOINT_POOL_FULL; - } - - (*retEndPoint)->Inet::RawEndPoint::Init(this, ipVer, ipProto); - SYSTEM_STATS_INCREMENT(chip::System::Stats::kInetLayer_NumRawEps); - - return CHIP_NO_ERROR; -} -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - #if INET_CONFIG_ENABLE_TCP_ENDPOINT /** * Creates a new TCPEndPoint object. @@ -1035,13 +976,6 @@ CHIP_ERROR InetLayer::HandleInetLayerEvent(chip::System::Object & aTarget, chip: break; #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - case kInetEvent_RawDataReceived: - static_cast(aTarget).HandleDataReceived( - System::PacketBufferHandle::Adopt(reinterpret_cast(aArgument))); - break; -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - #if INET_CONFIG_ENABLE_UDP_ENDPOINT case kInetEvent_UDPDataReceived: static_cast(aTarget).HandleDataReceived( diff --git a/src/inet/InetLayer.h b/src/inet/InetLayer.h index 1e39068eeaf34e..35f6adf00dd644 100644 --- a/src/inet/InetLayer.h +++ b/src/inet/InetLayer.h @@ -61,10 +61,6 @@ #include #endif // INET_CONFIG_ENABLE_DNS_RESOLVER -#if INET_CONFIG_ENABLE_RAW_ENDPOINT -#include -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - #if INET_CONFIG_ENABLE_TCP_ENDPOINT #include #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT @@ -149,10 +145,6 @@ class DLL_EXPORT InetLayer friend class DNSResolver; #endif // INET_CONFIG_ENABLE_DNS_RESOLVER -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - friend class RawEndPoint; -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - #if INET_CONFIG_ENABLE_TCP_ENDPOINT friend class TCPEndPoint; #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT @@ -189,10 +181,6 @@ class DLL_EXPORT InetLayer // End Points -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - CHIP_ERROR NewRawEndPoint(IPVersion ipVer, IPProtocol ipProto, RawEndPoint ** retEndPoint); -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - #if INET_CONFIG_ENABLE_TCP_ENDPOINT CHIP_ERROR NewTCPEndPoint(TCPEndPoint ** retEndPoint); #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT @@ -253,9 +241,6 @@ class DLL_EXPORT InetLayer #if INET_CONFIG_ENABLE_UDP_ENDPOINT type == kInetEvent_UDPDataReceived || #endif // INET_CONFIG_ENABLE_UDP_ENDPOINT -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - type == kInetEvent_RawDataReceived || -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT false; } diff --git a/src/inet/RawEndPoint.cpp b/src/inet/RawEndPoint.cpp deleted file mode 100644 index 69863b34de910e..00000000000000 --- a/src/inet/RawEndPoint.cpp +++ /dev/null @@ -1,1044 +0,0 @@ -/* - * - * Copyright (c) 2020-2021 Project CHIP Authors - * Copyright (c) 2018 Google LLC. - * Copyright (c) 2013-2018 Nest Labs, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * This file implements the Inet::RawEndPoint class, - * where the CHIP Inet Layer encapsulates methods for interacting - * interacting with IP network endpoints (SOCK_RAW sockets - * on Linux and BSD-derived systems) or LwIP raw protocol - * control blocks, as the system is configured accordingly. - * - */ - -#define __APPLE_USE_RFC_3542 - -#include "RawEndPoint.h" - -#include "InetFaultInjection.h" -#include - -#include -#include -#include - -#if CHIP_SYSTEM_CONFIG_USE_LWIP -#include -#include -#include -#if CHIP_HAVE_CONFIG_H -#include // nogncheck -#endif // CHIP_HAVE_CONFIG_H -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS -#if HAVE_SYS_SOCKET_H -#include -#endif // HAVE_SYS_SOCKET_H -#include -#include -#include -#include -#if HAVE_NETINET_ICMP6_H -#include -#endif // HAVE_NETINET_ICMP6_H -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS - -// SOCK_CLOEXEC not defined on all platforms, e.g. iOS/macOS: -#ifdef SOCK_CLOEXEC -#define SOCK_FLAGS SOCK_CLOEXEC -#else -#define SOCK_FLAGS 0 -#endif - -#include -#include - -namespace chip { -namespace Inet { - -chip::System::ObjectPool RawEndPoint::sPool; - -#if CHIP_SYSTEM_CONFIG_USE_LWIP -/* - * Note that for LwIP InterfaceId is already defined to be 'struct - * netif'; consequently, some of the checking performed here could - * conceivably be optimized out and the HAVE_LWIP_UDP_BIND_NETIF case - * could simply be: - * - * udp_bind_netif(aUDP, intfId); - * - */ -static CHIP_ERROR LwIPBindInterface(struct raw_pcb * aRaw, InterfaceId intfId) -{ - CHIP_ERROR res = CHIP_NO_ERROR; - -#if HAVE_LWIP_RAW_BIND_NETIF - if (!IsInterfaceIdPresent(intfId)) - raw_bind_netif(aRaw, NULL); - else - { - struct netif * netifp = IPEndPointBasis::FindNetifFromInterfaceId(intfId); - - if (netifp == NULL) - res = INET_ERROR_UNKNOWN_INTERFACE; - else - raw_bind_netif(aRaw, netifp); - } -#else - if (!IsInterfaceIdPresent(intfId)) - aRaw->intf_filter = NULL; - else - { - struct netif * netifp = IPEndPointBasis::FindNetifFromInterfaceId(intfId); - - if (netifp == NULL) - res = INET_ERROR_UNKNOWN_INTERFACE; - else - aRaw->intf_filter = netifp; - } -#endif // HAVE_LWIP_RAW_BIND_NETIF - - return res; -} -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -/** - * @brief Bind the endpoint to an interface IP address. - * - * @param[in] addrType the protocol version of the IP address - * @param[in] addr the IP address (must be an interface address) - * @param[in] intfId an optional network interface indicator - * - * @retval CHIP_NO_ERROR success: endpoint bound to address - * @retval CHIP_ERROR_INCORRECT_STATE endpoint has been bound previously - * @retval CHIP_ERROR_NO_MEMORY insufficient memory for endpoint - * - * @retval INET_ERROR_UNKNOWN_INTERFACE - * On some platforms, the optionally specified interface is not - * present. - * - * @retval INET_ERROR_WRONG_PROTOCOL_TYPE - * \c addrType does not match \c IPVer. - * - * @retval INET_ERROR_WRONG_ADDRESS_TYPE - * \c addrType is \c kIPAddressType_Any, or the type of \c addr is not - * equal to \c addrType. - * - * @retval other another system or platform error - * - * @details - * Binds the endpoint to the specified network interface IP address. - * - * On LwIP, this method must not be called with the LwIP stack lock - * already acquired. - */ -CHIP_ERROR RawEndPoint::Bind(IPAddressType addrType, const IPAddress & addr, InterfaceId intfId) -{ - if (mState != kState_Ready && mState != kState_Bound) - { - return CHIP_ERROR_INCORRECT_STATE; - } - - if ((addr != IPAddress::Any) && (addr.Type() != kIPAddressType_Any) && (addr.Type() != addrType)) - { - return INET_ERROR_WRONG_ADDRESS_TYPE; - } - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - - // Lock LwIP stack - LOCK_TCPIP_CORE(); - - // Make sure we have the appropriate type of PCB. - CHIP_ERROR res = GetPCB(addrType); - - // Bind the PCB to the specified address. - if (res == CHIP_NO_ERROR) - { -#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5 - ip_addr_t ipAddr = addr.ToLwIPAddr(); -#if INET_CONFIG_ENABLE_IPV4 - lwip_ip_addr_type lType = IPAddress::ToLwIPAddrType(addrType); - IP_SET_TYPE_VAL(ipAddr, lType); -#endif // INET_CONFIG_ENABLE_IPV4 - res = chip::System::MapErrorLwIP(raw_bind(mRaw, &ipAddr)); -#else // LWIP_VERSION_MAJOR <= 1 && LWIP_VERSION_MINOR < 5 - if (addrType == kIPAddressType_IPv6) - { - ip6_addr_t ipv6Addr = addr.ToIPv6(); - res = chip::System::MapErrorLwIP(raw_bind_ip6(mRaw, &ipv6Addr)); - } -#if INET_CONFIG_ENABLE_IPV4 - else if (addrType == kIPAddressType_IPv4) - { - ip4_addr_t ipv4Addr = addr.ToIPv4(); - res = chip::System::MapErrorLwIP(raw_bind(mRaw, &ipv4Addr)); - } -#endif // INET_CONFIG_ENABLE_IPV4 - else - res = INET_ERROR_WRONG_ADDRESS_TYPE; -#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5 - } - - if (res == CHIP_NO_ERROR) - { - res = LwIPBindInterface(mRaw, intfId); - } - - // Unlock LwIP stack - UNLOCK_TCPIP_CORE(); - - ReturnErrorOnFailure(res); - -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS - // Make sure we have the appropriate type of socket. - ReturnErrorOnFailure(GetSocket(addrType)); - ReturnErrorOnFailure(IPEndPointBasis::Bind(addrType, addr, 0, intfId)); - -#if CHIP_SYSTEM_CONFIG_USE_DISPATCH - dispatch_queue_t dispatchQueue = static_cast(Layer().SystemLayer())->GetDispatchQueue(); - if (dispatchQueue != nullptr) - { - unsigned long fd = static_cast(mSocket); - - mReadableSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, fd, 0, dispatchQueue); - ReturnErrorCodeIf(mReadableSource == nullptr, CHIP_ERROR_NO_MEMORY); - - dispatch_source_set_event_handler(mReadableSource, ^{ - this->HandlePendingIO(System::SocketEventFlags::kRead); - }); - - dispatch_resume(mReadableSource); - } -#endif // CHIP_SYSTEM_CONFIG_USE_DISPATCH - - mBoundIntfId = intfId; -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS - - mState = kState_Bound; - - return CHIP_NO_ERROR; -} - -/** - * Bind the raw endpoint to an IPv6 link-local scope address at the specified - * interface index. Also sets various IPv6 socket options appropriate for - * transmitting packets to and from on-link destinations. - * - * @param[in] intfId An InterfaceId to identify the scope of the address. - * @param[in] addr An IPv6 link-local scope IPAddress object. - * - * @retval CHIP_NO_ERROR success: endpoint bound to address - * @retval CHIP_ERROR_INCORRECT_STATE endpoint has been bound previously - * @retval CHIP_ERROR_NO_MEMORY insufficient memory for endpoint - * - * @retval INET_ERROR_WRONG_PROTOCOL_TYPE - * \c addrType does not match \c IPVer. - * - * @retval INET_ERROR_WRONG_ADDRESS_TYPE - * \c addr is not an IPv6 link-local address or \c intfId is - * \c INET_NULL_INTERFACEID. - * - * @retval other another system or platform error - * - * @details - * Binds the endpoint to the IPv6 link-local address \c addr on the - * network interface indicated by \c intfId. - * - * On LwIP, this method must not be called with the LwIP stack lock - * already acquired. - */ -CHIP_ERROR RawEndPoint::BindIPv6LinkLocal(InterfaceId intfId, const IPAddress & addr) -{ - CHIP_ERROR res = CHIP_NO_ERROR; - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS - const int lIfIndex = static_cast(intfId); -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS - - if (mState != kState_Ready && mState != kState_Bound) - { - res = CHIP_ERROR_INCORRECT_STATE; - goto ret; - } - - if (!addr.IsIPv6LinkLocal()) - { - res = INET_ERROR_WRONG_ADDRESS_TYPE; - goto ret; - } - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - - // Lock LwIP stack - LOCK_TCPIP_CORE(); - - // Make sure we have the appropriate type of PCB. - res = GetPCB(addr.Type()); - - // Bind the PCB to the specified address. - if (res == CHIP_NO_ERROR) - { -#if LWIP_VERSION_MAJOR > 1 - ip_addr_t ipAddr = addr.ToLwIPAddr(); - res = chip::System::MapErrorLwIP(raw_bind(mRaw, &ipAddr)); -#else // LWIP_VERSION_MAJOR <= 1 - ip6_addr_t ipv6Addr = addr.ToIPv6(); - res = chip::System::MapErrorLwIP(raw_bind_ip6(mRaw, &ipv6Addr)); -#endif // LWIP_VERSION_MAJOR <= 1 - - if (res != CHIP_NO_ERROR) - { - raw_remove(mRaw); - mRaw = NULL; - mLwIPEndPointType = kLwIPEndPointType_Unknown; - } - } - - // Unlock LwIP stack - UNLOCK_TCPIP_CORE(); - -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS - - static const int sInt255 = 255; - - // Make sure we have the appropriate type of socket. - res = GetSocket(kIPAddressType_IPv6); - if (res != CHIP_NO_ERROR) - { - goto ret; - } - - if (::setsockopt(mSocket, IPPROTO_IPV6, IPV6_MULTICAST_IF, &lIfIndex, sizeof(lIfIndex)) != 0) - { - goto optfail; - } - - if (::setsockopt(mSocket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &sInt255, sizeof(sInt255)) != 0) - { - goto optfail; - } - - if (::setsockopt(mSocket, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &sInt255, sizeof(sInt255)) != 0) - { - goto optfail; - } - - mAddrType = kIPAddressType_IPv6; - goto ret; - -optfail: - res = chip::System::MapErrorPOSIX(errno); - static_cast(Layer().SystemLayer())->StopWatchingSocket(&mWatch); - close(mSocket); - mSocket = INET_INVALID_SOCKET_FD; - mAddrType = kIPAddressType_Unknown; - -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS - -ret: - if (res == CHIP_NO_ERROR) - { - mState = kState_Bound; - } - - return res; -} - -/** - * @brief Prepare the endpoint to receive ICMP messages. - * - * @param[in] onMessageReceived The endpoint's message reception event handling function delegate. - * @param[in] onReceiveError The endpoint's receive error event handling function delegate. - * @param[in] appState Application state pointer. - * - * @retval CHIP_NO_ERROR always returned. - * - * @details - * If \c mState is already \c kState_Listening, then no operation is - * performed, otherwise the \c mState is set to \c kState_Listening and - * the endpoint is prepared to received ICMPv6 messages, according to the - * semantics of the platform. - * - * On LwIP, this method must not be called with the LwIP stack lock - * already acquired - */ -CHIP_ERROR RawEndPoint::Listen(IPEndPointBasis::OnMessageReceivedFunct onMessageReceived, - IPEndPointBasis::OnReceiveErrorFunct onReceiveError, void * appState) -{ - if (mState == kState_Listening) - { - return CHIP_NO_ERROR; - } - - if (mState != kState_Bound) - { - return CHIP_ERROR_INCORRECT_STATE; - } - - OnMessageReceived = onMessageReceived; - OnReceiveError = onReceiveError; - AppState = appState; - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - - // Lock LwIP stack - LOCK_TCPIP_CORE(); - -#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5 - raw_recv(mRaw, LwIPReceiveRawMessage, this); -#else // LWIP_VERSION_MAJOR <= 1 && LWIP_VERSION_MINOR < 5 - if (PCB_ISIPV6(mRaw)) - raw_recv_ip6(mRaw, LwIPReceiveRawMessage, this); - else - raw_recv(mRaw, LwIPReceiveRawMessage, this); -#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5 - - // Unlock LwIP stack - UNLOCK_TCPIP_CORE(); - -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - - mState = kState_Listening; - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS - // Wait for ability to read on this endpoint. - auto layer = static_cast(Layer().SystemLayer()); - ReturnErrorOnFailure(layer->SetCallback(mWatch, HandlePendingIO, reinterpret_cast(this))); - ReturnErrorOnFailure(layer->RequestCallbackOnPendingRead(mWatch)); -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS - - return CHIP_NO_ERROR; -} - -/** - * @brief Close the endpoint. - * - * @details - * If mState != kState_Closed, then closes the endpoint, removing - * it from the set of endpoints eligible for communication events. - * - * On LwIP systems, this method must not be called with the LwIP stack - * lock already acquired. - */ -void RawEndPoint::Close() -{ - if (mState != kState_Closed) - { -#if CHIP_SYSTEM_CONFIG_USE_LWIP - - // Lock LwIP stack - LOCK_TCPIP_CORE(); - - // Since Raw PCB is released synchronously here, but Raw endpoint itself might have to wait - // for destruction asynchronously, there could be more allocated Raw endpoints than Raw PCBs. - if (mRaw != NULL) - { - raw_remove(mRaw); - mRaw = NULL; - mLwIPEndPointType = kLwIPEndPointType_Unknown; - } - - // Unlock LwIP stack - UNLOCK_TCPIP_CORE(); - -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS - if (mSocket != INET_INVALID_SOCKET_FD) - { - static_cast(Layer().SystemLayer())->StopWatchingSocket(&mWatch); - close(mSocket); - mSocket = INET_INVALID_SOCKET_FD; - } - -#if CHIP_SYSTEM_CONFIG_USE_DISPATCH - if (mReadableSource) - { - dispatch_source_cancel(mReadableSource); - dispatch_release(mReadableSource); - } -#endif // CHIP_SYSTEM_CONFIG_USE_DISPATCH -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS - - mState = kState_Closed; - } -} - -/** - * @brief Close the endpoint and recycle its memory. - * - * @details - * Invokes the \c Close method, then invokes the - * InetLayerBasis::Release method to return the object to its - * memory pool. - * - * On LwIP systems, this method must not be called with the LwIP stack - * lock already acquired. - */ -void RawEndPoint::Free() -{ - Close(); - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - DeferredFree(kReleaseDeferralErrorTactic_Die); -#else // !CHIP_SYSTEM_CONFIG_USE_LWIP - Release(); -#endif // !CHIP_SYSTEM_CONFIG_USE_LWIP -} - -/** - * A synonym for SendTo(addr, INET_NULL_INTERFACEID, msg, - * sendFlags). - */ -CHIP_ERROR RawEndPoint::SendTo(const IPAddress & addr, chip::System::PacketBufferHandle && msg, uint16_t sendFlags) -{ - return SendTo(addr, INET_NULL_INTERFACEID, std::move(msg), sendFlags); -} - -/** - * @brief Send an ICMP message to the specified destination address. - * - * @param[in] addr the destination IP address - * @param[in] intfId an optional network interface indicator - * @param[in] msg the packet buffer containing the UDP message - * @param[in] sendFlags optional transmit option flags - * - * @retval CHIP_NO_ERROR - * success: \c msg is queued for transmit. - * - * @retval CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE - * the system does not support the requested operation. - * - * @retval INET_ERROR_WRONG_ADDRESS_TYPE - * the destination address and the bound interface address do not - * have matching protocol versions or address type. - * - * @retval CHIP_ERROR_MESSAGE_TOO_LONG - * \c msg does not contain the whole ICMP message. - * - * @retval CHIP_ERROR_OUTBOUND_MESSAGE_TOO_BIG - * On some platforms, only a truncated portion of \c msg was queued - * for transmit. - * - * @retval other another system or platform error - * - * @details - * Send the ICMP message in \c msg to the destination given in \c addr. - */ -CHIP_ERROR RawEndPoint::SendTo(const IPAddress & addr, InterfaceId intfId, chip::System::PacketBufferHandle && msg, - uint16_t sendFlags) -{ - IPPacketInfo pktInfo; - pktInfo.Clear(); - pktInfo.DestAddress = addr; - pktInfo.Interface = intfId; - return SendMsg(&pktInfo, std::move(msg), sendFlags); -} - -/** - * @brief Send an ICMP message to the specified destination. - * - * @param[in] pktInfo destination information for the message - * @param[in] msg the packet buffer containing the UDP message - * @param[in] sendFlags optional transmit option flags - * - * @retval CHIP_NO_ERROR - * success: \c msg is queued for transmit. - * - * @retval CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE - * the system does not support the requested operation. - * - * @retval INET_ERROR_WRONG_ADDRESS_TYPE - * the destination address and the bound interface address do not - * have matching protocol versions or address type. - * - * @retval CHIP_ERROR_MESSAGE_TOO_LONG - * \c msg does not contain the whole ICMP message. - * - * @retval CHIP_ERROR_OUTBOUND_MESSAGE_TOO_BIG - * On some platforms, only a truncated portion of \c msg was queued - * for transmit. - * - * @retval other another system or platform error - * - * @details - * Send the ICMP message \c msg using the destination information given in \c addr. - */ -CHIP_ERROR RawEndPoint::SendMsg(const IPPacketInfo * pktInfo, chip::System::PacketBufferHandle && msg, uint16_t sendFlags) -{ - CHIP_ERROR res = CHIP_NO_ERROR; - const IPAddress & addr = pktInfo->DestAddress; - - INET_FAULT_INJECT(FaultInjection::kFault_Send, return INET_ERROR_UNKNOWN_INTERFACE;); - INET_FAULT_INJECT(FaultInjection::kFault_SendNonCritical, return CHIP_ERROR_NO_MEMORY;); - - // Do not allow sending an IPv4 address on an IPv6 end point and - // vice versa. - - if (IPVer == kIPVersion_6 && addr.Type() != kIPAddressType_IPv6) - { - return INET_ERROR_WRONG_ADDRESS_TYPE; - } -#if INET_CONFIG_ENABLE_IPV4 - if (IPVer == kIPVersion_4 && addr.Type() != kIPAddressType_IPv4) - { - return INET_ERROR_WRONG_ADDRESS_TYPE; - } -#endif // INET_CONFIG_ENABLE_IPV4 - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - - // Lock LwIP stack - LOCK_TCPIP_CORE(); - - // Make sure we have the appropriate type of PCB based on the destination address. - res = GetPCB(addr.Type()); - SuccessOrExit(res); - - // Send the message to the specified address/port. - { - err_t lwipErr = ERR_VAL; - -#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5 - ip_addr_t ipAddr = addr.ToLwIPAddr(); - - lwipErr = raw_sendto(mRaw, System::LwIPPacketBufferView::UnsafeGetLwIPpbuf(msg), &ipAddr); -#else // LWIP_VERSION_MAJOR <= 1 && LWIP_VERSION_MINOR < 5 - if (PCB_ISIPV6(mRaw)) - { - ip6_addr_t ipv6Addr = addr.ToIPv6(); - - lwipErr = raw_sendto_ip6(mRaw, System::LwIPPacketBufferView::UnsafeGetLwIPpbuf(msg), &ipv6Addr); - } -#if INET_CONFIG_ENABLE_IPV4 - else - { - ip4_addr_t ipv4Addr = addr.ToIPv4(); - - lwipErr = raw_sendto(mRaw, System::LwIPPacketBufferView::UnsafeGetLwIPpbuf(msg), &ipv4Addr); - } -#endif // INET_CONFIG_ENABLE_IPV4 -#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5 - - if (lwipErr != ERR_OK) - res = chip::System::MapErrorLwIP(lwipErr); - } - - // Unlock LwIP stack - UNLOCK_TCPIP_CORE(); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS - // Make sure we have the appropriate type of socket based on the - // destination address. - - res = GetSocket(addr.Type()); - SuccessOrExit(res); - - res = IPEndPointBasis::SendMsg(pktInfo, std::move(msg), sendFlags); -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS - -exit: - CHIP_SYSTEM_FAULT_INJECT_ASYNC_EVENT(); - - return res; -} - -/** - * @brief Set the ICMP6 filter parameters in the network stack. - * - * @param[in] numICMPTypes length of array at \c aICMPTypes - * @param[in] aICMPTypes the set of ICMPv6 type codes to filter. - * - * @retval CHIP_NO_ERROR success: filter parameters set - * @retval CHIP_ERROR_NOT_IMPLEMENTED system does not implement - * @retval INET_ERROR_WRONG_ADDRESS_TYPE endpoint not IPv6 type - * @retval INET_ERROR_WRONG_PROTOCOL_TYPE endpoint not ICMP6 type - * - * @retval other another system or platform error - * - * @details - * Apply the ICMPv6 filtering parameters for the codes in \c aICMPTypes to - * the underlying endpoint in the system networking stack. - */ -CHIP_ERROR RawEndPoint::SetICMPFilter(uint8_t numICMPTypes, const uint8_t * aICMPTypes) -{ -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS -#if !(HAVE_NETINET_ICMP6_H && HAVE_ICMP6_FILTER) - return CHIP_ERROR_NOT_IMPLEMENTED; -#endif //!(HAVE_NETINET_ICMP6_H && HAVE_ICMP6_FILTER) -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS - - VerifyOrReturnError(IPVer == kIPVersion_6, INET_ERROR_WRONG_ADDRESS_TYPE); - VerifyOrReturnError(IPProto == kIPProtocol_ICMPv6, INET_ERROR_WRONG_PROTOCOL_TYPE); - VerifyOrReturnError((numICMPTypes == 0 && aICMPTypes == nullptr) || (numICMPTypes != 0 && aICMPTypes != nullptr), - CHIP_ERROR_INVALID_ARGUMENT); - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - LOCK_TCPIP_CORE(); - NumICMPTypes = numICMPTypes; - ICMPTypes = aICMPTypes; - UNLOCK_TCPIP_CORE(); -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS -#if HAVE_NETINET_ICMP6_H && HAVE_ICMP6_FILTER - struct icmp6_filter filter; - if (numICMPTypes > 0) - { - ICMP6_FILTER_SETBLOCKALL(&filter); - for (int j = 0; j < numICMPTypes; ++j) - { - ICMP6_FILTER_SETPASS(aICMPTypes[j], &filter); - } - } - else - { - ICMP6_FILTER_SETPASSALL(&filter); - } - if (setsockopt(mSocket, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(filter)) == -1) - { - return chip::System::MapErrorPOSIX(errno); - } -#endif // HAVE_NETINET_ICMP6_H && HAVE_ICMP6_FILTER -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS - - return CHIP_NO_ERROR; -} - -/** - * @brief Bind the endpoint to a network interface. - * - * @param[in] addrType the protocol version of the IP address. - * - * @param[in] intfId indicator of the network interface. - * - * @retval CHIP_NO_ERROR success: endpoint bound to address - * @retval CHIP_ERROR_NO_MEMORY insufficient memory for endpoint - * @retval CHIP_ERROR_NOT_IMPLEMENTED system implementation not complete. - * - * @retval INET_ERROR_UNKNOWN_INTERFACE - * On some platforms, the interface is not present. - * - * @retval other another system or platform error - * - * @details - * Binds the endpoint to the specified network interface IP address. - * - * On LwIP, this method must not be called with the LwIP stack lock - * already acquired. - */ -CHIP_ERROR RawEndPoint::BindInterface(IPAddressType addrType, InterfaceId intfId) -{ - // A lock is required because the LwIP thread may be referring to intf_filter, - // while this code running in the Inet application is potentially modifying it. - // NOTE: this only supports LwIP interfaces whose number is no bigger than 9. - - if (mState != kState_Ready && mState != kState_Bound) - { - return CHIP_ERROR_INCORRECT_STATE; - } - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - LOCK_TCPIP_CORE(); - - // Make sure we have the appropriate type of PCB. - CHIP_ERROR err = GetPCB(addrType); - - if (err == CHIP_NO_ERROR) - { - err = LwIPBindInterface(mRaw, intfId); - } - - UNLOCK_TCPIP_CORE(); - - ReturnErrorOnFailure(err); - -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS - // Make sure we have the appropriate type of socket. - ReturnErrorOnFailure(GetSocket(addrType)); - ReturnErrorOnFailure(IPEndPointBasis::BindInterface(addrType, intfId)); -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS - - mState = kState_Bound; - - return CHIP_NO_ERROR; -} - -void RawEndPoint::Init(InetLayer * inetLayer, IPVersion ipVer, IPProtocol ipProto) -{ - IPEndPointBasis::Init(inetLayer); - - IPVer = ipVer; - IPProto = ipProto; -} - -/** - * Get the bound interface on this endpoint. - * - * @return InterfaceId The bound interface id. - */ -InterfaceId RawEndPoint::GetBoundInterface() -{ -#if CHIP_SYSTEM_CONFIG_USE_LWIP -#if HAVE_LWIP_RAW_BIND_NETIF - return netif_get_by_index(mRaw->netif_idx); -#else - return mRaw->intf_filter; -#endif -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS - return mBoundIntfId; -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS -} - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - -void RawEndPoint::HandleDataReceived(System::PacketBufferHandle && msg) -{ - IPEndPointBasis::HandleDataReceived(std::move(msg)); -} - -CHIP_ERROR RawEndPoint::GetPCB(IPAddressType addrType) -{ - // IMPORTANT: This method MUST be called with the LwIP stack LOCKED! - -#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5 - if (mRaw == nullptr) - { - switch (addrType) - { - case kIPAddressType_IPv6: -#if INET_CONFIG_ENABLE_IPV4 - case kIPAddressType_IPv4: -#endif // INET_CONFIG_ENABLE_IPV4 - mRaw = raw_new_ip_type(IPAddress::ToLwIPAddrType(addrType), IPProto); - break; - - default: - return INET_ERROR_WRONG_ADDRESS_TYPE; - } - - if (mRaw == NULL) - { - ChipLogError(Inet, "raw_new_ip_type failed"); - return CHIP_ERROR_NO_MEMORY; - } - - mLwIPEndPointType = kLwIPEndPointType_Raw; - } - else - { - const lwip_ip_addr_type lLwIPAddrType = static_cast(IP_GET_TYPE(&mRaw->local_ip)); - - switch (lLwIPAddrType) - { - case IPADDR_TYPE_V6: - VerifyOrReturnError(addrType == kIPAddressType_IPv6, INET_ERROR_WRONG_ADDRESS_TYPE); - break; - -#if INET_CONFIG_ENABLE_IPV4 - case IPADDR_TYPE_V4: - VerifyOrReturnError(addrType == kIPAddressType_IPv4, INET_ERROR_WRONG_ADDRESS_TYPE); - break; -#endif // INET_CONFIG_ENABLE_IPV4 - - default: - break; - } - } -#else // LWIP_VERSION_MAJOR <= 1 && LWIP_VERSION_MINOR < 5 - if (mRaw == NULL) - { - if (IPVer == kIPVersion_6) - { - mRaw = raw_new_ip6(IPProto); - if (mRaw != NULL) - ip_set_option(mRaw, SOF_REUSEADDR); - } -#if INET_CONFIG_ENABLE_IPV4 - else if (IPVer == kIPVersion_4) - { - mRaw = raw_new(IPProto); - } -#endif // INET_CONFIG_ENABLE_IPV4 - else - { - return INET_ERROR_WRONG_ADDRESS_TYPE; - } - - if (mRaw == NULL) - { - ChipLogError(Inet, "raw_new failed"); - return CHIP_ERROR_NO_MEMORY; - } - - mLwIPEndPointType = kLwIPEndPointType_Raw; - } - else - { -#if INET_CONFIG_ENABLE_IPV4 - const IPAddressType pcbType = PCB_ISIPV6(mRaw) ? kIPAddressType_IPv6 : kIPAddressType_IPv4; -#else // !INET_CONFIG_ENABLE_IPV4 - const IPAddressType pcbType = kIPAddressType_IPv6; -#endif // !INET_CONFIG_ENABLE_IPV4 - - if (addrType != pcbType) - { - return INET_ERROR_WRONG_ADDRESS_TYPE; - } - } -#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5 - - return CHIP_NO_ERROR; -} - -/* This function is executed when a raw_pcb is listening and an IP datagram (v4 or v6) is received. - * NOTE: currently ICMPv4 filtering is currently not implemented, but it can easily be added later. - * This fn() may be executed concurrently with SetICMPFilter() - * - this fn() runs in the LwIP thread (and the lock has already been taken) - * - SetICMPFilter() runs in the Inet thread. - * Returns non-zero if and only if ownership of the pbuf has been taken. - */ -#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5 -u8_t RawEndPoint::LwIPReceiveRawMessage(void * arg, struct raw_pcb * pcb, struct pbuf * p, const ip_addr_t * addr) -#else // LWIP_VERSION_MAJOR <= 1 && LWIP_VERSION_MINOR < 5 -u8_t RawEndPoint::LwIPReceiveRawMessage(void * arg, struct raw_pcb * pcb, struct pbuf * p, ip_addr_t * addr) -#endif // LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5 -{ - RawEndPoint * ep = static_cast(arg); - IPPacketInfo * pktInfo = NULL; - uint8_t enqueue = 1; - System::PacketBufferHandle buf = System::PacketBufferHandle::Adopt(p); - - // Filtering based on the saved ICMP6 types (the only protocol currently supported.) - if ((ep->IPVer == kIPVersion_6) && (ep->IPProto == kIPProtocol_ICMPv6)) - { - if (ep->NumICMPTypes > 0) - { // When no filter is defined, let all ICMPv6 packets pass - // The type is the first 8 bits field of an ICMP (v4 or v6) packet - uint8_t icmp_type = *(buf->Start() + ip_current_header_tot_len()); - uint8_t icmp_type_found = 0; - for (int j = 0; j < ep->NumICMPTypes; ++j) - { - if (ep->ICMPTypes[j] == icmp_type) - { - icmp_type_found = 1; - break; - } - } - if (!icmp_type_found) - { - enqueue = 0; // do not eat it - } - } - } - - if (enqueue) - { - pktInfo = GetPacketInfo(buf); - - if (pktInfo != NULL) - { -#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5 - pktInfo->SrcAddress = IPAddress::FromLwIPAddr(*addr); - pktInfo->DestAddress = IPAddress::FromLwIPAddr(*ip_current_dest_addr()); -#else // LWIP_VERSION_MAJOR <= 1 - if (PCB_ISIPV6(pcb)) - { - pktInfo->SrcAddress = IPAddress::FromIPv6(*(ip6_addr_t *) addr); - pktInfo->DestAddress = IPAddress::FromIPv6(*ip6_current_dest_addr()); - } -#if INET_CONFIG_ENABLE_IPV4 - else - { - pktInfo->SrcAddress = IPAddress::FromIPv4(*addr); - pktInfo->DestAddress = IPAddress::FromIPv4(*ip_current_dest_addr()); - } -#endif // INET_CONFIG_ENABLE_IPV4 -#endif // LWIP_VERSION_MAJOR <= 1 - - pktInfo->Interface = ip_current_netif(); - pktInfo->SrcPort = 0; - pktInfo->DestPort = 0; - } - - PostPacketBufferEvent(static_cast(ep->Layer().SystemLayer()), *ep, kInetEvent_RawDataReceived, - std::move(buf)); - } - - return enqueue; -} - -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS -CHIP_ERROR RawEndPoint::GetSocket(IPAddressType aAddressType) -{ - constexpr int lType = (SOCK_RAW | SOCK_FLAGS); - int lProtocol; - - switch (aAddressType) - { - case kIPAddressType_IPv6: - lProtocol = IPPROTO_ICMPV6; - break; - -#if INET_CONFIG_ENABLE_IPV4 - case kIPAddressType_IPv4: - lProtocol = IPPROTO_ICMP; - break; -#endif // INET_CONFIG_ENABLE_IPV4 - - default: - return INET_ERROR_WRONG_ADDRESS_TYPE; - } - - return IPEndPointBasis::GetSocket(aAddressType, lType, lProtocol); -} - -// static -void RawEndPoint::HandlePendingIO(System::SocketEvents events, intptr_t data) -{ - reinterpret_cast(data)->HandlePendingIO(events); -} - -void RawEndPoint::HandlePendingIO(System::SocketEvents events) -{ - if (mState == kState_Listening && OnMessageReceived != nullptr && events.Has(System::SocketEventFlags::kRead)) - { - const uint16_t lPort = 0; - - IPEndPointBasis::HandlePendingIO(lPort); - } -} - -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS - -} // namespace Inet -} // namespace chip diff --git a/src/inet/RawEndPoint.h b/src/inet/RawEndPoint.h deleted file mode 100644 index eaafe30a0c162e..00000000000000 --- a/src/inet/RawEndPoint.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * - * Copyright (c) 2020-2021 Project CHIP Authors - * Copyright (c) 2018 Google LLC - * Copyright (c) 2013-2017 Nest Labs, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * This header file defines the Inet::RawEndPoint - * class, where the CHIP Inet Layer encapsulates methods for - * interacting with IP network endpoints (SOCK_RAW sockets - * on Linux and BSD-derived systems) or LwIP raw protocol - * control blocks, as the system is configured accordingly. - */ - -#pragma once - -#include "inet/IPEndPointBasis.h" -#include - -#include - -#if CHIP_SYSTEM_CONFIG_USE_DISPATCH -#include -#endif - -namespace chip { -namespace Inet { - -class InetLayer; -class IPPacketInfo; - -/** - * @brief Objects of this class represent raw IP network endpoints. - * - * @details - * CHIP Inet Layer encapsulates methods for interacting with IP network - * endpoints (SOCK_RAW sockets on Linux and BSD-derived systems) or LwIP - * raw protocol control blocks, as the system is configured accordingly. - */ -class DLL_EXPORT RawEndPoint : public IPEndPointBasis -{ - friend class InetLayer; - -public: - /** - * @brief Version of the Internet protocol - * - * @details - * While this field is a mutable class variable, it is an invariant of the - * class that it not be modified. - */ - IPVersion IPVer; // This data member is read-only - - /** - * @brief version of the Internet Control Message Protocol (ICMP) - * - * @details - * While this field is a mutable class variable, it is an invariant of the - * class that it not be modified. - */ - IPProtocol IPProto; // This data member is read-only - - RawEndPoint() = default; - CHIP_ERROR Bind(IPAddressType addrType, const IPAddress & addr, InterfaceId intfId = INET_NULL_INTERFACEID); - CHIP_ERROR BindIPv6LinkLocal(InterfaceId intfId, const IPAddress & addr); - CHIP_ERROR BindInterface(IPAddressType addrType, InterfaceId intfId); - InterfaceId GetBoundInterface(); - CHIP_ERROR Listen(IPEndPointBasis::OnMessageReceivedFunct onMessageReceived, - IPEndPointBasis::OnReceiveErrorFunct onReceiveError, void * appState = nullptr); - CHIP_ERROR SendTo(const IPAddress & addr, chip::System::PacketBufferHandle && msg, uint16_t sendFlags = 0); - CHIP_ERROR SendTo(const IPAddress & addr, InterfaceId intfId, chip::System::PacketBufferHandle && msg, uint16_t sendFlags = 0); - CHIP_ERROR SendMsg(const IPPacketInfo * pktInfo, chip::System::PacketBufferHandle && msg, uint16_t sendFlags = 0); - CHIP_ERROR SetICMPFilter(uint8_t numICMPTypes, const uint8_t * aICMPTypes); - void Close(); - void Free(); - -private: - RawEndPoint(const RawEndPoint &) = delete; - - static chip::System::ObjectPool sPool; - - void Init(InetLayer * inetLayer, IPVersion ipVer, IPProtocol ipProto); - -#if CHIP_SYSTEM_CONFIG_USE_LWIP - uint8_t NumICMPTypes; - const uint8_t * ICMPTypes; - - void HandleDataReceived(chip::System::PacketBufferHandle && msg); - CHIP_ERROR GetPCB(IPAddressType addrType); - -#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5 - static u8_t LwIPReceiveRawMessage(void * arg, struct raw_pcb * pcb, struct pbuf * p, const ip_addr_t * addr); -#else // LWIP_VERSION_MAJOR <= 1 && LWIP_VERSION_MINOR < 5 - static u8_t LwIPReceiveRawMessage(void * arg, struct raw_pcb * pcb, struct pbuf * p, ip_addr_t * addr); -#endif // LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5 -#endif // CHIP_SYSTEM_CONFIG_USE_LWIP - -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS - CHIP_ERROR GetSocket(IPAddressType addrType); - void HandlePendingIO(System::SocketEvents events); - static void HandlePendingIO(System::SocketEvents events, intptr_t data); - -#if CHIP_SYSTEM_CONFIG_USE_DISPATCH - dispatch_source_t mReadableSource = nullptr; -#endif // CHIP_SYSTEM_CONFIG_USE_DISPATCH -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS -}; - -} // namespace Inet -} // namespace chip diff --git a/src/inet/inet.gni b/src/inet/inet.gni index 1b77bbe1a4025d..37c29ca0874354 100644 --- a/src/inet/inet.gni +++ b/src/inet/inet.gni @@ -23,9 +23,6 @@ declare_args() { # Enable DNS resolver. chip_inet_config_enable_dns_resolver = true - # Enable raw endpoint. - chip_inet_config_enable_raw_endpoint = true - # Enable UDP endpoint. chip_inet_config_enable_udp_endpoint = true diff --git a/src/inet/tests/TestInetEndPoint.cpp b/src/inet/tests/TestInetEndPoint.cpp index 7f47369777b786..f9390ab64115c2 100644 --- a/src/inet/tests/TestInetEndPoint.cpp +++ b/src/inet/tests/TestInetEndPoint.cpp @@ -80,9 +80,6 @@ void HandleTimer(Layer * aLayer, void * aAppState) // Test before init network, Inet is not initialized static void TestInetPre(nlTestSuite * inSuite, void * inContext) { -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - RawEndPoint * testRawEP = nullptr; -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT #if INET_CONFIG_ENABLE_UDP_ENDPOINT UDPEndPoint * testUDPEP = nullptr; #endif // INET_CONFIG_ENABLE_UDP_ENDPOINT @@ -102,11 +99,6 @@ static void TestInetPre(nlTestSuite * inSuite, void * inContext) ShutdownSystemLayer(); } -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - err = gInet.NewRawEndPoint(kIPVersion_6, kIPProtocol_ICMPv6, &testRawEP); - NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INCORRECT_STATE); -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - #if INET_CONFIG_ENABLE_UDP_ENDPOINT err = gInet.NewUDPEndPoint(&testUDPEP); NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INCORRECT_STATE); @@ -318,29 +310,11 @@ static void TestInetEndPointInternal(nlTestSuite * inSuite, void * inContext) InterfaceId intId; // EndPoint -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - RawEndPoint * testRaw6EP = nullptr; -#if INET_CONFIG_ENABLE_IPV4 - RawEndPoint * testRaw4EP = nullptr; -#endif // INET_CONFIG_ENABLE_IPV4 -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT UDPEndPoint * testUDPEP = nullptr; TCPEndPoint * testTCPEP1 = nullptr; PacketBufferHandle buf = PacketBufferHandle::New(PacketBuffer::kMaxSize); - bool didBind = false; - bool didListen = false; // init all the EndPoints -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - err = gInet.NewRawEndPoint(kIPVersion_6, kIPProtocol_ICMPv6, &testRaw6EP); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - -#if INET_CONFIG_ENABLE_IPV4 - err = gInet.NewRawEndPoint(kIPVersion_4, kIPProtocol_ICMPv4, &testRaw4EP); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); -#endif // INET_CONFIG_ENABLE_IPV4 -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - err = gInet.NewUDPEndPoint(&testUDPEP); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); @@ -352,75 +326,10 @@ static void TestInetEndPointInternal(nlTestSuite * inSuite, void * inContext) err = gInet.GetInterfaceFromAddr(addr, intId); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - // RawEndPoint special cases to cover the error branch - uint8_t ICMP6Types[2] = { 128, 129 }; #if INET_CONFIG_ENABLE_IPV4 NL_TEST_ASSERT(inSuite, IPAddress::FromString("10.0.0.1", addr_v4)); #endif // INET_CONFIG_ENABLE_IPV4 - // error bind cases -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - err = testRaw6EP->Bind(kIPAddressType_Unknown, addr_any); - NL_TEST_ASSERT(inSuite, err == INET_ERROR_WRONG_ADDRESS_TYPE); -#if INET_CONFIG_ENABLE_IPV4 - err = testRaw6EP->Bind(kIPAddressType_IPv4, addr); - NL_TEST_ASSERT(inSuite, err == INET_ERROR_WRONG_ADDRESS_TYPE); - err = testRaw6EP->BindIPv6LinkLocal(intId, addr_v4); - NL_TEST_ASSERT(inSuite, err == INET_ERROR_WRONG_ADDRESS_TYPE); -#endif // INET_CONFIG_ENABLE_IPV4 - err = testRaw6EP->BindInterface(kIPAddressType_Unknown, INET_NULL_INTERFACEID); - NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR); - - // A bind should succeed with appropriate permissions but will - // otherwise fail. - - err = testRaw6EP->BindIPv6LinkLocal(intId, addr); - NL_TEST_ASSERT(inSuite, (err == CHIP_NO_ERROR) || (err == System::MapErrorPOSIX(EPERM))); - - didBind = (err == CHIP_NO_ERROR); - - // Listen after bind should succeed if the prior bind succeeded. - - err = testRaw6EP->Listen(nullptr /*OnMessageReceived*/, nullptr /*OnReceiveError*/); - NL_TEST_ASSERT(inSuite, (didBind && (err == CHIP_NO_ERROR)) || (!didBind && (err == CHIP_ERROR_INCORRECT_STATE))); - - didListen = (err == CHIP_NO_ERROR); - - // If the first listen succeeded, then the second listen should be successful. - - err = testRaw6EP->Listen(nullptr /*OnMessageReceived*/, nullptr /*OnReceiveError*/); - NL_TEST_ASSERT(inSuite, (didBind && didListen && (err == CHIP_NO_ERROR)) || (!didBind && (err == CHIP_ERROR_INCORRECT_STATE))); - - didListen = (err == CHIP_NO_ERROR); - - // A bind-after-listen should result in an incorrect state error; - // otherwise, it will fail with a permissions error. - - err = testRaw6EP->Bind(kIPAddressType_IPv6, addr); - NL_TEST_ASSERT(inSuite, - (didListen && (err == CHIP_ERROR_INCORRECT_STATE)) || (!didListen && (err == System::MapErrorPOSIX(EPERM)))); - - // error SetICMPFilter case - err = testRaw6EP->SetICMPFilter(0, ICMP6Types); - NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INVALID_ARGUMENT); - -#if INET_CONFIG_ENABLE_IPV4 - // We should never be able to send an IPv4-addressed message on an - // IPv6 raw socket. - // - // Ostensibly the address obtained above from - // gInet.GetLinkLocalAddr(INET_NULL_INTERFACEID, &addr) is an IPv6 - // LLA; however, make sure it actually is. - - NL_TEST_ASSERT(inSuite, addr.Type() == kIPAddressType_IPv6); - - err = testRaw4EP->SendTo(addr, std::move(buf)); - NL_TEST_ASSERT(inSuite, err == INET_ERROR_WRONG_ADDRESS_TYPE); - testRaw4EP->Free(); -#endif // INET_CONFIG_ENABLE_IPV4 - testRaw6EP->Free(); -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - // UdpEndPoint special cases to cover the error branch err = testUDPEP->Listen(nullptr /*OnMessageReceived*/, nullptr /*OnReceiveError*/); NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INCORRECT_STATE); @@ -499,21 +408,11 @@ static void TestInetEndPointInternal(nlTestSuite * inSuite, void * inContext) // Test the InetLayer resource limitation static void TestInetEndPointLimit(nlTestSuite * inSuite, void * inContext) { -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - RawEndPoint * testRawEP[INET_CONFIG_NUM_RAW_ENDPOINTS + 1] = { nullptr }; -#endif // - UDPEndPoint * testUDPEP[INET_CONFIG_NUM_UDP_ENDPOINTS + 1] = { nullptr }; TCPEndPoint * testTCPEP[INET_CONFIG_NUM_TCP_ENDPOINTS + 1] = { nullptr }; CHIP_ERROR err = CHIP_NO_ERROR; -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - for (int i = 0; i < INET_CONFIG_NUM_RAW_ENDPOINTS + 1; i++) - err = gInet.NewRawEndPoint(kIPVersion_6, kIPProtocol_ICMPv6, &testRawEP[i]); - NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_ENDPOINT_POOL_FULL); -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - for (int i = 0; i < INET_CONFIG_NUM_UDP_ENDPOINTS + 1; i++) err = gInet.NewUDPEndPoint(&testUDPEP[i]); NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_ENDPOINT_POOL_FULL); @@ -539,12 +438,6 @@ static void TestInetEndPointLimit(nlTestSuite * inSuite, void * inContext) ShutdownNetwork(); ShutdownSystemLayer(); -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - // Release RAW endpoints - for (int i = 0; i < INET_CONFIG_NUM_RAW_ENDPOINTS; i++) - testRawEP[i]->Free(); -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - // Release UDP endpoints for (int i = 0; i < INET_CONFIG_NUM_UDP_ENDPOINTS; i++) testUDPEP[i]->Free(); diff --git a/src/inet/tests/TestInetLayer.cpp b/src/inet/tests/TestInetLayer.cpp index 72b55af3cfbbd6..71b5d7ddd0b57a 100644 --- a/src/inet/tests/TestInetLayer.cpp +++ b/src/inet/tests/TestInetLayer.cpp @@ -92,7 +92,6 @@ static const uint32_t kExpectedTxSizeDefault = kExpectedRxSizeDefault; static const uint32_t kOptFlagsDefault = (kOptFlagUseIPv6 | kOptFlagUseUDPIP); -static RawEndPoint * sRawIPEndPoint = nullptr; static TCPEndPoint * sTCPIPEndPoint = nullptr; // Used for connect/send/receive static TCPEndPoint * sTCPIPListenEndPoint = nullptr; // Used for accept/listen static UDPEndPoint * sUDPIPEndPoint = nullptr; @@ -121,7 +120,6 @@ static OptionDef sToolOptionDefs[] = #endif // INET_CONFIG_ENABLE_IPV4 { "ipv6", kNoArgument, kToolOptIPv6Only }, { "listen", kNoArgument, kToolOptListen }, - { "raw", kNoArgument, kToolOptRawIP }, { "send-size", kArgumentRequired, kToolOptSendSize }, { "tcp", kNoArgument, kToolOptTCPIP }, { "udp", kNoArgument, kToolOptUDPIP }, @@ -155,9 +153,6 @@ static const char * sToolOptionHelp = " -s, --send-size \n" " Send size bytes of user data (default: 59 bytes)\n" "\n" - " -r, --raw\n" - " Use raw IP (default).\n" - "\n" " -t, --tcp\n" " Use TCP over IP.\n" "\n" @@ -381,27 +376,8 @@ static bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdent gInterfaceName = aValue; break; - case kToolOptRawIP: - if (gOptFlags & kOptFlagUseUDPIP) - { - PrintArgError("%s: the use of --raw is exclusive with --udp. Please select only one of the two options.\n", aProgram); - retval = false; - } - else if (gOptFlags & kOptFlagUseTCPIP) - { - PrintArgError("%s: the use of --raw is exclusive with --tcp. Please select only one of the two options.\n", aProgram); - retval = false; - } - gOptFlags |= kOptFlagUseRawIP; - break; - case kToolOptTCPIP: - if (gOptFlags & kOptFlagUseRawIP) - { - PrintArgError("%s: the use of --tcp is exclusive with --raw. Please select only one of the two options.\n", aProgram); - retval = false; - } - else if (gOptFlags & kOptFlagUseUDPIP) + if (gOptFlags & kOptFlagUseUDPIP) { PrintArgError("%s: the use of --tcp is exclusive with --udp. Please select only one of the two options.\n", aProgram); retval = false; @@ -418,12 +394,7 @@ static bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdent break; case kToolOptUDPIP: - if (gOptFlags & kOptFlagUseRawIP) - { - PrintArgError("%s: the use of --udp is exclusive with --raw. Please select only one of the two options.\n", aProgram); - retval = false; - } - else if (gOptFlags & kOptFlagUseTCPIP) + if (gOptFlags & kOptFlagUseTCPIP) { PrintArgError("%s: the use of --udp is exclusive with --tcp. Please select only one of the two options.\n", aProgram); retval = false; @@ -470,7 +441,7 @@ bool HandleNonOptionArgs(const char * aProgram, int argc, char * argv[]) // If no IP version or transport flags were specified, use the defaults. - if (!(gOptFlags & (kOptFlagUseIPv4 | kOptFlagUseIPv6 | kOptFlagUseRawIP | kOptFlagUseTCPIP | kOptFlagUseUDPIP))) + if (!(gOptFlags & (kOptFlagUseIPv4 | kOptFlagUseIPv6 | kOptFlagUseTCPIP | kOptFlagUseUDPIP))) { gOptFlags |= kOptFlagsDefault; } @@ -652,61 +623,6 @@ static void HandleTCPConnectionReceived(TCPEndPoint * aListenEndPoint, TCPEndPoi sTCPIPEndPoint = aConnectEndPoint; } -// Raw Endpoint Callbacks - -static void HandleRawMessageReceived(IPEndPointBasis * aEndPoint, PacketBufferHandle && aBuffer, const IPPacketInfo * aPacketInfo) -{ - const bool lCheckBuffer = true; - const bool lStatsByPacket = true; - IPAddressType lAddressType; - bool lStatus; - - VerifyOrExit(aEndPoint != nullptr, lStatus = false); - VerifyOrExit(!aBuffer.IsNull(), lStatus = false); - VerifyOrExit(aPacketInfo != nullptr, lStatus = false); - - Common::HandleRawMessageReceived(aEndPoint, aBuffer, aPacketInfo); - - lAddressType = aPacketInfo->DestAddress.Type(); - - if (lAddressType == kIPAddressType_IPv6) - { - lStatus = Common::HandleICMPv6DataReceived(std::move(aBuffer), sTestState.mStats, !lStatsByPacket, lCheckBuffer); - } -#if INET_CONFIG_ENABLE_IPV4 - else if (lAddressType == kIPAddressType_IPv4) - { - const uint16_t kIPv4HeaderSize = 20; - - aBuffer->ConsumeHead(kIPv4HeaderSize); - - lStatus = Common::HandleICMPv4DataReceived(std::move(aBuffer), sTestState.mStats, !lStatsByPacket, lCheckBuffer); - } -#endif // INET_CONFIG_ENABLE_IPV4 - else - { - lStatus = false; - } - - if (lStatus) - { - PrintReceivedStats(sTestState.mStats); - } - -exit: - if (!lStatus) - { - SetStatusFailed(sTestState.mStatus); - } -} - -static void HandleRawReceiveError(IPEndPointBasis * aEndPoint, CHIP_ERROR aError, const IPPacketInfo * aPacketInfo) -{ - Common::HandleRawReceiveError(aEndPoint, aError, aPacketInfo); - - SetStatusFailed(sTestState.mStatus); -} - // UDP Endpoint Callbacks static void HandleUDPMessageReceived(IPEndPointBasis * aEndPoint, PacketBufferHandle && aBuffer, const IPPacketInfo * aPacketInfo) @@ -740,11 +656,7 @@ static bool IsTransportReadyForSend() { bool lStatus = false; - if ((gOptFlags & (kOptFlagUseRawIP)) == (kOptFlagUseRawIP)) - { - lStatus = (sRawIPEndPoint != nullptr); - } - else if ((gOptFlags & kOptFlagUseUDPIP) == kOptFlagUseUDPIP) + if ((gOptFlags & kOptFlagUseUDPIP) == kOptFlagUseUDPIP) { lStatus = (sUDPIPEndPoint != nullptr); } @@ -799,57 +711,32 @@ static CHIP_ERROR DriveSendForDestination(const IPAddress & aAddress, uint16_t a { PacketBufferHandle lBuffer; - if ((gOptFlags & (kOptFlagUseRawIP)) == (kOptFlagUseRawIP)) + if ((gOptFlags & kOptFlagUseUDPIP) == kOptFlagUseUDPIP) { - // For ICMP (v4 or v6), we'll send n aSize or smaller - // datagrams (with overhead for the ICMP header), each - // patterned from zero to aSize - 1, following the ICMP - // header. + const uint8_t lFirstValue = 0; - if ((gOptFlags & kOptFlagUseIPv6) == (kOptFlagUseIPv6)) - { - lBuffer = Common::MakeICMPv6DataBuffer(aSize); - VerifyOrReturnError(!lBuffer.IsNull(), CHIP_ERROR_NO_MEMORY); - } -#if INET_CONFIG_ENABLE_IPV4 - else if ((gOptFlags & kOptFlagUseIPv4) == (kOptFlagUseIPv4)) - { - lBuffer = Common::MakeICMPv4DataBuffer(aSize); - VerifyOrReturnError(!lBuffer.IsNull(), CHIP_ERROR_NO_MEMORY); - } -#endif // INET_CONFIG_ENABLE_IPV4 + // For UDP, we'll send n aSize or smaller datagrams, each + // patterned from zero to aSize - 1. + + lBuffer = Common::MakeDataBuffer(aSize, lFirstValue); + VerifyOrReturnError(!lBuffer.IsNull(), CHIP_ERROR_NO_MEMORY); - ReturnErrorOnFailure(sRawIPEndPoint->SendTo(aAddress, std::move(lBuffer))); + ReturnErrorOnFailure(sUDPIPEndPoint->SendTo(aAddress, kUDPPort, std::move(lBuffer))); } - else + else if ((gOptFlags & kOptFlagUseTCPIP) == kOptFlagUseTCPIP) { - if ((gOptFlags & kOptFlagUseUDPIP) == kOptFlagUseUDPIP) - { - const uint8_t lFirstValue = 0; - - // For UDP, we'll send n aSize or smaller datagrams, each - // patterned from zero to aSize - 1. - - lBuffer = Common::MakeDataBuffer(aSize, lFirstValue); - VerifyOrReturnError(!lBuffer.IsNull(), CHIP_ERROR_NO_MEMORY); + const uint32_t lFirstValue = sTestState.mStats.mTransmit.mActual; + VerifyOrReturnError(lFirstValue < 256u, CHIP_ERROR_UNEXPECTED_EVENT); - ReturnErrorOnFailure(sUDPIPEndPoint->SendTo(aAddress, kUDPPort, std::move(lBuffer))); - } - else if ((gOptFlags & kOptFlagUseTCPIP) == kOptFlagUseTCPIP) - { - const uint32_t lFirstValue = sTestState.mStats.mTransmit.mActual; - VerifyOrReturnError(lFirstValue < 256u, CHIP_ERROR_UNEXPECTED_EVENT); - - // For TCP, we'll send one byte stream of - // sTestState.mStats.mTransmit.mExpected in n aSize or - // smaller transactions, patterned from zero to - // sTestState.mStats.mTransmit.mExpected - 1. + // For TCP, we'll send one byte stream of + // sTestState.mStats.mTransmit.mExpected in n aSize or + // smaller transactions, patterned from zero to + // sTestState.mStats.mTransmit.mExpected - 1. - lBuffer = Common::MakeDataBuffer(aSize, uint8_t(lFirstValue)); - VerifyOrReturnError(!lBuffer.IsNull(), CHIP_ERROR_NO_MEMORY); + lBuffer = Common::MakeDataBuffer(aSize, uint8_t(lFirstValue)); + VerifyOrReturnError(!lBuffer.IsNull(), CHIP_ERROR_NO_MEMORY); - ReturnErrorOnFailure(sTCPIPEndPoint->Send(std::move(lBuffer))); - } + ReturnErrorOnFailure(sTCPIPEndPoint->Send(std::move(lBuffer))); } return CHIP_NO_ERROR; @@ -903,8 +790,6 @@ void DriveSend() static void StartTest() { IPAddressType lIPAddressType = kIPAddressType_IPv6; - IPProtocol lIPProtocol = kIPProtocol_ICMPv6; - IPVersion lIPVersion = kIPVersion_6; IPAddress lAddress = chip::Inet::IPAddress::Any; CHIP_ERROR lStatus; @@ -915,8 +800,6 @@ static void StartTest() if (gOptFlags & kOptFlagUseIPv4) { lIPAddressType = kIPAddressType_IPv4; - lIPProtocol = kIPProtocol_ICMPv4; - lIPVersion = kIPVersion_4; if (!gNetworkOptions.LocalIPv6Addr.empty()) lAddress = gNetworkOptions.LocalIPv4Addr[0]; else @@ -926,7 +809,7 @@ static void StartTest() // clang-format off printf("Using %sIP%s, device interface: %s (w/%c LwIP)\n", - ((gOptFlags & kOptFlagUseRawIP) ? "" : ((gOptFlags & kOptFlagUseTCPIP) ? "TCP/" : "UDP/")), + ((gOptFlags & kOptFlagUseTCPIP) ? "TCP/" : "UDP/"), ((gOptFlags & kOptFlagUseIPv4) ? "v4" : "v6"), ((gInterfaceName) ? gInterfaceName : ""), (CHIP_SYSTEM_CONFIG_USE_LWIP ? '\0' : 'o')); @@ -934,21 +817,7 @@ static void StartTest() // Allocate the endpoints for sending or receiving. -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - if (gOptFlags & kOptFlagUseRawIP) - { - lStatus = gInet.NewRawEndPoint(lIPVersion, lIPProtocol, &sRawIPEndPoint); - INET_FAIL_ERROR(lStatus, "InetLayer::NewRawEndPoint failed"); - - if (IsInterfaceIdPresent(gInterfaceId)) - { - lStatus = sRawIPEndPoint->BindInterface(lIPAddressType, gInterfaceId); - INET_FAIL_ERROR(lStatus, "RawEndPoint::BindInterface failed"); - } - } - else -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - if (gOptFlags & kOptFlagUseUDPIP) + if (gOptFlags & kOptFlagUseUDPIP) { lStatus = gInet.NewUDPEndPoint(&sUDPIPEndPoint); INET_FAIL_ERROR(lStatus, "InetLayer::NewUDPEndPoint failed"); @@ -962,24 +831,7 @@ static void StartTest() if (Common::IsReceiver()) { -#if INET_CONFIG_ENABLE_RAW_ENDPOINT - if (gOptFlags & kOptFlagUseRawIP) - { - lStatus = sRawIPEndPoint->Bind(lIPAddressType, lAddress); - INET_FAIL_ERROR(lStatus, "RawEndPoint::Bind failed"); - - if (gOptFlags & kOptFlagUseIPv6) - { - lStatus = sRawIPEndPoint->SetICMPFilter(kICMPv6_FilterTypes, gICMPv6Types); - INET_FAIL_ERROR(lStatus, "RawEndPoint::SetICMPFilter failed"); - } - - lStatus = sRawIPEndPoint->Listen(HandleRawMessageReceived, HandleRawReceiveError); - INET_FAIL_ERROR(lStatus, "RawEndPoint::Listen failed"); - } - else -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT - if (gOptFlags & kOptFlagUseUDPIP) + if (gOptFlags & kOptFlagUseUDPIP) { lStatus = sUDPIPEndPoint->Bind(lIPAddressType, IPAddress::Any, kUDPPort); INET_FAIL_ERROR(lStatus, "UDPEndPoint::Bind failed"); @@ -1021,11 +873,6 @@ static void CleanupTest() // Release the resources associated with the allocated end points. - if (sRawIPEndPoint != nullptr) - { - sRawIPEndPoint->Free(); - } - if (sTCPIPEndPoint != nullptr) { lStatus = sTCPIPEndPoint->Close(); diff --git a/src/inet/tests/TestInetLayerCommon.hpp b/src/inet/tests/TestInetLayerCommon.hpp index 9d961da65ed36e..b90aa0bd6400f8 100644 --- a/src/inet/tests/TestInetLayerCommon.hpp +++ b/src/inet/tests/TestInetLayerCommon.hpp @@ -33,7 +33,6 @@ #include #include -#include #include #include @@ -54,7 +53,6 @@ #define kToolOptIPv6Only '6' #define kToolOptInterval 'i' #define kToolOptListen 'l' -#define kToolOptRawIP 'r' #define kToolOptSendSize 's' #define kToolOptUDPIP 'u' @@ -65,7 +63,6 @@ enum OptFlagsCommon kOptFlagUseIPv4 = 0x00000001, kOptFlagUseIPv6 = 0x00000002, - kOptFlagUseRawIP = 0x00000004, kOptFlagUseUDPIP = 0x00000008, kOptFlagListen = 0x00000010, @@ -147,14 +144,6 @@ extern bool HandleICMPv6DataReceived(chip::System::PacketBufferHandle && aBuffer extern void HandleSendTimerComplete(chip::System::Layer * aSystemLayer, void * aAppState); -// Raw Endpoint Callback Handlers - -extern void HandleRawMessageReceived(const chip::Inet::IPEndPointBasis * aEndPoint, - const chip::System::PacketBufferHandle & aBuffer, - const chip::Inet::IPPacketInfo * aPacketInfo); -extern void HandleRawReceiveError(const chip::Inet::IPEndPointBasis * aEndPoint, const CHIP_ERROR & aError, - const chip::Inet::IPPacketInfo * aPacketInfo); - // UDP Endpoint Callback Handlers extern void HandleUDPMessageReceived(const chip::Inet::IPEndPointBasis * aEndPoint, diff --git a/src/inet/tests/TestInetLayerMulticast.cpp b/src/inet/tests/TestInetLayerMulticast.cpp index 4f4705a6c0be07..20c6d8f6cf1f71 100644 --- a/src/inet/tests/TestInetLayerMulticast.cpp +++ b/src/inet/tests/TestInetLayerMulticast.cpp @@ -21,8 +21,7 @@ * @file * This file implements a process to effect a functional test for * the InetLayer Internet Protocol stack abstraction interfaces - * for handling IP (v4 or v6) multicast on either bare IP (i.e., - * "raw") or UDP endpoints. + * for handling IP (v4 or v6) multicast on UDP endpoints. * */ @@ -108,9 +107,8 @@ static void CleanupTest(); /* Global Variables */ // clang-format off -static const uint32_t kOptFlagsDefault = (kOptFlagUseIPv6 | kOptFlagUseRawIP); +static const uint32_t kOptFlagsDefault = (kOptFlagUseIPv6 | kOptFlagUseUDPIP); -static RawEndPoint * sRawIPEndPoint = nullptr; static UDPEndPoint * sUDPIPEndPoint = nullptr; static GroupAddresses<4> sGroupAddresses; @@ -136,7 +134,6 @@ static OptionDef sToolOptionDefs[] = { "ipv6", kNoArgument, kToolOptIPv6Only }, { "listen", kNoArgument, kToolOptListen }, { "no-loopback", kNoArgument, kToolOptNoLoopback }, - { "raw", kNoArgument, kToolOptRawIP }, { "send-size", kArgumentRequired, kToolOptSendSize }, { "udp", kNoArgument, kToolOptUDPIP }, { } @@ -175,9 +172,6 @@ static const char * sToolOptionHelp = " -s, --send-size \n" " Send size bytes of user data (default: 59 bytes)\n" "\n" - " -r, --raw\n" - " Use raw IP (default).\n" - "\n" " -u, --udp\n" " Use UDP over IP.\n" "\n"; @@ -429,15 +423,6 @@ static bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdent gInterfaceName = aValue; break; - case kToolOptRawIP: - if (gOptFlags & kOptFlagUseUDPIP) - { - PrintArgError("%s: the use of --raw is exclusive with --udp. Please select only one of the two options.\n", aProgram); - retval = false; - } - gOptFlags |= kOptFlagUseRawIP; - break; - case kToolOptSendSize: if (!ParseInt(aValue, gSendSize)) { @@ -447,11 +432,6 @@ static bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdent break; case kToolOptUDPIP: - if (gOptFlags & kOptFlagUseRawIP) - { - PrintArgError("%s: the use of --udp is exclusive with --raw. Please select only one of the two options.\n", aProgram); - retval = false; - } gOptFlags |= kOptFlagUseUDPIP; break; @@ -483,7 +463,7 @@ bool HandleNonOptionArgs(const char * aProgram, int argc, char * argv[]) // If no IP version or transport flags were specified, use the defaults. - if (!(gOptFlags & (kOptFlagUseIPv4 | kOptFlagUseIPv6 | kOptFlagUseRawIP | kOptFlagUseUDPIP))) + if (!(gOptFlags & (kOptFlagUseIPv4 | kOptFlagUseIPv6 | kOptFlagUseUDPIP))) { gOptFlags |= kOptFlagsDefault; } @@ -609,65 +589,6 @@ static bool HandleDataReceived(const PacketBufferHandle & aBuffer, const IPPacke return true; } -// Raw Endpoint Callbacks - -static void HandleRawMessageReceived(IPEndPointBasis * aEndPoint, PacketBufferHandle && aBuffer, const IPPacketInfo * aPacketInfo) -{ - const bool lCheckBuffer = true; - const bool lStatsByPacket = true; - IPAddressType lAddressType; - bool lStatus = true; - GroupAddress * lGroupAddress; - - VerifyOrExit(aEndPoint != nullptr, lStatus = false); - VerifyOrExit(!aBuffer.IsNull(), lStatus = false); - VerifyOrExit(aPacketInfo != nullptr, lStatus = false); - - Common::HandleRawMessageReceived(aEndPoint, aBuffer, aPacketInfo); - - lGroupAddress = FindGroupAddress(aPacketInfo->DestAddress); - - if (lGroupAddress != nullptr) - { - lAddressType = aPacketInfo->DestAddress.Type(); - - if (lAddressType == kIPAddressType_IPv4) - { - const uint16_t kIPv4HeaderSize = 20; - - aBuffer->ConsumeHead(kIPv4HeaderSize); - - lStatus = Common::HandleICMPv4DataReceived(std::move(aBuffer), lGroupAddress->mStats, lStatsByPacket, lCheckBuffer); - } - else if (lAddressType == kIPAddressType_IPv6) - { - lStatus = Common::HandleICMPv6DataReceived(std::move(aBuffer), lGroupAddress->mStats, lStatsByPacket, lCheckBuffer); - } - else - { - lStatus = false; - } - - if (lStatus) - { - PrintReceivedStats(*lGroupAddress); - } - } - -exit: - if (!lStatus) - { - SetStatusFailed(sTestState.mStatus); - } -} - -static void HandleRawReceiveError(IPEndPointBasis * aEndPoint, CHIP_ERROR aError, const IPPacketInfo * aPacketInfo) -{ - Common::HandleRawReceiveError(aEndPoint, aError, aPacketInfo); - - SetStatusFailed(sTestState.mStatus); -} - // UDP Endpoint Callbacks static void HandleUDPMessageReceived(IPEndPointBasis * aEndPoint, PacketBufferHandle && aBuffer, const IPPacketInfo * aPacketInfo) @@ -701,11 +622,7 @@ static bool IsTransportReadyForSend() { bool lStatus = false; - if ((gOptFlags & (kOptFlagUseRawIP)) == (kOptFlagUseRawIP)) - { - lStatus = (sRawIPEndPoint != nullptr); - } - else if ((gOptFlags & kOptFlagUseUDPIP) == kOptFlagUseUDPIP) + if ((gOptFlags & kOptFlagUseUDPIP) == kOptFlagUseUDPIP) { lStatus = (sUDPIPEndPoint != nullptr); } @@ -724,29 +641,6 @@ static CHIP_ERROR DriveSendForDestination(const IPAddress & aAddress, uint16_t a { PacketBufferHandle lBuffer; - if ((gOptFlags & (kOptFlagUseRawIP)) == (kOptFlagUseRawIP)) - { - // For ICMP (v4 or v6), we'll send n aSize or smaller - // datagrams (with overhead for the ICMP header), each - // patterned from zero to aSize - 1, following the ICMP - // header. - - if ((gOptFlags & kOptFlagUseIPv6) == (kOptFlagUseIPv6)) - { - lBuffer = Common::MakeICMPv6DataBuffer(aSize); - VerifyOrReturnError(!lBuffer.IsNull(), CHIP_ERROR_NO_MEMORY); - } -#if INET_CONFIG_ENABLE_IPV4 - else if ((gOptFlags & kOptFlagUseIPv4) == (kOptFlagUseIPv4)) - { - lBuffer = Common::MakeICMPv4DataBuffer(aSize); - VerifyOrReturnError(!lBuffer.IsNull(), CHIP_ERROR_NO_MEMORY); - } -#endif // INET_CONFIG_ENABLE_IPV4 - - return sRawIPEndPoint->SendTo(aAddress, std::move(lBuffer)); - } - if ((gOptFlags & kOptFlagUseUDPIP) == kOptFlagUseUDPIP) { const uint8_t lFirstValue = 0; @@ -825,7 +719,6 @@ void DriveSend() static void StartTest() { IPAddressType lIPAddressType = kIPAddressType_IPv6; - IPProtocol lIPProtocol = kIPProtocol_ICMPv6; IPVersion lIPVersion = kIPVersion_6; IPAddress lAddress = IPAddress::Any; IPEndPointBasis * lEndPoint = nullptr; @@ -836,14 +729,13 @@ static void StartTest() if (gOptFlags & kOptFlagUseIPv4) { lIPAddressType = kIPAddressType_IPv4; - lIPProtocol = kIPProtocol_ICMPv4; lIPVersion = kIPVersion_4; } #endif // INET_CONFIG_ENABLE_IPV4 // clang-format off printf("Using %sIP%s, device interface: %s (w/%c LwIP)\n", - ((gOptFlags & kOptFlagUseRawIP) ? "" : "UDP/"), + "UDP/", ((gOptFlags & kOptFlagUseIPv4) ? "v4" : "v6"), ((gInterfaceName) ? gInterfaceName : ""), (CHIP_SYSTEM_CONFIG_USE_LWIP ? '\0' : 'o')); @@ -851,32 +743,7 @@ static void StartTest() // Allocate the endpoints for sending or receiving. - if (gOptFlags & kOptFlagUseRawIP) - { - lStatus = gInet.NewRawEndPoint(lIPVersion, lIPProtocol, &sRawIPEndPoint); - INET_FAIL_ERROR(lStatus, "InetLayer::NewRawEndPoint failed"); - - lStatus = sRawIPEndPoint->Bind(lIPAddressType, lAddress); - INET_FAIL_ERROR(lStatus, "RawEndPoint::Bind failed"); - - if (gOptFlags & kOptFlagUseIPv6) - { - lStatus = sRawIPEndPoint->SetICMPFilter(kICMPv6_FilterTypes, gICMPv6Types); - INET_FAIL_ERROR(lStatus, "RawEndPoint::SetICMPFilter (IPv6) failed"); - } - - if (IsInterfaceIdPresent(gInterfaceId)) - { - lStatus = sRawIPEndPoint->BindInterface(lIPAddressType, gInterfaceId); - INET_FAIL_ERROR(lStatus, "RawEndPoint::BindInterface failed"); - } - - lStatus = sRawIPEndPoint->Listen(HandleRawMessageReceived, HandleRawReceiveError); - INET_FAIL_ERROR(lStatus, "RawEndPoint::Listen failed"); - - lEndPoint = sRawIPEndPoint; - } - else if (gOptFlags & kOptFlagUseUDPIP) + if (gOptFlags & kOptFlagUseUDPIP) { lStatus = gInet.NewUDPEndPoint(&sUDPIPEndPoint); INET_FAIL_ERROR(lStatus, "InetLayer::NewUDPEndPoint failed"); @@ -946,11 +813,7 @@ static void CleanupTest() // Leave the multicast groups - if (gOptFlags & kOptFlagUseRawIP) - { - lEndPoint = sRawIPEndPoint; - } - else if (gOptFlags & kOptFlagUseUDPIP) + if (gOptFlags & kOptFlagUseUDPIP) { lEndPoint = sUDPIPEndPoint; } @@ -974,11 +837,6 @@ static void CleanupTest() // Release the resources associated with the allocated end points. - if (sRawIPEndPoint != nullptr) - { - sRawIPEndPoint->Free(); - } - if (sUDPIPEndPoint != nullptr) { sUDPIPEndPoint->Free(); diff --git a/src/lwip/k32w/lwipopts.h b/src/lwip/k32w/lwipopts.h index d2f0203b1df40b..fef3def735f2c0 100644 --- a/src/lwip/k32w/lwipopts.h +++ b/src/lwip/k32w/lwipopts.h @@ -55,13 +55,8 @@ #define LWIP_SOCKET 0 -#if INET_CONFIG_ENABLE_RAW_ENDPOINT -#define LWIP_RAW 1 -#define MEMP_NUM_RAW_PCB (5) -#else #define LWIP_RAW 0 #define MEMP_NUM_RAW_PCB 0 -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT #if INET_CONFIG_ENABLE_TCP_ENDPOINT #define LWIP_TCP 1 #else diff --git a/src/lwip/qpg/lwipopts.h b/src/lwip/qpg/lwipopts.h index 1db3ccb248e874..1cd86d29ab289c 100644 --- a/src/lwip/qpg/lwipopts.h +++ b/src/lwip/qpg/lwipopts.h @@ -50,13 +50,8 @@ #define LWIP_SOCKET 0 -#ifdef INET_CONFIG_ENABLE_RAW_ENDPOINT -#define LWIP_RAW 1 -#define MEMP_NUM_RAW_PCB (5) -#else #define LWIP_RAW 0 #define MEMP_NUM_RAW_PCB 0 -#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT #ifdef INET_CONFIG_ENABLE_TCP_ENDPOINT #define LWIP_TCP 1 #else diff --git a/src/platform/K32W/args.gni b/src/platform/K32W/args.gni index 758135675b1e0e..e4203cf5b71ea4 100644 --- a/src/platform/K32W/args.gni +++ b/src/platform/K32W/args.gni @@ -24,7 +24,6 @@ chip_inet_config_enable_ipv4 = false chip_inet_config_enable_dns_resolver = false chip_inet_config_enable_tcp_endpoint = false -chip_inet_config_enable_raw_endpoint = false chip_build_tests = false diff --git a/src/platform/qpg/args.gni b/src/platform/qpg/args.gni index ecb114318a83b0..386dc90cebe1d9 100644 --- a/src/platform/qpg/args.gni +++ b/src/platform/qpg/args.gni @@ -28,7 +28,6 @@ lwip_platform = "qpg" chip_inet_config_enable_ipv4 = false chip_inet_config_enable_dns_resolver = false chip_inet_config_enable_tcp_endpoint = false -chip_inet_config_enable_raw_endpoint = false # Size opt's #chip_progress_logging = false diff --git a/src/system/SystemLayerImplSelect.h b/src/system/SystemLayerImplSelect.h index 0378327c3730da..c2a2ebf8eb245c 100644 --- a/src/system/SystemLayerImplSelect.h +++ b/src/system/SystemLayerImplSelect.h @@ -77,8 +77,7 @@ class LayerImplSelect : public LayerSocketsLoop protected: static SocketEvents SocketEventsFromFDs(int socket, const fd_set & readfds, const fd_set & writefds, const fd_set & exceptfds); - static constexpr int kSocketWatchMax = (INET_CONFIG_ENABLE_RAW_ENDPOINT ? INET_CONFIG_NUM_RAW_ENDPOINTS : 0) + - (INET_CONFIG_ENABLE_TCP_ENDPOINT ? INET_CONFIG_NUM_TCP_ENDPOINTS : 0) + + static constexpr int kSocketWatchMax = (INET_CONFIG_ENABLE_TCP_ENDPOINT ? INET_CONFIG_NUM_TCP_ENDPOINTS : 0) + (INET_CONFIG_ENABLE_UDP_ENDPOINT ? INET_CONFIG_NUM_UDP_ENDPOINTS : 0) + (INET_CONFIG_ENABLE_DNS_RESOLVER ? INET_CONFIG_NUM_DNS_RESOLVERS : 0); diff --git a/src/system/SystemPacketBuffer.h b/src/system/SystemPacketBuffer.h index 0adf690deca3a1..e59e00cba17729 100644 --- a/src/system/SystemPacketBuffer.h +++ b/src/system/SystemPacketBuffer.h @@ -844,7 +844,6 @@ using PacketBufferWriter = PacketBufferWriterBase Date: Mon, 13 Sep 2021 11:47:47 -0400 Subject: [PATCH 013/255] Remove support for PacketBufferTLVReader using chained buffers. (#9592) It was unused, and if we can guarantee a contiguous buffer consumers can be safer --- src/lib/core/tests/TestCHIPTLV.cpp | 24 ++++++++++++++++-------- src/system/TLVPacketBufferBackingStore.h | 17 ++++++++--------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/lib/core/tests/TestCHIPTLV.cpp b/src/lib/core/tests/TestCHIPTLV.cpp index 1d04382a9d5ee1..2715cee28293ea 100644 --- a/src/lib/core/tests/TestCHIPTLV.cpp +++ b/src/lib/core/tests/TestCHIPTLV.cpp @@ -1967,7 +1967,7 @@ void CheckPacketBuffer(nlTestSuite * inSuite, void * inContext) ReadEncoding1(inSuite, reader); - reader.Init(buf.Retain(), buf->MaxDataLength()); + reader.Init(buf.Retain()); reader.ImplicitProfileId = TestProfile_2; ReadEncoding1(inSuite, reader); @@ -2477,7 +2477,6 @@ void CheckCHIPTLVSkipCircular(nlTestSuite * inSuite, void * inContext) */ void CheckBufferOverflow(nlTestSuite * inSuite, void * inContext) { - System::PacketBufferTLVWriter writer; System::PacketBufferTLVReader reader; System::PacketBufferHandle buf = System::PacketBufferHandle::New(sizeof(Encoding1), 0); @@ -2485,25 +2484,34 @@ void CheckBufferOverflow(nlTestSuite * inSuite, void * inContext) uint16_t reserve = static_cast((sizeof(Encoding1) < maxDataLen) ? (maxDataLen - sizeof(Encoding1)) + 2 : 0); // Repeatedly write and read a TLV encoding to a chain of PacketBuffers. Use progressively larger - // and larger amounts of space in the first buffer to force the encoding/decoding to overlap the + // and larger amounts of space in the first buffer to force the encoding to overlap the // end of the buffer and the beginning of the next. for (; reserve < maxDataLen; reserve++) { buf->SetStart(buf->Start() + reserve); - writer.Init(buf.Retain(), /* useChainedBuffers = */ true); - writer.ImplicitProfileId = TestProfile_2; + { + System::PacketBufferTLVWriter writer; + // Scope for writer because we want it to go out of scope before we + // mess with the chain after writing is done. + writer.Init(buf.Retain(), /* useChainedBuffers = */ true); + writer.ImplicitProfileId = TestProfile_2; - WriteEncoding1(inSuite, writer); + WriteEncoding1(inSuite, writer); + } TestBufferContents(inSuite, buf, Encoding1, sizeof(Encoding1)); - reader.Init(buf.Retain(), /* useChainedBuffers = */ true); + // Compact the buffer, since we don't allow reading from chained + // buffers. + buf->CompactHead(); + + reader.Init(buf.Retain()); reader.ImplicitProfileId = TestProfile_2; ReadEncoding1(inSuite, reader); - buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSizeWithoutReserve, 0); + buf = System::PacketBufferHandle::New(sizeof(Encoding1), 0); } } diff --git a/src/system/TLVPacketBufferBackingStore.h b/src/system/TLVPacketBufferBackingStore.h index e6c4fff671d786..512d4a20e996f4 100644 --- a/src/system/TLVPacketBufferBackingStore.h +++ b/src/system/TLVPacketBufferBackingStore.h @@ -87,25 +87,24 @@ class TLVPacketBufferBackingStore : public chip::TLV::TLVBackingStore bool mUseChainedBuffers; }; -class DLL_EXPORT PacketBufferTLVReader : public chip::TLV::TLVReader +class DLL_EXPORT PacketBufferTLVReader : public TLV::ContiguousBufferTLVReader { public: /** * Initializes a TLVReader object to read from a PacketBuffer. * - * @param[in] buffer A handle to PacketBuffer, to be used as backing store for a TLV class. - * @param[in] useChainedBuffers - * If true, advance to the next buffer in the chain once all data - * in the current buffer has been consumed. + * @param[in] buffer A handle to PacketBuffer, to be used as backing + * store for a TLV class. If the buffer is chained, + * only the head of the chain will be used. */ - void Init(chip::System::PacketBufferHandle && buffer, bool useChainedBuffers = false) + void Init(chip::System::PacketBufferHandle && buffer) { - mBackingStore.Init(std::move(buffer), useChainedBuffers); - chip::TLV::TLVReader::Init(mBackingStore); + mBuffer = std::move(buffer); + TLV::ContiguousBufferTLVReader::Init(mBuffer->Start(), mBuffer->DataLength()); } private: - TLVPacketBufferBackingStore mBackingStore; + PacketBufferHandle mBuffer; }; class DLL_EXPORT PacketBufferTLVWriter : public chip::TLV::TLVWriter From 92d3a288159fcf5077217ddf9ea91d03fabd6e3e Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 13 Sep 2021 13:26:57 -0400 Subject: [PATCH 014/255] Revert "Add mDNS shutdown (#9621)" (#9640) This reverts commit 3da26cfa879282c06fea97b7c98db371d0d018a7. Tizen builds seem broken since this change: ``` 2021-09-13 15:22:31 INFO /__w/connectedhomeip/connectedhomeip/out/tizen-arm-light/../../examples/lighting-app/linux/third_party/connectedhomeip/src/lib/mdns/Discovery_ImplPlatform.h:46: undefined reference to `chip::Mdns::ChipMdnsShutdown()' 409 2021-09-13 15:22:31 INFO collect2: error: ld returned 1 exit status ``` --- src/controller/CHIPDeviceController.cpp | 4 ---- src/controller/tests/TestCommissionableNodeController.cpp | 1 - src/lib/mdns/Discovery_ImplPlatform.h | 1 - src/lib/mdns/MinimalMdnsServer.cpp | 5 ----- src/lib/mdns/MinimalMdnsServer.h | 1 - src/lib/mdns/Resolver.h | 1 - src/lib/mdns/Resolver_ImplMinimalMdns.cpp | 6 ------ src/lib/mdns/Resolver_ImplNone.cpp | 1 - src/platform/fake/MdnsImpl.cpp | 5 ----- 9 files changed, 25 deletions(-) diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 1c497ece4e92a3..900262dffab078 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -266,10 +266,6 @@ CHIP_ERROR DeviceController::Shutdown() // manager. app::InteractionModelEngine::GetInstance()->Shutdown(); -#if CHIP_DEVICE_CONFIG_ENABLE_MDNS - Mdns::Resolver::Instance().ShutdownResolver(); -#endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS - // TODO(#6668): Some exchange has leak, shutting down ExchangeManager will cause a assert fail. // if (mExchangeMgr != nullptr) // { diff --git a/src/controller/tests/TestCommissionableNodeController.cpp b/src/controller/tests/TestCommissionableNodeController.cpp index d0df594c6d2068..43aa5917d35fee 100644 --- a/src/controller/tests/TestCommissionableNodeController.cpp +++ b/src/controller/tests/TestCommissionableNodeController.cpp @@ -33,7 +33,6 @@ class MockResolver : public Resolver public: CHIP_ERROR SetResolverDelegate(ResolverDelegate *) override { return SetResolverDelegateStatus; } CHIP_ERROR StartResolver(chip::Inet::InetLayer * inetLayer, uint16_t port) override { return StartResolverStatus; } - void ShutdownResolver() override {} CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type) override { return ResolveNodeIdStatus; } CHIP_ERROR FindCommissioners(DiscoveryFilter filter = DiscoveryFilter()) override { return FindCommissionersStatus; } CHIP_ERROR FindCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter()) override { return CHIP_ERROR_NOT_IMPLEMENTED; } diff --git a/src/lib/mdns/Discovery_ImplPlatform.h b/src/lib/mdns/Discovery_ImplPlatform.h index 0db90a695a1c62..c0bc89d1168831 100644 --- a/src/lib/mdns/Discovery_ImplPlatform.h +++ b/src/lib/mdns/Discovery_ImplPlatform.h @@ -43,7 +43,6 @@ class DiscoveryImplPlatform : public ServiceAdvertiser, public Resolver /// Starts the service resolver if not yet started CHIP_ERROR StartResolver(Inet::InetLayer * inetLayer, uint16_t port) override { return Init(); } - void ShutdownResolver() override { ChipMdnsShutdown(); } /// Advertises the CHIP node as an operational node CHIP_ERROR Advertise(const OperationalAdvertisingParameters & params) override; diff --git a/src/lib/mdns/MinimalMdnsServer.cpp b/src/lib/mdns/MinimalMdnsServer.cpp index 7bd268bb72eb8c..3044547126ede0 100644 --- a/src/lib/mdns/MinimalMdnsServer.cpp +++ b/src/lib/mdns/MinimalMdnsServer.cpp @@ -107,10 +107,5 @@ CHIP_ERROR GlobalMinimalMdnsServer::StartServer(chip::Inet::InetLayer * inetLaye return GlobalMinimalMdnsServer::Server().Listen(inetLayer, &allInterfaces, port); } -void GlobalMinimalMdnsServer::ShutdownServer() -{ - GlobalMinimalMdnsServer::Server().Shutdown(); -} - } // namespace Mdns } // namespace chip diff --git a/src/lib/mdns/MinimalMdnsServer.h b/src/lib/mdns/MinimalMdnsServer.h index e84cff5205a43e..e42342073fa5a4 100644 --- a/src/lib/mdns/MinimalMdnsServer.h +++ b/src/lib/mdns/MinimalMdnsServer.h @@ -90,7 +90,6 @@ class GlobalMinimalMdnsServer : public mdns::Minimal::ServerDelegate /// Calls Server().Listen() on all available interfaces CHIP_ERROR StartServer(chip::Inet::InetLayer * inetLayer, uint16_t port); - void ShutdownServer(); void SetQueryDelegate(MdnsPacketDelegate * delegate) { mQueryDelegate = delegate; } void SetResponseDelegate(MdnsPacketDelegate * delegate) { mResponseDelegate = delegate; } diff --git a/src/lib/mdns/Resolver.h b/src/lib/mdns/Resolver.h index f8badf5ba10521..47faa4eaa7ace0 100644 --- a/src/lib/mdns/Resolver.h +++ b/src/lib/mdns/Resolver.h @@ -260,7 +260,6 @@ class Resolver /// /// Unsual name to allow base MDNS classes to implement both Advertiser and Resolver interfaces. virtual CHIP_ERROR StartResolver(chip::Inet::InetLayer * inetLayer, uint16_t port) = 0; - virtual void ShutdownResolver() = 0; /// Registers a resolver delegate if none has been registered before virtual CHIP_ERROR SetResolverDelegate(ResolverDelegate * delegate) = 0; diff --git a/src/lib/mdns/Resolver_ImplMinimalMdns.cpp b/src/lib/mdns/Resolver_ImplMinimalMdns.cpp index 599cb9269fe4e3..d73fb1cabb0fdf 100644 --- a/src/lib/mdns/Resolver_ImplMinimalMdns.cpp +++ b/src/lib/mdns/Resolver_ImplMinimalMdns.cpp @@ -335,7 +335,6 @@ class MinMdnsResolver : public Resolver, public MdnsPacketDelegate ///// Resolver implementation CHIP_ERROR StartResolver(chip::Inet::InetLayer * inetLayer, uint16_t port) override; - void ShutdownResolver() override; CHIP_ERROR SetResolverDelegate(ResolverDelegate * delegate) override; CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type) override; CHIP_ERROR FindCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter()) override; @@ -395,11 +394,6 @@ CHIP_ERROR MinMdnsResolver::StartResolver(chip::Inet::InetLayer * inetLayer, uin return GlobalMinimalMdnsServer::Instance().StartServer(inetLayer, port); } -void MinMdnsResolver::ShutdownResolver() -{ - GlobalMinimalMdnsServer::Instance().ShutdownServer(); -} - CHIP_ERROR MinMdnsResolver::SetResolverDelegate(ResolverDelegate * delegate) { mDelegate = delegate; diff --git a/src/lib/mdns/Resolver_ImplNone.cpp b/src/lib/mdns/Resolver_ImplNone.cpp index bd0f097622327d..8f1cb81b7298dd 100644 --- a/src/lib/mdns/Resolver_ImplNone.cpp +++ b/src/lib/mdns/Resolver_ImplNone.cpp @@ -29,7 +29,6 @@ class NoneResolver : public Resolver CHIP_ERROR SetResolverDelegate(ResolverDelegate *) override { return CHIP_NO_ERROR; } CHIP_ERROR StartResolver(chip::Inet::InetLayer * inetLayer, uint16_t port) override { return CHIP_NO_ERROR; } - void ShutdownResolver() override {} CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type) override { diff --git a/src/platform/fake/MdnsImpl.cpp b/src/platform/fake/MdnsImpl.cpp index 9eb7379c799efb..30bb388066e5a3 100644 --- a/src/platform/fake/MdnsImpl.cpp +++ b/src/platform/fake/MdnsImpl.cpp @@ -95,11 +95,6 @@ CHIP_ERROR ChipMdnsInit(MdnsAsyncReturnCallback initCallback, MdnsAsyncReturnCal return CHIP_NO_ERROR; } -CHIP_ERROR ChipMdnsShutdown() -{ - return CHIP_NO_ERROR; -} - CHIP_ERROR ChipMdnsPublishService(const MdnsService * service) { return test::CheckExpected(test::CallType::kStart, service); From b976ebe0300079d2f839bbb386ac9dd7154dd1b1 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 13 Sep 2021 14:50:28 -0400 Subject: [PATCH 015/255] Ensure that stack layers above transport manager never get chained packet buffers. (#9599) None of our upper-layer core really deals with chained packet buffers, starting with the way we do in-place decryption that assumes that we have a contiguous buffer. The changes here: 1) Flatten out possibly-chained buffers in the LwIP case in the UDP endpoint. 2) Ensure that we don't have a chained buffer in BTP. There was already a check for this in the "in progress" case; this change just adds the same check in the "idle" case. --- src/ble/BtpEngine.cpp | 4 ++++ src/inet/UDPEndPoint.cpp | 18 ++++++++++++++++++ src/transport/TransportMgrBase.cpp | 9 +++++++++ 3 files changed, 31 insertions(+) diff --git a/src/ble/BtpEngine.cpp b/src/ble/BtpEngine.cpp index 5c36bc354177ec..6c5e561b96ad3b 100644 --- a/src/ble/BtpEngine.cpp +++ b/src/ble/BtpEngine.cpp @@ -321,6 +321,10 @@ CHIP_ERROR BtpEngine::HandleCharacteristicReceived(System::PacketBufferHandle && mRxBuf->AddToEnd(std::move(data)); mRxBuf->CompactHead(); // will free 'data' and adjust rx buf's end/length + + // For now, limit BtpEngine message size to max length of 1 pbuf, as we do for chip messages sent via IP. + // TODO add support for BtpEngine messages longer than 1 pbuf + VerifyOrExit(!mRxBuf->HasChainedBuffer(), err = CHIP_ERROR_INBOUND_MESSAGE_TOO_BIG); } else if (mRxState == kState_InProgress) { diff --git a/src/inet/UDPEndPoint.cpp b/src/inet/UDPEndPoint.cpp index 4f114b8e5db68c..60bd3f841083a8 100644 --- a/src/inet/UDPEndPoint.cpp +++ b/src/inet/UDPEndPoint.cpp @@ -864,6 +864,24 @@ void UDPEndPoint::LwIPReceiveUDPMessage(void * arg, struct udp_pcb * pcb, struct System::LayerLwIP * lSystemLayer = static_cast(ep->Layer().SystemLayer()); IPPacketInfo * pktInfo = NULL; System::PacketBufferHandle buf = System::PacketBufferHandle::Adopt(p); + if (buf->HasChainedBuffer()) + { + // Try the simple expedient of flattening in-place. + buf->CompactHead(); + } + + if (buf->HasChainedBuffer()) + { + // Have to allocate a new big-enough buffer and copy. + uint16_t messageSize = buf->TotalLength(); + System::PacketBufferHandle copy = System::PacketBufferHandle::New(messageSize, 0); + if (copy.IsNull() || buf->Read(copy->Start(), messageSize) != CHIP_NO_ERROR) + { + ChipLogError(Inet, "No memory to flatten incoming packet buffer chain of size %" PRIu16, buf->TotalLength()); + return; + } + buf = std::move(copy); + } pktInfo = GetPacketInfo(buf); if (pktInfo != NULL) diff --git a/src/transport/TransportMgrBase.cpp b/src/transport/TransportMgrBase.cpp index 868d54732405b2..a88e116377bedf 100644 --- a/src/transport/TransportMgrBase.cpp +++ b/src/transport/TransportMgrBase.cpp @@ -52,6 +52,15 @@ void TransportMgrBase::Close() void TransportMgrBase::HandleMessageReceived(const Transport::PeerAddress & peerAddress, System::PacketBufferHandle && msg) { + if (msg->HasChainedBuffer()) + { + // Something in the lower levels messed up. + char addrBuffer[Transport::PeerAddress::kMaxToStringSize]; + peerAddress.ToString(addrBuffer); + ChipLogError(Inet, "message from %s dropped due to lower layers not ensuring a single packet buffer.", addrBuffer); + return; + } + if (mSecureSessionMgr != nullptr) { mSecureSessionMgr->OnMessageReceived(peerAddress, std::move(msg)); From d3b4b7ef5c0b65c61dc50dad969ed8a705cfada3 Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Tue, 14 Sep 2021 00:22:59 +0530 Subject: [PATCH 016/255] ESP32: Wait till NimBLE host-cotroller is synced (#9565) * Use RTC memory as heap in unicore mode and readme fixes Signed-off-by: Shubham Patil * Wait till NimBLE host-controller is synced Signed-off-by: Shubham Patil --- .../esp32/README.md | 10 +++++++++- .../esp32/sdkconfig.defaults | 3 +++ .../esp32/sdkconfig.optimize.defaults | 3 +++ src/platform/ESP32/nimble/BLEManagerImpl.cpp | 20 +++++++++++++++++-- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/examples/temperature-measurement-app/esp32/README.md b/examples/temperature-measurement-app/esp32/README.md index 6756a11c7758f3..a0408df6823e10 100644 --- a/examples/temperature-measurement-app/esp32/README.md +++ b/examples/temperature-measurement-app/esp32/README.md @@ -214,5 +214,13 @@ Optimization related to WiFi, BLuetooth, Asserts etc are the part of this example by default. To enable this option set is_debug=false from command-line. ``` -idf.py -p /dev/tty.SLAB_USBtoUART -Dis_debug=false build flash monitor +# Reconfigure the project for additional optimizations +rm -rf sdkconfig build/ +idf.py -Dis_debug=false reconfigure + +# Set additional configurations if required +idf.py menuconfig + +# Build, flash, and monitor the device +idf.py -p /dev/tty.SLAB_USBtoUART build flash monitor ``` diff --git a/examples/temperature-measurement-app/esp32/sdkconfig.defaults b/examples/temperature-measurement-app/esp32/sdkconfig.defaults index b96ea1f15d90f1..a24175c5b32d76 100644 --- a/examples/temperature-measurement-app/esp32/sdkconfig.defaults +++ b/examples/temperature-measurement-app/esp32/sdkconfig.defaults @@ -56,6 +56,9 @@ CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=16 # FreeRTOS CONFIG_FREERTOS_UNICORE=y +# Add RTC memory to system heap +CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y + # LWIP CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=16 diff --git a/examples/temperature-measurement-app/esp32/sdkconfig.optimize.defaults b/examples/temperature-measurement-app/esp32/sdkconfig.optimize.defaults index db3481aa618f37..86335c251937d2 100644 --- a/examples/temperature-measurement-app/esp32/sdkconfig.optimize.defaults +++ b/examples/temperature-measurement-app/esp32/sdkconfig.optimize.defaults @@ -57,6 +57,9 @@ CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=16 # FreeRTOS CONFIG_FREERTOS_UNICORE=y +# Add RTC memory to system heap +CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y + # Log output CONFIG_LOG_DEFAULT_LEVEL_NONE=y diff --git a/src/platform/ESP32/nimble/BLEManagerImpl.cpp b/src/platform/ESP32/nimble/BLEManagerImpl.cpp index 21c5367ac08550..bd29932eccad1d 100644 --- a/src/platform/ESP32/nimble/BLEManagerImpl.cpp +++ b/src/platform/ESP32/nimble/BLEManagerImpl.cpp @@ -90,6 +90,8 @@ const ble_uuid128_t UUID_CHIPoBLEChar_TX = { { BLE_UUID_TYPE_128 }, { 0x12, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18 } }; +SemaphoreHandle_t semaphoreHandle = NULL; + } // unnamed namespace BLEManagerImpl BLEManagerImpl::sInstance; @@ -595,9 +597,8 @@ void BLEManagerImpl::bleprph_on_reset(int reason) void BLEManagerImpl::bleprph_on_sync(void) { - sInstance.mFlags.Set(Flags::kESPBLELayerInitialized); - sInstance.mFlags.Set(Flags::kGATTServiceStarted); ESP_LOGI(TAG, "BLE host-controller synced"); + xSemaphoreGive(semaphoreHandle); } void BLEManagerImpl::bleprph_host_task(void * param) @@ -614,6 +615,14 @@ CHIP_ERROR BLEManagerImpl::InitESPBleLayer(void) VerifyOrExit(!mFlags.Has(Flags::kESPBLELayerInitialized), /* */); + semaphoreHandle = xSemaphoreCreateBinary(); + if (semaphoreHandle == NULL) + { + err = CHIP_ERROR_NO_MEMORY; + ESP_LOGE(TAG, "Failed to create semaphore"); + ExitNow(); + } + for (int i = 0; i < kMaxConnections; i++) { mSubscribedConIds[i] = BLE_CONNECTION_UNINITIALIZED; @@ -655,6 +664,13 @@ CHIP_ERROR BLEManagerImpl::InitESPBleLayer(void) nimble_port_freertos_init(bleprph_host_task); + xSemaphoreTake(semaphoreHandle, portMAX_DELAY); + vSemaphoreDelete(semaphoreHandle); + semaphoreHandle = NULL; + + sInstance.mFlags.Set(Flags::kESPBLELayerInitialized); + sInstance.mFlags.Set(Flags::kGATTServiceStarted); + exit: return err; } From a24a6c308a4d937120e5400a8b508659bff9b730 Mon Sep 17 00:00:00 2001 From: Kevin Schoedel <67607049+kpschoedel@users.noreply.github.com> Date: Mon, 13 Sep 2021 14:55:07 -0400 Subject: [PATCH 017/255] Small artifacts for bloat reports (#9331) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Small-artifact bloat reports #### Problem The current bloat report requires preserving large binaries, and has trouble matching tree parents for comparison. #### Change overview This change makes example builds generate small artifacts containing json file(s) containing build item identification and section sizes. Artifacts names have the form “Size,PR,WORKFLOW,CURRENT_SHA,PARENT_SHA”; these contain one or more json files, each containing a report on one build target. The reporting scripts then examines the list of available artifacts to list of artifacts to identify pairs with the same $WORKFLOW where one's $CURRENT_SHA is the other's $PARENT_SHA, and only then downloads and processes those artifacts to generate comparisons for matching builds. - Changes to `examples-…` workflows: - Adds some `GH_EVENT_…` variables to workflow `env`, to identify the current run. - Uses the `gh_sizes.py` script to generate size report json files. - Uploads size report artifacts. - Changes to `scripts/tools/memory`: - Adds minimal platform config files for recently-added platforms. - Adds markdown output options (required for github comments) along with some associated cleanup. - Adds a script `scripts/tools/memory/gh_sizes.py` for use by workflows; this is similar to `report_summary.py` with a suitable consistent set of arguments. - Adds a script `scripts/tools/memory/gh_report.py` to analyze size report artifacts. - Modifies `bloat_check.py` to ignore the size report artifacts. The github comments produced by `gh_report.py` are slightly different fromt the existing reports. Since this change enables reports for many more builds, a full report will be over a hundred lines, and is placed inside a details tag. Only size changes above a configurable threshold are called out ‘above the fold’. Note that this PR does _not_ include a change to actually send size report comments on github; this is left to a followup after that code has been verified on real-world size artifacts. #### Testing Fork-CI runs and offline verification on resulting artifacts. * remove leftover debug print * small json format change * changes from review - restore original scripts/examples/esp_example.sh and scripts/examples/gn_efr32_example.sh - avoid a problem using pyelftools `describe_p_type` * telink output moved * report sections directly rather than aggregated symbols by section --- .github/workflows/examples-efr32.yaml | 39 +- .github/workflows/examples-esp32.yaml | 44 ++ .github/workflows/examples-infineon.yaml | 14 + .github/workflows/examples-k32w.yaml | 33 +- .../workflows/examples-linux-standalone.yaml | 65 ++- .github/workflows/examples-mbed.yaml | 25 +- .github/workflows/examples-nrfconnect.yaml | 85 ++- .github/workflows/examples-qpg.yaml | 34 +- .github/workflows/examples-telink.yaml | 15 +- scripts/helpers/bloat_check.py | 4 + scripts/requirements.txt | 1 + scripts/tools/memory/collect.py | 1 + scripts/tools/memory/gh_report.py | 548 ++++++++++++++++++ scripts/tools/memory/gh_sizes.py | 195 +++++++ scripts/tools/memory/memdf/collect.py | 6 + .../tools/memory/memdf/collector/elftools.py | 2 +- scripts/tools/memory/memdf/report.py | 417 +++++++++---- scripts/tools/memory/memdf/select.py | 21 +- scripts/tools/memory/memdf/util/nd.py | 23 +- scripts/tools/memory/memdf/util/sqlite.py | 110 ++++ scripts/tools/memory/platform/esp32.cfg | 2 +- scripts/tools/memory/platform/linux.cfg | 77 +++ scripts/tools/memory/platform/mbed.cfg | 42 ++ scripts/tools/memory/platform/p6.cfg | 42 ++ scripts/tools/memory/platform/telink.cfg | 42 ++ scripts/tools/memory/report_summary.py | 4 +- 26 files changed, 1723 insertions(+), 168 deletions(-) create mode 100755 scripts/tools/memory/gh_report.py create mode 100755 scripts/tools/memory/gh_sizes.py create mode 100644 scripts/tools/memory/memdf/util/sqlite.py create mode 100644 scripts/tools/memory/platform/linux.cfg create mode 100644 scripts/tools/memory/platform/mbed.cfg create mode 100644 scripts/tools/memory/platform/p6.cfg create mode 100644 scripts/tools/memory/platform/telink.cfg diff --git a/.github/workflows/examples-efr32.yaml b/.github/workflows/examples-efr32.yaml index 2b73a924b26ee5..d98671cf85e350 100644 --- a/.github/workflows/examples-efr32.yaml +++ b/.github/workflows/examples-efr32.yaml @@ -30,6 +30,9 @@ jobs: env: EFR32_BOARD: BRD4161A BUILD_TYPE: gn_efr32 + GH_EVENT_PR: ${{ github.event_name == 'pull_request' && github.event.number || 0 }} + GH_EVENT_HASH: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + GH_EVENT_PARENT: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} runs-on: ubuntu-latest if: github.actor != 'restyled-io[bot]' @@ -57,25 +60,29 @@ jobs: .environment/pigweed-venv/*.log - name: Build example EFR32 Lock App for BRD4161A timeout-minutes: 10 - run: - scripts/examples/gn_efr32_example.sh examples/lock-app/efr32/ - out/lock_app_debug BRD4161A + run: | + scripts/examples/gn_efr32_example.sh examples/lock-app/efr32/ out/lock_app_debug BRD4161A + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py efr32 BRD4161A lock-app \ + out/lock_app_debug/BRD4161A/chip-efr32-lock-example.out /tmp/bloat_reports/ - name: Build example EFR32 Lighting App for BRD4161A timeout-minutes: 10 - run: - scripts/examples/gn_efr32_example.sh - examples/lighting-app/efr32/ out/lighting_app_debug BRD4161A + run: | + scripts/examples/gn_efr32_example.sh examples/lighting-app/efr32/ out/lighting_app_debug BRD4161A + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py efr32 BRD4161A lighting-app \ + out/lighting_app_debug/BRD4161A/chip-efr32-lighting-example.out /tmp/bloat_reports/ - name: Build example EFR32 Lighting App for BRD4161A with RPCs timeout-minutes: 10 - run: - scripts/examples/gn_efr32_example.sh - examples/lighting-app/efr32/ out/lighting_app_debug_rpc BRD4161A - -args='import("//with_pw_rpc.gni")' + run: | + scripts/examples/gn_efr32_example.sh examples/lighting-app/efr32/ out/lighting_app_debug_rpc BRD4161A \ + -args='import("//with_pw_rpc.gni")' + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py efr32 BRD4161A+rpc lighting-app \ + out/lighting_app_debug_rpc/BRD4161A/chip-efr32-lighting-example.out /tmp/bloat_reports/ - name: Build example EFR32 Window Covering for BRD4161A timeout-minutes: 10 - run: - scripts/examples/gn_efr32_example.sh examples/window-app/efr32/ - out/window_app_debug BRD4161A + run: | + scripts/examples/gn_efr32_example.sh examples/window-app/efr32/ out/window_app_debug BRD4161A + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py efr32 BRD4161A window-app \ + out/window_app_debug/BRD4161A/chip-efr32-window-example.out /tmp/bloat_reports/ - name: Binary artifact suffix id: outsuffix uses: haya14busa/action-cond@v1.0.0 @@ -94,3 +101,9 @@ jobs: out/lock_app_debug/BRD4161A/chip-efr32-lock-example.out.map out/lighting_app_debug_rpc/BRD4161A/chip-efr32-lighting-example.out out/lighting_app_debug_rpc/BRD4161A/chip-efr32-lighting-example.out.map + - name: Uploading Size Reports + uses: actions/upload-artifact@v2 + with: + name: Size,EFR32-Examples,${{ env.GH_EVENT_PR }},${{ env.GH_EVENT_HASH }},${{ env.GH_EVENT_PARENT }} + path: | + /tmp/bloat_reports/ diff --git a/.github/workflows/examples-esp32.yaml b/.github/workflows/examples-esp32.yaml index 1cce1a171e9083..dfb4cf96f42243 100644 --- a/.github/workflows/examples-esp32.yaml +++ b/.github/workflows/examples-esp32.yaml @@ -30,6 +30,9 @@ jobs: env: BUILD_TYPE: esp32 + GH_EVENT_PR: ${{ github.event_name == 'pull_request' && github.event.number || 0 }} + GH_EVENT_HASH: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + GH_EVENT_PARENT: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} runs-on: ubuntu-latest if: github.actor != 'restyled-io[bot]' @@ -64,6 +67,10 @@ jobs: mkdir -p example_binaries/$BUILD_TYPE-build cp examples/all-clusters-app/esp32/build/chip-all-clusters-app.elf \ example_binaries/$BUILD_TYPE-build/chip-all-clusters-app.elf + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + esp32 m5stack all-clusters-app \ + example_binaries/$BUILD_TYPE-build/chip-all-clusters-app.elf \ + /tmp/bloat_reports/ - name: Build example All Clusters App C3 timeout-minutes: 10 run: scripts/examples/esp_example.sh all-clusters-app sdkconfig_c3devkit.defaults @@ -72,6 +79,10 @@ jobs: mkdir -p example_binaries/$BUILD_TYPE-build cp examples/all-clusters-app/esp32/build/chip-all-clusters-app.elf \ example_binaries/$BUILD_TYPE-build/chip-all-clusters-app.elf + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + esp32 c3devkit all-clusters-app \ + example_binaries/$BUILD_TYPE-build/chip-all-clusters-app.elf \ + /tmp/bloat_reports/ - name: Build example Pigweed App timeout-minutes: 5 run: scripts/examples/esp_example.sh pigweed-app sdkconfig.defaults @@ -80,6 +91,10 @@ jobs: mkdir -p example_binaries/$BUILD_TYPE-build cp examples/pigweed-app/esp32/build/chip-pigweed-app.elf \ example_binaries/$BUILD_TYPE-build/chip-pigweed-app.elf + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + esp32 default pigweed-app \ + example_binaries/$BUILD_TYPE-build/chip-pigweed-app.elf \ + /tmp/bloat_reports/ - name: Build example Lock App timeout-minutes: 5 run: scripts/examples/esp_example.sh lock-app sdkconfig.defaults @@ -88,6 +103,10 @@ jobs: mkdir -p example_binaries/$BUILD_TYPE-build cp examples/lock-app/esp32/build/chip-lock-app.elf \ example_binaries/$BUILD_TYPE-build/chip-lock-app.elf + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + esp32 default lock-app \ + example_binaries/$BUILD_TYPE-build/chip-lock-app.elf \ + /tmp/bloat_reports/ - name: Build example Bridge App timeout-minutes: 5 run: scripts/examples/esp_example.sh bridge-app @@ -96,6 +115,10 @@ jobs: mkdir -p example_binaries/$BUILD_TYPE-build cp examples/bridge-app/esp32/build/chip-bridge-app.elf \ example_binaries/$BUILD_TYPE-build/chip-bridge-app.elf + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + esp32 default bridge-app \ + example_binaries/$BUILD_TYPE-build/chip-bridge-app.elf \ + /tmp/bloat_reports/ - name: Build example Persistent Storage App timeout-minutes: 5 run: scripts/examples/esp_example.sh persistent-storage sdkconfig.defaults @@ -104,6 +127,10 @@ jobs: mkdir -p example_binaries/$BUILD_TYPE-build cp examples/persistent-storage/esp32/build/chip-persistent-storage.elf \ example_binaries/$BUILD_TYPE-build/chip-persistent-storage.elf + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + esp32 default persistent-storage \ + example_binaries/$BUILD_TYPE-build/chip-persistent-storage.elf \ + /tmp/bloat_reports/ - name: Build example Shell App timeout-minutes: 5 run: scripts/examples/esp_example.sh shell sdkconfig.defaults @@ -112,6 +139,10 @@ jobs: mkdir -p example_binaries/$BUILD_TYPE-build cp examples/shell/esp32/build/chip-shell.elf \ example_binaries/$BUILD_TYPE-build/chip-shell.elf + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + esp32 default shell \ + example_binaries/$BUILD_TYPE-build/chip-shell.elf \ + /tmp/bloat_reports/ - name: Build example Temperature Measurement App timeout-minutes: 5 run: scripts/examples/esp_example.sh temperature-measurement-app sdkconfig.optimize.defaults @@ -120,6 +151,10 @@ jobs: mkdir -p example_binaries/$BUILD_TYPE-build cp examples/temperature-measurement-app/esp32/build/chip-temperature-measurement-app.elf \ example_binaries/$BUILD_TYPE-build/chip-temperature-measurement-app.elf + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + esp32 optimize temperature-measurement-app \ + example_binaries/$BUILD_TYPE-build/chip-temperature-measurement-app.elf \ + /tmp/bloat_reports/ - name: Build example IPv6 Only App timeout-minutes: 5 run: scripts/examples/esp_example.sh ipv6only-app sdkconfig.defaults @@ -128,6 +163,10 @@ jobs: mkdir -p example_binaries/$BUILD_TYPE-build cp examples/ipv6only-app/esp32/build/chip-ipv6only-app.elf \ example_binaries/$BUILD_TYPE-build/chip-ipv6only-app.elf + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + esp32 default ipv6only-app \ + example_binaries/$BUILD_TYPE-build/chip-ipv6only-app.elf \ + /tmp/bloat_reports/ - name: Binary artifact suffix id: outsuffix uses: haya14busa/action-cond@v1.0.0 @@ -145,3 +184,8 @@ jobs: ${{ env.BUILD_TYPE }}-example-build-${{ steps.outsuffix.outputs.value }} path: /tmp/output_binaries/${{ env.BUILD_TYPE }}-build + - name: Uploading Size Reports + uses: actions/upload-artifact@v2 + with: + name: Size,ESP32-Examples,${{ env.GH_EVENT_PR }},${{ env.GH_EVENT_HASH }},${{ env.GH_EVENT_PARENT }} + path: /tmp/bloat_reports/ diff --git a/.github/workflows/examples-infineon.yaml b/.github/workflows/examples-infineon.yaml index 196fc434169a77..033cd8ee7a0311 100644 --- a/.github/workflows/examples-infineon.yaml +++ b/.github/workflows/examples-infineon.yaml @@ -28,6 +28,11 @@ jobs: name: Infineon examples building timeout-minutes: 30 + env: + GH_EVENT_PR: ${{ github.event_name == 'pull_request' && github.event.number || 0 }} + GH_EVENT_HASH: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + GH_EVENT_PARENT: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} + runs-on: ubuntu-latest if: github.actor != 'restyled-io[bot]' @@ -55,4 +60,13 @@ jobs: run: | scripts/run_in_build_env.sh \ "scripts/build/build_examples.py --no-log-timestamps --platform infineon --app lock build" + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + p6 default lock-app \ + out/infineon-p6board-lock/chip-p6-lock-example.out + - name: Uploading Size Reports + uses: actions/upload-artifact@v2 + with: + name: Size,P6-Examples,${{ env.GH_EVENT_PR }},${{ env.GH_EVENT_HASH }},${{ env.GH_EVENT_PARENT }} + path: | + out/infineon-p6board-lock/p6-default-lock-app-sizes.json diff --git a/.github/workflows/examples-k32w.yaml b/.github/workflows/examples-k32w.yaml index 11058a5a61129d..6e337556fb9947 100644 --- a/.github/workflows/examples-k32w.yaml +++ b/.github/workflows/examples-k32w.yaml @@ -29,6 +29,9 @@ jobs: env: BUILD_TYPE: gn_k32w + GH_EVENT_PR: ${{ github.event_name == 'pull_request' && github.event.number || 0 }} + GH_EVENT_HASH: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + GH_EVENT_PARENT: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} runs-on: ubuntu-latest if: github.actor != 'restyled-io[bot]' @@ -56,16 +59,28 @@ jobs: .environment/pigweed-venv/*.log - name: Build example K32W Lock App timeout-minutes: 5 - run: scripts/examples/k32w_example.sh - examples/lock-app/k32w out/lock_app_debug + run: | + scripts/examples/k32w_example.sh examples/lock-app/k32w out/lock_app_debug + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + k32w k32w061+debug lock-app \ + out/lock_app_debug/chip-k32w061-lock-example \ + /tmp/bloat_reports/ - name: Build example K32W Shell App timeout-minutes: 5 - run: scripts/examples/k32w_example.sh - examples/shell/k32w out/shell_app_debug + run: | + scripts/examples/k32w_example.sh examples/shell/k32w out/shell_app_debug + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + k32w k32w061+debug shell \ + out/shell_app_debug/chip-k32w061-shell-example \ + /tmp/bloat_reports/ - name: Build example K32W Lighting App with Secure Element timeout-minutes: 5 - run: scripts/examples/k32w_se_example.sh - examples/lighting-app/k32w out/lighting_app_se_release + run: | + scripts/examples/k32w_se_example.sh examples/lighting-app/k32w out/lighting_app_se_release + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + k32w k32w061+se05x+release lighting-app \ + out/lighting_app_se_release/chip-k32w061-light-example \ + /tmp/bloat_reports/ - name: Binary artifact suffix id: outsuffix uses: haya14busa/action-cond@v1.0.0 @@ -82,3 +97,9 @@ jobs: path: | out/lock_app_debug/chip-k32w061-lock-example.out out/lock_app_debug/chip-k32w061-lock-example.out.map + - name: Uploading Size Reports + uses: actions/upload-artifact@v2 + with: + name: Size,K32W-Examples,${{ env.GH_EVENT_PR }},${{ env.GH_EVENT_HASH }},${{ env.GH_EVENT_PARENT }} + path: | + /tmp/bloat_reports/ diff --git a/.github/workflows/examples-linux-standalone.yaml b/.github/workflows/examples-linux-standalone.yaml index ff751c8578dc31..1f77a89bbfd807 100644 --- a/.github/workflows/examples-linux-standalone.yaml +++ b/.github/workflows/examples-linux-standalone.yaml @@ -29,6 +29,9 @@ jobs: env: BUILD_TYPE: gn_linux + GH_EVENT_PR: ${{ github.event_name == 'pull_request' && github.event.number || 0 }} + GH_EVENT_HASH: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + GH_EVENT_PARENT: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} runs-on: ubuntu-latest if: github.actor != 'restyled-io[bot]' @@ -57,36 +60,62 @@ jobs: .environment/pigweed-venv/*.log - name: Build example Standalone Echo Client timeout-minutes: 5 - run: - scripts/examples/gn_build_example.sh examples/chip-tool - out/chip_tool_debug + run: | + scripts/examples/gn_build_example.sh examples/chip-tool out/chip_tool_debug + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + linux debug chip-tool \ + out/chip_tool_debug/chip-tool \ + /tmp/bloat_reports/ - name: Build example Standalone Shell timeout-minutes: 5 - run: - scripts/examples/gn_build_example.sh examples/shell/standalone - out/shell_debug + run: | + scripts/examples/gn_build_example.sh examples/shell/standalone out/shell_debug + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + linux debug shell \ + out/shell_debug/chip-shell \ + /tmp/bloat_reports/ - name: Build example Standalone All Clusters Server timeout-minutes: 5 - run: - scripts/examples/gn_build_example.sh examples/all-clusters-app/linux - out/all_clusters_debug chip_bypass_rendezvous=true + run: | + scripts/examples/gn_build_example.sh examples/all-clusters-app/linux out/all_clusters_debug \ + chip_bypass_rendezvous=true + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + linux debug all-clusters-app \ + out/all_clusters_debug/chip-all-clusters-app \ + /tmp/bloat_reports/ - name: Build example TV app timeout-minutes: 5 - run: + run: | scripts/examples/gn_build_example.sh examples/tv-app/linux out/tv_app_debug + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + linux debug tv-app \ + out/tv_app_debug/chip-tv-app \ + /tmp/bloat_reports/ - name: Build example lighting app with RPCs timeout-minutes: 5 - run: - scripts/examples/gn_build_example.sh examples/lighting-app/linux - out/lighting_app_debug_rpc 'import("//with_pw_rpc.gni")' + run: | + scripts/examples/gn_build_example.sh examples/lighting-app/linux out/lighting_app_debug_rpc \ + 'import("//with_pw_rpc.gni")' + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + linux debug+rpc lighting-app \ + out/lighting_app_debug_rpc/chip-lighting-app \ + /tmp/bloat_reports/ - name: Build example Standalone Bridge timeout-minutes: 5 - run: + run: | scripts/examples/gn_build_example.sh examples/bridge-app/linux out/bridge_debug + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + linux debug+rpc bridge-app \ + out/bridge_debug/chip-bridge-app \ + /tmp/bloat_reports/ - name: Build example OTA Provider timeout-minutes: 5 - run: + run: | scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/ota_provider_debug + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + linux debug ota-provider-app \ + out/ota_provider_debug/chip-ota-provider-app \ + /tmp/bloat_reports/ - name: Binary artifact suffix id: outsuffix uses: haya14busa/action-cond@v1.0.0 @@ -103,3 +132,9 @@ jobs: path: | out/all_clusters_debug/all-clusters-server out/all_clusters_debug/all-clusters-server.map + - name: Uploading Size Reports + uses: actions/upload-artifact@v2 + with: + name: Size,Linux-Examples,${{ env.GH_EVENT_PR }},${{ env.GH_EVENT_HASH }},${{ env.GH_EVENT_PARENT }} + path: | + /tmp/bloat_reports/ diff --git a/.github/workflows/examples-mbed.yaml b/.github/workflows/examples-mbed.yaml index 6cec70a4589264..6df9897a110d99 100644 --- a/.github/workflows/examples-mbed.yaml +++ b/.github/workflows/examples-mbed.yaml @@ -32,6 +32,9 @@ jobs: BUILD_TYPE: mbedos APP_PROFILE: release APP_TARGET: CY8CPROTO_062_4343W + GH_EVENT_PR: ${{ github.event_name == 'pull_request' && github.event.number || 0 }} + GH_EVENT_HASH: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + GH_EVENT_PARENT: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} runs-on: ubuntu-latest if: github.actor != 'restyled-io[bot]' @@ -39,6 +42,7 @@ jobs: container: image: connectedhomeip/chip-build-mbed-os:latest volumes: + - "/tmp/bloat_reports:/tmp/bloat_reports" - "/tmp/output_binaries:/tmp/output_binaries" steps: @@ -62,11 +66,21 @@ jobs: - name: Build lock-app example timeout-minutes: 10 - run: scripts/examples/mbed_example.sh -a=lock-app -b=$APP_TARGET -p=$APP_PROFILE + run: | + scripts/examples/mbed_example.sh -a=lock-app -b=$APP_TARGET -p=$APP_PROFILE + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + mbed $APP_TARGET+$APP_PROFILE lock-app \ + examples/lock-app/mbed/build-CY8CPROTO_062_4343W/release/chip-mbed-lock-app-example \ + /tmp/bloat_reports/ - name: Build lighting-app example timeout-minutes: 10 - run: scripts/examples/mbed_example.sh -a=lighting-app -b=$APP_TARGET -p=$APP_PROFILE + run: | + scripts/examples/mbed_example.sh -a=lighting-app -b=$APP_TARGET -p=$APP_PROFILE + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + mbed $APP_TARGET+$APP_PROFILE lighting-app \ + examples/lighting-app/mbed/build-CY8CPROTO_062_4343W/release/chip-mbed-lighting-app-example \ + /tmp/bloat_reports/ - name: Copy aside build products run: | @@ -91,3 +105,10 @@ jobs: ${{ env.BUILD_TYPE }}-binaries-${{env.APP_TARGET}}-${{ env.APP_PROFILE}}-build-${{ steps.outsuffix.outputs.value }} path: /tmp/output_binaries/${{ env.BUILD_TYPE }}-build + + - name: Uploading Size Reports + uses: actions/upload-artifact@v2 + with: + name: Size,Mbed-Examples,${{ env.GH_EVENT_PR }},${{ env.GH_EVENT_HASH }},${{ env.GH_EVENT_PARENT }} + path: | + /tmp/bloat_reports/ diff --git a/.github/workflows/examples-nrfconnect.yaml b/.github/workflows/examples-nrfconnect.yaml index 21cbfaeefcd8fb..16bb09a5ee7e9b 100644 --- a/.github/workflows/examples-nrfconnect.yaml +++ b/.github/workflows/examples-nrfconnect.yaml @@ -29,6 +29,9 @@ jobs: env: BUILD_TYPE: nrfconnect + GH_EVENT_PR: ${{ github.event_name == 'pull_request' && github.event.number || 0 }} + GH_EVENT_HASH: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + GH_EVENT_PARENT: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} runs-on: ubuntu-latest if: github.actor != 'restyled-io[bot]' @@ -60,37 +63,87 @@ jobs: run: scripts/run_in_build_env.sh "python3 scripts/setup/nrfconnect/update_ncs.py --update --shallow" - name: Build example nRF Connect SDK Lock App on nRF52840 DK timeout-minutes: 10 - run: scripts/examples/nrfconnect_example.sh lock-app nrf52840dk_nrf52840 + run: | + scripts/examples/nrfconnect_example.sh lock-app nrf52840dk_nrf52840 + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + nrfconnect nrf52840dk_nrf52840 lock-app \ + examples/lock-app/nrfconnect/build/nrf52840dk_nrf52840/zephyr/zephyr.elf \ + /tmp/bloat_reports/ - name: Build example nRF Connect SDK Lighting App on nRF52840 DK timeout-minutes: 10 - run: scripts/examples/nrfconnect_example.sh lighting-app nrf52840dk_nrf52840 + run: | + scripts/examples/nrfconnect_example.sh lighting-app nrf52840dk_nrf52840 + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + nrfconnect nrf52840dk_nrf52840 lighting-app \ + examples/lighting-app/nrfconnect/build/nrf52840dk_nrf52840/zephyr/zephyr.elf \ + /tmp/bloat_reports/ - name: Build example nRF Connect SDK Lighting App on nRF52840 DK with RPC timeout-minutes: 10 - run: scripts/examples/nrfconnect_example.sh lighting-app nrf52840dk_nrf52840 -DOVERLAY_CONFIG=rpc.overlay + run: | + scripts/examples/nrfconnect_example.sh lighting-app nrf52840dk_nrf52840 -DOVERLAY_CONFIG=rpc.overlay + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + nrfconnect nrf52840dk_nrf52840+rpc lighting-app \ + examples/lighting-app/nrfconnect/build/nrf52840dk_nrf52840/zephyr/zephyr.elf \ + /tmp/bloat_reports/ - name: Build example nRF Connect SDK Shell on nRF52840 DK timeout-minutes: 10 - run: scripts/examples/nrfconnect_example.sh shell nrf52840dk_nrf52840 + run: | + scripts/examples/nrfconnect_example.sh shell nrf52840dk_nrf52840 + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + nrfconnect nrf52840dk_nrf52840 shell \ + examples/shell/nrfconnect/build/nrf52840dk_nrf52840/zephyr/zephyr.elf \ + /tmp/bloat_reports/ - name: Build example nRF Connect SDK Pigweed on nRF52840 DK timeout-minutes: 10 - run: scripts/examples/nrfconnect_example.sh pigweed-app nrf52840dk_nrf52840 + run: | + scripts/examples/nrfconnect_example.sh pigweed-app nrf52840dk_nrf52840 + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + nrfconnect nrf52840dk_nrf52840 pigweed-app \ + examples/pigweed-app/nrfconnect/build/nrf52840dk_nrf52840/zephyr/zephyr.elf \ + /tmp/bloat_reports/ - name: Build example nRF Connect SDK Lock App on nRF5340 DK timeout-minutes: 10 - run: scripts/examples/nrfconnect_example.sh lock-app nrf5340dk_nrf5340_cpuapp + run: | + scripts/examples/nrfconnect_example.sh lock-app nrf5340dk_nrf5340_cpuapp + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + nrfconnect nrf5340dk_nrf5340_cpuapp lock-app \ + examples/lock-app/nrfconnect/build/nrf5340dk_nrf5340_cpuapp/zephyr/zephyr.elf \ + /tmp/bloat_reports/ - name: Build example nRF Connect SDK Lighting App on nRF5340 DK timeout-minutes: 10 - run: scripts/examples/nrfconnect_example.sh lighting-app nrf5340dk_nrf5340_cpuapp + run: | + scripts/examples/nrfconnect_example.sh lighting-app nrf5340dk_nrf5340_cpuapp + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + nrfconnect nrf5340dk_nrf5340_cpuapp lighting-app \ + examples/lighting-app/nrfconnect/build/nrf5340dk_nrf5340_cpuapp/zephyr/zephyr.elf \ + /tmp/bloat_reports/ - name: Build example nRF Connect SDK Shell on nRF5340 DK timeout-minutes: 10 - run: scripts/examples/nrfconnect_example.sh shell nrf5340dk_nrf5340_cpuapp + run: | + scripts/examples/nrfconnect_example.sh shell nrf5340dk_nrf5340_cpuapp + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + nrfconnect nrf5340dk_nrf5340_cpuapp shell \ + examples/shell/nrfconnect/build/nrf5340dk_nrf5340_cpuapp/zephyr/zephyr.elf \ + /tmp/bloat_reports/ - name: Build example nRF Connect SDK Pump App on nRF52840 DK - timeout-minutes: 5 - run: scripts/examples/nrfconnect_example.sh pump-app nrf52840dk_nrf52840 + timeout-minutes: 10 + run: | + scripts/examples/nrfconnect_example.sh pump-app nrf52840dk_nrf52840 + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + nrfconnect nrf52840dk_nrf52840 pump-app \ + examples/pump-app/nrfconnect/build/nrf52840dk_nrf52840/zephyr/zephyr.elf \ + /tmp/bloat_reports/ - name: Build example nRF Connect SDK Pump Controller App on nRF52840 DK - timeout-minutes: 5 - run: scripts/examples/nrfconnect_example.sh pump-controller-app nrf52840dk_nrf52840 + timeout-minutes: 10 + run: | + scripts/examples/nrfconnect_example.sh pump-controller-app nrf52840dk_nrf52840 + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + nrfconnect nrf52840dk_nrf52840 pump-controller-app \ + examples/pump-controller-app/nrfconnect/build/nrf52840dk_nrf52840/zephyr/zephyr.elf \ + /tmp/bloat_reports/ - name: Run unit tests for Zephyr native_posix_64 platform timeout-minutes: 10 - run: + run: | scripts/run_in_build_env.sh "scripts/tests/nrfconnect_native_posix_tests.sh native_posix_64" - name: Copy aside build products run: | @@ -113,3 +166,9 @@ jobs: ${{ env.BUILD_TYPE }}-example-build-${{ steps.outsuffix.outputs.value }} path: /tmp/output_binaries/${{ env.BUILD_TYPE }}-build + - name: Uploading Size Reports + uses: actions/upload-artifact@v2 + with: + name: Size,nRFConnect-Examples,${{ env.GH_EVENT_PR }},${{ env.GH_EVENT_HASH }},${{ env.GH_EVENT_PARENT }} + path: | + /tmp/bloat_reports/ diff --git a/.github/workflows/examples-qpg.yaml b/.github/workflows/examples-qpg.yaml index 50518558390431..94e71a2df49d15 100644 --- a/.github/workflows/examples-qpg.yaml +++ b/.github/workflows/examples-qpg.yaml @@ -29,6 +29,9 @@ jobs: env: BUILD_TYPE: gn_qpg + GH_EVENT_PR: ${{ github.event_name == 'pull_request' && github.event.number || 0 }} + GH_EVENT_HASH: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + GH_EVENT_PARENT: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} runs-on: ubuntu-latest if: github.actor != 'restyled-io[bot]' @@ -56,16 +59,29 @@ jobs: .environment/pigweed-venv/*.log - name: Build example QPG6100 Lock App timeout-minutes: 5 - run: scripts/examples/gn_build_example.sh - examples/lock-app/qpg out/lock_app_debug qpg_target_ic=\"qpg6100\" + run: | + scripts/examples/gn_build_example.sh examples/lock-app/qpg out/lock_app_debug qpg_target_ic=\"qpg6100\" + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + qpg qpg6100+debug lock-app \ + out/lock_app_debug/chip-qpg6100-lock-example.out \ + /tmp/bloat_reports/ - name: Build example QPG6100 Lighting App timeout-minutes: 5 - run: scripts/examples/gn_build_example.sh - examples/lighting-app/qpg out/lighting_app_debug qpg_target_ic=\"qpg6100\" + run: | + scripts/examples/gn_build_example.sh examples/lighting-app/qpg out/lighting_app_debug qpg_target_ic=\"qpg6100\" + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + qpg qpg6100+debug lighting-app \ + out/lighting_app_debug/chip-qpg6100-lighting-example.out \ + /tmp/bloat_reports/ - name: Build example QPG6100 persistent-storage timeout-minutes: 5 - run: scripts/examples/gn_build_example.sh - examples/persistent-storage/qpg out/persistent-storage_app_debug qpg_target_ic=\"qpg6100\" + run: | + scripts/examples/gn_build_example.sh examples/persistent-storage/qpg out/persistent-storage_app_debug \ + qpg_target_ic=\"qpg6100\" + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + qpg qpg6100+debug persistent-storage-app \ + out/persistent-storage_app_debug/chip-qpg6100-persistent_storage-example.out \ + /tmp/bloat_reports/ - name: Binary artifact suffix id: outsuffix uses: haya14busa/action-cond@v1.0.0 @@ -82,3 +98,9 @@ jobs: path: | out/lighting_app_debug/chip-qpg6100-lighting-example.out out/lighting_app_debug/chip-qpg6100-lighting-example.out.map + - name: Uploading Size Reports + uses: actions/upload-artifact@v2 + with: + name: Size,QPG-Examples,${{ env.GH_EVENT_PR }},${{ env.GH_EVENT_HASH }},${{ env.GH_EVENT_PARENT }} + path: | + /tmp/bloat_reports/ diff --git a/.github/workflows/examples-telink.yaml b/.github/workflows/examples-telink.yaml index dd971792abc77d..b279f8f235c8cd 100644 --- a/.github/workflows/examples-telink.yaml +++ b/.github/workflows/examples-telink.yaml @@ -27,6 +27,9 @@ jobs: name: Telink env: BUILD_TYPE: telink + GH_EVENT_PR: ${{ github.event_name == 'pull_request' && github.event.number || 0 }} + GH_EVENT_HASH: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + GH_EVENT_PARENT: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} runs-on: ubuntu-latest if: github.actor != 'restyled-io[bot]' @@ -41,7 +44,17 @@ jobs: uses: actions/checkout@v2 with: submodules: true - - name: Build example Telink Lighting App + - name: Build example Telink Lighting App run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --no-log-timestamps --platform telink --app light build" + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + telink tlsr9518adk80d lighting-app \ + out/telink-tlsr9518adk80d-light/zephyr/zephyr.elf \ + /tmp/bloat_reports/ + - name: Uploading Size Reports + uses: actions/upload-artifact@v2 + with: + name: Size,Telink-Examples,${{ env.GH_EVENT_PR }},${{ env.GH_EVENT_HASH }},${{ env.GH_EVENT_PARENT }} + path: | + /tmp/bloat_reports/ diff --git a/scripts/helpers/bloat_check.py b/scripts/helpers/bloat_check.py index 52b7d0f46047c5..db1157008d2a9f 100755 --- a/scripts/helpers/bloat_check.py +++ b/scripts/helpers/bloat_check.py @@ -268,6 +268,10 @@ def main(): pull_artifact_re = re.compile('^(.*)-pull-(\\d+)$') binary_count = 0 for a in artifacts: + # Ignore size reports; they are handled by a separate script. + if a.name.startswith('Size,'): + continue + # logs cleanup after 3 days is_log = a.name.endswith('-logs') diff --git a/scripts/requirements.txt b/scripts/requirements.txt index edcd7ae09b9348..7905aff72b6862 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -41,6 +41,7 @@ protobuf # scripts/tools/memory anytree cxxfilt +ghapi pandas ; platform_machine != 'aarch64' # scripts/build diff --git a/scripts/tools/memory/collect.py b/scripts/tools/memory/collect.py index 03f76e3b672c99..5c0a48e39183d2 100755 --- a/scripts/tools/memory/collect.py +++ b/scripts/tools/memory/collect.py @@ -36,6 +36,7 @@ def main(argv): try: config = memdf.collect.parse_args({ **memdf.select.CONFIG, + **memdf.report.REPORT_DEMANGLE_CONFIG, **memdf.report.OUTPUT_CONFIG }, argv) memdf.report.write_dfs(config, memdf.collect.collect_files(config)) diff --git a/scripts/tools/memory/gh_report.py b/scripts/tools/memory/gh_report.py new file mode 100755 index 00000000000000..7f395a684b0540 --- /dev/null +++ b/scripts/tools/memory/gh_report.py @@ -0,0 +1,548 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +"""Generate reports from size artifacts.""" + +import io +import itertools +import json +import logging +import os +import os.path +import sqlite3 +import sys +import zipfile + +from pathlib import Path +from typing import Dict, IO, Iterable, Optional, Union + +import dateutil # type: ignore +import fastcore # type: ignore +import ghapi.all # type: ignore +import pandas as pd # type: ignore + +import memdf.report +import memdf.util.config +import memdf.util.sqlite +from memdf import Config, ConfigDescription + +GITHUB_CONFIG: ConfigDescription = { + Config.group_def('github'): { + 'title': 'github options', + }, + 'github.token': { + 'help': 'Github API token, or "SKIP" to suppress connecting to github', + 'metavar': 'TOKEN', + 'default': '', + 'argparse': { + 'alias': ['--github-api-token', '--token'], + }, + }, + 'github.repository': { + 'help': 'Github repostiory', + 'metavar': 'OWNER/REPO', + 'default': '', + 'argparse': { + 'alias': ['--repo'], + }, + }, + 'github.comment': { + 'help': 'Send output as github PR comments', + 'default': False, + 'argparse': { + 'alias': ['--comment'], + }, + }, + 'github.keep': { + 'help': 'Leave PR artifacts after commenting', + 'default': False, + 'argparse': { + 'alias': ['--keep'], + }, + }, + Config.group_map('report'): { + 'group': 'output' + }, + 'report.pr': { + 'help': 'Report on pull requests', + 'default': False, + 'argparse': { + 'alias': ['--pr', '--pull-request'], + }, + }, + 'report.push': { + 'help': 'Report on pushes', + 'default': False, + 'argparse': { + 'alias': ['--push'] + }, + }, + 'report.query': { + 'help': 'Run an SQL query', + 'default': [], + 'argparse': { + 'alias': ['--query', '--sql'] + }, + }, + 'report.increases': { + 'help': 'Highlight large increases', + 'metavar': 'PERCENT', + 'default': 0.0, + 'argparse': { + 'alias': ['--threshold'], + 'type': float, + }, + }, +} + + +class SizeDatabase(memdf.util.sqlite.Database): + """A database for recording and comparing size reports.""" + on_open = ["PRAGMA foreign_keys = ON", "PRAGMA encoding = 'UTF-8'"] + on_writable = [ + """ + -- A ‘thing’ identifies the kind of built object. + -- Builds of the same thing are comparable. + CREATE TABLE IF NOT EXISTS thing ( + id INTEGER PRIMARY KEY, + platform TEXT NOT NULL, -- Build platform + config TEXT NOT NULL, -- Build configuration discriminator + target TEXT NOT NULL, -- Build target + UNIQUE(platform, config, target) + ) + """, """ + -- A ‘build’ identifies a built instance of a thing at some point. + CREATE TABLE IF NOT EXISTS build ( + id INTEGER PRIMARY KEY, + thing_id INTEGER REFERENCES thing(id), + hash TEXT NOT NULL, -- Commit hash + parent TEXT NOT NULL, -- Parent commit hash + pr INTEGER DEFAULT 0, -- Github PR number + time INTEGER NOT NULL, -- Unix-epoch timestamp + artifact INTEGER DEFAULT 0, -- Github artifact ID + commented INTEGER DEFAULT 0, + UNIQUE(thing_id, hash, parent, pr, time, artifact) + ) + """, """ + -- A ‘size’ entry gives the size of a section for a particular build. + CREATE TABLE IF NOT EXISTS size ( + build_id INTEGER REFERENCES build(id), + name TEXT NOT NULL, -- Section name + size INTEGER NOT NULL, -- Section size in bytes + PRIMARY KEY (build_id, name) + ) + """ + ] + + def __init__(self, config: Config): + super().__init__(config['database.file']) + self.config = config + self.gh = gh_open(config) + self.deleted_artifacts: set[int] = set() + + def add_sizes(self, **kwargs): + """ + Add a size report to the database. + + The incoming arguments must contain the non-ID column names from + ‘thing’ and ‘build’ tables, plus a 'sizes' entry that is a sequence + of mappings containing 'name' and 'size'. + """ + td = {k: kwargs[k] for k in ('platform', 'config', 'target')} + thing = self.store_and_return_id('thing', **td) + bd = {k: kwargs[k] for k in ('hash', 'parent', 'time')} + cd = {k: kwargs.get(k, 0) for k in ('pr', 'artifact', 'commented')} + build = self.store_and_return_id('build', thing_id=thing, **bd, **cd) + for d in kwargs['sizes']: + self.store('size', build_id=build, **d) + + def add_sizes_from_json(self, s: Union[bytes, str], origin: Dict): + """Add sizes from a JSON size report.""" + r = origin.copy() + r.update(json.loads(s)) + by = r.get('by', 'section') + r['sizes'] = [{ + 'name': s[by], + 'size': s['size'] + } for s in r['frames'][by]] + self.add_sizes(**r) + + def add_sizes_from_zipfile(self, f: Union[IO, Path], origin: Dict): + """Add size reports from a zip.""" + with zipfile.ZipFile(f, 'r') as zip_file: + for i in zip_file.namelist(): + if i.endswith('-sizes.json'): + origin['member'] = i + with zip_file.open(i) as member: + self.add_sizes_from_json(member.read(), origin) + + def add_sizes_from_file(self, filename: str): + """Add size reports from a file.""" + origin = {'file': filename} + path = Path(filename) + if path.suffix == '.json': + logging.info('Reading JSON %s', path) + with open(path) as f: + self.add_sizes_from_json(f.read(), origin) + elif path.suffix == '.zip': + logging.info('Reading ZIP %s', path) + self.add_sizes_from_zipfile(path, origin) + else: + logging.warning('Unknown file type "%s" ignored', filename) + + def add_sizes_from_github(self): + """Read size report artifacts from github.""" + if not self.gh: + return + + # Size artifacts have names of the form + # Size,{group},{pr},{commit_hash},{parent_hash} + # Record them keyed by group and commit_hash to match them up + # after we have the entire list. + size_artifacts: Dict[str, Dict[str, fastcore.basics.AttrDict]] = {} + for i in ghapi.all.paged(self.gh.actions.list_artifacts_for_repo): + if not i.artifacts: + break + for a in i.artifacts: + if a.name.startswith('Size,'): + _, group, pr, commit, parent, *_ = (a.name + ',').split( + ',', 5) + a.parent = parent + a.pr = pr + a.created_at = dateutil.parser.isoparse(a.created_at) + if group not in size_artifacts: + size_artifacts[group] = {} + size_artifacts[group][commit] = a + + # Determine required size artifacts. + required_artifact_ids: set[int] = set() + for group, group_reports in size_artifacts.items(): + logging.info('Group %s', group) + for report in group_reports.values(): + if self.config['report.pr' if report.pr else 'report.push']: + if report.parent not in group_reports: + logging.info(' No match for %s', report.name) + continue + # We have size information for both this report and its + # parent, so ensure that both artifacts are downloaded. + parent = group_reports[report.parent] + required_artifact_ids.add(report.id) + required_artifact_ids.add(parent.id) + logging.info(' Match %s', report.parent) + logging.info(' %s %s', report.id, report.name) + logging.info(' %s %s', parent.id, parent.name) + + # Download and add required artifacts. + for i in required_artifact_ids: + logging.debug('Download artifact %d', i) + try: + blob = self.gh.actions.download_artifact(i, 'zip') + except Exception as e: + logging.error('Failed to download artifact %d: %s', i, e) + self.add_sizes_from_zipfile(io.BytesIO(blob), {'artifact': i}) + + def read_inputs(self): + """Read size report from github and/or local files.""" + self.add_sizes_from_github() + for filename in self.config['args.inputs']: + self.add_sizes_from_file(filename) + self.commit() + + def select_matching_commits(self): + """Find matching builds, where one's commit is the other's parent.""" + return self.execute(''' + SELECT DISTINCT c.pr AS pr, c.hash AS hash, p.hash AS parent + FROM build c + INNER JOIN build p ON p.hash = c.parent + WHERE c.commented = 0 + ORDER BY c.pr, c.hash, p.hash ASC + ''') + + def set_commented(self, build_ids: Iterable[int]): + """Set the commented flag for the given builds.""" + if not build_ids: + return + for build_id in build_ids: + self.execute('UPDATE build SET commented = 1 WHERE id = ?', + (build_id, )) + self.commit() + + def delete_stale_builds(self, build_ids: Iterable[int]): + """Delete stale builds.""" + if not build_ids: + return + for build_id in build_ids: + logging.info('Deleting obsolete build %d', build_id) + self.execute('DELETE FROM size WHERE build_id = ?', (build_id, )) + self.execute('DELETE FROM build WHERE id = ?', (build_id, )) + self.commit() + + def delete_artifact(self, artifact_id: int): + if self.gh and artifact_id not in self.deleted_artifacts: + self.deleted_artifacts.add(artifact_id) + self.gh.actions.delete_artifact(artifact_id) + + def delete_stale_artifacts(self, stale_artifacts: Iterable[int]): + if not self.config['github.keep']: + for artifact_id in stale_artifacts: + logging.info('Deleting obsolete artifact %d', artifact_id) + self.delete_artifact(artifact_id) + + +def gh_open(config: Config) -> Optional[ghapi.core.GhApi]: + """Return a GhApi, if so configured.""" + gh: Optional[ghapi.core.GhApi] = None + if config['github.repository']: + owner, repo = config.get('github.repository').split('/', 1) + config.put('github.owner', owner) + config.put('github.repo', repo) + if not config['github.token']: + config['github.token'] = os.environ.get('GITHUB_TOKEN') + if not config['github.token']: + logging.error('Missing --github-token') + return None + token = config['github.token'] + if token != 'SKIP': + gh = ghapi.all.GhApi(owner=owner, + repo=repo, + token=config['github.token']) + return gh + + +def gh_get_comments_for_pr(gh: ghapi.core.GhApi, pr: int): + return itertools.chain.from_iterable( + ghapi.all.paged(gh.issues.list_comments, pr)) + + +def percent_change(a: int, b: int) -> float: + if a == 0: + return 0.0 if b == 0 else float('inf') + return 100. * (b - a) / a + + +def changes_for_commit(db: SizeDatabase, pr: int, commit: str, + parent: str) -> pd.DataFrame: + """Return a DataFrame with size changes between the given commits.""" + cur = db.execute( + ''' + SELECT DISTINCT + t.id AS thing, + cb.artifact AS artifact, + pb.id AS parent_build, + cb.id AS commit_build, + t.platform, t.config, t.target, + cs.name, + ps.size AS parent_size, + cs.size AS commit_size, + cs.size - ps.size AS change + FROM thing t + INNER JOIN build cb ON cb.thing_id = t.id + INNER JOIN build pb ON pb.thing_id = t.id AND pb.hash = cb.parent + INNER JOIN size cs ON cs.build_id = cb.id + INNER JOIN size ps ON ps.build_id = pb.id AND cs.name = ps.name + WHERE cb.hash = ? AND pb.hash = ? + ORDER BY t.platform, t.config, t.target, + cs.name, cb.time DESC, pb.time DESC + ''', (commit, parent)) + + keep = ('platform', 'target', 'config', 'name', 'parent_size', + 'commit_size', 'change') + things: set[int] = set() + artifacts: set[int] = set() + builds: set[int] = set() + stale_builds: set[int] = set() + stale_artifacts: set[int] = set() + previous: Optional[sqlite3.Row] = None + rows = [] + + for row in cur.fetchall(): + row = sqlite3.Row(cur, row) + things.add(row['thing']) + if (previous is not None and row['thing'] == previous['thing'] + and row['name'] == previous['name']): + # This is duplicate build, older because we sort descending, + # presumably from a partial workflow re-run. + if row['parent_build'] != previous['parent_build']: + stale_builds.add(row['parent_build']) + if row['commit_build'] != previous['commit_build']: + stale_builds.add(row['commit_build']) + stale_artifacts.add(row['artifact']) + else: + previous = row + new = [row[k] for k in keep] + new.append(percent_change(row['parent_size'], row['commit_size'])) + rows.append(new) + artifacts.add(row['artifact']) + builds.add(row['commit_build']) + + db.delete_stale_builds(stale_builds) + db.delete_stale_artifacts(stale_artifacts) + + df = pd.DataFrame(rows, + columns=('platform', 'target', 'config', 'section', + parent[:8], commit[:8], 'change', '% change')) + df.attrs = { + 'name': f'{pr},{commit},{parent}', + 'title': (f'PR #{pr}: ' if pr else '') + + f'Size comparison from {commit} to {parent}', + 'things': things, + 'builds': builds, + 'artifacts': artifacts, + 'pr': pr, + 'commit': commit, + 'parent': parent, + } + return df + + +def gh_send_change_report(db: SizeDatabase, df: pd.DataFrame, + tdf: pd.DataFrame) -> bool: + """Send a change report as a github comment.""" + if not db.gh: + return False + pr = df.attrs['pr'] + title = df.attrs['title'] + existing_comment_id = 0 + for comment in gh_get_comments_for_pr(db.gh, pr): + if comment.body.partition('\n')[0] == df.attrs['title']: + existing_comment_id = comment.id + title = comment.body + break + + md = io.StringIO() + md.write(title) + md.write('\n') + + if tdf is not None and not tdf.empty: + md.write(f'\n**{tdf.attrs["title"]}:**\n\n') + memdf.report.write_df(db.config, + tdf, + md, + 'pipe', + hierify=True, + title=False, + tabulate={'floatfmt': '5.1f'}) + + count = len(df.attrs['things']) + summary = f'{count} build{"" if count == 1 else "s"}' + md.write(f'\n
\n{summary}\n\n') + memdf.report.write_df(db.config, + df, + md, + 'pipe', + hierify=True, + title=False, + tabulate={'floatfmt': '5.1f'}) + md.write('\n
\n') + text = md.getvalue() + md.close() + + try: + if existing_comment_id: + db.gh.issues.update_comment(existing_comment_id, text) + else: + db.gh.issues.create_comment(pr, text) + return True + except Exception: + return False + + +def report_matching_commits(db: SizeDatabase) -> Dict[str, pd.DataFrame]: + """Report on all new comparable commits.""" + if not (db.config['report.pr'] or db.config['report.push']): + return {} + dfs = {} + for pr, commit, parent in db.select_matching_commits().fetchall(): + if not db.config['report.pr' if pr else 'report.push']: + continue + df = changes_for_commit(db, pr, commit, parent) + dfs[df.attrs['name']] = df + + if threshold := db.config['report.increases']: + tdf = df[df['% change'] > threshold] + else: + tdf = None + if tdf is not None and not tdf.empty: + commit = df.attrs['commit'] + parent = df.attrs['parent'] + tdf.attrs['name'] = f'L,{commit},{parent}' + tdf.attrs['title'] = ( + f'Increases above {threshold:.1f}% from {commit} to {parent}') + dfs[tdf.attrs['name']] = tdf + + if pr and db.config['github.comment']: + if gh_send_change_report(db, df, tdf): + # Mark the originating builds, and remove the originating + # artifacts, so that they don't generate duplicate report + # comments. + db.set_commented(df.attrs['builds']) + if not db.config['github.keep']: + for artifact_id in df.attrs['artifacts']: + logging.info('Deleting artifact %d', artifact_id) + db.delete_artifact(artifact_id) + return dfs + + +def report_queries(db: SizeDatabase) -> Dict[str, pd.DataFrame]: + """Perform any requested SQL queries.""" + dfs = {} + q = 0 + for query in db.config['report.query']: + q += 1 + cur = db.execute(query) + columns = [i[0] for i in cur.description] + rows = cur.fetchall() + if rows: + df = pd.DataFrame(rows, columns=columns) + df.attrs = {'name': f'query{q}', 'title': query} + dfs[df.attrs['name']] = df + db.commit() + return dfs + + +def main(argv): + status = 0 + try: + config = Config().init({ + **memdf.util.config.CONFIG, + **memdf.util.sqlite.CONFIG, + **memdf.report.OUTPUT_CONFIG, + **GITHUB_CONFIG, + }) + config.argparse.add_argument('inputs', metavar='FILE', nargs='*') + config.parse(argv) + + dfs = {} + with SizeDatabase(config) as db: + db.read_inputs() + dfs.update(report_matching_commits(db)) + dfs.update(report_queries(db)) + + memdf.report.write_dfs(config, + dfs, + hierify=True, + title=True, + tabulate={'floatfmt': '5.1f'}) + + except Exception as exception: + status = 1 + raise exception + + return status + + +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff --git a/scripts/tools/memory/gh_sizes.py b/scripts/tools/memory/gh_sizes.py new file mode 100755 index 00000000000000..65f5415c6c07c6 --- /dev/null +++ b/scripts/tools/memory/gh_sizes.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +""" +This is similar to scripts/tools/memory/report_summary.py, but generates +a specific output format with a simplified interface for use in github +workflows. + +Usage: gh_sizes.py ‹platform› ‹config› ‹target› ‹binary› [‹output›] [‹option›…] + ‹platform› - Platform name, corresponding to a config file + in scripts/tools/memory/platform/ + ‹config› - Configuration identification string. + ‹target› - Build artifact identification string. + ‹binary› - Binary build artifact. + ‹output› - Output name or directory. + ‹option›… - Other options as for report_summary. + +This script also expects certain environment variables, which can be set in a +github workflow as follows: + + env: + BUILD_TYPE: nrfconnect + GH_EVENT_PR: ${{ github.event_name == 'pull_request' && github.event.number || 0 }} + GH_EVENT_HASH: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + GH_EVENT_PARENT: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} + +Default output file is {platform}-{configname}-{buildname}-sizes.json in the +binary's directory. This file has the form: + + { + "platform": "‹platform›", + "config": "‹config›", + "target": "‹target›", + "time": 1317645296, + "input": "‹binary›", + "event": "pull_request", + "hash": "496620796f752063616e20726561642074686973", + "parent": "20796f752061726520746f6f20636c6f73652e0a", + "pr": 12345, + "by": "section", + "frames": { + "section": [ + {"section": ".bss", "size": 260496}, + {"section": ".data", "size": 1648}, + {"section": ".text", "size": 740236} + ] + } + } + +""" + +import datetime +import logging +import os +import pathlib +import sys + +import memdf.collect +import memdf.report +import memdf.select +import memdf.util + +from memdf import Config, ConfigDescription, DFs, SectionDF + +PLATFORM_CONFIG_DIR = pathlib.Path('scripts/tools/memory/platform') + +CONFIG: ConfigDescription = { + 'event': { + 'help': 'Github workflow event name', + 'metavar': 'NAME', + 'default': os.environ.get('GITHUB_EVENT_NAME'), + }, + 'pr': { + 'help': 'Github PR number', + 'metavar': 'NUMBER', + 'default': int(os.environ.get('GH_EVENT_PR', '0')), + }, + 'hash': { + 'help': 'Current commit hash', + 'metavar': 'HASH', + 'default': os.environ.get('GH_EVENT_HASH'), + }, + 'parent': { + 'help': 'Parent commit hash', + 'metavar': 'HASH', + 'default': os.environ.get('GH_EVENT_PARENT'), + }, + 'timestamp': { + 'help': 'Build timestamp', + 'metavar': 'TIME', + 'default': int(datetime.datetime.now().timestamp()), + }, +} + + +def main(argv): + status = 0 + + try: + _, platform, config_name, target_name, binary, *args = argv + except ValueError: + program = pathlib.Path(argv[0]) + logging.error( + """ + Usage: %s platform config target binary [output] [options] + + This is intended for use in github workflows. + For other purposes, a general program for the same operations is + %s/report_summary.py + + """, program.name, program.parent) + return 1 + + try: + config_file = pathlib.Path(platform) + if config_file.is_file(): + platform = config_file.stem + else: + config_file = (PLATFORM_CONFIG_DIR / platform).with_suffix('.cfg') + + output_base = f'{platform}-{config_name}-{target_name}-sizes.json' + if args and not args[0].startswith('-'): + out, *args = args + output = pathlib.Path(out) + if out.endswith('/') and not output.exists(): + output.mkdir(parents=True) + if output.is_dir(): + output = output / output_base + else: + output = pathlib.Path(binary).parent / output_base + + config = Config().init({ + **memdf.util.config.CONFIG, + **memdf.collect.CONFIG, + **memdf.select.CONFIG, + **memdf.report.OUTPUT_CONFIG, + **CONFIG, + }) + config.put('output.file', output) + config.put('output.format', 'json_records') + if config_file.is_file(): + config.read_config_file(config_file) + else: + logging.warning('Missing config file: %s', config_file) + config.parse([argv[0]] + args) + + config.put('output.metadata.platform', platform) + config.put('output.metadata.config', config_name) + config.put('output.metadata.target', target_name) + config.put('output.metadata.time', config['timestamp']) + config.put('output.metadata.input', binary) + config.put('output.metadata.by', 'section') + for key in ['event', 'hash', 'parent', 'pr']: + if value := config[key]: + config.putl(['output', 'metadata', key], value) + + collected: DFs = memdf.collect.collect_files(config, [binary]) + + sections = collected[SectionDF.name] + section_summary = sections[['section', + 'size']].sort_values(by='section') + section_summary.attrs['name'] = "section" + + summaries = { + 'section': section_summary, + } + + # Write configured (json) report to the output file. + memdf.report.write_dfs(config, summaries) + + # Write text report to stdout. + memdf.report.write_dfs(config, summaries, sys.stdout, 'simple') + + except Exception as exception: + status = 1 + raise exception + + return status + + +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff --git a/scripts/tools/memory/memdf/collect.py b/scripts/tools/memory/memdf/collect.py index b521d1183aef9a..b04c7b87d2b63c 100644 --- a/scripts/tools/memory/memdf/collect.py +++ b/scripts/tools/memory/memdf/collect.py @@ -284,6 +284,12 @@ def postprocess_collected(config: Config, dfs: DFs) -> None: dfs[c.name] = memdf.select.select_configured_column( config, dfs[c.name], column) + for df in dfs.values(): + if demangle := set((c for c in df.columns if c.endswith('symbol'))): + df.attrs['demangle'] = demangle + if hexify := set((c for c in df.columns if c.endswith('address'))): + df.attrs['hexify'] = hexify + FileReader = Callable[[Config, str, str], DFs] diff --git a/scripts/tools/memory/memdf/collector/elftools.py b/scripts/tools/memory/memdf/collector/elftools.py index 3219a4c11ac73d..84f4e16ba7ab19 100644 --- a/scripts/tools/memory/memdf/collector/elftools.py +++ b/scripts/tools/memory/memdf/collector/elftools.py @@ -37,7 +37,7 @@ def read_segments(config: Config, ef: ELFFile) -> SegmentDF: rows = [] for segment in ef.iter_segments(): rows.append([ - elftools.elf.descriptions.describe_p_type(segment['p_type']), + segment['p_type'], segment['p_vaddr'], segment['p_paddr'], segment['p_memsz'], segment['p_flags'] ]) diff --git a/scripts/tools/memory/memdf/report.py b/scripts/tools/memory/memdf/report.py index 5bf5246293d27e..0cd5cfe30b45fa 100644 --- a/scripts/tools/memory/memdf/report.py +++ b/scripts/tools/memory/memdf/report.py @@ -17,10 +17,12 @@ import contextlib import io +import json import pathlib import sys -from typing import Callable, Dict, IO, Optional, Union +from typing import (Any, Callable, Dict, List, Mapping, IO, Optional, Protocol, + Sequence, Tuple, Union) import cxxfilt # type: ignore import pandas as pd # type: ignore @@ -96,6 +98,38 @@ def demangle(symbol: str): return symbol +def hierify_rows(table: Sequence[Sequence[Any]]) -> List[List[Any]]: + if not table: + return table + persist = None + rows = [] + for row in table: + if persist is None: + persist = [None] * len(row) + new_persist = [] + new_row = [] + changed = False + for old, new in zip(persist, list(row)): + if not changed and isinstance(new, str) and new == old: + new_row.append('') + new_persist.append(old) + else: + changed = True + new_row.append(new) + new_persist.append(new) + rows.append(new_row) + persist = new_persist + return rows + + +def hierify(df: pd.DataFrame) -> pd.DataFrame: + columns = list(df.columns) + rows = hierify_rows(df.itertuples(index=False)) + r = pd.DataFrame(rows, columns=columns) + r.attrs = df.attrs + return r + + # Output OUTPUT_FILE_CONFIG: ConfigDescription = { @@ -112,38 +146,19 @@ def demangle(symbol: str): }, } -OUTPUT_FORMAT_CONFIG: ConfigDescription = { - Config.group_def('output'): { - 'title': 'output options', - }, - 'output.format': { - 'help': - 'Output format', - 'metavar': - 'FORMAT', - 'default': - 'text', - 'choices': [ - 'text', - 'csv', - 'tsv', - 'json_split', - 'json_records', - 'json_index', - 'json_columns', - 'json_values', - 'json_table', - ], - 'argparse': { - 'alias': ['--to', '-t'], - }, - }, -} -OUTPUT_CONFIG: ConfigDescription = { - **OUTPUT_FILE_CONFIG, - **OUTPUT_FORMAT_CONFIG, -} +def postprocess_output_metadata(config: Config, key: str) -> None: + """For --output-metadata=KEY:VALUE list, convert to dictionary.""" + assert key == 'output.metadata' + metadata = {} + for s in config.get(key): + if ':' in s: + k, v = s.split(':', 1) + else: + k, v = s, True + metadata[k] = v + config.put(key, metadata) + OutputOption = Union[IO, str, None] @@ -158,7 +173,8 @@ def open_output(config: Config, if isinstance(output, str): filename = output else: - if not (filename := config['output.file']): + filename = config['output.file'] + if (not filename) or (filename == '-'): yield sys.stdout return if suffix: @@ -168,22 +184,21 @@ def open_output(config: Config, f.close() -def write_table(config: Config, df: DF, output: IO) -> None: +# Single-table writers. + +def write_nothing(config: Config, df: DF, output: IO, **_kwargs) -> None: + pass + + +def write_text(config: Config, df: DF, output: IO, **_kwargs) -> None: """Write a memory usage data frame as a human-readable table.""" memdf.util.pretty.debug(df) if df.shape[0]: df = df.copy() - if 'symbol' in df.columns and config['report.demangle']: - df['symbol'] = df['symbol'].apply(demangle) last_column_is_left_justified = False formatters = [] for column in df.columns: - if column.endswith('address'): - # Hex format address. - width = (int(df[column].max()).bit_length() + 3) // 4 - formatters.append(lambda x: - '{0:0{width}X}'.format(x, width=width)) - elif pd.api.types.is_string_dtype(df.dtypes[column]): + if pd.api.types.is_string_dtype(df.dtypes[column]): df[column] = df[column].astype(str) # Left justify strings. width = max(len(column), df[column].str.len().max()) @@ -204,35 +219,49 @@ def write_table(config: Config, df: DF, output: IO) -> None: print(' '.join(df.columns)) -def write_text(config: Config, frames: DFs, output: OutputOption, - method: str) -> None: - """Write a group of of memory usage data frames as human-readable text.""" - with open_output(config, output) as out: - sep = '' - for df in frames.values(): - print(end=sep, file=out) - sep = '\n' - write_table(config, df, out) +def write_json(_config: Config, df: DF, output: IO, **kwargs) -> None: + """Write a memory usage data frame as json.""" + orient = kwargs.get('method', 'records') + # .removeprefix('json_') in 3.9 + if orient.startswith('json_'): + orient = orient[5:] + df.to_json(output, orient=orient) -def write_json(config: Config, frames: DFs, output: OutputOption, - method: str) -> None: - """Write a group of memory usage data frames as json.""" - orient = method[5:] - with open_output(config, output) as out: - sep = '[' - for df in frames.values(): - print(sep, file=out) - sep = ',' - df.to_json(out, orient=orient) - print(']', file=out) +def write_csv(_config: Config, df: DF, output: IO, **kwargs) -> None: + """Write a memory usage data frame in csv or tsv form.""" + kinds = {'csv': ',', 'tsv': '\t'} + method = kwargs.get('method', 'csv') + delimiter = kwargs.get('delimiter', kinds.get(method, method)) + df.to_csv(output, index=False, sep=delimiter) + + +def write_markdown(_config: Config, df: DF, output: IO, **kwargs) -> None: + """Write a memory usage data frame as markdown.""" + args = {k: kwargs[k] for k in ('index',) if k in kwargs} + if 'tabulate' in kwargs: + args.update(kwargs['tabulate']) + if 'tablefmt' not in args: + args['tablefmt'] = kwargs.get('method', 'pipe') + df.to_markdown(output, index=False, **args) + print(file=output) + + +# Multi-table writers. + +class DFsWriter(Protocol): + """Type checking for multiple table writers.""" + + def __call__(self, config: Config, dfs: DFs, output: OutputOption, + writer: Callable, **kwargs) -> None: + pass dfname_count = 0 -def dfname(df: DF) -> str: - """Get a name for a data frame; used when writing separate csv files.""" +def dfname(df: DF, k: str = 'unknown') -> str: + """Get a name for a data frame.""" try: return df.name except AttributeError: @@ -240,52 +269,238 @@ def dfname(df: DF) -> str: return c.name global dfname_count dfname_count += 1 - return 'unknown' + str(dfname_count) + return k + str(dfname_count) -def write_csv(config: Config, - frames: DFs, - output: OutputOption, - method: str = 'csv') -> None: - """Write a group of memory usage data frames in csv or tsv form. +def write_one(config: Config, frames: DFs, output: OutputOption, + writer: Callable, **kw) -> None: + """Write a group of of memory usage data frames to a single file.""" + with open_output(config, output) as out: + sep = '' + for df in frames.values(): + print(end=sep, file=out) + if kw.get('title') and 'titlefmt' in kw and 'title' in df.attrs: + print(kw['titlefmt'].format(df.attrs['title']), file=out) + sep = '\n' + writer(config, df, out, **kw) - When writing to files, a separate file is written for each table, - using the supplied file name as a prefix. - """ - kinds = {'csv': ',', 'tsv': '\t'} - delimiter = kinds.get(method, method) - if isinstance(output, str) and (extension := pathlib.Path(output).suffix): - pass - elif method in kinds: - extension = '.' + method - else: - extension = '.csv' + +def write_many(config: Config, frames: DFs, output: OutputOption, + writer: Callable, **kwargs) -> None: + """Write a group of memory usage data frames to multiple files.""" + if (suffix := kwargs.get('suffix')) is None: + if isinstance(output, str) and (suffix := pathlib.Path(output).suffix): + pass + elif 'method' in kwargs: + suffix = '.' + kwargs['method'] + else: + suffix = '' for df in frames.values(): name = dfname(df) - with open_output(config, output, f'-{name}{extension}') as out: - df.to_csv(out, index=False, sep=delimiter) - - -FileWriter = Callable[[Config, DFs, OutputOption, str], None] - -FILE_WRITERS: Dict[str, FileWriter] = { - 'text': write_text, - 'json_split': write_json, - 'json_records': write_json, - 'json_index': write_json, - 'json_columns': write_json, - 'json_values': write_json, - 'json_table': write_json, - 'csv': write_csv, - 'tsv': write_csv, + with open_output(config, output, f'-{name}{suffix}') as out: + writer(config, df, out, **kwargs) + + +def write_jsons(config: Config, frames: DFs, output: OutputOption, + writer: Callable, **kwargs) -> None: + """Write a group of memory usage data frames as a json dictionary.""" + with open_output(config, output) as out: + print('{', file=out) + if metadata := config['output.metadata']: + for k, v in metadata.items(): + print(f' {json.dumps(k)}: {json.dumps(v)},', file=out) + print(' "frames": ', file=out, end='') + sep = '{' + for df in frames.values(): + name = df.attrs.get('name', df.attrs.get('title', dfname(df))) + print(sep, file=out) + sep = ',' + print(f' {json.dumps(name)}: ', file=out, end='') + writer(config, df, out, indent=6, **kwargs) + print('}}', file=out) + + +def write_none(_config: Config, _frames: DFs, _output: OutputOption, + _writer: Callable, **_kwargs) -> None: + pass + + +def kwgetset(k: str, *args): + r = set() + for i in args: + r |= set(i.get(k, set())) + return r + + +def prep(config: Config, df: pd.DataFrame, kw: Dict) -> pd.DataFrame: + """Preprocess a table for output.""" + def each_column(k: str): + for column in set(df.attrs.get(k, set()) | kw.get(k, set())): + if column in df.columns: + yield column + + def maybe_copy(copied, df): + return (True, df if copied else df.copy()) + + copied = False + + if config['report.demangle']: + for column in each_column('demangle'): + copied, df = maybe_copy(copied, df) + df[column] = df[column].apply(demangle) + + for column in each_column('hexify'): + copied, df = maybe_copy(copied, df) + width = (int(df[column].max()).bit_length() + 3) // 4 + df[column] = df[column].apply( + lambda x: '{0:0{width}X}'.format(x, width=width)) + + if kw.get('hierify'): + df = hierify(df) + + return df + + +class Writer: + def __init__(self, + group: Callable, + single: Callable, + defaults: Optional[Dict] = None, + overrides: Optional[Dict] = None): + self.group = group + self.single = single + self.defaults = defaults or {} + self.overrides = overrides or {} + + def write_df(self, + config: Config, + frame: pd.DataFrame, + output: OutputOption = None, + **kwargs) -> None: + args = self._args(kwargs) + with open_output(config, output) as out: + self.single(config, prep(config, frame, args), out, **args) + + def write_dfs(self, + config: Config, + frames: DFs, + output: OutputOption = None, + **kwargs) -> None: + """Write a group of memory usage data frames.""" + args = self._args(kwargs) + frames = {k: prep(config, df, args) for k, df in frames.items()} + self.group(config, frames, output, self.single, **args) + + def _args(self, kw: Mapping) -> Dict: + r = self.defaults.copy() + r.update(kw) + r.update(self.overrides) + return r + + +class MarkdownWriter(Writer): + def __init__(self, + defaults: Optional[Dict] = None, + overrides: Optional[Dict] = None): + super().__init__(write_one, write_markdown, defaults, overrides) + + +class JsonWriter(Writer): + def __init__(self, + defaults: Optional[Dict] = None, + overrides: Optional[Dict] = None): + super().__init__(write_jsons, write_json, defaults, overrides) + self.overrides['hierify'] = False + + +class CsvWriter(Writer): + def __init__(self, + defaults: Optional[Dict] = None, + overrides: Optional[Dict] = None): + super().__init__(write_many, write_csv, defaults, overrides) + self.overrides['hierify'] = False + + +WRITERS: Dict[str, Writer] = { + 'none': Writer(write_none, write_nothing), + 'text': Writer(write_one, write_text, {'titlefmt': '\n{}\n'}), + 'json_split': JsonWriter(), + 'json_records': JsonWriter(), + 'json_index': JsonWriter(), + 'json_columns': JsonWriter(), + 'json_values': JsonWriter(), + 'json_table': JsonWriter(), + 'csv': CsvWriter({'delimiter': ','}), + 'tsv': CsvWriter({'delimiter': '\t'}), + 'plain': MarkdownWriter({'titlefmt': '\n{}\n'}), + 'simple': MarkdownWriter({'titlefmt': '\n{}\n'}), + 'grid': MarkdownWriter({'titlefmt': '\n\n'}), + 'fancy_grid': MarkdownWriter({'titlefmt': '\n\n'}), + 'html': MarkdownWriter({'titlefmt': '

'}), + 'unsafehtml': MarkdownWriter({'titlefmt': '

'}), + 'github': MarkdownWriter(), + 'pipe': MarkdownWriter(), + 'orgtbl': MarkdownWriter(), + 'jira': MarkdownWriter(), + 'presto': MarkdownWriter(), + 'pretty': MarkdownWriter(), + 'psql': MarkdownWriter(), + 'rst': MarkdownWriter(), + 'mediawiki': MarkdownWriter(), + 'moinmoin': MarkdownWriter(), + 'youtrack': MarkdownWriter(), + 'latex': MarkdownWriter(), + 'latex_raw': MarkdownWriter(), + 'latex_booktabs': MarkdownWriter(), + 'latex_longtable': MarkdownWriter(), + 'textile': MarkdownWriter(), +} + +OUTPUT_FORMAT_CONFIG: ConfigDescription = { + Config.group_def('output'): { + 'title': 'output options', + }, + 'output.format': { + 'help': 'Output format', + 'metavar': 'FORMAT', + 'default': 'simple', + 'choices': list(WRITERS.keys()), + 'argparse': { + 'alias': ['--to', '-t'], + }, + }, + 'output.metadata': { + 'help': 'Metadata for JSON', + 'metavar': 'NAME:VALUE', + 'default': [], + 'argparse': { + 'alias': ['--metadata'] + }, + 'postprocess': postprocess_output_metadata, + } +} + +OUTPUT_CONFIG: ConfigDescription = { + **OUTPUT_FILE_CONFIG, + **OUTPUT_FORMAT_CONFIG, } def write_dfs(config: Config, frames: DFs, output: OutputOption = None, - method: Optional[str] = None) -> None: + method: Optional[str] = None, + **kwargs) -> None: """Write a group of memory usage data frames.""" - if method is None: - method = config['output.format'] - FILE_WRITERS[method](config, frames, output, method) + kwargs['method'] = method or config['output.format'] + WRITERS[kwargs['method']].write_dfs(config, frames, output, **kwargs) + + +def write_df(config: Config, + frame: DF, + output: OutputOption = None, + method: Optional[str] = None, + **kwargs) -> None: + """Write a memory usage data frame.""" + kwargs['method'] = method or config['output.format'] + WRITERS[kwargs['method']].write_df(config, frame, output, **kwargs) diff --git a/scripts/tools/memory/memdf/select.py b/scripts/tools/memory/memdf/select.py index f14d58bae1a5bb..77a3d3f05b4d1e 100644 --- a/scripts/tools/memory/memdf/select.py +++ b/scripts/tools/memory/memdf/select.py @@ -15,12 +15,16 @@ # """Data frame selection utilities.""" +import numpy as np # type: ignore + import memdf.name import memdf.util.pretty import memdf.util.config from memdf import Config, ConfigDescription, DF +from typing import Optional + def split_size(config: Config, key: str) -> None: """Split a name:size configuration value. @@ -128,14 +132,18 @@ def synthesize_region(config: Config, df: DF, column: str) -> DF: return df +def groupby_region(df: DF): + return df[(df['size'] > 0) | (df['region'] != memdf.name.UNKNOWN)] + + SYNTHESIZE = { - 'region': synthesize_region, + 'region': (synthesize_region, groupby_region), } def synthesize_column(config: Config, df: DF, column: str) -> DF: if column not in df.columns: - SYNTHESIZE[column](config, df, column) + SYNTHESIZE[column][0](config, df, column) return df @@ -152,3 +160,12 @@ def select_configured(config: Config, df: DF, columns=SELECTION_CHOICES) -> DF: for column in columns: df = select_configured_column(config, df, column) return df + + +def groupby(config: Config, df: DF, by: Optional[str] = None): + if not by: + by = config['report.by'] + df = df[[by, 'size']].groupby(by).aggregate(np.sum).reset_index() + if by in SYNTHESIZE: + df = SYNTHESIZE[by][1](df) + return df diff --git a/scripts/tools/memory/memdf/util/nd.py b/scripts/tools/memory/memdf/util/nd.py index 33010aa7cad8bf..3cfb99e62165eb 100644 --- a/scripts/tools/memory/memdf/util/nd.py +++ b/scripts/tools/memory/memdf/util/nd.py @@ -15,9 +15,9 @@ # """Nested dictionary utilities.""" -from typing import (Any, Mapping, MutableMapping, Optional) +from typing import Any, Mapping, MutableMapping, Optional, Sequence -Key = list +Key = Sequence def get(nd: Optional[Mapping], keys: Key, default: Any = None) -> Any: @@ -46,10 +46,25 @@ def put(nd: MutableMapping, keys: Key, value: Any) -> None: nd[key] = value +def store(nd: MutableMapping, keys: Key, value: Any, empty: Any, add) -> None: + """Store a value in a nested dictionary where the leaves are containers.""" + while True: + key = keys[0] + keys = keys[1:] + if not keys: + break + if key not in nd: + nd[key] = {} + nd = nd[key] + if key not in nd: + nd[key] = empty + add(nd[key], value) + + def update(nd: MutableMapping, src: Mapping) -> None: """Update a nested dictionary.""" for k, v in src.items(): - if k not in nd: + if k not in nd or nd[k] is None: nd[k] = v elif isinstance(nd[k], dict) and isinstance(v, dict): update(nd[k], v) @@ -61,4 +76,4 @@ def update(nd: MutableMapping, src: Mapping) -> None: elif type(nd[k]) == type(v): nd[k] = v else: - raise TypeError("type mismatch") + raise TypeError(f"type mismatch {k},{v} was {nd[k]}") diff --git a/scripts/tools/memory/memdf/util/sqlite.py b/scripts/tools/memory/memdf/util/sqlite.py new file mode 100644 index 00000000000000..eba40f1818de8c --- /dev/null +++ b/scripts/tools/memory/memdf/util/sqlite.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +"""Wrapper and utility functions around sqlite3""" + +import sqlite3 + +from typing import List, Optional + +from memdf import Config, ConfigDescription + +CONFIG: ConfigDescription = { + Config.group_def('database'): { + 'title': 'database options', + }, + 'database.file': { + 'help': 'Sqlite3 file', + 'metavar': 'FILENAME', + 'default': ':memory:', + 'argparse': { + 'alias': ['--db'], + }, + }, +} + + +class Database: + """Wrapper and utility functions around sqlite3""" + on_open: Optional[List[str]] = None + on_writable: Optional[List[str]] = None + + def __init__(self, filename: str, writable: bool = True): + self.filename = filename + self.writable = writable + self.con: Optional[sqlite3.Connection] = None + + def __enter__(self): + return self.open() + + def __exit__(self, et, ev, traceback): + self.close() + return False + + def open(self): + """Open and initialize the database connection.""" + if not self.con: + db = 'file:' + self.filename + if not self.writable: + db += '?mode=ro' + self.con = sqlite3.connect(db, uri=True) + if self.on_open: + for i in self.on_open: + self.con.execute(i) + if self.writable and self.on_writable: + for i in self.on_writable: + self.con.execute(i) + return self + + def close(self): + if self.con: + self.con.close() + self.con = None + return self + + def connection(self) -> sqlite3.Connection: + assert self.con + return self.con + + def execute(self, query, parameters=None): + if parameters: + return self.con.execute(query, parameters) + return self.con.execute(query) + + def commit(self): + self.con.commit() + return self + + def store(self, table: str, **kwargs): + """Insert the data if it does not already exist.""" + q = (f"INSERT INTO {table} ({','.join(kwargs.keys())})" + f" VALUES ({','.join('?' * len(kwargs))})" + f" ON CONFLICT DO NOTHING") + v = list(kwargs.values()) + self.connection().execute(q, v) + + def get_matching(self, table: str, columns: List[str], **kwargs): + return self.connection().execute( + f"SELECT {','.join(columns)} FROM {table}" + f" WHERE {'=? AND '.join(kwargs.keys())}=?", + list(kwargs.values())) + + def get_matching_id(self, table: str, **kwargs): + return self.get_matching(table, ['id'], **kwargs).fetchone()[0] + + def store_and_return_id(self, table: str, **kwargs) -> int: + self.store(table, **kwargs) + return self.get_matching_id(table, **kwargs) diff --git a/scripts/tools/memory/platform/esp32.cfg b/scripts/tools/memory/platform/esp32.cfg index 3b140fe93ac55a..650af9c33a5bfb 100644 --- a/scripts/tools/memory/platform/esp32.cfg +++ b/scripts/tools/memory/platform/esp32.cfg @@ -18,7 +18,7 @@ 'section': { # By default, only these sections will be included # when operating by sections. - 'default': ['.flash.text', '.flash.rodata', '.dram0.bss', '.dram0'.data', '.iram0.text'] + 'default': ['.flash.text', '.flash.rodata', '.dram0.bss', '.dram0.data', '.iram0.text'] }, 'symbol': { 'free': { diff --git a/scripts/tools/memory/platform/linux.cfg b/scripts/tools/memory/platform/linux.cfg new file mode 100644 index 00000000000000..2f11c3f4d4db99 --- /dev/null +++ b/scripts/tools/memory/platform/linux.cfg @@ -0,0 +1,77 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Memory tools default configuation for Linux. + +{ + 'section': { + # By default, only these sections will be included + # when operating by sections. + 'default': [ + '.text', '.data', '.data.rel.ro', '.bss', '.dynamic', '.got', + '.init', '.init_array', '.rodata' + ] + }, +# 'symbol': { +# 'free': { +# # These symbols mark the start or end of areas where memory that +# # does not belong to any symbol is considered unused (rather than +# # a gap that may be in use for some non-symbol purpose, e.g. string +# # constants or alignment). +# 'start': [], +# 'end': [], +# } +# }, + 'region': { + # Regions are sets of sections that can be used for aggregate reports. + 'sections': { + 'FLASH': [ + ".dynstr", + ".dynsym", + ".eh_frame_hdr", + ".eh_frame", + ".fini", + ".gcc_except_table", + ".gnu.version_d", + ".gnu.version_r", + ".gnu.version", + ".hash", + ".init", + ".interp", + ".note.ABI-tag", + ".rodata1", + ".rodata", + ".strtab", + ".symtab", + ".text", + ], + 'RAM': [ + ".bss", + ".ctors", + ".data1", + ".data.rel.ro", + ".data", + ".dtors", + ".dynamic", + ".fini_array", + ".got.plt", + ".init_array", + ".jcr", + ".preinit_array", + ".tbss", + ".tdata", + ] + } + }, +} diff --git a/scripts/tools/memory/platform/mbed.cfg b/scripts/tools/memory/platform/mbed.cfg new file mode 100644 index 00000000000000..f261ef24a6f9d3 --- /dev/null +++ b/scripts/tools/memory/platform/mbed.cfg @@ -0,0 +1,42 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Memory tools default configuation for Mbed. + +{ + 'section': { + # By default, only these sections will be included + # when operating by sections. + 'default': ['.text', '.data', '.bss', '.heap'], + }, +# 'symbol': { +# 'free': { +# # These symbols mark the start or end of areas where memory that +# # does not belong to any symbol is considered unused (rather than +# # a gap that may be in use for some non-symbol purpose, e.g. string +# # constants or alignment). +# 'start': [], +# 'end': [], +# } +# }, +# 'region': { +# # Regions are sets of sections that can be used for aggregate reports. +# 'sections': { +# 'FLASH': [ +# ], +# 'RAM': [ +# ] +# } +# }, +} diff --git a/scripts/tools/memory/platform/p6.cfg b/scripts/tools/memory/platform/p6.cfg new file mode 100644 index 00000000000000..96990a3cc7b5b6 --- /dev/null +++ b/scripts/tools/memory/platform/p6.cfg @@ -0,0 +1,42 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Memory tools default configuation for Infineon P6. + +{ + 'section': { + # By default, only these sections will be included + # when operating by sections. + 'default': ['.text', '.data', '.bss', '.heap'], + }, +# 'symbol': { +# 'free': { +# # These symbols mark the start or end of areas where memory that +# # does not belong to any symbol is considered unused (rather than +# # a gap that may be in use for some non-symbol purpose, e.g. string +# # constants or alignment). +# 'start': [], +# 'end': [], +# } +# }, +# 'region': { +# # Regions are sets of sections that can be used for aggregate reports. +# 'sections': { +# 'FLASH': [ +# ], +# 'RAM': [ +# ] +# } +# }, +} diff --git a/scripts/tools/memory/platform/telink.cfg b/scripts/tools/memory/platform/telink.cfg new file mode 100644 index 00000000000000..4db7fcd95fc201 --- /dev/null +++ b/scripts/tools/memory/platform/telink.cfg @@ -0,0 +1,42 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Memory tools default configuation for Telink. + +{ + 'section': { + # By default, only these sections will be included + # when operating by sections. + 'default': ['bss', 'noinit', 'ram_code' 'rodata', 'text'] + }, +# 'symbol': { +# 'free': { +# # These symbols mark the start or end of areas where memory that +# # does not belong to any symbol is considered unused (rather than +# # a gap that may be in use for some non-symbol purpose, e.g. string +# # constants or alignment). +# 'start': [], +# 'end': [], +# } +# }, +# 'region': { +# # Regions are sets of sections that can be used for aggregate reports. +# 'sections': { +# 'FLASH': [ +# ], +# 'RAM': [ +# ] +# } +# }, +} diff --git a/scripts/tools/memory/report_summary.py b/scripts/tools/memory/report_summary.py index a0f7002e0dfe80..489600c7a1af3f 100755 --- a/scripts/tools/memory/report_summary.py +++ b/scripts/tools/memory/report_summary.py @@ -49,10 +49,8 @@ def main(argv): }, argv) dfs: DFs = memdf.collect.collect_files(config) - by = config['report.by'] symbols = dfs[SymbolDF.name] - summary = symbols[[by, 'size' - ]].groupby(by).aggregate(np.sum).reset_index() + summary = memdf.select.groupby(config, symbols) memdf.report.write_dfs(config, {SymbolDF.name: summary}) except Exception as exception: From e90a2b3f097a8a06ae2fc883058d62244d6094f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=A9gevand?= <77852424+jmeg-sfy@users.noreply.github.com> Date: Mon, 13 Sep 2021 20:55:26 +0200 Subject: [PATCH 018/255] Update WindowCovering cluster revision (#9396) * WC: Update ClusterRevision to Matter initial release * WC: Update rev # for all-cluster-app --- .../all-clusters-common/all-clusters-app.zap | 4 ++-- examples/window-app/common/window-app.zap | 12 ++++++------ .../tests/suites/certification/Test_TC_WNCV_1_1.yaml | 4 ++-- .../zcl/data-model/chip/window-covering.xml | 2 +- src/controller/data_model/controller-clusters.zap | 4 ++-- src/darwin/Framework/CHIPTests/CHIPClustersTests.m | 4 ++-- .../all-clusters-app/zap-generated/endpoint_config.h | 2 +- .../chip-tool/zap-generated/test/Commands.h | 8 ++++---- .../zap-generated/endpoint_config.h | 2 +- .../window-app/zap-generated/endpoint_config.h | 4 ++-- 10 files changed, 23 insertions(+), 23 deletions(-) diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index 20ad9bca617e7d..cbe78c7faef49f 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -9266,7 +9266,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "3", + "defaultValue": "5", "reportable": 0, "minInterval": 0, "maxInterval": 65344, @@ -9562,7 +9562,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "3", + "defaultValue": "5", "reportable": 0, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/window-app/common/window-app.zap b/examples/window-app/common/window-app.zap index a70567cac6a16b..ce00bae460e2d5 100644 --- a/examples/window-app/common/window-app.zap +++ b/examples/window-app/common/window-app.zap @@ -2754,7 +2754,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "3", + "defaultValue": "5", "reportable": 0, "minInterval": 0, "maxInterval": 65344, @@ -2885,7 +2885,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "3", + "defaultValue": "5", "reportable": 0, "minInterval": 0, "maxInterval": 65344, @@ -4835,7 +4835,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "3", + "defaultValue": "5", "reportable": 0, "minInterval": 0, "maxInterval": 65344, @@ -5146,7 +5146,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "3", + "defaultValue": "5", "reportable": 0, "minInterval": 0, "maxInterval": 65344, @@ -5954,7 +5954,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "3", + "defaultValue": "5", "reportable": 0, "minInterval": 0, "maxInterval": 65344, @@ -6250,7 +6250,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "3", + "defaultValue": "5", "reportable": 0, "minInterval": 0, "maxInterval": 65344, diff --git a/src/app/tests/suites/certification/Test_TC_WNCV_1_1.yaml b/src/app/tests/suites/certification/Test_TC_WNCV_1_1.yaml index 559ead3816c182..9ca7dd106f023f 100644 --- a/src/app/tests/suites/certification/Test_TC_WNCV_1_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_WNCV_1_1.yaml @@ -23,7 +23,7 @@ tests: command: "readAttribute" attribute: "ClusterRevision" response: - value: 3 + value: 5 - label: "write the default value to mandatory global attribute: @@ -40,7 +40,7 @@ tests: command: "readAttribute" attribute: "ClusterRevision" response: - value: 3 + value: 5 - label: "read the optional global attribute: FeatureMap" disabled: 1 diff --git a/src/app/zap-templates/zcl/data-model/chip/window-covering.xml b/src/app/zap-templates/zcl/data-model/chip/window-covering.xml index 277463c34d7a3d..c1dd3dc19d5518 100644 --- a/src/app/zap-templates/zcl/data-model/chip/window-covering.xml +++ b/src/app/zap-templates/zcl/data-model/chip/window-covering.xml @@ -22,7 +22,7 @@ limitations under the License. true true - + Type PhysicalClosedLimitLift diff --git a/src/controller/data_model/controller-clusters.zap b/src/controller/data_model/controller-clusters.zap index 7bf4f0344cd3d6..df5212187e1a18 100644 --- a/src/controller/data_model/controller-clusters.zap +++ b/src/controller/data_model/controller-clusters.zap @@ -4962,7 +4962,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "3", + "defaultValue": "5", "reportable": 0, "minInterval": 0, "maxInterval": 65344, @@ -5258,7 +5258,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "3", + "defaultValue": "5", "reportable": 0, "minInterval": 0, "maxInterval": 65344, diff --git a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m index 50d8408e27f758..2ca603e6966ca3 100644 --- a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m +++ b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m @@ -4873,7 +4873,7 @@ - (void)testSendClusterTest_TC_WNCV_1_1_000000_ReadAttribute NSLog(@"read the global attribute: ClusterRevision Error: %@", err); XCTAssertEqual(err.code, 0); - XCTAssertEqual([values[@"value"] unsignedShortValue], 3); + XCTAssertEqual([values[@"value"] unsignedShortValue], 5); [expectation fulfill]; }]; @@ -4891,7 +4891,7 @@ - (void)testSendClusterTest_TC_WNCV_1_1_000001_ReadAttribute NSLog(@"reads back global attribute: ClusterRevision Error: %@", err); XCTAssertEqual(err.code, 0); - XCTAssertEqual([values[@"value"] unsignedShortValue], 3); + XCTAssertEqual([values[@"value"] unsignedShortValue], 5); [expectation fulfill]; }]; diff --git a/zzz_generated/all-clusters-app/zap-generated/endpoint_config.h b/zzz_generated/all-clusters-app/zap-generated/endpoint_config.h index 5fb753fc555518..3354ee00583c46 100644 --- a/zzz_generated/all-clusters-app/zap-generated/endpoint_config.h +++ b/zzz_generated/all-clusters-app/zap-generated/endpoint_config.h @@ -2313,7 +2313,7 @@ { 0x0013, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0xFFFF) }, /* InstalledClosedLimitTilt */ \ { 0x0017, ZAP_TYPE(BITMAP8), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0x00) }, /* Mode */ \ { 0x001A, ZAP_TYPE(BITMAP16), 2, 0, ZAP_SIMPLE_DEFAULT(0x00) }, /* SafetyStatus */ \ - { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(3) }, /* ClusterRevision */ \ + { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(5) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Barrier Control (server) */ \ { 0x0001, ZAP_TYPE(ENUM8), 1, 0, ZAP_EMPTY_DEFAULT() }, /* barrier moving state */ \ diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index e968d06cb58911..6ada916ed52cad 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -18365,9 +18365,9 @@ class Test_TC_WNCV_1_1 : public TestCommand return; } - if (clusterRevision != 3U) + if (clusterRevision != 5U) { - ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "3"); + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "5"); runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); return; } @@ -18428,9 +18428,9 @@ class Test_TC_WNCV_1_1 : public TestCommand return; } - if (clusterRevision != 3U) + if (clusterRevision != 5U) { - ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "3"); + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "5"); runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); return; } diff --git a/zzz_generated/controller-clusters/zap-generated/endpoint_config.h b/zzz_generated/controller-clusters/zap-generated/endpoint_config.h index 1a35421d860354..c541b1a62da665 100644 --- a/zzz_generated/controller-clusters/zap-generated/endpoint_config.h +++ b/zzz_generated/controller-clusters/zap-generated/endpoint_config.h @@ -139,7 +139,7 @@ { 0xFFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(CLIENT), ZAP_SIMPLE_DEFAULT(3) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Window Covering (client) */ \ - { 0xFFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(CLIENT), ZAP_SIMPLE_DEFAULT(3) }, /* ClusterRevision */ \ + { 0xFFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(CLIENT), ZAP_SIMPLE_DEFAULT(5) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Barrier Control (client) */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(CLIENT), ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ diff --git a/zzz_generated/window-app/zap-generated/endpoint_config.h b/zzz_generated/window-app/zap-generated/endpoint_config.h index a1220c3e9a1245..6995ba27a3a46a 100644 --- a/zzz_generated/window-app/zap-generated/endpoint_config.h +++ b/zzz_generated/window-app/zap-generated/endpoint_config.h @@ -810,7 +810,7 @@ { 0x0013, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0xFFFF) }, /* InstalledClosedLimitTilt */ \ { 0x0017, ZAP_TYPE(BITMAP8), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0x14) }, /* Mode */ \ { 0x001A, ZAP_TYPE(BITMAP16), 2, 0, ZAP_SIMPLE_DEFAULT(0x0000) }, /* SafetyStatus */ \ - { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(3) }, /* ClusterRevision */ \ + { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(5) }, /* ClusterRevision */ \ \ /* Endpoint: 2, Cluster: Window Covering (server) */ \ { 0x0000, ZAP_TYPE(ENUM8), 1, 0, ZAP_SIMPLE_DEFAULT(0x00) }, /* Type */ \ @@ -831,7 +831,7 @@ { 0x0013, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0xFFFF) }, /* InstalledClosedLimitTilt */ \ { 0x0017, ZAP_TYPE(BITMAP8), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0x00) }, /* Mode */ \ { 0x001A, ZAP_TYPE(BITMAP16), 2, 0, ZAP_SIMPLE_DEFAULT(0x0000) }, /* SafetyStatus */ \ - { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(3) }, /* ClusterRevision */ \ + { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(5) }, /* ClusterRevision */ \ } // This is an array of EmberAfCluster structures. From 016b1d57770bf152eace4dc49b536e6da1777982 Mon Sep 17 00:00:00 2001 From: Kevin Schoedel <67607049+kpschoedel@users.noreply.github.com> Date: Mon, 13 Sep 2021 14:59:09 -0400 Subject: [PATCH 019/255] Have Linux/MdnsImpl use System::Layer timer. (#9537) #### Problem Linux/MdnsImpl currently uses ad-hoc coupling with the POSIX I/O event loop, which intrudes on and constrains the latter's implementation. #### Change overview Replace the `GetMdnsTimeout()`/`HandleMdnsTimeout()` pair with a `System::Layer` timer tracking the earliest mDNS timeout. The last remnants of ~the Old Republic~ `select()` have been swept away. #### Testing Existing unit test TestMdns --- src/controller/java/MdnsImpl.cpp | 5 -- src/platform/Darwin/MdnsImpl.cpp | 4 -- src/platform/Linux/MdnsImpl.cpp | 69 ++++++++++++-------------- src/platform/Linux/MdnsImpl.h | 6 ++- src/system/SystemLayerImplLibevent.cpp | 11 ---- src/system/SystemLayerImplSelect.cpp | 19 ------- 6 files changed, 36 insertions(+), 78 deletions(-) diff --git a/src/controller/java/MdnsImpl.cpp b/src/controller/java/MdnsImpl.cpp index db0d6aaa978446..078ffb59fca374 100644 --- a/src/controller/java/MdnsImpl.cpp +++ b/src/controller/java/MdnsImpl.cpp @@ -103,11 +103,6 @@ CHIP_ERROR ChipMdnsResolve(MdnsService * service, Inet::InterfaceId interface, M return CHIP_NO_ERROR; } -// Implementation of other methods required by the CHIP stack - -void GetMdnsTimeout(timeval & timeout) {} -void HandleMdnsTimeout() {} - // Implemention of Java-specific functions void InitializeWithObjects(jobject resolverObject, jobject mdnsCallbackObject) diff --git a/src/platform/Darwin/MdnsImpl.cpp b/src/platform/Darwin/MdnsImpl.cpp index fe97ad1e3de6b2..2eda54e5a2ed1e 100644 --- a/src/platform/Darwin/MdnsImpl.cpp +++ b/src/platform/Darwin/MdnsImpl.cpp @@ -549,9 +549,5 @@ CHIP_ERROR ChipMdnsResolve(MdnsService * service, chip::Inet::InterfaceId interf return Resolve(context, callback, interfaceId, service->mAddressType, regtype.c_str(), service->mName); } -void GetMdnsTimeout(timeval & timeout) {} - -void HandleMdnsTimeout() {} - } // namespace Mdns } // namespace chip diff --git a/src/platform/Linux/MdnsImpl.cpp b/src/platform/Linux/MdnsImpl.cpp index 81207e5ad95c91..4590fd996312f4 100644 --- a/src/platform/Linux/MdnsImpl.cpp +++ b/src/platform/Linux/MdnsImpl.cpp @@ -29,6 +29,7 @@ #include #include #include +#include using chip::Mdns::kMdnsTypeMaxSize; using chip::Mdns::MdnsServiceProtocol; @@ -136,8 +137,6 @@ namespace Mdns { MdnsAvahi MdnsAvahi::sInstance; -constexpr uint64_t kUsPerSec = 1000 * 1000; - Poller::Poller() { mAvahiPoller.userdata = this; @@ -149,6 +148,8 @@ Poller::Poller() mAvahiPoller.timeout_new = TimeoutNew; mAvahiPoller.timeout_update = TimeoutUpdate; mAvahiPoller.timeout_free = TimeoutFree; + + mEarliestTimeout = std::chrono::steady_clock::time_point(); } AvahiWatch * Poller::WatchNew(const struct AvahiPoll * poller, int fd, AvahiWatchEvent event, AvahiWatchCallback callback, @@ -237,9 +238,10 @@ steady_clock::time_point GetAbsTimeout(const struct timeval * timeout) AvahiTimeout * Poller::TimeoutNew(const struct timeval * timeout, AvahiTimeoutCallback callback, void * context) { - mTimers.emplace_back(new AvahiTimeout{ GetAbsTimeout(timeout), callback, timeout != nullptr, context, this }); - return mTimers.back().get(); + AvahiTimeout * timer = mTimers.back().get(); + SystemTimerUpdate(timer); + return timer; } void Poller::TimeoutUpdate(AvahiTimeout * timer, const struct timeval * timeout) @@ -248,6 +250,7 @@ void Poller::TimeoutUpdate(AvahiTimeout * timer, const struct timeval * timeout) { timer->mAbsTimeout = GetAbsTimeout(timeout); timer->mEnabled = true; + static_cast(timer->mPoller)->SystemTimerUpdate(timer); } else { @@ -267,48 +270,48 @@ void Poller::TimeoutFree(AvahiTimeout & timer) mTimers.end()); } -void Poller::GetTimeout(timeval & timeout) +void Poller::SystemTimerCallback(System::Layer * layer, void * data) { - microseconds timeoutVal = seconds(timeout.tv_sec) + microseconds(timeout.tv_usec); + static_cast(data)->HandleTimeout(); +} +void Poller::HandleTimeout() +{ + mEarliestTimeout = std::chrono::steady_clock::time_point(); + steady_clock::time_point now = steady_clock::now(); + + AvahiTimeout * earliest = nullptr; for (auto && timer : mTimers) { - steady_clock::time_point absTimeout = timer->mAbsTimeout; - steady_clock::time_point now = steady_clock::now(); - if (!timer->mEnabled) { continue; } - if (absTimeout < now) + if (timer->mAbsTimeout <= now) { - timeoutVal = microseconds(0); - break; + timer->mCallback(timer.get(), timer->mContext); } else { - timeoutVal = std::min(timeoutVal, duration_cast(absTimeout - now)); + if ((earliest == nullptr) || (timer->mAbsTimeout < earliest->mAbsTimeout)) + { + earliest = timer.get(); + } } } - - timeout.tv_sec = static_cast(timeoutVal.count()) / kUsPerSec; - timeout.tv_usec = static_cast(timeoutVal.count()) % kUsPerSec; + if (earliest) + { + SystemTimerUpdate(earliest); + } } -void Poller::HandleTimeout() +void Poller::SystemTimerUpdate(AvahiTimeout * timer) { - steady_clock::time_point now = steady_clock::now(); - - for (auto && timer : mTimers) + if ((mEarliestTimeout == std::chrono::steady_clock::time_point()) || (timer->mAbsTimeout < mEarliestTimeout)) { - if (!timer->mEnabled) - { - continue; - } - if (timer->mAbsTimeout <= now) - { - timer->mCallback(timer.get(), timer->mContext); - } + mEarliestTimeout = timer->mAbsTimeout; + auto msDelay = std::chrono::duration_cast(steady_clock::now() - mEarliestTimeout).count(); + DeviceLayer::SystemLayer.StartTimer(msDelay, SystemTimerCallback, this); } } @@ -751,16 +754,6 @@ void MdnsAvahi::HandleResolve(AvahiServiceResolver * resolver, AvahiIfIndex inte chip::Platform::Delete(context); } -void GetMdnsTimeout(timeval & timeout) -{ - MdnsAvahi::GetInstance().GetPoller().GetTimeout(timeout); -} - -void HandleMdnsTimeout() -{ - MdnsAvahi::GetInstance().GetPoller().HandleTimeout(); -} - CHIP_ERROR ChipMdnsInit(MdnsAsyncReturnCallback initCallback, MdnsAsyncReturnCallback errorCallback, void * context) { return MdnsAvahi::GetInstance().Init(initCallback, errorCallback, context); diff --git a/src/platform/Linux/MdnsImpl.h b/src/platform/Linux/MdnsImpl.h index 84a31561391c0f..0842c83627aefe 100644 --- a/src/platform/Linux/MdnsImpl.h +++ b/src/platform/Linux/MdnsImpl.h @@ -62,7 +62,6 @@ class Poller public: Poller(void); - void GetTimeout(timeval & timeout); void HandleTimeout(); const AvahiPoll * GetAvahiPoll(void) const { return &mAvahiPoller; } @@ -88,8 +87,13 @@ class Poller static void TimeoutFree(AvahiTimeout * timer); void TimeoutFree(AvahiTimeout & timer); + void SystemTimerUpdate(AvahiTimeout * timer); + static void SystemTimerCallback(System::Layer * layer, void * data); + std::vector> mWatches; std::vector> mTimers; + std::chrono::steady_clock::time_point mEarliestTimeout; + AvahiPoll mAvahiPoller; }; diff --git a/src/system/SystemLayerImplLibevent.cpp b/src/system/SystemLayerImplLibevent.cpp index 1e642c443a4e33..883cefe59fe72b 100644 --- a/src/system/SystemLayerImplLibevent.cpp +++ b/src/system/SystemLayerImplLibevent.cpp @@ -30,17 +30,6 @@ #include #include -#if CHIP_DEVICE_CONFIG_ENABLE_MDNS && !__ZEPHYR__ - -namespace chip { -namespace Mdns { -void GetMdnsTimeout(timeval & timeout); -void HandleMdnsTimeout(); -} // namespace Mdns -} // namespace chip - -#endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS && !__ZEPHYR__ - #ifndef CHIP_CONFIG_LIBEVENT_DEBUG_CHECKS #define CHIP_CONFIG_LIBEVENT_DEBUG_CHECKS 1 #endif diff --git a/src/system/SystemLayerImplSelect.cpp b/src/system/SystemLayerImplSelect.cpp index 929e943cb3c99b..48900f3a21248b 100644 --- a/src/system/SystemLayerImplSelect.cpp +++ b/src/system/SystemLayerImplSelect.cpp @@ -37,17 +37,6 @@ #define PTHREAD_NULL 0 #endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING && !defined(PTHREAD_NULL) -#if CHIP_DEVICE_CONFIG_ENABLE_MDNS && !__ZEPHYR__ - -namespace chip { -namespace Mdns { -void GetMdnsTimeout(timeval & timeout); -void HandleMdnsTimeout(); -} // namespace Mdns -} // namespace chip - -#endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS && !__ZEPHYR__ - namespace chip { namespace System { @@ -351,10 +340,6 @@ void LayerImplSelect::PrepareEvents() const Clock::MonotonicMilliseconds sleepTime = (awakenTime > currentTime) ? (awakenTime - currentTime) : 0; Clock::MillisecondsToTimeval(sleepTime, mNextTimeout); -#if CHIP_DEVICE_CONFIG_ENABLE_MDNS && !__ZEPHYR__ && !__MBED__ - chip::Mdns::GetMdnsTimeout(mNextTimeout); -#endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS && !__ZEPHYR__ - mMaxFd = -1; FD_ZERO(&mSelected.mReadSet); FD_ZERO(&mSelected.mWriteSet); @@ -419,10 +404,6 @@ void LayerImplSelect::HandleEvents() } } -#if CHIP_DEVICE_CONFIG_ENABLE_MDNS && !__ZEPHYR__ && !__MBED__ - chip::Mdns::HandleMdnsTimeout(); -#endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS && !__ZEPHYR__ - #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING mHandleSelectThread = PTHREAD_NULL; #endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING From 0ca8cbd0c936ea14f3aa5ac885df3000280b11dd Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 13 Sep 2021 15:48:17 -0400 Subject: [PATCH 020/255] Simplify telink build (#9639) * Update telink build instructions to work with latest vscode image. Latest vscode image contains TELINK_ZEPHYR_SDK_DIR, no need to hardcode the path to it in the build script anymore. * Restyle fixes --- scripts/build/builders/telink.py | 36 +++++++++---------- .../build/expected_all_platform_commands.txt | 2 +- scripts/build/test.py | 1 + 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/scripts/build/builders/telink.py b/scripts/build/builders/telink.py index d4da89217b3a06..b8c547299292ff 100644 --- a/scripts/build/builders/telink.py +++ b/scripts/build/builders/telink.py @@ -60,35 +60,31 @@ def __init__(self, self.board = board def generate(self): + if os.path.exists(self.output_dir): + return - if not os.path.exists(self.output_dir): - cmd = 'export ZEPHYR_BASE="$TELINK_ZEPHYR_BASE"\n' + if not self._runner.dry_run: + # Zephyr base + if 'TELINK_ZEPHYR_BASE' not in os.environ: + raise Exception("Telink builds require TELINK_ZEPHYR_BASE") - if not self._runner.dry_run: + cmd = 'export ZEPHYR_BASE="$TELINK_ZEPHYR_BASE"\n' - # Zephyr base - if 'TELINK_ZEPHYR_BASE' not in os.environ: - # TODO: remove once variable in all images - cmd = '' - if 'ZEPHYR_BASE' not in os.environ: - raise Exception( - "Telink builds require TELINK_ZEPHYR_BASE or ZEPHYR_BASE to be set") + if 'TELINK_ZEPHYR_SDK_DIR' in os.environ: + cmd += 'export ZEPHYR_SDK_INSTALL_DIR="$TELINK_ZEPHYR_SDK_DIR"\n' - # TODO: TELINK_ZEPHYR_SDK_DIR should be used for compilation and - # NOT hardcoding of zephyr-sdk-0.13.0 - cmd += ''' + cmd += ''' export ZEPHYR_TOOLCHAIN_VARIANT=zephyr -export ZEPHYR_SDK_INSTALL_DIR="$ZEPHYR_BASE/../../zephyr-sdk-0.13.0" source "$ZEPHYR_BASE/zephyr-env.sh"; west build --cmake-only -d {outdir} -b {board} {sourcedir} '''.format( - outdir=shlex.quote( - self.output_dir), board=self.board.GnArgName(), sourcedir=shlex.quote( - os.path.join( - self.root, 'examples', self.app.ExampleName(), 'telink'))).strip() + outdir=shlex.quote( + self.output_dir), board=self.board.GnArgName(), sourcedir=shlex.quote( + os.path.join( + self.root, 'examples', self.app.ExampleName(), 'telink'))).strip() - self._Execute(['bash', '-c', cmd], - title='Generating ' + self.identifier) + self._Execute(['bash', '-c', cmd], + title='Generating ' + self.identifier) def _build(self): logging.info('Compiling Telink at %s', self.output_dir) diff --git a/scripts/build/expected_all_platform_commands.txt b/scripts/build/expected_all_platform_commands.txt index 3b3f5f78c71abf..a4c0c61879d899 100644 --- a/scripts/build/expected_all_platform_commands.txt +++ b/scripts/build/expected_all_platform_commands.txt @@ -127,8 +127,8 @@ gn gen --check --fail-on-unused-args --root={root}/examples/lock-app/p6 '--args= # Generating telink-tlsr9518adk80d-light bash -c 'export ZEPHYR_BASE="$TELINK_ZEPHYR_BASE" +export ZEPHYR_SDK_INSTALL_DIR="$TELINK_ZEPHYR_SDK_DIR" export ZEPHYR_TOOLCHAIN_VARIANT=zephyr -export ZEPHYR_SDK_INSTALL_DIR="$ZEPHYR_BASE/../../zephyr-sdk-0.13.0" source "$ZEPHYR_BASE/zephyr-env.sh"; west build --cmake-only -d {out}/telink-tlsr9518adk80d-light -b tlsr9518adk80d {root}/examples/lighting-app/telink' diff --git a/scripts/build/test.py b/scripts/build/test.py index b6f7a6d94a7ea6..87cb9403b1546a 100644 --- a/scripts/build/test.py +++ b/scripts/build/test.py @@ -47,6 +47,7 @@ def build_actual_output(root: str, out: str) -> List[str]: 'ANDROID_NDK_HOME': 'TEST_ANDROID_NDK_HOME', 'ANDROID_HOME': 'TEST_ANDROID_HOME', 'TIZEN_HOME': 'TEST_TIZEN_HOME', + 'TELINK_ZEPHYR_SDK_DIR': 'TELINK_ZEPHYR_SDK_DIR', }) retval = subprocess.run([ From c23f6f4b0e4cee4cbb76a59ba8abe9b037a7cc7a Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 13 Sep 2021 16:02:24 -0400 Subject: [PATCH 021/255] Fix system layer call: add missing brackets (#9646) --- src/platform/Linux/MdnsImpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/Linux/MdnsImpl.cpp b/src/platform/Linux/MdnsImpl.cpp index 4590fd996312f4..b19e38d1811d98 100644 --- a/src/platform/Linux/MdnsImpl.cpp +++ b/src/platform/Linux/MdnsImpl.cpp @@ -311,7 +311,7 @@ void Poller::SystemTimerUpdate(AvahiTimeout * timer) { mEarliestTimeout = timer->mAbsTimeout; auto msDelay = std::chrono::duration_cast(steady_clock::now() - mEarliestTimeout).count(); - DeviceLayer::SystemLayer.StartTimer(msDelay, SystemTimerCallback, this); + DeviceLayer::SystemLayer().StartTimer(msDelay, SystemTimerCallback, this); } } From bc2d74b7c0ae5a582fc27cd21a1d7eecd440e793 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 13 Sep 2021 16:14:23 -0400 Subject: [PATCH 022/255] Enable the src/controller tests on all platforms except nrfconnect. (#9638) 1) Modify our CHIPClientCallbacks template to suppress the "possibly unbounded stack" warning from a VLA we know we want to remove. 2) Don't try to link in BLELayer in the TestDevice test if BLE networking is disabled (so that BLELayer symbols don't actually exist). 3) Heap-allocate the huge FabricTable so we don't run into compile errors due to a stack frame being too big in TestDevice. 4) Fix the fact that SystemLayerImplSelect did not default-initialize mDispatchQueue. This matters because TestDevice does weird things with a separate SystemLayer that the PlatformManager does not know about, nor does it call InitChipStack in any case. The tests are still disabled on nrfconnect because I could not get them to link there so far. Fixes https://github.com/project-chip/connectedhomeip/issues/9173 --- src/BUILD.gn | 6 +- .../app/CHIPClientCallbacks-src.zapt | 9 + src/controller/tests/BUILD.gn | 8 +- src/controller/tests/TestDevice.cpp | 13 +- src/system/SystemLayerImplSelect.h | 2 +- .../zap-generated/CHIPClientCallbacks.cpp | 175 ++++++++++++++++++ .../zap-generated/CHIPClientCallbacks.cpp | 21 +++ 7 files changed, 221 insertions(+), 13 deletions(-) diff --git a/src/BUILD.gn b/src/BUILD.gn index 9dc4e295b73900..3239029a4c94f7 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -92,9 +92,9 @@ if (chip_build_tests) { deps += [ "${chip_root}/src/ble/tests" ] } - if (!is_clang && chip_device_platform != "darwin" && - chip_device_platform != "nrfconnect" && - chip_device_platform != "efr32") { + # On nrfconnect, the controller tests run into + # https://github.com/project-chip/connectedhomeip/issues/9630 + if (chip_device_platform != "nrfconnect") { deps += [ "${chip_root}/src/controller/tests" ] } diff --git a/src/app/zap-templates/templates/app/CHIPClientCallbacks-src.zapt b/src/app/zap-templates/templates/app/CHIPClientCallbacks-src.zapt index 29d6ffa23fe2de..7bffd70f48fe31 100644 --- a/src/app/zap-templates/templates/app/CHIPClientCallbacks-src.zapt +++ b/src/app/zap-templates/templates/app/CHIPClientCallbacks-src.zapt @@ -338,6 +338,11 @@ bool emberAfDiscoverCommandsReceivedResponseCallback(ClusterId clusterId, uint16 {{#if (chip_server_has_list_attributes)}} {{#chip_server_cluster_attributes}} {{#if isList}} +{{! TODO: This stack usage bit is not OK. See https://github.com/project-chip/connectedhomeip/issues/8558 }} +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void {{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}ListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { // TODO: Add actual support for array and lists. @@ -387,6 +392,10 @@ void {{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}ListAttribu Callback::Callback<{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}ListAttributeCallback> * cb = Callback::Callback<{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}ListAttributeCallback>::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +{{! TODO: This stack usage bit is not OK. See https://github.com/project-chip/connectedhomeip/issues/8558 }} +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ {{/if}} {{/chip_server_cluster_attributes}} diff --git a/src/controller/tests/BUILD.gn b/src/controller/tests/BUILD.gn index 45c14fcab444d6..1647574120cb31 100644 --- a/src/controller/tests/BUILD.gn +++ b/src/controller/tests/BUILD.gn @@ -23,9 +23,7 @@ chip_test_suite("tests") { test_sources = [ "TestCommissionableNodeController.cpp" ] - if (chip_device_platform == "linux" || chip_device_platform == "Darwin") { - test_sources += [ "TestDevice.cpp" ] - } + test_sources += [ "TestDevice.cpp" ] cflags = [ "-Wconversion" ] @@ -34,7 +32,5 @@ chip_test_suite("tests") { "${nlunit_test_root}:nlunit-test", ] - if (chip_device_platform == "linux" || chip_device_platform == "Darwin") { - public_deps += [ "${chip_root}/src/controller/data_model" ] - } + public_deps += [ "${chip_root}/src/controller/data_model" ] } diff --git a/src/controller/tests/TestDevice.cpp b/src/controller/tests/TestDevice.cpp index dc7c0aa305dc74..141bec9f699013 100644 --- a/src/controller/tests/TestDevice.cpp +++ b/src/controller/tests/TestDevice.cpp @@ -15,7 +15,9 @@ * limitations under the License. */ +#if CONFIG_NETWORK_LAYER_BLE #include +#endif // CONFIG_NETWORK_LAYER_BLE #include #include #include @@ -47,8 +49,12 @@ void TestDevice_EstablishSessionDirectly(nlTestSuite * inSuite, void * inContext ExchangeManager exchangeMgr; Inet::InetLayer inetLayer; System::LayerImpl systemLayer; +#if CONFIG_NETWORK_LAYER_BLE Ble::BleLayer blelayer; - FabricTable fabrics; +#endif // CONFIG_NETWORK_LAYER_BLE + // Heap-allocate the fairly large FabricTable so we don't end up with a huge + // stack. + FabricTable * fabrics = Platform::New(); secure_channel::MessageCounterManager messageCounterManager; SessionIDAllocator idAllocator; @@ -65,7 +71,7 @@ void TestDevice_EstablishSessionDirectly(nlTestSuite * inSuite, void * inContext BleListenParameters(&blelayer) #endif ); - sessionMgr.Init(&systemLayer, &transportMgr, &fabrics, &messageCounterManager); + sessionMgr.Init(&systemLayer, &transportMgr, fabrics, &messageCounterManager); exchangeMgr.Init(&sessionMgr); messageCounterManager.Init(&exchangeMgr); @@ -76,7 +82,7 @@ void TestDevice_EstablishSessionDirectly(nlTestSuite * inSuite, void * inContext .inetLayer = &inetLayer, .storageDelegate = nullptr, .idAllocator = &idAllocator, - .fabricsTable = &fabrics, + .fabricsTable = fabrics, }; Device device; NodeId mockNodeId = 1; @@ -93,6 +99,7 @@ void TestDevice_EstablishSessionDirectly(nlTestSuite * inSuite, void * inContext messageCounterManager.Shutdown(); exchangeMgr.Shutdown(); sessionMgr.Shutdown(); + Platform::Delete(fabrics); transportMgr.Close(); inetLayer.Shutdown(); systemLayer.Shutdown(); diff --git a/src/system/SystemLayerImplSelect.h b/src/system/SystemLayerImplSelect.h index c2a2ebf8eb245c..6db3abcef30b60 100644 --- a/src/system/SystemLayerImplSelect.h +++ b/src/system/SystemLayerImplSelect.h @@ -115,7 +115,7 @@ class LayerImplSelect : public LayerSocketsLoop #endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING #if CHIP_SYSTEM_CONFIG_USE_DISPATCH - dispatch_queue_t mDispatchQueue; + dispatch_queue_t mDispatchQueue = nullptr; #endif }; diff --git a/zzz_generated/controller-clusters/zap-generated/CHIPClientCallbacks.cpp b/zzz_generated/controller-clusters/zap-generated/CHIPClientCallbacks.cpp index a76a63307a3f64..f6ac35cc1df911 100644 --- a/zzz_generated/controller-clusters/zap-generated/CHIPClientCallbacks.cpp +++ b/zzz_generated/controller-clusters/zap-generated/CHIPClientCallbacks.cpp @@ -351,6 +351,10 @@ bool emberAfDiscoverCommandsReceivedResponseCallback(ClusterId clusterId, uint16 return true; } +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void ApplicationLauncherClusterApplicationLauncherListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) @@ -383,7 +387,14 @@ void ApplicationLauncherClusterApplicationLauncherListListAttributeFilter(TLV::T Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void AudioOutputClusterAudioOutputListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { @@ -421,7 +432,14 @@ void AudioOutputClusterAudioOutputListListAttributeFilter(TLV::TLVReader * tlvDa Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void ContentLauncherClusterAcceptsHeaderListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { @@ -454,7 +472,14 @@ void ContentLauncherClusterAcceptsHeaderListListAttributeFilter(TLV::TLVReader * Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void ContentLauncherClusterSupportedStreamingTypesListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) @@ -487,7 +512,14 @@ void ContentLauncherClusterSupportedStreamingTypesListAttributeFilter(TLV::TLVRe Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void DescriptorClusterDeviceListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { @@ -522,7 +554,14 @@ void DescriptorClusterDeviceListListAttributeFilter(TLV::TLVReader * tlvData, Ca Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void DescriptorClusterServerListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { @@ -554,7 +593,14 @@ void DescriptorClusterServerListListAttributeFilter(TLV::TLVReader * tlvData, Ca Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void DescriptorClusterClientListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { @@ -586,7 +632,14 @@ void DescriptorClusterClientListListAttributeFilter(TLV::TLVReader * tlvData, Ca Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void DescriptorClusterPartsListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { @@ -618,7 +671,14 @@ void DescriptorClusterPartsListListAttributeFilter(TLV::TLVReader * tlvData, Cal Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void FixedLabelClusterLabelListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { @@ -653,7 +713,14 @@ void FixedLabelClusterLabelListListAttributeFilter(TLV::TLVReader * tlvData, Cal Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void GeneralCommissioningClusterBasicCommissioningInfoListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) @@ -686,7 +753,14 @@ void GeneralCommissioningClusterBasicCommissioningInfoListListAttributeFilter(TL Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void GeneralDiagnosticsClusterNetworkInterfacesListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) @@ -734,7 +808,14 @@ void GeneralDiagnosticsClusterNetworkInterfacesListAttributeFilter(TLV::TLVReade Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void GroupKeyManagementClusterGroupsListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { @@ -772,7 +853,14 @@ void GroupKeyManagementClusterGroupsListAttributeFilter(TLV::TLVReader * tlvData Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void GroupKeyManagementClusterGroupKeysListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { @@ -816,7 +904,14 @@ void GroupKeyManagementClusterGroupKeysListAttributeFilter(TLV::TLVReader * tlvD Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void MediaInputClusterMediaInputListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { @@ -857,7 +952,14 @@ void MediaInputClusterMediaInputListListAttributeFilter(TLV::TLVReader * tlvData Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void OperationalCredentialsClusterFabricsListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { @@ -904,7 +1006,14 @@ void OperationalCredentialsClusterFabricsListListAttributeFilter(TLV::TLVReader Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void TvChannelClusterTvChannelListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { @@ -948,7 +1057,14 @@ void TvChannelClusterTvChannelListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void TargetNavigatorClusterTargetNavigatorListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) @@ -984,7 +1100,14 @@ void TargetNavigatorClusterTargetNavigatorListListAttributeFilter(TLV::TLVReader Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void TestClusterClusterListInt8uListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { @@ -1016,7 +1139,14 @@ void TestClusterClusterListInt8uListAttributeFilter(TLV::TLVReader * tlvData, Ca Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void TestClusterClusterListOctetStringListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { @@ -1049,7 +1179,14 @@ void TestClusterClusterListOctetStringListAttributeFilter(TLV::TLVReader * tlvDa Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void TestClusterClusterListStructOctetStringListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { @@ -1084,7 +1221,14 @@ void TestClusterClusterListStructOctetStringListAttributeFilter(TLV::TLVReader * Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void ThreadNetworkDiagnosticsClusterNeighborTableListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) @@ -1156,7 +1300,14 @@ void ThreadNetworkDiagnosticsClusterNeighborTableListListAttributeFilter(TLV::TL Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void ThreadNetworkDiagnosticsClusterRouteTableListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) @@ -1216,7 +1367,14 @@ void ThreadNetworkDiagnosticsClusterRouteTableListListAttributeFilter(TLV::TLVRe Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void ThreadNetworkDiagnosticsClusterSecurityPolicyListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) @@ -1252,7 +1410,14 @@ void ThreadNetworkDiagnosticsClusterSecurityPolicyListAttributeFilter(TLV::TLVRe Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void ThreadNetworkDiagnosticsClusterOperationalDatasetComponentsListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) @@ -1319,7 +1484,14 @@ void ThreadNetworkDiagnosticsClusterOperationalDatasetComponentsListAttributeFil onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void ThreadNetworkDiagnosticsClusterActiveNetworkFaultsListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) @@ -1352,6 +1524,9 @@ void ThreadNetworkDiagnosticsClusterActiveNetworkFaultsListListAttributeFilter(T Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ bool emberAfAccountLoginClusterGetSetupPINResponseCallback(EndpointId endpoint, app::CommandSender * commandObj, uint8_t * setupPIN) { diff --git a/zzz_generated/tv-app/zap-generated/CHIPClientCallbacks.cpp b/zzz_generated/tv-app/zap-generated/CHIPClientCallbacks.cpp index 0f98252f959355..383abd31bb1b37 100644 --- a/zzz_generated/tv-app/zap-generated/CHIPClientCallbacks.cpp +++ b/zzz_generated/tv-app/zap-generated/CHIPClientCallbacks.cpp @@ -351,6 +351,10 @@ bool emberAfDiscoverCommandsReceivedResponseCallback(ClusterId clusterId, uint16 return true; } +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void GeneralCommissioningClusterBasicCommissioningInfoListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) @@ -383,7 +387,14 @@ void GeneralCommissioningClusterBasicCommissioningInfoListListAttributeFilter(TL Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void OperationalCredentialsClusterFabricsListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { @@ -430,7 +441,14 @@ void OperationalCredentialsClusterFabricsListListAttributeFilter(TLV::TLVReader Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ +#if !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif // __clang__ void OperationalCredentialsClusterTrustedRootCertificatesListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) @@ -464,6 +482,9 @@ void OperationalCredentialsClusterTrustedRootCertificatesListAttributeFilter(TLV Callback::Callback::FromCancelable(onSuccessCallback); cb->mCall(cb->mContext, count, data); } +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ bool emberAfGeneralCommissioningClusterArmFailSafeResponseCallback(EndpointId endpoint, app::CommandSender * commandObj, uint8_t errorCode, uint8_t * debugText) From f0723a2b59fe7c12f2ce8311fd41341841958596 Mon Sep 17 00:00:00 2001 From: Pankaj Garg Date: Mon, 13 Sep 2021 13:44:44 -0700 Subject: [PATCH 023/255] Update PASE state machine to match the latest specifications (#9582) * Update PASE state machine to match the latest specifications * Use TLV formatted messages * Use StatusReport to indicate errors and completion * Address review comments * Address comments * some cleanup --- src/messaging/ApplicationExchangeDispatch.cpp | 8 +- src/protocols/secure_channel/Constants.h | 15 +- src/protocols/secure_channel/PASESession.cpp | 545 ++++++++++-------- src/protocols/secure_channel/PASESession.h | 25 +- .../SessionEstablishmentExchangeDispatch.cpp | 9 +- 5 files changed, 354 insertions(+), 248 deletions(-) diff --git a/src/messaging/ApplicationExchangeDispatch.cpp b/src/messaging/ApplicationExchangeDispatch.cpp index 02e7ff3ad131b7..7e7caf59c1e8e0 100644 --- a/src/messaging/ApplicationExchangeDispatch.cpp +++ b/src/messaging/ApplicationExchangeDispatch.cpp @@ -49,10 +49,10 @@ bool ApplicationExchangeDispatch::MessagePermitted(uint16_t protocol, uint8_t ty { case static_cast(Protocols::SecureChannel::MsgType::PBKDFParamRequest): case static_cast(Protocols::SecureChannel::MsgType::PBKDFParamResponse): - case static_cast(Protocols::SecureChannel::MsgType::PASE_Spake2p1): - case static_cast(Protocols::SecureChannel::MsgType::PASE_Spake2p2): - case static_cast(Protocols::SecureChannel::MsgType::PASE_Spake2p3): - case static_cast(Protocols::SecureChannel::MsgType::PASE_Spake2pError): + case static_cast(Protocols::SecureChannel::MsgType::PASE_Pake1): + case static_cast(Protocols::SecureChannel::MsgType::PASE_Pake2): + case static_cast(Protocols::SecureChannel::MsgType::PASE_Pake3): + case static_cast(Protocols::SecureChannel::MsgType::PASE_PakeError): case static_cast(Protocols::SecureChannel::MsgType::CASE_SigmaR1): case static_cast(Protocols::SecureChannel::MsgType::CASE_SigmaR2): case static_cast(Protocols::SecureChannel::MsgType::CASE_SigmaR3): diff --git a/src/protocols/secure_channel/Constants.h b/src/protocols/secure_channel/Constants.h index 48825aa182613d..387f7ff41a0ecd 100644 --- a/src/protocols/secure_channel/Constants.h +++ b/src/protocols/secure_channel/Constants.h @@ -57,10 +57,10 @@ enum class MsgType : uint8_t // Password-based session establishment Message Types PBKDFParamRequest = 0x20, PBKDFParamResponse = 0x21, - PASE_Spake2p1 = 0x22, - PASE_Spake2p2 = 0x23, - PASE_Spake2p3 = 0x24, - PASE_Spake2pError = 0x2F, + PASE_Pake1 = 0x22, + PASE_Pake2 = 0x23, + PASE_Pake3 = 0x24, + PASE_PakeError = 0x2F, // Certificate-based session establishment Message Types CASE_SigmaR1 = 0x30, @@ -72,7 +72,12 @@ enum class MsgType : uint8_t }; // Placeholder value for the ProtocolCode field when the GeneralCode is Success or Continue. -constexpr uint16_t kProtocolCodeSuccess = 0x0000; +constexpr uint16_t kProtocolCodeSuccess = 0x0000; +constexpr uint16_t kProtocolCodeNoSharedRoot = 0x0001; +constexpr uint16_t kProtocolCodeInvalidParam = 0x0002; +constexpr uint16_t kProtocolCodeCloseSession = 0x0003; +constexpr uint16_t kProtocolCodeBusy = 0x0004; +constexpr uint16_t kProtocolCodeSessionNotFound = 0x0005; // Placeholder value for the ProtocolCode field when there is no additional protocol-specific code to provide more information. constexpr uint16_t kProtocolCodeGeneralFailure = 0xFFFF; diff --git a/src/protocols/secure_channel/PASESession.cpp b/src/protocols/secure_channel/PASESession.cpp index e80bb5e6b9d6d5..6ff77062ffc82e 100644 --- a/src/protocols/secure_channel/PASESession.cpp +++ b/src/protocols/secure_channel/PASESession.cpp @@ -42,13 +42,16 @@ #include #include #include +#include #include +#include #include namespace chip { using namespace Crypto; using namespace Messaging; +using namespace Protocols::SecureChannel; const char * kSpake2pContext = "CHIP PAKE V1 Commissioning"; const char * kSpake2pI2RSessionInfo = "Commissioning I2R Key"; @@ -82,7 +85,7 @@ void PASESession::Clear() memset(&mPoint[0], 0, sizeof(mPoint)); memset(&mPASEVerifier, 0, sizeof(mPASEVerifier)); memset(&mKe[0], 0, sizeof(mKe)); - mNextExpectedMsg = Protocols::SecureChannel::MsgType::PASE_Spake2pError; + mNextExpectedMsg = MsgType::PASE_PakeError; // Note: we don't need to explicitly clear the state of mSpake2p object. // Clearing the following state takes care of it. @@ -273,7 +276,7 @@ CHIP_ERROR PASESession::WaitForPairing(uint32_t mySetUpPINCode, uint32_t pbkdf2I mIterationCount = pbkdf2IterCount; - mNextExpectedMsg = Protocols::SecureChannel::MsgType::PBKDFParamRequest; + mNextExpectedMsg = MsgType::PBKDFParamRequest; mPairingComplete = false; mPasscodeID = 0; @@ -346,133 +349,205 @@ CHIP_ERROR PASESession::DeriveSecureSession(SecureSession & session, SecureSessi CHIP_ERROR PASESession::SendPBKDFParamRequest() { - System::PacketBufferHandle req = System::PacketBufferHandle::New(kPBKDFParamRandomNumberSize); + ReturnErrorOnFailure(DRBG_get_bytes(mPBKDFLocalRandomData, sizeof(mPBKDFLocalRandomData))); + + const size_t max_msg_len = + EstimateTLVStructOverhead(kPBKDFParamRandomNumberSize + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint8_t), 4); + System::PacketBufferHandle req = System::PacketBufferHandle::New(max_msg_len); VerifyOrReturnError(!req.IsNull(), CHIP_ERROR_NO_MEMORY); - ReturnErrorOnFailure(DRBG_get_bytes(req->Start(), kPBKDFParamRandomNumberSize)); + System::PacketBufferTLVWriter tlvWriter; + tlvWriter.Init(std::move(req)); - req->SetDataLength(kPBKDFParamRandomNumberSize); + TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; + ReturnErrorOnFailure(tlvWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, outerContainerType)); + ReturnErrorOnFailure(tlvWriter.PutBytes(TLV::ContextTag(1), mPBKDFLocalRandomData, sizeof(mPBKDFLocalRandomData))); + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(2), GetLocalKeyId(), true)); + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(3), mPasscodeID, true)); + ReturnErrorOnFailure(tlvWriter.PutBoolean(TLV::ContextTag(4), mHavePBKDFParameters)); + // TODO - Add optional MRP parameter support to PASE + ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType)); + ReturnErrorOnFailure(tlvWriter.Finalize(&req)); // Update commissioning hash with the pbkdf2 param request that's being sent. ReturnErrorOnFailure(mCommissioningHash.AddData(ByteSpan{ req->Start(), req->DataLength() })); - mNextExpectedMsg = Protocols::SecureChannel::MsgType::PBKDFParamResponse; + mNextExpectedMsg = MsgType::PBKDFParamResponse; - ReturnErrorOnFailure(mExchangeCtxt->SendMessage(Protocols::SecureChannel::MsgType::PBKDFParamRequest, std::move(req), - SendFlags(SendMessageFlags::kExpectResponse))); + ReturnErrorOnFailure( + mExchangeCtxt->SendMessage(MsgType::PBKDFParamRequest, std::move(req), SendFlags(SendMessageFlags::kExpectResponse))); ChipLogDetail(SecureChannel, "Sent PBKDF param request"); return CHIP_NO_ERROR; } -CHIP_ERROR PASESession::HandlePBKDFParamRequest(const System::PacketBufferHandle & msg) +CHIP_ERROR PASESession::HandlePBKDFParamRequest(System::PacketBufferHandle && msg) { CHIP_ERROR err = CHIP_NO_ERROR; - // Request message processing - const uint8_t * req = msg->Start(); - size_t reqlen = msg->DataLength(); + System::PacketBufferTLVReader tlvReader; + TLV::TLVType containerType = TLV::kTLVType_Structure; + + uint16_t initiatorSessionId = 0; + uint8_t initiatorRandom[kPBKDFParamRandomNumberSize]; - VerifyOrExit(req != nullptr, err = CHIP_ERROR_MESSAGE_INCOMPLETE); - VerifyOrExit(reqlen == kPBKDFParamRandomNumberSize, err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); + uint32_t decodeTagIdSeq = 0; + bool hasPBKDFParameters = false; ChipLogDetail(SecureChannel, "Received PBKDF param request"); - // Update commissioning hash with the received pbkdf2 param request - err = mCommissioningHash.AddData(ByteSpan{ req, reqlen }); - SuccessOrExit(err); + SuccessOrExit(err = mCommissioningHash.AddData(ByteSpan{ msg->Start(), msg->DataLength() })); + + tlvReader.Init(std::move(msg)); + SuccessOrExit(err = tlvReader.Next(containerType, TLV::AnonymousTag)); + SuccessOrExit(err = tlvReader.EnterContainer(containerType)); + + SuccessOrExit(err = tlvReader.Next()); + VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.GetBytes(initiatorRandom, sizeof(initiatorRandom))); - err = SendPBKDFParamResponse(); + SuccessOrExit(err = tlvReader.Next()); + VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.Get(initiatorSessionId)); + + ChipLogDetail(SecureChannel, "Peer assigned session ID %d", initiatorSessionId); + // TODO - Update KeyId() functions to SessionId() + SetPeerKeyId(initiatorSessionId); + + SuccessOrExit(err = tlvReader.Next()); + VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.Get(mPasscodeID)); + + SuccessOrExit(err = tlvReader.Next()); + VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.Get(hasPBKDFParameters)); + + // TODO - Check if optional MRP parameters were sent. If so, cache them. + + err = SendPBKDFParamResponse(ByteSpan(initiatorRandom), hasPBKDFParameters); SuccessOrExit(err); exit: if (err != CHIP_NO_ERROR) { - SendErrorMsg(Spake2pErrorType::kUnexpected); + SendStatusReport(kProtocolCodeInvalidParam); } return err; } -CHIP_ERROR PASESession::SendPBKDFParamResponse() +CHIP_ERROR PASESession::SendPBKDFParamResponse(ByteSpan initiatorRandom, bool initiatorHasPBKDFParams) { - System::PacketBufferHandle resp; - static_assert(CHAR_BIT == 8, "Assuming sizeof() returns octets here and for sizeof(mPoint)"); - size_t resplen = kPBKDFParamRandomNumberSize + sizeof(uint64_t) + sizeof(uint32_t) + mSaltLength; + ReturnErrorOnFailure(DRBG_get_bytes(mPBKDFLocalRandomData, sizeof(mPBKDFLocalRandomData))); - size_t sizeof_point = sizeof(mPoint); - - uint8_t * msg = nullptr; - - resp = System::PacketBufferHandle::New(resplen); + const size_t max_msg_len = EstimateTLVStructOverhead( + kPBKDFParamRandomNumberSize + kPBKDFParamRandomNumberSize + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint8_t), 5); + System::PacketBufferHandle resp = System::PacketBufferHandle::New(max_msg_len); VerifyOrReturnError(!resp.IsNull(), CHIP_ERROR_NO_MEMORY); - msg = resp->Start(); + System::PacketBufferTLVWriter tlvWriter; + tlvWriter.Init(std::move(resp)); - // Fill in the random value - ReturnErrorOnFailure(DRBG_get_bytes(msg, kPBKDFParamRandomNumberSize)); + TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; + ReturnErrorOnFailure(tlvWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, outerContainerType)); + // The initiator random value is being sent back in the response as required by the specifications + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(1), initiatorRandom)); + ReturnErrorOnFailure(tlvWriter.PutBytes(TLV::ContextTag(2), mPBKDFLocalRandomData, sizeof(mPBKDFLocalRandomData))); + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(3), GetLocalKeyId(), true)); - // Let's construct the rest of the message using BufferWriter + if (!initiatorHasPBKDFParams) { - Encoding::LittleEndian::BufferWriter bbuf(&msg[kPBKDFParamRandomNumberSize], resplen - kPBKDFParamRandomNumberSize); - bbuf.Put64(mIterationCount); - bbuf.Put32(mSaltLength); - bbuf.Put(mSalt, mSaltLength); - VerifyOrReturnError(bbuf.Fit(), CHIP_ERROR_NO_MEMORY); + TLV::TLVType pbkdfParamContainer; + ReturnErrorOnFailure(tlvWriter.StartContainer(TLV::ContextTag(4), TLV::kTLVType_Structure, pbkdfParamContainer)); + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(1), mIterationCount, true)); + ReturnErrorOnFailure(tlvWriter.PutBytes(TLV::ContextTag(2), mSalt, mSaltLength)); + ReturnErrorOnFailure(tlvWriter.EndContainer(pbkdfParamContainer)); } - resp->SetDataLength(static_cast(resplen)); + ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType)); + ReturnErrorOnFailure(tlvWriter.Finalize(&resp)); // Update commissioning hash with the pbkdf2 param response that's being sent. ReturnErrorOnFailure(mCommissioningHash.AddData(ByteSpan{ resp->Start(), resp->DataLength() })); ReturnErrorOnFailure(SetupSpake2p(mIterationCount, ByteSpan(mSalt, mSaltLength))); + + size_t sizeof_point = sizeof(mPoint); ReturnErrorOnFailure(mSpake2p.ComputeL(mPoint, &sizeof_point, mPASEVerifier.mL, kSpake2p_WS_Length)); - mNextExpectedMsg = Protocols::SecureChannel::MsgType::PASE_Spake2p1; + mNextExpectedMsg = MsgType::PASE_Pake1; - ReturnErrorOnFailure(mExchangeCtxt->SendMessage(Protocols::SecureChannel::MsgType::PBKDFParamResponse, std::move(resp), - SendFlags(SendMessageFlags::kExpectResponse))); + ReturnErrorOnFailure( + mExchangeCtxt->SendMessage(MsgType::PBKDFParamResponse, std::move(resp), SendFlags(SendMessageFlags::kExpectResponse))); ChipLogDetail(SecureChannel, "Sent PBKDF param response"); return CHIP_NO_ERROR; } -CHIP_ERROR PASESession::HandlePBKDFParamResponse(const System::PacketBufferHandle & msg) +CHIP_ERROR PASESession::HandlePBKDFParamResponse(System::PacketBufferHandle && msg) { + CHIP_ERROR err = CHIP_NO_ERROR; - // Response message processing - const uint8_t * resp = msg->Start(); - size_t resplen = msg->DataLength(); + System::PacketBufferTLVReader tlvReader; + TLV::TLVType containerType = TLV::kTLVType_Structure; + + uint16_t responderSessionId = 0; + uint8_t random[kPBKDFParamRandomNumberSize]; - // This the fixed part of the message. The variable part of the message contains the salt. - // The length of the variable part is determined by the salt length in the fixed header. - static_assert(CHAR_BIT == 8, "Assuming that sizeof returns octets"); - size_t fixed_resplen = kPBKDFParamRandomNumberSize + sizeof(uint64_t) + sizeof(uint32_t); + uint32_t decodeTagIdSeq = 0; + uint32_t iterCount = 0; + uint32_t saltLength = 0; + const uint8_t * salt; ChipLogDetail(SecureChannel, "Received PBKDF param response"); - VerifyOrExit(resp != nullptr, err = CHIP_ERROR_MESSAGE_INCOMPLETE); - VerifyOrExit(resplen >= fixed_resplen, err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); + SuccessOrExit(err = mCommissioningHash.AddData(ByteSpan{ msg->Start(), msg->DataLength() })); - { - // Let's skip the random number portion of the message - const uint8_t * msgptr = &resp[kPBKDFParamRandomNumberSize]; - uint64_t iterCount = chip::Encoding::LittleEndian::Read64(msgptr); - uint32_t saltlen = chip::Encoding::LittleEndian::Read32(msgptr); + tlvReader.Init(std::move(msg)); + SuccessOrExit(err = tlvReader.Next(containerType, TLV::AnonymousTag)); + SuccessOrExit(err = tlvReader.EnterContainer(containerType)); + + SuccessOrExit(err = tlvReader.Next()); + VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + // Initiator's random value + SuccessOrExit(err = tlvReader.GetBytes(random, sizeof(random))); + VerifyOrExit(ByteSpan(random).data_equal(ByteSpan(mPBKDFLocalRandomData)), err = CHIP_ERROR_INVALID_PASE_PARAMETER); + + SuccessOrExit(err = tlvReader.Next()); + VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + // Responder's random value + SuccessOrExit(err = tlvReader.GetBytes(random, sizeof(random))); - VerifyOrExit(resplen == fixed_resplen + saltlen, err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); + SuccessOrExit(err = tlvReader.Next()); + VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.Get(responderSessionId)); - // Specifications allow message to carry a uint64_t sized iteration count. Current APIs are - // limiting it to uint32_t. Let's make sure it'll fit the size limit. - VerifyOrExit(CanCastTo(iterCount), err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); + ChipLogDetail(SecureChannel, "Peer assigned session ID %d", responderSessionId); + SetPeerKeyId(responderSessionId); - // Update commissioning hash with the received pbkdf2 param response - err = mCommissioningHash.AddData(ByteSpan{ resp, resplen }); + if (mHavePBKDFParameters) + { + // TODO - Add a unit test that exercises mHavePBKDFParameters path + err = SetupSpake2p(mIterationCount, ByteSpan(mSalt, mSaltLength)); SuccessOrExit(err); + } + else + { + SuccessOrExit(err = tlvReader.Next()); + SuccessOrExit(err = tlvReader.EnterContainer(containerType)); + decodeTagIdSeq = 0; + + SuccessOrExit(err = tlvReader.Next()); + VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.Get(iterCount)); + + SuccessOrExit(err = tlvReader.Next()); + VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + saltLength = tlvReader.GetLength(); + SuccessOrExit(err = tlvReader.GetDataPtr(salt)); - err = SetupSpake2p(static_cast(iterCount), ByteSpan(msgptr, saltlen)); + err = SetupSpake2p(iterCount, ByteSpan(salt, saltLength)); SuccessOrExit(err); } @@ -482,38 +557,46 @@ CHIP_ERROR PASESession::HandlePBKDFParamResponse(const System::PacketBufferHandl exit: if (err != CHIP_NO_ERROR) { - SendErrorMsg(Spake2pErrorType::kUnexpected); + SendStatusReport(kProtocolCodeInvalidParam); } return err; } CHIP_ERROR PASESession::SendMsg1() { + const size_t max_msg_len = EstimateTLVStructOverhead(kMAX_Point_Length, 1); + System::PacketBufferHandle msg = System::PacketBufferHandle::New(max_msg_len); + VerifyOrReturnError(!msg.IsNull(), CHIP_ERROR_NO_MEMORY); + + System::PacketBufferTLVWriter tlvWriter; + tlvWriter.Init(std::move(msg)); + + TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; + ReturnErrorOnFailure(tlvWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, outerContainerType)); + uint8_t X[kMAX_Point_Length]; size_t X_len = sizeof(X); + constexpr uint8_t kPake1_pA = 1; + ReturnErrorOnFailure( mSpake2p.BeginProver(nullptr, 0, nullptr, 0, mPASEVerifier.mW0, kSpake2p_WS_Length, mPASEVerifier.mL, kSpake2p_WS_Length)); - ReturnErrorOnFailure(mSpake2p.ComputeRoundOne(NULL, 0, X, &X_len)); + VerifyOrReturnError(X_len == sizeof(X), CHIP_ERROR_INTERNAL); + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(kPake1_pA), ByteSpan(X))); + ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType)); + ReturnErrorOnFailure(tlvWriter.Finalize(&msg)); - Encoding::LittleEndian::PacketBufferWriter bbuf(System::PacketBufferHandle::New(sizeof(uint16_t) + X_len)); - VerifyOrReturnError(!bbuf.IsNull(), CHIP_ERROR_NO_MEMORY); - bbuf.Put16(GetLocalKeyId()); - bbuf.Put(&X[0], X_len); - VerifyOrReturnError(bbuf.Fit(), CHIP_ERROR_NO_MEMORY); + mNextExpectedMsg = MsgType::PASE_Pake2; - mNextExpectedMsg = Protocols::SecureChannel::MsgType::PASE_Spake2p2; - - // Call delegate to send the Msg1 to peer - ReturnErrorOnFailure(mExchangeCtxt->SendMessage(Protocols::SecureChannel::MsgType::PASE_Spake2p1, bbuf.Finalize(), - SendFlags(SendMessageFlags::kExpectResponse))); + ReturnErrorOnFailure( + mExchangeCtxt->SendMessage(MsgType::PASE_Pake1, std::move(msg), SendFlags(SendMessageFlags::kExpectResponse))); ChipLogDetail(SecureChannel, "Sent spake2p msg1"); return CHIP_NO_ERROR; } -CHIP_ERROR PASESession::HandleMsg1_and_SendMsg2(const System::PacketBufferHandle & msg) +CHIP_ERROR PASESession::HandleMsg1_and_SendMsg2(System::PacketBufferHandle && msg1) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -523,52 +606,51 @@ CHIP_ERROR PASESession::HandleMsg1_and_SendMsg2(const System::PacketBufferHandle uint8_t verifier[kMAX_Hash_Length]; size_t verifier_len = kMAX_Hash_Length; - uint16_t data_len; // To be initialized once we compute it. + ChipLogDetail(SecureChannel, "Received spake2p msg1"); - const uint8_t * buf = msg->Start(); - size_t buf_len = msg->DataLength(); + System::PacketBufferTLVReader tlvReader; + TLV::TLVType containerType = TLV::kTLVType_Structure; - uint16_t encryptionKeyId = 0; + const uint8_t * X; + size_t X_len = 0; - ChipLogDetail(SecureChannel, "Received spake2p msg1"); + tlvReader.Init(std::move(msg1)); + SuccessOrExit(err = tlvReader.Next(containerType, TLV::AnonymousTag)); + SuccessOrExit(err = tlvReader.EnterContainer(containerType)); - VerifyOrExit(buf != nullptr, err = CHIP_ERROR_MESSAGE_INCOMPLETE); - VerifyOrExit(buf_len == sizeof(encryptionKeyId) + kMAX_Point_Length, err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); + SuccessOrExit(err = tlvReader.Next()); + VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == 1, err = CHIP_ERROR_INVALID_TLV_TAG); + X_len = tlvReader.GetLength(); + SuccessOrExit(err = tlvReader.GetDataPtr(X)); + SuccessOrExit( + err = mSpake2p.BeginVerifier(nullptr, 0, nullptr, 0, mPASEVerifier.mW0, kSpake2p_WS_Length, mPoint, sizeof(mPoint))); - err = mSpake2p.BeginVerifier(nullptr, 0, nullptr, 0, mPASEVerifier.mW0, kSpake2p_WS_Length, mPoint, sizeof(mPoint)); - SuccessOrExit(err); + SuccessOrExit(err = mSpake2p.ComputeRoundOne(X, X_len, Y, &Y_len)); + VerifyOrReturnError(Y_len == sizeof(Y), CHIP_ERROR_INTERNAL); + SuccessOrExit(err = mSpake2p.ComputeRoundTwo(X, X_len, verifier, &verifier_len)); + msg1 = nullptr; - encryptionKeyId = chip::Encoding::LittleEndian::Read16(buf); - msg->ConsumeHead(sizeof(encryptionKeyId)); + { + const size_t max_msg_len = EstimateTLVStructOverhead(Y_len + verifier_len, 2); + constexpr uint8_t kPake2_pB = 1; + constexpr uint8_t kPake2_cB = 2; - // Pass Pa to check abort condition. - err = mSpake2p.ComputeRoundOne(msg->Start(), msg->DataLength(), Y, &Y_len); - SuccessOrExit(err); + System::PacketBufferHandle msg2 = System::PacketBufferHandle::New(max_msg_len); + VerifyOrExit(!msg2.IsNull(), err = CHIP_ERROR_NO_MEMORY); - ChipLogDetail(SecureChannel, "Peer assigned session key ID %d", encryptionKeyId); - SetPeerKeyId(encryptionKeyId); + System::PacketBufferTLVWriter tlvWriter; + tlvWriter.Init(std::move(msg2)); - err = mSpake2p.ComputeRoundTwo(msg->Start(), msg->DataLength(), verifier, &verifier_len); - SuccessOrExit(err); + TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; + SuccessOrExit(err = tlvWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, outerContainerType)); + SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(kPake2_pB), ByteSpan(Y))); + SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(kPake2_cB), ByteSpan(verifier, verifier_len))); + SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType)); + SuccessOrExit(err = tlvWriter.Finalize(&msg2)); - // Make sure our addition doesn't overflow. - VerifyOrExit(UINTMAX_MAX - verifier_len >= Y_len, err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); - VerifyOrExit(CanCastTo(Y_len + verifier_len), err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); - data_len = static_cast(sizeof(encryptionKeyId) + Y_len + verifier_len); + mNextExpectedMsg = MsgType::PASE_Pake3; - { - Encoding::LittleEndian::PacketBufferWriter bbuf(System::PacketBufferHandle::New(data_len)); - VerifyOrExit(!bbuf.IsNull(), err = CHIP_ERROR_NO_MEMORY); - bbuf.Put16(GetLocalKeyId()); - bbuf.Put(&Y[0], Y_len); - bbuf.Put(verifier, verifier_len); - VerifyOrExit(bbuf.Fit(), err = CHIP_ERROR_NO_MEMORY); - - mNextExpectedMsg = Protocols::SecureChannel::MsgType::PASE_Spake2p3; - - // Call delegate to send the Msg2 to peer - err = mExchangeCtxt->SendMessage(Protocols::SecureChannel::MsgType::PASE_Spake2p2, bbuf.Finalize(), - SendFlags(SendMessageFlags::kExpectResponse)); + err = mExchangeCtxt->SendMessage(MsgType::PASE_Pake2, std::move(msg2), SendFlags(SendMessageFlags::kExpectResponse)); SuccessOrExit(err); } @@ -578,115 +660,117 @@ CHIP_ERROR PASESession::HandleMsg1_and_SendMsg2(const System::PacketBufferHandle if (err != CHIP_NO_ERROR) { - SendErrorMsg(Spake2pErrorType::kUnexpected); + SendStatusReport(kProtocolCodeInvalidParam); } return err; } -CHIP_ERROR PASESession::HandleMsg2_and_SendMsg3(const System::PacketBufferHandle & msg) +CHIP_ERROR PASESession::HandleMsg2_and_SendMsg3(System::PacketBufferHandle && msg2) { CHIP_ERROR err = CHIP_NO_ERROR; uint8_t verifier[kMAX_Hash_Length]; - size_t verifier_len_raw = kMAX_Hash_Length; - uint16_t verifier_len; // To be inited one we check length is small enough - - uint8_t * buf = msg->Start(); - size_t buf_len = msg->DataLength(); + size_t verifier_len = kMAX_Hash_Length; System::PacketBufferHandle resp; - Spake2pErrorType spake2pErr = Spake2pErrorType::kUnexpected; + ChipLogDetail(SecureChannel, "Received spake2p msg2"); - uint16_t encryptionKeyId = 0; + System::PacketBufferTLVReader tlvReader; + TLV::TLVType containerType = TLV::kTLVType_Structure; - ChipLogDetail(SecureChannel, "Received spake2p msg2"); + const uint8_t * Y; + size_t Y_len = 0; - VerifyOrExit(buf != nullptr, err = CHIP_ERROR_MESSAGE_INCOMPLETE); - VerifyOrExit(buf_len == sizeof(encryptionKeyId) + kMAX_Point_Length + kMAX_Hash_Length, - err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); + const uint8_t * peer_verifier; + size_t peer_verifier_len = 0; - encryptionKeyId = chip::Encoding::LittleEndian::Read16(buf); - msg->ConsumeHead(sizeof(encryptionKeyId)); - buf = msg->Start(); - buf_len = msg->DataLength(); + uint32_t decodeTagIdSeq = 0; - ChipLogDetail(SecureChannel, "Peer assigned session key ID %d", encryptionKeyId); - SetPeerKeyId(encryptionKeyId); + tlvReader.Init(std::move(msg2)); + SuccessOrExit(err = tlvReader.Next(containerType, TLV::AnonymousTag)); + SuccessOrExit(err = tlvReader.EnterContainer(containerType)); - err = mSpake2p.ComputeRoundTwo(buf, kMAX_Point_Length, verifier, &verifier_len_raw); - SuccessOrExit(err); - VerifyOrExit(CanCastTo(verifier_len_raw), err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); - verifier_len = static_cast(verifier_len_raw); + SuccessOrExit(err = tlvReader.Next()); + VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + Y_len = tlvReader.GetLength(); + SuccessOrExit(err = tlvReader.GetDataPtr(Y)); - { - const uint8_t * hash = &buf[kMAX_Point_Length]; - err = mSpake2p.KeyConfirm(hash, kMAX_Hash_Length); - if (err != CHIP_NO_ERROR) - { - spake2pErr = Spake2pErrorType::kInvalidKeyConfirmation; - SuccessOrExit(err); - } + SuccessOrExit(err = tlvReader.Next()); + VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + peer_verifier_len = tlvReader.GetLength(); + SuccessOrExit(err = tlvReader.GetDataPtr(peer_verifier)); - err = mSpake2p.GetKeys(mKe, &mKeLen); - SuccessOrExit(err); - } + SuccessOrExit(err = mSpake2p.ComputeRoundTwo(Y, Y_len, verifier, &verifier_len)); + + SuccessOrExit(err = mSpake2p.KeyConfirm(peer_verifier, peer_verifier_len)); + SuccessOrExit(err = mSpake2p.GetKeys(mKe, &mKeLen)); + msg2 = nullptr; { - Encoding::PacketBufferWriter bbuf(System::PacketBufferHandle::New(verifier_len)); - VerifyOrExit(!bbuf.IsNull(), err = CHIP_ERROR_NO_MEMORY); + const size_t max_msg_len = EstimateTLVStructOverhead(verifier_len, 1); + constexpr uint8_t kPake3_cB = 1; - bbuf.Put(verifier, verifier_len); - VerifyOrExit(bbuf.Fit(), err = CHIP_ERROR_NO_MEMORY); + System::PacketBufferHandle msg3 = System::PacketBufferHandle::New(max_msg_len); + VerifyOrExit(!msg3.IsNull(), err = CHIP_ERROR_NO_MEMORY); - // Call delegate to send the Msg3 to peer - err = mExchangeCtxt->SendMessage(Protocols::SecureChannel::MsgType::PASE_Spake2p3, bbuf.Finalize()); - SuccessOrExit(err); - } + System::PacketBufferTLVWriter tlvWriter; + tlvWriter.Init(std::move(msg3)); - ChipLogDetail(SecureChannel, "Sent spake2p msg3"); + TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; + SuccessOrExit(err = tlvWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, outerContainerType)); + SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(kPake3_cB), ByteSpan(verifier, verifier_len))); + SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType)); + SuccessOrExit(err = tlvWriter.Finalize(&msg3)); - mPairingComplete = true; + mNextExpectedMsg = MsgType::StatusReport; - // Forget our exchange, as no additional messages are expected from the peer - mExchangeCtxt = nullptr; + err = mExchangeCtxt->SendMessage(MsgType::PASE_Pake3, std::move(msg3), SendFlags(SendMessageFlags::kExpectResponse)); + SuccessOrExit(err); + } - // Call delegate to indicate pairing completion - mDelegate->OnSessionEstablished(); + ChipLogDetail(SecureChannel, "Sent spake2p msg3"); exit: if (err != CHIP_NO_ERROR) { - SendErrorMsg(spake2pErr); + SendStatusReport(kProtocolCodeInvalidParam); } return err; } -CHIP_ERROR PASESession::HandleMsg3(const System::PacketBufferHandle & msg) +CHIP_ERROR PASESession::HandleMsg3(System::PacketBufferHandle && msg) { - CHIP_ERROR err = CHIP_NO_ERROR; - const uint8_t * hash = msg->Start(); - Spake2pErrorType spake2pErr = Spake2pErrorType::kUnexpected; + CHIP_ERROR err = CHIP_NO_ERROR; ChipLogDetail(SecureChannel, "Received spake2p msg3"); - // We will set NextExpectedMsg to PASE_Spake2pError in all cases - // However, when we are using IP rendezvous, we might set it to PASE_Spake2p1. - mNextExpectedMsg = Protocols::SecureChannel::MsgType::PASE_Spake2pError; + // We will set NextExpectedMsg to PASE_PakeError in all cases + mNextExpectedMsg = MsgType::PASE_PakeError; - VerifyOrExit(hash != nullptr, err = CHIP_ERROR_MESSAGE_INCOMPLETE); - VerifyOrExit(msg->DataLength() == kMAX_Hash_Length, err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); + System::PacketBufferTLVReader tlvReader; + TLV::TLVType containerType = TLV::kTLVType_Structure; - err = mSpake2p.KeyConfirm(hash, kMAX_Hash_Length); - if (err != CHIP_NO_ERROR) - { - spake2pErr = Spake2pErrorType::kInvalidKeyConfirmation; - SuccessOrExit(err); - } + const uint8_t * peer_verifier; + size_t peer_verifier_len = 0; - err = mSpake2p.GetKeys(mKe, &mKeLen); - SuccessOrExit(err); + tlvReader.Init(std::move(msg)); + SuccessOrExit(err = tlvReader.Next(containerType, TLV::AnonymousTag)); + SuccessOrExit(err = tlvReader.EnterContainer(containerType)); + + SuccessOrExit(err = tlvReader.Next()); + VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == 1, err = CHIP_ERROR_INVALID_TLV_TAG); + peer_verifier_len = tlvReader.GetLength(); + SuccessOrExit(err = tlvReader.GetDataPtr(peer_verifier)); + + VerifyOrExit(peer_verifier_len == kMAX_Hash_Length, err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); + + SuccessOrExit(err = mSpake2p.KeyConfirm(peer_verifier, peer_verifier_len)); + SuccessOrExit(err = mSpake2p.GetKeys(mKe, &mKeLen)); + + // Send confirmation to peer that we succeeded so they can start using the session. + SendStatusReport(kProtocolCodeSuccess); mPairingComplete = true; @@ -700,56 +784,66 @@ CHIP_ERROR PASESession::HandleMsg3(const System::PacketBufferHandle & msg) if (err != CHIP_NO_ERROR) { - SendErrorMsg(spake2pErr); + SendStatusReport(kProtocolCodeInvalidParam); } return err; } -void PASESession::SendErrorMsg(Spake2pErrorType errorCode) +void PASESession::SendStatusReport(uint16_t protocolCode) { - System::PacketBufferHandle msg; - uint16_t msglen = sizeof(Spake2pErrorMsg); - Spake2pErrorMsg * pMsg = nullptr; + // TODO - Move SendStatusReport to a common part of the code. + // This could be reused for all secure channel protocol state machinies. + GeneralStatusCode generalCode = + (protocolCode == kProtocolCodeSuccess) ? GeneralStatusCode::kSuccess : GeneralStatusCode::kFailure; + uint32_t protocolId = Protocols::SecureChannel::Id.ToFullyQualifiedSpecForm(); + + ChipLogDetail(SecureChannel, "Sending status report"); - msg = System::PacketBufferHandle::New(msglen); - VerifyOrReturn(!msg.IsNull(), ChipLogError(SecureChannel, "Failed to allocate error message")); + StatusReport statusReport(generalCode, protocolId, protocolCode); - pMsg = reinterpret_cast(msg->Start()); - pMsg->error = errorCode; + Encoding::LittleEndian::PacketBufferWriter bbuf(System::PacketBufferHandle::New(statusReport.Size())); + statusReport.WriteToBuffer(bbuf); - msg->SetDataLength(msglen); + System::PacketBufferHandle msg = bbuf.Finalize(); + VerifyOrReturn(!msg.IsNull(), ChipLogError(SecureChannel, "Failed to allocate status report message")); - VerifyOrReturn(mExchangeCtxt->SendMessage(Protocols::SecureChannel::MsgType::PASE_Spake2pError, std::move(msg)) == - CHIP_NO_ERROR, - ChipLogError(SecureChannel, "Failed to send error message")); + VerifyOrReturn(mExchangeCtxt->SendMessage(MsgType::StatusReport, std::move(msg)) == CHIP_NO_ERROR, + ChipLogError(SecureChannel, "Failed to send status report message")); } -CHIP_ERROR PASESession::HandleErrorMsg(const System::PacketBufferHandle & msg) +CHIP_ERROR PASESession::HandleStatusReport(System::PacketBufferHandle && msg) { - ReturnErrorCodeIf(msg->Start() == nullptr || msg->DataLength() != sizeof(Spake2pErrorMsg), CHIP_ERROR_MESSAGE_INCOMPLETE); - - static_assert( - sizeof(Spake2pErrorMsg) == sizeof(uint8_t), - "Assuming size of Spake2pErrorMsg message is 1 octet, so that endian-ness conversion and memory alignment is not needed"); + StatusReport report; + CHIP_ERROR err = report.Parse(std::move(msg)); + ReturnErrorOnFailure(err); + VerifyOrReturnError(report.GetProtocolId() == Protocols::SecureChannel::Id.ToFullyQualifiedSpecForm(), + CHIP_ERROR_INVALID_ARGUMENT); - Spake2pErrorMsg * pMsg = reinterpret_cast(msg->Start()); - - CHIP_ERROR err = CHIP_NO_ERROR; - switch (pMsg->error) + if (report.GetGeneralCode() == GeneralStatusCode::kSuccess && report.GetProtocolCode() == kProtocolCodeSuccess) { - case Spake2pErrorType::kInvalidKeyConfirmation: - err = CHIP_ERROR_KEY_CONFIRMATION_FAILED; - break; + mPairingComplete = true; - case Spake2pErrorType::kUnexpected: - err = CHIP_ERROR_INVALID_PASE_PARAMETER; - break; + // Forget our exchange, as no additional messages are expected from the peer + mExchangeCtxt = nullptr; - default: - err = CHIP_ERROR_INTERNAL; - break; - }; - ChipLogError(SecureChannel, "Received error during pairing process. %s", ErrorStr(err)); + // Call delegate to indicate pairing completion + mDelegate->OnSessionEstablished(); + } + else + { + switch (report.GetProtocolCode()) + { + case kProtocolCodeInvalidParam: + err = CHIP_ERROR_INVALID_PASE_PARAMETER; + break; + + default: + err = CHIP_ERROR_INTERNAL; + break; + }; + ChipLogError(SecureChannel, "Received error (protocol code %d) during pairing process. %s", report.GetProtocolCode(), + ErrorStr(err)); + } return err; } @@ -776,8 +870,7 @@ CHIP_ERROR PASESession::ValidateReceivedMessage(ExchangeContext * exchange, cons } VerifyOrReturnError(!msg.IsNull(), CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnError(payloadHeader.HasMessageType(mNextExpectedMsg) || - payloadHeader.HasMessageType(Protocols::SecureChannel::MsgType::PASE_Spake2pError), + VerifyOrReturnError(payloadHeader.HasMessageType(mNextExpectedMsg) || payloadHeader.HasMessageType(MsgType::StatusReport), CHIP_ERROR_INVALID_MESSAGE_TYPE); return CHIP_NO_ERROR; @@ -791,30 +884,30 @@ CHIP_ERROR PASESession::OnMessageReceived(ExchangeContext * exchange, const Payl SetPeerAddress(mMessageDispatch.GetPeerAddress()); - switch (static_cast(payloadHeader.GetMessageType())) + switch (static_cast(payloadHeader.GetMessageType())) { - case Protocols::SecureChannel::MsgType::PBKDFParamRequest: - err = HandlePBKDFParamRequest(msg); + case MsgType::PBKDFParamRequest: + err = HandlePBKDFParamRequest(std::move(msg)); break; - case Protocols::SecureChannel::MsgType::PBKDFParamResponse: - err = HandlePBKDFParamResponse(msg); + case MsgType::PBKDFParamResponse: + err = HandlePBKDFParamResponse(std::move(msg)); break; - case Protocols::SecureChannel::MsgType::PASE_Spake2p1: - err = HandleMsg1_and_SendMsg2(msg); + case MsgType::PASE_Pake1: + err = HandleMsg1_and_SendMsg2(std::move(msg)); break; - case Protocols::SecureChannel::MsgType::PASE_Spake2p2: - err = HandleMsg2_and_SendMsg3(msg); + case MsgType::PASE_Pake2: + err = HandleMsg2_and_SendMsg3(std::move(msg)); break; - case Protocols::SecureChannel::MsgType::PASE_Spake2p3: - err = HandleMsg3(msg); + case MsgType::PASE_Pake3: + err = HandleMsg3(std::move(msg)); break; - case Protocols::SecureChannel::MsgType::PASE_Spake2pError: - err = HandleErrorMsg(msg); + case MsgType::StatusReport: + err = HandleStatusReport(std::move(msg)); break; default: diff --git a/src/protocols/secure_channel/PASESession.h b/src/protocols/secure_channel/PASESession.h index 0a33b6d4f3a3b9..2873699fde9a72 100644 --- a/src/protocols/secure_channel/PASESession.h +++ b/src/protocols/secure_channel/PASESession.h @@ -255,25 +255,28 @@ class DLL_EXPORT PASESession : public Messaging::ExchangeDelegate, public Pairin CHIP_ERROR SetupSpake2p(uint32_t pbkdf2IterCount, const ByteSpan & salt); CHIP_ERROR SendPBKDFParamRequest(); - CHIP_ERROR HandlePBKDFParamRequest(const System::PacketBufferHandle & msg); + CHIP_ERROR HandlePBKDFParamRequest(System::PacketBufferHandle && msg); - CHIP_ERROR SendPBKDFParamResponse(); - CHIP_ERROR HandlePBKDFParamResponse(const System::PacketBufferHandle & msg); + CHIP_ERROR SendPBKDFParamResponse(ByteSpan initiatorRandom, bool initiatorHasPBKDFParams); + CHIP_ERROR HandlePBKDFParamResponse(System::PacketBufferHandle && msg); CHIP_ERROR SendMsg1(); - CHIP_ERROR HandleMsg1_and_SendMsg2(const System::PacketBufferHandle & msg); - CHIP_ERROR HandleMsg2_and_SendMsg3(const System::PacketBufferHandle & msg); - CHIP_ERROR HandleMsg3(const System::PacketBufferHandle & msg); + CHIP_ERROR HandleMsg1_and_SendMsg2(System::PacketBufferHandle && msg); + CHIP_ERROR HandleMsg2_and_SendMsg3(System::PacketBufferHandle && msg); + CHIP_ERROR HandleMsg3(System::PacketBufferHandle && msg); - void SendErrorMsg(Spake2pErrorType errorCode); - CHIP_ERROR HandleErrorMsg(const System::PacketBufferHandle & msg); + void SendStatusReport(uint16_t protocolCode); + CHIP_ERROR HandleStatusReport(System::PacketBufferHandle && msg); + + // TODO - Move EstimateTLVStructOverhead to CHIPTLV header file + constexpr size_t EstimateTLVStructOverhead(size_t dataLen, size_t nFields) { return dataLen + (sizeof(uint64_t) * nFields); } void CloseExchange(); SessionEstablishmentDelegate * mDelegate = nullptr; - Protocols::SecureChannel::MsgType mNextExpectedMsg = Protocols::SecureChannel::MsgType::PASE_Spake2pError; + Protocols::SecureChannel::MsgType mNextExpectedMsg = Protocols::SecureChannel::MsgType::PASE_PakeError; #ifdef ENABLE_HSM_SPAKE Spake2pHSM_P256_SHA256_HKDF_HMAC mSpake2p; @@ -291,6 +294,10 @@ class DLL_EXPORT PASESession : public Messaging::ExchangeDelegate, public Pairin bool mComputeVerifier = true; + bool mHavePBKDFParameters = false; + + uint8_t mPBKDFLocalRandomData[kPBKDFParamRandomNumberSize]; + Hash_SHA256_stream mCommissioningHash; uint32_t mIterationCount = 0; uint16_t mSaltLength = 0; diff --git a/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.cpp b/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.cpp index 5443adaef05a80..ea6beca4c68135 100644 --- a/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.cpp +++ b/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.cpp @@ -66,14 +66,15 @@ bool SessionEstablishmentExchangeDispatch::MessagePermitted(uint16_t protocol, u case static_cast(Protocols::SecureChannel::MsgType::StandaloneAck): case static_cast(Protocols::SecureChannel::MsgType::PBKDFParamRequest): case static_cast(Protocols::SecureChannel::MsgType::PBKDFParamResponse): - case static_cast(Protocols::SecureChannel::MsgType::PASE_Spake2p1): - case static_cast(Protocols::SecureChannel::MsgType::PASE_Spake2p2): - case static_cast(Protocols::SecureChannel::MsgType::PASE_Spake2p3): - case static_cast(Protocols::SecureChannel::MsgType::PASE_Spake2pError): + case static_cast(Protocols::SecureChannel::MsgType::PASE_Pake1): + case static_cast(Protocols::SecureChannel::MsgType::PASE_Pake2): + case static_cast(Protocols::SecureChannel::MsgType::PASE_Pake3): + case static_cast(Protocols::SecureChannel::MsgType::PASE_PakeError): case static_cast(Protocols::SecureChannel::MsgType::CASE_SigmaR1): case static_cast(Protocols::SecureChannel::MsgType::CASE_SigmaR2): case static_cast(Protocols::SecureChannel::MsgType::CASE_SigmaR3): case static_cast(Protocols::SecureChannel::MsgType::CASE_SigmaErr): + case static_cast(Protocols::SecureChannel::MsgType::StatusReport): return true; default: From 692b86cf24b8e587384fcad6d640d3efb52a82b8 Mon Sep 17 00:00:00 2001 From: Pankaj Garg Date: Mon, 13 Sep 2021 15:34:05 -0700 Subject: [PATCH 024/255] Expire associated secure sessions when a fabric is deleted (#9571) * Expire associated secure sessions when a fabric is deleted * regen zap files * another zap regen * address review comments * address review comments * updates * update CASESession error handling * fix build error --- .../operational-credentials-server.cpp | 44 ++++++++++++++++++- .../suites/OperationalCredentialsCluster.yaml | 12 +++++ src/messaging/ExchangeContext.h | 1 + src/messaging/ReliableMessageMgr.cpp | 2 +- src/protocols/secure_channel/CASESession.cpp | 6 ++- src/transport/PeerConnections.h | 24 ++++++++++ src/transport/SecureSessionMgr.cpp | 12 +++++ src/transport/SecureSessionMgr.h | 1 + 8 files changed, 97 insertions(+), 5 deletions(-) diff --git a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp index d61676e531a728..68a84e83e63697 100644 --- a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp +++ b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp @@ -238,18 +238,58 @@ void emberAfPluginOperationalCredentialsServerInitCallback(void) writeFabricsIntoFabricsListAttribute(); } +namespace { +class FabricCleanupExchangeDelegate : public Messaging::ExchangeDelegate +{ +public: + CHIP_ERROR OnMessageReceived(Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader, + System::PacketBufferHandle && payload) override + { + return CHIP_NO_ERROR; + } + void OnResponseTimeout(Messaging::ExchangeContext * ec) override {} + void OnExchangeClosing(Messaging::ExchangeContext * ec) override + { + FabricIndex currentFabricIndex = ec->GetSecureSession().GetFabricIndex(); + ec->GetExchangeMgr()->GetSessionMgr()->ExpireAllPairingsForFabric(currentFabricIndex); + } +}; + +FabricCleanupExchangeDelegate gFabricCleanupExchangeDelegate; + +} // namespace + bool emberAfOperationalCredentialsClusterRemoveFabricCallback(EndpointId endpoint, app::CommandHandler * commandObj, - FabricIndex fabricIndex) + FabricIndex fabricBeingRemoved) { emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: RemoveFabric"); // TODO: Generate emberAfFabricClusterPrintln EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS; - CHIP_ERROR err = Server::GetInstance().GetFabricTable().Delete(fabricIndex); + CHIP_ERROR err = Server::GetInstance().GetFabricTable().Delete(fabricBeingRemoved); VerifyOrExit(err == CHIP_NO_ERROR, status = EMBER_ZCL_STATUS_FAILURE); exit: writeFabricsIntoFabricsListAttribute(); emberAfSendImmediateDefaultResponse(status); + if (err == CHIP_NO_ERROR) + { + Messaging::ExchangeContext * ec = commandObj->GetExchangeContext(); + FabricIndex currentFabricIndex = ec->GetSecureSession().GetFabricIndex(); + if (currentFabricIndex == fabricBeingRemoved) + { + // If the current fabric is being removed, expiring all the secure sessions causes crashes as + // the message sent by emberAfSendImmediateDefaultResponse() is still in the queue. Also, RMP + // retries to send the message and runs into issues. + // We are hijacking the exchange delegate here (as no more messages should be received on this exchange), + // and wait for it to close, before expiring the secure sessions for the fabric. + // TODO: https://github.com/project-chip/connectedhomeip/issues/9642 + ec->SetDelegate(&gFabricCleanupExchangeDelegate); + } + else + { + ec->GetExchangeMgr()->GetSessionMgr()->ExpireAllPairingsForFabric(fabricBeingRemoved); + } + } return true; } diff --git a/src/app/tests/suites/OperationalCredentialsCluster.yaml b/src/app/tests/suites/OperationalCredentialsCluster.yaml index a2fbd460c5bd13..d025f11728a5a4 100644 --- a/src/app/tests/suites/OperationalCredentialsCluster.yaml +++ b/src/app/tests/suites/OperationalCredentialsCluster.yaml @@ -34,3 +34,15 @@ tests: constraints: type: uint8 minValue: 1 + + # This test is currently disabled as it breaks on Darwin. + # The test removes the current fabric, and Darwin test runner reuses + # the same pairing to run all the tests. Due to that, all subsequent + # tests fail. + - label: "Remove fabric" + disabled: true + command: "RemoveFabric" + arguments: + values: + - name: "FabricIndex" + value: 1 diff --git a/src/messaging/ExchangeContext.h b/src/messaging/ExchangeContext.h index e45dc15098d94a..43ae371e0c8927 100644 --- a/src/messaging/ExchangeContext.h +++ b/src/messaging/ExchangeContext.h @@ -165,6 +165,7 @@ class DLL_EXPORT ExchangeContext : public ReliableMessageContext, public Referen } SessionHandle GetSecureSession() { return mSecureSession.Value(); } + bool HasSecureSession() const { return mSecureSession.HasValue(); } uint16_t GetExchangeId() const { return mExchangeId; } diff --git a/src/messaging/ReliableMessageMgr.cpp b/src/messaging/ReliableMessageMgr.cpp index 384ee0ea902b27..c180b9d5701224 100644 --- a/src/messaging/ReliableMessageMgr.cpp +++ b/src/messaging/ReliableMessageMgr.cpp @@ -357,7 +357,7 @@ CHIP_ERROR ReliableMessageMgr::SendFromRetransTable(RetransTableEntry * entry) } const ExchangeMessageDispatch * dispatcher = rc->GetExchangeContext()->GetMessageDispatch(); - if (dispatcher == nullptr) + if (dispatcher == nullptr || !rc->GetExchangeContext()->HasSecureSession()) { // Using same error message for all errors to reduce code size. ChipLogError(ExchangeManager, "Crit-err %" CHIP_ERROR_FORMAT " when sending CHIP MsgId:%08" PRIX32 ", send tries: %d", diff --git a/src/protocols/secure_channel/CASESession.cpp b/src/protocols/secure_channel/CASESession.cpp index 6feab01290c096..65c3026a402b7a 100644 --- a/src/protocols/secure_channel/CASESession.cpp +++ b/src/protocols/secure_channel/CASESession.cpp @@ -1035,8 +1035,10 @@ void CASESession::SendErrorMsg(SigmaErrorType errorCode) msg->SetDataLength(msglen); - VerifyOrReturn(mExchangeCtxt->SendMessage(Protocols::SecureChannel::MsgType::CASE_SigmaErr, std::move(msg)) != CHIP_NO_ERROR, - ChipLogError(SecureChannel, "Failed to send error message")); + if (mExchangeCtxt->SendMessage(Protocols::SecureChannel::MsgType::CASE_SigmaErr, std::move(msg)) != CHIP_NO_ERROR) + { + ChipLogError(SecureChannel, "Failed to send error message"); + } } CHIP_ERROR CASESession::ConstructSaltSigmaR2(const ByteSpan & rand, const Crypto::P256PublicKey & pubkey, const ByteSpan & ipk, diff --git a/src/transport/PeerConnections.h b/src/transport/PeerConnections.h index faa820d1084817..17093b84e7ef65 100644 --- a/src/transport/PeerConnections.h +++ b/src/transport/PeerConnections.h @@ -316,6 +316,30 @@ class PeerConnections return state; } + /** + * Get the first peer connection state that matches the given fabric index. + * + * @param fabric The fabric index to match + * + * @return the state found, nullptr if not found + */ + CHECK_RETURN_VALUE + PeerConnectionState * FindPeerConnectionStateByFabric(FabricIndex fabric) + { + for (auto & state : mStates) + { + if (!state.IsInitialized()) + { + continue; + } + if (state.GetFabricIndex() == fabric) + { + return &state; + } + } + return nullptr; + } + /// Convenience method to mark a peer connection state as active void MarkConnectionActive(PeerConnectionState * state) { diff --git a/src/transport/SecureSessionMgr.cpp b/src/transport/SecureSessionMgr.cpp index b727c0c75ab302..093ce844e19ef4 100644 --- a/src/transport/SecureSessionMgr.cpp +++ b/src/transport/SecureSessionMgr.cpp @@ -207,6 +207,18 @@ void SecureSessionMgr::ExpireAllPairings(NodeId peerNodeId, FabricIndex fabric) } } +void SecureSessionMgr::ExpireAllPairingsForFabric(FabricIndex fabric) +{ + ChipLogDetail(Inet, "Expiring all connections for fabric %d!!", fabric); + PeerConnectionState * state = mPeerConnections.FindPeerConnectionStateByFabric(fabric); + while (state != nullptr) + { + mPeerConnections.MarkConnectionExpired( + state, [this](const Transport::PeerConnectionState & state1) { HandleConnectionExpired(state1); }); + state = mPeerConnections.FindPeerConnectionStateByFabric(fabric); + } +} + CHIP_ERROR SecureSessionMgr::NewPairing(const Optional & peerAddr, NodeId peerNodeId, PairingSession * pairing, SecureSession::SessionRole direction, FabricIndex fabric) { diff --git a/src/transport/SecureSessionMgr.h b/src/transport/SecureSessionMgr.h index 4f3427a8843a7c..740bae8fe1995a 100644 --- a/src/transport/SecureSessionMgr.h +++ b/src/transport/SecureSessionMgr.h @@ -225,6 +225,7 @@ class DLL_EXPORT SecureSessionMgr : public TransportMgrDelegate void ExpirePairing(SessionHandle session); void ExpireAllPairings(NodeId peerNodeId, FabricIndex fabric); + void ExpireAllPairingsForFabric(FabricIndex fabric); /** * @brief From 7c00fa2c60faa4a1bd6ef836e1bfca2dbe8e7bff Mon Sep 17 00:00:00 2001 From: C Freeman Date: Mon, 13 Sep 2021 19:47:00 -0400 Subject: [PATCH 025/255] Add tests for CHIPMemString. (#9619) * Add tests for CHIPMemString. * Update src/lib/support/tests/TestCHIPMemString.cpp Co-authored-by: Boris Zbarsky * Address review comments Use buf len instead of strlen to make it more clear about what the buffer sizes really mean. Co-authored-by: Boris Zbarsky --- src/lib/support/tests/BUILD.gn | 1 + src/lib/support/tests/TestCHIPMemString.cpp | 166 ++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 src/lib/support/tests/TestCHIPMemString.cpp diff --git a/src/lib/support/tests/BUILD.gn b/src/lib/support/tests/BUILD.gn index ee1af161003649..f85bf6c5d3e25f 100644 --- a/src/lib/support/tests/BUILD.gn +++ b/src/lib/support/tests/BUILD.gn @@ -29,6 +29,7 @@ chip_test_suite("tests") { "TestCHIPArgParser.cpp", "TestCHIPCounter.cpp", "TestCHIPMem.cpp", + "TestCHIPMemString.cpp", "TestDefer.cpp", "TestErrorStr.cpp", "TestFixedBufferAllocator.cpp", diff --git a/src/lib/support/tests/TestCHIPMemString.cpp b/src/lib/support/tests/TestCHIPMemString.cpp new file mode 100644 index 00000000000000..f887995079f9b8 --- /dev/null +++ b/src/lib/support/tests/TestCHIPMemString.cpp @@ -0,0 +1,166 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::Platform; + +// ================================= +// Unit tests +// ================================= + +namespace { +template +struct TestBuffers +{ + char correctSizeBuf[kTestBufLen]; + char tooSmallBuf[kTestBufLen - 1]; + char wayTooSmallBuf[1]; + char tooBigBuf[kTestBufLen + 10]; + void Reset() + { + memset(correctSizeBuf, 1, sizeof(correctSizeBuf)); + memset(tooSmallBuf, 1, sizeof(tooSmallBuf)); + memset(wayTooSmallBuf, 1, sizeof(wayTooSmallBuf)); + memset(tooBigBuf, 1, sizeof(tooBigBuf)); + } + void CheckCorrectness(nlTestSuite * inSuite, const char * testStr) + { + // correctSizeBuf and tooBigBuf should have the complete string. + NL_TEST_ASSERT(inSuite, correctSizeBuf[kTestBufLen - 1] == '\0'); + NL_TEST_ASSERT(inSuite, tooBigBuf[kTestBufLen - 1] == '\0'); + NL_TEST_ASSERT(inSuite, strcmp(correctSizeBuf, testStr) == 0); + NL_TEST_ASSERT(inSuite, strcmp(tooBigBuf, testStr) == 0); + NL_TEST_ASSERT(inSuite, strlen(correctSizeBuf) == strlen(testStr)); + NL_TEST_ASSERT(inSuite, strlen(tooBigBuf) == strlen(testStr)); + + // wayTooSmallBuf is tiny and thus will only have the null terminator + NL_TEST_ASSERT(inSuite, wayTooSmallBuf[0] == '\0'); + + // tooSmallBuf should still have a null terminator on the end + NL_TEST_ASSERT(inSuite, tooSmallBuf[kTestBufLen - 2] == '\0'); + NL_TEST_ASSERT(inSuite, memcmp(tooSmallBuf, testStr, kTestBufLen - 2) == 0); + } +}; + +} // namespace + +static void TestCopyString(nlTestSuite * inSuite, void * inContext) +{ + constexpr char testWord[] = "testytest"; + ByteSpan testWordSpan = ByteSpan(reinterpret_cast(testWord), sizeof(testWord) - 1); + TestBuffers testBuffers; + + // CopyString with explicit size + testBuffers.Reset(); + CopyString(testBuffers.correctSizeBuf, sizeof(testBuffers.correctSizeBuf), testWord); + CopyString(testBuffers.tooSmallBuf, sizeof(testBuffers.tooSmallBuf), testWord); + CopyString(testBuffers.wayTooSmallBuf, sizeof(testBuffers.wayTooSmallBuf), testWord); + CopyString(testBuffers.tooBigBuf, sizeof(testBuffers.tooBigBuf), testWord); + testBuffers.CheckCorrectness(inSuite, testWord); + + // CopyString with array size + testBuffers.Reset(); + CopyString(testBuffers.correctSizeBuf, testWord); + CopyString(testBuffers.tooSmallBuf, testWord); + CopyString(testBuffers.wayTooSmallBuf, testWord); + CopyString(testBuffers.tooBigBuf, testWord); + testBuffers.CheckCorrectness(inSuite, testWord); + + // CopyString with explicit size from ByteSpan + testBuffers.Reset(); + CopyString(testBuffers.correctSizeBuf, sizeof(testBuffers.correctSizeBuf), testWordSpan); + CopyString(testBuffers.tooSmallBuf, sizeof(testBuffers.tooSmallBuf), testWordSpan); + CopyString(testBuffers.wayTooSmallBuf, sizeof(testBuffers.wayTooSmallBuf), testWordSpan); + CopyString(testBuffers.tooBigBuf, sizeof(testBuffers.tooBigBuf), testWordSpan); + testBuffers.CheckCorrectness(inSuite, testWord); + + // CopyString with array size from ByteSpan + testBuffers.Reset(); + CopyString(testBuffers.correctSizeBuf, testWordSpan); + CopyString(testBuffers.tooSmallBuf, testWordSpan); + CopyString(testBuffers.wayTooSmallBuf, testWordSpan); + CopyString(testBuffers.tooBigBuf, testWordSpan); + testBuffers.CheckCorrectness(inSuite, testWord); +} + +static void TestMemoryAllocString(nlTestSuite * inSuite, void * inContext) +{ + constexpr char testStr[] = "testytestString"; + char * allocatedStr = MemoryAllocString(testStr, sizeof(testStr)); + NL_TEST_ASSERT(inSuite, allocatedStr != nullptr); + if (allocatedStr == nullptr) + { + return; + } + NL_TEST_ASSERT(inSuite, strcmp(testStr, allocatedStr) == 0); + MemoryFree(allocatedStr); +} + +static void TestScopedBuffer(nlTestSuite * inSuite, void * inContext) +{ + // Scoped buffer has its own tests that check the memory properly. Here we are just testing that the string is copied in + // properly. + constexpr char testStr[] = "testytestString"; + ScopedMemoryString scopedString = ScopedMemoryString(testStr, sizeof(testStr)); + NL_TEST_ASSERT(inSuite, strcmp(scopedString.Get(), testStr) == 0); +} + +static const nlTest sTests[] = { NL_TEST_DEF("Test CopyString", TestCopyString), + NL_TEST_DEF("Test MemoryAllocString", TestMemoryAllocString), + NL_TEST_DEF("Test ScopedBuffer", TestScopedBuffer), NL_TEST_SENTINEL() }; + +int TestMemString_Setup(void * inContext) +{ + CHIP_ERROR error = MemoryInit(); + if (error != CHIP_NO_ERROR) + return (FAILURE); + return (SUCCESS); +} + +/** + * Tear down the test suite. + */ +int TestMemString_Teardown(void * inContext) +{ + MemoryShutdown(); + return (SUCCESS); +} + +int TestMemString() +{ + nlTestSuite theSuite = { "CHIP Memory Allocation tests", &sTests[0], TestMemString_Setup, TestMemString_Teardown }; + + // Run test suit againt one context. + nlTestRunner(&theSuite, nullptr); + return nlTestRunnerStats(&theSuite); +} + +CHIP_REGISTER_TEST_SUITE(TestMemString) From ec5f5dc30907a321d17a7b68fcbe1723d521a567 Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Mon, 13 Sep 2021 16:47:42 -0700 Subject: [PATCH 026/255] Add and Enable IM subscription support (#9510) * [testsuite] Refactor test suite simulated cluster command * Add initial IM subscriber server change --Extend IM ReadHandler with subscribe capability, and update the corresponding reporting engine, which can process multiple subscriber, process subscribe request and generate subscribe response. --Hook setDirty API to ember so that ember can generate the change set and send it out via IM report. * Add initial IM subscription client change --Extends IM read client with subscribe capability and it can send subscribe request and process subscribe process and further maintain subscription with livess check. --Disable path filter for IM read/subscribe request. --Update templates to use interaction model APIs for sending subscribe requests. --Update DeviceControllerInteractionModelDelegate to handle report messages from subscription. --Update ChipCallback Mgr to bridge subscribe responses to existing callbacks, and handle TLV message just as read responses. --Update TestSuite for basic Subscription protocol tests, test routing looks like follows: Send subscribe request, wait for response. Wait for a few seconds, and execute "kick" commands. The test is expected to receive the same number of Reports as the number of kick commands. The test will fail when not receiving enough report data from server in global timeout. --Update python script test to (in cirque) include a similar test routine as test suite. --Add unit test for positive and negative subscribe test --Add integrated cirque test for subscribe * Update test cases, add darwin test * run codegen Co-authored-by: Song Guo --- examples/bridge-app/esp32/main/main.cpp | 21 +- examples/bridge-app/linux/main.cpp | 21 +- .../partials/process_response_value.zapt | 78 +++ .../templates/partials/test_cluster.zapt | 114 +--- .../testsuite/WaitForAttributeReport.zapt | 38 ++ .../partials/testsuite/WaitForMs.zapt | 6 + .../templates/reporting-commands.zapt | 2 +- examples/chip-tool/templates/templates.json | 12 + .../chip-tool/templates/tests-commands.zapt | 3 +- src/app/ClusterInfo.h | 4 - src/app/InteractionModelDelegate.h | 13 +- src/app/InteractionModelEngine.cpp | 115 +++- src/app/InteractionModelEngine.h | 23 +- src/app/MessageDef/SubscribeResponse.cpp | 49 +- src/app/MessageDef/SubscribeResponse.h | 26 +- src/app/ReadClient.cpp | 245 +++++++- src/app/ReadClient.h | 47 +- src/app/ReadHandler.cpp | 233 +++++-- src/app/ReadHandler.h | 46 +- src/app/ReadPrepareParams.h | 12 +- src/app/reporting/Engine.cpp | 116 +++- src/app/reporting/Engine.h | 22 + src/app/reporting/reporting.cpp | 47 -- src/app/reporting/reporting.h | 3 + src/app/tests/TestCHIPDeviceCallbacksMgr.cpp | 44 +- src/app/tests/TestClusterInfo.cpp | 10 - src/app/tests/TestInteractionModelEngine.cpp | 27 + src/app/tests/TestMessageDef.cpp | 20 +- src/app/tests/TestReadInteraction.cpp | 426 ++++++++++++- src/app/tests/TestReportingEngine.cpp | 39 +- .../tests/integration/chip_im_initiator.cpp | 123 +++- .../tests/integration/chip_im_responder.cpp | 38 +- src/app/tests/suites/TestDelayCommands.yaml | 2 +- src/app/tests/suites/TestSubscribe_OnOff.yaml | 41 ++ src/app/util/CHIPDeviceCallbacksMgr.cpp | 70 ++- src/app/util/CHIPDeviceCallbacksMgr.h | 30 +- src/app/util/attribute-table.cpp | 2 +- .../util/ember-compatibility-functions.cpp | 21 +- src/app/util/im-client-callbacks.cpp | 63 +- src/app/util/im-client-callbacks.h | 1 + .../common/ClusterTestGeneration.js | 47 +- ...yCommands.js => TestSuiteHelperCluster.js} | 19 +- .../app/CHIPClientCallbacks-src.zapt | 243 +------- .../templates/app/CHIPClusters-src.zapt | 26 +- src/app/zap-templates/templates/app/helper.js | 26 +- src/controller/CHIPCluster.cpp | 6 +- src/controller/CHIPCluster.h | 4 +- src/controller/CHIPDevice.cpp | 45 +- src/controller/CHIPDevice.h | 18 +- src/controller/CHIPDeviceController.cpp | 27 +- src/controller/CHIPDeviceController.h | 41 +- ...DeviceControllerInteractionModelDelegate.h | 86 +++ .../chip/interaction_model/Delegate.cpp | 5 +- .../python/chip/interaction_model/Delegate.h | 5 +- .../python/chip/interaction_model/__init__.py | 2 + .../python/chip/interaction_model/delegate.py | 23 +- .../python/test/test_scripts/base.py | 55 ++ .../test/test_scripts/mobile-device-test.py | 4 + .../CHIP/templates/clusters-tests.zapt | 75 +-- .../partials/process_response_value.zapt | 38 ++ .../CHIP/templates/partials/test_cluster.zapt | 56 +- .../testsuite/WaitForAttributeReport.zapt | 14 + .../partials/testsuite/WaitForMs.zapt | 2 + .../Framework/CHIP/templates/templates.json | 12 + .../Framework/CHIPTests/CHIPClustersTests.m | 153 ++--- src/lib/core/CHIPConfig.h | 11 +- .../zap-generated/reporting/Commands.h | 73 ++- .../chip-tool/zap-generated/test/Commands.h | 576 +++++++++++++++++- .../zap-generated/CHIPClientCallbacks.cpp | 474 +++++--------- .../zap-generated/CHIPClusters.cpp | 520 +++++++--------- .../zap-generated/CHIPClientCallbacks.cpp | 249 -------- .../zap-generated/CHIPClusters.cpp | 2 - .../zap-generated/CHIPClientCallbacks.cpp | 249 -------- .../pump-app/zap-generated/CHIPClusters.cpp | 65 +- .../zap-generated/CHIPClientCallbacks.cpp | 249 -------- .../zap-generated/CHIPClusters.cpp | 107 ++-- .../zap-generated/CHIPClientCallbacks.cpp | 276 +-------- .../tv-app/zap-generated/CHIPClusters.cpp | 2 - 78 files changed, 3460 insertions(+), 2678 deletions(-) create mode 100644 examples/chip-tool/templates/partials/process_response_value.zapt create mode 100644 examples/chip-tool/templates/partials/testsuite/WaitForAttributeReport.zapt create mode 100644 examples/chip-tool/templates/partials/testsuite/WaitForMs.zapt create mode 100644 src/app/tests/suites/TestSubscribe_OnOff.yaml rename src/app/zap-templates/common/{simulated-clusters/TestDelayCommands.js => TestSuiteHelperCluster.js} (67%) create mode 100644 src/controller/DeviceControllerInteractionModelDelegate.h create mode 100644 src/darwin/Framework/CHIP/templates/partials/process_response_value.zapt create mode 100644 src/darwin/Framework/CHIP/templates/partials/testsuite/WaitForAttributeReport.zapt create mode 100644 src/darwin/Framework/CHIP/templates/partials/testsuite/WaitForMs.zapt diff --git a/examples/bridge-app/esp32/main/main.cpp b/examples/bridge-app/esp32/main/main.cpp index ad2420ded777ca..5d0dbbbb62aa4f 100644 --- a/examples/bridge-app/esp32/main/main.cpp +++ b/examples/bridge-app/esp32/main/main.cpp @@ -314,25 +314,25 @@ void HandleDeviceStatusChanged(Device * dev, Device::Changed_t itemChangedMask) if (itemChangedMask & Device::kChanged_Reachable) { uint8_t reachable = dev->IsReachable() ? 1 : 0; - emberAfReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, - ZCL_REACHABLE_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, 0, ZCL_BOOLEAN_ATTRIBUTE_TYPE, - &reachable); + InteractionModelReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, + ZCL_REACHABLE_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, 0, + ZCL_BOOLEAN_ATTRIBUTE_TYPE, &reachable); } if (itemChangedMask & Device::kChanged_State) { uint8_t isOn = dev->IsOn() ? 1 : 0; - emberAfReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, - CLUSTER_MASK_SERVER, 0, ZCL_BOOLEAN_ATTRIBUTE_TYPE, &isOn); + InteractionModelReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, + CLUSTER_MASK_SERVER, 0, ZCL_BOOLEAN_ATTRIBUTE_TYPE, &isOn); } if (itemChangedMask & Device::kChanged_Name) { uint8_t zclName[kUserLabelSize]; ToZclCharString(zclName, dev->GetName(), kUserLabelSize - 1); - emberAfReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, - ZCL_USER_LABEL_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, 0, ZCL_CHAR_STRING_ATTRIBUTE_TYPE, - zclName); + InteractionModelReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, + ZCL_USER_LABEL_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, 0, + ZCL_CHAR_STRING_ATTRIBUTE_TYPE, zclName); } if (itemChangedMask & Device::kChanged_Location) { @@ -343,8 +343,9 @@ void HandleDeviceStatusChanged(Device * dev, Device::Changed_t itemChangedMask) EncodeFixedLabel("room", dev->GetLocation(), buffer, sizeof(buffer), &am); - emberAfReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_FIXED_LABEL_CLUSTER_ID, ZCL_LABEL_LIST_ATTRIBUTE_ID, - CLUSTER_MASK_SERVER, 0, ZCL_ARRAY_ATTRIBUTE_TYPE, buffer); + InteractionModelReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_FIXED_LABEL_CLUSTER_ID, + ZCL_LABEL_LIST_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, 0, + ZCL_ARRAY_ATTRIBUTE_TYPE, buffer); } } diff --git a/examples/bridge-app/linux/main.cpp b/examples/bridge-app/linux/main.cpp index 9d4f08c1b07eb0..17af693bba8493 100644 --- a/examples/bridge-app/linux/main.cpp +++ b/examples/bridge-app/linux/main.cpp @@ -207,16 +207,16 @@ void HandleDeviceStatusChanged(Device * dev, Device::Changed_t itemChangedMask) if (itemChangedMask & Device::kChanged_Reachable) { uint8_t reachable = dev->IsReachable() ? 1 : 0; - emberAfReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, - ZCL_REACHABLE_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, 0, ZCL_BOOLEAN_ATTRIBUTE_TYPE, - &reachable); + InteractionModelReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, + ZCL_REACHABLE_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, 0, + ZCL_BOOLEAN_ATTRIBUTE_TYPE, &reachable); } if (itemChangedMask & Device::kChanged_State) { uint8_t isOn = dev->IsOn() ? 1 : 0; - emberAfReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, - CLUSTER_MASK_SERVER, 0, ZCL_BOOLEAN_ATTRIBUTE_TYPE, &isOn); + InteractionModelReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, + CLUSTER_MASK_SERVER, 0, ZCL_BOOLEAN_ATTRIBUTE_TYPE, &isOn); } if (itemChangedMask & Device::kChanged_Name) @@ -224,9 +224,9 @@ void HandleDeviceStatusChanged(Device * dev, Device::Changed_t itemChangedMask) uint8_t zclName[kUserLabelSize]; MutableByteSpan zclNameSpan(zclName); MakeZclCharString(zclNameSpan, dev->GetName()); - emberAfReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, - ZCL_USER_LABEL_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, 0, ZCL_CHAR_STRING_ATTRIBUTE_TYPE, - zclNameSpan.data()); + InteractionModelReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, + ZCL_USER_LABEL_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, 0, + ZCL_CHAR_STRING_ATTRIBUTE_TYPE, zclNameSpan.data()); } if (itemChangedMask & Device::kChanged_Location) @@ -238,8 +238,9 @@ void HandleDeviceStatusChanged(Device * dev, Device::Changed_t itemChangedMask) EncodeFixedLabel("room", dev->GetLocation(), buffer, sizeof(buffer), &am); - emberAfReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_FIXED_LABEL_CLUSTER_ID, ZCL_LABEL_LIST_ATTRIBUTE_ID, - CLUSTER_MASK_SERVER, 0, ZCL_ARRAY_ATTRIBUTE_TYPE, buffer); + InteractionModelReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_FIXED_LABEL_CLUSTER_ID, + ZCL_LABEL_LIST_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, 0, + ZCL_ARRAY_ATTRIBUTE_TYPE, buffer); } } diff --git a/examples/chip-tool/templates/partials/process_response_value.zapt b/examples/chip-tool/templates/partials/process_response_value.zapt new file mode 100644 index 00000000000000..e82ff965abcc7d --- /dev/null +++ b/examples/chip-tool/templates/partials/process_response_value.zapt @@ -0,0 +1,78 @@ +{{#chip_tests_item_response_parameters}} +{{#if hasExpectedValue}} +{{#if isList}} +if (count != {{expectedValue.length}}) +{ + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "{{expectedValue}}"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; +} +{{else}} +{{#if (isString type)}} +{{chipType}} {{asLowerCamelCase name}}Argument = chip::ByteSpan(chip::Uint8::from_const_char("{{expectedValue}}"), strlen("{{expectedValue}}")); +if (!{{asLowerCamelCase name}}.data_equal({{asLowerCamelCase name}}Argument)) +{{else}} +if ({{asLowerCamelCase name}} != {{expectedValue}}{{asTypeLiteralSuffix chipType}}) +{{/if}} +{ + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "{{expectedValue}}"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; +} +{{/if}} +{{/if}} +{{#if hasExpectedConstraints}} +{{#if expectedConstraints.type}} +ChipLogError(chipTool, "Warning: {{asLowerCamelCase name}} type checking is not implemented yet. Expected type: '%s'", "{{expectedConstraints.type}}"); +{{/if}} + +{{#if expectedConstraints.format}} +ChipLogError(chipTool, "Warning: {{asLowerCamelCase name}} format checking is not implemented yet. Expected format: '%s'", "{{expectedConstraints.format}}"); +{{/if}} + +{{#if expectedConstraints.minLength}} + if ({{asLowerCamelCase name}}.size() < {{expectedConstraints.minLength}}) + { + ChipLogError(chipTool, "Error: {{asLowerCamelCase name}} is too short. Min size is {{expectedConstraints.minLength}} but got '%zu'", {{asLowerCamelCase name}}.size()); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } +{{/if}} + +{{#if expectedConstraints.maxLength}} + if ({{asLowerCamelCase name}}.size() > {{expectedConstraints.maxLength}}) + { + ChipLogError(chipTool, "Error: {{asLowerCamelCase name}} is too long. Max size is {{expectedConstraints.maxLength}} but got '%zu'", {{asLowerCamelCase name}}.size()); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } +{{/if}} + +{{#if expectedConstraints.minValue}} + if ({{asLowerCamelCase name}} < {{expectedConstraints.minValue}}) + { + ChipLogError(chipTool, "Error: {{asLowerCamelCase name}} is lower than expected. Min value is {{expectedConstraints.minValue}} but got '%d'", {{asLowerCamelCase name}}); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } +{{/if}} + +{{#if expectedConstraints.maxValue}} + if ({{asLowerCamelCase name}} > {{expectedConstraints.maxValue}}) + { + ChipLogError(chipTool, "Error: {{asLowerCamelCase name}} is higher than expected. Max value is {{expectedConstraints.maxValue}} but got '%d'", {{asLowerCamelCase name}}); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } +{{/if}} + +{{#if expectedConstraints.notValue}} + if ({{asLowerCamelCase name}} == {{expectedConstraints.notValue}}) + { + ChipLogError(chipTool, "Error: {{asLowerCamelCase name}} was not expected to be '{{expectedConstraints.notValue}}' due to notValue constraint"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } +{{/if}} +{{/if}} +{{/chip_tests_item_response_parameters}} diff --git a/examples/chip-tool/templates/partials/test_cluster.zapt b/examples/chip-tool/templates/partials/test_cluster.zapt index 0be51994967840..6d7a4e3c352843 100644 --- a/examples/chip-tool/templates/partials/test_cluster.zapt +++ b/examples/chip-tool/templates/partials/test_cluster.zapt @@ -46,19 +46,22 @@ class {{filename}}: public TestCommand {{#chip_tests_items}} {{#if (isTestOnlyCluster cluster)}} - CHIP_ERROR TestSendCluster{{asUpperCamelCase cluster}}Command{{asUpperCamelCase command}}_{{index}}() - { - ChipLogProgress(chipTool, "{{cluster}} - {{label}}"); - - return {{command}}({{#chip_tests_item_parameters}}{{#not_first}}, {{/not_first}}{{definedValue}}{{/chip_tests_item_parameters}}); - } + {{> (asTestSuiteSimulatedClusterCommandPartial command) }} {{else}} // Test {{label}} using SuccessCallback_{{index}} = void (*)(void * context{{#chip_tests_item_response_parameters}}, {{#if isList}}uint16_t count, {{/if}}{{chipType}} {{#if isList}}* {{/if}}{{asLowerCamelCase name}}{{/chip_tests_item_response_parameters}}); chip::Callback::Callback mOnSuccessCallback_{{index}} { OnTestSendCluster{{asUpperCamelCase cluster}}Command{{asUpperCamelCase command}}_{{index}}_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_{{index}} { OnTestSendCluster{{asUpperCamelCase cluster}}Command{{asUpperCamelCase command}}_{{index}}_FailureResponse, this }; + {{#if isSubscribeAttribute}} + chip::Callback::Callback mOnSubscriptionEstablishedCallback_{{index}} { SubscribeAttribute_{{ index }}_OnSubscriptionEstablishedCallback, this }; + {{/if}} + bool mIsFailureExpected_{{index}} = {{response.error}}; + {{#if isSubscribeAttribute}} + bool mReceivedReport_{{index}} = false; + {{/if}} + CHIP_ERROR TestSendCluster{{asUpperCamelCase cluster}}Command{{asUpperCamelCase command}}_{{index}}() { ChipLogProgress(chipTool, "{{cluster}} - {{label}}: Sending command..."); @@ -77,6 +80,9 @@ class {{filename}}: public TestCommand {{/if}} {{/chip_tests_item_parameters}} err = cluster.{{asUpperCamelCase command}}(mOnSuccessCallback_{{index}}.Cancel(), mOnFailureCallback_{{index}}.Cancel(){{#chip_tests_item_parameters}}, {{asLowerCamelCase name}}Argument{{/chip_tests_item_parameters}}); + {{else if isSubscribeAttribute}} + cluster.ReportAttribute{{asUpperCamelCase attribute}}(mOnSuccessCallback_{{index}}.Cancel()); + err = cluster.ConfigureAttribute{{asUpperCamelCase attribute}}(mOnSubscriptionEstablishedCallback_{{index}}.Cancel(), mOnFailureCallback_{{index}}.Cancel(), {{minInterval}}, {{maxInterval}}); {{else if isReadAttribute}} err = cluster.ReadAttribute{{asUpperCamelCase attribute}}(mOnSuccessCallback_{{index}}.Cancel(), mOnFailureCallback_{{index}}.Cancel()); {{else if isWriteAttribute}} @@ -95,6 +101,19 @@ class {{filename}}: public TestCommand return err; } + {{#if isSubscribeAttribute }} + static void SubscribeAttribute_{{ index }}_OnSubscriptionEstablishedCallback(void * context) + { + {{parent.filename}} * runner = reinterpret_cast<{{parent.filename}} *>(context); + if (!runner->mReceivedReport_{{index}}) { + ChipLogError(chipTool, "Error: Initial report not received!"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + runner->NextTest(); + } + {{/if}} + static void OnTestSendCluster{{asUpperCamelCase cluster}}Command{{asUpperCamelCase command}}_{{index}}_FailureResponse(void * context, uint8_t status) { ChipLogProgress(chipTool, "{{cluster}} - {{label}}: Failure Response"); @@ -130,86 +149,13 @@ class {{filename}}: public TestCommand return; } - {{#chip_tests_item_response_parameters}} - {{#if hasExpectedValue}} - {{#if isList}} - if (count != {{expectedValue.length}}) - { - ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "{{expectedValue}}"); - runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); - return; - } - {{else}} - {{#if (isString type)}} - {{chipType}} {{asLowerCamelCase name}}Argument = chip::ByteSpan(chip::Uint8::from_const_char("{{expectedValue}}"), strlen("{{expectedValue}}")); - if (!{{asLowerCamelCase name}}.data_equal({{asLowerCamelCase name}}Argument)) - {{else}} - if ({{asLowerCamelCase name}} != {{expectedValue}}{{asTypeLiteralSuffix chipType}}) - {{/if}} - { - ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "{{expectedValue}}"); - runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); - return; - } - {{/if}} - {{/if}} - {{#if hasExpectedConstraints}} - {{#if expectedConstraints.type}} - ChipLogError(chipTool, "Warning: {{asLowerCamelCase name}} type checking is not implemented yet. Expected type: '%s'", "{{expectedConstraints.type}}"); - {{/if}} - - {{#if expectedConstraints.format}} - ChipLogError(chipTool, "Warning: {{asLowerCamelCase name}} format checking is not implemented yet. Expected format: '%s'", "{{expectedConstraints.format}}"); - {{/if}} - - {{#if expectedConstraints.minLength}} - if ({{asLowerCamelCase name}}.size() < {{expectedConstraints.minLength}}) - { - ChipLogError(chipTool, "Error: {{asLowerCamelCase name}} is too short. Min size is {{expectedConstraints.minLength}} but got '%zu'", {{asLowerCamelCase name}}.size()); - runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); - return; - } - {{/if}} - - {{#if expectedConstraints.maxLength}} - if ({{asLowerCamelCase name}}.size() > {{expectedConstraints.maxLength}}) - { - ChipLogError(chipTool, "Error: {{asLowerCamelCase name}} is too long. Max size is {{expectedConstraints.maxLength}} but got '%zu'", {{asLowerCamelCase name}}.size()); - runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); - return; - } - {{/if}} - - {{#if expectedConstraints.minValue}} - if ({{asLowerCamelCase name}} < {{expectedConstraints.minValue}}) - { - ChipLogError(chipTool, "Error: {{asLowerCamelCase name}} is lower than expected. Min value is {{expectedConstraints.minValue}} but got '%d'", {{asLowerCamelCase name}}); - runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); - return; - } - {{/if}} + {{> process_response_value}} - {{#if expectedConstraints.maxValue}} - if ({{asLowerCamelCase name}} > {{expectedConstraints.maxValue}}) - { - ChipLogError(chipTool, "Error: {{asLowerCamelCase name}} is higher than expected. Max value is {{expectedConstraints.maxValue}} but got '%d'", {{asLowerCamelCase name}}); - runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); - return; - } - {{/if}} - - {{#if expectedConstraints.notValue}} - if ({{asLowerCamelCase name}} == {{expectedConstraints.notValue}}) - { - ChipLogError(chipTool, "Error: {{asLowerCamelCase name}} was not expected to be '{{expectedConstraints.notValue}}' due to notValue constraint"); - runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); - return; - } - {{/if}} + {{#if isSubscribeAttribute}} + runner->mReceivedReport_{{index}} = true; + {{else}} + runner->NextTest(); {{/if}} - {{/chip_tests_item_response_parameters}} - - runner->NextTest(); } {{/if}} diff --git a/examples/chip-tool/templates/partials/testsuite/WaitForAttributeReport.zapt b/examples/chip-tool/templates/partials/testsuite/WaitForAttributeReport.zapt new file mode 100644 index 00000000000000..b45162af201604 --- /dev/null +++ b/examples/chip-tool/templates/partials/testsuite/WaitForAttributeReport.zapt @@ -0,0 +1,38 @@ +// The callback should be called atleast once +{{#chip_tests_WaitForAttributeReport_attribute_info}} +using OnReportCallback_{{parent.index}} = void (*)(void * context{{#chip_tests_item_response_parameters}}, {{#if isList}}uint16_t count, {{/if}}{{chipType}} {{#if isList}}* {{/if}}{{asLowerCamelCase name}}{{/chip_tests_item_response_parameters}}); +chip::Callback::Callback mOnReportCallback_{{parent.index}} { SubscribeAttribute_{{ parent.index }}_OnReportCallback, this }; +{{/chip_tests_WaitForAttributeReport_attribute_info}} + +bool mReceivedReport_{{index}} = false; + +CHIP_ERROR TestSendCluster{{asUpperCamelCase cluster}}Command{{asUpperCamelCase command}}_{{index}}() +{ + ChipLogProgress(chipTool, "{{cluster}} - {{asUpperCamelCase command}} - {{label}}"); +{{#chip_tests_WaitForAttributeReport_attribute_info}} + chip::Controller::{{asUpperCamelCase cluster}}Cluster cluster; + cluster.Associate(mDevice, {{endpoint}}); + return cluster.ReportAttribute{{asUpperCamelCase attribute}}(mOnReportCallback_{{parent.index}}.Cancel()); +{{/chip_tests_WaitForAttributeReport_attribute_info}} +} + +{{#chip_tests_WaitForAttributeReport_attribute_info}} +static void SubscribeAttribute_{{ parent.index }}_OnReportCallback(void * context{{#chip_tests_item_response_parameters}}, {{#if isList}}uint16_t count, {{/if}}{{chipType}} {{#if isList}}* {{/if}}{{asLowerCamelCase name}}{{/chip_tests_item_response_parameters}}) +{ + ChipLogProgress(chipTool, "On/Off - Subscribe {{asUpperCamelCase attribute}} Attribute: Report Data"); + {{parent.parent.filename}} * runner = reinterpret_cast<{{parent.parent.filename}} *>(context); + + if (runner->mReceivedReport_{{parent.index}}) + { + // Receiving attribute more than once is not an issue, since the following handler will override previous handlers. + return; + } + + {{> process_response_value}} + + runner->mReceivedReport_{{parent.index}} = true; + ChipLogProgress(chipTool, "On/Off - report received."); + runner->NextTest(); +} + +{{/chip_tests_WaitForAttributeReport_attribute_info}} diff --git a/examples/chip-tool/templates/partials/testsuite/WaitForMs.zapt b/examples/chip-tool/templates/partials/testsuite/WaitForMs.zapt new file mode 100644 index 00000000000000..771ae4227fe91b --- /dev/null +++ b/examples/chip-tool/templates/partials/testsuite/WaitForMs.zapt @@ -0,0 +1,6 @@ +CHIP_ERROR TestSendCluster{{asUpperCamelCase cluster}}Command{{asUpperCamelCase command}}_{{index}}() +{ + ChipLogProgress(chipTool, "{{cluster}} - {{asUpperCamelCase command}} - {{label}}"); + + return {{command}}({{#chip_tests_item_parameters}}{{#not_first}}, {{/not_first}}{{definedValue}}{{/chip_tests_item_parameters}}); +} diff --git a/examples/chip-tool/templates/reporting-commands.zapt b/examples/chip-tool/templates/reporting-commands.zapt index a7b50578be5aa1..c9c05e691fb22f 100644 --- a/examples/chip-tool/templates/reporting-commands.zapt +++ b/examples/chip-tool/templates/reporting-commands.zapt @@ -31,7 +31,7 @@ public: {{#chip_client_clusters}} {{#chip_server_cluster_attributes}} {{#if isReportableAttribute}} - callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, {{asHex parent.code 4}}, {{asHex code 4}}, onReport{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}Callback->Cancel()); + callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, {{asHex parent.code 4}}, {{asHex code 4}}, onReport{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}Callback->Cancel(), BasicAttributeFilter<{{chipCallback.name}}AttributeCallback>); {{/if}} {{/chip_server_cluster_attributes}} {{/chip_client_clusters}} diff --git a/examples/chip-tool/templates/templates.json b/examples/chip-tool/templates/templates.json index 55b4702a55cdbd..e378232b78a82f 100644 --- a/examples/chip-tool/templates/templates.json +++ b/examples/chip-tool/templates/templates.json @@ -23,9 +23,21 @@ "name": "cluster_header", "path": "../../../src/app/zap-templates/partials/cluster_header.zapt" }, + { + "name": "process_response_value", + "path": "partials/process_response_value.zapt" + }, { "name": "test_cluster", "path": "partials/test_cluster.zapt" + }, + { + "name": "TestSuiteHelper_WaitForMs", + "path": "partials/testsuite/WaitForMs.zapt" + }, + { + "name": "TestSuiteHelper_WaitForAttributeReport", + "path": "partials/testsuite/WaitForAttributeReport.zapt" } ], "templates": [ diff --git a/examples/chip-tool/templates/tests-commands.zapt b/examples/chip-tool/templates/tests-commands.zapt index 85b73098b087e4..f667107cb8a2c9 100644 --- a/examples/chip-tool/templates/tests-commands.zapt +++ b/examples/chip-tool/templates/tests-commands.zapt @@ -4,4 +4,5 @@ #include -{{>test_cluster tests="TV_TargetNavigatorCluster, TV_AudioOutputCluster, TV_ApplicationLauncherCluster, TV_KeypadInputCluster, TV_AccountLoginCluster, TV_WakeOnLanCluster, TV_ApplicationBasicCluster, TV_MediaPlaybackCluster, TV_TvChannelCluster, TV_LowPowerCluster, TV_MediaInputCluster, TestCluster, TestConstraints, TestDelayCommands, Test_TC_OO_1_1, Test_TC_OO_2_1, Test_TC_OO_2_2, Test_TC_DM_1_1, Test_TC_DM_3_1, Test_TC_CC_3_4, Test_TC_CC_5, Test_TC_CC_6, Test_TC_CC_7, Test_TC_CC_8, Test_TC_WNCV_1_1, Test_TC_WNCV_2_1, Test_TC_BI_1_1, Test_TC_FLW_1_1, Test_TC_TM_1_1, Test_TC_OCC_1_1, OperationalCredentialsCluster"}} +{{>test_cluster tests="TV_TargetNavigatorCluster, TV_AudioOutputCluster, TV_ApplicationLauncherCluster, TV_KeypadInputCluster, TV_AccountLoginCluster, TV_WakeOnLanCluster, TV_ApplicationBasicCluster, TV_MediaPlaybackCluster, TV_TvChannelCluster, TV_LowPowerCluster, TV_MediaInputCluster, TestCluster, TestConstraints, TestDelayCommands, TestSubscribe_OnOff, Test_TC_OO_1_1, Test_TC_OO_2_1, Test_TC_OO_2_2, Test_TC_DM_1_1, Test_TC_DM_3_1, Test_TC_CC_3_4, Test_TC_CC_5, Test_TC_CC_6, Test_TC_CC_7, Test_TC_CC_8, Test_TC_WNCV_1_1, Test_TC_WNCV_2_1, Test_TC_BI_1_1, Test_TC_FLW_1_1, Test_TC_TM_1_1, Test_TC_OCC_1_1, OperationalCredentialsCluster"}} + diff --git a/src/app/ClusterInfo.h b/src/app/ClusterInfo.h index 9d22ad8514b8bd..f9179ab373db72 100644 --- a/src/app/ClusterInfo.h +++ b/src/app/ClusterInfo.h @@ -92,15 +92,11 @@ struct ClusterInfo } ClusterInfo() {} - bool IsDirty() { return mDirty; } - void SetDirty() { mDirty = true; } - void ClearDirty() { mDirty = false; } NodeId mNodeId = 0; ClusterId mClusterId = 0; ListIndex mListIndex = 0; AttributeId mFieldId = 0; EndpointId mEndpointId = 0; - bool mDirty = false; BitFlags mFlags; ClusterInfo * mpNext = nullptr; EventId mEventId = 0; diff --git a/src/app/InteractionModelDelegate.h b/src/app/InteractionModelDelegate.h index 2c1cccf2a93ba7..9068a5c2e3c15c 100644 --- a/src/app/InteractionModelDelegate.h +++ b/src/app/InteractionModelDelegate.h @@ -40,6 +40,7 @@ static constexpr uint32_t kImMessageTimeoutMsec = 12000; class ReadClient; class WriteClient; class CommandSender; +class ReadHandler; /** * @brief @@ -196,7 +197,17 @@ class InteractionModelDelegate } /** - * Notification that a read client has completed the current interaction. + * Notification that a Subscribe Response has been processed and application can do further work . + */ + virtual CHIP_ERROR SubscribeResponseProcessed(const ReadClient * apReadClient) { return CHIP_ERROR_NOT_IMPLEMENTED; } + + /** + * Notification that Subscription has been established successfully and application can do further work in handler. + */ + virtual CHIP_ERROR SubscriptionEstablished(const ReadHandler * apReadHandler) { return CHIP_ERROR_NOT_IMPLEMENTED; } + + /** + * Notification that a read interaction was completed on the client successfully. * @param[in] apReadClient A current read client which can identify the read client to the consumer, particularly * during multiple read interactions * @param[in] aError notify final error regarding the current read interaction diff --git a/src/app/InteractionModelEngine.cpp b/src/app/InteractionModelEngine.cpp index 893c279060bc0f..bda1188f806f47 100644 --- a/src/app/InteractionModelEngine.cpp +++ b/src/app/InteractionModelEngine.cpp @@ -106,10 +106,11 @@ void InteractionModelEngine::Shutdown() VerifyOrDie(writeHandler.IsFree()); } + mReportingEngine.Shutdown(); + for (uint32_t index = 0; index < CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS; index++) { mClusterInfoPool[index].mpNext = nullptr; - mClusterInfoPool[index].ClearDirty(); } mpNextAvailableClusterInfo = nullptr; @@ -137,7 +138,8 @@ CHIP_ERROR InteractionModelEngine::NewCommandSender(CommandSender ** const apCom return CHIP_ERROR_NO_MEMORY; } -CHIP_ERROR InteractionModelEngine::NewReadClient(ReadClient ** const apReadClient, uint64_t aAppIdentifier) +CHIP_ERROR InteractionModelEngine::NewReadClient(ReadClient ** const apReadClient, ReadClient::InteractionType aInteractionType, + uint64_t aAppIdentifier) { CHIP_ERROR err = CHIP_ERROR_NO_MEMORY; @@ -146,7 +148,7 @@ CHIP_ERROR InteractionModelEngine::NewReadClient(ReadClient ** const apReadClien if (readClient.IsFree()) { *apReadClient = &readClient; - err = readClient.Init(mpExchangeMgr, mpDelegate, aAppIdentifier); + err = readClient.Init(mpExchangeMgr, mpDelegate, aInteractionType, aAppIdentifier); if (CHIP_NO_ERROR != err) { *apReadClient = nullptr; @@ -227,17 +229,19 @@ CHIP_ERROR InteractionModelEngine::OnInvokeCommandRequest(Messaging::ExchangeCon CHIP_ERROR InteractionModelEngine::OnReadInitialRequest(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader, - System::PacketBufferHandle && aPayload) + System::PacketBufferHandle && aPayload, + ReadHandler::InteractionType aInteractionType) { CHIP_ERROR err = CHIP_NO_ERROR; - ChipLogDetail(InteractionModel, "Receive Read request"); + ChipLogDetail(InteractionModel, "Receive %s request", + aInteractionType == ReadHandler::InteractionType::Subscribe ? "Subscribe" : "Read"); for (auto & readHandler : mReadHandlers) { if (readHandler.IsFree()) { - err = readHandler.Init(mpExchangeMgr, mpDelegate, apExchangeContext); + err = readHandler.Init(mpExchangeMgr, mpDelegate, apExchangeContext, aInteractionType); SuccessOrExit(err); err = readHandler.OnReadInitialRequest(std::move(aPayload)); apExchangeContext = nullptr; @@ -282,6 +286,36 @@ CHIP_ERROR InteractionModelEngine::OnWriteRequest(Messaging::ExchangeContext * a return err; } +CHIP_ERROR InteractionModelEngine::OnUnsolicitedReportData(Messaging::ExchangeContext * apExchangeContext, + const PayloadHeader & aPayloadHeader, + System::PacketBufferHandle && aPayload) +{ + System::PacketBufferTLVReader reader; + reader.Init(aPayload.Retain()); + ReturnLogErrorOnFailure(reader.Next()); + + ReportData::Parser report; + ReturnLogErrorOnFailure(report.Init(reader)); + + uint64_t subscriptionId = 0; + ReturnLogErrorOnFailure(report.GetSubscriptionId(&subscriptionId)); + + for (auto & readClient : mReadClients) + { + if (!readClient.IsSubscriptionTypeIdle()) + { + continue; + } + if (!readClient.IsMatchingClient(subscriptionId)) + { + continue; + } + + return readClient.OnUnsolicitedReportData(apExchangeContext, std::move(aPayload)); + } + return CHIP_NO_ERROR; +} + CHIP_ERROR InteractionModelEngine::OnMessageReceived(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader, System::PacketBufferHandle && aPayload) { @@ -291,12 +325,21 @@ CHIP_ERROR InteractionModelEngine::OnMessageReceived(Messaging::ExchangeContext } else if (aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::ReadRequest)) { - return OnReadInitialRequest(apExchangeContext, aPayloadHeader, std::move(aPayload)); + return OnReadInitialRequest(apExchangeContext, aPayloadHeader, std::move(aPayload), ReadHandler::InteractionType::Read); } else if (aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::WriteRequest)) { return OnWriteRequest(apExchangeContext, aPayloadHeader, std::move(aPayload)); } + else if (aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::SubscribeRequest)) + { + return OnReadInitialRequest(apExchangeContext, aPayloadHeader, std::move(aPayload), + ReadHandler::InteractionType::Subscribe); + } + else if (aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::ReportData)) + { + return OnUnsolicitedReportData(apExchangeContext, aPayloadHeader, std::move(aPayload)); + } else { return OnUnknownMsgType(apExchangeContext, aPayloadHeader, std::move(aPayload)); @@ -312,7 +355,7 @@ CHIP_ERROR InteractionModelEngine::SendReadRequest(ReadPrepareParams & aReadPrep { ReadClient * client = nullptr; CHIP_ERROR err = CHIP_NO_ERROR; - ReturnErrorOnFailure(NewReadClient(&client, aAppIdentifier)); + ReturnErrorOnFailure(NewReadClient(&client, ReadClient::InteractionType::Read, aAppIdentifier)); err = client->SendReadRequest(aReadPrepareParams); if (err != CHIP_NO_ERROR) { @@ -321,6 +364,14 @@ CHIP_ERROR InteractionModelEngine::SendReadRequest(ReadPrepareParams & aReadPrep return err; } +CHIP_ERROR InteractionModelEngine::SendSubscribeRequest(ReadPrepareParams & aReadPrepareParams, uint64_t aAppIdentifier) +{ + ReadClient * client = nullptr; + ReturnErrorOnFailure(NewReadClient(&client, ReadClient::InteractionType::Subscribe, aAppIdentifier)); + ReturnErrorOnFailure(client->SendSubscribeRequest(aReadPrepareParams)); + return CHIP_NO_ERROR; +} + uint16_t InteractionModelEngine::GetReadClientArrayIndex(const ReadClient * const apReadClient) const { return static_cast(apReadClient - mReadClients); @@ -341,10 +392,8 @@ void InteractionModelEngine::ReleaseClusterInfoList(ClusterInfo *& aClusterInfo) while (lastClusterInfo != nullptr && lastClusterInfo->mpNext != nullptr) { - lastClusterInfo->ClearDirty(); lastClusterInfo = lastClusterInfo->mpNext; } - lastClusterInfo->ClearDirty(); lastClusterInfo->mFlags.ClearAll(); lastClusterInfo->mpNext = mpNextAvailableClusterInfo; mpNextAvailableClusterInfo = aClusterInfo; @@ -356,6 +405,7 @@ CHIP_ERROR InteractionModelEngine::PushFront(ClusterInfo *& aClusterInfoList, Cl ClusterInfo * last = aClusterInfoList; if (mpNextAvailableClusterInfo == nullptr) { + ChipLogProgress(InteractionModel, "There is no available cluster info in mClusterInfoPool"); return CHIP_ERROR_NO_MEMORY; } aClusterInfoList = mpNextAvailableClusterInfo; @@ -365,5 +415,50 @@ CHIP_ERROR InteractionModelEngine::PushFront(ClusterInfo *& aClusterInfoList, Cl return CHIP_NO_ERROR; } +bool InteractionModelEngine::MergeOverlappedAttributePath(ClusterInfo * apAttributePathList, ClusterInfo & aAttributePath) +{ + ClusterInfo * runner = apAttributePathList; + while (runner != nullptr) + { + // If overlapped, we would skip this target path, + // --If targetPath is part of previous path, return true + // --If previous path is part of target path, update filedid and listindex and mflags with target path, return true + if (runner->IsAttributePathSupersetOf(aAttributePath)) + { + return true; + } + if (aAttributePath.IsAttributePathSupersetOf(*runner)) + { + runner->mListIndex = aAttributePath.mListIndex; + runner->mFieldId = aAttributePath.mFieldId; + runner->mFlags = aAttributePath.mFlags; + return true; + } + runner = runner->mpNext; + } + return false; +} + +bool InteractionModelEngine::IsOverlappedAttributePath(ClusterInfo & aAttributePath) +{ + for (auto & handler : mReadHandlers) + { + if (handler.IsSubscriptionType() && (handler.IsGeneratingReports() || handler.IsAwaitingReportResponse())) + { + for (auto clusterInfo = handler.GetAttributeClusterInfolist(); clusterInfo != nullptr; + clusterInfo = clusterInfo->mpNext) + { + if (clusterInfo->IsAttributePathSupersetOf(aAttributePath) || + aAttributePath.IsAttributePathSupersetOf(*clusterInfo)) + { + return true; + } + } + } + } + ChipLogDetail(DataManagement, "AttributePath is not interested"); + return false; +} + } // namespace app } // namespace chip diff --git a/src/app/InteractionModelEngine.h b/src/app/InteractionModelEngine.h index f1c2290ca241c8..3e0dd9e1e30ca3 100644 --- a/src/app/InteractionModelEngine.h +++ b/src/app/InteractionModelEngine.h @@ -111,6 +111,14 @@ class InteractionModelEngine : public Messaging::ExchangeDelegate */ CHIP_ERROR SendReadRequest(ReadPrepareParams & aReadPrepareParams, uint64_t aAppIdentifier = 0); + /** + * Creates a new read client and sends SubscribeRequest message to the node using the read client. + * Shuts down on transmission failure. + * + * @retval #CHIP_ERROR_NO_MEMORY If there is no ReadClient available + * @retval #CHIP_NO_ERROR On success. + */ + CHIP_ERROR SendSubscribeRequest(ReadPrepareParams & aReadPrepareParams, uint64_t aAppIdentifier = 0); /** * Retrieve a WriteClient that the SDK consumer can use to send a write. If the call succeeds, * see WriteClient documentation for lifetime handling. @@ -141,6 +149,10 @@ class InteractionModelEngine : public Messaging::ExchangeDelegate void ReleaseClusterInfoList(ClusterInfo *& aClusterInfo); CHIP_ERROR PushFront(ClusterInfo *& aClusterInfoLisst, ClusterInfo & aClusterInfo); + // Merges aAttributePath inside apAttributePathList if current path is overlapped with existing path in apAttributePathList + // Overlap means the path is superset or subset of another path + bool MergeOverlappedAttributePath(ClusterInfo * apAttributePathList, ClusterInfo & aAttributePath); + bool IsOverlappedAttributePath(ClusterInfo & aAttributePath); private: friend class reporting::Engine; @@ -156,8 +168,9 @@ class InteractionModelEngine : public Messaging::ExchangeDelegate * Called when Interaction Model receives a Read Request message. Errors processing * the Read Request are handled entirely within this function. */ + CHIP_ERROR OnReadInitialRequest(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader, - System::PacketBufferHandle && aPayload); + System::PacketBufferHandle && aPayload, ReadHandler::InteractionType aInteractionType); /** * Called when Interaction Model receives a Write Request message. Errors processing @@ -166,6 +179,11 @@ class InteractionModelEngine : public Messaging::ExchangeDelegate CHIP_ERROR OnWriteRequest(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader, System::PacketBufferHandle && aPayload); + /**This function handles processing of un-solicited ReportData messages on the client, which can + * only occur post subscription establishment + */ + CHIP_ERROR OnUnsolicitedReportData(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader, + System::PacketBufferHandle && aPayload); /** * Retrieve a ReadClient that the SDK consumer can use to send do a read. If the call succeeds, the consumer * is responsible for calling Shutdown() on the ReadClient once it's done using it. @@ -173,7 +191,8 @@ class InteractionModelEngine : public Messaging::ExchangeDelegate * @retval #CHIP_ERROR_INCORRECT_STATE If there is no ReadClient available * @retval #CHIP_NO_ERROR On success. */ - CHIP_ERROR NewReadClient(ReadClient ** const apReadClient, uint64_t aAppIdentifier); + CHIP_ERROR NewReadClient(ReadClient ** const apReadClient, ReadClient::InteractionType aInteractionType, + uint64_t aAppIdentifier); Messaging::ExchangeManager * mpExchangeMgr = nullptr; InteractionModelDelegate * mpDelegate = nullptr; diff --git a/src/app/MessageDef/SubscribeResponse.cpp b/src/app/MessageDef/SubscribeResponse.cpp index 6e19cda36512bd..6add842ded8c92 100644 --- a/src/app/MessageDef/SubscribeResponse.cpp +++ b/src/app/MessageDef/SubscribeResponse.cpp @@ -59,15 +59,27 @@ CHIP_ERROR SubscribeResponse::Parser::CheckSchemaValidity() const } #endif // CHIP_DETAIL_LOGGING break; - case kCsTag_FinalSyncIntervalSeconds: - VerifyOrReturnLogError(!(TagPresenceMask & (1 << kCsTag_FinalSyncIntervalSeconds)), CHIP_ERROR_INVALID_TLV_TAG); - TagPresenceMask |= (1 << kCsTag_FinalSyncIntervalSeconds); + case kCsTag_MinIntervalFloorSeconds: + VerifyOrReturnLogError(!(TagPresenceMask & (1 << kCsTag_MinIntervalFloorSeconds)), CHIP_ERROR_INVALID_TLV_TAG); + TagPresenceMask |= (1 << kCsTag_MinIntervalFloorSeconds); VerifyOrReturnLogError(chip::TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); #if CHIP_DETAIL_LOGGING { - uint16_t finalSyncIntervalSeconds; - ReturnLogErrorOnFailure(reader.Get(finalSyncIntervalSeconds)); - PRETTY_PRINT("\tFinalSyncIntervalSeconds = 0x%" PRIx16 ",", finalSyncIntervalSeconds); + uint16_t minIntervalFloorSeconds; + ReturnLogErrorOnFailure(reader.Get(minIntervalFloorSeconds)); + PRETTY_PRINT("\tMinIntervalFloorSeconds = 0x%" PRIx16 ",", minIntervalFloorSeconds); + } +#endif // CHIP_DETAIL_LOGGING + break; + case kCsTag_MaxIntervalCeilingSeconds: + VerifyOrReturnLogError(!(TagPresenceMask & (1 << kCsTag_MaxIntervalCeilingSeconds)), CHIP_ERROR_INVALID_TLV_TAG); + TagPresenceMask |= (1 << kCsTag_MaxIntervalCeilingSeconds); + VerifyOrReturnLogError(chip::TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); +#if CHIP_DETAIL_LOGGING + { + uint16_t maxIntervalCeilingSeconds; + ReturnLogErrorOnFailure(reader.Get(maxIntervalCeilingSeconds)); + PRETTY_PRINT("\tMaxIntervalCeilingSeconds = 0x%" PRIx16 ",", maxIntervalCeilingSeconds); } #endif // CHIP_DETAIL_LOGGING break; @@ -80,7 +92,8 @@ CHIP_ERROR SubscribeResponse::Parser::CheckSchemaValidity() const if (CHIP_END_OF_TLV == err) { - const uint16_t RequiredFields = (1 << kCsTag_SubscriptionId) | (1 << kCsTag_FinalSyncIntervalSeconds); + const uint16_t RequiredFields = + (1 << kCsTag_SubscriptionId) | (1 << kCsTag_MinIntervalFloorSeconds) | (1 << kCsTag_MaxIntervalCeilingSeconds); if ((TagPresenceMask & RequiredFields) == RequiredFields) { @@ -97,9 +110,14 @@ CHIP_ERROR SubscribeResponse::Parser::GetSubscriptionId(uint64_t * const apSubsc return GetUnsignedInteger(kCsTag_SubscriptionId, apSubscribeId); } -CHIP_ERROR SubscribeResponse::Parser::GetFinalSyncIntervalSeconds(uint16_t * const apFinalSyncIntervalSeconds) const +CHIP_ERROR SubscribeResponse::Parser::GetMinIntervalFloorSeconds(uint16_t * const apMinIntervalFloorSeconds) const +{ + return GetUnsignedInteger(kCsTag_MinIntervalFloorSeconds, apMinIntervalFloorSeconds); +} + +CHIP_ERROR SubscribeResponse::Parser::GetMaxIntervalCeilingSeconds(uint16_t * const apMaxIntervalCeilingSeconds) const { - return GetUnsignedInteger(kCsTag_FinalSyncIntervalSeconds, apFinalSyncIntervalSeconds); + return GetUnsignedInteger(kCsTag_MaxIntervalCeilingSeconds, apMaxIntervalCeilingSeconds); } CHIP_ERROR SubscribeResponse::Builder::Init(chip::TLV::TLVWriter * const apWriter) @@ -116,11 +134,20 @@ SubscribeResponse::Builder & SubscribeResponse::Builder::SubscriptionId(const ui return *this; } -SubscribeResponse::Builder & SubscribeResponse::Builder::FinalSyncIntervalSeconds(const uint16_t aFinalSyncIntervalSeconds) +SubscribeResponse::Builder & SubscribeResponse::Builder::MinIntervalFloorSeconds(const uint16_t aMinIntervalFloorSeconds) +{ + if (mError == CHIP_NO_ERROR) + { + mError = mpWriter->Put(chip::TLV::ContextTag(kCsTag_MinIntervalFloorSeconds), aMinIntervalFloorSeconds); + } + return *this; +} + +SubscribeResponse::Builder & SubscribeResponse::Builder::MaxIntervalCeilingSeconds(const uint16_t aMaxIntervalCeilingSeconds) { if (mError == CHIP_NO_ERROR) { - mError = mpWriter->Put(chip::TLV::ContextTag(kCsTag_FinalSyncIntervalSeconds), aFinalSyncIntervalSeconds); + mError = mpWriter->Put(chip::TLV::ContextTag(kCsTag_MaxIntervalCeilingSeconds), aMaxIntervalCeilingSeconds); } return *this; } diff --git a/src/app/MessageDef/SubscribeResponse.h b/src/app/MessageDef/SubscribeResponse.h index bf01f1ff74eb3e..0ba9ca4f27d438 100644 --- a/src/app/MessageDef/SubscribeResponse.h +++ b/src/app/MessageDef/SubscribeResponse.h @@ -31,8 +31,9 @@ namespace app { namespace SubscribeResponse { enum { - kCsTag_SubscriptionId = 0, - kCsTag_FinalSyncIntervalSeconds = 1, + kCsTag_SubscriptionId = 0, + kCsTag_MinIntervalFloorSeconds = 1, + kCsTag_MaxIntervalCeilingSeconds = 2, }; class Parser : public chip::app::Parser @@ -66,12 +67,20 @@ class Parser : public chip::app::Parser CHIP_ERROR GetSubscriptionId(uint64_t * const apSubscriptionId) const; /** - * @brief Get FinalSyncIntervalSeconds. Next() must be called before accessing them. + * @brief Get Final MinIntervalFloorSeconds. Next() must be called before accessing them. * * @return #CHIP_NO_ERROR on success * #CHIP_END_OF_TLV if there is no such element */ - CHIP_ERROR GetFinalSyncIntervalSeconds(uint16_t * const apFinalSyncIntervalSeconds) const; + CHIP_ERROR GetMinIntervalFloorSeconds(uint16_t * const apMinIntervalFloorSeconds) const; + + /** + * @brief Get Final MaxIntervalCeilingSeconds. Next() must be called before accessing them. + * + * @return #CHIP_NO_ERROR on success + * #CHIP_END_OF_TLV if there is no such element + */ + CHIP_ERROR GetMaxIntervalCeilingSeconds(uint16_t * const apMaxIntervalCeilingSeconds) const; }; class Builder : public chip::app::Builder @@ -85,9 +94,14 @@ class Builder : public chip::app::Builder SubscribeResponse::Builder & SubscriptionId(const uint64_t SubscriptionId); /** - * @brief Final Sync Interval for the subscription back to the clients. + * @brief Final Min Interval for the subscription back to the clients. + */ + SubscribeResponse::Builder & MinIntervalFloorSeconds(const uint16_t aMinIntervalFloorSeconds); + + /** + * @brief Final Max Interval for the subscription back to the clients. */ - SubscribeResponse::Builder & FinalSyncIntervalSeconds(const uint16_t aFinalSyncIntervalSeconds); + SubscribeResponse::Builder & MaxIntervalCeilingSeconds(const uint16_t aMaxIntervalCeilingSeconds); /** * @brief Mark the end of this SubscribeResponse diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index 6b2c4a34ed2bf9..b9dea66a60334f 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -31,18 +31,22 @@ namespace chip { namespace app { CHIP_ERROR ReadClient::Init(Messaging::ExchangeManager * apExchangeMgr, InteractionModelDelegate * apDelegate, - uint64_t aAppIdentifier) + InteractionType aInteractionType, uint64_t aAppIdentifier) { CHIP_ERROR err = CHIP_NO_ERROR; // Error if already initialized. + VerifyOrExit(IsFree(), err = CHIP_ERROR_INCORRECT_STATE); VerifyOrExit(apExchangeMgr != nullptr, err = CHIP_ERROR_INCORRECT_STATE); VerifyOrExit(mpExchangeMgr == nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); - - mpExchangeMgr = apExchangeMgr; - mpDelegate = apDelegate; - mState = ClientState::Initialized; - mAppIdentifier = aAppIdentifier; - mInitialReport = true; + mpExchangeMgr = apExchangeMgr; + mpDelegate = apDelegate; + mState = ClientState::Initialized; + mAppIdentifier = aAppIdentifier; + mMinIntervalFloorSeconds = 0; + mMaxIntervalCeilingSeconds = 0; + mSubscriptionId = 0; + mInitialReport = true; + mInteractionType = aInteractionType; AbortExistingExchangeContext(); exit: @@ -63,12 +67,23 @@ void ReadClient::ShutdownInternal(CHIP_ERROR aError) { mpDelegate->ReadError(this, aError); } - mpDelegate->ReadDone(this); + else + { + mpDelegate->ReadDone(this); + } mpDelegate = nullptr; } - mpExchangeMgr = nullptr; - mpExchangeCtx = nullptr; - mInitialReport = true; + if (IsSubscriptionType()) + { + CancelLivenessCheckTimer(); + } + mMinIntervalFloorSeconds = 0; + mMaxIntervalCeilingSeconds = 0; + mSubscriptionId = 0; + mInteractionType = InteractionType::Read; + mpExchangeMgr = nullptr; + mpExchangeCtx = nullptr; + mInitialReport = true; MoveToState(ClientState::Uninitialized); } @@ -83,6 +98,10 @@ const char * ReadClient::GetStateStr() const return "INIT"; case ClientState::AwaitingInitialReport: return "AwaitingInitialReport"; + case ClientState::AwaitingSubscribeResponse: + return "AwaitingSubscribeResponse"; + case ClientState::SubscriptionActive: + return "SubscriptionActive"; } #endif // CHIP_DETAIL_LOGGING return "N/A"; @@ -175,7 +194,6 @@ CHIP_ERROR ReadClient::SendStatusReport(CHIP_ERROR aError) Protocols::SecureChannel::GeneralStatusCode generalCode = Protocols::SecureChannel::GeneralStatusCode::kSuccess; uint32_t protocolId = Protocols::InteractionModel::Id.ToFullyQualifiedSpecForm(); uint16_t protocolCode = to_underlying(Protocols::InteractionModel::ProtocolCode::Success); - bool expectResponse = false; VerifyOrReturnLogError(mpExchangeCtx != nullptr, CHIP_ERROR_INCORRECT_STATE); if (aError != CHIP_NO_ERROR) @@ -191,9 +209,21 @@ CHIP_ERROR ReadClient::SendStatusReport(CHIP_ERROR aError) System::PacketBufferHandle msgBuf = buf.Finalize(); VerifyOrReturnLogError(!msgBuf.IsNull(), CHIP_ERROR_NO_MEMORY); - ReturnLogErrorOnFailure(mpExchangeCtx->SendMessage( - Protocols::SecureChannel::MsgType::StatusReport, std::move(msgBuf), - Messaging::SendFlags(expectResponse ? Messaging::SendMessageFlags::kExpectResponse : Messaging::SendMessageFlags::kNone))); + if (IsSubscriptionType()) + { + if (IsAwaitingInitialReport()) + { + MoveToState(ClientState::AwaitingSubscribeResponse); + } + else + { + RefreshLivenessCheckTimer(); + } + } + ReturnLogErrorOnFailure( + mpExchangeCtx->SendMessage(Protocols::SecureChannel::MsgType::StatusReport, std::move(msgBuf), + Messaging::SendFlags(IsAwaitingSubscribeResponse() ? Messaging::SendMessageFlags::kExpectResponse + : Messaging::SendMessageFlags::kNone))); return CHIP_NO_ERROR; } @@ -261,14 +291,22 @@ CHIP_ERROR ReadClient::OnMessageReceived(Messaging::ExchangeContext * apExchange err = ProcessReportData(std::move(aPayload)); SuccessOrExit(err); } + else if (aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::SubscribeResponse)) + { + VerifyOrExit(apExchangeContext == mpExchangeCtx, err = CHIP_ERROR_INCORRECT_STATE); + err = ProcessSubscribeResponse(std::move(aPayload)); + SuccessOrExit(err); + } else { err = CHIP_ERROR_INVALID_MESSAGE_TYPE; } exit: - ShutdownInternal(err); - + if (!IsSubscriptionType() || err != CHIP_NO_ERROR) + { + ShutdownInternal(err); + } return err; } @@ -283,6 +321,18 @@ CHIP_ERROR ReadClient::AbortExistingExchangeContext() return CHIP_NO_ERROR; } +CHIP_ERROR ReadClient::OnUnsolicitedReportData(Messaging::ExchangeContext * apExchangeContext, + System::PacketBufferHandle && aPayload) +{ + mpExchangeCtx = apExchangeContext; + CHIP_ERROR err = ProcessReportData(std::move(aPayload)); + if (err != CHIP_NO_ERROR) + { + ShutdownInternal(err); + } + return err; +} + CHIP_ERROR ReadClient::ProcessReportData(System::PacketBufferHandle && aPayload) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -292,6 +342,7 @@ CHIP_ERROR ReadClient::ProcessReportData(System::PacketBufferHandle && aPayload) bool isAttributeDataListPresent = false; bool suppressResponse = false; bool moreChunkedMessages = false; + uint64_t subscriptionId = 0; EventList::Parser eventList; AttributeDataList::Parser attributeDataList; System::PacketBufferTLVReader reader; @@ -314,10 +365,31 @@ CHIP_ERROR ReadClient::ProcessReportData(System::PacketBufferHandle && aPayload) } SuccessOrExit(err); - if (IsInitialReport()) + err = report.GetSubscriptionId(&subscriptionId); + if (CHIP_NO_ERROR == err) + { + if (IsInitialReport()) + { + mSubscriptionId = subscriptionId; + } + else if (!IsMatchingClient(subscriptionId)) + { + err = CHIP_ERROR_INVALID_ARGUMENT; + } + } + else if (CHIP_END_OF_TLV == err) { - ChipLogProgress(DataManagement, "ProcessReportData handles the initial report"); + if (IsSubscriptionType()) + { + err = CHIP_ERROR_INVALID_ARGUMENT; + } + else + { + err = CHIP_NO_ERROR; + } } + SuccessOrExit(err); + err = report.GetMoreChunkedMessages(&moreChunkedMessages); if (CHIP_END_OF_TLV == err) { @@ -368,6 +440,10 @@ CHIP_ERROR ReadClient::ProcessReportData(System::PacketBufferHandle && aPayload) } exit: SendStatusReport(err); + if (!mInitialReport) + { + mpExchangeCtx = nullptr; + } mInitialReport = false; return err; } @@ -453,5 +529,136 @@ CHIP_ERROR ReadClient::ProcessAttributeDataList(TLV::TLVReader & aAttributeDataL exit: return err; } + +CHIP_ERROR ReadClient::RefreshLivenessCheckTimer() +{ + CancelLivenessCheckTimer(); + ChipLogProgress(DataManagement, "Refresh LivenessCheckTime with %d seconds", mMaxIntervalCeilingSeconds); + CHIP_ERROR err = InteractionModelEngine::GetInstance()->GetExchangeManager()->GetSessionMgr()->SystemLayer()->StartTimer( + mMaxIntervalCeilingSeconds * kMillisecondsPerSecond, OnLivenessTimeoutCallback, this); + + if (err != CHIP_NO_ERROR) + { + ShutdownInternal(err); + } + return err; +} + +void ReadClient::CancelLivenessCheckTimer() +{ + InteractionModelEngine::GetInstance()->GetExchangeManager()->GetSessionMgr()->SystemLayer()->CancelTimer( + OnLivenessTimeoutCallback, this); +} + +void ReadClient::OnLivenessTimeoutCallback(System::Layer * apSystemLayer, void * apAppState) +{ + ReadClient * const client = reinterpret_cast(apAppState); + ChipLogError(DataManagement, "Subscription Liveness timeout, shutting down"); + if (client->IsFree()) + { + ChipLogError(DataManagement, + "ReadClient::OnLivenessTimeoutCallback invoked on a free client! This is a bug in CHIP stack!"); + return; + } + // TODO: add a more specific error here for liveness timeout failure to distinguish between other classes of timeouts (i.e + // response timeouts). + client->ShutdownInternal(CHIP_ERROR_TIMEOUT); +} + +CHIP_ERROR ReadClient::ProcessSubscribeResponse(System::PacketBufferHandle && aPayload) +{ + System::PacketBufferTLVReader reader; + reader.Init(std::move(aPayload)); + ReturnLogErrorOnFailure(reader.Next()); + + SubscribeResponse::Parser subscribeResponse; + ReturnLogErrorOnFailure(subscribeResponse.Init(reader)); + +#if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK + ReturnLogErrorOnFailure(subscribeResponse.CheckSchemaValidity()); +#endif + + uint64_t subscriptionId = 0; + ReturnLogErrorOnFailure(subscribeResponse.GetSubscriptionId(&subscriptionId)); + VerifyOrReturnLogError(IsMatchingClient(subscriptionId), CHIP_ERROR_INVALID_ARGUMENT); + ReturnLogErrorOnFailure(subscribeResponse.GetMinIntervalFloorSeconds(&mMinIntervalFloorSeconds)); + ReturnLogErrorOnFailure(subscribeResponse.GetMaxIntervalCeilingSeconds(&mMaxIntervalCeilingSeconds)); + mpDelegate->SubscribeResponseProcessed(this); + + MoveToState(ClientState::SubscriptionActive); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR ReadClient::SendSubscribeRequest(ReadPrepareParams & aReadPrepareParams) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + System::PacketBufferHandle msgBuf; + System::PacketBufferTLVWriter writer; + SubscribeRequest::Builder request; + VerifyOrExit(ClientState::Initialized == mState, err = CHIP_ERROR_INCORRECT_STATE); + VerifyOrExit(mpExchangeCtx == nullptr, err = CHIP_ERROR_INCORRECT_STATE); + VerifyOrExit(mpDelegate != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes); + VerifyOrExit(!msgBuf.IsNull(), err = CHIP_ERROR_NO_MEMORY); + + writer.Init(std::move(msgBuf)); + + err = request.Init(&writer); + SuccessOrExit(err); + + if (aReadPrepareParams.mEventPathParamsListSize != 0 && aReadPrepareParams.mpEventPathParamsList != nullptr) + { + EventPathList::Builder & eventPathListBuilder = request.CreateEventPathListBuilder(); + SuccessOrExit(err = eventPathListBuilder.GetError()); + err = GenerateEventPathList(eventPathListBuilder, aReadPrepareParams.mpEventPathParamsList, + aReadPrepareParams.mEventPathParamsListSize); + SuccessOrExit(err); + + if (aReadPrepareParams.mEventNumber != 0) + { + // EventNumber is optional + request.EventNumber(aReadPrepareParams.mEventNumber); + } + } + + if (aReadPrepareParams.mAttributePathParamsListSize != 0 && aReadPrepareParams.mpAttributePathParamsList != nullptr) + { + AttributePathList::Builder & attributePathListBuilder = request.CreateAttributePathListBuilder(); + SuccessOrExit(err = attributePathListBuilder.GetError()); + err = GenerateAttributePathList(attributePathListBuilder, aReadPrepareParams.mpAttributePathParamsList, + aReadPrepareParams.mAttributePathParamsListSize); + SuccessOrExit(err); + } + + request.MinIntervalSeconds(aReadPrepareParams.mMinIntervalFloorSeconds) + .MaxIntervalSeconds(aReadPrepareParams.mMaxIntervalCeilingSeconds) + .EndOfSubscribeRequest(); + SuccessOrExit(err = request.GetError()); + + err = writer.Finalize(&msgBuf); + SuccessOrExit(err); + + mpExchangeCtx = mpExchangeMgr->NewContext(aReadPrepareParams.mSessionHandle, this); + VerifyOrExit(mpExchangeCtx != nullptr, err = CHIP_ERROR_NO_MEMORY); + mpExchangeCtx->SetResponseTimeout(kImMessageTimeoutMsec); + + err = mpExchangeCtx->SendMessage(Protocols::InteractionModel::MsgType::SubscribeRequest, std::move(msgBuf), + Messaging::SendFlags(Messaging::SendMessageFlags::kExpectResponse)); + SuccessOrExit(err); + MoveToState(ClientState::AwaitingInitialReport); + +exit: + if (err != CHIP_NO_ERROR) + { + AbortExistingExchangeContext(); + } + if (err != CHIP_NO_ERROR) + { + Shutdown(); + } + return err; +} + }; // namespace app }; // namespace chip diff --git a/src/app/ReadClient.h b/src/app/ReadClient.h index f85442befabcd6..67d8c9123a9c20 100644 --- a/src/app/ReadClient.h +++ b/src/app/ReadClient.h @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -52,6 +54,11 @@ namespace app { class ReadClient : public Messaging::ExchangeDelegate { public: + enum class InteractionType : uint8_t + { + Read, + Subscribe, + }; /** * Shut down the Client. This terminates this instance of the object and releases * all held resources. The object must not be used after Shutdown() is called. @@ -74,8 +81,20 @@ class ReadClient : public Messaging::ExchangeDelegate */ CHIP_ERROR SendReadRequest(ReadPrepareParams & aReadPrepareParams); + /** + * Send a subscribe Request. There can be one Subscribe Request outstanding on a given ReadClient. + * If SendSubscribeRequest returns success, no more subscribe Requests can be sent on this ReadClient + * until the corresponding InteractionModelDelegate::ReadDone call happens with guarantee. + * + * @retval #others fail to send subscribe request + * @retval #CHIP_NO_ERROR On success. + */ + CHIP_ERROR SendSubscribeRequest(ReadPrepareParams & aSubscribePrepareParams); + CHIP_ERROR OnUnsolicitedReportData(Messaging::ExchangeContext * apExchangeContext, System::PacketBufferHandle && aPayload); uint64_t GetAppIdentifier() const { return mAppIdentifier; } Messaging::ExchangeContext * GetExchangeContext() const { return mpExchangeCtx; } + bool IsReadType() { return mInteractionType == InteractionType::Read; } + bool IsSubscriptionType() const { return mInteractionType == InteractionType::Subscribe; }; CHIP_ERROR SendStatusReport(CHIP_ERROR aError); private: @@ -84,11 +103,17 @@ class ReadClient : public Messaging::ExchangeDelegate enum class ClientState { - Uninitialized = 0, ///< The client has not been initialized - Initialized, ///< The client has been initialized and is ready for a SendReadRequest - AwaitingInitialReport, ///< The client is waiting for initial report + Uninitialized = 0, ///< The client has not been initialized + Initialized, ///< The client has been initialized and is ready for a SendReadRequest + AwaitingInitialReport, ///< The client is waiting for initial report + AwaitingSubscribeResponse, ///< The client is waiting for subscribe response + SubscriptionActive, ///< The client is maintaining subscription }; + bool IsMatchingClient(uint64_t aSubscriptionId) + { + return aSubscriptionId == mSubscriptionId && mInteractionType == InteractionType::Subscribe; + } /** * Initialize the client object. Within the lifetime * of this instance, this method is invoked once after object @@ -102,7 +127,8 @@ class ReadClient : public Messaging::ExchangeDelegate * @retval #CHIP_NO_ERROR On success. * */ - CHIP_ERROR Init(Messaging::ExchangeManager * apExchangeMgr, InteractionModelDelegate * apDelegate, uint64_t aAppIdentifier); + CHIP_ERROR Init(Messaging::ExchangeManager * apExchangeMgr, InteractionModelDelegate * apDelegate, + InteractionType aInteractionType, uint64_t aAppIdentifier); virtual ~ReadClient() = default; @@ -115,16 +141,21 @@ class ReadClient : public Messaging::ExchangeDelegate * */ bool IsFree() const { return mState == ClientState::Uninitialized; } + bool IsSubscriptionTypeIdle() const { return mState == ClientState::SubscriptionActive; } bool IsAwaitingInitialReport() const { return mState == ClientState::AwaitingInitialReport; } + bool IsAwaitingSubscribeResponse() const { return mState == ClientState::AwaitingSubscribeResponse; } + CHIP_ERROR GenerateEventPathList(EventPathList::Builder & aEventPathListBuilder, EventPathParams * apEventPathParamsList, size_t aEventPathParamsListSize); CHIP_ERROR GenerateAttributePathList(AttributePathList::Builder & aAttributeathListBuilder, AttributePathParams * apAttributePathParamsList, size_t aAttributePathParamsListSize); CHIP_ERROR ProcessAttributeDataList(TLV::TLVReader & aAttributeDataListReader); - void SetExchangeContext(Messaging::ExchangeContext * apExchangeContext) { mpExchangeCtx = apExchangeContext; } void ClearExchangeContext() { mpExchangeCtx = nullptr; } - + static void OnLivenessTimeoutCallback(System::Layer * apSystemLayer, void * apAppState); + CHIP_ERROR ProcessSubscribeResponse(System::PacketBufferHandle && aPayload); + CHIP_ERROR RefreshLivenessCheckTimer(); + void CancelLivenessCheckTimer(); void MoveToState(const ClientState aTargetState); CHIP_ERROR ProcessReportData(System::PacketBufferHandle && aPayload); CHIP_ERROR AbortExistingExchangeContext(); @@ -142,6 +173,10 @@ class ReadClient : public Messaging::ExchangeDelegate ClientState mState = ClientState::Uninitialized; uint64_t mAppIdentifier = 0; bool mInitialReport = true; + uint16_t mMinIntervalFloorSeconds = 0; + uint16_t mMaxIntervalCeilingSeconds = 0; + uint64_t mSubscriptionId = 0; + InteractionType mInteractionType = InteractionType::Read; }; }; // namespace app diff --git a/src/app/ReadHandler.cpp b/src/app/ReadHandler.cpp index f64ba2aedc0d75..4cb1cbcd64f573 100644 --- a/src/app/ReadHandler.cpp +++ b/src/app/ReadHandler.cpp @@ -25,17 +25,21 @@ #include #include #include +#include +#include #include #include +#include #include namespace chip { namespace app { CHIP_ERROR ReadHandler::Init(Messaging::ExchangeManager * apExchangeMgr, InteractionModelDelegate * apDelegate, - Messaging::ExchangeContext * apExchangeContext) + Messaging::ExchangeContext * apExchangeContext, InteractionType aInteractionType) { CHIP_ERROR err = CHIP_NO_ERROR; // Error if already initialized. + VerifyOrReturnError(IsFree(), err = CHIP_ERROR_INCORRECT_STATE); VerifyOrReturnError(mpExchangeCtx == nullptr, err = CHIP_ERROR_INCORRECT_STATE); mpExchangeMgr = apExchangeMgr; mpExchangeCtx = apExchangeContext; @@ -45,7 +49,11 @@ CHIP_ERROR ReadHandler::Init(Messaging::ExchangeManager * apExchangeMgr, Interac mCurrentPriority = PriorityLevel::Invalid; mInitialReport = true; MoveToState(HandlerState::Initialized); - mpDelegate = apDelegate; + mpDelegate = apDelegate; + mSubscriptionId = 0; + mHoldReport = false; + mDirty = false; + mInteractionType = aInteractionType; if (apExchangeContext != nullptr) { apExchangeContext->SetDelegate(this); @@ -56,6 +64,11 @@ CHIP_ERROR ReadHandler::Init(Messaging::ExchangeManager * apExchangeMgr, Interac void ReadHandler::Shutdown(ShutdownOptions aOptions) { + if (IsSubscriptionType()) + { + InteractionModelEngine::GetInstance()->GetExchangeManager()->GetSessionMgr()->SystemLayer()->CancelTimer( + OnRefreshSubscribeTimerSyncCallback, this); + } if (aOptions == ShutdownOptions::AbortCurrentExchange) { if (mpExchangeCtx != nullptr) @@ -65,27 +78,40 @@ void ReadHandler::Shutdown(ShutdownOptions aOptions) } } - if (IsReporting()) + if (IsAwaitingReportResponse()) { InteractionModelEngine::GetInstance()->GetReportingEngine().OnReportConfirm(); } InteractionModelEngine::GetInstance()->ReleaseClusterInfoList(mpAttributeClusterInfoList); InteractionModelEngine::GetInstance()->ReleaseClusterInfoList(mpEventClusterInfoList); - mpExchangeCtx = nullptr; + mSubscriptionId = 0; + mMinIntervalFloorSeconds = 0; + mMaxIntervalCeilingSeconds = 0; + mInteractionType = InteractionType::Read; + mpExchangeCtx = nullptr; MoveToState(HandlerState::Uninitialized); mpAttributeClusterInfoList = nullptr; mpEventClusterInfoList = nullptr; mCurrentPriority = PriorityLevel::Invalid; mInitialReport = false; mpDelegate = nullptr; + mHoldReport = false; + mDirty = false; } CHIP_ERROR ReadHandler::OnReadInitialRequest(System::PacketBufferHandle && aPayload) { CHIP_ERROR err = CHIP_NO_ERROR; System::PacketBufferHandle response; + if (IsSubscriptionType()) + { + err = ProcessSubscribeRequest(std::move(aPayload)); + } + else + { + err = ProcessReadRequest(std::move(aPayload)); + } - err = ProcessReadRequest(std::move(aPayload)); if (err != CHIP_NO_ERROR) { Shutdown(); @@ -107,10 +133,26 @@ CHIP_ERROR ReadHandler::OnStatusReport(Messaging::ExchangeContext * apExchangeCo err = CHIP_ERROR_INVALID_ARGUMENT); switch (mState) { - case HandlerState::Reporting: - Shutdown(); + case HandlerState::AwaitingReportResponse: + if (IsSubscriptionType()) + { + InteractionModelEngine::GetInstance()->GetReportingEngine().OnReportConfirm(); + if (IsInitialReport()) + { + err = SendSubscribeResponse(); + SuccessOrExit(err); + } + else + { + MoveToState(HandlerState::GeneratingReports); + } + } + else + { + Shutdown(); + } break; - case HandlerState::Reportable: + case HandlerState::GeneratingReports: case HandlerState::Initialized: case HandlerState::Uninitialized: default: @@ -128,14 +170,30 @@ CHIP_ERROR ReadHandler::OnStatusReport(Messaging::ExchangeContext * apExchangeCo CHIP_ERROR ReadHandler::SendReportData(System::PacketBufferHandle && aPayload) { VerifyOrReturnLogError(IsReportable(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnLogError(mpExchangeCtx != nullptr, CHIP_ERROR_INCORRECT_STATE); if (IsInitialReport()) { VerifyOrReturnLogError(mpExchangeCtx != nullptr, CHIP_ERROR_INCORRECT_STATE); + mSessionHandle.SetValue(mpExchangeCtx->GetSecureSession()); + } + else + { + mpExchangeCtx = mpExchangeMgr->NewContext(mSessionHandle.Value(), this); + mpExchangeCtx->SetResponseTimeout(kImMessageTimeoutMsec); } VerifyOrReturnLogError(mpExchangeCtx != nullptr, CHIP_ERROR_INCORRECT_STATE); - MoveToState(HandlerState::Reporting); - return mpExchangeCtx->SendMessage(Protocols::InteractionModel::MsgType::ReportData, std::move(aPayload), - Messaging::SendFlags(Messaging::SendMessageFlags::kExpectResponse)); + MoveToState(HandlerState::AwaitingReportResponse); + CHIP_ERROR err = mpExchangeCtx->SendMessage(Protocols::InteractionModel::MsgType::ReportData, std::move(aPayload), + Messaging::SendFlags(Messaging::SendMessageFlags::kExpectResponse)); + if (err == CHIP_NO_ERROR) + { + if (IsSubscriptionType() && !IsInitialReport()) + { + err = RefreshSubscribeSyncTimer(); + } + } + ClearDirty(); + return err; } CHIP_ERROR ReadHandler::OnMessageReceived(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader, @@ -219,7 +277,7 @@ CHIP_ERROR ReadHandler::ProcessReadRequest(System::PacketBufferHandle && aPayloa err = CHIP_NO_ERROR; } - MoveToState(HandlerState::Reportable); + MoveToState(HandlerState::GeneratingReports); err = InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleRun(); SuccessOrExit(err); @@ -280,18 +338,9 @@ CHIP_ERROR ReadHandler::ProcessAttributePathList(AttributePathList::Parser & aAt err = CHIP_NO_ERROR; } SuccessOrExit(err); - - if (MergeOverlappedAttributePath(clusterInfo)) - { - continue; - } - else - { - err = InteractionModelEngine::GetInstance()->PushFront(mpAttributeClusterInfoList, clusterInfo); - SuccessOrExit(err); - mpAttributeClusterInfoList->SetDirty(); - mInitialReport = true; - } + err = InteractionModelEngine::GetInstance()->PushFront(mpAttributeClusterInfoList, clusterInfo); + SuccessOrExit(err); + mInitialReport = true; } // if we have exhausted this container if (CHIP_END_OF_TLV == err) @@ -303,31 +352,6 @@ CHIP_ERROR ReadHandler::ProcessAttributePathList(AttributePathList::Parser & aAt return err; } -bool ReadHandler::MergeOverlappedAttributePath(ClusterInfo & aAttributePath) -{ - ClusterInfo * runner = mpAttributeClusterInfoList; - while (runner != nullptr) - { - // If overlapped, we would skip this target path, - // --If targetPath is part of previous path, return true - // --If previous path is part of target path, update filedid and listindex and mflags with target path, return true - if (runner->IsAttributePathSupersetOf(aAttributePath)) - { - return true; - } - if (aAttributePath.IsAttributePathSupersetOf(*runner)) - { - runner->mListIndex = aAttributePath.mListIndex; - runner->mFieldId = aAttributePath.mFieldId; - runner->mFlags = aAttributePath.mFlags; - runner->SetDirty(); - return true; - } - runner = runner->mpNext; - } - return false; -} - CHIP_ERROR ReadHandler::ProcessEventPathList(EventPathList::Parser & aEventPathListParser) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -383,11 +407,11 @@ const char * ReadHandler::GetStateStr() const case HandlerState::Initialized: return "Initialized"; - case HandlerState::Reportable: - return "Reportable"; + case HandlerState::GeneratingReports: + return "GeneratingReports"; - case HandlerState::Reporting: - return "Reporting"; + case HandlerState::AwaitingReportResponse: + return "AwaitingReportResponse"; } #endif // CHIP_DETAIL_LOGGING return "N/A"; @@ -441,5 +465,108 @@ void ReadHandler::MoveToNextScheduledDirtyPriority() mCurrentPriority = PriorityLevel::Invalid; } + +CHIP_ERROR ReadHandler::SendSubscribeResponse() +{ + System::PacketBufferHandle packet = System::PacketBufferHandle::New(chip::app::kMaxSecureSduLengthBytes); + VerifyOrReturnLogError(!packet.IsNull(), CHIP_ERROR_NO_MEMORY); + + System::PacketBufferTLVWriter writer; + writer.Init(std::move(packet)); + + SubscribeResponse::Builder response; + ReturnLogErrorOnFailure(response.Init(&writer)); + response.SubscriptionId(mSubscriptionId) + .MinIntervalFloorSeconds(mMaxIntervalCeilingSeconds) + .MaxIntervalCeilingSeconds(mMaxIntervalCeilingSeconds) + .EndOfSubscribeResponse(); + ReturnLogErrorOnFailure(response.GetError()); + + ReturnLogErrorOnFailure(writer.Finalize(&packet)); + VerifyOrReturnLogError(mpExchangeCtx != nullptr, CHIP_ERROR_INCORRECT_STATE); + + ReturnLogErrorOnFailure(RefreshSubscribeSyncTimer()); + mInitialReport = false; + MoveToState(HandlerState::GeneratingReports); + if (mpDelegate != nullptr) + { + mpDelegate->SubscriptionEstablished(this); + } + return mpExchangeCtx->SendMessage(Protocols::InteractionModel::MsgType::SubscribeResponse, std::move(packet)); +} + +CHIP_ERROR ReadHandler::ProcessSubscribeRequest(System::PacketBufferHandle && aPayload) +{ + System::PacketBufferTLVReader reader; + reader.Init(std::move(aPayload)); + + ReturnLogErrorOnFailure(reader.Next()); + SubscribeRequest::Parser subscribeRequestParser; + ReturnLogErrorOnFailure(subscribeRequestParser.Init(reader)); +#if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK + ReturnLogErrorOnFailure(subscribeRequestParser.CheckSchemaValidity()); +#endif + + AttributePathList::Parser attributePathListParser; + CHIP_ERROR err = subscribeRequestParser.GetAttributePathList(&attributePathListParser); + if (err == CHIP_END_OF_TLV) + { + err = CHIP_NO_ERROR; + } + else if (err == CHIP_NO_ERROR) + { + ReturnLogErrorOnFailure(ProcessAttributePathList(attributePathListParser)); + } + ReturnLogErrorOnFailure(err); + + EventPathList::Parser eventPathListParser; + err = subscribeRequestParser.GetEventPathList(&eventPathListParser); + if (err == CHIP_END_OF_TLV) + { + err = CHIP_NO_ERROR; + } + else if (err == CHIP_NO_ERROR) + { + ReturnLogErrorOnFailure(ProcessEventPathList(eventPathListParser)); + } + ReturnLogErrorOnFailure(err); + + ReturnLogErrorOnFailure(subscribeRequestParser.GetMinIntervalSeconds(&mMinIntervalFloorSeconds)); + ReturnLogErrorOnFailure(subscribeRequestParser.GetMaxIntervalSeconds(&mMaxIntervalCeilingSeconds)); + + // TODO: Use GetSecureRandomData to generate subscription id + // it needs #include , but somehow CHIPRNG.h is missing + // err = Platform::Security::GetSecureRandomData((uint8_t *) &mSubscriptionId, sizeof(mSubscriptionId)); + // SuccessOrExit(err); + mSubscriptionId = GetRandU64(); + + MoveToState(HandlerState::GeneratingReports); + + InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleRun(); + // mpExchangeCtx can be null here due to + // https://github.com/project-chip/connectedhomeip/issues/8031 + if (mpExchangeCtx) + { + mpExchangeCtx->WillSendMessage(); + } + return CHIP_NO_ERROR; +} + +void ReadHandler::OnRefreshSubscribeTimerSyncCallback(System::Layer * apSystemLayer, void * apAppState) +{ + ReadHandler * aReadHandler = static_cast(apAppState); + aReadHandler->mHoldReport = false; + InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleRun(); +} + +CHIP_ERROR ReadHandler::RefreshSubscribeSyncTimer() +{ + ChipLogProgress(DataManagement, "ReadHandler::Refresh Subscribe Sync Timer with %d seconds", mMinIntervalFloorSeconds); + InteractionModelEngine::GetInstance()->GetExchangeManager()->GetSessionMgr()->SystemLayer()->CancelTimer( + OnRefreshSubscribeTimerSyncCallback, this); + mHoldReport = true; + return InteractionModelEngine::GetInstance()->GetExchangeManager()->GetSessionMgr()->SystemLayer()->StartTimer( + mMinIntervalFloorSeconds * kMillisecondsPerSecond, OnRefreshSubscribeTimerSyncCallback, this); +} } // namespace app } // namespace chip diff --git a/src/app/ReadHandler.h b/src/app/ReadHandler.h index 5e91e2be8e4941..0bd8b23377493c 100644 --- a/src/app/ReadHandler.h +++ b/src/app/ReadHandler.h @@ -56,6 +56,12 @@ class ReadHandler : public Messaging::ExchangeDelegate AbortCurrentExchange, }; + enum class InteractionType : uint8_t + { + Read, + Subscribe, + }; + /** * Initialize the ReadHandler. Within the lifetime * of this instance, this method is invoked once after object @@ -68,7 +74,7 @@ class ReadHandler : public Messaging::ExchangeDelegate * */ CHIP_ERROR Init(Messaging::ExchangeManager * apExchangeMgr, InteractionModelDelegate * apDelegate, - Messaging::ExchangeContext * apExchangeContext); + Messaging::ExchangeContext * apExchangeContext, InteractionType aInteractionType); /** * Shut down the ReadHandler. This terminates this instance @@ -77,7 +83,7 @@ class ReadHandler : public Messaging::ExchangeDelegate */ void Shutdown(ShutdownOptions aOptions = ShutdownOptions::KeepCurrentExchange); /** - * Process a read request. Parts of the processing may end up being asynchronous, but the ReadHandler + * Process a read/subscribe request. Parts of the processing may end up being asynchronous, but the ReadHandler * guarantees that it will call Shutdown on itself when processing is done (including if OnReadInitialRequest * returns an error). * @@ -99,8 +105,9 @@ class ReadHandler : public Messaging::ExchangeDelegate CHIP_ERROR SendReportData(System::PacketBufferHandle && aPayload); bool IsFree() const { return mState == HandlerState::Uninitialized; } - bool IsReportable() const { return mState == HandlerState::Reportable; } - bool IsReporting() const { return mState == HandlerState::Reporting; } + bool IsReportable() const { return mState == HandlerState::GeneratingReports && !mHoldReport; } + bool IsGeneratingReports() const { return mState == HandlerState::GeneratingReports; } + bool IsAwaitingReportResponse() const { return mState == HandlerState::AwaitingReportResponse; } virtual ~ReadHandler() = default; ClusterInfo * GetAttributeClusterInfolist() { return mpAttributeClusterInfoList; } @@ -117,17 +124,30 @@ class ReadHandler : public Messaging::ExchangeDelegate // is larger than current self vended event number void MoveToNextScheduledDirtyPriority(); + bool IsReadType() { return mInteractionType == InteractionType::Read; } + bool IsSubscriptionType() { return mInteractionType == InteractionType::Subscribe; } bool IsInitialReport() { return mInitialReport; } + CHIP_ERROR OnSubscribeRequest(Messaging::ExchangeContext * apExchangeContext, System::PacketBufferHandle && aPayload); + void GetSubscriptionId(uint64_t & aSubscriptionId) { aSubscriptionId = mSubscriptionId; } + void SetDirty() { mDirty = true; } + void ClearDirty() { mDirty = false; } + bool IsDirty() { return mDirty; } private: + friend class TestReadInteraction; enum class HandlerState { - Uninitialized = 0, ///< The handler has not been initialized - Initialized, ///< The handler has been initialized and is ready - Reportable, ///< The handler has received read request and is waiting for the data to send to be available - Reporting, ///< The handler is reporting + Uninitialized = 0, ///< The handler has not been initialized + Initialized, ///< The handler has been initialized and is ready + GeneratingReports, ///< The handler has received either a Read or Subscribe request and is the process of generating a + ///< report. + AwaitingReportResponse, ///< The handler has sent the report to the client and is awaiting a status response. }; + static void OnRefreshSubscribeTimerSyncCallback(System::Layer * apSystemLayer, void * apAppState); + CHIP_ERROR RefreshSubscribeSyncTimer(); + CHIP_ERROR SendSubscribeResponse(); + CHIP_ERROR ProcessSubscribeRequest(System::PacketBufferHandle && aPayload); CHIP_ERROR ProcessReadRequest(System::PacketBufferHandle && aPayload); CHIP_ERROR ProcessAttributePathList(AttributePathList::Parser & aAttributePathListParser); CHIP_ERROR ProcessEventPathList(EventPathList::Parser & aEventPathListParser); @@ -141,9 +161,6 @@ class ReadHandler : public Messaging::ExchangeDelegate const char * GetStateStr() const; - // Merges aAttributePath inside the existing internal mpAttributeClusterInfoList - bool MergeOverlappedAttributePath(ClusterInfo & aAttributePath); - Messaging::ExchangeContext * mpExchangeCtx = nullptr; // Don't need the response for report data if true @@ -164,6 +181,13 @@ class ReadHandler : public Messaging::ExchangeDelegate Messaging::ExchangeManager * mpExchangeMgr = nullptr; InteractionModelDelegate * mpDelegate = nullptr; bool mInitialReport = false; + InteractionType mInteractionType = InteractionType::Read; + uint64_t mSubscriptionId = 0; + uint16_t mMinIntervalFloorSeconds = 0; + uint16_t mMaxIntervalCeilingSeconds = 0; + Optional mSessionHandle; + bool mHoldReport = false; + bool mDirty = false; }; } // namespace app } // namespace chip diff --git a/src/app/ReadPrepareParams.h b/src/app/ReadPrepareParams.h index 9740ac29d38ab5..e41c3b7d51a133 100644 --- a/src/app/ReadPrepareParams.h +++ b/src/app/ReadPrepareParams.h @@ -36,8 +36,8 @@ struct ReadPrepareParams size_t mAttributePathParamsListSize = 0; EventNumber mEventNumber = 0; uint32_t mTimeout = kImMessageTimeoutMsec; - uint16_t mMinIntervalSeconds = 0; - uint16_t mMaxIntervalSeconds = 0; + uint16_t mMinIntervalFloorSeconds = 0; + uint16_t mMaxIntervalCeilingSeconds = 0; ReadPrepareParams(SessionHandle sessionHandle) : mSessionHandle(sessionHandle) {} ReadPrepareParams(ReadPrepareParams && other) : mSessionHandle(other.mSessionHandle) @@ -47,8 +47,8 @@ struct ReadPrepareParams mpAttributePathParamsList = other.mpAttributePathParamsList; mAttributePathParamsListSize = other.mAttributePathParamsListSize; mEventNumber = other.mEventNumber; - mMinIntervalSeconds = other.mMinIntervalSeconds; - mMaxIntervalSeconds = other.mMaxIntervalSeconds; + mMinIntervalFloorSeconds = other.mMinIntervalFloorSeconds; + mMaxIntervalCeilingSeconds = other.mMaxIntervalCeilingSeconds; mTimeout = other.mTimeout; other.mpEventPathParamsList = nullptr; other.mEventPathParamsListSize = 0; @@ -67,8 +67,8 @@ struct ReadPrepareParams mpAttributePathParamsList = other.mpAttributePathParamsList; mAttributePathParamsListSize = other.mAttributePathParamsListSize; mEventNumber = other.mEventNumber; - mMinIntervalSeconds = other.mMinIntervalSeconds; - mMaxIntervalSeconds = other.mMaxIntervalSeconds; + mMinIntervalFloorSeconds = other.mMinIntervalFloorSeconds; + mMaxIntervalCeilingSeconds = other.mMaxIntervalCeilingSeconds; mTimeout = other.mTimeout; other.mpEventPathParamsList = nullptr; other.mEventPathParamsListSize = 0; diff --git a/src/app/reporting/Engine.cpp b/src/app/reporting/Engine.cpp index 804171b4f56708..02788e8928c3fd 100644 --- a/src/app/reporting/Engine.cpp +++ b/src/app/reporting/Engine.cpp @@ -38,6 +38,15 @@ CHIP_ERROR Engine::Init() return CHIP_NO_ERROR; } +void Engine::Shutdown() +{ + mMoreChunkedMessages = false; + mNumReportsInFlight = 0; + mCurReadHandlerIdx = 0; + InteractionModelEngine::GetInstance()->ReleaseClusterInfoList(mpGlobalDirtySet); + mpGlobalDirtySet = nullptr; +} + EventNumber Engine::CountEvents(ReadHandler * apReadHandler, EventNumber * apInitialEvents) { EventNumber event_count = 0; @@ -76,8 +85,6 @@ Engine::RetrieveClusterData(AttributeDataList::Builder & aAttributeDataList, Clu err = attributeDataElementBuilder.GetError(); exit: - aClusterInfo.ClearDirty(); - if (err != CHIP_NO_ERROR) { ChipLogError(DataManagement, "Error retrieving data from clusterId: " ChipLogFormatMEI ", err = %" CHIP_ERROR_FORMAT, @@ -89,29 +96,46 @@ Engine::RetrieveClusterData(AttributeDataList::Builder & aAttributeDataList, Clu CHIP_ERROR Engine::BuildSingleReportDataAttributeDataList(ReportData::Builder & aReportDataBuilder, ReadHandler * apReadHandler) { - CHIP_ERROR err = CHIP_NO_ERROR; - ClusterInfo * clusterInfo = apReadHandler->GetAttributeClusterInfolist(); - bool attributeClean = true; + CHIP_ERROR err = CHIP_NO_ERROR; + bool attributeClean = true; TLV::TLVWriter backup; aReportDataBuilder.Checkpoint(backup); AttributeDataList::Builder attributeDataList = aReportDataBuilder.CreateAttributeDataListBuilder(); SuccessOrExit(err = aReportDataBuilder.GetError()); // TODO: Need to handle multiple chunk of message - while (clusterInfo != nullptr) + for (auto clusterInfo = apReadHandler->GetAttributeClusterInfolist(); clusterInfo != nullptr; clusterInfo = clusterInfo->mpNext) { - if (clusterInfo->IsDirty()) + if (apReadHandler->IsInitialReport()) + { + // Retrieve data for this cluster instance and clear its dirty flag. + err = RetrieveClusterData(attributeDataList, *clusterInfo); + VerifyOrExit(err == CHIP_NO_ERROR, + ChipLogError(DataManagement, " Error retrieving data from cluster, aborting")); + attributeClean = false; + } + else { - if (apReadHandler->IsInitialReport()) + for (auto path = mpGlobalDirtySet; path != nullptr; path = path->mpNext) { - // Retrieve data for this cluster instance and clear its dirty flag. - err = RetrieveClusterData(attributeDataList, *clusterInfo); + if (clusterInfo->IsAttributePathSupersetOf(*path)) + { + err = RetrieveClusterData(attributeDataList, *path); + } + else if (path->IsAttributePathSupersetOf(*clusterInfo)) + { + err = RetrieveClusterData(attributeDataList, *clusterInfo); + } + else + { + // partial overlap is not possible, hence the 'continue' here: clusterInfo and path have nothing in + // common. + continue; + } VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(DataManagement, " Error retrieving data from cluster, aborting")); attributeClean = false; } - clusterInfo->ClearDirty(); } - clusterInfo = clusterInfo->mpNext; } attributeDataList.EndOfAttributeDataList(); err = attributeDataList.GetError(); @@ -242,6 +266,13 @@ CHIP_ERROR Engine::BuildAndSendSingleReportData(ReadHandler * apReadHandler) err = reportDataBuilder.Init(&reportDataWriter); SuccessOrExit(err); + if (apReadHandler->IsSubscriptionType()) + { + uint64_t subscriptionId = 0; + apReadHandler->GetSubscriptionId(subscriptionId); + reportDataBuilder.SubscriptionId(subscriptionId); + } + err = BuildSingleReportDataAttributeDataList(reportDataBuilder, apReadHandler); SuccessOrExit(err); @@ -333,6 +364,66 @@ void Engine::Run() mCurReadHandlerIdx = (mCurReadHandlerIdx + 1) % CHIP_IM_MAX_NUM_READ_HANDLER; readHandler = imEngine->mReadHandlers + mCurReadHandlerIdx; } + + bool allReadClean = true; + for (auto & handler : InteractionModelEngine::GetInstance()->mReadHandlers) + { + UpdateReadHandlerDirty(handler); + if (handler.IsDirty()) + { + allReadClean = false; + break; + } + } + + if (allReadClean) + { + InteractionModelEngine::GetInstance()->ReleaseClusterInfoList(mpGlobalDirtySet); + } +} + +CHIP_ERROR Engine::SetDirty(ClusterInfo & aClusterInfo) +{ + for (auto & handler : InteractionModelEngine::GetInstance()->mReadHandlers) + { + if (handler.IsSubscriptionType() && (handler.IsGeneratingReports() || handler.IsAwaitingReportResponse())) + { + handler.SetDirty(); + } + } + if (!InteractionModelEngine::GetInstance()->MergeOverlappedAttributePath(mpGlobalDirtySet, aClusterInfo) && + InteractionModelEngine::GetInstance()->IsOverlappedAttributePath(aClusterInfo)) + { + ReturnLogErrorOnFailure(InteractionModelEngine::GetInstance()->PushFront(mpGlobalDirtySet, aClusterInfo)); + } + return CHIP_NO_ERROR; +} + +void Engine::UpdateReadHandlerDirty(ReadHandler & aReadHandler) +{ + if (!aReadHandler.IsDirty()) + { + return; + } + if (!aReadHandler.IsSubscriptionType()) + { + return; + } + for (auto clusterInfo = aReadHandler.GetAttributeClusterInfolist(); clusterInfo != nullptr; clusterInfo = clusterInfo->mpNext) + { + bool intersected = false; + for (auto path = mpGlobalDirtySet; path != nullptr; path = path->mpNext) + { + if (path->IsAttributePathSupersetOf(*clusterInfo) || clusterInfo->IsAttributePathSupersetOf(*path)) + { + intersected = true; + } + } + if (!intersected) + { + aReadHandler.ClearDirty(); + } + } } CHIP_ERROR Engine::SendReport(ReadHandler * apReadHandler, System::PacketBufferHandle && aPayload) @@ -341,7 +432,6 @@ CHIP_ERROR Engine::SendReport(ReadHandler * apReadHandler, System::PacketBufferH // We can only have 1 report in flight for any given read - increment and break out. mNumReportsInFlight++; - err = apReadHandler->SendReportData(std::move(aPayload)); return err; } diff --git a/src/app/reporting/Engine.h b/src/app/reporting/Engine.h index 4fcda1f2f98f60..bcd6547c81a330 100644 --- a/src/app/reporting/Engine.h +++ b/src/app/reporting/Engine.h @@ -60,6 +60,8 @@ class Engine */ CHIP_ERROR Init(); + void Shutdown(); + /** * Main work-horse function that executes the run-loop. */ @@ -77,6 +79,11 @@ class Engine */ CHIP_ERROR ScheduleRun(); + /** + * Application marks mutated change path and would be sent out in later report. + */ + CHIP_ERROR SetDirty(ClusterInfo & aClusterInfo); + private: friend class TestReportingEngine; /** @@ -90,6 +97,12 @@ class Engine CHIP_ERROR RetrieveClusterData(AttributeDataList::Builder & aAttributeDataList, ClusterInfo & aClusterInfo); EventNumber CountEvents(ReadHandler * apReadHandler, EventNumber * apInitialEvents); + /** + * Check all active subscription, if the subscription has no paths that intersect with global dirty set, + * it would clear dirty flag for that subscription + * + */ + void UpdateReadHandlerDirty(ReadHandler & aReadHandler); /** * Send Report via ReadHandler * @@ -119,6 +132,15 @@ class Engine * */ uint32_t mCurReadHandlerIdx = 0; + + /** + * mpGlobalDirtySet is used to track the dirty cluster info application modified for attributes during + * post-subscription via SetDirty API, and further form the report. This reporting engine acquires this global dirty + * set from mClusterInfoPool managed by InteractionModelEngine, where all active read handlers also acquire the interested + * cluster Info list from mClusterInfoPool. + * + */ + ClusterInfo * mpGlobalDirtySet = nullptr; }; }; // namespace reporting diff --git a/src/app/reporting/reporting.cpp b/src/app/reporting/reporting.cpp index 78807d0e1ea348..9c9873d78b2f10 100644 --- a/src/app/reporting/reporting.cpp +++ b/src/app/reporting/reporting.cpp @@ -694,53 +694,6 @@ EmberStatus emAfPluginReportingRemoveEntry(uint8_t index) return status; } -void emberAfReportingAttributeChangeCallback(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId, uint8_t mask, - uint16_t manufacturerCode, EmberAfAttributeType type, uint8_t * data) -{ - uint8_t i; - for (i = 0; i < REPORT_TABLE_SIZE; i++) - { - EmberAfPluginReportingEntry entry; - emAfPluginReportingGetEntry(i, &entry); - if (entry.endpoint == EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID) - { - continue; - } - if (entry.direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED && entry.endpoint == endpoint && - entry.clusterId == clusterId && entry.attributeId == attributeId && entry.mask == mask && - entry.manufacturerCode == manufacturerCode) - { - // For CHAR and OCTET strings, the string value may be too long to fit into the - // lastReportValue field (EmberAfDifferenceType), so instead we save the string's - // hash, and detect changes in string value based on unequal hash. - uint32_t stringHash = 0; - uint8_t dataSize = emberAfGetDataSize(type); - uint8_t * dataRef = data; - if (type == ZCL_OCTET_STRING_ATTRIBUTE_TYPE || type == ZCL_CHAR_STRING_ATTRIBUTE_TYPE) - { - stringHash = computeStringHash(data + 1, emberAfStringLength(data)); - dataRef = (uint8_t *) &stringHash; - dataSize = sizeof(stringHash); - } - // If we are reporting this particular attribute, we only care whether - // the new value meets the reportable change criteria. If it does, we - // mark the entry as ready to report and reschedule the tick. Whether - // the tick will be scheduled for immediate or delayed execution depends - // on the minimum reporting interval. This is handled in the scheduler. - EmberAfDifferenceType difference = - emberAfGetDifference(dataRef, emAfPluginReportVolatileData[i].lastReportValue, dataSize); - uint8_t analogOrDiscrete = emberAfGetAttributeAnalogOrDiscreteType(type); - if ((analogOrDiscrete == EMBER_AF_DATA_TYPE_DISCRETE && difference != 0) || - (analogOrDiscrete == EMBER_AF_DATA_TYPE_ANALOG && entry.data.reported.reportableChange <= difference)) - { - emAfPluginReportVolatileData[i].reportableChange = true; - scheduleTick(); - } - break; - } - } -} - bool emAfPluginReportingDoEntriesMatch(const EmberAfPluginReportingEntry * const entry1, const EmberAfPluginReportingEntry * const entry2) { diff --git a/src/app/reporting/reporting.h b/src/app/reporting/reporting.h index 2ab9de71710283..27cbac7daac870 100644 --- a/src/app/reporting/reporting.h +++ b/src/app/reporting/reporting.h @@ -129,3 +129,6 @@ EmberStatus emberAfClearReportTableCallback(void); */ void emberAfReportingAttributeChangeCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, chip::AttributeId attributeId, uint8_t mask, uint16_t manufacturerCode, EmberAfAttributeType type, uint8_t * data); +void InteractionModelReportingAttributeChangeCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, + chip::AttributeId attributeId, uint8_t mask, uint16_t manufacturerCode, + EmberAfAttributeType type, uint8_t * data); diff --git a/src/app/tests/TestCHIPDeviceCallbacksMgr.cpp b/src/app/tests/TestCHIPDeviceCallbacksMgr.cpp index 836d0de5e49620..52b43c1cb19203 100644 --- a/src/app/tests/TestCHIPDeviceCallbacksMgr.cpp +++ b/src/app/tests/TestCHIPDeviceCallbacksMgr.cpp @@ -313,42 +313,54 @@ void ShouldGetSingleReportCallback(nlTestSuite * testSuite, void * apContext) NL_TEST_ASSERT(context.testSuite, false); }; + const auto reportFilter = [](TLV::TLVReader * reader, Callback::Cancelable * callback, Callback::Cancelable * failureCallback) { + IgnoreUnusedVariable(reader); + IgnoreUnusedVariable(callback); + IgnoreUnusedVariable(failureCallback); + }; + Callback::Callback reportCallback{ onReport, &callbackContext }; { Callback::Cancelable * reportCancelable = nullptr; + TLVDataFilter filter = nullptr; CHIP_ERROR error = - callbacks.GetReportCallback(kTestNodeId, kTestEndpointId, kTestClusterId, kTestAttributeId, &reportCancelable); + callbacks.GetReportCallback(kTestNodeId, kTestEndpointId, kTestClusterId, kTestAttributeId, &reportCancelable, &filter); NL_TEST_ASSERT(testSuite, error == CHIP_ERROR_KEY_NOT_FOUND); NL_TEST_ASSERT(testSuite, reportCancelable == nullptr); + NL_TEST_ASSERT(testSuite, filter == nullptr); } { - CHIP_ERROR error = - callbacks.AddReportCallback(kTestNodeId, kTestEndpointId, kTestClusterId, kTestAttributeId, reportCallback.Cancel()); + CHIP_ERROR error = callbacks.AddReportCallback(kTestNodeId, kTestEndpointId, kTestClusterId, kTestAttributeId, + reportCallback.Cancel(), reportFilter); NL_TEST_ASSERT(testSuite, error == CHIP_NO_ERROR); } { Callback::Cancelable * reportCancelable = nullptr; + TLVDataFilter filter = nullptr; CHIP_ERROR error = - callbacks.GetReportCallback(kTestNodeId, kTestEndpointId, kTestClusterId, kTestAttributeId, &reportCancelable); + callbacks.GetReportCallback(kTestNodeId, kTestEndpointId, kTestClusterId, kTestAttributeId, &reportCancelable, &filter); NL_TEST_ASSERT(testSuite, error == CHIP_NO_ERROR); auto outReportCallback = decltype(reportCallback)::FromCancelable(reportCancelable); NL_TEST_ASSERT(testSuite, outReportCallback == &reportCallback); + NL_TEST_ASSERT(testSuite, filter == reportFilter); } { Callback::Cancelable * reportCancelable = nullptr; + TLVDataFilter filter = nullptr; CHIP_ERROR error = - callbacks.GetReportCallback(kTestNodeId, kTestEndpointId, kTestClusterId, kTestAttributeId, &reportCancelable); + callbacks.GetReportCallback(kTestNodeId, kTestEndpointId, kTestClusterId, kTestAttributeId, &reportCancelable, &filter); NL_TEST_ASSERT(testSuite, error == CHIP_NO_ERROR); auto outReportCallback = decltype(reportCallback)::FromCancelable(reportCancelable); NL_TEST_ASSERT(testSuite, outReportCallback == &reportCallback); + NL_TEST_ASSERT(testSuite, filter == reportFilter); } } @@ -373,41 +385,53 @@ void ShouldFailGetCanceledReportCallback(nlTestSuite * testSuite, void * apConte NL_TEST_ASSERT(context.testSuite, false); }; + const auto reportFilter = [](TLV::TLVReader * reader, Callback::Cancelable * callback, Callback::Cancelable * failureCallback) { + IgnoreUnusedVariable(reader); + IgnoreUnusedVariable(callback); + IgnoreUnusedVariable(failureCallback); + }; + Callback::Callback reportCallback{ onReport, &callbackContext }; { Callback::Cancelable * reportCancelable = nullptr; + TLVDataFilter filter = nullptr; CHIP_ERROR error = - callbacks.GetReportCallback(kTestNodeId, kTestEndpointId, kTestClusterId, kTestAttributeId, &reportCancelable); + callbacks.GetReportCallback(kTestNodeId, kTestEndpointId, kTestClusterId, kTestAttributeId, &reportCancelable, &filter); NL_TEST_ASSERT(testSuite, error == CHIP_ERROR_KEY_NOT_FOUND); NL_TEST_ASSERT(testSuite, reportCancelable == nullptr); + NL_TEST_ASSERT(testSuite, filter == nullptr); } { - CHIP_ERROR error = - callbacks.AddReportCallback(kTestNodeId, kTestEndpointId, kTestClusterId, kTestAttributeId, reportCallback.Cancel()); + CHIP_ERROR error = callbacks.AddReportCallback(kTestNodeId, kTestEndpointId, kTestClusterId, kTestAttributeId, + reportCallback.Cancel(), reportFilter); NL_TEST_ASSERT(testSuite, error == CHIP_NO_ERROR); } { Callback::Cancelable * reportCancelable = nullptr; + TLVDataFilter filter = nullptr; CHIP_ERROR error = - callbacks.GetReportCallback(kTestNodeId, kTestEndpointId, kTestClusterId, kTestAttributeId, &reportCancelable); + callbacks.GetReportCallback(kTestNodeId, kTestEndpointId, kTestClusterId, kTestAttributeId, &reportCancelable, &filter); NL_TEST_ASSERT(testSuite, error == CHIP_NO_ERROR); auto outReportCallback = decltype(reportCallback)::FromCancelable(reportCancelable); NL_TEST_ASSERT(testSuite, outReportCallback == &reportCallback); + NL_TEST_ASSERT(testSuite, filter == reportFilter); } reportCallback.Cancel(); { Callback::Cancelable * reportCancelable = nullptr; + TLVDataFilter filter = nullptr; CHIP_ERROR error = - callbacks.GetReportCallback(kTestNodeId, kTestEndpointId, kTestClusterId, kTestAttributeId, &reportCancelable); + callbacks.GetReportCallback(kTestNodeId, kTestEndpointId, kTestClusterId, kTestAttributeId, &reportCancelable, &filter); NL_TEST_ASSERT(testSuite, error == CHIP_ERROR_KEY_NOT_FOUND); NL_TEST_ASSERT(testSuite, reportCancelable == nullptr); + NL_TEST_ASSERT(testSuite, filter == nullptr); } } diff --git a/src/app/tests/TestClusterInfo.cpp b/src/app/tests/TestClusterInfo.cpp index 22a1c94bcac64f..932fe062104e72 100644 --- a/src/app/tests/TestClusterInfo.cpp +++ b/src/app/tests/TestClusterInfo.cpp @@ -29,15 +29,6 @@ namespace chip { namespace app { namespace TestClusterInfo { -void TestDirty(nlTestSuite * apSuite, void * apContext) -{ - ClusterInfo clusterInfo1; - clusterInfo1.SetDirty(); - NL_TEST_ASSERT(apSuite, clusterInfo1.IsDirty()); - clusterInfo1.ClearDirty(); - NL_TEST_ASSERT(apSuite, !clusterInfo1.IsDirty()); -} - void TestAttributePathIncludedSameFieldId(nlTestSuite * apSuite, void * apContext) { ClusterInfo clusterInfo1; @@ -104,7 +95,6 @@ void TestAttributePathIncludedDifferentClusterId(nlTestSuite * apSuite, void * a namespace { const nlTest sTests[] = { - NL_TEST_DEF("TestDirty", chip::app::TestClusterInfo::TestDirty), NL_TEST_DEF("TestAttributePathIncludedSameFieldId", chip::app::TestClusterInfo::TestAttributePathIncludedSameFieldId), NL_TEST_DEF("TestAttributePathIncludedDifferentFieldId", chip::app::TestClusterInfo::TestAttributePathIncludedDifferentFieldId), NL_TEST_DEF("TestAttributePathIncludedDifferentEndpointId", diff --git a/src/app/tests/TestInteractionModelEngine.cpp b/src/app/tests/TestInteractionModelEngine.cpp index 321fedf918d240..4c4d7507cfd90e 100644 --- a/src/app/tests/TestInteractionModelEngine.cpp +++ b/src/app/tests/TestInteractionModelEngine.cpp @@ -57,6 +57,7 @@ class TestInteractionModelEngine { public: static void TestClusterInfoPushRelease(nlTestSuite * apSuite, void * apContext); + static void TestMergeOverlappedAttributePath(nlTestSuite * apSuite, void * apContext); static int GetClusterInfoListLength(ClusterInfo * apClusterInfoList); }; @@ -101,6 +102,31 @@ void TestInteractionModelEngine::TestClusterInfoPushRelease(nlTestSuite * apSuit InteractionModelEngine::GetInstance()->ReleaseClusterInfoList(clusterInfoList); NL_TEST_ASSERT(apSuite, GetClusterInfoListLength(clusterInfoList) == 0); } + +void TestInteractionModelEngine::TestMergeOverlappedAttributePath(nlTestSuite * apSuite, void * apContext) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + err = InteractionModelEngine::GetInstance()->Init(&gExchangeManager, nullptr); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + ClusterInfo clusterInfoList[2]; + + clusterInfoList[0].mFlags.Set(chip::app::ClusterInfo::Flags::kFieldIdValid); + clusterInfoList[0].mFieldId = 1; + clusterInfoList[1].mFlags.Set(chip::app::ClusterInfo::Flags::kFieldIdValid); + clusterInfoList[1].mFieldId = 2; + + chip::app::ClusterInfo testClusterInfo; + testClusterInfo.mFlags.Set(chip::app::ClusterInfo::Flags::kFieldIdValid); + testClusterInfo.mFieldId = 3; + + NL_TEST_ASSERT(apSuite, !InteractionModelEngine::GetInstance()->MergeOverlappedAttributePath(clusterInfoList, testClusterInfo)); + testClusterInfo.mFieldId = 0xFFFFFFFF; + NL_TEST_ASSERT(apSuite, InteractionModelEngine::GetInstance()->MergeOverlappedAttributePath(clusterInfoList, testClusterInfo)); + testClusterInfo.mFlags.Set(chip::app::ClusterInfo::Flags::kListIndexValid); + testClusterInfo.mFieldId = 1; + testClusterInfo.mListIndex = 2; + NL_TEST_ASSERT(apSuite, InteractionModelEngine::GetInstance()->MergeOverlappedAttributePath(clusterInfoList, testClusterInfo)); +} } // namespace app } // namespace chip @@ -130,6 +156,7 @@ void InitializeChip(nlTestSuite * apSuite) const nlTest sTests[] = { NL_TEST_DEF("TestClusterInfoPushRelease", chip::app::TestInteractionModelEngine::TestClusterInfoPushRelease), + NL_TEST_DEF("TestMergeOverlappedAttributePath", chip::app::TestInteractionModelEngine::TestMergeOverlappedAttributePath), NL_TEST_SENTINEL() }; // clang-format on diff --git a/src/app/tests/TestMessageDef.cpp b/src/app/tests/TestMessageDef.cpp index e4d9d75254a2df..178f8137d25f47 100644 --- a/src/app/tests/TestMessageDef.cpp +++ b/src/app/tests/TestMessageDef.cpp @@ -981,7 +981,10 @@ void BuildSubscribeResponse(nlTestSuite * apSuite, chip::TLV::TLVWriter & aWrite subscribeResponseBuilder.SubscriptionId(1); NL_TEST_ASSERT(apSuite, subscribeResponseBuilder.GetError() == CHIP_NO_ERROR); - subscribeResponseBuilder.FinalSyncIntervalSeconds(1); + subscribeResponseBuilder.MinIntervalFloorSeconds(1); + NL_TEST_ASSERT(apSuite, subscribeResponseBuilder.GetError() == CHIP_NO_ERROR); + + subscribeResponseBuilder.MaxIntervalCeilingSeconds(2); NL_TEST_ASSERT(apSuite, subscribeResponseBuilder.GetError() == CHIP_NO_ERROR); subscribeResponseBuilder.EndOfSubscribeResponse(); @@ -993,10 +996,10 @@ void ParseSubscribeResponse(nlTestSuite * apSuite, chip::TLV::TLVReader & aReade CHIP_ERROR err = CHIP_NO_ERROR; SubscribeResponse::Parser subscribeResponseParser; - uint64_t subscriptionId = 0; - uint16_t finalSyncIntervalSeconds = 0; - - err = subscribeResponseParser.Init(aReader); + uint64_t subscriptionId = 0; + uint16_t minIntervalFloorSeconds = 0; + uint16_t maxIntervalCeilingSeconds = 0; + err = subscribeResponseParser.Init(aReader); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); #if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK err = subscribeResponseParser.CheckSchemaValidity(); @@ -1005,8 +1008,11 @@ void ParseSubscribeResponse(nlTestSuite * apSuite, chip::TLV::TLVReader & aReade err = subscribeResponseParser.GetSubscriptionId(&subscriptionId); NL_TEST_ASSERT(apSuite, subscriptionId == 1 && err == CHIP_NO_ERROR); - err = subscribeResponseParser.GetFinalSyncIntervalSeconds(&finalSyncIntervalSeconds); - NL_TEST_ASSERT(apSuite, finalSyncIntervalSeconds == 1 && err == CHIP_NO_ERROR); + err = subscribeResponseParser.GetMinIntervalFloorSeconds(&minIntervalFloorSeconds); + NL_TEST_ASSERT(apSuite, minIntervalFloorSeconds == 1 && err == CHIP_NO_ERROR); + + err = subscribeResponseParser.GetMaxIntervalCeilingSeconds(&maxIntervalCeilingSeconds); + NL_TEST_ASSERT(apSuite, maxIntervalCeilingSeconds == 2 && err == CHIP_NO_ERROR); } void BuildTimedRequest(nlTestSuite * apSuite, chip::TLV::TLVWriter & aWriter) diff --git a/src/app/tests/TestReadInteraction.cpp b/src/app/tests/TestReadInteraction.cpp index be52e93a774dcf..88873b23aae49d 100644 --- a/src/app/tests/TestReadInteraction.cpp +++ b/src/app/tests/TestReadInteraction.cpp @@ -117,6 +117,33 @@ void GenerateEvents(nlTestSuite * apSuite, void * apContext) NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); } +void GenerateSubscribeResponse(nlTestSuite * apSuite, void * apContext, chip::System::PacketBufferHandle && aPayload) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + chip::System::PacketBufferTLVWriter writer; + writer.Init(std::move(aPayload)); + + chip::app::SubscribeResponse::Builder subscribeResponseBuilder; + + err = subscribeResponseBuilder.Init(&writer); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + subscribeResponseBuilder.SubscriptionId(0); + NL_TEST_ASSERT(apSuite, subscribeResponseBuilder.GetError() == CHIP_NO_ERROR); + + subscribeResponseBuilder.MinIntervalFloorSeconds(1); + NL_TEST_ASSERT(apSuite, subscribeResponseBuilder.GetError() == CHIP_NO_ERROR); + + subscribeResponseBuilder.MaxIntervalCeilingSeconds(2); + NL_TEST_ASSERT(apSuite, subscribeResponseBuilder.GetError() == CHIP_NO_ERROR); + + subscribeResponseBuilder.EndOfSubscribeResponse(); + NL_TEST_ASSERT(apSuite, subscribeResponseBuilder.GetError() == CHIP_NO_ERROR); + + err = writer.Finalize(&aPayload); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); +} + class MockInteractionModelApp : public chip::app::InteractionModelDelegate { public: @@ -176,10 +203,17 @@ class MockInteractionModelApp : public chip::app::InteractionModelDelegate CHIP_ERROR ReadDone(const chip::app::ReadClient * apReadClient) override { return CHIP_NO_ERROR; } - bool mGotEventResponse = false; - int mNumAttributeResponse = 0; - bool mGotReport = false; - bool mReadError = false; + CHIP_ERROR SubscriptionEstablished(const chip::app::ReadHandler * apReadHandler) override + { + mpReadHandler = const_cast(apReadHandler); + return CHIP_ERROR_NOT_IMPLEMENTED; + } + + bool mGotEventResponse = false; + int mNumAttributeResponse = 0; + bool mGotReport = false; + bool mReadError = false; + chip::app::ReadHandler * mpReadHandler = nullptr; }; } // namespace @@ -190,32 +224,24 @@ CHIP_ERROR ReadSingleClusterData(ClusterInfo & aClusterInfo, TLV::TLVWriter * ap uint64_t version = 0; ChipLogDetail(DataManagement, "TEST Cluster %" PRIx32 ", Field %" PRIx32 " is dirty", aClusterInfo.mClusterId, aClusterInfo.mFieldId); + + if (apDataExists != nullptr) + { + *apDataExists = (aClusterInfo.mClusterId == kTestClusterId && aClusterInfo.mEndpointId == kTestEndpointId); + } + if (apWriter == nullptr) { - return CHIP_ERROR_INVALID_ARGUMENT; + return CHIP_NO_ERROR; } if (!(aClusterInfo.mClusterId == kTestClusterId && aClusterInfo.mEndpointId == kTestEndpointId)) { - if (apDataExists != nullptr) - { - *apDataExists = false; - } - return apWriter->Put(chip::TLV::ContextTag(AttributeDataElement::kCsTag_Status), chip::Protocols::InteractionModel::ProtocolCode::UnsupportedAttribute); } - if (apDataExists != nullptr) - { - *apDataExists = true; - } - - CHIP_ERROR err = apWriter->Put(TLV::ContextTag(AttributeDataElement::kCsTag_Data), kTestFieldValue1); - if (err != CHIP_NO_ERROR) - { - return err; - } + ReturnErrorOnFailure(apWriter->Put(TLV::ContextTag(AttributeDataElement::kCsTag_Data), kTestFieldValue1)); return apWriter->Put(TLV::ContextTag(AttributeDataElement::kCsTag_DataVersion), version); } @@ -230,7 +256,11 @@ class TestReadInteraction static void TestReadClientGenerateTwoEventPathList(nlTestSuite * apSuite, void * apContext); static void TestReadClientInvalidReport(nlTestSuite * apSuite, void * apContext); static void TestReadHandlerInvalidAttributePath(nlTestSuite * apSuite, void * apContext); + static void TestProcessSubscribeResponse(nlTestSuite * apSuite, void * apContext); + static void TestProcessSubscribeRequest(nlTestSuite * apSuite, void * apContext); static void TestReadRoundtrip(nlTestSuite * apSuite, void * apContext); + static void TestSubscribeRoundtrip(nlTestSuite * apSuite, void * apContext); + static void TestSubscribeInvalidAttributePathRoundtrip(nlTestSuite * apSuite, void * apContext); static void TestReadInvalidAttributePathRoundtrip(nlTestSuite * apSuite, void * apContext); private: @@ -320,7 +350,8 @@ void TestReadInteraction::TestReadClient(nlTestSuite * apSuite, void * apContext app::ReadClient readClient; chip::app::InteractionModelDelegate delegate; System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); - err = readClient.Init(&ctx.GetExchangeManager(), &delegate, 0 /* application identifier */); + err = readClient.Init(&ctx.GetExchangeManager(), &delegate, chip::app::ReadClient::InteractionType::Read, + 0 /* application identifier */); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); ReadPrepareParams readPrepareParams(ctx.GetSessionBobToAlice()); err = readClient.SendReadRequest(readPrepareParams); @@ -347,8 +378,9 @@ void TestReadInteraction::TestReadHandler(nlTestSuite * apSuite, void * apContex auto * engine = chip::app::InteractionModelEngine::GetInstance(); err = engine->Init(&ctx.GetExchangeManager(), &delegate); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + Messaging::ExchangeContext * exchangeCtx = ctx.NewExchangeToAlice(nullptr); - readHandler.Init(&ctx.GetExchangeManager(), nullptr, exchangeCtx); + readHandler.Init(&ctx.GetExchangeManager(), nullptr, exchangeCtx, chip::app::ReadHandler::InteractionType::Read); GenerateReportData(apSuite, apContext, reportDatabuf); err = readHandler.SendReportData(std::move(reportDatabuf)); @@ -400,7 +432,8 @@ void TestReadInteraction::TestReadClientGenerateAttributePathList(nlTestSuite * err = request.Init(&writer); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - err = readClient.Init(&ctx.GetExchangeManager(), &delegate, 0 /* application identifier */); + err = readClient.Init(&ctx.GetExchangeManager(), &delegate, chip::app::ReadClient::InteractionType::Read, + 0 /* application identifier */); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); AttributePathParams attributePathParams[2]; @@ -424,7 +457,8 @@ void TestReadInteraction::TestReadClientGenerateInvalidAttributePathList(nlTestS msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes); NL_TEST_ASSERT(apSuite, !msgBuf.IsNull()); writer.Init(std::move(msgBuf)); - err = readClient.Init(&ctx.GetExchangeManager(), &delegate, 0 /* application identifier */); + err = readClient.Init(&ctx.GetExchangeManager(), &delegate, chip::app::ReadClient::InteractionType::Read, + 0 /* application identifier */); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); err = request.Init(&writer); @@ -446,7 +480,8 @@ void TestReadInteraction::TestReadClientInvalidReport(nlTestSuite * apSuite, voi chip::app::InteractionModelDelegate delegate; System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); - err = readClient.Init(&ctx.GetExchangeManager(), &delegate, 0 /* application identifier */); + err = readClient.Init(&ctx.GetExchangeManager(), &delegate, chip::app::ReadClient::InteractionType::Read, + 0 /* application identifier */); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); ReadPrepareParams readPrepareParams(ctx.GetSessionBobToAlice()); @@ -475,8 +510,9 @@ void TestReadInteraction::TestReadHandlerInvalidAttributePath(nlTestSuite * apSu auto * engine = chip::app::InteractionModelEngine::GetInstance(); err = engine->Init(&ctx.GetExchangeManager(), &delegate); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + Messaging::ExchangeContext * exchangeCtx = ctx.NewExchangeToAlice(nullptr); - readHandler.Init(&ctx.GetExchangeManager(), nullptr, exchangeCtx); + readHandler.Init(&ctx.GetExchangeManager(), nullptr, exchangeCtx, chip::app::ReadHandler::InteractionType::Read); GenerateReportData(apSuite, apContext, reportDatabuf); err = readHandler.SendReportData(std::move(reportDatabuf)); @@ -524,7 +560,8 @@ void TestReadInteraction::TestReadClientGenerateOneEventPathList(nlTestSuite * a err = request.Init(&writer); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - err = readClient.Init(&ctx.GetExchangeManager(), &delegate, 0 /* application identifier */); + err = readClient.Init(&ctx.GetExchangeManager(), &delegate, chip::app::ReadClient::InteractionType::Read, + 0 /* application identifier */); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); chip::app::EventPathParams eventPathParams[2]; @@ -573,7 +610,8 @@ void TestReadInteraction::TestReadClientGenerateTwoEventPathList(nlTestSuite * a err = request.Init(&writer); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - err = readClient.Init(&ctx.GetExchangeManager(), &delegate, 0 /* application identifier */); + err = readClient.Init(&ctx.GetExchangeManager(), &delegate, chip::app::ReadClient::InteractionType::Read, + 0 /* application identifier */); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); chip::app::EventPathParams eventPathParams[2]; @@ -651,7 +689,7 @@ void TestReadInteraction::TestReadRoundtrip(nlTestSuite * apSuite, void * apCont attributePathParams[1].mNodeId = chip::kTestDeviceNodeId; attributePathParams[1].mEndpointId = kTestEndpointId; attributePathParams[1].mClusterId = kTestClusterId; - attributePathParams[1].mFieldId = 1; + attributePathParams[1].mFieldId = 2; attributePathParams[1].mListIndex = 1; attributePathParams[1].mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); attributePathParams[1].mFlags.Set(chip::app::AttributePathParams::Flags::kListIndexValid); @@ -666,7 +704,7 @@ void TestReadInteraction::TestReadRoundtrip(nlTestSuite * apSuite, void * apCont InteractionModelEngine::GetInstance()->GetReportingEngine().Run(); NL_TEST_ASSERT(apSuite, delegate.mGotEventResponse); - NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 1); + NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 2); NL_TEST_ASSERT(apSuite, delegate.mGotReport); NL_TEST_ASSERT(apSuite, !delegate.mReadError); // By now we should have closed all exchanges and sent all pending acks, so @@ -716,6 +754,330 @@ void TestReadInteraction::TestReadInvalidAttributePathRoundtrip(nlTestSuite * ap engine->Shutdown(); } + +void TestReadInteraction::TestProcessSubscribeResponse(nlTestSuite * apSuite, void * apContext) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + TestContext & ctx = *static_cast(apContext); + app::ReadClient readClient; + chip::app::InteractionModelDelegate delegate; + System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); + err = readClient.Init(&ctx.GetExchangeManager(), &delegate, chip::app::ReadClient::InteractionType::Subscribe, + 0 /* application identifier */); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + readClient.MoveToState(chip::app::ReadClient::ClientState::AwaitingSubscribeResponse); + + GenerateSubscribeResponse(apSuite, apContext, buf.Retain()); + + err = readClient.ProcessSubscribeResponse(std::move(buf)); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + readClient.ShutdownInternal(CHIP_NO_ERROR); +} + +void TestReadInteraction::TestProcessSubscribeRequest(nlTestSuite * apSuite, void * apContext) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + TestContext & ctx = *static_cast(apContext); + app::ReadHandler readHandler; + System::PacketBufferTLVWriter writer; + System::PacketBufferHandle subscribeRequestbuf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); + SubscribeRequest::Builder subscribeRequestBuilder; + chip::app::InteractionModelDelegate delegate; + auto * engine = chip::app::InteractionModelEngine::GetInstance(); + err = engine->Init(&ctx.GetExchangeManager(), &delegate); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + Messaging::ExchangeContext * exchangeCtx = ctx.NewExchangeToAlice(nullptr); + readHandler.Init(&ctx.GetExchangeManager(), nullptr, exchangeCtx, chip::app::ReadHandler::InteractionType::Subscribe); + + writer.Init(std::move(subscribeRequestbuf)); + err = subscribeRequestBuilder.Init(&writer); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + AttributePathList::Builder attributePathListBuilder = subscribeRequestBuilder.CreateAttributePathListBuilder(); + NL_TEST_ASSERT(apSuite, attributePathListBuilder.GetError() == CHIP_NO_ERROR); + + AttributePath::Builder attributePathBuilder = attributePathListBuilder.CreateAttributePathBuilder(); + NL_TEST_ASSERT(apSuite, attributePathListBuilder.GetError() == CHIP_NO_ERROR); + + attributePathBuilder.NodeId(1).EndpointId(2).ClusterId(3).FieldId(4).ListIndex(5).EndOfAttributePath(); + err = attributePathBuilder.GetError(); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + attributePathListBuilder.EndOfAttributePathList(); + err = attributePathListBuilder.GetError(); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + subscribeRequestBuilder.MinIntervalSeconds(2); + NL_TEST_ASSERT(apSuite, subscribeRequestBuilder.GetError() == CHIP_NO_ERROR); + + subscribeRequestBuilder.MaxIntervalSeconds(3); + NL_TEST_ASSERT(apSuite, subscribeRequestBuilder.GetError() == CHIP_NO_ERROR); + + subscribeRequestBuilder.KeepExistingSubscriptions(true); + NL_TEST_ASSERT(apSuite, subscribeRequestBuilder.GetError() == CHIP_NO_ERROR); + + subscribeRequestBuilder.IsProxy(true); + NL_TEST_ASSERT(apSuite, subscribeRequestBuilder.GetError() == CHIP_NO_ERROR); + + subscribeRequestBuilder.EndOfSubscribeRequest(); + NL_TEST_ASSERT(apSuite, subscribeRequestBuilder.GetError() == CHIP_NO_ERROR); + + NL_TEST_ASSERT(apSuite, subscribeRequestBuilder.GetError() == CHIP_NO_ERROR); + err = writer.Finalize(&subscribeRequestbuf); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + err = readHandler.ProcessSubscribeRequest(std::move(subscribeRequestbuf)); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + exchangeCtx->Close(); + engine->Shutdown(); +} + +void TestReadInteraction::TestSubscribeRoundtrip(nlTestSuite * apSuite, void * apContext) +{ + TestContext & ctx = *static_cast(apContext); + CHIP_ERROR err = CHIP_NO_ERROR; + + Messaging::ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); + // Shouldn't have anything in the retransmit table when starting the test. + NL_TEST_ASSERT(apSuite, rm->TestGetCountRetransTable() == 0); + + GenerateEvents(apSuite, apContext); + + MockInteractionModelApp delegate; + auto * engine = chip::app::InteractionModelEngine::GetInstance(); + err = engine->Init(&ctx.GetExchangeManager(), &delegate); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(apSuite, !delegate.mGotEventResponse); + + ReadPrepareParams readPrepareParams(ctx.GetSessionBobToAlice()); + chip::app::EventPathParams eventPathParams[2]; + readPrepareParams.mpEventPathParamsList = eventPathParams; + readPrepareParams.mpEventPathParamsList[0].mNodeId = kTestNodeId; + readPrepareParams.mpEventPathParamsList[0].mEndpointId = kTestEndpointId; + readPrepareParams.mpEventPathParamsList[0].mClusterId = kTestClusterId; + readPrepareParams.mpEventPathParamsList[0].mEventId = kTestEventIdDebug; + + readPrepareParams.mpEventPathParamsList[1].mNodeId = kTestNodeId; + readPrepareParams.mpEventPathParamsList[1].mEndpointId = kTestEndpointId; + readPrepareParams.mpEventPathParamsList[1].mClusterId = kTestClusterId; + readPrepareParams.mpEventPathParamsList[1].mEventId = kTestEventIdCritical; + + readPrepareParams.mEventPathParamsListSize = 2; + + chip::app::AttributePathParams attributePathParams[2]; + readPrepareParams.mpAttributePathParamsList = attributePathParams; + readPrepareParams.mpAttributePathParamsList[0].mNodeId = chip::kTestDeviceNodeId; + readPrepareParams.mpAttributePathParamsList[0].mEndpointId = kTestEndpointId; + readPrepareParams.mpAttributePathParamsList[0].mClusterId = kTestClusterId; + readPrepareParams.mpAttributePathParamsList[0].mFieldId = 1; + readPrepareParams.mpAttributePathParamsList[0].mListIndex = 0; + readPrepareParams.mpAttributePathParamsList[0].mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + + readPrepareParams.mpAttributePathParamsList[1].mNodeId = chip::kTestDeviceNodeId; + readPrepareParams.mpAttributePathParamsList[1].mEndpointId = kTestEndpointId; + readPrepareParams.mpAttributePathParamsList[1].mClusterId = kTestClusterId; + readPrepareParams.mpAttributePathParamsList[1].mFieldId = 2; + readPrepareParams.mpAttributePathParamsList[1].mListIndex = 0; + readPrepareParams.mpAttributePathParamsList[1].mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + + readPrepareParams.mAttributePathParamsListSize = 2; + + readPrepareParams.mMinIntervalFloorSeconds = 2; + readPrepareParams.mMaxIntervalCeilingSeconds = 5; + printf("\nSend subscribe request message to Node: %" PRIu64 "\n", chip::kTestDeviceNodeId); + + err = engine->SendSubscribeRequest(readPrepareParams); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + delegate.mGotReport = false; + engine->GetReportingEngine().Run(); + NL_TEST_ASSERT(apSuite, delegate.mGotReport); + NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 2); + + chip::app::ClusterInfo dirtyPath1; + dirtyPath1.mClusterId = kTestClusterId; + dirtyPath1.mEndpointId = kTestEndpointId; + dirtyPath1.mFlags.Set(chip::app::ClusterInfo::Flags::kFieldIdValid); + dirtyPath1.mFieldId = 1; + + chip::app::ClusterInfo dirtyPath2; + dirtyPath2.mClusterId = kTestClusterId; + dirtyPath2.mEndpointId = kTestEndpointId; + dirtyPath2.mFlags.Set(chip::app::ClusterInfo::Flags::kFieldIdValid); + dirtyPath2.mFieldId = 2; + + chip::app::ClusterInfo dirtyPath3; + dirtyPath2.mClusterId = kTestClusterId; + dirtyPath2.mEndpointId = kTestEndpointId; + dirtyPath2.mFlags.Set(chip::app::ClusterInfo::Flags::kFieldIdValid); + dirtyPath2.mFlags.Set(chip::app::ClusterInfo::Flags::kListIndexValid); + dirtyPath2.mFieldId = 2; + dirtyPath2.mListIndex = 1; + + chip::app::ClusterInfo dirtyPath4; + dirtyPath4.mClusterId = kTestClusterId; + dirtyPath4.mEndpointId = kTestEndpointId; + dirtyPath4.mFlags.Set(chip::app::ClusterInfo::Flags::kFieldIdValid); + dirtyPath4.mFieldId = 3; + + chip::app::ClusterInfo dirtyPath5; + dirtyPath5.mClusterId = kTestClusterId; + dirtyPath5.mEndpointId = kTestEndpointId; + dirtyPath5.mFlags.Set(chip::app::ClusterInfo::Flags::kFieldIdValid); + dirtyPath5.mFieldId = 4; + + // Test report with 2 different path + delegate.mpReadHandler->mHoldReport = false; + delegate.mGotReport = false; + delegate.mNumAttributeResponse = 0; + err = engine->GetReportingEngine().SetDirty(dirtyPath1); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = engine->GetReportingEngine().SetDirty(dirtyPath2); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + engine->GetReportingEngine().Run(); + NL_TEST_ASSERT(apSuite, delegate.mGotReport); + NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 2); + + // Test report with 2 different path, and 1 same path + delegate.mpReadHandler->mHoldReport = false; + delegate.mGotReport = false; + delegate.mNumAttributeResponse = 0; + err = engine->GetReportingEngine().SetDirty(dirtyPath1); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = engine->GetReportingEngine().SetDirty(dirtyPath2); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = engine->GetReportingEngine().SetDirty(dirtyPath2); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + engine->GetReportingEngine().Run(); + NL_TEST_ASSERT(apSuite, delegate.mGotReport); + NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 2); + + // Test report with 3 different path, and one path is overlapped with another + delegate.mpReadHandler->mHoldReport = false; + delegate.mGotReport = false; + delegate.mNumAttributeResponse = 0; + err = engine->GetReportingEngine().SetDirty(dirtyPath1); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = engine->GetReportingEngine().SetDirty(dirtyPath2); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = engine->GetReportingEngine().SetDirty(dirtyPath3); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + engine->GetReportingEngine().Run(); + NL_TEST_ASSERT(apSuite, delegate.mGotReport); + NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 2); + + // Test report with 3 different path, all are not overlapped, one path is not interested for current subscription + delegate.mpReadHandler->mHoldReport = false; + delegate.mGotReport = false; + delegate.mNumAttributeResponse = 0; + err = engine->GetReportingEngine().SetDirty(dirtyPath1); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = engine->GetReportingEngine().SetDirty(dirtyPath2); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = engine->GetReportingEngine().SetDirty(dirtyPath4); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + engine->GetReportingEngine().Run(); + NL_TEST_ASSERT(apSuite, delegate.mGotReport); + NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 2); + + // Test empty report + delegate.mpReadHandler->mHoldReport = false; + delegate.mGotReport = false; + delegate.mNumAttributeResponse = 0; + engine->GetReportingEngine().Run(); + NL_TEST_ASSERT(apSuite, delegate.mGotReport); + NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 0); + + // Test multiple subscriptipn + delegate.mNumAttributeResponse = 0; + delegate.mGotReport = false; + ReadPrepareParams readPrepareParams1(ctx.GetSessionBobToAlice()); + chip::app::AttributePathParams attributePathParams1[1]; + readPrepareParams1.mpAttributePathParamsList = attributePathParams1; + readPrepareParams1.mpAttributePathParamsList[0].mNodeId = chip::kTestDeviceNodeId; + readPrepareParams1.mpAttributePathParamsList[0].mEndpointId = kTestEndpointId; + readPrepareParams1.mpAttributePathParamsList[0].mClusterId = kTestClusterId; + readPrepareParams1.mpAttributePathParamsList[0].mFieldId = 1; + readPrepareParams1.mpAttributePathParamsList[0].mListIndex = 0; + readPrepareParams1.mpAttributePathParamsList[0].mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + readPrepareParams1.mAttributePathParamsListSize = 1; + readPrepareParams1.mMinIntervalFloorSeconds = 2; + readPrepareParams1.mMaxIntervalCeilingSeconds = 5; + printf("\nSend another subscribe request message to Node: %" PRIu64 "\n", chip::kTestDeviceNodeId); + + err = engine->SendSubscribeRequest(readPrepareParams1); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + engine->GetReportingEngine().Run(); + NL_TEST_ASSERT(apSuite, delegate.mGotReport); + NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 1); + + // Test report with 1 path modification for 2 subscription + delegate.mpReadHandler->mHoldReport = false; + delegate.mGotReport = false; + delegate.mNumAttributeResponse = 0; + err = engine->GetReportingEngine().SetDirty(dirtyPath1); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + engine->GetReportingEngine().Run(); + NL_TEST_ASSERT(apSuite, delegate.mGotReport); + NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 1); + + delegate.mpReadHandler->mHoldReport = false; + engine->GetReportingEngine().Run(); + NL_TEST_ASSERT(apSuite, delegate.mGotReport); + NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 1); + // By now we should have closed all exchanges and sent all pending acks, so + // there should be no queued-up things in the retransmit table. + NL_TEST_ASSERT(apSuite, rm->TestGetCountRetransTable() == 0); + + engine->Shutdown(); +} + +void TestReadInteraction::TestSubscribeInvalidAttributePathRoundtrip(nlTestSuite * apSuite, void * apContext) +{ + TestContext & ctx = *static_cast(apContext); + CHIP_ERROR err = CHIP_NO_ERROR; + + Messaging::ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); + // Shouldn't have anything in the retransmit table when starting the test. + NL_TEST_ASSERT(apSuite, rm->TestGetCountRetransTable() == 0); + + GenerateEvents(apSuite, apContext); + + MockInteractionModelApp delegate; + auto * engine = chip::app::InteractionModelEngine::GetInstance(); + err = engine->Init(&ctx.GetExchangeManager(), &delegate); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(apSuite, !delegate.mGotEventResponse); + + ReadPrepareParams readPrepareParams(ctx.GetSessionBobToAlice()); + chip::app::AttributePathParams attributePathParams[1]; + readPrepareParams.mpAttributePathParamsList = attributePathParams; + readPrepareParams.mpAttributePathParamsList[0].mNodeId = chip::kTestDeviceNodeId; + readPrepareParams.mpAttributePathParamsList[0].mEndpointId = kTestEndpointId; + readPrepareParams.mpAttributePathParamsList[0].mClusterId = kInvalidTestClusterId; + readPrepareParams.mpAttributePathParamsList[0].mFieldId = 1; + readPrepareParams.mpAttributePathParamsList[0].mListIndex = 0; + readPrepareParams.mpAttributePathParamsList[0].mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + + readPrepareParams.mAttributePathParamsListSize = 1; + + readPrepareParams.mSessionHandle = ctx.GetSessionBobToAlice(); + readPrepareParams.mMinIntervalFloorSeconds = 2; + readPrepareParams.mMaxIntervalCeilingSeconds = 5; + printf("\nSend subscribe request message to Node: %" PRIu64 "\n", chip::kTestDeviceNodeId); + + err = chip::app::InteractionModelEngine::GetInstance()->SendSubscribeRequest(readPrepareParams); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + delegate.mNumAttributeResponse = 0; + InteractionModelEngine::GetInstance()->GetReportingEngine().Run(); + NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 0); + delegate.mpReadHandler->mHoldReport = false; + InteractionModelEngine::GetInstance()->GetReportingEngine().Run(); + NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 0); + engine->Shutdown(); +} + } // namespace app } // namespace chip @@ -737,6 +1099,10 @@ const nlTest sTests[] = NL_TEST_DEF("TestReadClientGenerateTwoEventPathList", chip::app::TestReadInteraction::TestReadClientGenerateTwoEventPathList), NL_TEST_DEF("TestReadClientInvalidReport", chip::app::TestReadInteraction::TestReadClientInvalidReport), NL_TEST_DEF("TestReadHandlerInvalidAttributePath", chip::app::TestReadInteraction::TestReadHandlerInvalidAttributePath), + NL_TEST_DEF("TestProcessSubscribeResponse", chip::app::TestReadInteraction::TestProcessSubscribeResponse), + NL_TEST_DEF("TestProcessSubscribeRequest", chip::app::TestReadInteraction::TestProcessSubscribeRequest), + NL_TEST_DEF("TestSubscribeRoundtrip", chip::app::TestReadInteraction::TestSubscribeRoundtrip), + NL_TEST_DEF("TestSubscribeInvalidAttributePathRoundtrip", chip::app::TestReadInteraction::TestSubscribeInvalidAttributePathRoundtrip), NL_TEST_DEF("TestReadInvalidAttributePathRoundtrip", chip::app::TestReadInteraction::TestReadInvalidAttributePathRoundtrip), NL_TEST_SENTINEL() }; diff --git a/src/app/tests/TestReportingEngine.cpp b/src/app/tests/TestReportingEngine.cpp index c38e1d6b5dcb1f..7732686c7f227c 100644 --- a/src/app/tests/TestReportingEngine.cpp +++ b/src/app/tests/TestReportingEngine.cpp @@ -50,12 +50,12 @@ static SecureSessionMgr gSessionManager; static Messaging::ExchangeManager gExchangeManager; static TransportMgr gTransportManager; static secure_channel::MessageCounterManager gMessageCounterManager; -constexpr ClusterId kTestClusterId = 6; -constexpr EndpointId kTestEndpointId = 1; -constexpr chip::FieldId kTestFieldId1 = 1; -constexpr chip::FieldId kTestFieldId2 = 2; -constexpr uint8_t kTestFieldValue1 = 1; -constexpr uint8_t kTestFieldValue2 = 2; +constexpr ClusterId kTestClusterId = 6; +constexpr EndpointId kTestEndpointId = 1; +constexpr chip::AttributeId kTestFieldId1 = 1; +constexpr chip::AttributeId kTestFieldId2 = 2; +constexpr uint8_t kTestFieldValue1 = 1; +constexpr uint8_t kTestFieldValue2 = 2; namespace app { CHIP_ERROR ReadSingleClusterData(AttributePathParams & aAttributePathParams, TLV::TLVWriter * apWriter, bool * apDataExists) @@ -102,7 +102,6 @@ void TestReportingEngine::TestBuildAndSendSingleReportData(nlTestSuite * apSuite { CHIP_ERROR err = CHIP_NO_ERROR; app::ReadHandler readHandler; - Engine reportingEngine; System::PacketBufferTLVWriter writer; System::PacketBufferHandle readRequestbuf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); ReadRequest::Builder readRequestBuilder; @@ -122,22 +121,34 @@ void TestReportingEngine::TestBuildAndSendSingleReportData(nlTestSuite * apSuite NL_TEST_ASSERT(apSuite, readRequestBuilder.GetError() == CHIP_NO_ERROR); attributePathBuilder = attributePathListBuilder.CreateAttributePathBuilder(); NL_TEST_ASSERT(apSuite, attributePathListBuilder.GetError() == CHIP_NO_ERROR); - attributePathBuilder = - attributePathBuilder.NodeId(1).EndpointId(kTestEndpointId).ClusterId(kTestClusterId).FieldId(0).EndOfAttributePath(); + attributePathBuilder = attributePathBuilder.NodeId(1) + .EndpointId(kTestEndpointId) + .ClusterId(kTestClusterId) + .FieldId(kTestFieldId1) + .EndOfAttributePath(); + NL_TEST_ASSERT(apSuite, attributePathBuilder.GetError() == CHIP_NO_ERROR); + + attributePathBuilder = attributePathListBuilder.CreateAttributePathBuilder(); + NL_TEST_ASSERT(apSuite, attributePathListBuilder.GetError() == CHIP_NO_ERROR); + attributePathBuilder = attributePathBuilder.NodeId(1) + .EndpointId(kTestEndpointId) + .ClusterId(kTestClusterId) + .FieldId(kTestFieldId2) + .EndOfAttributePath(); NL_TEST_ASSERT(apSuite, attributePathBuilder.GetError() == CHIP_NO_ERROR); attributePathListBuilder.EndOfAttributePathList(); - readRequestBuilder.EventNumber(1); + NL_TEST_ASSERT(apSuite, readRequestBuilder.GetError() == CHIP_NO_ERROR); readRequestBuilder.EndOfReadRequest(); NL_TEST_ASSERT(apSuite, readRequestBuilder.GetError() == CHIP_NO_ERROR); err = writer.Finalize(&readRequestbuf); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); - + readHandler.Init(&gExchangeManager, nullptr, exchangeCtx, chip::app::ReadHandler::InteractionType::Read); readHandler.OnReadInitialRequest(std::move(readRequestbuf)); - reportingEngine.Init(); - err = reportingEngine.BuildAndSendSingleReportData(&readHandler); - NL_TEST_ASSERT(apSuite, err == CHIP_ERROR_INCORRECT_STATE); + err = InteractionModelEngine::GetInstance()->GetReportingEngine().BuildAndSendSingleReportData(&readHandler); + NL_TEST_ASSERT(apSuite, err == CHIP_ERROR_NOT_CONNECTED); } + } // namespace reporting } // namespace app } // namespace chip diff --git a/src/app/tests/integration/chip_im_initiator.cpp b/src/app/tests/integration/chip_im_initiator.cpp index 57b5f4e7062caa..7c1a3ce2786fc9 100644 --- a/src/app/tests/integration/chip_im_initiator.cpp +++ b/src/app/tests/integration/chip_im_initiator.cpp @@ -51,6 +51,9 @@ constexpr size_t kMaxWriteMessageCount = 3; constexpr uint32_t gMessageIntervalMsec = 1200; constexpr uint32_t gMessageTimeoutMsec = 1000; constexpr chip::FabricIndex gFabricIndex = 0; +constexpr size_t kMaxSubMessageCount = 1; +constexpr int32_t gMessageIntervalSeconds = 1; +constexpr uint64_t gSubMaxReport = 5; chip::TransportMgr gTransportManager; chip::Inet::IPAddress gDestAddr; @@ -76,6 +79,15 @@ uint64_t gWriteCount = 0; // Count of the number of WriteResponses received. uint64_t gWriteRespCount = 0; +// Count of the number of SubscribeRequests sent. +uint64_t gSubCount = 0; + +// Count of the number of SubscribeResponses received. +uint64_t gSubRespCount = 0; + +// Count of the number of reports for subscription. +uint64_t gSubReportCount = 0; + // Whether the last command successed. enum class TestCommandResult : uint8_t { @@ -90,6 +102,7 @@ void CommandRequestTimerHandler(chip::System::Layer * systemLayer, void * appSta void BadCommandRequestTimerHandler(chip::System::Layer * systemLayer, void * appState); void ReadRequestTimerHandler(chip::System::Layer * systemLayer, void * appState); void WriteRequestTimerHandler(chip::System::Layer * systemLayer, void * appState); +void SubscribeRequestTimerHandler(chip::System::Layer * systemLayer, void * appState); CHIP_ERROR SendCommandRequest(chip::app::CommandSender * commandSender) { @@ -255,6 +268,54 @@ CHIP_ERROR SendWriteRequest(chip::app::WriteClientHandle & apWriteClient) return err; } +CHIP_ERROR SendSubscribeRequest() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + gLastMessageTime = chip::System::Clock::GetMonotonicMilliseconds(); + + chip::app::ReadPrepareParams readPrepareParams(chip::SessionHandle(chip::kTestDeviceNodeId, 0, 0, gFabricIndex)); + chip::app::EventPathParams eventPathParams[2]; + chip::app::AttributePathParams attributePathParams[1]; + readPrepareParams.mpEventPathParamsList = eventPathParams; + readPrepareParams.mpEventPathParamsList[0].mNodeId = kTestNodeId; + readPrepareParams.mpEventPathParamsList[0].mEndpointId = kTestEndpointId; + readPrepareParams.mpEventPathParamsList[0].mClusterId = kTestClusterId; + readPrepareParams.mpEventPathParamsList[0].mEventId = kTestChangeEvent1; + + readPrepareParams.mpEventPathParamsList[1].mNodeId = kTestNodeId; + readPrepareParams.mpEventPathParamsList[1].mEndpointId = kTestEndpointId; + readPrepareParams.mpEventPathParamsList[1].mClusterId = kTestClusterId; + readPrepareParams.mpEventPathParamsList[1].mEventId = kTestChangeEvent2; + + readPrepareParams.mEventPathParamsListSize = 2; + + readPrepareParams.mpAttributePathParamsList = attributePathParams; + readPrepareParams.mpAttributePathParamsList[0].mNodeId = chip::kTestDeviceNodeId; + readPrepareParams.mpAttributePathParamsList[0].mEndpointId = kTestEndpointId; + readPrepareParams.mpAttributePathParamsList[0].mClusterId = kTestClusterId; + readPrepareParams.mpAttributePathParamsList[0].mFieldId = 1; + readPrepareParams.mpAttributePathParamsList[0].mListIndex = 0; + readPrepareParams.mpAttributePathParamsList[0].mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + + readPrepareParams.mAttributePathParamsListSize = 1; + + readPrepareParams.mMinIntervalFloorSeconds = 2; + readPrepareParams.mMaxIntervalCeilingSeconds = 5; + printf("\nSend subscribe request message to Node: %" PRIu64 "\n", chip::kTestDeviceNodeId); + + err = chip::app::InteractionModelEngine::GetInstance()->SendSubscribeRequest(readPrepareParams); + SuccessOrExit(err); + + gSubCount++; + +exit: + if (err != CHIP_NO_ERROR) + { + printf("Send subscribe request failed, err: %s\n", chip::ErrorStr(err)); + } + return err; +} + CHIP_ERROR EstablishSecureSession() { CHIP_ERROR err = CHIP_NO_ERROR; @@ -304,6 +365,15 @@ void HandleWriteComplete() static_cast(gWriteRespCount) * 100 / gWriteCount, static_cast(transitTime) / 1000); } +void HandleSubscribeReportComplete() +{ + uint32_t respTime = chip::System::Clock::GetMonotonicMilliseconds(); + uint32_t transitTime = respTime - gLastMessageTime; + gSubRespCount++; + printf("Subscribe Complete: %" PRIu64 "/%" PRIu64 "(%.2f%%) time=%.3fms\n", gSubRespCount, gSubCount, + static_cast(gSubRespCount) * 100 / gSubCount, static_cast(transitTime) / 1000); +} + void CommandRequestTimerHandler(chip::System::Layer * systemLayer, void * appState) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -419,6 +489,39 @@ void WriteRequestTimerHandler(chip::System::Layer * systemLayer, void * appState VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to schedule timer with error: %s\n", chip::ErrorStr(err))); } else + { + err = chip::DeviceLayer::SystemLayer().StartTimer(gMessageIntervalSeconds * 1000, SubscribeRequestTimerHandler, NULL); + VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to schedule timer with error: %s\n", chip::ErrorStr(err))); + } + +exit: + if (err != CHIP_NO_ERROR) + { + chip::DeviceLayer::PlatformMgr().StopEventLoopTask(); + } +} + +void SubscribeRequestTimerHandler(chip::System::Layer * systemLayer, void * appState) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + if (gSubRespCount != gSubCount) + { + printf("No response received\n"); + + // Set gSubRespCount to gSubCount to start next iteration if there is any. + gSubRespCount = gSubCount; + } + + if (gSubRespCount < kMaxSubMessageCount) + { + err = SendSubscribeRequest(); + VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to send write request with error: %s\n", chip::ErrorStr(err))); + + err = chip::DeviceLayer::SystemLayer().StartTimer(20 * 1000, SubscribeRequestTimerHandler, NULL); + VerifyOrExit(err == CHIP_NO_ERROR, printf("Failed to schedule timer with error: %s\n", chip::ErrorStr(err))); + } + else { // Complete all tests. chip::DeviceLayer::PlatformMgr().StopEventLoopTask(); @@ -444,7 +547,20 @@ class MockInteractionModelApp : public chip::app::InteractionModelDelegate { return CHIP_NO_ERROR; } - CHIP_ERROR ReportProcessed(const chip::app::ReadClient * apReadClient) override { return CHIP_NO_ERROR; } + CHIP_ERROR ReportProcessed(const chip::app::ReadClient * apReadClient) override + { + if (apReadClient->IsSubscriptionType()) + { + gSubReportCount++; + if (gSubReportCount == gSubMaxReport) + { + HandleSubscribeReportComplete(); + } + } + + return CHIP_NO_ERROR; + } + CHIP_ERROR ReadError(const chip::app::ReadClient * apReadClient, CHIP_ERROR aError) override { printf("ReadError with err %" CHIP_ERROR_FORMAT, aError.Format()); @@ -452,7 +568,10 @@ class MockInteractionModelApp : public chip::app::InteractionModelDelegate } CHIP_ERROR ReadDone(const chip::app::ReadClient * apReadClient) override { - HandleReadComplete(); + if (!apReadClient->IsSubscriptionType()) + { + HandleReadComplete(); + } return CHIP_NO_ERROR; } CHIP_ERROR CommandResponseStatus(const chip::app::CommandSender * apCommandSender, diff --git a/src/app/tests/integration/chip_im_responder.cpp b/src/app/tests/integration/chip_im_responder.cpp index ef1414b46ecb4f..b95d7ec4c95dd3 100644 --- a/src/app/tests/integration/chip_im_responder.cpp +++ b/src/app/tests/integration/chip_im_responder.cpp @@ -139,6 +139,7 @@ CHIP_ERROR WriteSingleClusterData(ClusterInfo & aClusterInfo, TLV::TLVReader & a } // namespace chip namespace { +bool testSyncReport = false; chip::TransportMgr gTransportManager; chip::SecurePairingUsingTestSecret gTestPairing; LivenessEventGenerator gLivenessGenerator; @@ -159,12 +160,47 @@ void InitializeEventLogging(chip::Messaging::ExchangeManager * apMgr) chip::app::EventManagement::CreateEventManagement(apMgr, sizeof(logStorageResources) / sizeof(logStorageResources[0]), gCircularEventBuffer, logStorageResources); } + +void MutateClusterHandler(chip::System::Layer * systemLayer, void * appState) +{ + chip::app::ClusterInfo dirtyPath; + dirtyPath.mClusterId = kTestClusterId; + dirtyPath.mEndpointId = kTestEndpointId; + dirtyPath.mFlags.Set(chip::app::ClusterInfo::Flags::kFieldIdValid); + printf("MutateClusterHandler is triggered..."); + // send dirty change + if (!testSyncReport) + { + dirtyPath.mFieldId = 1; + chip::app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetDirty(dirtyPath); + chip::app::InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleRun(); + chip::DeviceLayer::SystemLayer().StartTimer(1000, MutateClusterHandler, NULL); + testSyncReport = true; + } + else + { + dirtyPath.mFieldId = 10; // unknown field + chip::app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetDirty(dirtyPath); + // send sync message(empty report) + chip::app::InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleRun(); + } +} + +class MockInteractionModelApp : public chip::app::InteractionModelDelegate +{ +public: + virtual CHIP_ERROR SubscriptionEstablished(const chip::app::ReadHandler * apReadHandler) + { + chip::DeviceLayer::SystemLayer().StartTimer(1000, MutateClusterHandler, NULL); + return CHIP_NO_ERROR; + } +}; } // namespace int main(int argc, char * argv[]) { CHIP_ERROR err = CHIP_NO_ERROR; - chip::app::InteractionModelDelegate mockDelegate; + MockInteractionModelApp mockDelegate; chip::Optional peer(chip::Transport::Type::kUndefined); const chip::FabricIndex gFabricIndex = 0; chip::Transport::FabricTable fabrics; diff --git a/src/app/tests/suites/TestDelayCommands.yaml b/src/app/tests/suites/TestDelayCommands.yaml index b3f7839bdc93f3..6a32a4c7eaf972 100644 --- a/src/app/tests/suites/TestDelayCommands.yaml +++ b/src/app/tests/suites/TestDelayCommands.yaml @@ -20,7 +20,7 @@ config: tests: - label: "Wait 100ms" - cluster: "DelayCommands" + cluster: "TestSuite" command: "WaitForMs" arguments: values: diff --git a/src/app/tests/suites/TestSubscribe_OnOff.yaml b/src/app/tests/suites/TestSubscribe_OnOff.yaml new file mode 100644 index 00000000000000..69c0c4620d80c2 --- /dev/null +++ b/src/app/tests/suites/TestSubscribe_OnOff.yaml @@ -0,0 +1,41 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Subscribe Tests - OnOff Cluster + +config: + cluster: "On/Off" + endpoint: 1 + +tests: + - label: "Set OnOff Attribute to false" + command: "Off" + - label: "Subscribe OnOff Attribute" + command: "subscribeAttribute" + attribute: "OnOff" + minInterval: 2 + maxInterval: 10 + response: + value: false + - label: "Turn On the light to see attribute change" + command: "On" + - label: "Check for attribute report" + cluster: "TestSuite" + command: "WaitForAttributeReport" + waitfor: + endpoint: 1 + cluster: "On/Off" + attribute: "OnOff" + response: + value: true diff --git a/src/app/util/CHIPDeviceCallbacksMgr.cpp b/src/app/util/CHIPDeviceCallbacksMgr.cpp index 14c8fe99d4efab..5dbc9efdb254cc 100644 --- a/src/app/util/CHIPDeviceCallbacksMgr.cpp +++ b/src/app/util/CHIPDeviceCallbacksMgr.cpp @@ -29,23 +29,6 @@ #include #include -namespace { - -struct ReportCallbackInfo -{ - chip::NodeId nodeId; - chip::EndpointId endpointId; - chip::ClusterId clusterId; - chip::AttributeId attributeId; - - bool operator==(ReportCallbackInfo const & other) - { - return nodeId == other.nodeId && endpointId == other.endpointId && clusterId == other.clusterId && - attributeId == other.attributeId; - } -}; -} // namespace - namespace chip { namespace app { @@ -145,10 +128,55 @@ CHIP_ERROR CHIPDeviceCallbacksMgr::GetResponseCallback(NodeId nodeId, uint8_t se return CHIP_NO_ERROR; } +CHIP_ERROR CHIPDeviceCallbacksMgr::SetSubscribeFilter(const ReportCallbackInfo & info, TLVDataFilter filter) +{ + constexpr ReportCallbackInfo kEmptyInfo{ kPlaceholderNodeId, 0, 0, 0 }; + + for (size_t i = 0; i < kTLVFilterPoolSize; i++) + { + if (mReportFilterPool[i].info == info) + { + mReportFilterPool[i].filter = filter; + return CHIP_NO_ERROR; + } + } + + for (size_t i = 0; i < kTLVFilterPoolSize; i++) + { + if (mReportFilterPool[i].info == kEmptyInfo) + { + mReportFilterPool[i].info = info; + mReportFilterPool[i].filter = filter; + return CHIP_NO_ERROR; + } + } + + return CHIP_ERROR_NO_MEMORY; +} + +CHIP_ERROR CHIPDeviceCallbacksMgr::GetSubscribeFilter(const ReportCallbackInfo & info, TLVDataFilter * outFilter) +{ + for (size_t i = 0; i < kTLVFilterPoolSize; i++) + { + if (mReportFilterPool[i].info == info) + { + if (outFilter != nullptr) + { + *outFilter = mReportFilterPool[i].filter; + } + return CHIP_NO_ERROR; + } + } + + return CHIP_ERROR_KEY_NOT_FOUND; +} + CHIP_ERROR CHIPDeviceCallbacksMgr::AddReportCallback(NodeId nodeId, EndpointId endpointId, ClusterId clusterId, - AttributeId attributeId, Callback::Cancelable * onReportCallback) + AttributeId attributeId, Callback::Cancelable * onReportCallback, + TLVDataFilter filter) { VerifyOrReturnError(onReportCallback != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(filter != nullptr, CHIP_ERROR_INVALID_ARGUMENT); ReportCallbackInfo info = { nodeId, endpointId, clusterId, attributeId }; static_assert(sizeof(onReportCallback->mInfo) >= sizeof(info), "Callback info too large"); @@ -157,16 +185,20 @@ CHIP_ERROR CHIPDeviceCallbacksMgr::AddReportCallback(NodeId nodeId, EndpointId e // If a callback has already been registered for the same ReportCallbackInfo, let's cancel it. CancelCallback(info, mReports); + ReturnErrorOnFailure(SetSubscribeFilter(info, filter)); + mReports.Enqueue(onReportCallback); return CHIP_NO_ERROR; } CHIP_ERROR CHIPDeviceCallbacksMgr::GetReportCallback(NodeId nodeId, EndpointId endpointId, ClusterId clusterId, - AttributeId attributeId, Callback::Cancelable ** onReportCallback) + AttributeId attributeId, Callback::Cancelable ** onReportCallback, + TLVDataFilter * outFilter) { ReportCallbackInfo info = { nodeId, endpointId, clusterId, attributeId }; ReturnErrorOnFailure(GetCallback(info, mReports, onReportCallback)); + ReturnErrorOnFailure(GetSubscribeFilter(info, outFilter)); return CHIP_NO_ERROR; } diff --git a/src/app/util/CHIPDeviceCallbacksMgr.h b/src/app/util/CHIPDeviceCallbacksMgr.h index c50353d3fd8753..cba369a4103d32 100644 --- a/src/app/util/CHIPDeviceCallbacksMgr.h +++ b/src/app/util/CHIPDeviceCallbacksMgr.h @@ -51,6 +51,7 @@ constexpr size_t kTLVFilterPoolSize = CHIP_DEVICE_CALLBACK_MANAGER_TLV_FILTER_PO * The possible implementation of this function might be: * - Unpack the data with some schema from TLV * - Call success callback and failure callback according to the result of unpack routine. + * - onFailure MAY be nullptr, in this case, response error will be ignored. (Usually for subscribe responses.) */ using TLVDataFilter = void (*)(chip::TLV::TLVReader * data, chip::Callback::Cancelable * onSuccess, chip::Callback::Cancelable * onFailure); @@ -75,9 +76,9 @@ class DLL_EXPORT CHIPDeviceCallbacksMgr Callback::Cancelable ** onFailureCallback, TLVDataFilter * callbackFilter = nullptr); CHIP_ERROR AddReportCallback(NodeId nodeId, EndpointId endpointId, ClusterId clusterId, AttributeId attributeId, - Callback::Cancelable * onReportCallback); + Callback::Cancelable * onReportCallback, TLVDataFilter callbackFilter); CHIP_ERROR GetReportCallback(NodeId nodeId, EndpointId endpointId, ClusterId clusterId, AttributeId attributeId, - Callback::Cancelable ** onReportCallback); + Callback::Cancelable ** onReportCallback, TLVDataFilter * callbackFilter); private: CHIPDeviceCallbacksMgr() {} @@ -93,10 +94,25 @@ class DLL_EXPORT CHIPDeviceCallbacksMgr } }; + struct ReportCallbackInfo + { + chip::NodeId nodeId; + chip::EndpointId endpointId; + chip::ClusterId clusterId; + chip::AttributeId attributeId; + + bool operator==(ReportCallbackInfo const & other) + { + return nodeId == other.nodeId && endpointId == other.endpointId && clusterId == other.clusterId && + attributeId == other.attributeId; + } + }; + + template struct TLVFilterItem { - ResponseCallbackInfo info = { kPlaceholderNodeId, 0 }; - TLVDataFilter filter = nullptr; + T info = { .nodeId = kPlaceholderNodeId }; + TLVDataFilter filter = nullptr; }; template @@ -138,10 +154,14 @@ class DLL_EXPORT CHIPDeviceCallbacksMgr CHIP_ERROR AddResponseFilter(const ResponseCallbackInfo & info, TLVDataFilter callbackFilter); CHIP_ERROR PopResponseFilter(const ResponseCallbackInfo & info, TLVDataFilter * callbackFilter); + CHIP_ERROR SetSubscribeFilter(const ReportCallbackInfo & info, TLVDataFilter callbackFilter); + CHIP_ERROR GetSubscribeFilter(const ReportCallbackInfo & info, TLVDataFilter * callbackFilter); + Callback::CallbackDeque mResponsesSuccess; Callback::CallbackDeque mResponsesFailure; - TLVFilterItem mTLVFilterPool[kTLVFilterPoolSize]; + TLVFilterItem mTLVFilterPool[kTLVFilterPoolSize]; Callback::CallbackDeque mReports; + TLVFilterItem mReportFilterPool[kTLVFilterPoolSize]; }; } // namespace app diff --git a/src/app/util/attribute-table.cpp b/src/app/util/attribute-table.cpp index 5ec0810a14a67e..2ea8bc6fd51e12 100644 --- a/src/app/util/attribute-table.cpp +++ b/src/app/util/attribute-table.cpp @@ -600,7 +600,7 @@ EmberAfStatus emAfWriteAttribute(EndpointId endpoint, ClusterId cluster, Attribu // Function itself will weed out tokens that are not tokenized. emAfSaveAttributeToToken(data, endpoint, cluster, metadata); - emberAfReportingAttributeChangeCallback(endpoint, cluster, attributeID, mask, manufacturerCode, dataType, data); + InteractionModelReportingAttributeChangeCallback(endpoint, cluster, attributeID, mask, manufacturerCode, dataType, data); // Post write attribute callback for all attributes changes, regardless // of cluster. diff --git a/src/app/util/ember-compatibility-functions.cpp b/src/app/util/ember-compatibility-functions.cpp index 72e7c6cf65d87a..8eaf54da4b38ca 100644 --- a/src/app/util/ember-compatibility-functions.cpp +++ b/src/app/util/ember-compatibility-functions.cpp @@ -21,8 +21,10 @@ * when calling ember callbacks. */ +#include #include #include +#include #include #include #include @@ -460,6 +462,23 @@ CHIP_ERROR WriteSingleClusterData(ClusterInfo & aClusterInfo, TLV::TLVReader & a : Protocols::SecureChannel::GeneralStatusCode::kFailure, Protocols::SecureChannel::Id, imCode); } - } // namespace app } // namespace chip + +void InteractionModelReportingAttributeChangeCallback(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId, + uint8_t mask, uint16_t manufacturerCode, EmberAfAttributeType type, + uint8_t * data) +{ + IgnoreUnusedVariable(manufacturerCode); + IgnoreUnusedVariable(type); + IgnoreUnusedVariable(data); + IgnoreUnusedVariable(mask); + + ClusterInfo info; + info.mClusterId = clusterId; + info.mFieldId = attributeId; + info.mEndpointId = endpoint; + info.mFlags.Set(ClusterInfo::Flags::kFieldIdValid); + + InteractionModelEngine::GetInstance()->GetReportingEngine().SetDirty(info); +} diff --git a/src/app/util/im-client-callbacks.cpp b/src/app/util/im-client-callbacks.cpp index 1a05a88846cc5f..5abb573a855131 100644 --- a/src/app/util/im-client-callbacks.cpp +++ b/src/app/util/im-client-callbacks.cpp @@ -372,10 +372,20 @@ bool IMReadReportAttributesResponseCallback(const app::ReadClient * apReadClient Callback::Cancelable * onSuccessCallback = nullptr; Callback::Cancelable * onFailureCallback = nullptr; app::TLVDataFilter tlvFilter = nullptr; - NodeId sourceId = aPath.mNodeId; + NodeId sourceId = apReadClient->GetExchangeContext()->GetSecureSession().GetPeerNodeId(); // In CHIPClusters.cpp, we are using sequenceNumber as application identifier. uint8_t sequenceNumber = static_cast(apReadClient->GetAppIdentifier()); - CHIP_ERROR err = gCallbacks.GetResponseCallback(sourceId, sequenceNumber, &onSuccessCallback, &onFailureCallback, &tlvFilter); + + CHIP_ERROR err = CHIP_NO_ERROR; + if (apReadClient->IsSubscriptionType()) + { + err = gCallbacks.GetReportCallback(sourceId, aPath.mEndpointId, aPath.mClusterId, aPath.mFieldId, &onSuccessCallback, + &tlvFilter); + } + else + { + err = gCallbacks.GetResponseCallback(sourceId, sequenceNumber, &onSuccessCallback, &onFailureCallback, &tlvFilter); + } if (CHIP_NO_ERROR != err) { @@ -384,7 +394,7 @@ bool IMReadReportAttributesResponseCallback(const app::ReadClient * apReadClient ChipLogDetail(Zcl, "%s: Missing success callback", __FUNCTION__); } - if (onFailureCallback == nullptr) + if (onFailureCallback == nullptr && !apReadClient->IsSubscriptionType()) { ChipLogDetail(Zcl, "%s: Missing failure callback", __FUNCTION__); } @@ -404,7 +414,7 @@ bool IMReadReportAttributesResponseCallback(const app::ReadClient * apReadClient ChipLogProgress(Zcl, " attribute TLV Type: 0x%02x", apData->GetType()); tlvFilter(apData, onSuccessCallback, onFailureCallback); } - else + else if (onFailureCallback != nullptr) { Callback::Callback * cb = Callback::Callback::FromCancelable(onFailureCallback); @@ -415,6 +425,51 @@ bool IMReadReportAttributesResponseCallback(const app::ReadClient * apReadClient return true; } +bool IMSubscribeResponseCallback(const chip::app::ReadClient * apSubscribeClient, EmberAfStatus status) +{ + ChipLogProgress(Zcl, "SubscribeResponse:"); + ChipLogProgress(Zcl, " ApplicationIdentifier: %" PRIx64, apSubscribeClient->GetAppIdentifier()); + LogStatus(status); + + // In CHIPClusters.cpp, we are using sequenceNumber as application identifier. + uint8_t sequenceNumber = static_cast(apSubscribeClient->GetAppIdentifier()); + + CHIP_ERROR err = CHIP_NO_ERROR; + Callback::Cancelable * onSuccessCallback = nullptr; + Callback::Cancelable * onFailureCallback = nullptr; + err = gCallbacks.GetResponseCallback(apSubscribeClient->GetExchangeContext()->GetSecureSession().GetPeerNodeId(), + sequenceNumber, &onSuccessCallback, &onFailureCallback); + + if (CHIP_NO_ERROR != err) + { + if (onSuccessCallback == nullptr) + { + ChipLogDetail(Zcl, "%s: Missing success callback", __FUNCTION__); + } + + if (onFailureCallback == nullptr) + { + ChipLogDetail(Zcl, "%s: Missing failure callback", __FUNCTION__); + } + return true; + } + + if (status == EMBER_ZCL_STATUS_SUCCESS) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onSuccessCallback); + cb->mCall(cb->mContext); + } + else + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, static_cast(status)); + } + + return true; +} + bool emberAfDefaultResponseCallback(ClusterId clusterId, CommandId commandId, EmberAfStatus status) { ChipLogProgress(Zcl, "DefaultResponse:"); diff --git a/src/app/util/im-client-callbacks.h b/src/app/util/im-client-callbacks.h index 1af3014c608398..cc01f87218b25f 100644 --- a/src/app/util/im-client-callbacks.h +++ b/src/app/util/im-client-callbacks.h @@ -32,6 +32,7 @@ bool IMDefaultResponseCallback(const chip::app::Command * commandObj, EmberAfSta bool IMReadReportAttributesResponseCallback(const chip::app::ReadClient * apReadClient, const chip::app::ClusterInfo & aPath, chip::TLV::TLVReader * apData, chip::Protocols::InteractionModel::ProtocolCode status); bool IMWriteResponseCallback(const chip::app::WriteClient * writeClient, EmberAfStatus status); +bool IMSubscribeResponseCallback(const chip::app::ReadClient * apSubscribeClient, EmberAfStatus status); void LogStatus(uint8_t status); // Global Response Callbacks diff --git a/src/app/zap-templates/common/ClusterTestGeneration.js b/src/app/zap-templates/common/ClusterTestGeneration.js index 1252c234e1d464..58f9a37b66e926 100644 --- a/src/app/zap-templates/common/ClusterTestGeneration.js +++ b/src/app/zap-templates/common/ClusterTestGeneration.js @@ -26,7 +26,7 @@ const path = require('path'); // Import helpers from zap core const templateUtil = require(zapPath + 'dist/src-electron/generator/template-util.js') -const { DelayCommands } = require('./simulated-clusters/TestDelayCommands.js'); +const { TestSuiteHelperCluster } = require('./TestSuiteHelperCluster.js'); const { Clusters, asBlocks, asPromise } = require('./ClustersHelper.js'); const kClusterName = 'cluster'; @@ -73,6 +73,12 @@ function setDefaultType(test) test.isWriteAttribute = true; break; + case 'subscribeAttribute': + test.isAttribute = true; + test.isReadAttribute = true; + test.isSubscribeAttribute = true; + break; + default: test.isCommand = true; break; @@ -141,6 +147,7 @@ function setDefaultResponse(test) } if (!hasResponseValueOrConstraints) { + console.log(test); console.log(test[kResponseName]); const errorStr = 'Test does not have a "value" or a "constraints" defined.'; throwError(test, errorStr); @@ -214,18 +221,19 @@ function getClusters() { // Create a new array to merge the configured clusters list and test // simulated clusters. - return Clusters.getClusters().then(clusters => clusters.concat(DelayCommands)); + return Clusters.getClusters().then(clusters => clusters.concat(TestSuiteHelperCluster)); } function getCommands(clusterName) { - return (clusterName == DelayCommands.name) ? Promise.resolve(DelayCommands.commands) : Clusters.getClientCommands(clusterName); + return (clusterName == TestSuiteHelperCluster.name) ? Promise.resolve(TestSuiteHelperCluster.commands) + : Clusters.getClientCommands(clusterName); } function getAttributes(clusterName) { - return (clusterName == DelayCommands.name) ? Promise.resolve(DelayCommands.attributes) - : Clusters.getServerAttributes(clusterName); + return (clusterName == TestSuiteHelperCluster.name) ? Promise.resolve(TestSuiteHelperCluster.attributes) + : Clusters.getServerAttributes(clusterName); } function assertCommandOrAttribute(context) @@ -291,7 +299,15 @@ function chip_tests_items(options) function isTestOnlyCluster(name) { - return name == DelayCommands.name; + return name == TestSuiteHelperCluster.name; +} + +function chip_tests_with_command_attribute_info(options) +{ + const promise = assertCommandOrAttribute(this).then(item => { + return [ item ]; + }); + return asBlocks.call(this, promise, options); } function chip_tests_item_parameters(options) @@ -360,11 +376,20 @@ function chip_tests_item_response_parameters(options) return asBlocks.call(this, promise, options); } +function chip_tests_WaitForAttributeReport_attribute_info(options) +{ + const waitfor = Object.assign(JSON.parse(JSON.stringify(this.waitfor)), { command : 'readAttribute', isAttribute : true }); + setDefaults(waitfor, this.parent); + return templateUtil.collectBlocks([ waitfor ], options, this); +} + // // Module exports // -exports.chip_tests = chip_tests; -exports.chip_tests_items = chip_tests_items; -exports.chip_tests_item_parameters = chip_tests_item_parameters; -exports.chip_tests_item_response_parameters = chip_tests_item_response_parameters; -exports.isTestOnlyCluster = isTestOnlyCluster; +exports.chip_tests = chip_tests; +exports.chip_tests_items = chip_tests_items; +exports.chip_tests_item_parameters = chip_tests_item_parameters; +exports.chip_tests_item_response_parameters = chip_tests_item_response_parameters; +exports.isTestOnlyCluster = isTestOnlyCluster; +exports.chip_tests_with_command_attribute_info = chip_tests_with_command_attribute_info; +exports.chip_tests_WaitForAttributeReport_attribute_info = chip_tests_WaitForAttributeReport_attribute_info; diff --git a/src/app/zap-templates/common/simulated-clusters/TestDelayCommands.js b/src/app/zap-templates/common/TestSuiteHelperCluster.js similarity index 67% rename from src/app/zap-templates/common/simulated-clusters/TestDelayCommands.js rename to src/app/zap-templates/common/TestSuiteHelperCluster.js index 7c4736dc533e1b..73fd1f3ef21b9d 100644 --- a/src/app/zap-templates/common/simulated-clusters/TestDelayCommands.js +++ b/src/app/zap-templates/common/TestSuiteHelperCluster.js @@ -16,7 +16,7 @@ */ /* - * This file declare test suites utilities methods for delayed commands. + * This file declare test suites utilities methods for test suite. * * Each method declared in this file needs to be implemented on a per-language * basis and permits to exposes methods to the test suites that are not part @@ -30,12 +30,21 @@ const WaitForMs = { response : { arguments : [] } }; -const DelayCommands = { - name : 'DelayCommands', - commands : [ WaitForMs ], +const WaitForAttributeRepor = { + name : 'WaitForAttributeReport', + arguments : [], + response : { arguments : [ { name : 'value' } ] } + /* + * 'WaitForAttributeResponse' will take "attribute" parameter for detailed attribute path. + */ +}; + +const TestSuiteHelperCluster = { + name : 'TestSuite', + commands : [ WaitForMs, WaitForAttributeRepor ], }; // // Module exports // -exports.DelayCommands = DelayCommands; +exports.TestSuiteHelperCluster = TestSuiteHelperCluster; diff --git a/src/app/zap-templates/templates/app/CHIPClientCallbacks-src.zapt b/src/app/zap-templates/templates/app/CHIPClientCallbacks-src.zapt index 7bffd70f48fe31..91a13139edd698 100644 --- a/src/app/zap-templates/templates/app/CHIPClientCallbacks-src.zapt +++ b/src/app/zap-templates/templates/app/CHIPClientCallbacks-src.zapt @@ -351,8 +351,11 @@ void {{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}ListAttribu EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -427,240 +430,4 @@ bool emberAf{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}Call {{/chip_cluster_responses}} {{/chip_client_clusters}} - -bool emberAfReportAttributesCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen) -{ - ChipLogProgress(Zcl, "emberAfReportAttributeCallback:"); - ChipLogProgress(Zcl, " ClusterId: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); - - NodeId sourceId = emberAfCurrentCommand()->SourceNodeId(); - ChipLogProgress(Zcl, " Source NodeId: %" PRIu64, sourceId); - - EndpointId endpointId = emberAfCurrentCommand()->apsFrame->sourceEndpoint; - ChipLogProgress(Zcl, " Source EndpointId: 0x%04x", endpointId); - - // TODO onFailureCallback is just here because of the CHECK_MESSAGE_LENGTH macro. It needs to be removed. - Callback::Cancelable * onFailureCallback = nullptr; - - while (messageLen) - { - CHECK_MESSAGE_LENGTH(4); - AttributeId attributeId = Encoding::LittleEndian::Read32(message); // attribId - ChipLogProgress(Zcl, " attributeId: " ChipLogFormatMEI, ChipLogValueMEI(attributeId)); - - GET_REPORT_CALLBACK("emberAfReportAttributesCallback"); - - CHECK_MESSAGE_LENGTH(1); - uint8_t attributeType = Encoding::Read8(message); - ChipLogProgress(Zcl, " attributeType: 0x%02x", attributeType); - - switch (attributeType) - { - case 0x00: // nodata / No data - case 0x0A: // data24 / 24-bit data - case 0x0C: // data40 / 40-bit data - case 0x0D: // data48 / 48-bit data - case 0x0E: // data56 / 56-bit data - case 0x1A: // map24 / 24-bit bitmap - case 0x1C: // map40 / 40-bit bitmap - case 0x1D: // map48 / 48-bit bitmap - case 0x1E: // map56 / 56-bit bitmap - case 0x22: // uint24 / Unsigned 24-bit integer - case 0x24: // uint40 / Unsigned 40-bit integer - case 0x25: // uint48 / Unsigned 48-bit integer - case 0x26: // uint56 / Unsigned 56-bit integer - case 0x2A: // int24 / Signed 24-bit integer - case 0x2C: // int40 / Signed 40-bit integer - case 0x2D: // int48 / Signed 48-bit integer - case 0x2E: // int56 / Signed 56-bit integer - case 0x38: // semi / Semi-precision - case 0x39: // single / Single precision - case 0x3A: // double / Double precision - case 0x48: // array / Array - case 0x49: // struct / Structure - case 0x50: // set / Set - case 0x51: // bag / Bag - case 0xE0: // ToD / Time of day - { - ChipLogError(Zcl, "attributeType 0x%02x is not supported", attributeType); - return true; - } - - case 0x41: // octstr / Octet string - case 0x42: // string / Character string - { - // Short Strings must contains at least one byte for the length - CHECK_MESSAGE_LENGTH(1); - uint8_t length = Encoding::Read8(message); - ChipLogProgress(Zcl, " length: 0x%02x", length); - - // When the length is set to 0xFF, it represents a non-value. In this case the data field is zero length. - if (length == 0xFF) - { - length = 0; - } - - CHECK_MESSAGE_LENGTH(length); - if (attributeType == 0x41) - { - Callback::Callback * cb = Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - else - { - Callback::Callback * cb = Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - break; - } - - case 0x43: // octstr16 / Long octet string - case 0x44: // string16 / Long character string - { - // Long Strings must contains at least two bytes for the length - CHECK_MESSAGE_LENGTH(2); - uint16_t length = Encoding::LittleEndian::Read16(message); - ChipLogProgress(Zcl, " length: 0x%02x", length); - - // When the length is set to 0xFFFF, it represents a non-value. In this case the data field is zero length. - if (length == 0xFFFF) - { - length = 0; - } - - CHECK_MESSAGE_LENGTH(length); - if (attributeType == 0x43) - { - Callback::Callback * cb = Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - else - { - Callback::Callback * cb = Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - break; - } - - case 0x08: // data8 / 8-bit data - case 0x18: // map8 / 8-bit bitmap - case 0x20: // uint8 / Unsigned 8-bit integer - case 0x30: // enum8 / 8-bit enumeration - { - CHECK_MESSAGE_LENGTH(1); - uint8_t value = Encoding::Read8(message); - ChipLogProgress(Zcl, " value: 0x%02x", value); - - Callback::Callback * cb = Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x09: // data16 / 16-bit data - case 0x19: // map16 / 16-bit bitmap - case 0x21: // uint16 / Unsigned 16-bit integer - case 0x31: // enum16 / 16-bit enumeration - case 0xE8: // clusterId / Cluster ID - case 0xE9: // attribId / Attribute ID - case 0xEA: // bacOID / BACnet OID - case 0xF1: // key128 / 128-bit security key - case 0xFF: // unk / Unknown - { - CHECK_MESSAGE_LENGTH(2); - uint16_t value = Encoding::LittleEndian::Read16(message); - ChipLogProgress(Zcl, " value: 0x%04x", value); - - Callback::Callback * cb = Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x0B: // data32 / 32-bit data - case 0x1B: // map32 / 32-bit bitmap - case 0x23: // uint32 / Unsigned 32-bit integer - case 0xE1: // date / Date - case 0xE2: // UTC / UTCTime - { - CHECK_MESSAGE_LENGTH(4); - uint32_t value = Encoding::LittleEndian::Read32(message); - ChipLogProgress(Zcl, " value: 0x%08x", value); - - Callback::Callback * cb = Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x0F: // data64 / 64-bit data - case 0x1F: // map64 / 64-bit bitmap - case 0x27: // uint64 / Unsigned 64-bit integer - case 0xF0: // EUI64 / IEEE address - { - CHECK_MESSAGE_LENGTH(8); - uint64_t value = Encoding::LittleEndian::Read64(message); - ChipLogProgress(Zcl, " value: 0x" ChipLogFormatX64, ChipLogValueX64(value)); - - Callback::Callback * cb = Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x10: // bool / Boolean - { - CHECK_MESSAGE_LENGTH(1); - uint8_t value = Encoding::Read8(message); - ChipLogProgress(Zcl, " value: %d", value); - - Callback::Callback * cb = Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x28: // int8 / Signed 8-bit integer - { - CHECK_MESSAGE_LENGTH(1); - int8_t value = CastToSigned(Encoding::Read8(message)); - ChipLogProgress(Zcl, " value: %" PRId8, value); - - Callback::Callback * cb = Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x29: // int16 / Signed 16-bit integer - { - CHECK_MESSAGE_LENGTH(2); - int16_t value = CastToSigned(Encoding::LittleEndian::Read16(message)); - ChipLogProgress(Zcl, " value: %" PRId16, value); - - Callback::Callback * cb = Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x2B: // int32 / Signed 32-bit integer - { - CHECK_MESSAGE_LENGTH(4); - int32_t value = CastToSigned(Encoding::LittleEndian::Read32(message)); - ChipLogProgress(Zcl, " value: %" PRId32, value); - - Callback::Callback * cb = Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x2F: // int64 / Signed 64-bit integer - { - CHECK_MESSAGE_LENGTH(8); - int64_t value = CastToSigned(Encoding::LittleEndian::Read64(message)); - ChipLogProgress(Zcl, " value: %" PRId64, value); - - Callback::Callback * cb = Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - } - } - - return true; -} {{/if}} diff --git a/src/app/zap-templates/templates/app/CHIPClusters-src.zapt b/src/app/zap-templates/templates/app/CHIPClusters-src.zapt index 2cdab62e764bbf..fa6dc463e1a284 100644 --- a/src/app/zap-templates/templates/app/CHIPClusters-src.zapt +++ b/src/app/zap-templates/templates/app/CHIPClusters-src.zapt @@ -52,9 +52,7 @@ namespace { // Pick source endpoint as 1 for now constexpr EndpointId kSourceEndpoint = 1; - - [[maybe_unused]] const uint8_t kReportingDirectionReported = 0x00; -} // namespace +} using namespace app::Clusters; using namespace System; @@ -161,24 +159,18 @@ CHIP_ERROR {{asUpperCamelCase parent.name}}Cluster::WriteAttribute{{asUpperCamel {{#if isReportableAttribute}} CHIP_ERROR {{asUpperCamelCase parent.name}}Cluster::ConfigureAttribute{{asUpperCamelCase name}}(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval{{#if isAnalog}}, {{chipType}} change{{/if}}) { - COMMAND_HEADER("Report{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}", {{asUpperCamelCase parent.name}}::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32({{#if isGlobalAttribute}}Globals{{else}}{{asUpperCamelCase parent.name}}{{/if}}::Attributes::Ids::{{asUpperCamelCase name}}) - .Put8({{atomicTypeId}}) - .Put16(minInterval) - .Put16(maxInterval); - {{#if isAnalog}} - buf.Put{{chipTypePutLength}}(static_cast<{{chipTypePutCastType}}>(change)); - {{/if}} - COMMAND_FOOTER(); + {{#if isAnalog}}IgnoreUnusedVariable(change);{{/if}} + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = {{#if isGlobalAttribute}}Globals{{else}}{{asUpperCamelCase parent.name}}{{/if}}::Attributes::Ids::{{asUpperCamelCase name}}; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR {{asUpperCamelCase parent.name}}Cluster::ReportAttribute{{asUpperCamelCase name}}(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting({{asHex code 4}}, onReportCallback); + return RequestAttributeReporting({{#if isGlobalAttribute}}Globals{{else}}{{asUpperCamelCase parent.name}}{{/if}}::Attributes::Ids::{{asUpperCamelCase name}}, onReportCallback, BasicAttributeFilter<{{chipCallback.name}}AttributeCallback>); } {{/if}} diff --git a/src/app/zap-templates/templates/app/helper.js b/src/app/zap-templates/templates/app/helper.js index 22e39b6a8d395d..cf5d8588127270 100644 --- a/src/app/zap-templates/templates/app/helper.js +++ b/src/app/zap-templates/templates/app/helper.js @@ -335,16 +335,22 @@ function asMEI(prefix, suffix) return cHelper.asHex((prefix << 16) + suffix, 8); } +function asTestSuiteSimulatedClusterCommandPartial(label) +{ + return "TestSuiteHelper_" + asUpperCamelCase(label) +} + // // Module exports // -exports.asPrintFormat = asPrintFormat; -exports.asReadType = asReadType; -exports.asReadTypeLength = asReadTypeLength; -exports.chip_endpoint_generated_functions = chip_endpoint_generated_functions -exports.chip_endpoint_cluster_list = chip_endpoint_cluster_list -exports.asTypeLiteralSuffix = asTypeLiteralSuffix; -exports.asLowerCamelCase = asLowerCamelCase; -exports.asUpperCamelCase = asUpperCamelCase; -exports.hasSpecificAttributes = hasSpecificAttributes; -exports.asMEI = asMEI; +exports.asPrintFormat = asPrintFormat; +exports.asReadType = asReadType; +exports.asReadTypeLength = asReadTypeLength; +exports.chip_endpoint_generated_functions = chip_endpoint_generated_functions +exports.chip_endpoint_cluster_list = chip_endpoint_cluster_list +exports.asTypeLiteralSuffix = asTypeLiteralSuffix; +exports.asLowerCamelCase = asLowerCamelCase; +exports.asUpperCamelCase = asUpperCamelCase; +exports.hasSpecificAttributes = hasSpecificAttributes; +exports.asMEI = asMEI; +exports.asTestSuiteSimulatedClusterCommandPartial = asTestSuiteSimulatedClusterCommandPartial; diff --git a/src/controller/CHIPCluster.cpp b/src/controller/CHIPCluster.cpp index 35ab120a99f438..7ee70683767e3f 100644 --- a/src/controller/CHIPCluster.cpp +++ b/src/controller/CHIPCluster.cpp @@ -80,10 +80,12 @@ CHIP_ERROR ClusterBase::SendCommand(uint8_t seqNum, chip::System::PacketBufferHa return err; } -CHIP_ERROR ClusterBase::RequestAttributeReporting(AttributeId attributeId, Callback::Cancelable * onReportCallback) +CHIP_ERROR ClusterBase::RequestAttributeReporting(AttributeId attributeId, Callback::Cancelable * onReportCallback, + app::TLVDataFilter tlvDataFilter) { VerifyOrReturnError(onReportCallback != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - mDevice->AddReportHandler(mEndpoint, mClusterId, attributeId, onReportCallback); + VerifyOrReturnError(tlvDataFilter != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + mDevice->AddReportHandler(mEndpoint, mClusterId, attributeId, onReportCallback, tlvDataFilter); return CHIP_NO_ERROR; } diff --git a/src/controller/CHIPCluster.h b/src/controller/CHIPCluster.h index 2f3451502c1039..b1d5e061f5e6da 100644 --- a/src/controller/CHIPCluster.h +++ b/src/controller/CHIPCluster.h @@ -68,8 +68,10 @@ class DLL_EXPORT ClusterBase * The reporting handler continues to be called as long as the callback * is active. The user can stop the reporting by cancelling the callback. * Reference: chip::Callback::Cancel() + * @param[in] tlvDataFilter Filter interface for processing data from TLV */ - CHIP_ERROR RequestAttributeReporting(AttributeId attributeId, Callback::Cancelable * reportHandler); + CHIP_ERROR RequestAttributeReporting(AttributeId attributeId, Callback::Cancelable * reportHandler, + app::TLVDataFilter tlvDataFilter); const ClusterId mClusterId; Device * mDevice; diff --git a/src/controller/CHIPDevice.cpp b/src/controller/CHIPDevice.cpp index ce621a161798bb..52a8e42f328881 100644 --- a/src/controller/CHIPDevice.cpp +++ b/src/controller/CHIPDevice.cpp @@ -688,9 +688,9 @@ void Device::CancelIMResponseHandler(app::CommandSender * commandObj) } void Device::AddReportHandler(EndpointId endpoint, ClusterId cluster, AttributeId attribute, - Callback::Cancelable * onReportCallback) + Callback::Cancelable * onReportCallback, app::TLVDataFilter tlvDataFilter) { - mCallbacksMgr.AddReportCallback(mDeviceId, endpoint, cluster, attribute, onReportCallback); + mCallbacksMgr.AddReportCallback(mDeviceId, endpoint, cluster, attribute, onReportCallback, tlvDataFilter); } CHIP_ERROR Device::SendReadAttributeRequest(app::AttributePathParams aPath, Callback::Cancelable * onSuccessCallback, @@ -706,7 +706,7 @@ CHIP_ERROR Device::SendReadAttributeRequest(app::AttributePathParams aPath, Call { AddResponseHandler(seqNum, onSuccessCallback, onFailureCallback, aTlvDataFilter); } - // The application context is used to identify different requests from client applicaiton the type of it is intptr_t, here we + // The application context is used to identify different requests from client application the type of it is intptr_t, here we // use the seqNum. chip::app::ReadPrepareParams readPrepareParams(mSecureSession.Value()); readPrepareParams.mpAttributePathParamsList = &aPath; @@ -720,6 +720,45 @@ CHIP_ERROR Device::SendReadAttributeRequest(app::AttributePathParams aPath, Call return err; } +CHIP_ERROR Device::SendSubscribeAttributeRequest(app::AttributePathParams aPath, uint16_t mMinIntervalFloorSeconds, + uint16_t mMaxIntervalCeilingSeconds, Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback) +{ + bool loadedSecureSession = false; + uint8_t seqNum = GetNextSequenceNumber(); + aPath.mNodeId = GetDeviceId(); + + ReturnErrorOnFailure(LoadSecureSessionParametersIfNeeded(loadedSecureSession)); + + app::AttributePathParams * path = mpIMDelegate->AllocateAttributePathParam(1, seqNum); + + VerifyOrReturnError(path != nullptr, CHIP_ERROR_NO_MEMORY); + + *path = aPath; + + // The application context is used to identify different requests from client application the type of it is intptr_t, here we + // use the seqNum. + app::ReadPrepareParams params(GetSecureSession()); + params.mpAttributePathParamsList = path; + params.mAttributePathParamsListSize = 1; + params.mMinIntervalFloorSeconds = mMinIntervalFloorSeconds; + params.mMaxIntervalCeilingSeconds = mMaxIntervalCeilingSeconds; + + CHIP_ERROR err = + chip::app::InteractionModelEngine::GetInstance()->SendSubscribeRequest(params, seqNum /* application context */); + if (err != CHIP_NO_ERROR) + { + mpIMDelegate->FreeAttributePathParam(seqNum); + return err; + } + + if (onSuccessCallback != nullptr || onFailureCallback != nullptr) + { + AddResponseHandler(seqNum, onSuccessCallback, onFailureCallback); + } + return CHIP_NO_ERROR; +} + CHIP_ERROR Device::SendWriteAttributeRequest(app::WriteClientHandle aHandle, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { diff --git a/src/controller/CHIPDevice.h b/src/controller/CHIPDevice.h index 2934523d34dd65..73c7cbb54e2bb5 100644 --- a/src/controller/CHIPDevice.h +++ b/src/controller/CHIPDevice.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -87,7 +88,8 @@ struct ControllerDeviceInitParams #if CONFIG_NETWORK_LAYER_BLE Ble::BleLayer * bleLayer = nullptr; #endif - Transport::FabricTable * fabricsTable = nullptr; + Transport::FabricTable * fabricsTable = nullptr; + DeviceControllerInteractionModelDelegate * imDelegate = nullptr; }; class Device; @@ -150,6 +152,10 @@ class DLL_EXPORT Device : public Messaging::ExchangeDelegate, public SessionEsta CHIP_ERROR SendReadAttributeRequest(app::AttributePathParams aPath, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, app::TLVDataFilter aTlvDataFilter); + CHIP_ERROR SendSubscribeAttributeRequest(app::AttributePathParams aPath, uint16_t mMinIntervalFloorSeconds, + uint16_t mMaxIntervalCeilingSeconds, Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback); + CHIP_ERROR SendWriteAttributeRequest(app::WriteClientHandle aHandle, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); @@ -196,6 +202,7 @@ class DLL_EXPORT Device : public Messaging::ExchangeDelegate, public SessionEsta mStorageDelegate = params.storageDelegate; mIDAllocator = params.idAllocator; mFabricsTable = params.fabricsTable; + mpIMDelegate = params.imDelegate; #if CONFIG_NETWORK_LAYER_BLE mBleLayer = params.bleLayer; #endif @@ -377,10 +384,11 @@ class DLL_EXPORT Device : public Messaging::ExchangeDelegate, public SessionEsta void AddResponseHandler(uint8_t seqNum, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, app::TLVDataFilter tlvDataFilter = nullptr); void CancelResponseHandler(uint8_t seqNum); - void AddReportHandler(EndpointId endpoint, ClusterId cluster, AttributeId attribute, Callback::Cancelable * onReportCallback); + void AddReportHandler(EndpointId endpoint, ClusterId cluster, AttributeId attribute, Callback::Cancelable * onReportCallback, + app::TLVDataFilter tlvDataFilter); - // This two functions are pretty tricky, it is used to bridge the response, we need to implement interaction model delegate on - // the app side instead of register callbacks here. The IM delegate can provide more infomation then callback and it is + // This two functions are pretty tricky, it is used to bridge the response, we need to implement interaction model delegate + // on the app side instead of register callbacks here. The IM delegate can provide more infomation then callback and it is // type-safe. // TODO: Implement interaction model delegate in the application. void AddIMResponseHandler(app::CommandSender * commandObj, Callback::Cancelable * onSuccessCallback, @@ -475,6 +483,8 @@ class DLL_EXPORT Device : public Messaging::ExchangeDelegate, public SessionEsta Optional mSecureSession = Optional::Missing(); + DeviceControllerInteractionModelDelegate * mpIMDelegate = nullptr; + uint8_t mSequenceNumber = 0; uint32_t mLocalMessageCounter = 0; diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 900262dffab078..ffe976bf2811cf 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -177,13 +177,14 @@ CHIP_ERROR DeviceController::Init(ControllerInitParams params) if (params.imDelegate != nullptr) { - ReturnErrorOnFailure(chip::app::InteractionModelEngine::GetInstance()->Init(mExchangeMgr, params.imDelegate)); + mInteractionModelDelegate = params.imDelegate; } else { - mDefaultIMDelegate = chip::Platform::New(); - ReturnErrorOnFailure(chip::app::InteractionModelEngine::GetInstance()->Init(mExchangeMgr, mDefaultIMDelegate)); + mDefaultIMDelegate = chip::Platform::New(); + mInteractionModelDelegate = mDefaultIMDelegate; } + ReturnErrorOnFailure(chip::app::InteractionModelEngine::GetInstance()->Init(mExchangeMgr, mInteractionModelDelegate)); mExchangeMgr->SetDelegate(this); @@ -711,6 +712,7 @@ ControllerDeviceInitParams DeviceController::GetControllerDeviceInitParams() .storageDelegate = mStorageDelegate, .idAllocator = &mIDAllocator, .fabricsTable = &mFabrics, + .imDelegate = mInteractionModelDelegate, }; } @@ -1637,6 +1639,16 @@ CHIP_ERROR DeviceControllerInteractionModelDelegate::ReadError(const app::ReadCl return CHIP_NO_ERROR; } +CHIP_ERROR DeviceControllerInteractionModelDelegate::ReadDone(const app::ReadClient * apReadClient) +{ + // Release the object for subscription + if (apReadClient->IsSubscriptionType()) + { + FreeAttributePathParam(apReadClient->GetAppIdentifier()); + } + return CHIP_NO_ERROR; +} + CHIP_ERROR DeviceControllerInteractionModelDelegate::WriteResponseStatus( const app::WriteClient * apWriteClient, const Protocols::SecureChannel::GeneralStatusCode aGeneralCode, const uint32_t aProtocolId, const uint16_t aProtocolCode, app::AttributePathParams & aAttributePathParams, @@ -1661,6 +1673,15 @@ CHIP_ERROR DeviceControllerInteractionModelDelegate::WriteResponseError(const ap return CHIP_NO_ERROR; } +CHIP_ERROR DeviceControllerInteractionModelDelegate::SubscribeResponseProcessed(const app::ReadClient * apSubscribeClient) +{ +#if !CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE // temporary - until example app clusters are updated (Issue 8347) + // When WriteResponseError occurred, it means we failed to receive the response from server. + IMSubscribeResponseCallback(apSubscribeClient, EMBER_ZCL_STATUS_SUCCESS); +#endif + return CHIP_NO_ERROR; +} + void BasicSuccess(void * context, uint16_t val) { ChipLogProgress(Controller, "Received success response 0x%x\n", val); diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index e9f16b07f06eb9..79a2966e09a4a4 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -86,7 +87,7 @@ struct ControllerInitParams #if CONFIG_NETWORK_LAYER_BLE Ble::BleLayer * bleLayer = nullptr; #endif - app::InteractionModelDelegate * imDelegate = nullptr; + DeviceControllerInteractionModelDelegate * imDelegate = nullptr; #if CHIP_DEVICE_CONFIG_ENABLE_MDNS DeviceAddressUpdateDelegate * mDeviceAddressUpdateDelegate = nullptr; #endif @@ -173,39 +174,6 @@ struct CommissionerInitParams : public ControllerInitParams DevicePairingDelegate * pairingDelegate = nullptr; }; -/** - * @brief - * Used for make current OnSuccessCallback & OnFailureCallback works when interaction model landed, it will be removed - * after #6308 is landed. - */ -class DeviceControllerInteractionModelDelegate : public chip::app::InteractionModelDelegate -{ -public: - CHIP_ERROR CommandResponseStatus(const app::CommandSender * apCommandSender, - const Protocols::SecureChannel::GeneralStatusCode aGeneralCode, const uint32_t aProtocolId, - const uint16_t aProtocolCode, chip::EndpointId aEndpointId, const chip::ClusterId aClusterId, - chip::CommandId aCommandId, uint8_t aCommandIndex) override; - - CHIP_ERROR CommandResponseProtocolError(const app::CommandSender * apCommandSender, uint8_t aCommandIndex) override; - - CHIP_ERROR CommandResponseError(const app::CommandSender * apCommandSender, CHIP_ERROR aError) override; - - CHIP_ERROR CommandResponseProcessed(const app::CommandSender * apCommandSender) override; - - void OnReportData(const app::ReadClient * apReadClient, const app::ClusterInfo & aPath, TLV::TLVReader * apData, - Protocols::InteractionModel::ProtocolCode status) override; - CHIP_ERROR ReadError(const app::ReadClient * apReadClient, CHIP_ERROR aError) override; - - CHIP_ERROR WriteResponseStatus(const app::WriteClient * apWriteClient, - const Protocols::SecureChannel::GeneralStatusCode aGeneralCode, const uint32_t aProtocolId, - const uint16_t aProtocolCode, app::AttributePathParams & aAttributePathParams, - uint8_t aCommandIndex) override; - - CHIP_ERROR WriteResponseProtocolError(const app::WriteClient * apWriteClient, uint8_t aAttributeIndex) override; - - CHIP_ERROR WriteResponseError(const app::WriteClient * apWriteClient, CHIP_ERROR aError) override; -}; - /** * @brief * Controller applications can use this class to communicate with already paired CHIP devices. The @@ -303,6 +271,8 @@ class DLL_EXPORT DeviceController : public Messaging::ExchangeDelegate, */ uint64_t GetFabricId() const { return mFabricId; } + DeviceControllerInteractionModelDelegate * GetInteractionModelDelegate() { return mInteractionModelDelegate; } + protected: enum class State { @@ -340,7 +310,8 @@ class DLL_EXPORT DeviceController : public Messaging::ExchangeDelegate, #if CONFIG_NETWORK_LAYER_BLE Ble::BleLayer * mBleLayer = nullptr; #endif - System::Layer * mSystemLayer = nullptr; + System::Layer * mSystemLayer = nullptr; + DeviceControllerInteractionModelDelegate * mInteractionModelDelegate = nullptr; uint16_t mListenPort; uint16_t GetInactiveDeviceIndex(); diff --git a/src/controller/DeviceControllerInteractionModelDelegate.h b/src/controller/DeviceControllerInteractionModelDelegate.h new file mode 100644 index 00000000000000..1a0c23f6f37bda --- /dev/null +++ b/src/controller/DeviceControllerInteractionModelDelegate.h @@ -0,0 +1,86 @@ +#pragma once + +#include + +#include + +namespace chip { +namespace Controller { +/** + * @brief + * Used for make current OnSuccessCallback & OnFailureCallback works when interaction model landed, it will be removed + * after #6308 is landed. + */ +class DeviceControllerInteractionModelDelegate : public chip::app::InteractionModelDelegate +{ +public: + CHIP_ERROR CommandResponseStatus(const app::CommandSender * apCommandSender, + const Protocols::SecureChannel::GeneralStatusCode aGeneralCode, const uint32_t aProtocolId, + const uint16_t aProtocolCode, chip::EndpointId aEndpointId, const chip::ClusterId aClusterId, + chip::CommandId aCommandId, uint8_t aCommandIndex) override; + + CHIP_ERROR CommandResponseProtocolError(const app::CommandSender * apCommandSender, uint8_t aCommandIndex) override; + + CHIP_ERROR CommandResponseError(const app::CommandSender * apCommandSender, CHIP_ERROR aError) override; + + CHIP_ERROR CommandResponseProcessed(const app::CommandSender * apCommandSender) override; + + void OnReportData(const app::ReadClient * apReadClient, const app::ClusterInfo & aPath, TLV::TLVReader * apData, + Protocols::InteractionModel::ProtocolCode status) override; + CHIP_ERROR ReadError(const app::ReadClient * apReadClient, CHIP_ERROR aError) override; + + CHIP_ERROR WriteResponseStatus(const app::WriteClient * apWriteClient, + const Protocols::SecureChannel::GeneralStatusCode aGeneralCode, const uint32_t aProtocolId, + const uint16_t aProtocolCode, app::AttributePathParams & aAttributePathParams, + uint8_t aCommandIndex) override; + + CHIP_ERROR WriteResponseProtocolError(const app::WriteClient * apWriteClient, uint8_t aAttributeIndex) override; + + CHIP_ERROR WriteResponseError(const app::WriteClient * apWriteClient, CHIP_ERROR aError) override; + + CHIP_ERROR SubscribeResponseProcessed(const app::ReadClient * apSubscribeClient) override; + + CHIP_ERROR ReadDone(const app::ReadClient * apReadClient) override; + + // TODO: FreeAttributePathParam and AllocateAttributePathParam are used by CHIPDevice.cpp for getting a long-live attribute path + // object. + void FreeAttributePathParam(uint64_t applicationId) + { + for (auto & item : mAttributePathTransactionMapPool) + { + if (item.ApplicationId == applicationId) + { + item.ApplicationId = UINT64_MAX; + } + } + } + + // TODO: We only support allocating one path, should support multiple path later. + app::AttributePathParams * AllocateAttributePathParam(size_t n, uint64_t applicationId) + { + if (n > 1) + { + return nullptr; + } + for (auto & item : mAttributePathTransactionMapPool) + { + if (item.ApplicationId == UINT64_MAX) + { + item.ApplicationId = applicationId; + return &item.Params; + } + } + return nullptr; + } + +private: + struct AttributePathTransactionMap + { + uint64_t ApplicationId = UINT64_MAX; + app::AttributePathParams Params; + }; + AttributePathTransactionMap mAttributePathTransactionMapPool[CHIP_DEVICE_CONTROLLER_SUBSCRIPTION_ATTRIBUTE_PATH_POOL_SIZE]; +}; + +} // namespace Controller +} // namespace chip diff --git a/src/controller/python/chip/interaction_model/Delegate.cpp b/src/controller/python/chip/interaction_model/Delegate.cpp index b51e00f607b3ef..c65bdd151d3e18 100644 --- a/src/controller/python/chip/interaction_model/Delegate.cpp +++ b/src/controller/python/chip/interaction_model/Delegate.cpp @@ -126,8 +126,9 @@ void PythonInteractionModelDelegate::OnReportData(const app::ReadClient * apRead { AttributePath path{ .endpointId = aPath.mEndpointId, .clusterId = aPath.mClusterId, .fieldId = aPath.mFieldId }; onReportDataFunct(apReadClient->GetExchangeContext()->GetSecureSession().GetPeerNodeId(), - apReadClient->GetAppIdentifier(), &path, sizeof(path), writerBuffer, writer.GetLengthWritten(), - to_underlying(status)); + apReadClient->GetAppIdentifier(), + /* TODO: Use real SubscriptionId */ apReadClient->IsSubscriptionType() ? 1 : 0, &path, sizeof(path), + writerBuffer, writer.GetLengthWritten(), to_underlying(status)); } else { diff --git a/src/controller/python/chip/interaction_model/Delegate.h b/src/controller/python/chip/interaction_model/Delegate.h index 0dea367a4b7122..ed34a7aa629aee 100644 --- a/src/controller/python/chip/interaction_model/Delegate.h +++ b/src/controller/python/chip/interaction_model/Delegate.h @@ -79,8 +79,9 @@ typedef void (*PythonInteractionModelDelegate_OnCommandResponseFunct)(uint64_t c typedef void (*PythonInteractionModelDelegate_OnWriteResponseStatusFunct)(void * writeStatusBuf, uint32_t writeStatusBufLen); typedef void (*PythonInteractionModelDelegate_OnReportDataFunct)(chip::NodeId nodeId, uint64_t readClientAppIdentifier, - void * attributePathBuf, size_t attributePathBufLen, - uint8_t * readTlvData, size_t readTlvDataLen, uint16_t statusCode); + uint64_t subscriptionId, void * attributePathBuf, + size_t attributePathBufLen, uint8_t * readTlvData, + size_t readTlvDataLen, uint16_t statusCode); void pychip_InteractionModelDelegate_SetCommandResponseStatusCallback( PythonInteractionModelDelegate_OnCommandResponseStatusCodeReceivedFunct f); diff --git a/src/controller/python/chip/interaction_model/__init__.py b/src/controller/python/chip/interaction_model/__init__.py index 506ecac01dc6e0..30fdb1738469eb 100644 --- a/src/controller/python/chip/interaction_model/__init__.py +++ b/src/controller/python/chip/interaction_model/__init__.py @@ -22,6 +22,8 @@ """Provides Python APIs for CHIP.""" from construct.core import EnumInteger + +from .delegate import OnSubscriptionReport, SetAttributeReportCallback, AttributePath __all__ = ["IMDelegate", "ProtocolCode"] diff --git a/src/controller/python/chip/interaction_model/delegate.py b/src/controller/python/chip/interaction_model/delegate.py index b48a86da5398fd..7f40a0f5f029a1 100644 --- a/src/controller/python/chip/interaction_model/delegate.py +++ b/src/controller/python/chip/interaction_model/delegate.py @@ -14,6 +14,7 @@ limitations under the License. ''' +from abc import abstractmethod from construct import Struct, Int64ul, Int32ul, Int16ul, Int8ul from ctypes import CFUNCTYPE, c_void_p, c_uint32, c_uint64, c_uint8, c_uint16, c_ssize_t import ctypes @@ -86,7 +87,7 @@ class AttributeWriteResult: _OnCommandResponseProtocolErrorFunct = CFUNCTYPE(None, c_uint64, c_uint8) _OnCommandResponseFunct = CFUNCTYPE(None, c_uint64, c_uint32) _OnReportDataFunct = CFUNCTYPE( - None, c_uint64, c_ssize_t, c_void_p, c_uint32, c_void_p, c_uint32, c_uint16) + None, c_uint64, c_uint64, c_ssize_t, c_void_p, c_uint32, c_void_p, c_uint32, c_uint16) _OnWriteResponseStatusFunct = CFUNCTYPE(None, c_void_p, c_uint32) _commandStatusDict = dict() @@ -105,6 +106,14 @@ class AttributeWriteResult: DEFAULT_ATTRIBUTEREAD_APPID = 0 DEFAULT_ATTRIBUTEWRITE_APPID = 0 +_onSubscriptionReport = None + + +class OnSubscriptionReport: + @abstractmethod + def OnData(self, path: AttributePath, subscriptionId: int, data: typing.Any) -> None: + pass + def _GetCommandStatus(commandHandle: int): with _commandStatusLock: @@ -151,7 +160,8 @@ def _OnCommandResponse(commandHandle: int, errorcode: int): @ _OnReportDataFunct -def _OnReportData(nodeId: int, appId: int, attrPathBuf, attrPathBufLen: int, tlvDataBuf, tlvDataBufLen: int, statusCode: int): +def _OnReportData(nodeId: int, appId: int, subscriptionId: int, attrPathBuf, attrPathBufLen: int, tlvDataBuf, tlvDataBufLen: int, statusCode: int): + global _onSubscriptionReport attrPath = AttributePathStruct.parse( ctypes.string_at(attrPathBuf, attrPathBufLen)) tlvData = None @@ -166,6 +176,10 @@ def _OnReportData(nodeId: int, appId: int, attrPathBuf, attrPathBufLen: int, tlv # For all attribute read requests using CHIPCluster API, appId is filled by CHIPDevice, and should be smaller than 256 (UINT8_MAX). appId = DEFAULT_ATTRIBUTEREAD_APPID + if subscriptionId != 0: + if _onSubscriptionReport: + _onSubscriptionReport.OnData(path, subscriptionId, tlvData) + with _attributeDictLock: _attributeDict[appId] = AttributeReadResult( path, statusCode, tlvData) @@ -276,3 +290,8 @@ def GetAttributeReadResponse(appId: int) -> AttributeReadResult: def GetAttributeWriteResponse(appId: int) -> AttributeWriteResult: with _writeStatusDictLock: return _writeStatusDict.get(appId, None) + + +def SetAttributeReportCallback(path: AttributePath, callback: OnSubscriptionReport): + global _onSubscriptionReport + _onSubscriptionReport = callback diff --git a/src/controller/python/test/test_scripts/base.py b/src/controller/python/test/test_scripts/base.py index 397f9c9789834b..cdf1c7ad7b7fa4 100644 --- a/src/controller/python/test/test_scripts/base.py +++ b/src/controller/python/test/test_scripts/base.py @@ -17,6 +17,7 @@ from dataclasses import dataclass from typing import Any +import typing from chip import ChipDeviceCtrl import chip.interaction_model as IM import threading @@ -236,6 +237,60 @@ class AttributeWriteRequest: return False return True + def TestSubscription(self, nodeid: int, endpoint: int): + class _subscriptionHandler(IM.OnSubscriptionReport): + def __init__(self, path: IM.AttributePath, logger: logging.Logger): + super(_subscriptionHandler, self).__init__() + self.subscriptionReceived = 0 + self.path = path + self.countLock = threading.Lock() + self.cv = threading.Condition(self.countLock) + self.logger = logger + + def OnData(self, path: IM.AttributePath, subscriptionId: int, data: typing.Any) -> None: + if path != self.path: + return + logger.info( + f"Received report from server: path: {path}, value: {data}, subscriptionId: {subscriptionId}") + with self.countLock: + self.subscriptionReceived += 1 + self.cv.notify_all() + + class _conductAttributeChange(threading.Thread): + def __init__(self, devCtrl: ChipDeviceCtrl.ChipDeviceController, nodeid: int, endpoint: int): + super(_conductAttributeChange, self).__init__() + self.nodeid = nodeid + self.endpoint = endpoint + self.devCtrl = devCtrl + + def run(self): + for i in range(5): + time.sleep(3) + self.devCtrl.ZCLSend( + "OnOff", "Toggle", self.nodeid, self.endpoint, 0, {}) + + try: + subscribedPath = IM.AttributePath( + nodeId=nodeid, endpointId=endpoint, clusterId=6, attributeId=0) + # OnOff Cluster, OnOff Attribute + handler = _subscriptionHandler(subscribedPath, self.logger) + IM.SetAttributeReportCallback(subscribedPath, handler) + self.devCtrl.ZCLConfigureAttribute( + "OnOff", "OnOff", nodeid, endpoint, 1, 10, 0) + changeThread = _conductAttributeChange( + self.devCtrl, nodeid, endpoint) + changeThread.start() + with handler.cv: + while handler.subscriptionReceived < 5: + # We should observe 10 attribute changes + handler.cv.wait() + return True + except Exception as ex: + self.logger.exception(f"Failed to finish API test: {ex}") + return False + + return True + def TestNonControllerAPIs(self): ''' This function validates various APIs provided by chip package which is not related to controller. diff --git a/src/controller/python/test/test_scripts/mobile-device-test.py b/src/controller/python/test/test_scripts/mobile-device-test.py index dfcaeeafcda8b7..ec2980fc136455 100755 --- a/src/controller/python/test/test_scripts/mobile-device-test.py +++ b/src/controller/python/test/test_scripts/mobile-device-test.py @@ -108,6 +108,10 @@ def main(): group=GROUP_ID), "Failed to test Write Basic Attributes") + logger.info("Testing subscription") + FailIfNot(test.TestSubscription(nodeid=1, endpoint=LIGHTING_ENDPOINT_ID), + "Failed to subscribe attributes.") + logger.info("Testing closing sessions") FailIfNot(test.TestCloseSession(nodeid=1), "Failed to close sessions") diff --git a/src/darwin/Framework/CHIP/templates/clusters-tests.zapt b/src/darwin/Framework/CHIP/templates/clusters-tests.zapt index 12e90d51d2ade5..8281b816da0379 100644 --- a/src/darwin/Framework/CHIP/templates/clusters-tests.zapt +++ b/src/darwin/Framework/CHIP/templates/clusters-tests.zapt @@ -142,80 +142,7 @@ CHIPDevice * GetPairedDevice(uint64_t deviceId) [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; } -- (void)testSendClusterTestCluster_Reporting_0000_BindOnOff_Test -{ - XCTestExpectation * expectation = [self expectationWithDescription:@"Binding to OnOff Cluster complete"]; - CHIPDevice * device = GetPairedDevice(kDeviceId); - dispatch_queue_t queue = dispatch_get_main_queue(); - CHIPBinding * bindingCluster = [[CHIPBinding alloc] initWithDevice:device endpoint:1 queue:queue]; - XCTAssertNotNil(bindingCluster); - [bindingCluster bind:kDeviceId groupId:0 - endpointId:1 - clusterId:6 - responseHandler:^(NSError * err, NSDictionary * values) { - NSLog(@"Reporting Test Binding status : %@", err); - XCTAssertEqual(err.code, 0); - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; -} - -- (void)testSendClusterTestCluster_Reporting_0001_ConfigureOnOff_Test -{ - XCTestExpectation * expectation = [self expectationWithDescription:@"Reporting OnOff configured"]; - CHIPDevice * device = GetPairedDevice(kDeviceId); - dispatch_queue_t queue = dispatch_get_main_queue(); - CHIPOnOff * onOffCluster = [[CHIPOnOff alloc] initWithDevice:device endpoint:1 queue:queue]; - XCTAssertNotNil(onOffCluster); - [onOffCluster configureAttributeOnOffWithMinInterval:0 - maxInterval:1 - responseHandler:^(NSError * err, NSDictionary * values) { - NSLog(@"Reporting Test Configure status: %@", err); - - XCTAssertEqual(err.code, 0); - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; -} - -- (void)testSendClusterTestCluster_Reporting_0002_ReportOnOff_Test -{ - XCTestExpectation * expectation = [self expectationWithDescription:@"First report received"]; - CHIPDevice * device = GetPairedDevice(kDeviceId); - dispatch_queue_t queue = dispatch_get_main_queue(); - CHIPOnOff * onOffCluster = [[CHIPOnOff alloc] initWithDevice:device endpoint:1 queue:queue]; - XCTAssertNotNil(onOffCluster); - [onOffCluster reportAttributeOnOffWithResponseHandler:^(NSError * err, NSDictionary * values) - { - NSLog(@"Reporting Test Report first report: %@", err); - [expectation fulfill]; - XCTAssertEqual(err.code, 0); - }]; - - [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; -} - -- (void)testSendClusterTestCluster_Reporting_0003_StopReportOnOff_Test -{ - XCTestExpectation * expectation = [self expectationWithDescription:@"Reporting OnOff cancelled"]; - CHIPDevice * device = GetPairedDevice(kDeviceId); - dispatch_queue_t queue = dispatch_get_main_queue(); - CHIPOnOff * onOffCluster = [[CHIPOnOff alloc] initWithDevice:device endpoint:1 queue:queue]; - XCTAssertNotNil(onOffCluster); - [onOffCluster configureAttributeOnOffWithMinInterval:0 - maxInterval:0xffff - responseHandler:^(NSError * err, NSDictionary * values) { - NSLog(@"Reporting Test Cancel Reports status: %@", err); - - XCTAssertEqual(err.code, 0); - [expectation fulfill]; - }]; - [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; -} - -{{>test_cluster tests="TestCluster, TestConstraints, TestDelayCommands, Test_TC_OO_1_1, Test_TC_OO_2_1, Test_TC_OO_2_2, Test_TC_DM_1_1, Test_TC_DM_3_1, Test_TC_CC_3_4, Test_TC_CC_5, Test_TC_CC_6, Test_TC_CC_7, Test_TC_CC_8, Test_TC_WNCV_1_1, Test_TC_WNCV_2_1, Test_TC_BI_1_1, Test_TC_FLW_1_1, Test_TC_TM_1_1, Test_TC_OCC_1_1, OperationalCredentialsCluster"}} +{{>test_cluster tests="TestCluster, TestConstraints, TestDelayCommands, TestSubscribe_OnOff, Test_TC_OO_1_1, Test_TC_OO_2_1, Test_TC_OO_2_2, Test_TC_DM_1_1, Test_TC_DM_3_1, Test_TC_CC_3_4, Test_TC_CC_5, Test_TC_CC_6, Test_TC_CC_7, Test_TC_CC_8, Test_TC_WNCV_1_1, Test_TC_WNCV_2_1, Test_TC_BI_1_1, Test_TC_FLW_1_1, Test_TC_TM_1_1, Test_TC_OCC_1_1, OperationalCredentialsCluster"}} {{#chip_client_clusters}} {{#unless (isStrEqual "Test Cluster" name)}} diff --git a/src/darwin/Framework/CHIP/templates/partials/process_response_value.zapt b/src/darwin/Framework/CHIP/templates/partials/process_response_value.zapt new file mode 100644 index 00000000000000..87927090450d6e --- /dev/null +++ b/src/darwin/Framework/CHIP/templates/partials/process_response_value.zapt @@ -0,0 +1,38 @@ + {{#chip_tests_item_response_parameters}} + {{#if hasExpectedValue}} + {{#if isList}} + XCTAssertEqual([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] count], {{expectedValue.length}}); + {{else}} + {{#if (isString type)}} + {{#if (isOctetString type)}} + NSString * {{asLowerCamelCase name}}ArgumentString= @"{{expectedValue}}"; + NSData * {{asLowerCamelCase name}}Argument = [{{asLowerCamelCase name}}ArgumentString dataUsingEncoding:NSUTF8StringEncoding]; + XCTAssertTrue([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] isEqualToData:{{asLowerCamelCase name}}Argument]); + {{else}} + NSString * {{asLowerCamelCase name}}Argument= @"{{expectedValue}}"; + XCTAssertTrue([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] isEqualToString:{{asLowerCamelCase name}}Argument]); + {{/if}} + {{else}} + XCTAssertEqual([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] {{asObjectiveCNumberType "" type true}}Value], {{expectedValue}}{{asTypeLiteralSuffix}}); + {{/if}} + {{/if}} + {{/if}} + {{#if hasExpectedConstraints}} + {{#if expectedConstraints.minLength}} + XCTAssertGreaterThanOrEqual([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] length], {{expectedConstraints.minLength}}); + {{/if}} + {{#if expectedConstraints.maxLength}} + XCTAssertLessThanOrEqual([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] length], {{expectedConstraints.maxLength}}); + {{/if}} + {{#if expectedConstraints.minValue}} + XCTAssertGreaterThanOrEqual([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] {{asObjectiveCNumberType "" type true}}Value], {{expectedConstraints.minValue}}); + {{/if}} + {{#if expectedConstraints.maxValue}} + XCTAssertLessThanOrEqual([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] {{asObjectiveCNumberType "" type true}}Value], {{expectedConstraints.maxValue}}); + {{/if}} + {{#if expectedConstraints.notValue}} + XCTAssertNotEqual([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] {{asObjectiveCNumberType "" type true}}Value], {{expectedConstraints.notValue}}); + {{/if}} + {{/if}} + {{/chip_tests_item_response_parameters}} + \ No newline at end of file diff --git a/src/darwin/Framework/CHIP/templates/partials/test_cluster.zapt b/src/darwin/Framework/CHIP/templates/partials/test_cluster.zapt index 275ff0635b0405..85c2ab459b505f 100644 --- a/src/darwin/Framework/CHIP/templates/partials/test_cluster.zapt +++ b/src/darwin/Framework/CHIP/templates/partials/test_cluster.zapt @@ -4,8 +4,7 @@ { XCTestExpectation * expectation = [self expectationWithDescription:@"{{label}}"]; {{#if (isTestOnlyCluster cluster)}} - dispatch_queue_t queue = dispatch_get_main_queue(); - {{command}}(expectation, queue{{#chip_tests_item_parameters}}, {{definedValue}}{{/chip_tests_item_parameters}}); +{{> (asTestSuiteSimulatedClusterCommandPartial command)}} {{else}} CHIPDevice * device = GetPairedDevice(kDeviceId); dispatch_queue_t queue = dispatch_get_main_queue(); @@ -29,6 +28,18 @@ {{/if}} {{#if isCommand}} [cluster {{asLowerCamelCase command}}:{{#chip_tests_item_parameters}}{{#not_first}}{{asLowerCamelCase name}}:{{/not_first}}{{asLowerCamelCase name}}Argument {{#last}}responseHandler:{{/last}}{{/chip_tests_item_parameters}}^(NSError * err, NSDictionary * values) { + {{else if isSubscribeAttribute}} + __block bool initialReportReceived = false; + [cluster reportAttribute{{asUpperCamelCase attribute}}WithResponseHandler:^(NSError * err, NSDictionary * values) { + NSLog(@"Reporting Test Report: %@", err); + XCTAssertEqual(err.code, 0); + {{> process_response_value}} + initialReportReceived = true; + }]; + + [cluster configureAttribute{{asUpperCamelCase attribute}}WithMinInterval:{{minInterval}} + maxInterval:{{maxInterval}} + responseHandler:^(NSError * err, NSDictionary * values) { {{else if isReadAttribute}} [cluster readAttribute{{asUpperCamelCase attribute}}WithResponseHandler:^(NSError * err, NSDictionary * values) { {{else if isWriteAttribute}} @@ -47,45 +58,12 @@ {{#unless (isStrEqual "0" response.error)}} [expectation fulfill]; {{else}} - {{#chip_tests_item_response_parameters}} - {{#if hasExpectedValue}} - {{#if isList}} - XCTAssertEqual([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] count], {{expectedValue.length}}); + {{#unless isSubscribeAttribute}} + {{> process_response_value}} {{else}} - {{#if (isString type)}} - {{#if (isOctetString type)}} - NSString * {{asLowerCamelCase name}}ArgumentString= @"{{expectedValue}}"; - NSData * {{asLowerCamelCase name}}Argument = [{{asLowerCamelCase name}}ArgumentString dataUsingEncoding:NSUTF8StringEncoding]; - XCTAssertTrue([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] isEqualToData:{{asLowerCamelCase name}}Argument]); - {{else}} - NSString * {{asLowerCamelCase name}}Argument= @"{{expectedValue}}"; - XCTAssertTrue([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] isEqualToString:{{asLowerCamelCase name}}Argument]); - {{/if}} - {{else}} - XCTAssertEqual([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] {{asObjectiveCNumberType "" type true}}Value], {{expectedValue}}{{asTypeLiteralSuffix}}); - {{/if}} - {{/if}} - {{/if}} - {{#if hasExpectedConstraints}} - {{#if expectedConstraints.minLength}} - XCTAssertGreaterThanOrEqual([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] length], {{expectedConstraints.minLength}}); - {{/if}} - {{#if expectedConstraints.maxLength}} - XCTAssertLessThanOrEqual([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] length], {{expectedConstraints.maxLength}}); - {{/if}} - {{#if expectedConstraints.minValue}} - XCTAssertGreaterThanOrEqual([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] {{asObjectiveCNumberType "" type true}}Value], {{expectedConstraints.minValue}}); - {{/if}} - {{#if expectedConstraints.maxValue}} - XCTAssertLessThanOrEqual([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] {{asObjectiveCNumberType "" type true}}Value], {{expectedConstraints.maxValue}}); - {{/if}} - {{#if expectedConstraints.notValue}} - XCTAssertNotEqual([values[@"{{#if parent.isReadAttribute}}value{{else}}{{name}}{{/if}}"] {{asObjectiveCNumberType "" type true}}Value], {{expectedConstraints.notValue}}); - {{/if}} - {{/if}} - {{/chip_tests_item_response_parameters}} + XCTAssertEqual(initialReportReceived, true); + {{/unless}} [expectation fulfill]; - {{/unless}} }]; diff --git a/src/darwin/Framework/CHIP/templates/partials/testsuite/WaitForAttributeReport.zapt b/src/darwin/Framework/CHIP/templates/partials/testsuite/WaitForAttributeReport.zapt new file mode 100644 index 00000000000000..33c9332063e08e --- /dev/null +++ b/src/darwin/Framework/CHIP/templates/partials/testsuite/WaitForAttributeReport.zapt @@ -0,0 +1,14 @@ +{{#chip_tests_WaitForAttributeReport_attribute_info}} + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIP{{asUpperCamelCase cluster}} * cluster = [[CHIP{{asUpperCamelCase cluster}} alloc] initWithDevice:device endpoint:{{endpoint}} queue:queue]; + XCTAssertNotNil(cluster); + + [cluster reportAttribute{{asUpperCamelCase attribute}}WithResponseHandler:^(NSError * err, NSDictionary * values) { + NSLog(@"Reporting Test Report: %@", err); + XCTAssertEqual(err.code, 0); + + {{> process_response_value}} + [expectation fulfill]; + }]; +{{/chip_tests_WaitForAttributeReport_attribute_info}} diff --git a/src/darwin/Framework/CHIP/templates/partials/testsuite/WaitForMs.zapt b/src/darwin/Framework/CHIP/templates/partials/testsuite/WaitForMs.zapt new file mode 100644 index 00000000000000..57326c64d83df6 --- /dev/null +++ b/src/darwin/Framework/CHIP/templates/partials/testsuite/WaitForMs.zapt @@ -0,0 +1,2 @@ +dispatch_queue_t queue = dispatch_get_main_queue(); +{{command}}(expectation, queue{{#chip_tests_item_parameters}}, {{definedValue}}{{/chip_tests_item_parameters}}); diff --git a/src/darwin/Framework/CHIP/templates/templates.json b/src/darwin/Framework/CHIP/templates/templates.json index 7960d62a3c8618..72b96a1fabb180 100644 --- a/src/darwin/Framework/CHIP/templates/templates.json +++ b/src/darwin/Framework/CHIP/templates/templates.json @@ -19,9 +19,21 @@ "name": "test_cluster", "path": "partials/test_cluster.zapt" }, + { + "name": "process_response_value", + "path": "partials/process_response_value.zapt" + }, { "name": "CHIPCallbackBridge", "path": "partials/CHIPCallbackBridge.zapt" + }, + { + "name": "TestSuiteHelper_WaitForMs", + "path": "partials/testsuite/WaitForMs.zapt" + }, + { + "name": "TestSuiteHelper_WaitForAttributeReport", + "path": "partials/testsuite/WaitForAttributeReport.zapt" } ], "templates": [ diff --git a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m index 2ca603e6966ca3..e249b7fedc88d6 100644 --- a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m +++ b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m @@ -160,79 +160,6 @@ - (void)testReuseChipClusterObject [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; } -- (void)testSendClusterTestCluster_Reporting_0000_BindOnOff_Test -{ - XCTestExpectation * expectation = [self expectationWithDescription:@"Binding to OnOff Cluster complete"]; - CHIPDevice * device = GetPairedDevice(kDeviceId); - dispatch_queue_t queue = dispatch_get_main_queue(); - CHIPBinding * bindingCluster = [[CHIPBinding alloc] initWithDevice:device endpoint:1 queue:queue]; - XCTAssertNotNil(bindingCluster); - [bindingCluster bind:kDeviceId - groupId:0 - endpointId:1 - clusterId:6 - responseHandler:^(NSError * err, NSDictionary * values) { - NSLog(@"Reporting Test Binding status : %@", err); - XCTAssertEqual(err.code, 0); - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; -} - -- (void)testSendClusterTestCluster_Reporting_0001_ConfigureOnOff_Test -{ - XCTestExpectation * expectation = [self expectationWithDescription:@"Reporting OnOff configured"]; - CHIPDevice * device = GetPairedDevice(kDeviceId); - dispatch_queue_t queue = dispatch_get_main_queue(); - CHIPOnOff * onOffCluster = [[CHIPOnOff alloc] initWithDevice:device endpoint:1 queue:queue]; - XCTAssertNotNil(onOffCluster); - [onOffCluster configureAttributeOnOffWithMinInterval:0 - maxInterval:1 - responseHandler:^(NSError * err, NSDictionary * values) { - NSLog(@"Reporting Test Configure status: %@", err); - - XCTAssertEqual(err.code, 0); - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; -} - -- (void)testSendClusterTestCluster_Reporting_0002_ReportOnOff_Test -{ - XCTestExpectation * expectation = [self expectationWithDescription:@"First report received"]; - CHIPDevice * device = GetPairedDevice(kDeviceId); - dispatch_queue_t queue = dispatch_get_main_queue(); - CHIPOnOff * onOffCluster = [[CHIPOnOff alloc] initWithDevice:device endpoint:1 queue:queue]; - XCTAssertNotNil(onOffCluster); - [onOffCluster reportAttributeOnOffWithResponseHandler:^(NSError * err, NSDictionary * values) { - NSLog(@"Reporting Test Report first report: %@", err); - [expectation fulfill]; - XCTAssertEqual(err.code, 0); - }]; - - [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; -} - -- (void)testSendClusterTestCluster_Reporting_0003_StopReportOnOff_Test -{ - XCTestExpectation * expectation = [self expectationWithDescription:@"Reporting OnOff cancelled"]; - CHIPDevice * device = GetPairedDevice(kDeviceId); - dispatch_queue_t queue = dispatch_get_main_queue(); - CHIPOnOff * onOffCluster = [[CHIPOnOff alloc] initWithDevice:device endpoint:1 queue:queue]; - XCTAssertNotNil(onOffCluster); - [onOffCluster configureAttributeOnOffWithMinInterval:0 - maxInterval:0xffff - responseHandler:^(NSError * err, NSDictionary * values) { - NSLog(@"Reporting Test Cancel Reports status: %@", err); - - XCTAssertEqual(err.code, 0); - [expectation fulfill]; - }]; - [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; -} - - (void)testSendClusterTestCluster_000000_Test { XCTestExpectation * expectation = [self expectationWithDescription:@"Send Test Command"]; @@ -2421,6 +2348,86 @@ - (void)testSendClusterTestDelayCommands_000000_WaitForMs [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; } +- (void)testSendClusterTestSubscribe_OnOff_000000_Off +{ + XCTestExpectation * expectation = [self expectationWithDescription:@"Set OnOff Attribute to false"]; + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPOnOff * cluster = [[CHIPOnOff alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + [cluster off:^(NSError * err, NSDictionary * values) { + NSLog(@"Set OnOff Attribute to false Error: %@", err); + + XCTAssertEqual(err.code, 0); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} +- (void)testSendClusterTestSubscribe_OnOff_000001_SubscribeAttribute +{ + XCTestExpectation * expectation = [self expectationWithDescription:@"Subscribe OnOff Attribute"]; + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPOnOff * cluster = [[CHIPOnOff alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + __block bool initialReportReceived = false; + [cluster reportAttributeOnOffWithResponseHandler:^(NSError * err, NSDictionary * values) { + NSLog(@"Reporting Test Report: %@", err); + XCTAssertEqual(err.code, 0); + XCTAssertEqual([values[@"value"] boolValue], false); + initialReportReceived = true; + }]; + + [cluster configureAttributeOnOffWithMinInterval:2 + maxInterval:10 + responseHandler:^(NSError * err, NSDictionary * values) { + NSLog(@"Subscribe OnOff Attribute Error: %@", err); + + XCTAssertEqual(err.code, 0); + XCTAssertEqual(initialReportReceived, true); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} +- (void)testSendClusterTestSubscribe_OnOff_000002_On +{ + XCTestExpectation * expectation = [self expectationWithDescription:@"Turn On the light to see attribute change"]; + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPOnOff * cluster = [[CHIPOnOff alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + [cluster on:^(NSError * err, NSDictionary * values) { + NSLog(@"Turn On the light to see attribute change Error: %@", err); + + XCTAssertEqual(err.code, 0); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} +- (void)testSendClusterTestSubscribe_OnOff_000003_WaitForAttributeReport +{ + XCTestExpectation * expectation = [self expectationWithDescription:@"Check for attribute report"]; + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPOnOff * cluster = [[CHIPOnOff alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + [cluster reportAttributeOnOffWithResponseHandler:^(NSError * err, NSDictionary * values) { + NSLog(@"Reporting Test Report: %@", err); + XCTAssertEqual(err.code, 0); + + XCTAssertEqual([values[@"value"] boolValue], true); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} + - (void)testSendClusterTest_TC_OO_1_1_000000_ReadAttribute { XCTestExpectation * expectation = [self expectationWithDescription:@"read the global attribute: ClusterRevision"]; diff --git a/src/lib/core/CHIPConfig.h b/src/lib/core/CHIPConfig.h index b0efc02a376ceb..6b2169096f0142 100644 --- a/src/lib/core/CHIPConfig.h +++ b/src/lib/core/CHIPConfig.h @@ -2428,7 +2428,7 @@ extern const char CHIP_NON_PRODUCTION_MARKER[]; * @brief Defines the maximum number of path objects, limits the number of attributes being read or subscribed at the same time. */ #ifndef CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS -#define CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS 4 +#define CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS 8 #endif /** @@ -2449,6 +2449,15 @@ extern const char CHIP_NON_PRODUCTION_MARKER[]; #define CHIP_IM_MAX_NUM_WRITE_CLIENT 4 #endif +/** + * @def CHIP_DEVICE_CONTROLLER_SUBSCRIPTION_ATTRIBUTE_PATH_POOL_SIZE + * + * @brief Defines the object pool for allocating attribute path for subscription in device controller. + */ +#ifndef CHIP_DEVICE_CONTROLLER_SUBSCRIPTION_ATTRIBUTE_PATH_POOL_SIZE +#define CHIP_DEVICE_CONTROLLER_SUBSCRIPTION_ATTRIBUTE_PATH_POOL_SIZE CHIP_IM_MAX_NUM_READ_CLIENT +#endif + /** * @} */ diff --git a/zzz_generated/chip-tool/zap-generated/reporting/Commands.h b/zzz_generated/chip-tool/zap-generated/reporting/Commands.h index 25c0a5d7f519d4..2728c84b7e5c10 100644 --- a/zzz_generated/chip-tool/zap-generated/reporting/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/reporting/Commands.h @@ -61,55 +61,78 @@ class Listen : public ReportingCommand { chip::app::CHIPDeviceCallbacksMgr & callbacksMgr = chip::app::CHIPDeviceCallbacksMgr::GetInstance(); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x000F, 0x0055, - onReportBinaryInputBasicPresentValueCallback->Cancel()); + onReportBinaryInputBasicPresentValueCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x000F, 0x006F, - onReportBinaryInputBasicStatusFlagsCallback->Cancel()); + onReportBinaryInputBasicStatusFlagsCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0300, 0x0000, - onReportColorControlCurrentHueCallback->Cancel()); + onReportColorControlCurrentHueCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0300, 0x0001, - onReportColorControlCurrentSaturationCallback->Cancel()); + onReportColorControlCurrentSaturationCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0300, 0x0003, - onReportColorControlCurrentXCallback->Cancel()); + onReportColorControlCurrentXCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0300, 0x0004, - onReportColorControlCurrentYCallback->Cancel()); + onReportColorControlCurrentYCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0300, 0x0007, - onReportColorControlColorTemperatureCallback->Cancel()); + onReportColorControlColorTemperatureCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0101, 0x0000, - onReportDoorLockLockStateCallback->Cancel()); + onReportDoorLockLockStateCallback->Cancel(), BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0008, 0x0000, - onReportLevelControlCurrentLevelCallback->Cancel()); + onReportLevelControlCurrentLevelCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0406, 0x0000, - onReportOccupancySensingOccupancyCallback->Cancel()); + onReportOccupancySensingOccupancyCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0006, 0x0000, - onReportOnOffOnOffCallback->Cancel()); + onReportOnOffOnOffCallback->Cancel(), BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0403, 0x0000, - onReportPressureMeasurementMeasuredValueCallback->Cancel()); + onReportPressureMeasurementMeasuredValueCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0200, 0x0013, - onReportPumpConfigurationAndControlCapacityCallback->Cancel()); + onReportPumpConfigurationAndControlCapacityCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0405, 0x0000, - onReportRelativeHumidityMeasurementMeasuredValueCallback->Cancel()); + onReportRelativeHumidityMeasurementMeasuredValueCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x003B, 0x0001, - onReportSwitchCurrentPositionCallback->Cancel()); + onReportSwitchCurrentPositionCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0402, 0x0000, - onReportTemperatureMeasurementMeasuredValueCallback->Cancel()); + onReportTemperatureMeasurementMeasuredValueCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0201, 0x0000, - onReportThermostatLocalTemperatureCallback->Cancel()); + onReportThermostatLocalTemperatureCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0102, 0x0008, - onReportWindowCoveringCurrentPositionLiftPercentageCallback->Cancel()); + onReportWindowCoveringCurrentPositionLiftPercentageCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0102, 0x0009, - onReportWindowCoveringCurrentPositionTiltPercentageCallback->Cancel()); + onReportWindowCoveringCurrentPositionTiltPercentageCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0102, 0x000A, - onReportWindowCoveringOperationalStatusCallback->Cancel()); + onReportWindowCoveringOperationalStatusCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0102, 0x000B, - onReportWindowCoveringTargetPositionLiftPercent100thsCallback->Cancel()); + onReportWindowCoveringTargetPositionLiftPercent100thsCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0102, 0x000C, - onReportWindowCoveringTargetPositionTiltPercent100thsCallback->Cancel()); + onReportWindowCoveringTargetPositionTiltPercent100thsCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0102, 0x000E, - onReportWindowCoveringCurrentPositionLiftPercent100thsCallback->Cancel()); + onReportWindowCoveringCurrentPositionLiftPercent100thsCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0102, 0x000F, - onReportWindowCoveringCurrentPositionTiltPercent100thsCallback->Cancel()); + onReportWindowCoveringCurrentPositionTiltPercent100thsCallback->Cancel(), + BasicAttributeFilter); callbacksMgr.AddReportCallback(GetExecContext()->storage->GetRemoteNodeId(), endpointId, 0x0102, 0x001A, - onReportWindowCoveringSafetyStatusCallback->Cancel()); + onReportWindowCoveringSafetyStatusCallback->Cancel(), + BasicAttributeFilter); } static void OnDefaultSuccessResponse(void * context) { ChipLogProgress(chipTool, "Default Success Response"); } diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index 6ada916ed52cad..616105d61766f7 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -74,6 +74,7 @@ class TV_TargetNavigatorCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterTargetNavigatorCommandReadAttribute_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterTargetNavigatorCommandReadAttribute_0() @@ -139,6 +140,7 @@ class TV_TargetNavigatorCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterTargetNavigatorCommandNavigateTarget_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterTargetNavigatorCommandNavigateTarget_1() @@ -247,6 +249,7 @@ class TV_AudioOutputCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterAudioOutputCommandReadAttribute_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterAudioOutputCommandReadAttribute_0() @@ -311,6 +314,7 @@ class TV_AudioOutputCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterAudioOutputCommandSelectOutput_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterAudioOutputCommandSelectOutput_1() @@ -368,6 +372,7 @@ class TV_AudioOutputCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterAudioOutputCommandRenameOutput_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterAudioOutputCommandRenameOutput_2() @@ -478,6 +483,7 @@ class TV_ApplicationLauncherCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterApplicationLauncherCommandReadAttribute_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterApplicationLauncherCommandReadAttribute_0() @@ -542,6 +548,7 @@ class TV_ApplicationLauncherCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterApplicationLauncherCommandLaunchApp_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterApplicationLauncherCommandLaunchApp_1() @@ -603,6 +610,7 @@ class TV_ApplicationLauncherCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterApplicationLauncherCommandReadAttribute_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterApplicationLauncherCommandReadAttribute_2() @@ -666,6 +674,7 @@ class TV_ApplicationLauncherCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_3{ OnTestSendClusterApplicationLauncherCommandReadAttribute_3_FailureResponse, this }; + bool mIsFailureExpected_3 = 0; CHIP_ERROR TestSendClusterApplicationLauncherCommandReadAttribute_3() @@ -771,6 +780,7 @@ class TV_KeypadInputCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterKeypadInputCommandSendKey_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterKeypadInputCommandSendKey_0() @@ -874,6 +884,7 @@ class TV_AccountLoginCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterAccountLoginCommandGetSetupPIN_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterAccountLoginCommandGetSetupPIN_0() @@ -930,6 +941,7 @@ class TV_AccountLoginCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterAccountLoginCommandLogin_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterAccountLoginCommandLogin_1() @@ -1032,6 +1044,7 @@ class TV_WakeOnLanCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterWakeOnLanCommandReadAttribute_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterWakeOnLanCommandReadAttribute_0() @@ -1149,6 +1162,7 @@ class TV_ApplicationBasicCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterApplicationBasicCommandChangeStatus_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterApplicationBasicCommandChangeStatus_0() @@ -1206,6 +1220,7 @@ class TV_ApplicationBasicCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterApplicationBasicCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterApplicationBasicCommandReadAttribute_1() @@ -1269,6 +1284,7 @@ class TV_ApplicationBasicCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterApplicationBasicCommandReadAttribute_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterApplicationBasicCommandReadAttribute_2() @@ -1332,6 +1348,7 @@ class TV_ApplicationBasicCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_3{ OnTestSendClusterApplicationBasicCommandReadAttribute_3_FailureResponse, this }; + bool mIsFailureExpected_3 = 0; CHIP_ERROR TestSendClusterApplicationBasicCommandReadAttribute_3() @@ -1468,6 +1485,7 @@ class TV_MediaPlaybackCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterMediaPlaybackCommandMediaPlay_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaPlay_0() @@ -1531,6 +1549,7 @@ class TV_MediaPlaybackCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterMediaPlaybackCommandMediaPause_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaPause_1() @@ -1594,6 +1613,7 @@ class TV_MediaPlaybackCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterMediaPlaybackCommandMediaStop_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaStop_2() @@ -1657,6 +1677,7 @@ class TV_MediaPlaybackCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_3{ OnTestSendClusterMediaPlaybackCommandMediaStartOver_3_FailureResponse, this }; + bool mIsFailureExpected_3 = 0; CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaStartOver_3() @@ -1720,6 +1741,7 @@ class TV_MediaPlaybackCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_4{ OnTestSendClusterMediaPlaybackCommandMediaPrevious_4_FailureResponse, this }; + bool mIsFailureExpected_4 = 0; CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaPrevious_4() @@ -1783,6 +1805,7 @@ class TV_MediaPlaybackCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_5{ OnTestSendClusterMediaPlaybackCommandMediaNext_5_FailureResponse, this }; + bool mIsFailureExpected_5 = 0; CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaNext_5() @@ -1846,6 +1869,7 @@ class TV_MediaPlaybackCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_6{ OnTestSendClusterMediaPlaybackCommandMediaRewind_6_FailureResponse, this }; + bool mIsFailureExpected_6 = 0; CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaRewind_6() @@ -1909,6 +1933,7 @@ class TV_MediaPlaybackCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_7{ OnTestSendClusterMediaPlaybackCommandMediaFastForward_7_FailureResponse, this }; + bool mIsFailureExpected_7 = 0; CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaFastForward_7() @@ -1972,6 +1997,7 @@ class TV_MediaPlaybackCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_8{ OnTestSendClusterMediaPlaybackCommandMediaSkipForward_8_FailureResponse, this }; + bool mIsFailureExpected_8 = 0; CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaSkipForward_8() @@ -2037,6 +2063,7 @@ class TV_MediaPlaybackCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_9{ OnTestSendClusterMediaPlaybackCommandMediaSkipBackward_9_FailureResponse, this }; + bool mIsFailureExpected_9 = 0; CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaSkipBackward_9() @@ -2103,6 +2130,7 @@ class TV_MediaPlaybackCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_10{ OnTestSendClusterMediaPlaybackCommandMediaSeek_10_FailureResponse, this }; + bool mIsFailureExpected_10 = 0; CHIP_ERROR TestSendClusterMediaPlaybackCommandMediaSeek_10() @@ -2216,6 +2244,7 @@ class TV_TvChannelCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterTvChannelCommandReadAttribute_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterTvChannelCommandReadAttribute_0() @@ -2280,6 +2309,7 @@ class TV_TvChannelCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterTvChannelCommandChangeChannelByNumber_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterTvChannelCommandChangeChannelByNumber_1() @@ -2339,6 +2369,7 @@ class TV_TvChannelCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterTvChannelCommandSkipChannel_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterTvChannelCommandSkipChannel_2() @@ -2437,6 +2468,7 @@ class TV_LowPowerCluster : public TestCommand this }; chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterLowPowerCommandSleep_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterLowPowerCommandSleep_0() @@ -2551,6 +2583,7 @@ class TV_MediaInputCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterMediaInputCommandReadAttribute_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterMediaInputCommandReadAttribute_0() @@ -2615,6 +2648,7 @@ class TV_MediaInputCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterMediaInputCommandSelectInput_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterMediaInputCommandSelectInput_1() @@ -2672,6 +2706,7 @@ class TV_MediaInputCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterMediaInputCommandReadAttribute_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterMediaInputCommandReadAttribute_2() @@ -2735,6 +2770,7 @@ class TV_MediaInputCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_3{ OnTestSendClusterMediaInputCommandHideInputStatus_3_FailureResponse, this }; + bool mIsFailureExpected_3 = 0; CHIP_ERROR TestSendClusterMediaInputCommandHideInputStatus_3() @@ -2791,6 +2827,7 @@ class TV_MediaInputCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_4{ OnTestSendClusterMediaInputCommandShowInputStatus_4_FailureResponse, this }; + bool mIsFailureExpected_4 = 0; CHIP_ERROR TestSendClusterMediaInputCommandShowInputStatus_4() @@ -2847,6 +2884,7 @@ class TV_MediaInputCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_5{ OnTestSendClusterMediaInputCommandRenameInput_5_FailureResponse, this }; + bool mIsFailureExpected_5 = 0; CHIP_ERROR TestSendClusterMediaInputCommandRenameInput_5() @@ -3280,6 +3318,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterTestClusterCommandTest_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterTestClusterCommandTest_0() @@ -3336,6 +3375,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterTestClusterCommandTestNotHandled_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 1; CHIP_ERROR TestSendClusterTestClusterCommandTestNotHandled_1() @@ -3392,6 +3432,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterTestClusterCommandTestSpecific_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterTestClusterCommandTestSpecific_2() @@ -3455,6 +3496,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_3{ OnTestSendClusterTestClusterCommandTestAddArguments_3_FailureResponse, this }; + bool mIsFailureExpected_3 = 0; CHIP_ERROR TestSendClusterTestClusterCommandTestAddArguments_3() @@ -3520,6 +3562,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_4{ OnTestSendClusterTestClusterCommandTestAddArguments_4_FailureResponse, this }; + bool mIsFailureExpected_4 = 1; CHIP_ERROR TestSendClusterTestClusterCommandTestAddArguments_4() @@ -3578,6 +3621,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_5{ OnTestSendClusterTestClusterCommandReadAttribute_5_FailureResponse, this }; + bool mIsFailureExpected_5 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_5() @@ -3641,6 +3685,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_6{ OnTestSendClusterTestClusterCommandWriteAttribute_6_FailureResponse, this }; + bool mIsFailureExpected_6 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_6() @@ -3698,6 +3743,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_7{ OnTestSendClusterTestClusterCommandReadAttribute_7_FailureResponse, this }; + bool mIsFailureExpected_7 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_7() @@ -3761,6 +3807,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_8{ OnTestSendClusterTestClusterCommandWriteAttribute_8_FailureResponse, this }; + bool mIsFailureExpected_8 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_8() @@ -3818,6 +3865,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_9{ OnTestSendClusterTestClusterCommandReadAttribute_9_FailureResponse, this }; + bool mIsFailureExpected_9 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_9() @@ -3881,6 +3929,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_10{ OnTestSendClusterTestClusterCommandReadAttribute_10_FailureResponse, this }; + bool mIsFailureExpected_10 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_10() @@ -3944,6 +3993,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_11{ OnTestSendClusterTestClusterCommandWriteAttribute_11_FailureResponse, this }; + bool mIsFailureExpected_11 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_11() @@ -4001,6 +4051,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_12{ OnTestSendClusterTestClusterCommandReadAttribute_12_FailureResponse, this }; + bool mIsFailureExpected_12 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_12() @@ -4064,6 +4115,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_13{ OnTestSendClusterTestClusterCommandWriteAttribute_13_FailureResponse, this }; + bool mIsFailureExpected_13 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_13() @@ -4121,6 +4173,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_14{ OnTestSendClusterTestClusterCommandReadAttribute_14_FailureResponse, this }; + bool mIsFailureExpected_14 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_14() @@ -4184,6 +4237,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_15{ OnTestSendClusterTestClusterCommandReadAttribute_15_FailureResponse, this }; + bool mIsFailureExpected_15 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_15() @@ -4247,6 +4301,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_16{ OnTestSendClusterTestClusterCommandWriteAttribute_16_FailureResponse, this }; + bool mIsFailureExpected_16 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_16() @@ -4304,6 +4359,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_17{ OnTestSendClusterTestClusterCommandReadAttribute_17_FailureResponse, this }; + bool mIsFailureExpected_17 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_17() @@ -4367,6 +4423,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_18{ OnTestSendClusterTestClusterCommandWriteAttribute_18_FailureResponse, this }; + bool mIsFailureExpected_18 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_18() @@ -4424,6 +4481,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_19{ OnTestSendClusterTestClusterCommandReadAttribute_19_FailureResponse, this }; + bool mIsFailureExpected_19 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_19() @@ -4487,6 +4545,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_20{ OnTestSendClusterTestClusterCommandReadAttribute_20_FailureResponse, this }; + bool mIsFailureExpected_20 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_20() @@ -4550,6 +4609,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_21{ OnTestSendClusterTestClusterCommandWriteAttribute_21_FailureResponse, this }; + bool mIsFailureExpected_21 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_21() @@ -4607,6 +4667,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_22{ OnTestSendClusterTestClusterCommandReadAttribute_22_FailureResponse, this }; + bool mIsFailureExpected_22 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_22() @@ -4670,6 +4731,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_23{ OnTestSendClusterTestClusterCommandWriteAttribute_23_FailureResponse, this }; + bool mIsFailureExpected_23 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_23() @@ -4727,6 +4789,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_24{ OnTestSendClusterTestClusterCommandReadAttribute_24_FailureResponse, this }; + bool mIsFailureExpected_24 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_24() @@ -4790,6 +4853,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_25{ OnTestSendClusterTestClusterCommandReadAttribute_25_FailureResponse, this }; + bool mIsFailureExpected_25 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_25() @@ -4853,6 +4917,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_26{ OnTestSendClusterTestClusterCommandWriteAttribute_26_FailureResponse, this }; + bool mIsFailureExpected_26 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_26() @@ -4910,6 +4975,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_27{ OnTestSendClusterTestClusterCommandReadAttribute_27_FailureResponse, this }; + bool mIsFailureExpected_27 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_27() @@ -4973,6 +5039,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_28{ OnTestSendClusterTestClusterCommandWriteAttribute_28_FailureResponse, this }; + bool mIsFailureExpected_28 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_28() @@ -5030,6 +5097,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_29{ OnTestSendClusterTestClusterCommandReadAttribute_29_FailureResponse, this }; + bool mIsFailureExpected_29 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_29() @@ -5093,6 +5161,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_30{ OnTestSendClusterTestClusterCommandReadAttribute_30_FailureResponse, this }; + bool mIsFailureExpected_30 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_30() @@ -5156,6 +5225,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_31{ OnTestSendClusterTestClusterCommandWriteAttribute_31_FailureResponse, this }; + bool mIsFailureExpected_31 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_31() @@ -5213,6 +5283,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_32{ OnTestSendClusterTestClusterCommandReadAttribute_32_FailureResponse, this }; + bool mIsFailureExpected_32 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_32() @@ -5276,6 +5347,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_33{ OnTestSendClusterTestClusterCommandWriteAttribute_33_FailureResponse, this }; + bool mIsFailureExpected_33 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_33() @@ -5333,6 +5405,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_34{ OnTestSendClusterTestClusterCommandReadAttribute_34_FailureResponse, this }; + bool mIsFailureExpected_34 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_34() @@ -5396,6 +5469,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_35{ OnTestSendClusterTestClusterCommandReadAttribute_35_FailureResponse, this }; + bool mIsFailureExpected_35 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_35() @@ -5459,6 +5533,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_36{ OnTestSendClusterTestClusterCommandWriteAttribute_36_FailureResponse, this }; + bool mIsFailureExpected_36 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_36() @@ -5516,6 +5591,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_37{ OnTestSendClusterTestClusterCommandReadAttribute_37_FailureResponse, this }; + bool mIsFailureExpected_37 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_37() @@ -5579,6 +5655,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_38{ OnTestSendClusterTestClusterCommandWriteAttribute_38_FailureResponse, this }; + bool mIsFailureExpected_38 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_38() @@ -5636,6 +5713,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_39{ OnTestSendClusterTestClusterCommandReadAttribute_39_FailureResponse, this }; + bool mIsFailureExpected_39 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_39() @@ -5699,6 +5777,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_40{ OnTestSendClusterTestClusterCommandReadAttribute_40_FailureResponse, this }; + bool mIsFailureExpected_40 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_40() @@ -5762,6 +5841,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_41{ OnTestSendClusterTestClusterCommandWriteAttribute_41_FailureResponse, this }; + bool mIsFailureExpected_41 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_41() @@ -5819,6 +5899,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_42{ OnTestSendClusterTestClusterCommandReadAttribute_42_FailureResponse, this }; + bool mIsFailureExpected_42 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_42() @@ -5882,6 +5963,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_43{ OnTestSendClusterTestClusterCommandWriteAttribute_43_FailureResponse, this }; + bool mIsFailureExpected_43 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_43() @@ -5939,6 +6021,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_44{ OnTestSendClusterTestClusterCommandReadAttribute_44_FailureResponse, this }; + bool mIsFailureExpected_44 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_44() @@ -6002,6 +6085,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_45{ OnTestSendClusterTestClusterCommandReadAttribute_45_FailureResponse, this }; + bool mIsFailureExpected_45 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_45() @@ -6065,6 +6149,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_46{ OnTestSendClusterTestClusterCommandWriteAttribute_46_FailureResponse, this }; + bool mIsFailureExpected_46 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_46() @@ -6122,6 +6207,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_47{ OnTestSendClusterTestClusterCommandReadAttribute_47_FailureResponse, this }; + bool mIsFailureExpected_47 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_47() @@ -6185,6 +6271,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_48{ OnTestSendClusterTestClusterCommandWriteAttribute_48_FailureResponse, this }; + bool mIsFailureExpected_48 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_48() @@ -6242,6 +6329,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_49{ OnTestSendClusterTestClusterCommandReadAttribute_49_FailureResponse, this }; + bool mIsFailureExpected_49 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_49() @@ -6305,6 +6393,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_50{ OnTestSendClusterTestClusterCommandReadAttribute_50_FailureResponse, this }; + bool mIsFailureExpected_50 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_50() @@ -6368,6 +6457,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_51{ OnTestSendClusterTestClusterCommandWriteAttribute_51_FailureResponse, this }; + bool mIsFailureExpected_51 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_51() @@ -6425,6 +6515,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_52{ OnTestSendClusterTestClusterCommandReadAttribute_52_FailureResponse, this }; + bool mIsFailureExpected_52 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_52() @@ -6488,6 +6579,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_53{ OnTestSendClusterTestClusterCommandWriteAttribute_53_FailureResponse, this }; + bool mIsFailureExpected_53 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_53() @@ -6545,6 +6637,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_54{ OnTestSendClusterTestClusterCommandReadAttribute_54_FailureResponse, this }; + bool mIsFailureExpected_54 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_54() @@ -6608,6 +6701,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_55{ OnTestSendClusterTestClusterCommandWriteAttribute_55_FailureResponse, this }; + bool mIsFailureExpected_55 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_55() @@ -6665,6 +6759,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_56{ OnTestSendClusterTestClusterCommandReadAttribute_56_FailureResponse, this }; + bool mIsFailureExpected_56 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_56() @@ -6728,6 +6823,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_57{ OnTestSendClusterTestClusterCommandReadAttribute_57_FailureResponse, this }; + bool mIsFailureExpected_57 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_57() @@ -6791,6 +6887,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_58{ OnTestSendClusterTestClusterCommandWriteAttribute_58_FailureResponse, this }; + bool mIsFailureExpected_58 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_58() @@ -6848,6 +6945,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_59{ OnTestSendClusterTestClusterCommandReadAttribute_59_FailureResponse, this }; + bool mIsFailureExpected_59 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_59() @@ -6911,6 +7009,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_60{ OnTestSendClusterTestClusterCommandWriteAttribute_60_FailureResponse, this }; + bool mIsFailureExpected_60 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_60() @@ -6968,6 +7067,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_61{ OnTestSendClusterTestClusterCommandReadAttribute_61_FailureResponse, this }; + bool mIsFailureExpected_61 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_61() @@ -7031,6 +7131,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_62{ OnTestSendClusterTestClusterCommandWriteAttribute_62_FailureResponse, this }; + bool mIsFailureExpected_62 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_62() @@ -7088,6 +7189,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_63{ OnTestSendClusterTestClusterCommandReadAttribute_63_FailureResponse, this }; + bool mIsFailureExpected_63 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_63() @@ -7151,6 +7253,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_64{ OnTestSendClusterTestClusterCommandReadAttribute_64_FailureResponse, this }; + bool mIsFailureExpected_64 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_64() @@ -7214,6 +7317,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_65{ OnTestSendClusterTestClusterCommandWriteAttribute_65_FailureResponse, this }; + bool mIsFailureExpected_65 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_65() @@ -7271,6 +7375,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_66{ OnTestSendClusterTestClusterCommandReadAttribute_66_FailureResponse, this }; + bool mIsFailureExpected_66 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_66() @@ -7334,6 +7439,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_67{ OnTestSendClusterTestClusterCommandWriteAttribute_67_FailureResponse, this }; + bool mIsFailureExpected_67 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_67() @@ -7391,6 +7497,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_68{ OnTestSendClusterTestClusterCommandReadAttribute_68_FailureResponse, this }; + bool mIsFailureExpected_68 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_68() @@ -7454,6 +7561,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_69{ OnTestSendClusterTestClusterCommandWriteAttribute_69_FailureResponse, this }; + bool mIsFailureExpected_69 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_69() @@ -7511,6 +7619,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_70{ OnTestSendClusterTestClusterCommandReadAttribute_70_FailureResponse, this }; + bool mIsFailureExpected_70 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_70() @@ -7574,6 +7683,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_71{ OnTestSendClusterTestClusterCommandReadAttribute_71_FailureResponse, this }; + bool mIsFailureExpected_71 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_71() @@ -7637,6 +7747,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_72{ OnTestSendClusterTestClusterCommandWriteAttribute_72_FailureResponse, this }; + bool mIsFailureExpected_72 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_72() @@ -7694,6 +7805,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_73{ OnTestSendClusterTestClusterCommandReadAttribute_73_FailureResponse, this }; + bool mIsFailureExpected_73 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_73() @@ -7757,6 +7869,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_74{ OnTestSendClusterTestClusterCommandWriteAttribute_74_FailureResponse, this }; + bool mIsFailureExpected_74 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_74() @@ -7814,6 +7927,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_75{ OnTestSendClusterTestClusterCommandReadAttribute_75_FailureResponse, this }; + bool mIsFailureExpected_75 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_75() @@ -7877,6 +7991,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_76{ OnTestSendClusterTestClusterCommandWriteAttribute_76_FailureResponse, this }; + bool mIsFailureExpected_76 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_76() @@ -7934,6 +8049,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_77{ OnTestSendClusterTestClusterCommandReadAttribute_77_FailureResponse, this }; + bool mIsFailureExpected_77 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_77() @@ -7997,6 +8113,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_78{ OnTestSendClusterTestClusterCommandReadAttribute_78_FailureResponse, this }; + bool mIsFailureExpected_78 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_78() @@ -8060,6 +8177,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_79{ OnTestSendClusterTestClusterCommandWriteAttribute_79_FailureResponse, this }; + bool mIsFailureExpected_79 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_79() @@ -8117,6 +8235,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_80{ OnTestSendClusterTestClusterCommandReadAttribute_80_FailureResponse, this }; + bool mIsFailureExpected_80 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_80() @@ -8180,6 +8299,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_81{ OnTestSendClusterTestClusterCommandWriteAttribute_81_FailureResponse, this }; + bool mIsFailureExpected_81 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_81() @@ -8237,6 +8357,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_82{ OnTestSendClusterTestClusterCommandReadAttribute_82_FailureResponse, this }; + bool mIsFailureExpected_82 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_82() @@ -8300,6 +8421,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_83{ OnTestSendClusterTestClusterCommandReadAttribute_83_FailureResponse, this }; + bool mIsFailureExpected_83 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_83() @@ -8363,6 +8485,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_84{ OnTestSendClusterTestClusterCommandWriteAttribute_84_FailureResponse, this }; + bool mIsFailureExpected_84 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_84() @@ -8420,6 +8543,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_85{ OnTestSendClusterTestClusterCommandReadAttribute_85_FailureResponse, this }; + bool mIsFailureExpected_85 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_85() @@ -8483,6 +8607,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_86{ OnTestSendClusterTestClusterCommandWriteAttribute_86_FailureResponse, this }; + bool mIsFailureExpected_86 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_86() @@ -8540,6 +8665,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_87{ OnTestSendClusterTestClusterCommandReadAttribute_87_FailureResponse, this }; + bool mIsFailureExpected_87 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_87() @@ -8603,6 +8729,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_88{ OnTestSendClusterTestClusterCommandReadAttribute_88_FailureResponse, this }; + bool mIsFailureExpected_88 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_88() @@ -8667,6 +8794,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_89{ OnTestSendClusterTestClusterCommandWriteAttribute_89_FailureResponse, this }; + bool mIsFailureExpected_89 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_89() @@ -8725,6 +8853,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_90{ OnTestSendClusterTestClusterCommandReadAttribute_90_FailureResponse, this }; + bool mIsFailureExpected_90 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_90() @@ -8789,6 +8918,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_91{ OnTestSendClusterTestClusterCommandWriteAttribute_91_FailureResponse, this }; + bool mIsFailureExpected_91 = true; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_91() @@ -8848,6 +8978,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_92{ OnTestSendClusterTestClusterCommandReadAttribute_92_FailureResponse, this }; + bool mIsFailureExpected_92 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_92() @@ -8912,6 +9043,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_93{ OnTestSendClusterTestClusterCommandWriteAttribute_93_FailureResponse, this }; + bool mIsFailureExpected_93 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_93() @@ -8970,6 +9102,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_94{ OnTestSendClusterTestClusterCommandReadAttribute_94_FailureResponse, this }; + bool mIsFailureExpected_94 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_94() @@ -9034,6 +9167,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_95{ OnTestSendClusterTestClusterCommandWriteAttribute_95_FailureResponse, this }; + bool mIsFailureExpected_95 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_95() @@ -9099,6 +9233,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_96{ OnTestSendClusterTestClusterCommandReadAttribute_96_FailureResponse, this }; + bool mIsFailureExpected_96 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_96() @@ -9173,6 +9308,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_97{ OnTestSendClusterTestClusterCommandWriteAttribute_97_FailureResponse, this }; + bool mIsFailureExpected_97 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_97() @@ -9231,6 +9367,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_98{ OnTestSendClusterTestClusterCommandReadAttribute_98_FailureResponse, this }; + bool mIsFailureExpected_98 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_98() @@ -9295,6 +9432,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_99{ OnTestSendClusterTestClusterCommandWriteAttribute_99_FailureResponse, this }; + bool mIsFailureExpected_99 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_99() @@ -9352,6 +9490,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_100{ OnTestSendClusterTestClusterCommandWriteAttribute_100_FailureResponse, this }; + bool mIsFailureExpected_100 = true; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_100() @@ -9411,6 +9550,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_101{ OnTestSendClusterTestClusterCommandWriteAttribute_101_FailureResponse, this }; + bool mIsFailureExpected_101 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_101() @@ -9469,6 +9609,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_102{ OnTestSendClusterTestClusterCommandReadAttribute_102_FailureResponse, this }; + bool mIsFailureExpected_102 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_102() @@ -9533,6 +9674,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_103{ OnTestSendClusterTestClusterCommandWriteAttribute_103_FailureResponse, this }; + bool mIsFailureExpected_103 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_103() @@ -9598,6 +9740,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_104{ OnTestSendClusterTestClusterCommandReadAttribute_104_FailureResponse, this }; + bool mIsFailureExpected_104 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_104() @@ -9672,6 +9815,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_105{ OnTestSendClusterTestClusterCommandWriteAttribute_105_FailureResponse, this }; + bool mIsFailureExpected_105 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_105() @@ -9730,6 +9874,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_106{ OnTestSendClusterTestClusterCommandReadAttribute_106_FailureResponse, this }; + bool mIsFailureExpected_106 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_106() @@ -9794,6 +9939,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_107{ OnTestSendClusterTestClusterCommandReadAttribute_107_FailureResponse, this }; + bool mIsFailureExpected_107 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_107() @@ -9858,6 +10004,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_108{ OnTestSendClusterTestClusterCommandReadAttribute_108_FailureResponse, this }; + bool mIsFailureExpected_108 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_108() @@ -9923,6 +10070,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_109{ OnTestSendClusterTestClusterCommandReadAttribute_109_FailureResponse, this }; + bool mIsFailureExpected_109 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_109() @@ -9992,6 +10140,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_110{ OnTestSendClusterTestClusterCommandWriteAttribute_110_FailureResponse, this }; + bool mIsFailureExpected_110 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_110() @@ -10056,6 +10205,7 @@ class TestCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_111{ OnTestSendClusterTestClusterCommandTest_111_FailureResponse, this }; + bool mIsFailureExpected_111 = 1; CHIP_ERROR TestSendClusterTestClusterCommandTest_111() @@ -10164,6 +10314,7 @@ class TestConstraints : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterTestClusterCommandWriteAttribute_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterTestClusterCommandWriteAttribute_0() @@ -10221,6 +10372,7 @@ class TestConstraints : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterTestClusterCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_1() @@ -10284,6 +10436,7 @@ class TestConstraints : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterTestClusterCommandReadAttribute_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_2() @@ -10347,6 +10500,7 @@ class TestConstraints : public TestCommand chip::Callback::Callback mOnFailureCallback_3{ OnTestSendClusterTestClusterCommandReadAttribute_3_FailureResponse, this }; + bool mIsFailureExpected_3 = 0; CHIP_ERROR TestSendClusterTestClusterCommandReadAttribute_3() @@ -10426,7 +10580,7 @@ class TestDelayCommands : public TestCommand switch (mTestIndex++) { case 0: - err = TestSendClusterDelayCommandsCommandWaitForMs_0(); + err = TestSendClusterTestSuiteCommandWaitForMs_0(); break; } @@ -10445,14 +10599,293 @@ class TestDelayCommands : public TestCommand // Tests methods // - CHIP_ERROR TestSendClusterDelayCommandsCommandWaitForMs_0() + CHIP_ERROR TestSendClusterTestSuiteCommandWaitForMs_0() { - ChipLogProgress(chipTool, "DelayCommands - Wait 100ms"); + ChipLogProgress(chipTool, "TestSuite - WaitForMs - Wait 100ms"); return WaitForMs(100); } }; +class TestSubscribe_OnOff : public TestCommand +{ +public: + TestSubscribe_OnOff() : TestCommand("TestSubscribe_OnOff"), mTestIndex(0) {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mTestCount == mTestIndex) + { + ChipLogProgress(chipTool, "TestSubscribe_OnOff: Test complete"); + SetCommandExitStatus(CHIP_NO_ERROR); + } + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) + { + case 0: + err = TestSendClusterOnOffCommandOff_0(); + break; + case 1: + err = TestSendClusterOnOffCommandSubscribeAttribute_1(); + break; + case 2: + err = TestSendClusterOnOffCommandOn_2(); + break; + case 3: + err = TestSendClusterTestSuiteCommandWaitForAttributeReport_3(); + break; + } + + if (CHIP_NO_ERROR != err) + { + ChipLogProgress(chipTool, "TestSubscribe_OnOff: %s", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 4; + + // + // Tests methods + // + + // Test Set OnOff Attribute to false + using SuccessCallback_0 = void (*)(void * context); + chip::Callback::Callback mOnSuccessCallback_0{ OnTestSendClusterOnOffCommandOff_0_SuccessResponse, this }; + chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterOnOffCommandOff_0_FailureResponse, + this }; + + bool mIsFailureExpected_0 = 0; + + CHIP_ERROR TestSendClusterOnOffCommandOff_0() + { + ChipLogProgress(chipTool, "On/Off - Set OnOff Attribute to false: Sending command..."); + + chip::Controller::OnOffCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.Off(mOnSuccessCallback_0.Cancel(), mOnFailureCallback_0.Cancel()); + + return err; + } + + static void OnTestSendClusterOnOffCommandOff_0_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "On/Off - Set OnOff Attribute to false: Failure Response"); + + TestSubscribe_OnOff * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_0 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterOnOffCommandOff_0_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "On/Off - Set OnOff Attribute to false: Success Response"); + + TestSubscribe_OnOff * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_0 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // Test Subscribe OnOff Attribute + using SuccessCallback_1 = void (*)(void * context, bool onOff); + chip::Callback::Callback mOnSuccessCallback_1{ + OnTestSendClusterOnOffCommandSubscribeAttribute_1_SuccessResponse, this + }; + chip::Callback::Callback mOnFailureCallback_1{ + OnTestSendClusterOnOffCommandSubscribeAttribute_1_FailureResponse, this + }; + chip::Callback::Callback mOnSubscriptionEstablishedCallback_1{ + SubscribeAttribute_1_OnSubscriptionEstablishedCallback, this + }; + + bool mIsFailureExpected_1 = 0; + + bool mReceivedReport_1 = false; + + CHIP_ERROR TestSendClusterOnOffCommandSubscribeAttribute_1() + { + ChipLogProgress(chipTool, "On/Off - Subscribe OnOff Attribute: Sending command..."); + + chip::Controller::OnOffCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + cluster.ReportAttributeOnOff(mOnSuccessCallback_1.Cancel()); + err = cluster.ConfigureAttributeOnOff(mOnSubscriptionEstablishedCallback_1.Cancel(), mOnFailureCallback_1.Cancel(), 2, 10); + + return err; + } + + static void SubscribeAttribute_1_OnSubscriptionEstablishedCallback(void * context) + { + TestSubscribe_OnOff * runner = reinterpret_cast(context); + if (!runner->mReceivedReport_1) + { + ChipLogError(chipTool, "Error: Initial report not received!"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + runner->NextTest(); + } + + static void OnTestSendClusterOnOffCommandSubscribeAttribute_1_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "On/Off - Subscribe OnOff Attribute: Failure Response"); + + TestSubscribe_OnOff * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_1 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterOnOffCommandSubscribeAttribute_1_SuccessResponse(void * context, bool onOff) + { + ChipLogProgress(chipTool, "On/Off - Subscribe OnOff Attribute: Success Response"); + + TestSubscribe_OnOff * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_1 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + if (onOff != false) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "false"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->mReceivedReport_1 = true; + } + + // Test Turn On the light to see attribute change + using SuccessCallback_2 = void (*)(void * context); + chip::Callback::Callback mOnSuccessCallback_2{ OnTestSendClusterOnOffCommandOn_2_SuccessResponse, this }; + chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterOnOffCommandOn_2_FailureResponse, + this }; + + bool mIsFailureExpected_2 = 0; + + CHIP_ERROR TestSendClusterOnOffCommandOn_2() + { + ChipLogProgress(chipTool, "On/Off - Turn On the light to see attribute change: Sending command..."); + + chip::Controller::OnOffCluster cluster; + cluster.Associate(mDevice, 1); + + CHIP_ERROR err = CHIP_NO_ERROR; + + err = cluster.On(mOnSuccessCallback_2.Cancel(), mOnFailureCallback_2.Cancel()); + + return err; + } + + static void OnTestSendClusterOnOffCommandOn_2_FailureResponse(void * context, uint8_t status) + { + ChipLogProgress(chipTool, "On/Off - Turn On the light to see attribute change: Failure Response"); + + TestSubscribe_OnOff * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_2 == false) + { + ChipLogError(chipTool, "Error: The test was expecting a success callback. Got failure callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + static void OnTestSendClusterOnOffCommandOn_2_SuccessResponse(void * context) + { + ChipLogProgress(chipTool, "On/Off - Turn On the light to see attribute change: Success Response"); + + TestSubscribe_OnOff * runner = reinterpret_cast(context); + + if (runner->mIsFailureExpected_2 == true) + { + ChipLogError(chipTool, "Error: The test was expecting a failure callback. Got success callback"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->NextTest(); + } + + // The callback should be called atleast once + using OnReportCallback_3 = void (*)(void * context, bool onOff); + chip::Callback::Callback mOnReportCallback_3{ SubscribeAttribute_3_OnReportCallback, this }; + + bool mReceivedReport_3 = false; + + CHIP_ERROR TestSendClusterTestSuiteCommandWaitForAttributeReport_3() + { + ChipLogProgress(chipTool, "TestSuite - WaitForAttributeReport - Check for attribute report"); + chip::Controller::OnOffCluster cluster; + cluster.Associate(mDevice, 1); + return cluster.ReportAttributeOnOff(mOnReportCallback_3.Cancel()); + } + + static void SubscribeAttribute_3_OnReportCallback(void * context, bool onOff) + { + ChipLogProgress(chipTool, "On/Off - Subscribe OnOff Attribute: Report Data"); + TestSubscribe_OnOff * runner = reinterpret_cast(context); + + if (runner->mReceivedReport_3) + { + // Receiving attribute more than once is not an issue, since the following handler will override previous handlers. + return; + } + + if (onOff != true) + { + ChipLogError(chipTool, "Error: Value mismatch. Expected: '%s'", "true"); + runner->SetCommandExitStatus(CHIP_ERROR_INTERNAL); + return; + } + + runner->mReceivedReport_3 = true; + ChipLogProgress(chipTool, "On/Off - report received."); + runner->NextTest(); + } +}; + class Test_TC_OO_1_1 : public TestCommand { public: @@ -10511,6 +10944,7 @@ class Test_TC_OO_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterOnOffCommandReadAttribute_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_0() @@ -10573,6 +11007,7 @@ class Test_TC_OO_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterOnOffCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_1() @@ -10635,6 +11070,7 @@ class Test_TC_OO_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterOnOffCommandReadAttribute_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_2() @@ -10697,6 +11133,7 @@ class Test_TC_OO_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_3{ OnTestSendClusterOnOffCommandReadAttribute_3_FailureResponse, this }; + bool mIsFailureExpected_3 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_3() @@ -10835,6 +11272,7 @@ class Test_TC_OO_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterOnOffCommandReadAttribute_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_0() @@ -10897,6 +11335,7 @@ class Test_TC_OO_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterOnOffCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_1() @@ -10959,6 +11398,7 @@ class Test_TC_OO_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterOnOffCommandReadAttribute_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_2() @@ -11021,6 +11461,7 @@ class Test_TC_OO_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_3{ OnTestSendClusterOnOffCommandReadAttribute_3_FailureResponse, this }; + bool mIsFailureExpected_3 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_3() @@ -11083,6 +11524,7 @@ class Test_TC_OO_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_4{ OnTestSendClusterOnOffCommandReadAttribute_4_FailureResponse, this }; + bool mIsFailureExpected_4 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_4() @@ -11145,6 +11587,7 @@ class Test_TC_OO_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_5{ OnTestSendClusterOnOffCommandReadAttribute_5_FailureResponse, this }; + bool mIsFailureExpected_5 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_5() @@ -11207,6 +11650,7 @@ class Test_TC_OO_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_6{ OnTestSendClusterOnOffCommandWriteAttribute_6_FailureResponse, this }; + bool mIsFailureExpected_6 = 0; CHIP_ERROR TestSendClusterOnOffCommandWriteAttribute_6() @@ -11263,6 +11707,7 @@ class Test_TC_OO_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_7{ OnTestSendClusterOnOffCommandWriteAttribute_7_FailureResponse, this }; + bool mIsFailureExpected_7 = 0; CHIP_ERROR TestSendClusterOnOffCommandWriteAttribute_7() @@ -11319,6 +11764,7 @@ class Test_TC_OO_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_8{ OnTestSendClusterOnOffCommandWriteAttribute_8_FailureResponse, this }; + bool mIsFailureExpected_8 = 0; CHIP_ERROR TestSendClusterOnOffCommandWriteAttribute_8() @@ -11376,6 +11822,7 @@ class Test_TC_OO_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_9{ OnTestSendClusterOnOffCommandReadAttribute_9_FailureResponse, this }; + bool mIsFailureExpected_9 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_9() @@ -11439,6 +11886,7 @@ class Test_TC_OO_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_10{ OnTestSendClusterOnOffCommandReadAttribute_10_FailureResponse, this }; + bool mIsFailureExpected_10 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_10() @@ -11502,6 +11950,7 @@ class Test_TC_OO_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_11{ OnTestSendClusterOnOffCommandReadAttribute_11_FailureResponse, this }; + bool mIsFailureExpected_11 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_11() @@ -11644,6 +12093,7 @@ class Test_TC_OO_2_2 : public TestCommand chip::Callback::Callback mOnSuccessCallback_0{ OnTestSendClusterOnOffCommandOff_0_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterOnOffCommandOff_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterOnOffCommandOff_0() @@ -11699,6 +12149,7 @@ class Test_TC_OO_2_2 : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterOnOffCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_1() @@ -11759,6 +12210,7 @@ class Test_TC_OO_2_2 : public TestCommand chip::Callback::Callback mOnSuccessCallback_2{ OnTestSendClusterOnOffCommandOn_2_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterOnOffCommandOn_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterOnOffCommandOn_2() @@ -11814,6 +12266,7 @@ class Test_TC_OO_2_2 : public TestCommand chip::Callback::Callback mOnFailureCallback_3{ OnTestSendClusterOnOffCommandReadAttribute_3_FailureResponse, this }; + bool mIsFailureExpected_3 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_3() @@ -11874,6 +12327,7 @@ class Test_TC_OO_2_2 : public TestCommand chip::Callback::Callback mOnSuccessCallback_4{ OnTestSendClusterOnOffCommandOff_4_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_4{ OnTestSendClusterOnOffCommandOff_4_FailureResponse, this }; + bool mIsFailureExpected_4 = 0; CHIP_ERROR TestSendClusterOnOffCommandOff_4() @@ -11929,6 +12383,7 @@ class Test_TC_OO_2_2 : public TestCommand chip::Callback::Callback mOnFailureCallback_5{ OnTestSendClusterOnOffCommandReadAttribute_5_FailureResponse, this }; + bool mIsFailureExpected_5 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_5() @@ -11989,6 +12444,7 @@ class Test_TC_OO_2_2 : public TestCommand chip::Callback::Callback mOnSuccessCallback_6{ OnTestSendClusterOnOffCommandToggle_6_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_6{ OnTestSendClusterOnOffCommandToggle_6_FailureResponse, this }; + bool mIsFailureExpected_6 = 0; CHIP_ERROR TestSendClusterOnOffCommandToggle_6() @@ -12044,6 +12500,7 @@ class Test_TC_OO_2_2 : public TestCommand chip::Callback::Callback mOnFailureCallback_7{ OnTestSendClusterOnOffCommandReadAttribute_7_FailureResponse, this }; + bool mIsFailureExpected_7 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_7() @@ -12104,6 +12561,7 @@ class Test_TC_OO_2_2 : public TestCommand chip::Callback::Callback mOnSuccessCallback_8{ OnTestSendClusterOnOffCommandToggle_8_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_8{ OnTestSendClusterOnOffCommandToggle_8_FailureResponse, this }; + bool mIsFailureExpected_8 = 0; CHIP_ERROR TestSendClusterOnOffCommandToggle_8() @@ -12159,6 +12617,7 @@ class Test_TC_OO_2_2 : public TestCommand chip::Callback::Callback mOnFailureCallback_9{ OnTestSendClusterOnOffCommandReadAttribute_9_FailureResponse, this }; + bool mIsFailureExpected_9 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_9() @@ -12219,6 +12678,7 @@ class Test_TC_OO_2_2 : public TestCommand chip::Callback::Callback mOnSuccessCallback_10{ OnTestSendClusterOnOffCommandOn_10_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_10{ OnTestSendClusterOnOffCommandOn_10_FailureResponse, this }; + bool mIsFailureExpected_10 = 0; CHIP_ERROR TestSendClusterOnOffCommandOn_10() @@ -12275,6 +12735,7 @@ class Test_TC_OO_2_2 : public TestCommand chip::Callback::Callback mOnFailureCallback_11{ OnTestSendClusterOnOffCommandReadAttribute_11_FailureResponse, this }; + bool mIsFailureExpected_11 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_11() @@ -12335,6 +12796,7 @@ class Test_TC_OO_2_2 : public TestCommand chip::Callback::Callback mOnSuccessCallback_12{ OnTestSendClusterOnOffCommandOff_12_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_12{ OnTestSendClusterOnOffCommandOff_12_FailureResponse, this }; + bool mIsFailureExpected_12 = 0; CHIP_ERROR TestSendClusterOnOffCommandOff_12() @@ -12391,6 +12853,7 @@ class Test_TC_OO_2_2 : public TestCommand chip::Callback::Callback mOnFailureCallback_13{ OnTestSendClusterOnOffCommandReadAttribute_13_FailureResponse, this }; + bool mIsFailureExpected_13 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_13() @@ -12547,6 +13010,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterBasicCommandReadAttribute_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_0() @@ -12605,6 +13069,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterBasicCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_1() @@ -12669,6 +13134,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterBasicCommandReadAttribute_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_2() @@ -12726,6 +13192,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_3{ OnTestSendClusterBasicCommandReadAttribute_3_FailureResponse, this }; + bool mIsFailureExpected_3 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_3() @@ -12790,6 +13257,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_4{ OnTestSendClusterBasicCommandReadAttribute_4_FailureResponse, this }; + bool mIsFailureExpected_4 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_4() @@ -12847,6 +13315,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_5{ OnTestSendClusterBasicCommandReadAttribute_5_FailureResponse, this }; + bool mIsFailureExpected_5 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_5() @@ -12911,6 +13380,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_6{ OnTestSendClusterBasicCommandReadAttribute_6_FailureResponse, this }; + bool mIsFailureExpected_6 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_6() @@ -12978,6 +13448,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_7{ OnTestSendClusterBasicCommandReadAttribute_7_FailureResponse, this }; + bool mIsFailureExpected_7 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_7() @@ -13035,6 +13506,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_8{ OnTestSendClusterBasicCommandReadAttribute_8_FailureResponse, this }; + bool mIsFailureExpected_8 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_8() @@ -13109,6 +13581,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_9{ OnTestSendClusterBasicCommandReadAttribute_9_FailureResponse, this }; + bool mIsFailureExpected_9 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_9() @@ -13167,6 +13640,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_10{ OnTestSendClusterBasicCommandReadAttribute_10_FailureResponse, this }; + bool mIsFailureExpected_10 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_10() @@ -13245,6 +13719,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_11{ OnTestSendClusterBasicCommandReadAttribute_11_FailureResponse, this }; + bool mIsFailureExpected_11 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_11() @@ -13326,6 +13801,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_12{ OnTestSendClusterBasicCommandReadAttribute_12_FailureResponse, this }; + bool mIsFailureExpected_12 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_12() @@ -13397,6 +13873,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_13{ OnTestSendClusterBasicCommandReadAttribute_13_FailureResponse, this }; + bool mIsFailureExpected_13 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_13() @@ -13470,6 +13947,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_14{ OnTestSendClusterBasicCommandReadAttribute_14_FailureResponse, this }; + bool mIsFailureExpected_14 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_14() @@ -13541,6 +14019,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_15{ OnTestSendClusterBasicCommandReadAttribute_15_FailureResponse, this }; + bool mIsFailureExpected_15 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_15() @@ -13612,6 +14091,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_16{ OnTestSendClusterBasicCommandReadAttribute_16_FailureResponse, this }; + bool mIsFailureExpected_16 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_16() @@ -13676,6 +14156,7 @@ class Test_TC_DM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_17{ OnTestSendClusterBasicCommandReadAttribute_17_FailureResponse, this }; + bool mIsFailureExpected_17 = 0; CHIP_ERROR TestSendClusterBasicCommandReadAttribute_17() @@ -13877,6 +14358,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnSuccessCallback_0{ OnTestSendClusterOnOffCommandOn_0_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterOnOffCommandOn_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterOnOffCommandOn_0() @@ -13932,6 +14414,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterOnOffCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_1() @@ -13995,6 +14478,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterColorControlCommandMoveToHue_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveToHue_2() @@ -14057,6 +14541,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_3{ OnTestSendClusterColorControlCommandMoveToHue_3_FailureResponse, this }; + bool mIsFailureExpected_3 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveToHue_3() @@ -14119,6 +14604,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_4{ OnTestSendClusterColorControlCommandMoveToHue_4_FailureResponse, this }; + bool mIsFailureExpected_4 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveToHue_4() @@ -14181,6 +14667,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_5{ OnTestSendClusterColorControlCommandMoveToHue_5_FailureResponse, this }; + bool mIsFailureExpected_5 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveToHue_5() @@ -14242,6 +14729,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_6{ OnTestSendClusterColorControlCommandMoveHue_6_FailureResponse, this }; + bool mIsFailureExpected_6 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveHue_6() @@ -14302,6 +14790,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_7{ OnTestSendClusterColorControlCommandMoveHue_7_FailureResponse, this }; + bool mIsFailureExpected_7 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveHue_7() @@ -14362,6 +14851,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_8{ OnTestSendClusterColorControlCommandMoveHue_8_FailureResponse, this }; + bool mIsFailureExpected_8 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveHue_8() @@ -14422,6 +14912,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_9{ OnTestSendClusterColorControlCommandMoveHue_9_FailureResponse, this }; + bool mIsFailureExpected_9 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveHue_9() @@ -14483,6 +14974,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_10{ OnTestSendClusterColorControlCommandStepHue_10_FailureResponse, this }; + bool mIsFailureExpected_10 = 0; CHIP_ERROR TestSendClusterColorControlCommandStepHue_10() @@ -14545,6 +15037,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_11{ OnTestSendClusterColorControlCommandStepHue_11_FailureResponse, this }; + bool mIsFailureExpected_11 = 0; CHIP_ERROR TestSendClusterColorControlCommandStepHue_11() @@ -14607,6 +15100,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_12{ OnTestSendClusterColorControlCommandMoveToSaturation_12_FailureResponse, this }; + bool mIsFailureExpected_12 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveToSaturation_12() @@ -14668,6 +15162,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_13{ OnTestSendClusterColorControlCommandMoveSaturation_13_FailureResponse, this }; + bool mIsFailureExpected_13 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveSaturation_13() @@ -14729,6 +15224,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_14{ OnTestSendClusterColorControlCommandMoveSaturation_14_FailureResponse, this }; + bool mIsFailureExpected_14 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveSaturation_14() @@ -14790,6 +15286,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_15{ OnTestSendClusterColorControlCommandStepSaturation_15_FailureResponse, this }; + bool mIsFailureExpected_15 = 0; CHIP_ERROR TestSendClusterColorControlCommandStepSaturation_15() @@ -14852,6 +15349,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_16{ OnTestSendClusterColorControlCommandStepSaturation_16_FailureResponse, this }; + bool mIsFailureExpected_16 = 0; CHIP_ERROR TestSendClusterColorControlCommandStepSaturation_16() @@ -14914,6 +15412,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_17{ OnTestSendClusterColorControlCommandMoveToHueAndSaturation_17_FailureResponse, this }; + bool mIsFailureExpected_17 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveToHueAndSaturation_17() @@ -14974,6 +15473,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnSuccessCallback_18{ OnTestSendClusterOnOffCommandOff_18_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_18{ OnTestSendClusterOnOffCommandOff_18_FailureResponse, this }; + bool mIsFailureExpected_18 = 0; CHIP_ERROR TestSendClusterOnOffCommandOff_18() @@ -15030,6 +15530,7 @@ class Test_TC_CC_3_4 : public TestCommand chip::Callback::Callback mOnFailureCallback_19{ OnTestSendClusterOnOffCommandReadAttribute_19_FailureResponse, this }; + bool mIsFailureExpected_19 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_19() @@ -15154,6 +15655,7 @@ class Test_TC_CC_5 : public TestCommand chip::Callback::Callback mOnSuccessCallback_0{ OnTestSendClusterOnOffCommandOn_0_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterOnOffCommandOn_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterOnOffCommandOn_0() @@ -15209,6 +15711,7 @@ class Test_TC_CC_5 : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterOnOffCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_1() @@ -15272,6 +15775,7 @@ class Test_TC_CC_5 : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterColorControlCommandMoveToColor_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveToColor_2() @@ -15334,6 +15838,7 @@ class Test_TC_CC_5 : public TestCommand chip::Callback::Callback mOnFailureCallback_3{ OnTestSendClusterColorControlCommandMoveColor_3_FailureResponse, this }; + bool mIsFailureExpected_3 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveColor_3() @@ -15395,6 +15900,7 @@ class Test_TC_CC_5 : public TestCommand chip::Callback::Callback mOnFailureCallback_4{ OnTestSendClusterColorControlCommandStopMoveStep_4_FailureResponse, this }; + bool mIsFailureExpected_4 = 0; CHIP_ERROR TestSendClusterColorControlCommandStopMoveStep_4() @@ -15454,6 +15960,7 @@ class Test_TC_CC_5 : public TestCommand chip::Callback::Callback mOnFailureCallback_5{ OnTestSendClusterColorControlCommandStepColor_5_FailureResponse, this }; + bool mIsFailureExpected_5 = 0; CHIP_ERROR TestSendClusterColorControlCommandStepColor_5() @@ -15513,6 +16020,7 @@ class Test_TC_CC_5 : public TestCommand chip::Callback::Callback mOnSuccessCallback_6{ OnTestSendClusterOnOffCommandOff_6_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_6{ OnTestSendClusterOnOffCommandOff_6_FailureResponse, this }; + bool mIsFailureExpected_6 = 0; CHIP_ERROR TestSendClusterOnOffCommandOff_6() @@ -15568,6 +16076,7 @@ class Test_TC_CC_5 : public TestCommand chip::Callback::Callback mOnFailureCallback_7{ OnTestSendClusterOnOffCommandReadAttribute_7_FailureResponse, this }; + bool mIsFailureExpected_7 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_7() @@ -15698,6 +16207,7 @@ class Test_TC_CC_6 : public TestCommand chip::Callback::Callback mOnSuccessCallback_0{ OnTestSendClusterOnOffCommandOn_0_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterOnOffCommandOn_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterOnOffCommandOn_0() @@ -15753,6 +16263,7 @@ class Test_TC_CC_6 : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterOnOffCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_1() @@ -15816,6 +16327,7 @@ class Test_TC_CC_6 : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterColorControlCommandMoveToColorTemperature_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveToColorTemperature_2() @@ -15877,6 +16389,7 @@ class Test_TC_CC_6 : public TestCommand chip::Callback::Callback mOnFailureCallback_3{ OnTestSendClusterColorControlCommandMoveColorTemperature_3_FailureResponse, this }; + bool mIsFailureExpected_3 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveColorTemperature_3() @@ -15941,6 +16454,7 @@ class Test_TC_CC_6 : public TestCommand chip::Callback::Callback mOnFailureCallback_4{ OnTestSendClusterColorControlCommandMoveColorTemperature_4_FailureResponse, this }; + bool mIsFailureExpected_4 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveColorTemperature_4() @@ -16005,6 +16519,7 @@ class Test_TC_CC_6 : public TestCommand chip::Callback::Callback mOnFailureCallback_5{ OnTestSendClusterColorControlCommandMoveColorTemperature_5_FailureResponse, this }; + bool mIsFailureExpected_5 = 0; CHIP_ERROR TestSendClusterColorControlCommandMoveColorTemperature_5() @@ -16069,6 +16584,7 @@ class Test_TC_CC_6 : public TestCommand chip::Callback::Callback mOnFailureCallback_6{ OnTestSendClusterColorControlCommandStepColorTemperature_6_FailureResponse, this }; + bool mIsFailureExpected_6 = 0; CHIP_ERROR TestSendClusterColorControlCommandStepColorTemperature_6() @@ -16134,6 +16650,7 @@ class Test_TC_CC_6 : public TestCommand chip::Callback::Callback mOnFailureCallback_7{ OnTestSendClusterColorControlCommandStepColorTemperature_7_FailureResponse, this }; + bool mIsFailureExpected_7 = 0; CHIP_ERROR TestSendClusterColorControlCommandStepColorTemperature_7() @@ -16196,6 +16713,7 @@ class Test_TC_CC_6 : public TestCommand chip::Callback::Callback mOnSuccessCallback_8{ OnTestSendClusterOnOffCommandOff_8_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_8{ OnTestSendClusterOnOffCommandOff_8_FailureResponse, this }; + bool mIsFailureExpected_8 = 0; CHIP_ERROR TestSendClusterOnOffCommandOff_8() @@ -16251,6 +16769,7 @@ class Test_TC_CC_6 : public TestCommand chip::Callback::Callback mOnFailureCallback_9{ OnTestSendClusterOnOffCommandReadAttribute_9_FailureResponse, this }; + bool mIsFailureExpected_9 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_9() @@ -16390,6 +16909,7 @@ class Test_TC_CC_7 : public TestCommand chip::Callback::Callback mOnSuccessCallback_0{ OnTestSendClusterOnOffCommandOn_0_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterOnOffCommandOn_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterOnOffCommandOn_0() @@ -16445,6 +16965,7 @@ class Test_TC_CC_7 : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterOnOffCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_1() @@ -16508,6 +17029,7 @@ class Test_TC_CC_7 : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterColorControlCommandEnhancedMoveToHue_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterColorControlCommandEnhancedMoveToHue_2() @@ -16570,6 +17092,7 @@ class Test_TC_CC_7 : public TestCommand chip::Callback::Callback mOnFailureCallback_3{ OnTestSendClusterColorControlCommandReadAttribute_3_FailureResponse, this }; + bool mIsFailureExpected_3 = 0; CHIP_ERROR TestSendClusterColorControlCommandReadAttribute_3() @@ -16639,6 +17162,7 @@ class Test_TC_CC_7 : public TestCommand chip::Callback::Callback mOnFailureCallback_4{ OnTestSendClusterColorControlCommandEnhancedMoveHue_4_FailureResponse, this }; + bool mIsFailureExpected_4 = 0; CHIP_ERROR TestSendClusterColorControlCommandEnhancedMoveHue_4() @@ -16700,6 +17224,7 @@ class Test_TC_CC_7 : public TestCommand chip::Callback::Callback mOnFailureCallback_5{ OnTestSendClusterColorControlCommandEnhancedMoveHue_5_FailureResponse, this }; + bool mIsFailureExpected_5 = 0; CHIP_ERROR TestSendClusterColorControlCommandEnhancedMoveHue_5() @@ -16761,6 +17286,7 @@ class Test_TC_CC_7 : public TestCommand chip::Callback::Callback mOnFailureCallback_6{ OnTestSendClusterColorControlCommandEnhancedMoveHue_6_FailureResponse, this }; + bool mIsFailureExpected_6 = 0; CHIP_ERROR TestSendClusterColorControlCommandEnhancedMoveHue_6() @@ -16822,6 +17348,7 @@ class Test_TC_CC_7 : public TestCommand chip::Callback::Callback mOnFailureCallback_7{ OnTestSendClusterColorControlCommandEnhancedMoveHue_7_FailureResponse, this }; + bool mIsFailureExpected_7 = 0; CHIP_ERROR TestSendClusterColorControlCommandEnhancedMoveHue_7() @@ -16883,6 +17410,7 @@ class Test_TC_CC_7 : public TestCommand chip::Callback::Callback mOnFailureCallback_8{ OnTestSendClusterColorControlCommandEnhancedStepHue_8_FailureResponse, this }; + bool mIsFailureExpected_8 = 0; CHIP_ERROR TestSendClusterColorControlCommandEnhancedStepHue_8() @@ -16945,6 +17473,7 @@ class Test_TC_CC_7 : public TestCommand chip::Callback::Callback mOnFailureCallback_9{ OnTestSendClusterColorControlCommandEnhancedStepHue_9_FailureResponse, this }; + bool mIsFailureExpected_9 = 0; CHIP_ERROR TestSendClusterColorControlCommandEnhancedStepHue_9() @@ -17007,6 +17536,7 @@ class Test_TC_CC_7 : public TestCommand chip::Callback::Callback mOnFailureCallback_10{ OnTestSendClusterColorControlCommandEnhancedMoveToHueAndSaturation_10_FailureResponse, this }; + bool mIsFailureExpected_10 = 0; CHIP_ERROR TestSendClusterColorControlCommandEnhancedMoveToHueAndSaturation_10() @@ -17068,6 +17598,7 @@ class Test_TC_CC_7 : public TestCommand chip::Callback::Callback mOnSuccessCallback_11{ OnTestSendClusterOnOffCommandOff_11_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_11{ OnTestSendClusterOnOffCommandOff_11_FailureResponse, this }; + bool mIsFailureExpected_11 = 0; CHIP_ERROR TestSendClusterOnOffCommandOff_11() @@ -17124,6 +17655,7 @@ class Test_TC_CC_7 : public TestCommand chip::Callback::Callback mOnFailureCallback_12{ OnTestSendClusterOnOffCommandReadAttribute_12_FailureResponse, this }; + bool mIsFailureExpected_12 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_12() @@ -17272,6 +17804,7 @@ class Test_TC_CC_8 : public TestCommand chip::Callback::Callback mOnSuccessCallback_0{ OnTestSendClusterOnOffCommandOn_0_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterOnOffCommandOn_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterOnOffCommandOn_0() @@ -17327,6 +17860,7 @@ class Test_TC_CC_8 : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterOnOffCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_1() @@ -17390,6 +17924,7 @@ class Test_TC_CC_8 : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterColorControlCommandColorLoopSet_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterColorControlCommandColorLoopSet_2() @@ -17455,6 +17990,7 @@ class Test_TC_CC_8 : public TestCommand chip::Callback::Callback mOnFailureCallback_3{ OnTestSendClusterColorControlCommandReadAttribute_3_FailureResponse, this }; + bool mIsFailureExpected_3 = 0; CHIP_ERROR TestSendClusterColorControlCommandReadAttribute_3() @@ -17518,6 +18054,7 @@ class Test_TC_CC_8 : public TestCommand chip::Callback::Callback mOnFailureCallback_4{ OnTestSendClusterColorControlCommandReadAttribute_4_FailureResponse, this }; + bool mIsFailureExpected_4 = 0; CHIP_ERROR TestSendClusterColorControlCommandReadAttribute_4() @@ -17581,6 +18118,7 @@ class Test_TC_CC_8 : public TestCommand chip::Callback::Callback mOnFailureCallback_5{ OnTestSendClusterColorControlCommandReadAttribute_5_FailureResponse, this }; + bool mIsFailureExpected_5 = 0; CHIP_ERROR TestSendClusterColorControlCommandReadAttribute_5() @@ -17645,6 +18183,7 @@ class Test_TC_CC_8 : public TestCommand chip::Callback::Callback mOnFailureCallback_6{ OnTestSendClusterColorControlCommandReadAttribute_6_FailureResponse, this }; + bool mIsFailureExpected_6 = 0; CHIP_ERROR TestSendClusterColorControlCommandReadAttribute_6() @@ -17708,6 +18247,7 @@ class Test_TC_CC_8 : public TestCommand chip::Callback::Callback mOnFailureCallback_7{ OnTestSendClusterColorControlCommandColorLoopSet_7_FailureResponse, this }; + bool mIsFailureExpected_7 = 0; CHIP_ERROR TestSendClusterColorControlCommandColorLoopSet_7() @@ -17773,6 +18313,7 @@ class Test_TC_CC_8 : public TestCommand chip::Callback::Callback mOnFailureCallback_8{ OnTestSendClusterColorControlCommandReadAttribute_8_FailureResponse, this }; + bool mIsFailureExpected_8 = 0; CHIP_ERROR TestSendClusterColorControlCommandReadAttribute_8() @@ -17836,6 +18377,7 @@ class Test_TC_CC_8 : public TestCommand chip::Callback::Callback mOnFailureCallback_9{ OnTestSendClusterColorControlCommandColorLoopSet_9_FailureResponse, this }; + bool mIsFailureExpected_9 = 0; CHIP_ERROR TestSendClusterColorControlCommandColorLoopSet_9() @@ -17904,6 +18446,7 @@ class Test_TC_CC_8 : public TestCommand chip::Callback::Callback mOnFailureCallback_10{ OnTestSendClusterColorControlCommandReadAttribute_10_FailureResponse, this }; + bool mIsFailureExpected_10 = 0; CHIP_ERROR TestSendClusterColorControlCommandReadAttribute_10() @@ -17967,6 +18510,7 @@ class Test_TC_CC_8 : public TestCommand chip::Callback::Callback mOnFailureCallback_11{ OnTestSendClusterColorControlCommandReadAttribute_11_FailureResponse, this }; + bool mIsFailureExpected_11 = 0; CHIP_ERROR TestSendClusterColorControlCommandReadAttribute_11() @@ -18030,6 +18574,7 @@ class Test_TC_CC_8 : public TestCommand chip::Callback::Callback mOnFailureCallback_12{ OnTestSendClusterColorControlCommandColorLoopSet_12_FailureResponse, this }; + bool mIsFailureExpected_12 = 0; CHIP_ERROR TestSendClusterColorControlCommandColorLoopSet_12() @@ -18095,6 +18640,7 @@ class Test_TC_CC_8 : public TestCommand chip::Callback::Callback mOnFailureCallback_13{ OnTestSendClusterColorControlCommandReadAttribute_13_FailureResponse, this }; + bool mIsFailureExpected_13 = 0; CHIP_ERROR TestSendClusterColorControlCommandReadAttribute_13() @@ -18155,6 +18701,7 @@ class Test_TC_CC_8 : public TestCommand chip::Callback::Callback mOnSuccessCallback_14{ OnTestSendClusterOnOffCommandOff_14_SuccessResponse, this }; chip::Callback::Callback mOnFailureCallback_14{ OnTestSendClusterOnOffCommandOff_14_FailureResponse, this }; + bool mIsFailureExpected_14 = 0; CHIP_ERROR TestSendClusterOnOffCommandOff_14() @@ -18211,6 +18758,7 @@ class Test_TC_CC_8 : public TestCommand chip::Callback::Callback mOnFailureCallback_15{ OnTestSendClusterOnOffCommandReadAttribute_15_FailureResponse, this }; + bool mIsFailureExpected_15 = 0; CHIP_ERROR TestSendClusterOnOffCommandReadAttribute_15() @@ -18320,6 +18868,7 @@ class Test_TC_WNCV_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterWindowCoveringCommandReadAttribute_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterWindowCoveringCommandReadAttribute_0() @@ -18383,6 +18932,7 @@ class Test_TC_WNCV_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterWindowCoveringCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterWindowCoveringCommandReadAttribute_1() @@ -18519,6 +19069,7 @@ class Test_TC_WNCV_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterWindowCoveringCommandReadAttribute_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterWindowCoveringCommandReadAttribute_0() @@ -18582,6 +19133,7 @@ class Test_TC_WNCV_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterWindowCoveringCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterWindowCoveringCommandReadAttribute_1() @@ -18645,6 +19197,7 @@ class Test_TC_WNCV_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_2{ OnTestSendClusterWindowCoveringCommandReadAttribute_2_FailureResponse, this }; + bool mIsFailureExpected_2 = 0; CHIP_ERROR TestSendClusterWindowCoveringCommandReadAttribute_2() @@ -18708,6 +19261,7 @@ class Test_TC_WNCV_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_3{ OnTestSendClusterWindowCoveringCommandReadAttribute_3_FailureResponse, this }; + bool mIsFailureExpected_3 = 0; CHIP_ERROR TestSendClusterWindowCoveringCommandReadAttribute_3() @@ -18771,6 +19325,7 @@ class Test_TC_WNCV_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_4{ OnTestSendClusterWindowCoveringCommandReadAttribute_4_FailureResponse, this }; + bool mIsFailureExpected_4 = 0; CHIP_ERROR TestSendClusterWindowCoveringCommandReadAttribute_4() @@ -18835,6 +19390,7 @@ class Test_TC_WNCV_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_5{ OnTestSendClusterWindowCoveringCommandReadAttribute_5_FailureResponse, this }; + bool mIsFailureExpected_5 = 0; CHIP_ERROR TestSendClusterWindowCoveringCommandReadAttribute_5() @@ -18898,6 +19454,7 @@ class Test_TC_WNCV_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_6{ OnTestSendClusterWindowCoveringCommandReadAttribute_6_FailureResponse, this }; + bool mIsFailureExpected_6 = 0; CHIP_ERROR TestSendClusterWindowCoveringCommandReadAttribute_6() @@ -18961,6 +19518,7 @@ class Test_TC_WNCV_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_7{ OnTestSendClusterWindowCoveringCommandReadAttribute_7_FailureResponse, this }; + bool mIsFailureExpected_7 = 0; CHIP_ERROR TestSendClusterWindowCoveringCommandReadAttribute_7() @@ -19024,6 +19582,7 @@ class Test_TC_WNCV_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_8{ OnTestSendClusterWindowCoveringCommandReadAttribute_8_FailureResponse, this }; + bool mIsFailureExpected_8 = 0; CHIP_ERROR TestSendClusterWindowCoveringCommandReadAttribute_8() @@ -19087,6 +19646,7 @@ class Test_TC_WNCV_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_9{ OnTestSendClusterWindowCoveringCommandWriteAttribute_9_FailureResponse, this }; + bool mIsFailureExpected_9 = 0; CHIP_ERROR TestSendClusterWindowCoveringCommandWriteAttribute_9() @@ -19144,6 +19704,7 @@ class Test_TC_WNCV_2_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_10{ OnTestSendClusterWindowCoveringCommandReadAttribute_10_FailureResponse, this }; + bool mIsFailureExpected_10 = 0; CHIP_ERROR TestSendClusterWindowCoveringCommandReadAttribute_10() @@ -19253,6 +19814,7 @@ class Test_TC_BI_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterBinaryInputBasicCommandReadAttribute_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterBinaryInputBasicCommandReadAttribute_0() @@ -19316,6 +19878,7 @@ class Test_TC_BI_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterBinaryInputBasicCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterBinaryInputBasicCommandReadAttribute_1() @@ -19465,6 +20028,7 @@ class Test_TC_TM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterTemperatureMeasurementCommandReadAttribute_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterTemperatureMeasurementCommandReadAttribute_0() @@ -19529,6 +20093,7 @@ class Test_TC_TM_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterTemperatureMeasurementCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterTemperatureMeasurementCommandReadAttribute_1() @@ -19639,6 +20204,7 @@ class Test_TC_OCC_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterOccupancySensingCommandReadAttribute_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterOccupancySensingCommandReadAttribute_0() @@ -19702,6 +20268,7 @@ class Test_TC_OCC_1_1 : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterOccupancySensingCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterOccupancySensingCommandReadAttribute_1() @@ -19811,6 +20378,7 @@ class OperationalCredentialsCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_0{ OnTestSendClusterOperationalCredentialsCommandReadAttribute_0_FailureResponse, this }; + bool mIsFailureExpected_0 = 0; CHIP_ERROR TestSendClusterOperationalCredentialsCommandReadAttribute_0() @@ -19877,6 +20445,7 @@ class OperationalCredentialsCluster : public TestCommand chip::Callback::Callback mOnFailureCallback_1{ OnTestSendClusterOperationalCredentialsCommandReadAttribute_1_FailureResponse, this }; + bool mIsFailureExpected_1 = 0; CHIP_ERROR TestSendClusterOperationalCredentialsCommandReadAttribute_1() @@ -19956,6 +20525,7 @@ void registerCommandsTests(Commands & commands) make_unique(), make_unique(), make_unique(), + make_unique(), make_unique(), make_unique(), make_unique(), diff --git a/zzz_generated/controller-clusters/zap-generated/CHIPClientCallbacks.cpp b/zzz_generated/controller-clusters/zap-generated/CHIPClientCallbacks.cpp index f6ac35cc1df911..192d3df004d5f5 100644 --- a/zzz_generated/controller-clusters/zap-generated/CHIPClientCallbacks.cpp +++ b/zzz_generated/controller-clusters/zap-generated/CHIPClientCallbacks.cpp @@ -365,9 +365,12 @@ void ApplicationLauncherClusterApplicationLauncherListListAttributeFilter(TLV::T EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -404,9 +407,12 @@ void AudioOutputClusterAudioOutputListListAttributeFilter(TLV::TLVReader * tlvDa EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -449,9 +455,12 @@ void ContentLauncherClusterAcceptsHeaderListListAttributeFilter(TLV::TLVReader * EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -490,9 +499,12 @@ void ContentLauncherClusterSupportedStreamingTypesListAttributeFilter(TLV::TLVRe EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -529,9 +541,12 @@ void DescriptorClusterDeviceListListAttributeFilter(TLV::TLVReader * tlvData, Ca EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -571,9 +586,12 @@ void DescriptorClusterServerListListAttributeFilter(TLV::TLVReader * tlvData, Ca EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -610,9 +628,12 @@ void DescriptorClusterClientListListAttributeFilter(TLV::TLVReader * tlvData, Ca EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -649,9 +670,12 @@ void DescriptorClusterPartsListListAttributeFilter(TLV::TLVReader * tlvData, Cal EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -688,9 +712,12 @@ void FixedLabelClusterLabelListListAttributeFilter(TLV::TLVReader * tlvData, Cal EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -731,9 +758,12 @@ void GeneralCommissioningClusterBasicCommissioningInfoListListAttributeFilter(TL EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -771,9 +801,12 @@ void GeneralDiagnosticsClusterNetworkInterfacesListAttributeFilter(TLV::TLVReade EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -825,9 +858,12 @@ void GroupKeyManagementClusterGroupsListAttributeFilter(TLV::TLVReader * tlvData EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -870,9 +906,12 @@ void GroupKeyManagementClusterGroupKeysListAttributeFilter(TLV::TLVReader * tlvD EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -921,9 +960,12 @@ void MediaInputClusterMediaInputListListAttributeFilter(TLV::TLVReader * tlvData EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -969,9 +1011,12 @@ void OperationalCredentialsClusterFabricsListListAttributeFilter(TLV::TLVReader EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -1023,9 +1068,12 @@ void TvChannelClusterTvChannelListListAttributeFilter(TLV::TLVReader * tlvData, EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -1075,9 +1123,12 @@ void TargetNavigatorClusterTargetNavigatorListListAttributeFilter(TLV::TLVReader EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -1117,9 +1168,12 @@ void TestClusterClusterListInt8uListAttributeFilter(TLV::TLVReader * tlvData, Ca EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -1156,9 +1210,12 @@ void TestClusterClusterListOctetStringListAttributeFilter(TLV::TLVReader * tlvDa EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -1196,9 +1253,12 @@ void TestClusterClusterListStructOctetStringListAttributeFilter(TLV::TLVReader * EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -1239,9 +1299,12 @@ void ThreadNetworkDiagnosticsClusterNeighborTableListListAttributeFilter(TLV::TL EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -1318,9 +1381,12 @@ void ThreadNetworkDiagnosticsClusterRouteTableListListAttributeFilter(TLV::TLVRe EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -1385,9 +1451,12 @@ void ThreadNetworkDiagnosticsClusterSecurityPolicyListAttributeFilter(TLV::TLVRe EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -1428,9 +1497,12 @@ void ThreadNetworkDiagnosticsClusterOperationalDatasetComponentsListAttributeFil EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -1502,9 +1574,12 @@ void ThreadNetworkDiagnosticsClusterActiveNetworkFaultsListListAttributeFilter(T EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -2592,252 +2667,3 @@ bool emberAfTestClusterClusterTestSpecificResponseCallback(EndpointId endpoint, cb->mCall(cb->mContext, returnValue); return true; } - -bool emberAfReportAttributesCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen) -{ - ChipLogProgress(Zcl, "emberAfReportAttributeCallback:"); - ChipLogProgress(Zcl, " ClusterId: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); - - NodeId sourceId = emberAfCurrentCommand()->SourceNodeId(); - ChipLogProgress(Zcl, " Source NodeId: %" PRIu64, sourceId); - - EndpointId endpointId = emberAfCurrentCommand()->apsFrame->sourceEndpoint; - ChipLogProgress(Zcl, " Source EndpointId: 0x%04x", endpointId); - - // TODO onFailureCallback is just here because of the CHECK_MESSAGE_LENGTH macro. It needs to be removed. - Callback::Cancelable * onFailureCallback = nullptr; - - while (messageLen) - { - CHECK_MESSAGE_LENGTH(4); - AttributeId attributeId = Encoding::LittleEndian::Read32(message); // attribId - ChipLogProgress(Zcl, " attributeId: " ChipLogFormatMEI, ChipLogValueMEI(attributeId)); - - GET_REPORT_CALLBACK("emberAfReportAttributesCallback"); - - CHECK_MESSAGE_LENGTH(1); - uint8_t attributeType = Encoding::Read8(message); - ChipLogProgress(Zcl, " attributeType: 0x%02x", attributeType); - - switch (attributeType) - { - case 0x00: // nodata / No data - case 0x0A: // data24 / 24-bit data - case 0x0C: // data40 / 40-bit data - case 0x0D: // data48 / 48-bit data - case 0x0E: // data56 / 56-bit data - case 0x1A: // map24 / 24-bit bitmap - case 0x1C: // map40 / 40-bit bitmap - case 0x1D: // map48 / 48-bit bitmap - case 0x1E: // map56 / 56-bit bitmap - case 0x22: // uint24 / Unsigned 24-bit integer - case 0x24: // uint40 / Unsigned 40-bit integer - case 0x25: // uint48 / Unsigned 48-bit integer - case 0x26: // uint56 / Unsigned 56-bit integer - case 0x2A: // int24 / Signed 24-bit integer - case 0x2C: // int40 / Signed 40-bit integer - case 0x2D: // int48 / Signed 48-bit integer - case 0x2E: // int56 / Signed 56-bit integer - case 0x38: // semi / Semi-precision - case 0x39: // single / Single precision - case 0x3A: // double / Double precision - case 0x48: // array / Array - case 0x49: // struct / Structure - case 0x50: // set / Set - case 0x51: // bag / Bag - case 0xE0: // ToD / Time of day - { - ChipLogError(Zcl, "attributeType 0x%02x is not supported", attributeType); - return true; - } - - case 0x41: // octstr / Octet string - case 0x42: // string / Character string - { - // Short Strings must contains at least one byte for the length - CHECK_MESSAGE_LENGTH(1); - uint8_t length = Encoding::Read8(message); - ChipLogProgress(Zcl, " length: 0x%02x", length); - - // When the length is set to 0xFF, it represents a non-value. In this case the data field is zero length. - if (length == 0xFF) - { - length = 0; - } - - CHECK_MESSAGE_LENGTH(length); - if (attributeType == 0x41) - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - else - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - break; - } - - case 0x43: // octstr16 / Long octet string - case 0x44: // string16 / Long character string - { - // Long Strings must contains at least two bytes for the length - CHECK_MESSAGE_LENGTH(2); - uint16_t length = Encoding::LittleEndian::Read16(message); - ChipLogProgress(Zcl, " length: 0x%02x", length); - - // When the length is set to 0xFFFF, it represents a non-value. In this case the data field is zero length. - if (length == 0xFFFF) - { - length = 0; - } - - CHECK_MESSAGE_LENGTH(length); - if (attributeType == 0x43) - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - else - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - break; - } - - case 0x08: // data8 / 8-bit data - case 0x18: // map8 / 8-bit bitmap - case 0x20: // uint8 / Unsigned 8-bit integer - case 0x30: // enum8 / 8-bit enumeration - { - CHECK_MESSAGE_LENGTH(1); - uint8_t value = Encoding::Read8(message); - ChipLogProgress(Zcl, " value: 0x%02x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x09: // data16 / 16-bit data - case 0x19: // map16 / 16-bit bitmap - case 0x21: // uint16 / Unsigned 16-bit integer - case 0x31: // enum16 / 16-bit enumeration - case 0xE8: // clusterId / Cluster ID - case 0xE9: // attribId / Attribute ID - case 0xEA: // bacOID / BACnet OID - case 0xF1: // key128 / 128-bit security key - case 0xFF: // unk / Unknown - { - CHECK_MESSAGE_LENGTH(2); - uint16_t value = Encoding::LittleEndian::Read16(message); - ChipLogProgress(Zcl, " value: 0x%04x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x0B: // data32 / 32-bit data - case 0x1B: // map32 / 32-bit bitmap - case 0x23: // uint32 / Unsigned 32-bit integer - case 0xE1: // date / Date - case 0xE2: // UTC / UTCTime - { - CHECK_MESSAGE_LENGTH(4); - uint32_t value = Encoding::LittleEndian::Read32(message); - ChipLogProgress(Zcl, " value: 0x%08x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x0F: // data64 / 64-bit data - case 0x1F: // map64 / 64-bit bitmap - case 0x27: // uint64 / Unsigned 64-bit integer - case 0xF0: // EUI64 / IEEE address - { - CHECK_MESSAGE_LENGTH(8); - uint64_t value = Encoding::LittleEndian::Read64(message); - ChipLogProgress(Zcl, " value: 0x" ChipLogFormatX64, ChipLogValueX64(value)); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x10: // bool / Boolean - { - CHECK_MESSAGE_LENGTH(1); - uint8_t value = Encoding::Read8(message); - ChipLogProgress(Zcl, " value: %d", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x28: // int8 / Signed 8-bit integer - { - CHECK_MESSAGE_LENGTH(1); - int8_t value = CastToSigned(Encoding::Read8(message)); - ChipLogProgress(Zcl, " value: %" PRId8, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x29: // int16 / Signed 16-bit integer - { - CHECK_MESSAGE_LENGTH(2); - int16_t value = CastToSigned(Encoding::LittleEndian::Read16(message)); - ChipLogProgress(Zcl, " value: %" PRId16, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x2B: // int32 / Signed 32-bit integer - { - CHECK_MESSAGE_LENGTH(4); - int32_t value = CastToSigned(Encoding::LittleEndian::Read32(message)); - ChipLogProgress(Zcl, " value: %" PRId32, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x2F: // int64 / Signed 64-bit integer - { - CHECK_MESSAGE_LENGTH(8); - int64_t value = CastToSigned(Encoding::LittleEndian::Read64(message)); - ChipLogProgress(Zcl, " value: %" PRId64, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - } - } - - return true; -} diff --git a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp index c305dd1925b096..1beb29f92d5fe1 100644 --- a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp +++ b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp @@ -67,8 +67,6 @@ constexpr uint8_t kFrameControlGlobalCommand = 0x00; // Pick source endpoint as 1 for now constexpr EndpointId kSourceEndpoint = 1; - -[[maybe_unused]] const uint8_t kReportingDirectionReported = 0x00; } // namespace using namespace app::Clusters; @@ -1268,21 +1266,19 @@ CHIP_ERROR BinaryInputBasicCluster::ConfigureAttributePresentValue(Callback::Can Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval) { - COMMAND_HEADER("ReportBinaryInputBasicPresentValue", BinaryInputBasic::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(BinaryInputBasic::Attributes::Ids::PresentValue) - .Put8(16) - .Put16(minInterval) - .Put16(maxInterval); - COMMAND_FOOTER(); + + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = BinaryInputBasic::Attributes::Ids::PresentValue; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR BinaryInputBasicCluster::ReportAttributePresentValue(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0055, onReportCallback); + return RequestAttributeReporting(BinaryInputBasic::Attributes::Ids::PresentValue, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR BinaryInputBasicCluster::ReadAttributeStatusFlags(Callback::Cancelable * onSuccessCallback, @@ -1301,21 +1297,19 @@ CHIP_ERROR BinaryInputBasicCluster::ConfigureAttributeStatusFlags(Callback::Canc Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval) { - COMMAND_HEADER("ReportBinaryInputBasicStatusFlags", BinaryInputBasic::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(BinaryInputBasic::Attributes::Ids::StatusFlags) - .Put8(24) - .Put16(minInterval) - .Put16(maxInterval); - COMMAND_FOOTER(); + + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = BinaryInputBasic::Attributes::Ids::StatusFlags; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR BinaryInputBasicCluster::ReportAttributeStatusFlags(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x006F, onReportCallback); + return RequestAttributeReporting(BinaryInputBasic::Attributes::Ids::StatusFlags, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR BinaryInputBasicCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback, @@ -2622,22 +2616,19 @@ CHIP_ERROR ColorControlCluster::ConfigureAttributeCurrentHue(Callback::Cancelabl Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval, uint8_t change) { - COMMAND_HEADER("ReportColorControlCurrentHue", ColorControl::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(ColorControl::Attributes::Ids::CurrentHue) - .Put8(32) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put8(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = ColorControl::Attributes::Ids::CurrentHue; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR ColorControlCluster::ReportAttributeCurrentHue(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0000, onReportCallback); + return RequestAttributeReporting(ColorControl::Attributes::Ids::CurrentHue, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR ColorControlCluster::ReadAttributeCurrentSaturation(Callback::Cancelable * onSuccessCallback, @@ -2656,22 +2647,19 @@ CHIP_ERROR ColorControlCluster::ConfigureAttributeCurrentSaturation(Callback::Ca Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval, uint8_t change) { - COMMAND_HEADER("ReportColorControlCurrentSaturation", ColorControl::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(ColorControl::Attributes::Ids::CurrentSaturation) - .Put8(32) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put8(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = ColorControl::Attributes::Ids::CurrentSaturation; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR ColorControlCluster::ReportAttributeCurrentSaturation(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0001, onReportCallback); + return RequestAttributeReporting(ColorControl::Attributes::Ids::CurrentSaturation, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR ColorControlCluster::ReadAttributeRemainingTime(Callback::Cancelable * onSuccessCallback, @@ -2702,22 +2690,19 @@ CHIP_ERROR ColorControlCluster::ConfigureAttributeCurrentX(Callback::Cancelable Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval, uint16_t change) { - COMMAND_HEADER("ReportColorControlCurrentX", ColorControl::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(ColorControl::Attributes::Ids::CurrentX) - .Put8(33) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = ColorControl::Attributes::Ids::CurrentX; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR ColorControlCluster::ReportAttributeCurrentX(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0003, onReportCallback); + return RequestAttributeReporting(ColorControl::Attributes::Ids::CurrentX, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR ColorControlCluster::ReadAttributeCurrentY(Callback::Cancelable * onSuccessCallback, @@ -2736,22 +2721,19 @@ CHIP_ERROR ColorControlCluster::ConfigureAttributeCurrentY(Callback::Cancelable Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval, uint16_t change) { - COMMAND_HEADER("ReportColorControlCurrentY", ColorControl::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(ColorControl::Attributes::Ids::CurrentY) - .Put8(33) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = ColorControl::Attributes::Ids::CurrentY; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR ColorControlCluster::ReportAttributeCurrentY(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0004, onReportCallback); + return RequestAttributeReporting(ColorControl::Attributes::Ids::CurrentY, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR ColorControlCluster::ReadAttributeDriftCompensation(Callback::Cancelable * onSuccessCallback, @@ -2794,22 +2776,19 @@ CHIP_ERROR ColorControlCluster::ConfigureAttributeColorTemperature(Callback::Can Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval, uint16_t change) { - COMMAND_HEADER("ReportColorControlColorTemperature", ColorControl::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(ColorControl::Attributes::Ids::ColorTemperature) - .Put8(33) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = ColorControl::Attributes::Ids::ColorTemperature; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR ColorControlCluster::ReportAttributeColorTemperature(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0007, onReportCallback); + return RequestAttributeReporting(ColorControl::Attributes::Ids::ColorTemperature, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR ColorControlCluster::ReadAttributeColorMode(Callback::Cancelable * onSuccessCallback, @@ -4844,21 +4823,19 @@ CHIP_ERROR DoorLockCluster::ConfigureAttributeLockState(Callback::Cancelable * o Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval) { - COMMAND_HEADER("ReportDoorLockLockState", DoorLock::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(DoorLock::Attributes::Ids::LockState) - .Put8(48) - .Put16(minInterval) - .Put16(maxInterval); - COMMAND_FOOTER(); + + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = DoorLock::Attributes::Ids::LockState; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR DoorLockCluster::ReportAttributeLockState(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0000, onReportCallback); + return RequestAttributeReporting(DoorLock::Attributes::Ids::LockState, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR DoorLockCluster::ReadAttributeLockType(Callback::Cancelable * onSuccessCallback, @@ -6411,22 +6388,19 @@ CHIP_ERROR LevelControlCluster::ConfigureAttributeCurrentLevel(Callback::Cancela Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval, uint8_t change) { - COMMAND_HEADER("ReportLevelControlCurrentLevel", LevelControl::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(LevelControl::Attributes::Ids::CurrentLevel) - .Put8(32) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put8(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = LevelControl::Attributes::Ids::CurrentLevel; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR LevelControlCluster::ReportAttributeCurrentLevel(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0000, onReportCallback); + return RequestAttributeReporting(LevelControl::Attributes::Ids::CurrentLevel, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR LevelControlCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback, @@ -7812,21 +7786,19 @@ CHIP_ERROR OccupancySensingCluster::ConfigureAttributeOccupancy(Callback::Cancel Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval) { - COMMAND_HEADER("ReportOccupancySensingOccupancy", OccupancySensing::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(OccupancySensing::Attributes::Ids::Occupancy) - .Put8(24) - .Put16(minInterval) - .Put16(maxInterval); - COMMAND_FOOTER(); + + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = OccupancySensing::Attributes::Ids::Occupancy; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR OccupancySensingCluster::ReportAttributeOccupancy(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0000, onReportCallback); + return RequestAttributeReporting(OccupancySensing::Attributes::Ids::Occupancy, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR OccupancySensingCluster::ReadAttributeOccupancySensorType(Callback::Cancelable * onSuccessCallback, @@ -8128,21 +8100,19 @@ CHIP_ERROR OnOffCluster::ReadAttributeOnOff(Callback::Cancelable * onSuccessCall CHIP_ERROR OnOffCluster::ConfigureAttributeOnOff(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval) { - COMMAND_HEADER("ReportOnOffOnOff", OnOff::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(OnOff::Attributes::Ids::OnOff) - .Put8(16) - .Put16(minInterval) - .Put16(maxInterval); - COMMAND_FOOTER(); + + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = OnOff::Attributes::Ids::OnOff; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR OnOffCluster::ReportAttributeOnOff(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0000, onReportCallback); + return RequestAttributeReporting(OnOff::Attributes::Ids::OnOff, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR OnOffCluster::ReadAttributeGlobalSceneControl(Callback::Cancelable * onSuccessCallback, @@ -8714,22 +8684,19 @@ CHIP_ERROR PressureMeasurementCluster::ConfigureAttributeMeasuredValue(Callback: Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval, int16_t change) { - COMMAND_HEADER("ReportPressureMeasurementMeasuredValue", PressureMeasurement::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(PressureMeasurement::Attributes::Ids::MeasuredValue) - .Put8(41) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = PressureMeasurement::Attributes::Ids::MeasuredValue; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR PressureMeasurementCluster::ReportAttributeMeasuredValue(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0000, onReportCallback); + return RequestAttributeReporting(PressureMeasurement::Attributes::Ids::MeasuredValue, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR PressureMeasurementCluster::ReadAttributeMinMeasuredValue(Callback::Cancelable * onSuccessCallback, @@ -8855,22 +8822,19 @@ CHIP_ERROR PumpConfigurationAndControlCluster::ConfigureAttributeCapacity(Callba uint16_t minInterval, uint16_t maxInterval, int16_t change) { - COMMAND_HEADER("ReportPumpConfigurationAndControlCapacity", PumpConfigurationAndControl::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(PumpConfigurationAndControl::Attributes::Ids::Capacity) - .Put8(41) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = PumpConfigurationAndControl::Attributes::Ids::Capacity; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR PumpConfigurationAndControlCluster::ReportAttributeCapacity(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0013, onReportCallback); + return RequestAttributeReporting(PumpConfigurationAndControl::Attributes::Ids::Capacity, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR PumpConfigurationAndControlCluster::ReadAttributeOperationMode(Callback::Cancelable * onSuccessCallback, @@ -8941,22 +8905,19 @@ CHIP_ERROR RelativeHumidityMeasurementCluster::ConfigureAttributeMeasuredValue(C uint16_t minInterval, uint16_t maxInterval, uint16_t change) { - COMMAND_HEADER("ReportRelativeHumidityMeasurementMeasuredValue", RelativeHumidityMeasurement::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(RelativeHumidityMeasurement::Attributes::Ids::MeasuredValue) - .Put8(33) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = RelativeHumidityMeasurement::Attributes::Ids::MeasuredValue; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR RelativeHumidityMeasurementCluster::ReportAttributeMeasuredValue(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0000, onReportCallback); + return RequestAttributeReporting(RelativeHumidityMeasurement::Attributes::Ids::MeasuredValue, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR RelativeHumidityMeasurementCluster::ReadAttributeMinMeasuredValue(Callback::Cancelable * onSuccessCallback, @@ -9497,22 +9458,19 @@ CHIP_ERROR SwitchCluster::ConfigureAttributeCurrentPosition(Callback::Cancelable Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval, uint8_t change) { - COMMAND_HEADER("ReportSwitchCurrentPosition", Switch::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(Switch::Attributes::Ids::CurrentPosition) - .Put8(32) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put8(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = Switch::Attributes::Ids::CurrentPosition; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR SwitchCluster::ReportAttributeCurrentPosition(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0001, onReportCallback); + return RequestAttributeReporting(Switch::Attributes::Ids::CurrentPosition, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR SwitchCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback, @@ -9814,22 +9772,19 @@ CHIP_ERROR TemperatureMeasurementCluster::ConfigureAttributeMeasuredValue(Callba uint16_t minInterval, uint16_t maxInterval, int16_t change) { - COMMAND_HEADER("ReportTemperatureMeasurementMeasuredValue", TemperatureMeasurement::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(TemperatureMeasurement::Attributes::Ids::MeasuredValue) - .Put8(41) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = TemperatureMeasurement::Attributes::Ids::MeasuredValue; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR TemperatureMeasurementCluster::ReportAttributeMeasuredValue(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0000, onReportCallback); + return RequestAttributeReporting(TemperatureMeasurement::Attributes::Ids::MeasuredValue, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR TemperatureMeasurementCluster::ReadAttributeMinMeasuredValue(Callback::Cancelable * onSuccessCallback, @@ -10938,22 +10893,19 @@ CHIP_ERROR ThermostatCluster::ConfigureAttributeLocalTemperature(Callback::Cance Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval, int16_t change) { - COMMAND_HEADER("ReportThermostatLocalTemperature", Thermostat::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(Thermostat::Attributes::Ids::LocalTemperature) - .Put8(41) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = Thermostat::Attributes::Ids::LocalTemperature; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR ThermostatCluster::ReportAttributeLocalTemperature(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0000, onReportCallback); + return RequestAttributeReporting(Thermostat::Attributes::Ids::LocalTemperature, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR ThermostatCluster::ReadAttributeAbsMinHeatSetpointLimit(Callback::Cancelable * onSuccessCallback, @@ -12704,22 +12656,19 @@ CHIP_ERROR WindowCoveringCluster::ConfigureAttributeCurrentPositionLiftPercentag uint16_t minInterval, uint16_t maxInterval, uint8_t change) { - COMMAND_HEADER("ReportWindowCoveringCurrentPositionLiftPercentage", WindowCovering::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(WindowCovering::Attributes::Ids::CurrentPositionLiftPercentage) - .Put8(32) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put8(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = WindowCovering::Attributes::Ids::CurrentPositionLiftPercentage; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR WindowCoveringCluster::ReportAttributeCurrentPositionLiftPercentage(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0008, onReportCallback); + return RequestAttributeReporting(WindowCovering::Attributes::Ids::CurrentPositionLiftPercentage, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR WindowCoveringCluster::ReadAttributeCurrentPositionTiltPercentage(Callback::Cancelable * onSuccessCallback, @@ -12739,22 +12688,19 @@ CHIP_ERROR WindowCoveringCluster::ConfigureAttributeCurrentPositionTiltPercentag uint16_t minInterval, uint16_t maxInterval, uint8_t change) { - COMMAND_HEADER("ReportWindowCoveringCurrentPositionTiltPercentage", WindowCovering::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(WindowCovering::Attributes::Ids::CurrentPositionTiltPercentage) - .Put8(32) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put8(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = WindowCovering::Attributes::Ids::CurrentPositionTiltPercentage; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR WindowCoveringCluster::ReportAttributeCurrentPositionTiltPercentage(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0009, onReportCallback); + return RequestAttributeReporting(WindowCovering::Attributes::Ids::CurrentPositionTiltPercentage, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR WindowCoveringCluster::ReadAttributeOperationalStatus(Callback::Cancelable * onSuccessCallback, @@ -12773,21 +12719,19 @@ CHIP_ERROR WindowCoveringCluster::ConfigureAttributeOperationalStatus(Callback:: Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval) { - COMMAND_HEADER("ReportWindowCoveringOperationalStatus", WindowCovering::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(WindowCovering::Attributes::Ids::OperationalStatus) - .Put8(24) - .Put16(minInterval) - .Put16(maxInterval); - COMMAND_FOOTER(); + + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = WindowCovering::Attributes::Ids::OperationalStatus; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR WindowCoveringCluster::ReportAttributeOperationalStatus(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x000A, onReportCallback); + return RequestAttributeReporting(WindowCovering::Attributes::Ids::OperationalStatus, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR WindowCoveringCluster::ReadAttributeTargetPositionLiftPercent100ths(Callback::Cancelable * onSuccessCallback, @@ -12807,22 +12751,19 @@ CHIP_ERROR WindowCoveringCluster::ConfigureAttributeTargetPositionLiftPercent100 uint16_t minInterval, uint16_t maxInterval, uint16_t change) { - COMMAND_HEADER("ReportWindowCoveringTargetPositionLiftPercent100ths", WindowCovering::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(WindowCovering::Attributes::Ids::TargetPositionLiftPercent100ths) - .Put8(33) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = WindowCovering::Attributes::Ids::TargetPositionLiftPercent100ths; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR WindowCoveringCluster::ReportAttributeTargetPositionLiftPercent100ths(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x000B, onReportCallback); + return RequestAttributeReporting(WindowCovering::Attributes::Ids::TargetPositionLiftPercent100ths, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR WindowCoveringCluster::ReadAttributeTargetPositionTiltPercent100ths(Callback::Cancelable * onSuccessCallback, @@ -12842,22 +12783,19 @@ CHIP_ERROR WindowCoveringCluster::ConfigureAttributeTargetPositionTiltPercent100 uint16_t minInterval, uint16_t maxInterval, uint16_t change) { - COMMAND_HEADER("ReportWindowCoveringTargetPositionTiltPercent100ths", WindowCovering::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(WindowCovering::Attributes::Ids::TargetPositionTiltPercent100ths) - .Put8(33) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = WindowCovering::Attributes::Ids::TargetPositionTiltPercent100ths; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR WindowCoveringCluster::ReportAttributeTargetPositionTiltPercent100ths(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x000C, onReportCallback); + return RequestAttributeReporting(WindowCovering::Attributes::Ids::TargetPositionTiltPercent100ths, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR WindowCoveringCluster::ReadAttributeEndProductType(Callback::Cancelable * onSuccessCallback, @@ -12889,22 +12827,19 @@ CHIP_ERROR WindowCoveringCluster::ConfigureAttributeCurrentPositionLiftPercent10 uint16_t minInterval, uint16_t maxInterval, uint16_t change) { - COMMAND_HEADER("ReportWindowCoveringCurrentPositionLiftPercent100ths", WindowCovering::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(WindowCovering::Attributes::Ids::CurrentPositionLiftPercent100ths) - .Put8(33) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = WindowCovering::Attributes::Ids::CurrentPositionLiftPercent100ths; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR WindowCoveringCluster::ReportAttributeCurrentPositionLiftPercent100ths(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x000E, onReportCallback); + return RequestAttributeReporting(WindowCovering::Attributes::Ids::CurrentPositionLiftPercent100ths, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR WindowCoveringCluster::ReadAttributeCurrentPositionTiltPercent100ths(Callback::Cancelable * onSuccessCallback, @@ -12924,22 +12859,19 @@ CHIP_ERROR WindowCoveringCluster::ConfigureAttributeCurrentPositionTiltPercent10 uint16_t minInterval, uint16_t maxInterval, uint16_t change) { - COMMAND_HEADER("ReportWindowCoveringCurrentPositionTiltPercent100ths", WindowCovering::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(WindowCovering::Attributes::Ids::CurrentPositionTiltPercent100ths) - .Put8(33) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = WindowCovering::Attributes::Ids::CurrentPositionTiltPercent100ths; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR WindowCoveringCluster::ReportAttributeCurrentPositionTiltPercent100ths(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x000F, onReportCallback); + return RequestAttributeReporting(WindowCovering::Attributes::Ids::CurrentPositionTiltPercent100ths, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR WindowCoveringCluster::ReadAttributeInstalledOpenLimitLift(Callback::Cancelable * onSuccessCallback, @@ -13035,21 +12967,19 @@ CHIP_ERROR WindowCoveringCluster::ConfigureAttributeSafetyStatus(Callback::Cance Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval) { - COMMAND_HEADER("ReportWindowCoveringSafetyStatus", WindowCovering::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(WindowCovering::Attributes::Ids::SafetyStatus) - .Put8(25) - .Put16(minInterval) - .Put16(maxInterval); - COMMAND_FOOTER(); + + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = WindowCovering::Attributes::Ids::SafetyStatus; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR WindowCoveringCluster::ReportAttributeSafetyStatus(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x001A, onReportCallback); + return RequestAttributeReporting(WindowCovering::Attributes::Ids::SafetyStatus, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR WindowCoveringCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback, diff --git a/zzz_generated/lighting-app/zap-generated/CHIPClientCallbacks.cpp b/zzz_generated/lighting-app/zap-generated/CHIPClientCallbacks.cpp index e5c220dd2c98b9..33694badf51838 100644 --- a/zzz_generated/lighting-app/zap-generated/CHIPClientCallbacks.cpp +++ b/zzz_generated/lighting-app/zap-generated/CHIPClientCallbacks.cpp @@ -350,252 +350,3 @@ bool emberAfDiscoverCommandsReceivedResponseCallback(ClusterId clusterId, uint16 cb->mCall(cb->mContext); return true; } - -bool emberAfReportAttributesCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen) -{ - ChipLogProgress(Zcl, "emberAfReportAttributeCallback:"); - ChipLogProgress(Zcl, " ClusterId: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); - - NodeId sourceId = emberAfCurrentCommand()->SourceNodeId(); - ChipLogProgress(Zcl, " Source NodeId: %" PRIu64, sourceId); - - EndpointId endpointId = emberAfCurrentCommand()->apsFrame->sourceEndpoint; - ChipLogProgress(Zcl, " Source EndpointId: 0x%04x", endpointId); - - // TODO onFailureCallback is just here because of the CHECK_MESSAGE_LENGTH macro. It needs to be removed. - Callback::Cancelable * onFailureCallback = nullptr; - - while (messageLen) - { - CHECK_MESSAGE_LENGTH(4); - AttributeId attributeId = Encoding::LittleEndian::Read32(message); // attribId - ChipLogProgress(Zcl, " attributeId: " ChipLogFormatMEI, ChipLogValueMEI(attributeId)); - - GET_REPORT_CALLBACK("emberAfReportAttributesCallback"); - - CHECK_MESSAGE_LENGTH(1); - uint8_t attributeType = Encoding::Read8(message); - ChipLogProgress(Zcl, " attributeType: 0x%02x", attributeType); - - switch (attributeType) - { - case 0x00: // nodata / No data - case 0x0A: // data24 / 24-bit data - case 0x0C: // data40 / 40-bit data - case 0x0D: // data48 / 48-bit data - case 0x0E: // data56 / 56-bit data - case 0x1A: // map24 / 24-bit bitmap - case 0x1C: // map40 / 40-bit bitmap - case 0x1D: // map48 / 48-bit bitmap - case 0x1E: // map56 / 56-bit bitmap - case 0x22: // uint24 / Unsigned 24-bit integer - case 0x24: // uint40 / Unsigned 40-bit integer - case 0x25: // uint48 / Unsigned 48-bit integer - case 0x26: // uint56 / Unsigned 56-bit integer - case 0x2A: // int24 / Signed 24-bit integer - case 0x2C: // int40 / Signed 40-bit integer - case 0x2D: // int48 / Signed 48-bit integer - case 0x2E: // int56 / Signed 56-bit integer - case 0x38: // semi / Semi-precision - case 0x39: // single / Single precision - case 0x3A: // double / Double precision - case 0x48: // array / Array - case 0x49: // struct / Structure - case 0x50: // set / Set - case 0x51: // bag / Bag - case 0xE0: // ToD / Time of day - { - ChipLogError(Zcl, "attributeType 0x%02x is not supported", attributeType); - return true; - } - - case 0x41: // octstr / Octet string - case 0x42: // string / Character string - { - // Short Strings must contains at least one byte for the length - CHECK_MESSAGE_LENGTH(1); - uint8_t length = Encoding::Read8(message); - ChipLogProgress(Zcl, " length: 0x%02x", length); - - // When the length is set to 0xFF, it represents a non-value. In this case the data field is zero length. - if (length == 0xFF) - { - length = 0; - } - - CHECK_MESSAGE_LENGTH(length); - if (attributeType == 0x41) - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - else - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - break; - } - - case 0x43: // octstr16 / Long octet string - case 0x44: // string16 / Long character string - { - // Long Strings must contains at least two bytes for the length - CHECK_MESSAGE_LENGTH(2); - uint16_t length = Encoding::LittleEndian::Read16(message); - ChipLogProgress(Zcl, " length: 0x%02x", length); - - // When the length is set to 0xFFFF, it represents a non-value. In this case the data field is zero length. - if (length == 0xFFFF) - { - length = 0; - } - - CHECK_MESSAGE_LENGTH(length); - if (attributeType == 0x43) - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - else - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - break; - } - - case 0x08: // data8 / 8-bit data - case 0x18: // map8 / 8-bit bitmap - case 0x20: // uint8 / Unsigned 8-bit integer - case 0x30: // enum8 / 8-bit enumeration - { - CHECK_MESSAGE_LENGTH(1); - uint8_t value = Encoding::Read8(message); - ChipLogProgress(Zcl, " value: 0x%02x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x09: // data16 / 16-bit data - case 0x19: // map16 / 16-bit bitmap - case 0x21: // uint16 / Unsigned 16-bit integer - case 0x31: // enum16 / 16-bit enumeration - case 0xE8: // clusterId / Cluster ID - case 0xE9: // attribId / Attribute ID - case 0xEA: // bacOID / BACnet OID - case 0xF1: // key128 / 128-bit security key - case 0xFF: // unk / Unknown - { - CHECK_MESSAGE_LENGTH(2); - uint16_t value = Encoding::LittleEndian::Read16(message); - ChipLogProgress(Zcl, " value: 0x%04x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x0B: // data32 / 32-bit data - case 0x1B: // map32 / 32-bit bitmap - case 0x23: // uint32 / Unsigned 32-bit integer - case 0xE1: // date / Date - case 0xE2: // UTC / UTCTime - { - CHECK_MESSAGE_LENGTH(4); - uint32_t value = Encoding::LittleEndian::Read32(message); - ChipLogProgress(Zcl, " value: 0x%08x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x0F: // data64 / 64-bit data - case 0x1F: // map64 / 64-bit bitmap - case 0x27: // uint64 / Unsigned 64-bit integer - case 0xF0: // EUI64 / IEEE address - { - CHECK_MESSAGE_LENGTH(8); - uint64_t value = Encoding::LittleEndian::Read64(message); - ChipLogProgress(Zcl, " value: 0x" ChipLogFormatX64, ChipLogValueX64(value)); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x10: // bool / Boolean - { - CHECK_MESSAGE_LENGTH(1); - uint8_t value = Encoding::Read8(message); - ChipLogProgress(Zcl, " value: %d", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x28: // int8 / Signed 8-bit integer - { - CHECK_MESSAGE_LENGTH(1); - int8_t value = CastToSigned(Encoding::Read8(message)); - ChipLogProgress(Zcl, " value: %" PRId8, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x29: // int16 / Signed 16-bit integer - { - CHECK_MESSAGE_LENGTH(2); - int16_t value = CastToSigned(Encoding::LittleEndian::Read16(message)); - ChipLogProgress(Zcl, " value: %" PRId16, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x2B: // int32 / Signed 32-bit integer - { - CHECK_MESSAGE_LENGTH(4); - int32_t value = CastToSigned(Encoding::LittleEndian::Read32(message)); - ChipLogProgress(Zcl, " value: %" PRId32, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x2F: // int64 / Signed 64-bit integer - { - CHECK_MESSAGE_LENGTH(8); - int64_t value = CastToSigned(Encoding::LittleEndian::Read64(message)); - ChipLogProgress(Zcl, " value: %" PRId64, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - } - } - - return true; -} diff --git a/zzz_generated/lighting-app/zap-generated/CHIPClusters.cpp b/zzz_generated/lighting-app/zap-generated/CHIPClusters.cpp index 541efcc26190ca..85c9e30b60229c 100644 --- a/zzz_generated/lighting-app/zap-generated/CHIPClusters.cpp +++ b/zzz_generated/lighting-app/zap-generated/CHIPClusters.cpp @@ -67,8 +67,6 @@ constexpr uint8_t kFrameControlGlobalCommand = 0x00; // Pick source endpoint as 1 for now constexpr EndpointId kSourceEndpoint = 1; - -[[maybe_unused]] const uint8_t kReportingDirectionReported = 0x00; } // namespace using namespace app::Clusters; diff --git a/zzz_generated/pump-app/zap-generated/CHIPClientCallbacks.cpp b/zzz_generated/pump-app/zap-generated/CHIPClientCallbacks.cpp index e5c220dd2c98b9..33694badf51838 100644 --- a/zzz_generated/pump-app/zap-generated/CHIPClientCallbacks.cpp +++ b/zzz_generated/pump-app/zap-generated/CHIPClientCallbacks.cpp @@ -350,252 +350,3 @@ bool emberAfDiscoverCommandsReceivedResponseCallback(ClusterId clusterId, uint16 cb->mCall(cb->mContext); return true; } - -bool emberAfReportAttributesCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen) -{ - ChipLogProgress(Zcl, "emberAfReportAttributeCallback:"); - ChipLogProgress(Zcl, " ClusterId: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); - - NodeId sourceId = emberAfCurrentCommand()->SourceNodeId(); - ChipLogProgress(Zcl, " Source NodeId: %" PRIu64, sourceId); - - EndpointId endpointId = emberAfCurrentCommand()->apsFrame->sourceEndpoint; - ChipLogProgress(Zcl, " Source EndpointId: 0x%04x", endpointId); - - // TODO onFailureCallback is just here because of the CHECK_MESSAGE_LENGTH macro. It needs to be removed. - Callback::Cancelable * onFailureCallback = nullptr; - - while (messageLen) - { - CHECK_MESSAGE_LENGTH(4); - AttributeId attributeId = Encoding::LittleEndian::Read32(message); // attribId - ChipLogProgress(Zcl, " attributeId: " ChipLogFormatMEI, ChipLogValueMEI(attributeId)); - - GET_REPORT_CALLBACK("emberAfReportAttributesCallback"); - - CHECK_MESSAGE_LENGTH(1); - uint8_t attributeType = Encoding::Read8(message); - ChipLogProgress(Zcl, " attributeType: 0x%02x", attributeType); - - switch (attributeType) - { - case 0x00: // nodata / No data - case 0x0A: // data24 / 24-bit data - case 0x0C: // data40 / 40-bit data - case 0x0D: // data48 / 48-bit data - case 0x0E: // data56 / 56-bit data - case 0x1A: // map24 / 24-bit bitmap - case 0x1C: // map40 / 40-bit bitmap - case 0x1D: // map48 / 48-bit bitmap - case 0x1E: // map56 / 56-bit bitmap - case 0x22: // uint24 / Unsigned 24-bit integer - case 0x24: // uint40 / Unsigned 40-bit integer - case 0x25: // uint48 / Unsigned 48-bit integer - case 0x26: // uint56 / Unsigned 56-bit integer - case 0x2A: // int24 / Signed 24-bit integer - case 0x2C: // int40 / Signed 40-bit integer - case 0x2D: // int48 / Signed 48-bit integer - case 0x2E: // int56 / Signed 56-bit integer - case 0x38: // semi / Semi-precision - case 0x39: // single / Single precision - case 0x3A: // double / Double precision - case 0x48: // array / Array - case 0x49: // struct / Structure - case 0x50: // set / Set - case 0x51: // bag / Bag - case 0xE0: // ToD / Time of day - { - ChipLogError(Zcl, "attributeType 0x%02x is not supported", attributeType); - return true; - } - - case 0x41: // octstr / Octet string - case 0x42: // string / Character string - { - // Short Strings must contains at least one byte for the length - CHECK_MESSAGE_LENGTH(1); - uint8_t length = Encoding::Read8(message); - ChipLogProgress(Zcl, " length: 0x%02x", length); - - // When the length is set to 0xFF, it represents a non-value. In this case the data field is zero length. - if (length == 0xFF) - { - length = 0; - } - - CHECK_MESSAGE_LENGTH(length); - if (attributeType == 0x41) - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - else - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - break; - } - - case 0x43: // octstr16 / Long octet string - case 0x44: // string16 / Long character string - { - // Long Strings must contains at least two bytes for the length - CHECK_MESSAGE_LENGTH(2); - uint16_t length = Encoding::LittleEndian::Read16(message); - ChipLogProgress(Zcl, " length: 0x%02x", length); - - // When the length is set to 0xFFFF, it represents a non-value. In this case the data field is zero length. - if (length == 0xFFFF) - { - length = 0; - } - - CHECK_MESSAGE_LENGTH(length); - if (attributeType == 0x43) - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - else - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - break; - } - - case 0x08: // data8 / 8-bit data - case 0x18: // map8 / 8-bit bitmap - case 0x20: // uint8 / Unsigned 8-bit integer - case 0x30: // enum8 / 8-bit enumeration - { - CHECK_MESSAGE_LENGTH(1); - uint8_t value = Encoding::Read8(message); - ChipLogProgress(Zcl, " value: 0x%02x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x09: // data16 / 16-bit data - case 0x19: // map16 / 16-bit bitmap - case 0x21: // uint16 / Unsigned 16-bit integer - case 0x31: // enum16 / 16-bit enumeration - case 0xE8: // clusterId / Cluster ID - case 0xE9: // attribId / Attribute ID - case 0xEA: // bacOID / BACnet OID - case 0xF1: // key128 / 128-bit security key - case 0xFF: // unk / Unknown - { - CHECK_MESSAGE_LENGTH(2); - uint16_t value = Encoding::LittleEndian::Read16(message); - ChipLogProgress(Zcl, " value: 0x%04x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x0B: // data32 / 32-bit data - case 0x1B: // map32 / 32-bit bitmap - case 0x23: // uint32 / Unsigned 32-bit integer - case 0xE1: // date / Date - case 0xE2: // UTC / UTCTime - { - CHECK_MESSAGE_LENGTH(4); - uint32_t value = Encoding::LittleEndian::Read32(message); - ChipLogProgress(Zcl, " value: 0x%08x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x0F: // data64 / 64-bit data - case 0x1F: // map64 / 64-bit bitmap - case 0x27: // uint64 / Unsigned 64-bit integer - case 0xF0: // EUI64 / IEEE address - { - CHECK_MESSAGE_LENGTH(8); - uint64_t value = Encoding::LittleEndian::Read64(message); - ChipLogProgress(Zcl, " value: 0x" ChipLogFormatX64, ChipLogValueX64(value)); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x10: // bool / Boolean - { - CHECK_MESSAGE_LENGTH(1); - uint8_t value = Encoding::Read8(message); - ChipLogProgress(Zcl, " value: %d", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x28: // int8 / Signed 8-bit integer - { - CHECK_MESSAGE_LENGTH(1); - int8_t value = CastToSigned(Encoding::Read8(message)); - ChipLogProgress(Zcl, " value: %" PRId8, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x29: // int16 / Signed 16-bit integer - { - CHECK_MESSAGE_LENGTH(2); - int16_t value = CastToSigned(Encoding::LittleEndian::Read16(message)); - ChipLogProgress(Zcl, " value: %" PRId16, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x2B: // int32 / Signed 32-bit integer - { - CHECK_MESSAGE_LENGTH(4); - int32_t value = CastToSigned(Encoding::LittleEndian::Read32(message)); - ChipLogProgress(Zcl, " value: %" PRId32, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x2F: // int64 / Signed 64-bit integer - { - CHECK_MESSAGE_LENGTH(8); - int64_t value = CastToSigned(Encoding::LittleEndian::Read64(message)); - ChipLogProgress(Zcl, " value: %" PRId64, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - } - } - - return true; -} diff --git a/zzz_generated/pump-app/zap-generated/CHIPClusters.cpp b/zzz_generated/pump-app/zap-generated/CHIPClusters.cpp index a5cbbc3f366b40..45de1d65c879d2 100644 --- a/zzz_generated/pump-app/zap-generated/CHIPClusters.cpp +++ b/zzz_generated/pump-app/zap-generated/CHIPClusters.cpp @@ -67,8 +67,6 @@ constexpr uint8_t kFrameControlGlobalCommand = 0x00; // Pick source endpoint as 1 for now constexpr EndpointId kSourceEndpoint = 1; - -[[maybe_unused]] const uint8_t kReportingDirectionReported = 0x00; } // namespace using namespace app::Clusters; @@ -107,22 +105,19 @@ CHIP_ERROR FlowMeasurementCluster::ConfigureAttributeMeasuredValue(Callback::Can Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval, int16_t change) { - COMMAND_HEADER("ReportFlowMeasurementMeasuredValue", FlowMeasurement::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(FlowMeasurement::Attributes::Ids::MeasuredValue) - .Put8(41) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = FlowMeasurement::Attributes::Ids::MeasuredValue; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR FlowMeasurementCluster::ReportAttributeMeasuredValue(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0000, onReportCallback); + return RequestAttributeReporting(FlowMeasurement::Attributes::Ids::MeasuredValue, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR FlowMeasurementCluster::ReadAttributeMinMeasuredValue(Callback::Cancelable * onSuccessCallback, @@ -187,22 +182,19 @@ CHIP_ERROR PressureMeasurementCluster::ConfigureAttributeMeasuredValue(Callback: Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval, int16_t change) { - COMMAND_HEADER("ReportPressureMeasurementMeasuredValue", PressureMeasurement::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(PressureMeasurement::Attributes::Ids::MeasuredValue) - .Put8(41) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = PressureMeasurement::Attributes::Ids::MeasuredValue; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR PressureMeasurementCluster::ReportAttributeMeasuredValue(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0000, onReportCallback); + return RequestAttributeReporting(PressureMeasurement::Attributes::Ids::MeasuredValue, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR PressureMeasurementCluster::ReadAttributeMinMeasuredValue(Callback::Cancelable * onSuccessCallback, @@ -268,22 +260,19 @@ CHIP_ERROR TemperatureMeasurementCluster::ConfigureAttributeMeasuredValue(Callba uint16_t minInterval, uint16_t maxInterval, int16_t change) { - COMMAND_HEADER("ReportTemperatureMeasurementMeasuredValue", TemperatureMeasurement::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(TemperatureMeasurement::Attributes::Ids::MeasuredValue) - .Put8(41) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = TemperatureMeasurement::Attributes::Ids::MeasuredValue; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR TemperatureMeasurementCluster::ReportAttributeMeasuredValue(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0000, onReportCallback); + return RequestAttributeReporting(TemperatureMeasurement::Attributes::Ids::MeasuredValue, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR TemperatureMeasurementCluster::ReadAttributeMinMeasuredValue(Callback::Cancelable * onSuccessCallback, diff --git a/zzz_generated/pump-controller-app/zap-generated/CHIPClientCallbacks.cpp b/zzz_generated/pump-controller-app/zap-generated/CHIPClientCallbacks.cpp index e5c220dd2c98b9..33694badf51838 100644 --- a/zzz_generated/pump-controller-app/zap-generated/CHIPClientCallbacks.cpp +++ b/zzz_generated/pump-controller-app/zap-generated/CHIPClientCallbacks.cpp @@ -350,252 +350,3 @@ bool emberAfDiscoverCommandsReceivedResponseCallback(ClusterId clusterId, uint16 cb->mCall(cb->mContext); return true; } - -bool emberAfReportAttributesCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen) -{ - ChipLogProgress(Zcl, "emberAfReportAttributeCallback:"); - ChipLogProgress(Zcl, " ClusterId: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); - - NodeId sourceId = emberAfCurrentCommand()->SourceNodeId(); - ChipLogProgress(Zcl, " Source NodeId: %" PRIu64, sourceId); - - EndpointId endpointId = emberAfCurrentCommand()->apsFrame->sourceEndpoint; - ChipLogProgress(Zcl, " Source EndpointId: 0x%04x", endpointId); - - // TODO onFailureCallback is just here because of the CHECK_MESSAGE_LENGTH macro. It needs to be removed. - Callback::Cancelable * onFailureCallback = nullptr; - - while (messageLen) - { - CHECK_MESSAGE_LENGTH(4); - AttributeId attributeId = Encoding::LittleEndian::Read32(message); // attribId - ChipLogProgress(Zcl, " attributeId: " ChipLogFormatMEI, ChipLogValueMEI(attributeId)); - - GET_REPORT_CALLBACK("emberAfReportAttributesCallback"); - - CHECK_MESSAGE_LENGTH(1); - uint8_t attributeType = Encoding::Read8(message); - ChipLogProgress(Zcl, " attributeType: 0x%02x", attributeType); - - switch (attributeType) - { - case 0x00: // nodata / No data - case 0x0A: // data24 / 24-bit data - case 0x0C: // data40 / 40-bit data - case 0x0D: // data48 / 48-bit data - case 0x0E: // data56 / 56-bit data - case 0x1A: // map24 / 24-bit bitmap - case 0x1C: // map40 / 40-bit bitmap - case 0x1D: // map48 / 48-bit bitmap - case 0x1E: // map56 / 56-bit bitmap - case 0x22: // uint24 / Unsigned 24-bit integer - case 0x24: // uint40 / Unsigned 40-bit integer - case 0x25: // uint48 / Unsigned 48-bit integer - case 0x26: // uint56 / Unsigned 56-bit integer - case 0x2A: // int24 / Signed 24-bit integer - case 0x2C: // int40 / Signed 40-bit integer - case 0x2D: // int48 / Signed 48-bit integer - case 0x2E: // int56 / Signed 56-bit integer - case 0x38: // semi / Semi-precision - case 0x39: // single / Single precision - case 0x3A: // double / Double precision - case 0x48: // array / Array - case 0x49: // struct / Structure - case 0x50: // set / Set - case 0x51: // bag / Bag - case 0xE0: // ToD / Time of day - { - ChipLogError(Zcl, "attributeType 0x%02x is not supported", attributeType); - return true; - } - - case 0x41: // octstr / Octet string - case 0x42: // string / Character string - { - // Short Strings must contains at least one byte for the length - CHECK_MESSAGE_LENGTH(1); - uint8_t length = Encoding::Read8(message); - ChipLogProgress(Zcl, " length: 0x%02x", length); - - // When the length is set to 0xFF, it represents a non-value. In this case the data field is zero length. - if (length == 0xFF) - { - length = 0; - } - - CHECK_MESSAGE_LENGTH(length); - if (attributeType == 0x41) - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - else - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - break; - } - - case 0x43: // octstr16 / Long octet string - case 0x44: // string16 / Long character string - { - // Long Strings must contains at least two bytes for the length - CHECK_MESSAGE_LENGTH(2); - uint16_t length = Encoding::LittleEndian::Read16(message); - ChipLogProgress(Zcl, " length: 0x%02x", length); - - // When the length is set to 0xFFFF, it represents a non-value. In this case the data field is zero length. - if (length == 0xFFFF) - { - length = 0; - } - - CHECK_MESSAGE_LENGTH(length); - if (attributeType == 0x43) - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - else - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - break; - } - - case 0x08: // data8 / 8-bit data - case 0x18: // map8 / 8-bit bitmap - case 0x20: // uint8 / Unsigned 8-bit integer - case 0x30: // enum8 / 8-bit enumeration - { - CHECK_MESSAGE_LENGTH(1); - uint8_t value = Encoding::Read8(message); - ChipLogProgress(Zcl, " value: 0x%02x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x09: // data16 / 16-bit data - case 0x19: // map16 / 16-bit bitmap - case 0x21: // uint16 / Unsigned 16-bit integer - case 0x31: // enum16 / 16-bit enumeration - case 0xE8: // clusterId / Cluster ID - case 0xE9: // attribId / Attribute ID - case 0xEA: // bacOID / BACnet OID - case 0xF1: // key128 / 128-bit security key - case 0xFF: // unk / Unknown - { - CHECK_MESSAGE_LENGTH(2); - uint16_t value = Encoding::LittleEndian::Read16(message); - ChipLogProgress(Zcl, " value: 0x%04x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x0B: // data32 / 32-bit data - case 0x1B: // map32 / 32-bit bitmap - case 0x23: // uint32 / Unsigned 32-bit integer - case 0xE1: // date / Date - case 0xE2: // UTC / UTCTime - { - CHECK_MESSAGE_LENGTH(4); - uint32_t value = Encoding::LittleEndian::Read32(message); - ChipLogProgress(Zcl, " value: 0x%08x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x0F: // data64 / 64-bit data - case 0x1F: // map64 / 64-bit bitmap - case 0x27: // uint64 / Unsigned 64-bit integer - case 0xF0: // EUI64 / IEEE address - { - CHECK_MESSAGE_LENGTH(8); - uint64_t value = Encoding::LittleEndian::Read64(message); - ChipLogProgress(Zcl, " value: 0x" ChipLogFormatX64, ChipLogValueX64(value)); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x10: // bool / Boolean - { - CHECK_MESSAGE_LENGTH(1); - uint8_t value = Encoding::Read8(message); - ChipLogProgress(Zcl, " value: %d", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x28: // int8 / Signed 8-bit integer - { - CHECK_MESSAGE_LENGTH(1); - int8_t value = CastToSigned(Encoding::Read8(message)); - ChipLogProgress(Zcl, " value: %" PRId8, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x29: // int16 / Signed 16-bit integer - { - CHECK_MESSAGE_LENGTH(2); - int16_t value = CastToSigned(Encoding::LittleEndian::Read16(message)); - ChipLogProgress(Zcl, " value: %" PRId16, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x2B: // int32 / Signed 32-bit integer - { - CHECK_MESSAGE_LENGTH(4); - int32_t value = CastToSigned(Encoding::LittleEndian::Read32(message)); - ChipLogProgress(Zcl, " value: %" PRId32, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x2F: // int64 / Signed 64-bit integer - { - CHECK_MESSAGE_LENGTH(8); - int64_t value = CastToSigned(Encoding::LittleEndian::Read64(message)); - ChipLogProgress(Zcl, " value: %" PRId64, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - } - } - - return true; -} diff --git a/zzz_generated/pump-controller-app/zap-generated/CHIPClusters.cpp b/zzz_generated/pump-controller-app/zap-generated/CHIPClusters.cpp index ae4250cbaaefc6..acc03904772d3d 100644 --- a/zzz_generated/pump-controller-app/zap-generated/CHIPClusters.cpp +++ b/zzz_generated/pump-controller-app/zap-generated/CHIPClusters.cpp @@ -67,8 +67,6 @@ constexpr uint8_t kFrameControlGlobalCommand = 0x00; // Pick source endpoint as 1 for now constexpr EndpointId kSourceEndpoint = 1; - -[[maybe_unused]] const uint8_t kReportingDirectionReported = 0x00; } // namespace using namespace app::Clusters; @@ -107,22 +105,19 @@ CHIP_ERROR FlowMeasurementCluster::ConfigureAttributeMeasuredValue(Callback::Can Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval, int16_t change) { - COMMAND_HEADER("ReportFlowMeasurementMeasuredValue", FlowMeasurement::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(FlowMeasurement::Attributes::Ids::MeasuredValue) - .Put8(41) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = FlowMeasurement::Attributes::Ids::MeasuredValue; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR FlowMeasurementCluster::ReportAttributeMeasuredValue(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0000, onReportCallback); + return RequestAttributeReporting(FlowMeasurement::Attributes::Ids::MeasuredValue, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR FlowMeasurementCluster::ReadAttributeMinMeasuredValue(Callback::Cancelable * onSuccessCallback, @@ -544,22 +539,19 @@ CHIP_ERROR LevelControlCluster::ConfigureAttributeCurrentLevel(Callback::Cancela Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval, uint8_t change) { - COMMAND_HEADER("ReportLevelControlCurrentLevel", LevelControl::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(LevelControl::Attributes::Ids::CurrentLevel) - .Put8(32) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put8(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = LevelControl::Attributes::Ids::CurrentLevel; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR LevelControlCluster::ReportAttributeCurrentLevel(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0000, onReportCallback); + return RequestAttributeReporting(LevelControl::Attributes::Ids::CurrentLevel, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR LevelControlCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback, @@ -746,22 +738,19 @@ CHIP_ERROR PressureMeasurementCluster::ConfigureAttributeMeasuredValue(Callback: Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval, int16_t change) { - COMMAND_HEADER("ReportPressureMeasurementMeasuredValue", PressureMeasurement::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(PressureMeasurement::Attributes::Ids::MeasuredValue) - .Put8(41) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = PressureMeasurement::Attributes::Ids::MeasuredValue; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR PressureMeasurementCluster::ReportAttributeMeasuredValue(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0000, onReportCallback); + return RequestAttributeReporting(PressureMeasurement::Attributes::Ids::MeasuredValue, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR PressureMeasurementCluster::ReadAttributeMinMeasuredValue(Callback::Cancelable * onSuccessCallback, @@ -887,22 +876,19 @@ CHIP_ERROR PumpConfigurationAndControlCluster::ConfigureAttributeCapacity(Callba uint16_t minInterval, uint16_t maxInterval, int16_t change) { - COMMAND_HEADER("ReportPumpConfigurationAndControlCapacity", PumpConfigurationAndControl::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(PumpConfigurationAndControl::Attributes::Ids::Capacity) - .Put8(41) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = PumpConfigurationAndControl::Attributes::Ids::Capacity; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR PumpConfigurationAndControlCluster::ReportAttributeCapacity(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0013, onReportCallback); + return RequestAttributeReporting(PumpConfigurationAndControl::Attributes::Ids::Capacity, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR PumpConfigurationAndControlCluster::ReadAttributeOperationMode(Callback::Cancelable * onSuccessCallback, @@ -973,22 +959,19 @@ CHIP_ERROR TemperatureMeasurementCluster::ConfigureAttributeMeasuredValue(Callba uint16_t minInterval, uint16_t maxInterval, int16_t change) { - COMMAND_HEADER("ReportTemperatureMeasurementMeasuredValue", TemperatureMeasurement::Id); - buf.Put8(kFrameControlGlobalCommand) - .Put8(seqNum) - .Put32(Globals::Commands::Ids::ConfigureReporting) - .Put8(kReportingDirectionReported) - .Put32(TemperatureMeasurement::Attributes::Ids::MeasuredValue) - .Put8(41) - .Put16(minInterval) - .Put16(maxInterval); - buf.Put16(static_cast(change)); - COMMAND_FOOTER(); + IgnoreUnusedVariable(change); + chip::app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = TemperatureMeasurement::Attributes::Ids::MeasuredValue; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendSubscribeAttributeRequest(attributePath, minInterval, maxInterval, onSuccessCallback, onFailureCallback); } CHIP_ERROR TemperatureMeasurementCluster::ReportAttributeMeasuredValue(Callback::Cancelable * onReportCallback) { - return RequestAttributeReporting(0x0000, onReportCallback); + return RequestAttributeReporting(TemperatureMeasurement::Attributes::Ids::MeasuredValue, onReportCallback, + BasicAttributeFilter); } CHIP_ERROR TemperatureMeasurementCluster::ReadAttributeMinMeasuredValue(Callback::Cancelable * onSuccessCallback, diff --git a/zzz_generated/tv-app/zap-generated/CHIPClientCallbacks.cpp b/zzz_generated/tv-app/zap-generated/CHIPClientCallbacks.cpp index 383abd31bb1b37..b5c504f44f3929 100644 --- a/zzz_generated/tv-app/zap-generated/CHIPClientCallbacks.cpp +++ b/zzz_generated/tv-app/zap-generated/CHIPClientCallbacks.cpp @@ -365,9 +365,12 @@ void GeneralCommissioningClusterBasicCommissioningInfoListListAttributeFilter(TL EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -404,9 +407,12 @@ void OperationalCredentialsClusterFabricsListListAttributeFilter(TLV::TLVReader EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -459,9 +465,12 @@ void OperationalCredentialsClusterTrustedRootCertificatesListAttributeFilter(TLV EmberAfStatus res = PrepareListFromTLV(tlvData, message, messageLen); if (res != EMBER_ZCL_STATUS_SUCCESS) { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onFailureCallback); - cb->mCall(cb->mContext, res); + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, res); + } return; } @@ -696,252 +705,3 @@ bool emberAfOperationalCredentialsClusterOpCSRResponseCallback(EndpointId endpoi cb->mCall(cb->mContext, NOCSRElements, AttestationSignature); return true; } - -bool emberAfReportAttributesCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen) -{ - ChipLogProgress(Zcl, "emberAfReportAttributeCallback:"); - ChipLogProgress(Zcl, " ClusterId: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); - - NodeId sourceId = emberAfCurrentCommand()->SourceNodeId(); - ChipLogProgress(Zcl, " Source NodeId: %" PRIu64, sourceId); - - EndpointId endpointId = emberAfCurrentCommand()->apsFrame->sourceEndpoint; - ChipLogProgress(Zcl, " Source EndpointId: 0x%04x", endpointId); - - // TODO onFailureCallback is just here because of the CHECK_MESSAGE_LENGTH macro. It needs to be removed. - Callback::Cancelable * onFailureCallback = nullptr; - - while (messageLen) - { - CHECK_MESSAGE_LENGTH(4); - AttributeId attributeId = Encoding::LittleEndian::Read32(message); // attribId - ChipLogProgress(Zcl, " attributeId: " ChipLogFormatMEI, ChipLogValueMEI(attributeId)); - - GET_REPORT_CALLBACK("emberAfReportAttributesCallback"); - - CHECK_MESSAGE_LENGTH(1); - uint8_t attributeType = Encoding::Read8(message); - ChipLogProgress(Zcl, " attributeType: 0x%02x", attributeType); - - switch (attributeType) - { - case 0x00: // nodata / No data - case 0x0A: // data24 / 24-bit data - case 0x0C: // data40 / 40-bit data - case 0x0D: // data48 / 48-bit data - case 0x0E: // data56 / 56-bit data - case 0x1A: // map24 / 24-bit bitmap - case 0x1C: // map40 / 40-bit bitmap - case 0x1D: // map48 / 48-bit bitmap - case 0x1E: // map56 / 56-bit bitmap - case 0x22: // uint24 / Unsigned 24-bit integer - case 0x24: // uint40 / Unsigned 40-bit integer - case 0x25: // uint48 / Unsigned 48-bit integer - case 0x26: // uint56 / Unsigned 56-bit integer - case 0x2A: // int24 / Signed 24-bit integer - case 0x2C: // int40 / Signed 40-bit integer - case 0x2D: // int48 / Signed 48-bit integer - case 0x2E: // int56 / Signed 56-bit integer - case 0x38: // semi / Semi-precision - case 0x39: // single / Single precision - case 0x3A: // double / Double precision - case 0x48: // array / Array - case 0x49: // struct / Structure - case 0x50: // set / Set - case 0x51: // bag / Bag - case 0xE0: // ToD / Time of day - { - ChipLogError(Zcl, "attributeType 0x%02x is not supported", attributeType); - return true; - } - - case 0x41: // octstr / Octet string - case 0x42: // string / Character string - { - // Short Strings must contains at least one byte for the length - CHECK_MESSAGE_LENGTH(1); - uint8_t length = Encoding::Read8(message); - ChipLogProgress(Zcl, " length: 0x%02x", length); - - // When the length is set to 0xFF, it represents a non-value. In this case the data field is zero length. - if (length == 0xFF) - { - length = 0; - } - - CHECK_MESSAGE_LENGTH(length); - if (attributeType == 0x41) - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - else - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - break; - } - - case 0x43: // octstr16 / Long octet string - case 0x44: // string16 / Long character string - { - // Long Strings must contains at least two bytes for the length - CHECK_MESSAGE_LENGTH(2); - uint16_t length = Encoding::LittleEndian::Read16(message); - ChipLogProgress(Zcl, " length: 0x%02x", length); - - // When the length is set to 0xFFFF, it represents a non-value. In this case the data field is zero length. - if (length == 0xFFFF) - { - length = 0; - } - - CHECK_MESSAGE_LENGTH(length); - if (attributeType == 0x43) - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - else - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - break; - } - - case 0x08: // data8 / 8-bit data - case 0x18: // map8 / 8-bit bitmap - case 0x20: // uint8 / Unsigned 8-bit integer - case 0x30: // enum8 / 8-bit enumeration - { - CHECK_MESSAGE_LENGTH(1); - uint8_t value = Encoding::Read8(message); - ChipLogProgress(Zcl, " value: 0x%02x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x09: // data16 / 16-bit data - case 0x19: // map16 / 16-bit bitmap - case 0x21: // uint16 / Unsigned 16-bit integer - case 0x31: // enum16 / 16-bit enumeration - case 0xE8: // clusterId / Cluster ID - case 0xE9: // attribId / Attribute ID - case 0xEA: // bacOID / BACnet OID - case 0xF1: // key128 / 128-bit security key - case 0xFF: // unk / Unknown - { - CHECK_MESSAGE_LENGTH(2); - uint16_t value = Encoding::LittleEndian::Read16(message); - ChipLogProgress(Zcl, " value: 0x%04x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x0B: // data32 / 32-bit data - case 0x1B: // map32 / 32-bit bitmap - case 0x23: // uint32 / Unsigned 32-bit integer - case 0xE1: // date / Date - case 0xE2: // UTC / UTCTime - { - CHECK_MESSAGE_LENGTH(4); - uint32_t value = Encoding::LittleEndian::Read32(message); - ChipLogProgress(Zcl, " value: 0x%08x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x0F: // data64 / 64-bit data - case 0x1F: // map64 / 64-bit bitmap - case 0x27: // uint64 / Unsigned 64-bit integer - case 0xF0: // EUI64 / IEEE address - { - CHECK_MESSAGE_LENGTH(8); - uint64_t value = Encoding::LittleEndian::Read64(message); - ChipLogProgress(Zcl, " value: 0x" ChipLogFormatX64, ChipLogValueX64(value)); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x10: // bool / Boolean - { - CHECK_MESSAGE_LENGTH(1); - uint8_t value = Encoding::Read8(message); - ChipLogProgress(Zcl, " value: %d", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x28: // int8 / Signed 8-bit integer - { - CHECK_MESSAGE_LENGTH(1); - int8_t value = CastToSigned(Encoding::Read8(message)); - ChipLogProgress(Zcl, " value: %" PRId8, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x29: // int16 / Signed 16-bit integer - { - CHECK_MESSAGE_LENGTH(2); - int16_t value = CastToSigned(Encoding::LittleEndian::Read16(message)); - ChipLogProgress(Zcl, " value: %" PRId16, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x2B: // int32 / Signed 32-bit integer - { - CHECK_MESSAGE_LENGTH(4); - int32_t value = CastToSigned(Encoding::LittleEndian::Read32(message)); - ChipLogProgress(Zcl, " value: %" PRId32, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x2F: // int64 / Signed 64-bit integer - { - CHECK_MESSAGE_LENGTH(8); - int64_t value = CastToSigned(Encoding::LittleEndian::Read64(message)); - ChipLogProgress(Zcl, " value: %" PRId64, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - } - } - - return true; -} diff --git a/zzz_generated/tv-app/zap-generated/CHIPClusters.cpp b/zzz_generated/tv-app/zap-generated/CHIPClusters.cpp index 7cd10f89033f1b..a4757924ee49a0 100644 --- a/zzz_generated/tv-app/zap-generated/CHIPClusters.cpp +++ b/zzz_generated/tv-app/zap-generated/CHIPClusters.cpp @@ -67,8 +67,6 @@ constexpr uint8_t kFrameControlGlobalCommand = 0x00; // Pick source endpoint as 1 for now constexpr EndpointId kSourceEndpoint = 1; - -[[maybe_unused]] const uint8_t kReportingDirectionReported = 0x00; } // namespace using namespace app::Clusters; From 64d8f135b21331ce2092fb62980ee5d8eb8319ed Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 13 Sep 2021 20:50:02 -0300 Subject: [PATCH 027/255] linux: Filter ble/matter only (#9583) * linux: Restrict search to BLE only For BlueZ, set "Transport" discovery filter to "le" avoiding interleaved discovery. There is no need to inquiry for traditional Bluetooth devices. * linux: Restrict search to chip UUID For BlueZ, set discovery "UUIDs" filter to chip UUID to avoid reporting BLE devices that doesn't support chip/matter. --- .../Linux/bluez/ChipDeviceScanner.cpp | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/platform/Linux/bluez/ChipDeviceScanner.cpp b/src/platform/Linux/bluez/ChipDeviceScanner.cpp index bb03ba365e1e4c..db71b77166f089 100644 --- a/src/platform/Linux/bluez/ChipDeviceScanner.cpp +++ b/src/platform/Linux/bluez/ChipDeviceScanner.cpp @@ -273,6 +273,29 @@ int ChipDeviceScanner::MainLoopStartScan(ChipDeviceScanner * self) self->RemoveDevice(bluez_object_get_device1(&object)); } + /* Search for matter/chip UUID only */ + GVariantBuilder uuidsBuilder; + GVariant * uuids; + g_variant_builder_init(&uuidsBuilder, G_VARIANT_TYPE("as")); + g_variant_builder_add(&uuidsBuilder, "s", CHIP_BLE_UUID_SERVICE_STRING); + uuids = g_variant_builder_end(&uuidsBuilder); + + /* Search for LE only: Advertises */ + GVariantBuilder filterBuilder; + GVariant * filter; + + g_variant_builder_init(&filterBuilder, G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add(&filterBuilder, "{sv}", "Transport", g_variant_new_string("le")); + g_variant_builder_add(&filterBuilder, "{sv}", "UUIDs", uuids); + filter = g_variant_builder_end(&filterBuilder); + + if (!bluez_adapter1_call_set_discovery_filter_sync(self->mAdapter, filter, self->mCancellable, &error)) + { + /* Not critical: ignore if fails */ + ChipLogError(Ble, "Failed to set discovery filters: %s", error->message); + g_error_free(error); + } + ChipLogProgress(Ble, "BLE initiating scan."); if (!bluez_adapter1_call_start_discovery_sync(self->mAdapter, self->mCancellable, &error)) { From 102c6e201ba6de3f72b0b946592cb88b37502cfd Mon Sep 17 00:00:00 2001 From: Zang MingJie Date: Tue, 14 Sep 2021 21:08:41 +0800 Subject: [PATCH 028/255] Unauthenticated session (#9269) * unauthenticated-session * Resolve comments --- src/app/server/RendezvousServer.cpp | 3 +- src/channel/ChannelContext.cpp | 17 +- src/controller/CHIPDevice.cpp | 13 +- src/controller/CHIPDeviceController.cpp | 9 +- src/lib/core/CHIPConfig.h | 12 ++ src/lib/core/CHIPError.cpp | 3 + src/lib/core/CHIPError.h | 8 + src/lib/core/InPlace.h | 4 - src/lib/support/Pool.h | 17 +- src/lib/support/ReferenceCountedHandle.h | 9 +- src/messaging/ApplicationExchangeDispatch.cpp | 2 +- src/messaging/ExchangeMessageDispatch.h | 2 + src/messaging/ReliableMessageMgr.cpp | 2 +- src/messaging/tests/MessagingContext.cpp | 19 +- src/messaging/tests/MessagingContext.h | 11 +- .../tests/TestReliableMessageProtocol.cpp | 55 ++--- src/protocols/secure_channel/CASEServer.cpp | 2 +- src/protocols/secure_channel/CASESession.cpp | 2 - src/protocols/secure_channel/PASESession.cpp | 2 - .../SessionEstablishmentExchangeDispatch.cpp | 11 +- .../SessionEstablishmentExchangeDispatch.h | 19 +- .../secure_channel/tests/TestCASESession.cpp | 33 +-- .../secure_channel/tests/TestPASESession.cpp | 34 +-- src/transport/PeerMessageCounter.h | 29 ++- src/transport/SecureSessionMgr.cpp | 149 ++++++++----- src/transport/SecureSessionMgr.h | 15 +- src/transport/SessionHandle.h | 28 ++- src/transport/UnauthenticatedSessionTable.h | 200 ++++++++++++++++++ src/transport/tests/TestSecureSessionMgr.cpp | 12 +- 29 files changed, 525 insertions(+), 197 deletions(-) create mode 100644 src/transport/UnauthenticatedSessionTable.h diff --git a/src/app/server/RendezvousServer.cpp b/src/app/server/RendezvousServer.cpp index b3fb76357472fa..06eff52b32a898 100644 --- a/src/app/server/RendezvousServer.cpp +++ b/src/app/server/RendezvousServer.cpp @@ -118,8 +118,7 @@ CHIP_ERROR RendezvousServer::WaitForPairing(const RendezvousParameters & params, ReturnErrorOnFailure(mPairingSession.WaitForPairing(params.GetSetupPINCode(), pbkdf2IterCount, salt, keyID, this)); } - ReturnErrorOnFailure(mPairingSession.MessageDispatch().Init(transportMgr)); - mPairingSession.MessageDispatch().SetPeerAddress(params.GetPeerAddress()); + ReturnErrorOnFailure(mPairingSession.MessageDispatch().Init(mSessionMgr)); return CHIP_NO_ERROR; } diff --git a/src/channel/ChannelContext.cpp b/src/channel/ChannelContext.cpp index 72523b7c019f75..800b24c380ccf2 100644 --- a/src/channel/ChannelContext.cpp +++ b/src/channel/ChannelContext.cpp @@ -258,13 +258,22 @@ void ChannelContext::EnterCasePairingState() auto & prepare = GetPrepareVars(); prepare.mCasePairingSession = Platform::New(); - ExchangeContext * ctxt = - mExchangeManager->NewContext(SessionHandle::TemporaryUnauthenticatedSession(), prepare.mCasePairingSession); - VerifyOrReturn(ctxt != nullptr); - // TODO: currently only supports IP/UDP paring Transport::PeerAddress addr; addr.SetTransportType(Transport::Type::kUdp).SetIPAddress(prepare.mAddress); + + auto session = mExchangeManager->GetSessionMgr()->CreateUnauthenticatedSession(addr); + if (!session.HasValue()) + { + ExitCasePairingState(); + ExitPreparingState(); + EnterFailedState(CHIP_ERROR_NO_MEMORY); + return; + } + + ExchangeContext * ctxt = mExchangeManager->NewContext(session.Value(), prepare.mCasePairingSession); + VerifyOrReturn(ctxt != nullptr); + Transport::FabricInfo * fabric = mFabricsTable->FindFabricWithIndex(mFabricIndex); VerifyOrReturn(fabric != nullptr); CHIP_ERROR err = prepare.mCasePairingSession->EstablishSession(addr, fabric, prepare.mBuilder.GetPeerNodeId(), diff --git a/src/controller/CHIPDevice.cpp b/src/controller/CHIPDevice.cpp index 52a8e42f328881..94b6e799c03ce5 100644 --- a/src/controller/CHIPDevice.cpp +++ b/src/controller/CHIPDevice.cpp @@ -560,12 +560,17 @@ CHIP_ERROR Device::WarmupCASESession() VerifyOrReturnError(mDeviceOperationalCertProvisioned, CHIP_ERROR_INCORRECT_STATE); VerifyOrReturnError(mState == ConnectionState::NotConnected, CHIP_NO_ERROR); - Messaging::ExchangeContext * exchange = - mExchangeMgr->NewContext(SessionHandle::TemporaryUnauthenticatedSession(), &mCASESession); + // Create a UnauthenticatedSession for CASE pairing. + // Don't use mSecureSession here, because mSecureSession is the secure session. + Optional session = mSessionManager->CreateUnauthenticatedSession(mDeviceAddress); + if (!session.HasValue()) + { + return CHIP_ERROR_NO_MEMORY; + } + Messaging::ExchangeContext * exchange = mExchangeMgr->NewContext(session.Value(), &mCASESession); VerifyOrReturnError(exchange != nullptr, CHIP_ERROR_INTERNAL); - ReturnErrorOnFailure(mCASESession.MessageDispatch().Init(mSessionManager->GetTransportManager())); - mCASESession.MessageDispatch().SetPeerAddress(mDeviceAddress); + ReturnErrorOnFailure(mCASESession.MessageDispatch().Init(mSessionManager)); uint16_t keyID = 0; ReturnErrorOnFailure(mIDAllocator->Allocate(keyID)); diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index ffe976bf2811cf..c535d10dcb0b12 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -805,6 +805,7 @@ CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, RendezvousParam Transport::PeerAddress peerAddress = Transport::PeerAddress::UDP(Inet::IPAddress::Any); Messaging::ExchangeContext * exchangeCtxt = nullptr; + Optional session; uint16_t keyID = 0; @@ -857,9 +858,8 @@ CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, RendezvousParam mIsIPRendezvous = (params.GetPeerAddress().GetTransportType() != Transport::Type::kBle); - err = mPairingSession.MessageDispatch().Init(mTransportMgr); + err = mPairingSession.MessageDispatch().Init(mSessionMgr); SuccessOrExit(err); - mPairingSession.MessageDispatch().SetPeerAddress(params.GetPeerAddress()); device->Init(GetControllerDeviceInitParams(), mListenPort, remoteDeviceId, peerAddress, fabric->GetFabricIndex()); @@ -885,7 +885,10 @@ CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, RendezvousParam } } #endif - exchangeCtxt = mExchangeMgr->NewContext(SessionHandle::TemporaryUnauthenticatedSession(), &mPairingSession); + session = mSessionMgr->CreateUnauthenticatedSession(params.GetPeerAddress()); + VerifyOrExit(session.HasValue(), CHIP_ERROR_NO_MEMORY); + + exchangeCtxt = mExchangeMgr->NewContext(session.Value(), &mPairingSession); VerifyOrExit(exchangeCtxt != nullptr, err = CHIP_ERROR_INTERNAL); err = mIDAllocator.Allocate(keyID); diff --git a/src/lib/core/CHIPConfig.h b/src/lib/core/CHIPConfig.h index 6b2169096f0142..b3407b32e81328 100644 --- a/src/lib/core/CHIPConfig.h +++ b/src/lib/core/CHIPConfig.h @@ -2251,6 +2251,18 @@ #define CHIP_CONFIG_ENABLE_IFJ_SERVICE_FABRIC_JOIN 0 #endif // CHIP_CONFIG_ENABLE_IFJ_SERVICE_FABRIC_JOIN +/** + * @def CHIP_CONFIG_UNAUTHENTICATED_CONNECTION_POOL_SIZE + * + * @brief Define the size of the pool used for tracking CHIP unauthenticated + * states. The entries in the pool are automatically rotated by LRU. The size + * of the pool limits how many PASE and CASE pairing sessions can be processed + * simultaneously. + */ +#ifndef CHIP_CONFIG_UNAUTHENTICATED_CONNECTION_POOL_SIZE +#define CHIP_CONFIG_UNAUTHENTICATED_CONNECTION_POOL_SIZE 4 +#endif // CHIP_CONFIG_UNAUTHENTICATED_CONNECTION_POOL_SIZE + /** * @def CHIP_CONFIG_PEER_CONNECTION_POOL_SIZE * diff --git a/src/lib/core/CHIPError.cpp b/src/lib/core/CHIPError.cpp index d8a6eb2ff7c61f..fc6623e608ab53 100644 --- a/src/lib/core/CHIPError.cpp +++ b/src/lib/core/CHIPError.cpp @@ -644,6 +644,9 @@ bool FormatCHIPError(char * buf, uint16_t bufSize, CHIP_ERROR err) case CHIP_ERROR_DUPLICATE_MESSAGE_RECEIVED.AsInteger(): desc = "Duplicate message received"; break; + case CHIP_ERROR_MESSAGE_ID_OUT_OF_WINDOW.AsInteger(): + desc = "Message id out of window"; + break; } #endif // !CHIP_CONFIG_SHORT_ERROR_STR diff --git a/src/lib/core/CHIPError.h b/src/lib/core/CHIPError.h index c4a7d63fd86157..a50be6da4d441a 100644 --- a/src/lib/core/CHIPError.h +++ b/src/lib/core/CHIPError.h @@ -2173,6 +2173,14 @@ using CHIP_ERROR = ::chip::ChipError; */ #define CHIP_ERROR_FABRIC_MISMATCH_ON_ICA CHIP_CORE_ERROR(0xc6) +/** + * @def CHIP_ERROR_MESSAGE_ID_OUT_OF_WINDOW + * + * @brief + * The message id of the received message is out of receiving window + */ +#define CHIP_ERROR_MESSAGE_ID_OUT_OF_WINDOW CHIP_CORE_ERROR(0xc7) + /** * @} */ diff --git a/src/lib/core/InPlace.h b/src/lib/core/InPlace.h index 01a5a1f2bd9ee4..647fc51c6e87d1 100644 --- a/src/lib/core/InPlace.h +++ b/src/lib/core/InPlace.h @@ -23,10 +23,6 @@ */ #pragma once -#include -#include -#include - namespace chip { /// InPlace is disambiguation tags that can be passed to the constructors to indicate that the contained object should be diff --git a/src/lib/support/Pool.h b/src/lib/support/Pool.h index 2158929ca216ee..f9fe67aaa8d735 100644 --- a/src/lib/support/Pool.h +++ b/src/lib/support/Pool.h @@ -87,7 +87,7 @@ template class BitMapObjectPool : public StaticAllocatorBitmap { public: - BitMapObjectPool() : StaticAllocatorBitmap(mMemory, mUsage, N, sizeof(T)) {} + BitMapObjectPool() : StaticAllocatorBitmap(mData.mMemory, mUsage, N, sizeof(T)) {} static size_t Size() { return N; } @@ -110,6 +110,13 @@ class BitMapObjectPool : public StaticAllocatorBitmap Deallocate(element); } + template + void ResetObject(T * element, Args &&... args) + { + element->~T(); + new (element) T(std::forward(args)...); + } + /** * @brief * Run a functor for each active object in the pool @@ -144,7 +151,13 @@ class BitMapObjectPool : public StaticAllocatorBitmap }; std::atomic mUsage[(N + kBitChunkSize - 1) / kBitChunkSize]; - alignas(alignof(T)) uint8_t mMemory[N * sizeof(T)]; + union Data + { + Data() {} + ~Data() {} + alignas(alignof(T)) uint8_t mMemory[N * sizeof(T)]; + T mMemoryViewForDebug[N]; // Just for debugger + } mData; }; } // namespace chip diff --git a/src/lib/support/ReferenceCountedHandle.h b/src/lib/support/ReferenceCountedHandle.h index 637fe514405c31..c433a639db8d7a 100644 --- a/src/lib/support/ReferenceCountedHandle.h +++ b/src/lib/support/ReferenceCountedHandle.h @@ -28,14 +28,19 @@ class ReferenceCountedHandle explicit ReferenceCountedHandle(Target & target) : mTarget(target) { mTarget.Retain(); } ~ReferenceCountedHandle() { mTarget.Release(); } - ReferenceCountedHandle(const ReferenceCountedHandle & that) = delete; + ReferenceCountedHandle(const ReferenceCountedHandle & that) : mTarget(that.mTarget) { mTarget.Retain(); } + + ReferenceCountedHandle(ReferenceCountedHandle && that) : mTarget(that.mTarget) { mTarget.Retain(); } + ReferenceCountedHandle & operator=(const ReferenceCountedHandle & that) = delete; - ReferenceCountedHandle(ReferenceCountedHandle && that) = delete; ReferenceCountedHandle & operator=(ReferenceCountedHandle && that) = delete; bool operator==(const ReferenceCountedHandle & that) const { return &mTarget == &that.mTarget; } bool operator!=(const ReferenceCountedHandle & that) const { return !(*this == that); } + Target * operator->() { return &mTarget; } + Target & Get() const { return mTarget; } + private: Target & mTarget; }; diff --git a/src/messaging/ApplicationExchangeDispatch.cpp b/src/messaging/ApplicationExchangeDispatch.cpp index 7e7caf59c1e8e0..76b1dbb420e17a 100644 --- a/src/messaging/ApplicationExchangeDispatch.cpp +++ b/src/messaging/ApplicationExchangeDispatch.cpp @@ -30,7 +30,7 @@ CHIP_ERROR ApplicationExchangeDispatch::PrepareMessage(SessionHandle session, Pa System::PacketBufferHandle && message, EncryptedPacketBufferHandle & preparedMessage) { - return mSessionMgr->BuildEncryptedMessagePayload(session, payloadHeader, std::move(message), preparedMessage); + return mSessionMgr->PrepareMessage(session, payloadHeader, std::move(message), preparedMessage); } CHIP_ERROR ApplicationExchangeDispatch::SendPreparedMessage(SessionHandle session, diff --git a/src/messaging/ExchangeMessageDispatch.h b/src/messaging/ExchangeMessageDispatch.h index e937376c712392..25e92b4029a271 100644 --- a/src/messaging/ExchangeMessageDispatch.h +++ b/src/messaging/ExchangeMessageDispatch.h @@ -66,6 +66,8 @@ class ExchangeMessageDispatch : public ReferenceCounted protected: virtual bool MessagePermitted(uint16_t protocol, uint8_t type) = 0; + + // TODO: remove IsReliableTransmissionAllowed, this function should be provided over session. virtual bool IsReliableTransmissionAllowed() const { return true; } }; diff --git a/src/messaging/ReliableMessageMgr.cpp b/src/messaging/ReliableMessageMgr.cpp index c180b9d5701224..41b8baa60975f0 100644 --- a/src/messaging/ReliableMessageMgr.cpp +++ b/src/messaging/ReliableMessageMgr.cpp @@ -406,8 +406,8 @@ void ReliableMessageMgr::ClearRetransTable(RetransTableEntry & rEntry) // Expire any virtual ticks that have expired so all wakeup sources reflect the current time ExpireTicks(); - rEntry.rc->ReleaseContext(); rEntry.rc->SetOccupied(false); + rEntry.rc->ReleaseContext(); rEntry.rc = nullptr; // Clear all other fields diff --git a/src/messaging/tests/MessagingContext.cpp b/src/messaging/tests/MessagingContext.cpp index dc96e07fb9146e..6f870825ebc09b 100644 --- a/src/messaging/tests/MessagingContext.cpp +++ b/src/messaging/tests/MessagingContext.cpp @@ -37,11 +37,12 @@ CHIP_ERROR MessagingContext::Init(nlTestSuite * suite, TransportMgrBase * transp ReturnErrorOnFailure(mExchangeManager.Init(&mSecureSessionMgr)); ReturnErrorOnFailure(mMessageCounterManager.Init(&mExchangeManager)); - ReturnErrorOnFailure(mSecureSessionMgr.NewPairing(mAddress, GetAliceNodeId(), &mPairingBobToAlice, - SecureSession::SessionRole::kInitiator, mSrcFabricIndex)); + ReturnErrorOnFailure(mSecureSessionMgr.NewPairing(Optional::Value(mAliceAddress), GetAliceNodeId(), + &mPairingBobToAlice, SecureSession::SessionRole::kInitiator, + mSrcFabricIndex)); - return mSecureSessionMgr.NewPairing(mAddress, GetBobNodeId(), &mPairingAliceToBob, SecureSession::SessionRole::kResponder, - mDestFabricIndex); + return mSecureSessionMgr.NewPairing(Optional::Value(mBobAddress), GetBobNodeId(), &mPairingAliceToBob, + SecureSession::SessionRole::kResponder, mDestFabricIndex); } // Shutdown all layers, finalize operations @@ -67,6 +68,16 @@ SessionHandle MessagingContext::GetSessionAliceToBob() return SessionHandle(GetBobNodeId(), GetAliceKeyId(), GetBobKeyId(), mDestFabricIndex); } +Messaging::ExchangeContext * MessagingContext::NewUnauthenticatedExchangeToAlice(Messaging::ExchangeDelegate * delegate) +{ + return mExchangeManager.NewContext(mSecureSessionMgr.CreateUnauthenticatedSession(mAliceAddress).Value(), delegate); +} + +Messaging::ExchangeContext * MessagingContext::NewUnauthenticatedExchangeToBob(Messaging::ExchangeDelegate * delegate) +{ + return mExchangeManager.NewContext(mSecureSessionMgr.CreateUnauthenticatedSession(mBobAddress).Value(), delegate); +} + Messaging::ExchangeContext * MessagingContext::NewExchangeToAlice(Messaging::ExchangeDelegate * delegate) { // TODO: temprary create a SessionHandle from node id, will be fix in PR 3602 diff --git a/src/messaging/tests/MessagingContext.h b/src/messaging/tests/MessagingContext.h index 6bb4e70df69eb0..735278c344117e 100644 --- a/src/messaging/tests/MessagingContext.h +++ b/src/messaging/tests/MessagingContext.h @@ -37,8 +37,9 @@ class MessagingContext { public: MessagingContext() : - mInitialized(false), mAddress(Transport::PeerAddress::UDP(GetAddress(), CHIP_PORT)), - mPairingAliceToBob(GetBobKeyId(), GetAliceKeyId()), mPairingBobToAlice(GetAliceKeyId(), GetBobKeyId()) + mInitialized(false), mAliceAddress(Transport::PeerAddress::UDP(GetAddress(), CHIP_PORT + 1)), + mBobAddress(Transport::PeerAddress::UDP(GetAddress(), CHIP_PORT)), mPairingAliceToBob(GetBobKeyId(), GetAliceKeyId()), + mPairingBobToAlice(GetAliceKeyId(), GetBobKeyId()) {} ~MessagingContext() { VerifyOrDie(mInitialized == false); } @@ -80,6 +81,9 @@ class MessagingContext SessionHandle GetSessionBobToAlice(); SessionHandle GetSessionAliceToBob(); + Messaging::ExchangeContext * NewUnauthenticatedExchangeToAlice(Messaging::ExchangeDelegate * delegate); + Messaging::ExchangeContext * NewUnauthenticatedExchangeToBob(Messaging::ExchangeDelegate * delegate); + Messaging::ExchangeContext * NewExchangeToAlice(Messaging::ExchangeDelegate * delegate); Messaging::ExchangeContext * NewExchangeToBob(Messaging::ExchangeDelegate * delegate); @@ -98,7 +102,8 @@ class MessagingContext NodeId mAliceNodeId = 111222333; uint16_t mBobKeyId = 1; uint16_t mAliceKeyId = 2; - Optional mAddress; + Transport::PeerAddress mAliceAddress; + Transport::PeerAddress mBobAddress; SecurePairingUsingTestSecret mPairingAliceToBob; SecurePairingUsingTestSecret mPairingBobToAlice; Transport::FabricTable mFabrics; diff --git a/src/messaging/tests/TestReliableMessageProtocol.cpp b/src/messaging/tests/TestReliableMessageProtocol.cpp index 1f5a4b94ab217f..6f8874a9a1d702 100644 --- a/src/messaging/tests/TestReliableMessageProtocol.cpp +++ b/src/messaging/tests/TestReliableMessageProtocol.cpp @@ -124,26 +124,9 @@ class MockAppDelegate : public ExchangeDelegate nlTestSuite * mTestSuite = nullptr; }; -class MockSessionEstablishmentExchangeDispatch : public Messaging::ExchangeMessageDispatch +class MockSessionEstablishmentExchangeDispatch : public Messaging::ApplicationExchangeDispatch { public: - CHIP_ERROR PrepareMessage(SessionHandle session, PayloadHeader & payloadHeader, System::PacketBufferHandle && message, - EncryptedPacketBufferHandle & preparedMessage) override - { - PacketHeader packetHeader; - - ReturnErrorOnFailure(payloadHeader.EncodeBeforeData(message)); - ReturnErrorOnFailure(packetHeader.EncodeBeforeData(message)); - - preparedMessage = EncryptedPacketBufferHandle::MarkEncrypted(std::move(message)); - return CHIP_NO_ERROR; - } - - CHIP_ERROR SendPreparedMessage(SessionHandle session, const EncryptedPacketBufferHandle & preparedMessage) const override - { - return gTransportMgr.SendMessage(Transport::PeerAddress(), preparedMessage.CastToWritable()); - } - bool IsReliableTransmissionAllowed() const override { return mRetainMessageOnSend; } bool MessagePermitted(uint16_t protocol, uint8_t type) override { return true; } @@ -367,6 +350,9 @@ void CheckFailedMessageRetainOnSend(nlTestSuite * inSuite, void * inContext) CHIP_ERROR err = CHIP_NO_ERROR; MockSessionEstablishmentDelegate mockSender; + err = mockSender.mMessageDispatch.Init(&ctx.GetSecureSessionManager()); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); @@ -380,9 +366,6 @@ void CheckFailedMessageRetainOnSend(nlTestSuite * inSuite, void * inContext) 1, // CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL }); - err = mockSender.mMessageDispatch.Init(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - mockSender.mMessageDispatch.mRetainMessageOnSend = false; // Let's drop the initial message @@ -414,14 +397,20 @@ void CheckUnencryptedMessageReceiveFailure(nlTestSuite * inSuite, void * inConte NL_TEST_ASSERT(inSuite, !buffer.IsNull()); MockSessionEstablishmentDelegate mockReceiver; - CHIP_ERROR err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); + CHIP_ERROR err = mockReceiver.mMessageDispatch.Init(&ctx.GetSecureSessionManager()); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + + err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); // Expect the received messages to be encrypted mockReceiver.mMessageDispatch.mRequireEncryption = true; MockSessionEstablishmentDelegate mockSender; - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); + err = mockSender.mMessageDispatch.Init(&ctx.GetSecureSessionManager()); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + + ExchangeContext * exchange = ctx.NewUnauthenticatedExchangeToAlice(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); @@ -429,9 +418,6 @@ void CheckUnencryptedMessageReceiveFailure(nlTestSuite * inSuite, void * inConte NL_TEST_ASSERT(inSuite, rm != nullptr); NL_TEST_ASSERT(inSuite, rc != nullptr); - err = mockSender.mMessageDispatch.Init(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - gLoopback.mSentMessageCount = 0; gLoopback.mNumMessagesToDrop = 0; gLoopback.mDroppedMessageCount = 0; @@ -584,23 +570,23 @@ void CheckResendSessionEstablishmentMessageWithPeerExchange(nlTestSuite * inSuit CHIP_ERROR err = ctx.Init(inSuite, &gTransportMgr, &gIOContext); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.SetBobNodeId(kPlaceholderNodeId); - ctx.SetAliceNodeId(kPlaceholderNodeId); - ctx.SetBobKeyId(0); - ctx.SetAliceKeyId(0); - ctx.SetFabricIndex(kUndefinedFabricIndex); - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); NL_TEST_ASSERT(inSuite, !buffer.IsNull()); MockSessionEstablishmentDelegate mockReceiver; + err = mockReceiver.mMessageDispatch.Init(&ctx.GetSecureSessionManager()); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); mockReceiver.mTestSuite = inSuite; MockSessionEstablishmentDelegate mockSender; - ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender); + err = mockSender.mMessageDispatch.Init(&ctx.GetSecureSessionManager()); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + + ExchangeContext * exchange = ctx.NewUnauthenticatedExchangeToAlice(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); @@ -613,9 +599,6 @@ void CheckResendSessionEstablishmentMessageWithPeerExchange(nlTestSuite * inSuit 1, // CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL }); - err = mockSender.mMessageDispatch.Init(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - // Let's drop the initial message gLoopback.mSentMessageCount = 0; gLoopback.mNumMessagesToDrop = 1; diff --git a/src/protocols/secure_channel/CASEServer.cpp b/src/protocols/secure_channel/CASEServer.cpp index 382bdb4ce25450..6a926939708897 100644 --- a/src/protocols/secure_channel/CASEServer.cpp +++ b/src/protocols/secure_channel/CASEServer.cpp @@ -46,7 +46,7 @@ CHIP_ERROR CASEServer::ListenForSessionEstablishment(Messaging::ExchangeManager Cleanup(); - ReturnErrorOnFailure(GetSession().MessageDispatch().Init(transportMgr)); + ReturnErrorOnFailure(GetSession().MessageDispatch().Init(sessionMgr)); return CHIP_NO_ERROR; } diff --git a/src/protocols/secure_channel/CASESession.cpp b/src/protocols/secure_channel/CASESession.cpp index 65c3026a402b7a..29f27d0ccf8709 100644 --- a/src/protocols/secure_channel/CASESession.cpp +++ b/src/protocols/secure_channel/CASESession.cpp @@ -1221,8 +1221,6 @@ CHIP_ERROR CASESession::OnMessageReceived(ExchangeContext * ec, const PayloadHea CHIP_ERROR err = ValidateReceivedMessage(ec, payloadHeader, msg); SuccessOrExit(err); - SetPeerAddress(mMessageDispatch.GetPeerAddress()); - switch (static_cast(payloadHeader.GetMessageType())) { case Protocols::SecureChannel::MsgType::CASE_SigmaR1: diff --git a/src/protocols/secure_channel/PASESession.cpp b/src/protocols/secure_channel/PASESession.cpp index 6ff77062ffc82e..f47ba8ce5a8e52 100644 --- a/src/protocols/secure_channel/PASESession.cpp +++ b/src/protocols/secure_channel/PASESession.cpp @@ -882,8 +882,6 @@ CHIP_ERROR PASESession::OnMessageReceived(ExchangeContext * exchange, const Payl CHIP_ERROR err = ValidateReceivedMessage(exchange, payloadHeader, std::move(msg)); SuccessOrExit(err); - SetPeerAddress(mMessageDispatch.GetPeerAddress()); - switch (static_cast(payloadHeader.GetMessageType())) { case MsgType::PBKDFParamRequest: diff --git a/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.cpp b/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.cpp index ea6beca4c68135..983b75aac1f934 100644 --- a/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.cpp +++ b/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.cpp @@ -32,19 +32,13 @@ CHIP_ERROR SessionEstablishmentExchangeDispatch::PrepareMessage(SessionHandle se System::PacketBufferHandle && message, EncryptedPacketBufferHandle & preparedMessage) { - PacketHeader packetHeader; - ReturnErrorOnFailure(payloadHeader.EncodeBeforeData(message)); - ReturnErrorOnFailure(packetHeader.EncodeBeforeData(message)); - - preparedMessage = EncryptedPacketBufferHandle::MarkEncrypted(std::move(message)); - return CHIP_NO_ERROR; + return mSessionMgr->PrepareMessage(session, payloadHeader, std::move(message), preparedMessage); } CHIP_ERROR SessionEstablishmentExchangeDispatch::SendPreparedMessage(SessionHandle session, const EncryptedPacketBufferHandle & preparedMessage) const { - ReturnErrorCodeIf(mTransportMgr == nullptr, CHIP_ERROR_INCORRECT_STATE); - return mTransportMgr->SendMessage(mPeerAddress, preparedMessage.CastToWritable()); + return mSessionMgr->SendPreparedMessage(session, preparedMessage); } CHIP_ERROR SessionEstablishmentExchangeDispatch::OnMessageReceived(uint32_t messageCounter, const PayloadHeader & payloadHeader, @@ -52,7 +46,6 @@ CHIP_ERROR SessionEstablishmentExchangeDispatch::OnMessageReceived(uint32_t mess Messaging::MessageFlags msgFlags, ReliableMessageContext * reliableMessageContext) { - mPeerAddress = peerAddress; return ExchangeMessageDispatch::OnMessageReceived(messageCounter, payloadHeader, peerAddress, msgFlags, reliableMessageContext); } diff --git a/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.h b/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.h index 7c3ab655218cbd..d58db5ac08aa5d 100644 --- a/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.h +++ b/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.h @@ -36,10 +36,10 @@ class SessionEstablishmentExchangeDispatch : public Messaging::ExchangeMessageDi virtual ~SessionEstablishmentExchangeDispatch() {} - CHIP_ERROR Init(TransportMgrBase * transportMgr) + CHIP_ERROR Init(SecureSessionMgr * sessionMgr) { - ReturnErrorCodeIf(transportMgr == nullptr, CHIP_ERROR_INVALID_ARGUMENT); - mTransportMgr = transportMgr; + ReturnErrorCodeIf(sessionMgr == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + mSessionMgr = sessionMgr; return ExchangeMessageDispatch::Init(); } @@ -51,24 +51,13 @@ class SessionEstablishmentExchangeDispatch : public Messaging::ExchangeMessageDi const Transport::PeerAddress & peerAddress, Messaging::MessageFlags msgFlags, Messaging::ReliableMessageContext * reliableMessageContext) override; - const Transport::PeerAddress & GetPeerAddress() const { return mPeerAddress; } - - void SetPeerAddress(const Transport::PeerAddress & address) { mPeerAddress = address; } - protected: bool MessagePermitted(uint16_t protocol, uint8_t type) override; - bool IsReliableTransmissionAllowed() const override - { - // If the underlying transport is UDP. - return (mPeerAddress.GetTransportType() == Transport::Type::kUdp); - } - bool IsEncryptionRequired() const override { return false; } private: - TransportMgrBase * mTransportMgr = nullptr; - Transport::PeerAddress mPeerAddress; + SecureSessionMgr * mSessionMgr = nullptr; }; } // namespace chip diff --git a/src/protocols/secure_channel/tests/TestCASESession.cpp b/src/protocols/secure_channel/tests/TestCASESession.cpp index 2868e7373ded63..67f39cd35e2b47 100644 --- a/src/protocols/secure_channel/tests/TestCASESession.cpp +++ b/src/protocols/secure_channel/tests/TestCASESession.cpp @@ -176,8 +176,8 @@ void CASE_SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) FabricInfo * fabric = gCommissionerFabrics.FindFabricWithIndex(gCommissionerFabricIndex); NL_TEST_ASSERT(inSuite, fabric != nullptr); - NL_TEST_ASSERT(inSuite, pairing.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - ExchangeContext * context = ctx.NewExchangeToBob(&pairing); + NL_TEST_ASSERT(inSuite, pairing.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); + ExchangeContext * context = ctx.NewUnauthenticatedExchangeToBob(&pairing); NL_TEST_ASSERT(inSuite, pairing.EstablishSession(Transport::PeerAddress(Transport::Type::kBle), nullptr, Node01_01, 0, nullptr, @@ -191,14 +191,19 @@ void CASE_SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 1); + // Clear pending packet in CRMP + ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); + ReliableMessageContext * rc = context->GetReliableMessageContext(); + rm->ClearRetransTable(rc); + gLoopback.mMessageSendError = CHIP_ERROR_BAD_REQUEST; CASESession pairing1; - NL_TEST_ASSERT(inSuite, pairing1.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, pairing1.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); gLoopback.mSentMessageCount = 0; gLoopback.mMessageSendError = CHIP_ERROR_BAD_REQUEST; - ExchangeContext * context1 = ctx.NewExchangeToBob(&pairing1); + ExchangeContext * context1 = ctx.NewUnauthenticatedExchangeToBob(&pairing1); NL_TEST_ASSERT(inSuite, pairing1.EstablishSession(Transport::PeerAddress(Transport::Type::kBle), fabric, Node01_01, 0, context1, @@ -218,14 +223,14 @@ void CASE_SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inConte CASESessionSerializable serializableAccessory; gLoopback.mSentMessageCount = 0; - NL_TEST_ASSERT(inSuite, pairingCommissioner.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, pairingAccessory.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, pairingCommissioner.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, pairingAccessory.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType( Protocols::SecureChannel::MsgType::CASE_SigmaR1, &pairingAccessory) == CHIP_NO_ERROR); - ExchangeContext * contextCommissioner = ctx.NewExchangeToBob(&pairingCommissioner); + ExchangeContext * contextCommissioner = ctx.NewUnauthenticatedExchangeToBob(&pairingCommissioner); FabricInfo * fabric = gCommissionerFabrics.FindFabricWithIndex(gCommissionerFabricIndex); NL_TEST_ASSERT(inSuite, fabric != nullptr); @@ -236,7 +241,7 @@ void CASE_SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inConte pairingCommissioner.EstablishSession(Transport::PeerAddress(Transport::Type::kBle), fabric, Node01_01, 0, contextCommissioner, &delegateCommissioner) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 3); + NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 4); NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingComplete == 1); NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingComplete == 1); @@ -343,8 +348,8 @@ void CASE_SecurePairingHandshakeServerTest(nlTestSuite * inSuite, void * inConte TestContext & ctx = *reinterpret_cast(inContext); gLoopback.mSentMessageCount = 0; - NL_TEST_ASSERT(inSuite, pairingCommissioner->MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, gPairingServer.GetSession().MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, pairingCommissioner->MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, gPairingServer.GetSession().MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); SessionIDAllocator idAllocator; @@ -353,7 +358,7 @@ void CASE_SecurePairingHandshakeServerTest(nlTestSuite * inSuite, void * inConte &ctx.GetSecureSessionManager(), &gDeviceFabrics, &idAllocator) == CHIP_NO_ERROR); - ExchangeContext * contextCommissioner = ctx.NewExchangeToBob(pairingCommissioner); + ExchangeContext * contextCommissioner = ctx.NewUnauthenticatedExchangeToBob(pairingCommissioner); FabricInfo * fabric = gCommissionerFabrics.FindFabricWithIndex(gCommissionerFabricIndex); NL_TEST_ASSERT(inSuite, fabric != nullptr); @@ -362,12 +367,12 @@ void CASE_SecurePairingHandshakeServerTest(nlTestSuite * inSuite, void * inConte pairingCommissioner->EstablishSession(Transport::PeerAddress(Transport::Type::kBle), fabric, Node01_01, 0, contextCommissioner, &delegateCommissioner) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 3); + NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 4); NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingComplete == 1); auto * pairingCommissioner1 = chip::Platform::New(); - NL_TEST_ASSERT(inSuite, pairingCommissioner1->MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - ExchangeContext * contextCommissioner1 = ctx.NewExchangeToBob(pairingCommissioner1); + NL_TEST_ASSERT(inSuite, pairingCommissioner1->MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); + ExchangeContext * contextCommissioner1 = ctx.NewUnauthenticatedExchangeToBob(pairingCommissioner1); NL_TEST_ASSERT(inSuite, pairingCommissioner1->EstablishSession(Transport::PeerAddress(Transport::Type::kBle), fabric, Node01_01, 0, diff --git a/src/protocols/secure_channel/tests/TestPASESession.cpp b/src/protocols/secure_channel/tests/TestPASESession.cpp index 417b5bd3a212a3..9341875df472aa 100644 --- a/src/protocols/secure_channel/tests/TestPASESession.cpp +++ b/src/protocols/secure_channel/tests/TestPASESession.cpp @@ -122,8 +122,8 @@ void SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) gLoopback.Reset(); - NL_TEST_ASSERT(inSuite, pairing.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - ExchangeContext * context = ctx.NewExchangeToBob(&pairing); + NL_TEST_ASSERT(inSuite, pairing.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); + ExchangeContext * context = ctx.NewUnauthenticatedExchangeToBob(&pairing); NL_TEST_ASSERT(inSuite, pairing.Pair(Transport::PeerAddress(Transport::Type::kBle), 1234, 0, nullptr, nullptr) != CHIP_NO_ERROR); @@ -134,13 +134,18 @@ void SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 1); + // Clear pending packet in CRMP + ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); + ReliableMessageContext * rc = context->GetReliableMessageContext(); + rm->ClearRetransTable(rc); + gLoopback.Reset(); gLoopback.mSentMessageCount = 0; gLoopback.mMessageSendError = CHIP_ERROR_BAD_REQUEST; PASESession pairing1; - NL_TEST_ASSERT(inSuite, pairing1.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - ExchangeContext * context1 = ctx.NewExchangeToBob(&pairing1); + NL_TEST_ASSERT(inSuite, pairing1.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); + ExchangeContext * context1 = ctx.NewUnauthenticatedExchangeToBob(&pairing1); NL_TEST_ASSERT(inSuite, pairing1.Pair(Transport::PeerAddress(Transport::Type::kBle), 1234, 0, context1, &delegate) == CHIP_ERROR_BAD_REQUEST); @@ -157,16 +162,13 @@ void SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inContext, P gLoopback.mSentMessageCount = 0; - NL_TEST_ASSERT(inSuite, pairingCommissioner.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, pairingAccessory.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, pairingCommissioner.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, pairingAccessory.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); - ExchangeContext * contextCommissioner = ctx.NewExchangeToBob(&pairingCommissioner); + ExchangeContext * contextCommissioner = ctx.NewUnauthenticatedExchangeToBob(&pairingCommissioner); if (gLoopback.mNumMessagesToDrop != 0) { - pairingCommissioner.MessageDispatch().SetPeerAddress(PeerAddress(Type::kUdp)); - pairingAccessory.MessageDispatch().SetPeerAddress(PeerAddress(Type::kUdp)); - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); ReliableMessageContext * rc = contextCommissioner->GetReliableMessageContext(); NL_TEST_ASSERT(inSuite, rm != nullptr); @@ -221,6 +223,8 @@ void SecurePairingHandshakeWithPacketLossTest(nlTestSuite * inSuite, void * inCo void SecurePairingFailedHandshake(nlTestSuite * inSuite, void * inContext) { + TestContext & ctx = *reinterpret_cast(inContext); + TestSecurePairingDelegate delegateCommissioner; PASESession pairingCommissioner; @@ -230,14 +234,10 @@ void SecurePairingFailedHandshake(nlTestSuite * inSuite, void * inContext) gLoopback.Reset(); gLoopback.mSentMessageCount = 0; - NL_TEST_ASSERT(inSuite, pairingCommissioner.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, pairingAccessory.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - - TestContext & ctx = *reinterpret_cast(inContext); - ExchangeContext * contextCommissioner = ctx.NewExchangeToBob(&pairingCommissioner); + NL_TEST_ASSERT(inSuite, pairingCommissioner.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, pairingAccessory.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); - pairingCommissioner.MessageDispatch().SetPeerAddress(PeerAddress(Type::kUdp)); - pairingAccessory.MessageDispatch().SetPeerAddress(PeerAddress(Type::kUdp)); + ExchangeContext * contextCommissioner = ctx.NewUnauthenticatedExchangeToBob(&pairingCommissioner); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); ReliableMessageContext * rc = contextCommissioner->GetReliableMessageContext(); diff --git a/src/transport/PeerMessageCounter.h b/src/transport/PeerMessageCounter.h index a69d1bf93088e5..0d0e9e740374db 100644 --- a/src/transport/PeerMessageCounter.h +++ b/src/transport/PeerMessageCounter.h @@ -97,7 +97,7 @@ class PeerMessageCounter uint32_t offset = mSynced.mMaxCounter - counter; if (offset >= CHIP_CONFIG_MESSAGE_COUNTER_WINDOW_SIZE) { - return CHIP_ERROR_INVALID_ARGUMENT; // outside valid range + return CHIP_ERROR_MESSAGE_ID_OUT_OF_WINDOW; // outside valid range } if (mSynced.mWindow.test(offset)) { @@ -108,6 +108,33 @@ class PeerMessageCounter return CHIP_NO_ERROR; } + CHIP_ERROR VerifyOrTrustFirst(uint32_t counter) + { + switch (mStatus) + { + case Status::NotSynced: + // Trust and set the counter when not synced + SetCounter(counter); + return CHIP_NO_ERROR; + case Status::Synced: { + CHIP_ERROR err = Verify(counter); + if (err == CHIP_ERROR_MESSAGE_ID_OUT_OF_WINDOW) + { + // According to chip spec, when global unencrypted message + // counter is out of window, the peer may have reset and is + // using another randomize initial value. Trust the new + // counter here. + SetCounter(counter); + err = CHIP_NO_ERROR; + } + return err; + } + default: + VerifyOrDie(false); + return CHIP_ERROR_INTERNAL; + } + } + /** * @brief * With the counter verified and the packet MIC also verified by the secure key, we can trust the packet and adjust diff --git a/src/transport/SecureSessionMgr.cpp b/src/transport/SecureSessionMgr.cpp index 093ce844e19ef4..54ef62b6d4ba9f 100644 --- a/src/transport/SecureSessionMgr.cpp +++ b/src/transport/SecureSessionMgr.cpp @@ -102,9 +102,8 @@ void SecureSessionMgr::Shutdown() mCB = nullptr; } -CHIP_ERROR SecureSessionMgr::BuildEncryptedMessagePayload(SessionHandle session, PayloadHeader & payloadHeader, - System::PacketBufferHandle && msgBuf, - EncryptedPacketBufferHandle & encryptedMessage) +CHIP_ERROR SecureSessionMgr::PrepareMessage(SessionHandle session, PayloadHeader & payloadHeader, + System::PacketBufferHandle && message, EncryptedPacketBufferHandle & preparedMessage) { PacketHeader packetHeader; if (IsControlMessage(payloadHeader)) @@ -112,71 +111,97 @@ CHIP_ERROR SecureSessionMgr::BuildEncryptedMessagePayload(SessionHandle session, packetHeader.SetSecureSessionControlMsg(true); } - PeerConnectionState * state = GetPeerConnectionState(session); - if (state == nullptr) + if (session.IsSecure()) { - return CHIP_ERROR_NOT_CONNECTED; + PeerConnectionState * state = GetPeerConnectionState(session); + if (state == nullptr) + { + return CHIP_ERROR_NOT_CONNECTED; + } + + MessageCounter & counter = GetSendCounterForPacket(payloadHeader, *state); + ReturnErrorOnFailure(SecureMessageCodec::Encode(state, payloadHeader, packetHeader, message, counter)); + + ChipLogProgress(Inet, + "Build %s message %p to 0x" ChipLogFormatX64 " of type %d and protocolId %" PRIu32 + " on exchange %d with MessageId %" PRIu32 ".", + "encrypted", &preparedMessage, ChipLogValueX64(state->GetPeerNodeId()), payloadHeader.GetMessageType(), + payloadHeader.GetProtocolID().ToFullyQualifiedSpecForm(), payloadHeader.GetExchangeID(), + packetHeader.GetMessageId()); } + else + { + ReturnErrorOnFailure(payloadHeader.EncodeBeforeData(message)); - MessageCounter & counter = GetSendCounterForPacket(payloadHeader, *state); - ReturnErrorOnFailure(SecureMessageCodec::Encode(state, payloadHeader, packetHeader, msgBuf, counter)); + MessageCounter & counter = session.GetUnauthenticatedSession()->GetLocalMessageCounter(); + uint32_t messageId = counter.Value(); + ReturnErrorOnFailure(counter.Advance()); - ReturnErrorOnFailure(packetHeader.EncodeBeforeData(msgBuf)); + packetHeader.SetMessageId(messageId); - encryptedMessage = EncryptedPacketBufferHandle::MarkEncrypted(std::move(msgBuf)); - ChipLogProgress(Inet, "Encrypted message %p to 0x" ChipLogFormatX64 " of type %d and protocolId %" PRIu32 " on exchange %d.", - &encryptedMessage, ChipLogValueX64(state->GetPeerNodeId()), payloadHeader.GetMessageType(), - payloadHeader.GetProtocolID().ToFullyQualifiedSpecForm(), payloadHeader.GetExchangeID()); + ChipLogProgress(Inet, + "Build %s message %p to 0x" ChipLogFormatX64 " of type %d and protocolId %" PRIu32 + " on exchange %d with MessageId %" PRIu32 ".", + "plaintext", &preparedMessage, ChipLogValueX64(kUndefinedNodeId), payloadHeader.GetMessageType(), + payloadHeader.GetProtocolID().ToFullyQualifiedSpecForm(), payloadHeader.GetExchangeID(), + packetHeader.GetMessageId()); + } + + ReturnErrorOnFailure(packetHeader.EncodeBeforeData(message)); + preparedMessage = EncryptedPacketBufferHandle::MarkEncrypted(std::move(message)); return CHIP_NO_ERROR; } CHIP_ERROR SecureSessionMgr::SendPreparedMessage(SessionHandle session, const EncryptedPacketBufferHandle & preparedMessage) { - CHIP_ERROR err = CHIP_NO_ERROR; - PeerConnectionState * state = nullptr; - PacketBufferHandle msgBuf; + VerifyOrReturnError(mState == State::kInitialized, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(!preparedMessage.IsNull(), CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrExit(mState == State::kInitialized, err = CHIP_ERROR_INCORRECT_STATE); - VerifyOrExit(!preparedMessage.IsNull(), err = CHIP_ERROR_INVALID_ARGUMENT); - msgBuf = preparedMessage.CastToWritable(); - VerifyOrExit(!msgBuf.IsNull(), err = CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrExit(!msgBuf->HasChainedBuffer(), err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); + const Transport::PeerAddress * destination; - // Find an active connection to the specified peer node - state = GetPeerConnectionState(session); - VerifyOrExit(state != nullptr, err = CHIP_ERROR_NOT_CONNECTED); + if (session.IsSecure()) + { + // Find an active connection to the specified peer node + PeerConnectionState * state = GetPeerConnectionState(session); + if (state == nullptr) + { + ChipLogError(Inet, "Secure transport could not find a valid PeerConnection"); + return CHIP_ERROR_NOT_CONNECTED; + } - // This marks any connection where we send data to as 'active' - mPeerConnections.MarkConnectionActive(state); + // This marks any connection where we send data to as 'active' + mPeerConnections.MarkConnectionActive(state); - ChipLogProgress(Inet, "Sending msg %p to 0x" ChipLogFormatX64 " at utc time: %" PRId64 " msec", &preparedMessage, - ChipLogValueX64(state->GetPeerNodeId()), System::Clock::GetMonotonicMilliseconds()); + destination = &state->GetPeerAddress(); - if (mTransportMgr != nullptr) - { - ChipLogProgress(Inet, "Sending secure msg on generic transport"); - err = mTransportMgr->SendMessage(state->GetPeerAddress(), std::move(msgBuf)); + ChipLogProgress(Inet, "Sending %s msg %p to 0x" ChipLogFormatX64 " at utc time: %" PRId64 " msec", "encrypted", + &preparedMessage, ChipLogValueX64(state->GetPeerNodeId()), System::Clock::GetMonotonicMilliseconds()); } else { - ChipLogError(Inet, "The transport manager is not initialized. Unable to send the message"); - err = CHIP_ERROR_INCORRECT_STATE; + auto unauthenticated = session.GetUnauthenticatedSession(); + mUnauthenticatedSessions.MarkSessionActive(unauthenticated.Get()); + destination = &unauthenticated->GetPeerAddress(); + + ChipLogProgress(Inet, "Sending %s msg %p to 0x" ChipLogFormatX64 " at utc time: %" PRId64 " msec", "plaintext", + &preparedMessage, ChipLogValueX64(kUndefinedNodeId), System::Clock::GetMonotonicMilliseconds()); } - ChipLogProgress(Inet, "Secure msg send status %s", ErrorStr(err)); - SuccessOrExit(err); -exit: - if (!msgBuf.IsNull()) + PacketBufferHandle msgBuf = preparedMessage.CastToWritable(); + VerifyOrReturnError(!msgBuf.IsNull(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(!msgBuf->HasChainedBuffer(), CHIP_ERROR_INVALID_MESSAGE_LENGTH); + + if (mTransportMgr != nullptr) { - const char * errStr = ErrorStr(err); - if (state == nullptr) - { - ChipLogError(Inet, "Secure transport could not find a valid PeerConnection: %s", errStr); - } + ChipLogProgress(Inet, "Sending msg on generic transport"); + return mTransportMgr->SendMessage(*destination, std::move(msgBuf)); + } + else + { + ChipLogError(Inet, "The transport manager is not initialized. Unable to send the message"); + return CHIP_ERROR_INCORRECT_STATE; } - - return err; } void SecureSessionMgr::ExpirePairing(SessionHandle session) @@ -304,12 +329,36 @@ void SecureSessionMgr::OnMessageReceived(const PeerAddress & peerAddress, System void SecureSessionMgr::MessageDispatch(const PacketHeader & packetHeader, const Transport::PeerAddress & peerAddress, System::PacketBufferHandle && msg) { + Transport::UnauthenticatedSession * session = mUnauthenticatedSessions.FindOrAllocateEntry(peerAddress); + if (session == nullptr) + { + ChipLogError(Inet, "UnauthenticatedSession exhausted"); + return; + } + + SecureSessionMgrDelegate::DuplicateMessage isDuplicate = SecureSessionMgrDelegate::DuplicateMessage::No; + + // Verify message counter + CHIP_ERROR err = session->GetPeerMessageCounter().VerifyOrTrustFirst(packetHeader.GetMessageId()); + if (err == CHIP_ERROR_DUPLICATE_MESSAGE_RECEIVED) + { + ChipLogDetail(Inet, "Received a duplicate message with MessageId: %" PRIu32, packetHeader.GetMessageId()); + isDuplicate = SecureSessionMgrDelegate::DuplicateMessage::Yes; + err = CHIP_NO_ERROR; + } + VerifyOrDie(err == CHIP_NO_ERROR); + + mUnauthenticatedSessions.MarkSessionActive(*session); + + PayloadHeader payloadHeader; + ReturnOnFailure(payloadHeader.DecodeAndConsume(msg)); + + session->GetPeerMessageCounter().Commit(packetHeader.GetMessageId()); + if (mCB != nullptr) { - PayloadHeader payloadHeader; - ReturnOnFailure(payloadHeader.DecodeAndConsume(msg)); - mCB->OnMessageReceived(packetHeader, payloadHeader, SessionHandle::TemporaryUnauthenticatedSession(), peerAddress, - SecureSessionMgrDelegate::DuplicateMessage::No, std::move(msg)); + mCB->OnMessageReceived(packetHeader, payloadHeader, SessionHandle(Transport::UnauthenticatedSessionHandle(*session)), + peerAddress, isDuplicate, std::move(msg)); } } @@ -365,7 +414,7 @@ void SecureSessionMgr::SecureMessageDispatch(const PacketHeader & packetHeader, err = state->GetSessionMessageCounter().GetPeerMessageCounter().Verify(packetHeader.GetMessageId()); if (err == CHIP_ERROR_DUPLICATE_MESSAGE_RECEIVED) { - ChipLogDetail(Inet, "Received a duplicate message"); + ChipLogDetail(Inet, "Received a duplicate message with MessageId: %" PRIu32, packetHeader.GetMessageId()); isDuplicate = SecureSessionMgrDelegate::DuplicateMessage::Yes; err = CHIP_NO_ERROR; } diff --git a/src/transport/SecureSessionMgr.h b/src/transport/SecureSessionMgr.h index 740bae8fe1995a..f5d5ca82d7e7c9 100644 --- a/src/transport/SecureSessionMgr.h +++ b/src/transport/SecureSessionMgr.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -191,8 +192,8 @@ class DLL_EXPORT SecureSessionMgr : public TransportMgrDelegate * 3. Encode the packet header and prepend it to message. * Returns a encrypted message in encryptedMessage. */ - CHIP_ERROR BuildEncryptedMessagePayload(SessionHandle session, PayloadHeader & payloadHeader, - System::PacketBufferHandle && msgBuf, EncryptedPacketBufferHandle & encryptedMessage); + CHIP_ERROR PrepareMessage(SessionHandle session, PayloadHeader & payloadHeader, System::PacketBufferHandle && msgBuf, + EncryptedPacketBufferHandle & encryptedMessage); /** * @brief @@ -263,6 +264,15 @@ class DLL_EXPORT SecureSessionMgr : public TransportMgrDelegate */ void OnMessageReceived(const Transport::PeerAddress & source, System::PacketBufferHandle && msgBuf) override; + Optional CreateUnauthenticatedSession(const Transport::PeerAddress & peerAddress) + { + Transport::UnauthenticatedSession * session = mUnauthenticatedSessions.FindOrAllocateEntry(peerAddress); + if (session == nullptr) + return Optional::Missing(); + + return Optional::Value(SessionHandle(Transport::UnauthenticatedSessionHandle(*session))); + } + private: /** * The State of a secure transport object. @@ -280,6 +290,7 @@ class DLL_EXPORT SecureSessionMgr : public TransportMgrDelegate }; System::Layer * mSystemLayer = nullptr; + Transport::UnauthenticatedSessionTable mUnauthenticatedSessions; Transport::PeerConnections mPeerConnections; // < Active connections to other peers State mState; // < Initialization state of the object diff --git a/src/transport/SessionHandle.h b/src/transport/SessionHandle.h index fe9f0cadf26a5e..f701702def5c4e 100644 --- a/src/transport/SessionHandle.h +++ b/src/transport/SessionHandle.h @@ -17,6 +17,8 @@ #pragma once +#include + namespace chip { class SecureSessionMgr; @@ -26,6 +28,10 @@ class SessionHandle public: SessionHandle(NodeId peerNodeId, FabricIndex fabric) : mPeerNodeId(peerNodeId), mFabric(fabric) {} + SessionHandle(Transport::UnauthenticatedSessionHandle session) : + mPeerNodeId(kPlaceholderNodeId), mFabric(Transport::kUndefinedFabricIndex), mUnauthenticatedSessionHandle(session) + {} + SessionHandle(NodeId peerNodeId, uint16_t localKeyId, uint16_t peerKeyId, FabricIndex fabric) : mPeerNodeId(peerNodeId), mFabric(fabric) { @@ -33,6 +39,8 @@ class SessionHandle mPeerKeyId.SetValue(peerKeyId); } + bool IsSecure() const { return !mUnauthenticatedSessionHandle.HasValue(); } + bool HasFabricIndex() const { return (mFabric != Transport::kUndefinedFabricIndex); } FabricIndex GetFabricIndex() const { return mFabric; } void SetFabricIndex(FabricIndex fabricId) { mFabric = fabricId; } @@ -45,16 +53,13 @@ class SessionHandle bool MatchIncomingSession(const SessionHandle & that) const { - - if (that.GetLocalKeyId().HasValue()) + if (IsSecure()) { - return mLocalKeyId == that.mLocalKeyId; + return that.IsSecure() && mLocalKeyId.Value() == that.mLocalKeyId.Value(); } else { - // TODO: For unencrypted session, temporarily still rely on the old match logic in MatchExchange, need to update to - // match peer’s HW address (BLE) or peer’s IP/Port (for IP). - return true; + return !that.IsSecure() && mUnauthenticatedSessionHandle.Value() == that.mUnauthenticatedSessionHandle.Value(); } } @@ -62,14 +67,12 @@ class SessionHandle const Optional & GetPeerKeyId() const { return mPeerKeyId; } const Optional & GetLocalKeyId() const { return mLocalKeyId; } - // TODO: currently SessionHandle is not able to identify a unauthenticated session, create an empty handle for it - static SessionHandle TemporaryUnauthenticatedSession() - { - return SessionHandle(kPlaceholderNodeId, Transport::kUndefinedFabricIndex); - } + Transport::UnauthenticatedSessionHandle GetUnauthenticatedSession() { return mUnauthenticatedSessionHandle.Value(); } private: friend class SecureSessionMgr; + + // Fields for secure session NodeId mPeerNodeId; Optional mLocalKeyId; Optional mPeerKeyId; @@ -78,6 +81,9 @@ class SessionHandle // to identify an approach that'll allow looking up the corresponding information for // such sessions. FabricIndex mFabric; + + // Fields for unauthenticated session + Optional mUnauthenticatedSessionHandle; }; } // namespace chip diff --git a/src/transport/UnauthenticatedSessionTable.h b/src/transport/UnauthenticatedSessionTable.h new file mode 100644 index 00000000000000..48d721fb9ff096 --- /dev/null +++ b/src/transport/UnauthenticatedSessionTable.h @@ -0,0 +1,200 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace Transport { + +class UnauthenticatedSession; +using UnauthenticatedSessionHandle = ReferenceCountedHandle; + +class UnauthenticatedSessionDeleter +{ +public: + // This is a no-op because life-cycle of UnauthenticatedSessionTable is rotated by LRU + static void Release(UnauthenticatedSession * entry) {} +}; + +/** + * @brief + * An UnauthenticatedSession stores the binding of TransportAddress, and message counters. + */ +class UnauthenticatedSession : public ReferenceCounted +{ +public: + UnauthenticatedSession(const PeerAddress & address) : mPeerAddress(address) {} + + UnauthenticatedSession(const UnauthenticatedSession &) = delete; + UnauthenticatedSession & operator=(const UnauthenticatedSession &) = delete; + UnauthenticatedSession(UnauthenticatedSession &&) = delete; + UnauthenticatedSession & operator=(UnauthenticatedSession &&) = delete; + + uint64_t GetLastActivityTimeMs() const { return mLastActivityTimeMs; } + void SetLastActivityTimeMs(uint64_t value) { mLastActivityTimeMs = value; } + + const PeerAddress & GetPeerAddress() const { return mPeerAddress; } + + MessageCounter & GetLocalMessageCounter() { return mLocalMessageCounter; } + PeerMessageCounter & GetPeerMessageCounter() { return mPeerMessageCounter; } + +private: + uint64_t mLastActivityTimeMs = 0; + + const PeerAddress mPeerAddress; + GlobalUnencryptedMessageCounter mLocalMessageCounter; + PeerMessageCounter mPeerMessageCounter; +}; + +/* + * @brief + * An table which manages UnauthenticatedSessions + * + * The UnauthenticatedSession entries are rotated using LRU, but entry can be + * hold by using UnauthenticatedSessionHandle, which increase the reference + * count by 1. If the reference count is not 0, the entry won't be pruned. + */ +template +class UnauthenticatedSessionTable +{ +public: + /** + * Allocates a new session out of the internal resource pool. + * + * @returns CHIP_NO_ERROR if new session created. May fail if maximum connection count has been reached (with + * CHIP_ERROR_NO_MEMORY). + */ + CHECK_RETURN_VALUE + CHIP_ERROR AllocEntry(const PeerAddress & address, UnauthenticatedSession *& entry) + { + entry = mEntries.CreateObject(address); + if (entry != nullptr) + return CHIP_NO_ERROR; + + entry = FindLeastRecentUsedEntry(); + if (entry == nullptr) + { + return CHIP_ERROR_NO_MEMORY; + } + + mEntries.ResetObject(entry, address); + return CHIP_NO_ERROR; + } + + /** + * Get a session using given address + * + * @return the peer found, nullptr if not found + */ + CHECK_RETURN_VALUE + UnauthenticatedSession * FindEntry(const PeerAddress & address) + { + UnauthenticatedSession * result = nullptr; + mEntries.ForEachActiveObject([&](UnauthenticatedSession * entry) { + if (MatchPeerAddress(entry->GetPeerAddress(), address)) + { + result = entry; + return false; + } + return true; + }); + return result; + } + + /** + * Get a peer given the peer id. If the peer doesn't exist in the cache, allocate a new entry for it. + * + * @return the peer found or allocated, nullptr if not found and allocate failed. + */ + CHECK_RETURN_VALUE + UnauthenticatedSession * FindOrAllocateEntry(const PeerAddress & address) + { + UnauthenticatedSession * result = FindEntry(address); + if (result != nullptr) + return result; + + CHIP_ERROR err = AllocEntry(address, result); + if (err == CHIP_NO_ERROR) + { + return result; + } + else + { + return nullptr; + } + } + + /// Mark a session as active + void MarkSessionActive(UnauthenticatedSession & entry) { entry.SetLastActivityTimeMs(mTimeSource.GetCurrentMonotonicTimeMs()); } + + /// Allows access to the underlying time source used for keeping track of connection active time + Time::TimeSource & GetTimeSource() { return mTimeSource; } + +private: + UnauthenticatedSession * FindLeastRecentUsedEntry() + { + UnauthenticatedSession * result = nullptr; + uint64_t oldestTimeMs = std::numeric_limits::max(); + + mEntries.ForEachActiveObject([&](UnauthenticatedSession * entry) { + if (entry->GetReferenceCount() == 0 && entry->GetLastActivityTimeMs() < oldestTimeMs) + { + result = entry; + oldestTimeMs = entry->GetLastActivityTimeMs(); + } + return true; + }); + + return result; + } + + static bool MatchPeerAddress(const PeerAddress & a1, const PeerAddress & a2) + { + if (a1.GetTransportType() != a2.GetTransportType()) + return false; + + switch (a1.GetTransportType()) + { + case Transport::Type::kUndefined: + return false; + case Transport::Type::kUdp: + case Transport::Type::kTcp: + return a1.GetIPAddress() == a2.GetIPAddress() && a1.GetPort() == a2.GetPort() && + // Enforce interface equal-ness if the address is link-local, otherwise ignore interface + (a1.GetIPAddress().IsIPv6LinkLocal() ? a1.GetInterface() == a2.GetInterface() : true); + case Transport::Type::kBle: + // TODO: complete BLE address comparation + return true; + } + + return false; + } + + Time::TimeSource mTimeSource; + BitMapObjectPool mEntries; +}; + +} // namespace Transport +} // namespace chip diff --git a/src/transport/tests/TestSecureSessionMgr.cpp b/src/transport/tests/TestSecureSessionMgr.cpp index 1f40642882e971..69e745d562faf5 100644 --- a/src/transport/tests/TestSecureSessionMgr.cpp +++ b/src/transport/tests/TestSecureSessionMgr.cpp @@ -180,7 +180,7 @@ void CheckMessageTest(nlTestSuite * inSuite, void * inContext) payloadHeader.SetMessageType(chip::Protocols::Echo::MsgType::EchoRequest); EncryptedPacketBufferHandle preparedMessage; - err = secureSessionMgr.BuildEncryptedMessagePayload(localToRemoteSession, payloadHeader, std::move(buffer), preparedMessage); + err = secureSessionMgr.PrepareMessage(localToRemoteSession, payloadHeader, std::move(buffer), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); err = secureSessionMgr.SendPreparedMessage(localToRemoteSession, preparedMessage); @@ -194,8 +194,7 @@ void CheckMessageTest(nlTestSuite * inSuite, void * inContext) callback.LargeMessageSent = true; - err = secureSessionMgr.BuildEncryptedMessagePayload(localToRemoteSession, payloadHeader, std::move(large_buffer), - preparedMessage); + err = secureSessionMgr.PrepareMessage(localToRemoteSession, payloadHeader, std::move(large_buffer), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); err = secureSessionMgr.SendPreparedMessage(localToRemoteSession, preparedMessage); @@ -211,8 +210,7 @@ void CheckMessageTest(nlTestSuite * inSuite, void * inContext) callback.LargeMessageSent = true; - err = secureSessionMgr.BuildEncryptedMessagePayload(localToRemoteSession, payloadHeader, std::move(extra_large_buffer), - preparedMessage); + err = secureSessionMgr.PrepareMessage(localToRemoteSession, payloadHeader, std::move(extra_large_buffer), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_MESSAGE_TOO_LONG); } @@ -272,7 +270,7 @@ void SendEncryptedPacketTest(nlTestSuite * inSuite, void * inContext) payloadHeader.SetInitiator(true); - err = secureSessionMgr.BuildEncryptedMessagePayload(localToRemoteSession, payloadHeader, std::move(buffer), preparedMessage); + err = secureSessionMgr.PrepareMessage(localToRemoteSession, payloadHeader, std::move(buffer), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); err = secureSessionMgr.SendPreparedMessage(localToRemoteSession, preparedMessage); @@ -346,7 +344,7 @@ void SendBadEncryptedPacketTest(nlTestSuite * inSuite, void * inContext) payloadHeader.SetInitiator(true); - err = secureSessionMgr.BuildEncryptedMessagePayload(localToRemoteSession, payloadHeader, std::move(buffer), preparedMessage); + err = secureSessionMgr.PrepareMessage(localToRemoteSession, payloadHeader, std::move(buffer), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); err = secureSessionMgr.SendPreparedMessage(localToRemoteSession, preparedMessage); From 29e6bcd838bebef0a2cf4260a9654e69165fb6bd Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Tue, 14 Sep 2021 09:23:01 -0400 Subject: [PATCH 029/255] Fix error copying artifacts. (#9689) This fixes errors like: ``` FileNotFoundError: [Errno 2] No such file or directory: '/workspaces/connectedhomeip/out/tizen-arm-light/chip-tizen-lighting-example.out' ``` When trying to copy artifacts. Tested running: ``` ./scripts/build/build_examples.py --platform tizen build --copy-artifacts-to /tmp ``` --- scripts/build/builders/tizen.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/scripts/build/builders/tizen.py b/scripts/build/builders/tizen.py index b8289f4bd5b6fe..ef6433bebb2278 100644 --- a/scripts/build/builders/tizen.py +++ b/scripts/build/builders/tizen.py @@ -29,9 +29,9 @@ def ExampleName(self): else: raise Exception('Unknown app type: %r' % self) - def AppNamePrefix(self): + def AppName(self): if self == TizenApp.LIGHT: - return 'chip-tizen-lighting-example' + return 'chip-lighting-app' else: raise Exception('Unknown app type: %r' % self) @@ -91,12 +91,10 @@ def _build(self): def build_outputs(self): items = { - '%s.out' % self.app.AppNamePrefix(): - os.path.join(self.output_dir, '%s.out' % - self.app.AppNamePrefix()), - '%s.out.map' % self.app.AppNamePrefix(): - os.path.join(self.output_dir, - '%s.out.map' % self.app.AppNamePrefix()), + '%s' % self.app.AppName(): + os.path.join(self.output_dir, self.app.AppName()), + '%s.map' % self.app.AppName(): + os.path.join(self.output_dir, '%s.map' % self.app.AppName()), } return items From 54b88e7e8a2d8f3e5cde1dbabfa979845636698a Mon Sep 17 00:00:00 2001 From: Zang MingJie Date: Tue, 14 Sep 2021 23:32:16 +0800 Subject: [PATCH 030/255] Add mDNS shutdown (#9621) (#9674) --- src/controller/CHIPDeviceController.cpp | 4 ++++ src/controller/tests/TestCommissionableNodeController.cpp | 1 + src/lib/mdns/Discovery_ImplPlatform.h | 1 + src/lib/mdns/MinimalMdnsServer.cpp | 5 +++++ src/lib/mdns/MinimalMdnsServer.h | 1 + src/lib/mdns/Resolver.h | 1 + src/lib/mdns/Resolver_ImplMinimalMdns.cpp | 6 ++++++ src/lib/mdns/Resolver_ImplNone.cpp | 1 + src/platform/Tizen/MdnsImpl.cpp | 5 +++++ src/platform/fake/MdnsImpl.cpp | 5 +++++ 10 files changed, 30 insertions(+) diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index c535d10dcb0b12..7186c53e4f87f3 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -267,6 +267,10 @@ CHIP_ERROR DeviceController::Shutdown() // manager. app::InteractionModelEngine::GetInstance()->Shutdown(); +#if CHIP_DEVICE_CONFIG_ENABLE_MDNS + Mdns::Resolver::Instance().ShutdownResolver(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS + // TODO(#6668): Some exchange has leak, shutting down ExchangeManager will cause a assert fail. // if (mExchangeMgr != nullptr) // { diff --git a/src/controller/tests/TestCommissionableNodeController.cpp b/src/controller/tests/TestCommissionableNodeController.cpp index 43aa5917d35fee..d0df594c6d2068 100644 --- a/src/controller/tests/TestCommissionableNodeController.cpp +++ b/src/controller/tests/TestCommissionableNodeController.cpp @@ -33,6 +33,7 @@ class MockResolver : public Resolver public: CHIP_ERROR SetResolverDelegate(ResolverDelegate *) override { return SetResolverDelegateStatus; } CHIP_ERROR StartResolver(chip::Inet::InetLayer * inetLayer, uint16_t port) override { return StartResolverStatus; } + void ShutdownResolver() override {} CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type) override { return ResolveNodeIdStatus; } CHIP_ERROR FindCommissioners(DiscoveryFilter filter = DiscoveryFilter()) override { return FindCommissionersStatus; } CHIP_ERROR FindCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter()) override { return CHIP_ERROR_NOT_IMPLEMENTED; } diff --git a/src/lib/mdns/Discovery_ImplPlatform.h b/src/lib/mdns/Discovery_ImplPlatform.h index c0bc89d1168831..0db90a695a1c62 100644 --- a/src/lib/mdns/Discovery_ImplPlatform.h +++ b/src/lib/mdns/Discovery_ImplPlatform.h @@ -43,6 +43,7 @@ class DiscoveryImplPlatform : public ServiceAdvertiser, public Resolver /// Starts the service resolver if not yet started CHIP_ERROR StartResolver(Inet::InetLayer * inetLayer, uint16_t port) override { return Init(); } + void ShutdownResolver() override { ChipMdnsShutdown(); } /// Advertises the CHIP node as an operational node CHIP_ERROR Advertise(const OperationalAdvertisingParameters & params) override; diff --git a/src/lib/mdns/MinimalMdnsServer.cpp b/src/lib/mdns/MinimalMdnsServer.cpp index 3044547126ede0..7bd268bb72eb8c 100644 --- a/src/lib/mdns/MinimalMdnsServer.cpp +++ b/src/lib/mdns/MinimalMdnsServer.cpp @@ -107,5 +107,10 @@ CHIP_ERROR GlobalMinimalMdnsServer::StartServer(chip::Inet::InetLayer * inetLaye return GlobalMinimalMdnsServer::Server().Listen(inetLayer, &allInterfaces, port); } +void GlobalMinimalMdnsServer::ShutdownServer() +{ + GlobalMinimalMdnsServer::Server().Shutdown(); +} + } // namespace Mdns } // namespace chip diff --git a/src/lib/mdns/MinimalMdnsServer.h b/src/lib/mdns/MinimalMdnsServer.h index e42342073fa5a4..e84cff5205a43e 100644 --- a/src/lib/mdns/MinimalMdnsServer.h +++ b/src/lib/mdns/MinimalMdnsServer.h @@ -90,6 +90,7 @@ class GlobalMinimalMdnsServer : public mdns::Minimal::ServerDelegate /// Calls Server().Listen() on all available interfaces CHIP_ERROR StartServer(chip::Inet::InetLayer * inetLayer, uint16_t port); + void ShutdownServer(); void SetQueryDelegate(MdnsPacketDelegate * delegate) { mQueryDelegate = delegate; } void SetResponseDelegate(MdnsPacketDelegate * delegate) { mResponseDelegate = delegate; } diff --git a/src/lib/mdns/Resolver.h b/src/lib/mdns/Resolver.h index 47faa4eaa7ace0..f8badf5ba10521 100644 --- a/src/lib/mdns/Resolver.h +++ b/src/lib/mdns/Resolver.h @@ -260,6 +260,7 @@ class Resolver /// /// Unsual name to allow base MDNS classes to implement both Advertiser and Resolver interfaces. virtual CHIP_ERROR StartResolver(chip::Inet::InetLayer * inetLayer, uint16_t port) = 0; + virtual void ShutdownResolver() = 0; /// Registers a resolver delegate if none has been registered before virtual CHIP_ERROR SetResolverDelegate(ResolverDelegate * delegate) = 0; diff --git a/src/lib/mdns/Resolver_ImplMinimalMdns.cpp b/src/lib/mdns/Resolver_ImplMinimalMdns.cpp index d73fb1cabb0fdf..599cb9269fe4e3 100644 --- a/src/lib/mdns/Resolver_ImplMinimalMdns.cpp +++ b/src/lib/mdns/Resolver_ImplMinimalMdns.cpp @@ -335,6 +335,7 @@ class MinMdnsResolver : public Resolver, public MdnsPacketDelegate ///// Resolver implementation CHIP_ERROR StartResolver(chip::Inet::InetLayer * inetLayer, uint16_t port) override; + void ShutdownResolver() override; CHIP_ERROR SetResolverDelegate(ResolverDelegate * delegate) override; CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type) override; CHIP_ERROR FindCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter()) override; @@ -394,6 +395,11 @@ CHIP_ERROR MinMdnsResolver::StartResolver(chip::Inet::InetLayer * inetLayer, uin return GlobalMinimalMdnsServer::Instance().StartServer(inetLayer, port); } +void MinMdnsResolver::ShutdownResolver() +{ + GlobalMinimalMdnsServer::Instance().ShutdownServer(); +} + CHIP_ERROR MinMdnsResolver::SetResolverDelegate(ResolverDelegate * delegate) { mDelegate = delegate; diff --git a/src/lib/mdns/Resolver_ImplNone.cpp b/src/lib/mdns/Resolver_ImplNone.cpp index 8f1cb81b7298dd..bd0f097622327d 100644 --- a/src/lib/mdns/Resolver_ImplNone.cpp +++ b/src/lib/mdns/Resolver_ImplNone.cpp @@ -29,6 +29,7 @@ class NoneResolver : public Resolver CHIP_ERROR SetResolverDelegate(ResolverDelegate *) override { return CHIP_NO_ERROR; } CHIP_ERROR StartResolver(chip::Inet::InetLayer * inetLayer, uint16_t port) override { return CHIP_NO_ERROR; } + void ShutdownResolver() override {} CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type) override { diff --git a/src/platform/Tizen/MdnsImpl.cpp b/src/platform/Tizen/MdnsImpl.cpp index db50f0b1c4295c..174307855434db 100644 --- a/src/platform/Tizen/MdnsImpl.cpp +++ b/src/platform/Tizen/MdnsImpl.cpp @@ -31,6 +31,11 @@ CHIP_ERROR ChipMdnsInit(MdnsAsyncReturnCallback successCallback, MdnsAsyncReturn return CHIP_ERROR_NOT_IMPLEMENTED; } +CHIP_ERROR ChipMdnsShutdown() +{ + return CHIP_NO_ERROR; +} + CHIP_ERROR ChipMdnsSetHostname(const char * hostname) { return CHIP_ERROR_NOT_IMPLEMENTED; diff --git a/src/platform/fake/MdnsImpl.cpp b/src/platform/fake/MdnsImpl.cpp index 30bb388066e5a3..9eb7379c799efb 100644 --- a/src/platform/fake/MdnsImpl.cpp +++ b/src/platform/fake/MdnsImpl.cpp @@ -95,6 +95,11 @@ CHIP_ERROR ChipMdnsInit(MdnsAsyncReturnCallback initCallback, MdnsAsyncReturnCal return CHIP_NO_ERROR; } +CHIP_ERROR ChipMdnsShutdown() +{ + return CHIP_NO_ERROR; +} + CHIP_ERROR ChipMdnsPublishService(const MdnsService * service) { return test::CheckExpected(test::CallType::kStart, service); From f878d22e955bb3b5ee82935d90d599583a0e379e Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 14 Sep 2021 11:36:23 -0400 Subject: [PATCH 031/255] TLV Reader error handling test should not read uninitialized data. (#9653) We should just zero the data out, so it's known-bad. --- src/lib/core/tests/TestCHIPTLV.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/core/tests/TestCHIPTLV.cpp b/src/lib/core/tests/TestCHIPTLV.cpp index 2715cee28293ea..f78d5945fd6030 100644 --- a/src/lib/core/tests/TestCHIPTLV.cpp +++ b/src/lib/core/tests/TestCHIPTLV.cpp @@ -3021,7 +3021,7 @@ void TestCHIPTLVReaderDup(nlTestSuite * inSuite) void TestCHIPTLVReaderErrorHandling(nlTestSuite * inSuite) { CHIP_ERROR err; - uint8_t buf[2048]; + uint8_t buf[2048] = { 0 }; TLVReader reader; reader.Init(buf); From 0b6c0ba75e2ae439e1645d731ef55644749142bd Mon Sep 17 00:00:00 2001 From: "Hui.Li-TCL" Date: Wed, 15 Sep 2021 00:31:36 +0800 Subject: [PATCH 032/255] fix unknown argument: '-ffile-prefix-map by only build default target (#9690) --- src/android/CHIPTool/app/build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/android/CHIPTool/app/build.gradle b/src/android/CHIPTool/app/build.gradle index 9d82bb66e9af48..b2b0f59734f622 100644 --- a/src/android/CHIPTool/app/build.gradle +++ b/src/android/CHIPTool/app/build.gradle @@ -17,6 +17,12 @@ android { // NOTE: This build assumes CHIP was configured and built for armeabi-v7a. Deal with // other archs later when build is sane. // ndk {abiFilters 'armeabi-v7a'} + + externalNativeBuild { + cmake { + targets "default" + } + } } buildTypes { From fa0ef98047b793a62a1c493444d38ec93d728d96 Mon Sep 17 00:00:00 2001 From: Zang MingJie Date: Wed, 15 Sep 2021 00:32:01 +0800 Subject: [PATCH 033/255] Rename messageId into messageCounter (#9688) --- src/lib/core/CHIPError.cpp | 4 +- src/lib/core/CHIPError.h | 6 +- src/lib/core/tests/TestCHIPErrorStr.cpp | 2 +- src/lib/support/CHIPFaultInjection.cpp | 2 +- src/messaging/ExchangeMessageDispatch.cpp | 10 +-- src/messaging/ExchangeMgr.cpp | 4 +- src/messaging/Flags.h | 2 +- src/messaging/ReliableMessageContext.cpp | 63 ++++++++++--------- src/messaging/ReliableMessageContext.h | 18 +++--- src/messaging/ReliableMessageMgr.cpp | 30 ++++----- src/messaging/ReliableMessageMgr.h | 4 +- .../tests/TestReliableMessageProtocol.cpp | 2 +- src/transport/SecureMessageCodec.cpp | 6 +- src/transport/SecureSession.cpp | 2 +- src/transport/SecureSessionMgr.cpp | 28 ++++----- src/transport/SecureSessionMgr.h | 2 +- src/transport/raw/MessageHeader.cpp | 26 ++++---- src/transport/raw/MessageHeader.h | 22 +++---- src/transport/raw/tests/TestMessageHeader.cpp | 40 ++++++------ src/transport/raw/tests/TestTCP.cpp | 6 +- src/transport/raw/tests/TestUDP.cpp | 6 +- src/transport/tests/TestSecureSessionMgr.cpp | 12 ++-- 22 files changed, 151 insertions(+), 146 deletions(-) diff --git a/src/lib/core/CHIPError.cpp b/src/lib/core/CHIPError.cpp index fc6623e608ab53..3934a35bcb12be 100644 --- a/src/lib/core/CHIPError.cpp +++ b/src/lib/core/CHIPError.cpp @@ -389,8 +389,8 @@ bool FormatCHIPError(char * buf, uint16_t bufSize, CHIP_ERROR err) case CHIP_ERROR_RETRANS_TABLE_FULL.AsInteger(): desc = "Retransmit Table is already full"; break; - case CHIP_ERROR_INVALID_ACK_ID.AsInteger(): - desc = "Invalid Acknowledgment Id"; + case CHIP_ERROR_INVALID_ACK_MESSAGE_COUNTER.AsInteger(): + desc = "Invalid acknowledged message counter"; break; case CHIP_ERROR_SEND_THROTTLED.AsInteger(): desc = "Sending to peer is throttled on this Exchange"; diff --git a/src/lib/core/CHIPError.h b/src/lib/core/CHIPError.h index a50be6da4d441a..29590431aacb79 100644 --- a/src/lib/core/CHIPError.h +++ b/src/lib/core/CHIPError.h @@ -1316,13 +1316,13 @@ using CHIP_ERROR = ::chip::ChipError; #define CHIP_ERROR_RETRANS_TABLE_FULL CHIP_CORE_ERROR(0x64) /** - * @def CHIP_ERROR_INVALID_ACK_ID + * @def CHIP_ERROR_INVALID_ACK_MESSAGE_COUNTER * * @brief * An acknowledgment id is invalid. * */ -#define CHIP_ERROR_INVALID_ACK_ID CHIP_CORE_ERROR(0x65) +#define CHIP_ERROR_INVALID_ACK_MESSAGE_COUNTER CHIP_CORE_ERROR(0x65) /** * @def CHIP_ERROR_SEND_THROTTLED @@ -2177,7 +2177,7 @@ using CHIP_ERROR = ::chip::ChipError; * @def CHIP_ERROR_MESSAGE_ID_OUT_OF_WINDOW * * @brief - * The message id of the received message is out of receiving window + * The message counter of the received message is out of receiving window */ #define CHIP_ERROR_MESSAGE_ID_OUT_OF_WINDOW CHIP_CORE_ERROR(0xc7) diff --git a/src/lib/core/tests/TestCHIPErrorStr.cpp b/src/lib/core/tests/TestCHIPErrorStr.cpp index 7198448344b08d..b268ebfcf0f05a 100644 --- a/src/lib/core/tests/TestCHIPErrorStr.cpp +++ b/src/lib/core/tests/TestCHIPErrorStr.cpp @@ -150,7 +150,7 @@ static const CHIP_ERROR kTestElements[] = CHIP_ERROR_DEVICE_AUTH_TIMEOUT, CHIP_ERROR_MESSAGE_NOT_ACKNOWLEDGED, CHIP_ERROR_RETRANS_TABLE_FULL, - CHIP_ERROR_INVALID_ACK_ID, + CHIP_ERROR_INVALID_ACK_MESSAGE_COUNTER, CHIP_ERROR_SEND_THROTTLED, CHIP_ERROR_WRONG_MSG_VERSION_FOR_EXCHANGE, CHIP_ERROR_TRANSACTION_CANCELED, diff --git a/src/lib/support/CHIPFaultInjection.cpp b/src/lib/support/CHIPFaultInjection.cpp index e837a08817fafc..ec4a286cefc8e0 100644 --- a/src/lib/support/CHIPFaultInjection.cpp +++ b/src/lib/support/CHIPFaultInjection.cpp @@ -78,7 +78,7 @@ DLL_EXPORT void FuzzExchangeHeader(uint8_t * p, int32_t arg) 1, // MessageType 2, // ExchangeId 4, // ProfileId - 8 // AckMsgId + 8 // AckMessageCounter }; const uint8_t values[CHIP_FAULT_INJECTION_NUM_FUZZ_VALUES] = { 0x1, 0x2, 0xFF }; size_t offsetIndex = 0; diff --git a/src/messaging/ExchangeMessageDispatch.cpp b/src/messaging/ExchangeMessageDispatch.cpp index ab810af354810c..6788651581d33b 100644 --- a/src/messaging/ExchangeMessageDispatch.cpp +++ b/src/messaging/ExchangeMessageDispatch.cpp @@ -52,12 +52,13 @@ CHIP_ERROR ExchangeMessageDispatch::SendMessage(SessionHandle session, uint16_t // If there is a pending acknowledgment piggyback it on this message. if (reliableMessageContext->IsAckPending()) { - payloadHeader.SetAckId(reliableMessageContext->TakePendingPeerAckId()); + payloadHeader.SetAckMessageCounter(reliableMessageContext->TakePendingPeerAckMessageCounter()); #if !defined(NDEBUG) if (!payloadHeader.HasMessageType(Protocols::SecureChannel::MsgType::StandaloneAck)) { - ChipLogDetail(ExchangeManager, "Piggybacking Ack for MsgId:%08" PRIX32 " with msg", payloadHeader.GetAckId().Value()); + ChipLogDetail(ExchangeManager, "Piggybacking Ack for MessageCounter:%08" PRIX32 " with msg", + payloadHeader.GetAckMessageCounter().Value()); } #endif } @@ -103,9 +104,10 @@ CHIP_ERROR ExchangeMessageDispatch::OnMessageReceived(uint32_t messageCounter, c if (IsReliableTransmissionAllowed()) { - if (!msgFlags.Has(MessageFlagValues::kDuplicateMessage) && payloadHeader.IsAckMsg() && payloadHeader.GetAckId().HasValue()) + if (!msgFlags.Has(MessageFlagValues::kDuplicateMessage) && payloadHeader.IsAckMsg() && + payloadHeader.GetAckMessageCounter().HasValue()) { - ReturnErrorOnFailure(reliableMessageContext->HandleRcvdAck(payloadHeader.GetAckId().Value())); + ReturnErrorOnFailure(reliableMessageContext->HandleRcvdAck(payloadHeader.GetAckMessageCounter().Value())); } if (payloadHeader.NeedsAck()) diff --git a/src/messaging/ExchangeMgr.cpp b/src/messaging/ExchangeMgr.cpp index 2e0a1733bb0419..73869298434d24 100644 --- a/src/messaging/ExchangeMgr.cpp +++ b/src/messaging/ExchangeMgr.cpp @@ -224,7 +224,7 @@ void ExchangeManager::OnMessageReceived(const PacketHeader & packetHeader, const } // Matched ExchangeContext; send to message handler. - ec->HandleMessage(packetHeader.GetMessageId(), payloadHeader, source, msgFlags, std::move(msgBuf)); + ec->HandleMessage(packetHeader.GetMessageCounter(), payloadHeader, source, msgFlags, std::move(msgBuf)); found = true; return false; } @@ -297,7 +297,7 @@ void ExchangeManager::OnMessageReceived(const PacketHeader & packetHeader, const return; } - CHIP_ERROR err = ec->HandleMessage(packetHeader.GetMessageId(), payloadHeader, source, msgFlags, std::move(msgBuf)); + CHIP_ERROR err = ec->HandleMessage(packetHeader.GetMessageCounter(), payloadHeader, source, msgFlags, std::move(msgBuf)); if (err != CHIP_NO_ERROR) { // Using same error message for all errors to reduce code size. diff --git a/src/messaging/Flags.h b/src/messaging/Flags.h index be3849ce2b3132..11d86d3c4cce83 100644 --- a/src/messaging/Flags.h +++ b/src/messaging/Flags.h @@ -46,7 +46,7 @@ enum class MessageFlagValues : uint32_t /**< Indicates that the message is a duplicate of a previously received message. */ kDuplicateMessage = 0x00004000, /**< Indicates that the peer's group key message counter is not synchronized. */ - kPeerGroupMsgIdNotSynchronized = 0x00008000, + kPeerGroupMessageCounterNotSynchronized = 0x00008000, /**< Indicates that the source of the message is the initiator of the CHIP exchange. */ kFromInitiator = 0x00010000, /**< Indicates that message is being sent/received via the local ephemeral UDP port. */ diff --git a/src/messaging/ReliableMessageContext.cpp b/src/messaging/ReliableMessageContext.cpp index b48c47b9ed5fe6..79809a12e36d7d 100644 --- a/src/messaging/ReliableMessageContext.cpp +++ b/src/messaging/ReliableMessageContext.cpp @@ -40,7 +40,7 @@ namespace chip { namespace Messaging { ReliableMessageContext::ReliableMessageContext() : - mConfig(gDefaultReliableMessageProtocolConfig), mNextAckTimeTick(0), mPendingPeerAckId(0) + mConfig(gDefaultReliableMessageProtocolConfig), mNextAckTimeTick(0), mPendingPeerAckMessageCounter(0) {} void ReliableMessageContext::RetainContext() @@ -125,7 +125,7 @@ CHIP_ERROR ReliableMessageContext::FlushAcks() if (err == CHIP_NO_ERROR) { #if !defined(NDEBUG) - ChipLogDetail(ExchangeManager, "Flushed pending ack for MsgId:%08" PRIX32, mPendingPeerAckId); + ChipLogDetail(ExchangeManager, "Flushed pending ack for MessageCounter:%08" PRIX32, mPendingPeerAckMessageCounter); #endif } } @@ -150,36 +150,37 @@ uint64_t ReliableMessageContext::GetActiveRetransmitTimeoutTick() * @note * This message is part of the CHIP Reliable Messaging protocol. * - * @param[in] AckMsgId The msgId of incoming Ack message. + * @param[in] ackMessageCounter The messageCounter of incoming Ack message. * - * @retval #CHIP_ERROR_INVALID_ACK_ID if the msgId of received Ack is not in the RetransTable. + * @retval #CHIP_ERROR_INVALID_ACK_MESSAGE_COUNTER if the messageCounter of received Ack is not in the + * RetransTable. * @retval #CHIP_NO_ERROR if the context was removed. * */ -CHIP_ERROR ReliableMessageContext::HandleRcvdAck(uint32_t AckMsgId) +CHIP_ERROR ReliableMessageContext::HandleRcvdAck(uint32_t ackMessageCounter) { CHIP_ERROR err = CHIP_NO_ERROR; // Msg is an Ack; Check Retrans Table and remove message context - if (!GetReliableMessageMgr()->CheckAndRemRetransTable(this, AckMsgId)) + if (!GetReliableMessageMgr()->CheckAndRemRetransTable(this, ackMessageCounter)) { #if !defined(NDEBUG) - ChipLogError(ExchangeManager, "CHIP MsgId:%08" PRIX32 " not in RetransTable", AckMsgId); + ChipLogError(ExchangeManager, "CHIP MessageCounter:%08" PRIX32 " not in RetransTable", ackMessageCounter); #endif - err = CHIP_ERROR_INVALID_ACK_ID; + err = CHIP_ERROR_INVALID_ACK_MESSAGE_COUNTER; // Optionally call an application callback with this error. } else { #if !defined(NDEBUG) - ChipLogDetail(ExchangeManager, "Removed CHIP MsgId:%08" PRIX32 " from RetransTable", AckMsgId); + ChipLogDetail(ExchangeManager, "Removed CHIP MessageCounter:%08" PRIX32 " from RetransTable", ackMessageCounter); #endif } return err; } -CHIP_ERROR ReliableMessageContext::HandleNeedsAck(uint32_t messageId, BitFlags messageFlags) +CHIP_ERROR ReliableMessageContext::HandleNeedsAck(uint32_t messageCounter, BitFlags messageFlags) { // Skip processing ack if drop ack debug is enabled. @@ -189,7 +190,7 @@ CHIP_ERROR ReliableMessageContext::HandleNeedsAck(uint32_t messageId, BitFlagsExpireTicks(); - CHIP_ERROR err = HandleNeedsAckInner(messageId, messageFlags); + CHIP_ERROR err = HandleNeedsAckInner(messageCounter, messageFlags); // Schedule next physical wakeup on function exit GetReliableMessageMgr()->StartTimer(); @@ -197,7 +198,7 @@ CHIP_ERROR ReliableMessageContext::HandleNeedsAck(uint32_t messageId, BitFlags messageFlags) +CHIP_ERROR ReliableMessageContext::HandleNeedsAckInner(uint32_t messageCounter, BitFlags messageFlags) { // If the message IS a duplicate there will never be a response to it, so we @@ -205,25 +206,25 @@ CHIP_ERROR ReliableMessageContext::HandleNeedsAckInner(uint32_t messageId, BitFl if (messageFlags.Has(MessageFlagValues::kDuplicateMessage)) { #if !defined(NDEBUG) - ChipLogDetail(ExchangeManager, "Forcing tx of solitary ack for duplicate MsgId:%08" PRIX32, messageId); + ChipLogDetail(ExchangeManager, "Forcing tx of solitary ack for duplicate MessageCounter:%08" PRIX32, messageCounter); #endif - // Is there pending ack for a different message id. - bool wasAckPending = IsAckPending() && mPendingPeerAckId != messageId; + // Is there pending ack for a different message counter. + bool wasAckPending = IsAckPending() && mPendingPeerAckMessageCounter != messageCounter; - // Temporary store currently pending ack id (even if there is none). - uint32_t tempAckId = mPendingPeerAckId; + // Temporary store currently pending ack message counter (even if there is none). + uint32_t tempAckMessageCounter = mPendingPeerAckMessageCounter; - // Set the pending ack id. - SetPendingPeerAckId(messageId); + // Set the pending ack message counter. + SetPendingPeerAckMessageCounter(messageCounter); // Send the Ack for the duplication message in a SecureChannel::StandaloneAck message. CHIP_ERROR err = SendStandaloneAckMessage(); - // If there was pending ack for a different message id. + // If there was pending ack for a different message counter. if (wasAckPending) { - // Restore previously pending ack id. - SetPendingPeerAckId(tempAckId); + // Restore previously pending ack message counter. + SetPendingPeerAckMessageCounter(tempAckMessageCounter); } return err; @@ -234,15 +235,15 @@ CHIP_ERROR ReliableMessageContext::HandleNeedsAckInner(uint32_t messageId, BitFl if (IsAckPending()) { #if !defined(NDEBUG) - ChipLogDetail(ExchangeManager, "Pending ack queue full; forcing tx of solitary ack for MsgId:%08" PRIX32, - mPendingPeerAckId); + ChipLogDetail(ExchangeManager, "Pending ack queue full; forcing tx of solitary ack for MessageCounter:%08" PRIX32, + mPendingPeerAckMessageCounter); #endif // Send the Ack for the currently pending Ack in a SecureChannel::StandaloneAck message. ReturnErrorOnFailure(SendStandaloneAckMessage()); } - // Replace the Pending ack id. - SetPendingPeerAckId(messageId); + // Replace the Pending ack message counter. + SetPendingPeerAckMessageCounter(messageCounter); mNextAckTimeTick = static_cast(CHIP_CONFIG_RMP_DEFAULT_ACK_TIMEOUT_TICK + GetReliableMessageMgr()->GetTickCounterFromTimeDelta(System::Clock::GetMonotonicMilliseconds())); @@ -261,7 +262,7 @@ CHIP_ERROR ReliableMessageContext::SendStandaloneAckMessage() // Send the null message #if !defined(NDEBUG) - ChipLogDetail(ExchangeManager, "Sending Standalone Ack for MsgId:%08" PRIX32, mPendingPeerAckId); + ChipLogDetail(ExchangeManager, "Sending Standalone Ack for MessageCounter:%08" PRIX32, mPendingPeerAckMessageCounter); #endif CHIP_ERROR err = GetExchangeContext()->SendMessage(Protocols::SecureChannel::MsgType::StandaloneAck, std::move(msgBuf), @@ -273,16 +274,16 @@ CHIP_ERROR ReliableMessageContext::SendStandaloneAckMessage() } if (err != CHIP_NO_ERROR) { - ChipLogError(ExchangeManager, "Failed to send Solitary ack for MsgId:%08" PRIX32 ":%" CHIP_ERROR_FORMAT, mPendingPeerAckId, - err.Format()); + ChipLogError(ExchangeManager, "Failed to send Solitary ack for MessageCounter:%08" PRIX32 ":%" CHIP_ERROR_FORMAT, + mPendingPeerAckMessageCounter, err.Format()); } return err; } -void ReliableMessageContext::SetPendingPeerAckId(uint32_t aPeerAckId) +void ReliableMessageContext::SetPendingPeerAckMessageCounter(uint32_t aPeerAckMessageCounter) { - mPendingPeerAckId = aPeerAckId; + mPendingPeerAckMessageCounter = aPeerAckMessageCounter; SetAckPending(true); } diff --git a/src/messaging/ReliableMessageContext.h b/src/messaging/ReliableMessageContext.h index 099afb5b2bcd8a..de013761d71b8a 100644 --- a/src/messaging/ReliableMessageContext.h +++ b/src/messaging/ReliableMessageContext.h @@ -58,14 +58,14 @@ class ReliableMessageContext CHIP_ERROR FlushAcks(); /** - * Take the pending peer ack id from the context. This must only be called + * Take the pending peer ack message counter from the context. This must only be called * when IsAckPending() is true. After this call, IsAckPending() will be * false; it's the caller's responsibility to send the ack. */ - uint32_t TakePendingPeerAckId() + uint32_t TakePendingPeerAckMessageCounter() { SetAckPending(false); - return mPendingPeerAckId; + return mPendingPeerAckMessageCounter; } /** @@ -217,9 +217,9 @@ class ReliableMessageContext private: void RetainContext(); void ReleaseContext(); - CHIP_ERROR HandleRcvdAck(uint32_t AckMsgId); - CHIP_ERROR HandleNeedsAck(uint32_t messageId, BitFlags messageFlags); - CHIP_ERROR HandleNeedsAckInner(uint32_t messageId, BitFlags messageFlags); + CHIP_ERROR HandleRcvdAck(uint32_t ackMessageCounter); + CHIP_ERROR HandleNeedsAck(uint32_t messageCounter, BitFlags messageFlags); + CHIP_ERROR HandleNeedsAckInner(uint32_t messageCounter, BitFlags messageFlags); ExchangeContext * GetExchangeContext(); /** @@ -231,9 +231,9 @@ class ReliableMessageContext */ void SetAckPending(bool inAckPending); - // Set our pending peer ack id and any other state needed to ensure that we + // Set our pending peer ack message counter and any other state needed to ensure that we // will send that ack at some point. - void SetPendingPeerAckId(uint32_t aPeerAckId); + void SetPendingPeerAckMessageCounter(uint32_t aPeerAckMessageCounter); private: friend class ReliableMessageMgr; @@ -242,7 +242,7 @@ class ReliableMessageContext ReliableMessageProtocolConfig mConfig; uint16_t mNextAckTimeTick; // Next time for triggering Solo Ack - uint32_t mPendingPeerAckId; + uint32_t mPendingPeerAckMessageCounter; }; } // namespace Messaging diff --git a/src/messaging/ReliableMessageMgr.cpp b/src/messaging/ReliableMessageMgr.cpp index 41b8baa60975f0..ad99c66354d071 100644 --- a/src/messaging/ReliableMessageMgr.cpp +++ b/src/messaging/ReliableMessageMgr.cpp @@ -88,8 +88,8 @@ void ReliableMessageMgr::TicklessDebugDumpRetransTable(const char * log) { if (entry.rc) { - ChipLogDetail(ExchangeManager, "EC:%04" PRIX16 " MsgId:%08" PRIX32 " NextRetransTimeCtr:%04" PRIX16, entry.rc, - entry.msgId, entry.nextRetransTimeTick); + ChipLogDetail(ExchangeManager, "EC:%04" PRIX16 " MessageCounter:%08" PRIX32 " NextRetransTimeCtr:%04" PRIX16, entry.rc, + entry.messageCounter, entry.nextRetransTimeTick); } } } @@ -143,15 +143,15 @@ void ReliableMessageMgr::ExecuteActions() continue; } - uint8_t sendCount = entry.sendCount; - uint32_t msgId = entry.retainedBuf.GetMsgId(); + uint8_t sendCount = entry.sendCount; + uint32_t messageCounter = entry.retainedBuf.GetMessageCounter(); if (sendCount == CHIP_CONFIG_RMP_DEFAULT_MAX_RETRANS) { err = CHIP_ERROR_MESSAGE_NOT_ACKNOWLEDGED; - ChipLogError(ExchangeManager, "Failed to Send CHIP MsgId:%08" PRIX32 " sendCount: %" PRIu8 " max retries: %d", msgId, - sendCount, CHIP_CONFIG_RMP_DEFAULT_MAX_RETRANS); + ChipLogError(ExchangeManager, "Failed to Send CHIP MessageCounter:%08" PRIX32 " sendCount: %" PRIu8 " max retries: %d", + messageCounter, sendCount, CHIP_CONFIG_RMP_DEFAULT_MAX_RETRANS); // Remove from Table ClearRetransTable(entry); @@ -166,7 +166,7 @@ void ReliableMessageMgr::ExecuteActions() // If the retransmission was successful, update the passive timer entry.nextRetransTimeTick = static_cast(rc->GetActiveRetransmitTimeoutTick()); #if !defined(NDEBUG) - ChipLogDetail(ExchangeManager, "Retransmit MsgId:%08" PRIX32 " Send Cnt %d", msgId, entry.sendCount); + ChipLogDetail(ExchangeManager, "Retransmit MessageCounter:%08" PRIX32 " Send Cnt %d", messageCounter, entry.sendCount); #endif } } @@ -329,17 +329,17 @@ void ReliableMessageMgr::ResumeRetransmision(ReliableMessageContext * rc) } } -bool ReliableMessageMgr::CheckAndRemRetransTable(ReliableMessageContext * rc, uint32_t ackMsgId) +bool ReliableMessageMgr::CheckAndRemRetransTable(ReliableMessageContext * rc, uint32_t ackMessageCounter) { for (RetransTableEntry & entry : mRetransTable) { - if ((entry.rc == rc) && entry.retainedBuf.GetMsgId() == ackMsgId) + if ((entry.rc == rc) && entry.retainedBuf.GetMessageCounter() == ackMessageCounter) { // Clear the entry from the retransmision table. ClearRetransTable(entry); #if !defined(NDEBUG) - ChipLogDetail(ExchangeManager, "Rxd Ack; Removing MsgId:%08" PRIX32 " from Retrans Table", ackMsgId); + ChipLogDetail(ExchangeManager, "Rxd Ack; Removing MessageCounter:%08" PRIX32 " from Retrans Table", ackMessageCounter); #endif return true; } @@ -360,8 +360,9 @@ CHIP_ERROR ReliableMessageMgr::SendFromRetransTable(RetransTableEntry * entry) if (dispatcher == nullptr || !rc->GetExchangeContext()->HasSecureSession()) { // Using same error message for all errors to reduce code size. - ChipLogError(ExchangeManager, "Crit-err %" CHIP_ERROR_FORMAT " when sending CHIP MsgId:%08" PRIX32 ", send tries: %d", - CHIP_ERROR_INCORRECT_STATE.Format(), entry->retainedBuf.GetMsgId(), entry->sendCount); + ChipLogError(ExchangeManager, + "Crit-err %" CHIP_ERROR_FORMAT " when sending CHIP MessageCounter:%08" PRIX32 ", send tries: %d", + CHIP_ERROR_INCORRECT_STATE.Format(), entry->retainedBuf.GetMessageCounter(), entry->sendCount); ClearRetransTable(*entry); return CHIP_ERROR_INCORRECT_STATE; } @@ -377,8 +378,9 @@ CHIP_ERROR ReliableMessageMgr::SendFromRetransTable(RetransTableEntry * entry) { // Remove from table // Using same error message for all errors to reduce code size. - ChipLogError(ExchangeManager, "Crit-err %" CHIP_ERROR_FORMAT " when sending CHIP MsgId:%08" PRIX32 ", send tries: %d", - err.Format(), entry->retainedBuf.GetMsgId(), entry->sendCount); + ChipLogError(ExchangeManager, + "Crit-err %" CHIP_ERROR_FORMAT " when sending CHIP MessageCounter:%08" PRIX32 ", send tries: %d", err.Format(), + entry->retainedBuf.GetMessageCounter(), entry->sendCount); ClearRetransTable(*entry); } diff --git a/src/messaging/ReliableMessageMgr.h b/src/messaging/ReliableMessageMgr.h index fd7adae2a708c3..933f651185d75e 100644 --- a/src/messaging/ReliableMessageMgr.h +++ b/src/messaging/ReliableMessageMgr.h @@ -151,11 +151,11 @@ class ReliableMessageMgr * * @param[in] rc A pointer to the ExchangeContext object. * - * @param[in] msgId message ID which has been acked. + * @param[in] messageCounter message ID which has been acked. * * @retval #CHIP_NO_ERROR On success. */ - bool CheckAndRemRetransTable(ReliableMessageContext * rc, uint32_t msgId); + bool CheckAndRemRetransTable(ReliableMessageContext * rc, uint32_t messageCounter); /** * Send the specified entry from the retransmission table. diff --git a/src/messaging/tests/TestReliableMessageProtocol.cpp b/src/messaging/tests/TestReliableMessageProtocol.cpp index 6f8874a9a1d702..34d6ef108256af 100644 --- a/src/messaging/tests/TestReliableMessageProtocol.cpp +++ b/src/messaging/tests/TestReliableMessageProtocol.cpp @@ -78,7 +78,7 @@ class MockAppDelegate : public ExchangeDelegate auto * rc = ec->GetReliableMessageContext(); if (rc->IsAckPending()) { - (void) rc->TakePendingPeerAckId(); + (void) rc->TakePendingPeerAckMessageCounter(); } } diff --git a/src/transport/SecureMessageCodec.cpp b/src/transport/SecureMessageCodec.cpp index d49dfef267cfee..05bf96085797bd 100644 --- a/src/transport/SecureMessageCodec.cpp +++ b/src/transport/SecureMessageCodec.cpp @@ -43,13 +43,13 @@ CHIP_ERROR Encode(Transport::PeerConnectionState * state, PayloadHeader & payloa VerifyOrReturnError(!msgBuf->HasChainedBuffer(), CHIP_ERROR_INVALID_MESSAGE_LENGTH); VerifyOrReturnError(msgBuf->TotalLength() <= kMaxAppMessageLen, CHIP_ERROR_MESSAGE_TOO_LONG); - uint32_t msgId = counter.Value(); + uint32_t messageCounter = counter.Value(); static_assert(std::is_sameTotalLength()), uint16_t>::value, "Addition to generate payloadLength might overflow"); packetHeader - .SetMessageId(msgId) // + .SetMessageCounter(messageCounter) // .SetEncryptionKeyID(state->GetPeerKeyID()); packetHeader.GetFlags().Set(Header::FlagValues::kEncryptedMessage); @@ -68,7 +68,7 @@ CHIP_ERROR Encode(Transport::PeerConnectionState * state, PayloadHeader & payloa VerifyOrReturnError(CanCastTo(totalLen + taglen), CHIP_ERROR_INTERNAL); msgBuf->SetDataLength(static_cast(totalLen + taglen)); - ChipLogDetail(Inet, "Secure message was encrypted: Msg ID %" PRIu32, msgId); + ChipLogDetail(Inet, "Secure message was encrypted: Msg ID %" PRIu32, messageCounter); ReturnErrorOnFailure(counter.Advance()); return CHIP_NO_ERROR; diff --git a/src/transport/SecureSession.cpp b/src/transport/SecureSession.cpp index 0c78ca0ae61bb2..dea77b794cf517 100644 --- a/src/transport/SecureSession.cpp +++ b/src/transport/SecureSession.cpp @@ -102,7 +102,7 @@ CHIP_ERROR SecureSession::GetIV(const PacketHeader & header, uint8_t * iv, size_ Encoding::LittleEndian::BufferWriter bbuf(iv, len); bbuf.Put64(header.GetSourceNodeId().ValueOr(0)); - bbuf.Put32(header.GetMessageId()); + bbuf.Put32(header.GetMessageCounter()); return bbuf.Fit() ? CHIP_NO_ERROR : CHIP_ERROR_NO_MEMORY; } diff --git a/src/transport/SecureSessionMgr.cpp b/src/transport/SecureSessionMgr.cpp index 54ef62b6d4ba9f..b7092cf592838b 100644 --- a/src/transport/SecureSessionMgr.cpp +++ b/src/transport/SecureSessionMgr.cpp @@ -48,7 +48,7 @@ using System::PacketBufferHandle; using Transport::PeerAddress; using Transport::PeerConnectionState; -uint32_t EncryptedPacketBufferHandle::GetMsgId() const +uint32_t EncryptedPacketBufferHandle::GetMessageCounter() const { PacketHeader header; uint16_t headerSize = 0; @@ -56,7 +56,7 @@ uint32_t EncryptedPacketBufferHandle::GetMsgId() const if (err == CHIP_NO_ERROR) { - return header.GetMessageId(); + return header.GetMessageCounter(); } ChipLogError(Inet, "Failed to decode EncryptedPacketBufferHandle header with error: %s", ErrorStr(err)); @@ -124,27 +124,27 @@ CHIP_ERROR SecureSessionMgr::PrepareMessage(SessionHandle session, PayloadHeader ChipLogProgress(Inet, "Build %s message %p to 0x" ChipLogFormatX64 " of type %d and protocolId %" PRIu32 - " on exchange %d with MessageId %" PRIu32 ".", + " on exchange %d with MessageCounter %" PRIu32 ".", "encrypted", &preparedMessage, ChipLogValueX64(state->GetPeerNodeId()), payloadHeader.GetMessageType(), payloadHeader.GetProtocolID().ToFullyQualifiedSpecForm(), payloadHeader.GetExchangeID(), - packetHeader.GetMessageId()); + packetHeader.GetMessageCounter()); } else { ReturnErrorOnFailure(payloadHeader.EncodeBeforeData(message)); MessageCounter & counter = session.GetUnauthenticatedSession()->GetLocalMessageCounter(); - uint32_t messageId = counter.Value(); + uint32_t messageCounter = counter.Value(); ReturnErrorOnFailure(counter.Advance()); - packetHeader.SetMessageId(messageId); + packetHeader.SetMessageCounter(messageCounter); ChipLogProgress(Inet, "Build %s message %p to 0x" ChipLogFormatX64 " of type %d and protocolId %" PRIu32 - " on exchange %d with MessageId %" PRIu32 ".", + " on exchange %d with MessageCounter %" PRIu32 ".", "plaintext", &preparedMessage, ChipLogValueX64(kUndefinedNodeId), payloadHeader.GetMessageType(), payloadHeader.GetProtocolID().ToFullyQualifiedSpecForm(), payloadHeader.GetExchangeID(), - packetHeader.GetMessageId()); + packetHeader.GetMessageCounter()); } ReturnErrorOnFailure(packetHeader.EncodeBeforeData(message)); @@ -339,10 +339,10 @@ void SecureSessionMgr::MessageDispatch(const PacketHeader & packetHeader, const SecureSessionMgrDelegate::DuplicateMessage isDuplicate = SecureSessionMgrDelegate::DuplicateMessage::No; // Verify message counter - CHIP_ERROR err = session->GetPeerMessageCounter().VerifyOrTrustFirst(packetHeader.GetMessageId()); + CHIP_ERROR err = session->GetPeerMessageCounter().VerifyOrTrustFirst(packetHeader.GetMessageCounter()); if (err == CHIP_ERROR_DUPLICATE_MESSAGE_RECEIVED) { - ChipLogDetail(Inet, "Received a duplicate message with MessageId: %" PRIu32, packetHeader.GetMessageId()); + ChipLogDetail(Inet, "Received a duplicate message with MessageCounter: %" PRIu32, packetHeader.GetMessageCounter()); isDuplicate = SecureSessionMgrDelegate::DuplicateMessage::Yes; err = CHIP_NO_ERROR; } @@ -353,7 +353,7 @@ void SecureSessionMgr::MessageDispatch(const PacketHeader & packetHeader, const PayloadHeader payloadHeader; ReturnOnFailure(payloadHeader.DecodeAndConsume(msg)); - session->GetPeerMessageCounter().Commit(packetHeader.GetMessageId()); + session->GetPeerMessageCounter().Commit(packetHeader.GetMessageCounter()); if (mCB != nullptr) { @@ -411,10 +411,10 @@ void SecureSessionMgr::SecureMessageDispatch(const PacketHeader & packetHeader, return; } - err = state->GetSessionMessageCounter().GetPeerMessageCounter().Verify(packetHeader.GetMessageId()); + err = state->GetSessionMessageCounter().GetPeerMessageCounter().Verify(packetHeader.GetMessageCounter()); if (err == CHIP_ERROR_DUPLICATE_MESSAGE_RECEIVED) { - ChipLogDetail(Inet, "Received a duplicate message with MessageId: %" PRIu32, packetHeader.GetMessageId()); + ChipLogDetail(Inet, "Received a duplicate message with MessageCounter: %" PRIu32, packetHeader.GetMessageCounter()); isDuplicate = SecureSessionMgrDelegate::DuplicateMessage::Yes; err = CHIP_NO_ERROR; } @@ -444,7 +444,7 @@ void SecureSessionMgr::SecureMessageDispatch(const PacketHeader & packetHeader, } else { - state->GetSessionMessageCounter().GetPeerMessageCounter().Commit(packetHeader.GetMessageId()); + state->GetSessionMessageCounter().GetPeerMessageCounter().Commit(packetHeader.GetMessageCounter()); } // TODO: once mDNS address resolution is available reconsider if this is required diff --git a/src/transport/SecureSessionMgr.h b/src/transport/SecureSessionMgr.h index f5d5ca82d7e7c9..942f05f374ac6d 100644 --- a/src/transport/SecureSessionMgr.h +++ b/src/transport/SecureSessionMgr.h @@ -67,7 +67,7 @@ class EncryptedPacketBufferHandle final : private System::PacketBufferHandle // exposing operator-> bool HasChainedBuffer() const { return (*this)->HasChainedBuffer(); } - uint32_t GetMsgId() const; + uint32_t GetMessageCounter() const; /** * Creates a copy of the data in this packet. diff --git a/src/transport/raw/MessageHeader.cpp b/src/transport/raw/MessageHeader.cpp index 0a526432208986..b0c377a908004c 100644 --- a/src/transport/raw/MessageHeader.cpp +++ b/src/transport/raw/MessageHeader.cpp @@ -74,8 +74,8 @@ constexpr size_t kNodeIdSizeBytes = 8; /// size of a serialized vendor id inside a header constexpr size_t kVendorIdSizeBytes = 2; -/// size of a serialized ack id inside a header -constexpr size_t kAckIdSizeBytes = 4; +/// size of a serialized ack message counter inside a header +constexpr size_t kAckMessageCounterSizeBytes = 4; /// Mask to extract just the version part from a 16bit header prefix. constexpr uint16_t kVersionMask = 0x00F0; @@ -117,12 +117,12 @@ uint16_t PayloadHeader::EncodeSizeBytes() const size += kVendorIdSizeBytes; } - if (mAckId.HasValue()) + if (mAckMessageCounter.HasValue()) { - size += kAckIdSizeBytes; + size += kAckMessageCounterSizeBytes; } - static_assert(kEncryptedHeaderSizeBytes + kVendorIdSizeBytes + kAckIdSizeBytes <= UINT16_MAX, + static_assert(kEncryptedHeaderSizeBytes + kVendorIdSizeBytes + kAckMessageCounterSizeBytes <= UINT16_MAX, "Header size does not fit in uint16_t"); return static_cast(size); } @@ -156,7 +156,7 @@ CHIP_ERROR PacketHeader::Decode(const uint8_t * const data, uint16_t size, uint1 mFlags.SetRaw(header); mEncryptionType = static_cast((header & kEncryptionTypeMask) >> kEncryptionTypeShift); - err = reader.Read32(&mMessageId).StatusCode(); + err = reader.Read32(&mMessageCounter).StatusCode(); SuccessOrExit(err); if (mFlags.Has(Header::FlagValues::kSourceNodeIdPresent)) @@ -236,14 +236,14 @@ CHIP_ERROR PayloadHeader::Decode(const uint8_t * const data, uint16_t size, uint if (mExchangeFlags.Has(Header::ExFlagValues::kExchangeFlag_AckMsg)) { - uint32_t ack_id; - err = reader.Read32(&ack_id).StatusCode(); + uint32_t ack_message_counter; + err = reader.Read32(&ack_message_counter).StatusCode(); SuccessOrExit(err); - mAckId.SetValue(ack_id); + mAckMessageCounter.SetValue(ack_message_counter); } else { - mAckId.ClearValue(); + mAckMessageCounter.ClearValue(); } octets_read = static_cast(reader.OctetsRead()); @@ -276,7 +276,7 @@ CHIP_ERROR PacketHeader::Encode(uint8_t * data, uint16_t size, uint16_t * encode uint8_t * p = data; LittleEndian::Write16(p, header); - LittleEndian::Write32(p, mMessageId); + LittleEndian::Write32(p, mMessageCounter); if (mSourceNodeId.HasValue()) { LittleEndian::Write64(p, mSourceNodeId.Value()); @@ -323,9 +323,9 @@ CHIP_ERROR PayloadHeader::Encode(uint8_t * data, uint16_t size, uint16_t * encod LittleEndian::Write16(p, to_underlying(mProtocolID.GetVendorId())); } LittleEndian::Write16(p, mProtocolID.GetProtocolId()); - if (mAckId.HasValue()) + if (mAckMessageCounter.HasValue()) { - LittleEndian::Write32(p, mAckId.Value()); + LittleEndian::Write32(p, mAckMessageCounter.Value()); } // Written data size provided to caller on success diff --git a/src/transport/raw/MessageHeader.h b/src/transport/raw/MessageHeader.h index c4c223f5c761d1..854fa6d1720c33 100644 --- a/src/transport/raw/MessageHeader.h +++ b/src/transport/raw/MessageHeader.h @@ -113,12 +113,12 @@ class PacketHeader { public: /** - * Gets the message id set in the header. + * Gets the message counter set in the header. * * Message IDs are expecte to monotonically increase by one for each mesage * that has been sent. */ - uint32_t GetMessageId() const { return mMessageId; } + uint32_t GetMessageCounter() const { return mMessageCounter; } /** * Gets the source node id in the current message. @@ -198,9 +198,9 @@ class PacketHeader return *this; } - PacketHeader & SetMessageId(uint32_t id) + PacketHeader & SetMessageCounter(uint32_t id) { - mMessageId = id; + mMessageCounter = id; return *this; } @@ -295,7 +295,7 @@ class PacketHeader static constexpr int kHeaderVersion = 2; /// Value expected to be incremented for each message sent. - uint32_t mMessageId = 0; + uint32_t mMessageCounter = 0; /// What node the message originated from Optional mSourceNodeId; @@ -350,7 +350,7 @@ class PayloadHeader * * NOTE: the Acknowledged Message Counter is optional and may be missing. */ - const Optional & GetAckId() const { return mAckId; } + const Optional & GetAckMessageCounter() const { return mAckMessageCounter; } /** * Set the message type for this header. This requires setting the protocol @@ -391,17 +391,17 @@ class PayloadHeader return *this; } - PayloadHeader & SetAckId(uint32_t id) + PayloadHeader & SetAckMessageCounter(uint32_t id) { - mAckId.SetValue(id); + mAckMessageCounter.SetValue(id); mExchangeFlags.Set(Header::ExFlagValues::kExchangeFlag_AckMsg); return *this; } /** Set the AckMsg flag bit. */ - PayloadHeader & SetAckId(Optional id) + PayloadHeader & SetAckMessageCounter(Optional id) { - mAckId = id; + mAckMessageCounter = id; mExchangeFlags.Set(Header::ExFlagValues::kExchangeFlag_AckMsg, id.HasValue()); return *this; } @@ -540,7 +540,7 @@ class PayloadHeader Header::ExFlags mExchangeFlags; /// Message counter of a previous message that is being acknowledged by the current message - Optional mAckId; + Optional mAckMessageCounter; }; /** Handles encoding/decoding of CHIP message headers */ diff --git a/src/transport/raw/tests/TestMessageHeader.cpp b/src/transport/raw/tests/TestMessageHeader.cpp index 7138a29f4bde6e..e946a546277049 100644 --- a/src/transport/raw/tests/TestMessageHeader.cpp +++ b/src/transport/raw/tests/TestMessageHeader.cpp @@ -39,7 +39,7 @@ void TestPacketHeaderInitialState(nlTestSuite * inSuite, void * inContext) PacketHeader header; NL_TEST_ASSERT(inSuite, !header.IsSecureSessionControlMsg()); - NL_TEST_ASSERT(inSuite, header.GetMessageId() == 0); + NL_TEST_ASSERT(inSuite, header.GetMessageCounter() == 0); NL_TEST_ASSERT(inSuite, header.GetEncryptionKeyID() == 0); NL_TEST_ASSERT(inSuite, !header.GetDestinationNodeId().HasValue()); NL_TEST_ASSERT(inSuite, !header.GetSourceNodeId().HasValue()); @@ -61,26 +61,26 @@ void TestPacketHeaderEncodeDecode(nlTestSuite * inSuite, void * inContext) uint16_t encodeLen; uint16_t decodeLen; - header.SetMessageId(123); + header.SetMessageCounter(123); NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR); // change it to verify decoding - header.SetMessageId(222).SetSourceNodeId(1).SetDestinationNodeId(2); + header.SetMessageCounter(222).SetSourceNodeId(1).SetDestinationNodeId(2); NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, encodeLen == decodeLen); - NL_TEST_ASSERT(inSuite, header.GetMessageId() == 123); + NL_TEST_ASSERT(inSuite, header.GetMessageCounter() == 123); NL_TEST_ASSERT(inSuite, !header.GetDestinationNodeId().HasValue()); header.SetSourceNodeId(55); NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR); // change it to verify decoding - header.SetMessageId(222).SetSourceNodeId(1).SetDestinationNodeId(2); + header.SetMessageCounter(222).SetSourceNodeId(1).SetDestinationNodeId(2); NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, encodeLen == decodeLen); - NL_TEST_ASSERT(inSuite, header.GetMessageId() == 123); + NL_TEST_ASSERT(inSuite, header.GetMessageCounter() == 123); NL_TEST_ASSERT(inSuite, !header.GetDestinationNodeId().HasValue()); NL_TEST_ASSERT(inSuite, header.GetSourceNodeId() == Optional::Value(55ull)); @@ -88,53 +88,53 @@ void TestPacketHeaderEncodeDecode(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR); // change it to verify decoding - header.SetMessageId(222).SetSourceNodeId(1).SetDestinationNodeId(2); + header.SetMessageCounter(222).SetSourceNodeId(1).SetDestinationNodeId(2); NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, encodeLen == decodeLen); - NL_TEST_ASSERT(inSuite, header.GetMessageId() == 123); + NL_TEST_ASSERT(inSuite, header.GetMessageCounter() == 123); NL_TEST_ASSERT(inSuite, header.GetDestinationNodeId() == Optional::Value(11ull)); NL_TEST_ASSERT(inSuite, !header.GetSourceNodeId().HasValue()); - header.SetMessageId(234).SetSourceNodeId(77).SetDestinationNodeId(88); + header.SetMessageCounter(234).SetSourceNodeId(77).SetDestinationNodeId(88); NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR); // change it to verify decoding - header.SetMessageId(222).SetSourceNodeId(1).SetDestinationNodeId(2); + header.SetMessageCounter(222).SetSourceNodeId(1).SetDestinationNodeId(2); NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, encodeLen == decodeLen); - NL_TEST_ASSERT(inSuite, header.GetMessageId() == 234); + NL_TEST_ASSERT(inSuite, header.GetMessageCounter() == 234); NL_TEST_ASSERT(inSuite, header.GetDestinationNodeId() == Optional::Value(88ull)); NL_TEST_ASSERT(inSuite, header.GetSourceNodeId() == Optional::Value(77ull)); - header.SetMessageId(234).SetSourceNodeId(77).SetDestinationNodeId(88).SetSecureSessionControlMsg(true); + header.SetMessageCounter(234).SetSourceNodeId(77).SetDestinationNodeId(88).SetSecureSessionControlMsg(true); NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR); // change it to verify decoding - header.SetMessageId(222).SetSourceNodeId(1).SetDestinationNodeId(2); + header.SetMessageCounter(222).SetSourceNodeId(1).SetDestinationNodeId(2); NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, header.GetMessageId() == 234); + NL_TEST_ASSERT(inSuite, header.GetMessageCounter() == 234); NL_TEST_ASSERT(inSuite, header.GetDestinationNodeId() == Optional::Value(88ull)); NL_TEST_ASSERT(inSuite, header.GetSourceNodeId() == Optional::Value(77ull)); NL_TEST_ASSERT(inSuite, header.IsSecureSessionControlMsg()); - header.SetMessageId(234).SetSourceNodeId(77).SetDestinationNodeId(88).SetEncryptionKeyID(2); + header.SetMessageCounter(234).SetSourceNodeId(77).SetDestinationNodeId(88).SetEncryptionKeyID(2); NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR); // change it to verify decoding - header.SetMessageId(222).SetSourceNodeId(1).SetDestinationNodeId(2); + header.SetMessageCounter(222).SetSourceNodeId(1).SetDestinationNodeId(2); NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, header.GetMessageId() == 234); + NL_TEST_ASSERT(inSuite, header.GetMessageCounter() == 234); NL_TEST_ASSERT(inSuite, header.GetDestinationNodeId() == Optional::Value(88ull)); NL_TEST_ASSERT(inSuite, header.GetSourceNodeId() == Optional::Value(77ull)); NL_TEST_ASSERT(inSuite, header.GetEncryptionKeyID() == 2); - header.SetMessageId(234).SetSourceNodeId(77).SetDestinationNodeId(88); + header.SetMessageCounter(234).SetSourceNodeId(77).SetDestinationNodeId(88); NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR); // change it to verify decoding - header.SetMessageId(222).SetSourceNodeId(1).SetDestinationNodeId(2); + header.SetMessageCounter(222).SetSourceNodeId(1).SetDestinationNodeId(2); NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, header.GetMessageId() == 234); + NL_TEST_ASSERT(inSuite, header.GetMessageCounter() == 234); NL_TEST_ASSERT(inSuite, header.GetDestinationNodeId() == Optional::Value(88ull)); NL_TEST_ASSERT(inSuite, header.GetSourceNodeId() == Optional::Value(77ull)); } diff --git a/src/transport/raw/tests/TestTCP.cpp b/src/transport/raw/tests/TestTCP.cpp index 85e38a7d35bd25..31324bd457a71f 100644 --- a/src/transport/raw/tests/TestTCP.cpp +++ b/src/transport/raw/tests/TestTCP.cpp @@ -67,7 +67,7 @@ using TCPImpl = Transport::TCP(static_cast(PAYLOAD))); @@ -243,7 +243,7 @@ bool TestData::Init(const uint16_t sizes[]) Free(); PacketHeader header; - header.SetSourceNodeId(kSourceNodeId).SetDestinationNodeId(kDestinationNodeId).SetMessageId(kMessageId); + header.SetSourceNodeId(kSourceNodeId).SetDestinationNodeId(kDestinationNodeId).SetMessageCounter(kMessageCounter); const size_t headerLength = header.EncodeSizeBytes(); // Determine the total length. diff --git a/src/transport/raw/tests/TestUDP.cpp b/src/transport/raw/tests/TestUDP.cpp index fc33af368b63c4..3a9aadf58012fc 100644 --- a/src/transport/raw/tests/TestUDP.cpp +++ b/src/transport/raw/tests/TestUDP.cpp @@ -44,7 +44,7 @@ namespace { constexpr NodeId kSourceNodeId = 123654; constexpr NodeId kDestinationNodeId = 111222333; -constexpr uint32_t kMessageId = 18; +constexpr uint32_t kMessageCounter = 18; using TestContext = chip::Test::IOContext; TestContext sContext; @@ -67,7 +67,7 @@ class MockTransportMgrDelegate : public TransportMgrDelegate NL_TEST_ASSERT(mSuite, packetHeader.GetSourceNodeId() == Optional::Value(kSourceNodeId)); NL_TEST_ASSERT(mSuite, packetHeader.GetDestinationNodeId() == Optional::Value(kDestinationNodeId)); - NL_TEST_ASSERT(mSuite, packetHeader.GetMessageId() == kMessageId); + NL_TEST_ASSERT(mSuite, packetHeader.GetMessageCounter() == kMessageCounter); size_t data_len = msgBuf->DataLength(); int compare = memcmp(msgBuf->Start(), PAYLOAD, data_len); @@ -133,7 +133,7 @@ void CheckMessageTest(nlTestSuite * inSuite, void * inContext, const IPAddress & ReceiveHandlerCallCount = 0; PacketHeader header; - header.SetSourceNodeId(kSourceNodeId).SetDestinationNodeId(kDestinationNodeId).SetMessageId(kMessageId); + header.SetSourceNodeId(kSourceNodeId).SetDestinationNodeId(kDestinationNodeId).SetMessageCounter(kMessageCounter); err = header.EncodeBeforeData(buffer); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); diff --git a/src/transport/tests/TestSecureSessionMgr.cpp b/src/transport/tests/TestSecureSessionMgr.cpp index 69e745d562faf5..de5dd54e2051e7 100644 --- a/src/transport/tests/TestSecureSessionMgr.cpp +++ b/src/transport/tests/TestSecureSessionMgr.cpp @@ -362,14 +362,14 @@ void SendBadEncryptedPacketTest(nlTestSuite * inSuite, void * inContext) state->GetSessionMessageCounter().GetPeerMessageCounter().SetCounter(1); // Change Message ID - EncryptedPacketBufferHandle badMessageIdMsg = preparedMessage.CloneData(); - NL_TEST_ASSERT(inSuite, badMessageIdMsg.ExtractPacketHeader(packetHeader) == CHIP_NO_ERROR); + EncryptedPacketBufferHandle badMessageCounterMsg = preparedMessage.CloneData(); + NL_TEST_ASSERT(inSuite, badMessageCounterMsg.ExtractPacketHeader(packetHeader) == CHIP_NO_ERROR); - uint32_t msgID = packetHeader.GetMessageId(); - packetHeader.SetMessageId(msgID + 1); - NL_TEST_ASSERT(inSuite, badMessageIdMsg.InsertPacketHeader(packetHeader) == CHIP_NO_ERROR); + uint32_t messageCounter = packetHeader.GetMessageCounter(); + packetHeader.SetMessageCounter(messageCounter + 1); + NL_TEST_ASSERT(inSuite, badMessageCounterMsg.InsertPacketHeader(packetHeader) == CHIP_NO_ERROR); - err = secureSessionMgr.SendPreparedMessage(localToRemoteSession, badMessageIdMsg); + err = secureSessionMgr.SendPreparedMessage(localToRemoteSession, badMessageCounterMsg); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 1); From 9e8d268fc9ea02c9cc8928c46b3f98ae7e68bf5a Mon Sep 17 00:00:00 2001 From: Victor Morales Date: Tue, 14 Sep 2021 09:34:55 -0700 Subject: [PATCH 034/255] Detect typos in Markdown documents (2nd attempt) (#9347) * Fix documentation's typos Signed-off-by: Victor Morales * Add Spell checker CI action Signed-off-by: Victor Morales --- .github/.wordlist.txt | 982 ++++++++++++++++++ .github/workflows/spell.yml | 39 + .spellcheck.yml | 25 + docs/VSCODE_DEVELOPMENT.md | 2 +- docs/discussion/lwip_ipv6.md | 2 +- .../nrfconnect_examples_configuration.md | 2 +- docs/guides/nxp_k32w_android_commissioning.md | 4 +- .../python_chip_controller_advanced_usage.md | 4 +- .../guides/python_chip_controller_building.md | 8 +- examples/all-clusters-app/esp32/README.md | 2 +- examples/chip-tool/README.md | 2 +- examples/lighting-app/efr32/README.md | 4 +- .../nxp/linux-imx/imx8m/README.md | 2 +- examples/lighting-app/telink/Readme.md | 20 +- examples/lock-app/cc13x2x7_26x2x7/README.md | 2 +- examples/lock-app/efr32/README.md | 2 +- examples/lock-app/k32w/README.md | 2 +- examples/minimal-mdns/README.md | 26 +- examples/persistent-storage/efr32/README.md | 2 +- .../cc13x2x7_26x2x7/doc/programming-ccs.md | 2 +- .../cc13x2x7_26x2x7/doc/programming-ccs.md | 2 +- examples/tv-casting-app/linux/README.md | 2 +- examples/window-app/efr32/README.md | 8 +- scripts/tools/memory/README.md | 4 +- src/README.md | 2 +- src/platform/Linux/README.md | 2 +- src/platform/README.md | 8 +- src/platform/Zephyr/README.md | 2 +- src/platform/qpg/README.md | 2 +- src/test_driver/esp32/README.md | 2 +- src/test_driver/linux-cirque/README.md | 6 +- 31 files changed, 1110 insertions(+), 64 deletions(-) create mode 100644 .github/.wordlist.txt create mode 100644 .github/workflows/spell.yml create mode 100644 .spellcheck.yml diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt new file mode 100644 index 00000000000000..14e55e7ff34736 --- /dev/null +++ b/.github/.wordlist.txt @@ -0,0 +1,982 @@ +AAAA +aabbccddeeff +aarch +abcdef +abfb +ABI +ABIs +ables +accessor +AccountLogin +acdbc +ACKed +ACL +AdapterAddress +AdapterName +adb +addr +AddThreadNetwork +AddWiFiNetwork +adk +adoc +AdvAutonomous +AdvManagedFlag +AdvOnLink +AdvRouterAddr +AdvSendAdvert +AE +aef +algs +alloc +APIs +apk +AppConfig +ApplicationBasic +ApplicationLauncher +approver +aps +arg +argc +args +argv +armeabi +armv +ASYNC +att +attId +attrListName +attrMask +attSizeBytes +attType +AudioOutput +auth +autoconnect +autocrlf +autogenerated +automake +autotools +AwaitNextAction +AXXXF +babaf +backend +backticks +backtrace +BarrierControl +BasicCHIPRegression +baudrate +BD +BDX +BeagleBone +befc +bitbake +bld +ble +BLE +BleApplicationDelegate +BleLayer +BLEManager +BLEManagerImpl +BlePlatformDelegate +Blinls +bloaty +blocklist +blockquote +bluetoothd +bluez +bootable +Bootloader +BorderRouterAP +BRD +breakpoint +bredr +BridgedDeviceBasic +bridgedLightEndpoint +bringup +bt +btmgmt +BTN +BTP +btvirt +buildwithmatter +burndown +BytesMain +bz +bzip +CACACACA +cacerts +CAfile +cancelled +CBB +cbd +CCMP +CCS +CCSTUDIO +CCXML +ced +cfg +CFLAGS +cgit +cgroup +changeset +characterised +CharString +ChipBLEMgr +CHIPCirqueTest +CHIPCryptoPALHsm +CHIPDeviceController +ChipDeviceCtrl +CHIPDeviceEvent +CHIPDevicePlatformEvent +ChipEchoRequester +ChipEchoResponder +ChipImInitiator +ChipImResponder +ChipLight +ChipMessageLayer +CHIPTool +chmod +chrpath +CircleCI +cJTAG +CKIT +CLA +clapre +CLI +cloudbuild +CLRF +clusterAttrs +clusterId +clusterList +clusterListName +ClusterRevision +ClusterTestGeneration +cmake +CMSIS +CMVH +cn +codeaurora +codebase +CodeLab +codelabs +ColorControl +Comcast +Commandline +Commissionable +CommissioningFlow +commondatastorage +CONF +CONFIG +ConfigDescription +configTOTAL +ConfigurationManager +ConfigurationManagerImpl +connectedhomeip +ConnectionData +ConnectIP +ConnectivityManager +ConnectivityManagerImpl +connstring +conntype +const +ContentLaunch +ContentLauncher +contrib +controllee +conv +cortexa +cp +cpio +cpp +cppreference +cpuapp +cpython +crypto +cryptographic +csu +csv +ctl +ctrl +ctypes +CurrentHue +CurrentLevel +CurrentSaturation +customizations +cxx +CY +DAC +DAP +DataFrame +dataset +datasets +dbf +dBm +DBUILD +dbus +dcc +DCHIP +DCMAKE +DCONFIG +debianutils +DEDEDEDE +DelayedActionTime +demangle +deployable +deps +desc +descheduled +dev +devcontainer +devCtrl +DeviceCaCerts +DeviceCert +DeviceCommissioner +DeviceCommon +DeviceController +DeviceId +DeviceLayer +DeviceNetworkProvisioningDelegate +DeviceNetworkProvisioningDelegateImpl +DevicePairingDelegate +DevKitC +DevKitM +df +dfu +DHCP +DHCPv +dhrishi +dialout +diffstat +diffsyms +dimmable +dirs +disambiguated +discoverable +DispatchEvent +DispatchEventToApplication +DISTRO +Distutils +DK +DL +DNS +Dnsmasq +dnsmasqd +DNSStubListener +Dockerfile +Dockerfiles +Don'ts +DoorLock +DOTBR +DOVERLAY +downcasting +Doxygen +dpkg +dryrun +DS +duplicative +DV +dynload +eabi +EB +ECC +ECD +EchoRequests +EchoResponse +EchoService +edaf +edc +EDR +ee +EEE +eef +ef +efr +EFR +eg +EjQ +elftools +elock +emberAfExternalAttributeReadCallback +emberAfExternalAttributeWriteCallback +EnableNetwork +EnableWiFiNetwork +EndpointId +endpointName +eno +entrypoint +env +esd +ESPPORT +Espressif +eth +EthernetNetworkDiagnostics +ethernets +EvalCode +EvalCodeWithName +EvalFrameDefault +evk +exceptfds +ExchangeContext +exe +ExecStart +executables +ExtendedPAN +extern +extpanid +FabricId +factoryreset +fb +fbb +fbd +FC +FDDE +fddead +fde +FECA +feff +ffaa +ffeebaefa +FFF +fffe +fffff +Fi +filepath +fini +FixedLabel +flashdebug +focusable +forkpty +formatOnSave +fota +FOTA +FreeRTOS +FreeRTOSConfig +fsl +fsync +gcloud +GDB +GeneralCommissioning +GeneralDiagnostics +GenericConfigurationManagerImpl +GenericConnectivityManagerImpl +GenericImpl +GenericPlatformManagerImpl +GenericThreadConfigurationManagerImpl +GenericThreadStackManagerImpl +GenericWiFiConfigurationManagerImpl +GetDeviceId +GetDeviceInfo +GetDns +GetIP +getstarted +gitignore +glibc +gn +GND +gni +GNinja +gnuarmemb +GNUARMEMB +googleapis +googlesource +GPG +GPIO +GPL +GPLv +Gradle +gradlew +GroupId +GroupKeyManagement +gtk +Gv +hardcoded +hardknott +HardwareVersion +HardwareVersionString +hci +hciattach +hciconfig +hdlc +HKDF +hoc +hostapd +hostname +href +HTTPS +HW +iaszone +ICA +ICMP +IDF +idx +ifdef +ifdefs +IGMP +ihex +im +IM +imager +imagetool +img +Impl +ImplClass +implementers +imx +indexhtml +Inet +InetLayer +Infineon +ini +init +inlined +instantiation +integrations +IntelliSense +InteractionModelVersion +Interation +Interoperable +introvideos +InvokeCommandRequests +InvokeCommandResponse +IoT +ipaddr +ipp +iptables +iputils +IPv +ISCAN +itemName +iterable +jinja +jlink +JLink +JLinkExe +JLinkRTTClient +JN +jpg +js +json +JTAG +KA +Kconfig +KeypadInput +KitProg +kNodeIdNotSpecified +knownissues +KVS +LabelList +LAUNCHXL +ldflags +LEDs +LevelControl +LF +libavahi +libc +libcairo +libCHIP +libdbus +LIBDIR +libegl +libffi +libgirepository +libglib +libical +libncurses +libreadline +libsdl +libssl +libstdc +libthread +libtool +libTransportLayer +libudev +libwebkitgtk +lifecycle +lightbulb +lightin +LinkSoftwareAndDocumentationPack +LocalConfigDisabled +localhost +localstatedir +loopback +LowPower +LPC +LTE +LTS +LwIP +LwIP's +macaddr +machineType +MacOS +MacOSX +MacPorts +Makefile +makefiles +MakeTpCall +mandir +ManualPairingCode +ManualTest +ManufacturingDate +masterkey +matterc +matterd +MatterLock +MaxInterval +MaxRtrAdvInterval +mbedTLS +mcu +MCUboot +mcumgr +MCUs +mcux +MCUXpresso +mdash +MDNS +MediaInput +MediaPlayback +mem +memdf +MemMonitoring +menuconfig +MeshCoP +MfgDeviceCaCerts +MfgSpecificPing +mfrcacerts +mfrcert +MfrDeviceCert +MfrDeviceId +mgmt +microcontroller +MicroSD +middleware +Minicom +MinInterval +MinRtrAdvInterval +mkdir +mlan +MLD +mmevk +moal +modprobe +Modustoolbox +moveMode +MoveToHue +MoveToLevel +MoveToSaturation +MoveWithOnOff +MPSL +MRP +MTU +Multiband +Multicast +multilib +Multiprotocol +MX +mydir +MyPASSWORD +MySSID +nano +natively +navpad +ncs +nding +NDK +netif +netplan +NetworkCommissioning +networkID +networkname +NewUDPEndPoint +nfds +nl +NLUnitTest +NLUnitTests +NodeId +nongnu +nordicsemi +NotAvailable +nRF +nrfconnect +nrfdks +nrfutil +nrfxlib +NTAG +NUM +nwk +NXP +objcopy +OccupancySensing +OctetString +OECORE +ol +Onboarding +onboardingcodes +oneshot +onnetwork +OnOff +OnOffClusterTest +OnPlatformEvent +OO +OpenSSL +OpenThread +OpenThreadDemo +openweave +OperationalCredentials +operationalDataset +opkg +optionMask +optionOverride +optionsMask +optionsOverride +orgs +OTA +OTBR +otcli +PAA +PacketBuffer +PAI +PairDevice +PAKE +param +params +PartNumber +PASE +Passcode +PBKDF +pbuf +pbufs +PCA +pcaps +PDFs +PDK +peerAddrStr +pem +percentageLiftValue +pexpect +PID +Pigweed +PinCode +pkgconfig +PlatformManager +PlatformManagerImpl +plt +png +polymorphism +POSIX +PosixConfig +postAttributeChangeCallback +pre +preprocessor +Presetup +prj +ProductID +ProductLabel +ProductName +productrev +ProductRevision +ProductURL +proto +protos +Prover +PRs +PSCAN +PSK +PTR +pts +PumpConfigurationAndControl +pwd +PXXXF +py +pychip +pycrypto +pycryptodome +PyEval +PyFunction +pylint +PyObject +PyRun +QEMU +Qorvo +QPG +QRCode +qrcodetool +QRCodeUrl +QSPI +QueryImage +qvCHIP +RADVD +raspberryPi +RasPi +RCP +ReadConfigValue +readelf +readfds +README +Reag +rebase +recommand +recommanded +recurse +regen +RelativeHumidityMeasurement +RemainAfterExit +remoteDeviceId +Rendez +RendezvousInformation +RendezvousParameters +RendezVousTest +repo +req +Requestor +responder +reusability +rfid +rfids +RGB +riscv +rloc +rmw +Rollershade +rootfs +RPC +RPCs +RPi +rsn +RSSI +rtld +RTOS +RTT +RUNAS +RunMain +runtime +rw +sbin +scalability +scalable +scm +sco +scp +ScriptBinding +SDC +SDHC +SDK +SDK's +SDKs +SDKTARGETSYSROOT +sdl +segger +SEGGER +semver +sendto +SERIALDEVICE +SerialNumber +ServiceId +SetDns +SetUpPINCode +SetupQRCode +sexualized +SIGINT +SiLabs +SiliconLabs +SimpleFileExFlags +SimpleLink +sl +SLAAC +SLTB +SLWSTK +SmartThings +SMP +socat +socio +softap +SoftDevice +softmmu +SoftwareDiagnostics +SoftwareVersion +SoftwareVersionString +spinel +src +SRP +SRV +SSID +startoffset +StartScan +stderr +stdout +str +strcpy +su +Subclassing +subcommand +subcommands +subdirectories +subdirectory +submodule +submodules +subprocess +sudo +svg +SVR +SWD +sysconfdir +SysConfig +sysctl +sysdeps +sysroot +SYSROOT +systemctl +systemd +systemdsystemunitdir +systemduserunitdir +sysv +TargetNavigator +TBD +TCP +teardown +Telink +TemperatureMeasurement +TestArray +TestCluster +TestEmptyString +TestMultiRead +TESTPASSWD +TESTSSID +TestString +TestStruct +TestThreadStackMgr +TestUint +TestUpdateValue +testws +texinfo +textboxes +TFT +ThreadStackManager +ThreadStackManagerImpl +Thunderboard +timeoutMs +TKIP +tlsr +TLV +tmp +tngvndl +TODO +toolchain +toolchains +topologies +totalTests +trackAlloc +trackFree +transitionTime +TransportMgrBase +TrustedRootCertificates +TSG +tsv +tty +ttyACM +ttyACMx +ttymxc +ttyUSB +TvChannel +txt +uart +UART +UDP +UDPEndPoint +ug +ui +uint +unblur +UNBLUR +uncommissioned +unfocus +Unicast +UniFlash +unpair +unprovisioned +untrusted +UpdateTokens +upstreamed +URI +usbmodem +USBtoUART +uscif +USERINTERFACE +UserLabel +usermod +usr +util +utils +UUID +VCP +Vectorcall +VendorID +VendorName +vendorpayload +venv +Verifier +VID +visualstudio +vlatest +VLEDs +vnc +vous +VSC +VSCode +WakeOnLan +WantedBy +webpage +wget +whde +whitespace +whitespaces +whl +wic +WindowCovering +WindowCoveringGoToLiftPercentage +wlan +wmm +WPA +wpan +wra +writefds +wrover +WS +WSL +WSTK +xab +xaver +xbef +xcd +Xcode +xd +xds +xdsdfu +xef +xF +xFFFF +xfffff +xffffffffe +xfffffffff +xtensa +xwayland +XXXX +XXXXXXXX +xyz +xz +yaml +yearday +yml +YNJV +Yocto +yoctoproject +YourFolder +zapt +zaptool +ZCL +zclconfigure +zclread +zclwrite +ZephyrConfig +zephyrproject +Zigbee +zigbeealliance +zigbeethread diff --git a/.github/workflows/spell.yml b/.github/workflows/spell.yml new file mode 100644 index 00000000000000..e2d07a49ac00a8 --- /dev/null +++ b/.github/workflows/spell.yml @@ -0,0 +1,39 @@ +# Copyright (c) 2020-2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Run misspell + +on: + push: + paths: + - '**.md' + - '!.github/*' + pull_request: + paths: + - '**.md' + - '!.github/*' + +jobs: + check-reviewdog: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: reviewdog/action-misspell@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + check-spellcheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: igsekor/pyspelling-any@v0.0.2 diff --git a/.spellcheck.yml b/.spellcheck.yml new file mode 100644 index 00000000000000..a6c56411bcc5a6 --- /dev/null +++ b/.spellcheck.yml @@ -0,0 +1,25 @@ +# Copyright (c) 2020-2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +matrix: + - name: markdown + dictionary: + wordlists: + - .github/.wordlist.txt + pipeline: + - pyspelling.filters.markdown: + sources: + - '**/*.md|!third_party/**|!examples/common/**/repo/**' + aspell: + ignore-case: true diff --git a/docs/VSCODE_DEVELOPMENT.md b/docs/VSCODE_DEVELOPMENT.md index 1f7463dbed607a..8e1047568c6e17 100644 --- a/docs/VSCODE_DEVELOPMENT.md +++ b/docs/VSCODE_DEVELOPMENT.md @@ -85,7 +85,7 @@ session. Developers are encouraged to add tasks to the [launch json](../.vscode/launch.json) over time to make sure everyone is using -the same base debuging setup. +the same base debugging setup. ## Submitting a Pull Request - Practical Advice diff --git a/docs/discussion/lwip_ipv6.md b/docs/discussion/lwip_ipv6.md index 04fcec47769c67..bbfc92d49df28f 100644 --- a/docs/discussion/lwip_ipv6.md +++ b/docs/discussion/lwip_ipv6.md @@ -118,7 +118,7 @@ Instead, it might be better to build this into the ICMP layer itself. ## DNS -LwIP’s DNS handling isn’t great and breaks down when the router supports +LwIP's DNS handling isn’t great and breaks down when the router supports IPv4/IPv6. There is a single list of DNS servers, DHCP, SLAAC and DHCPv6 all update the list without locks. Basically, whatever wrote to the list last gets to set the list. Although there is handling for IP type (requesting A or AAAA diff --git a/docs/guides/nrfconnect_examples_configuration.md b/docs/guides/nrfconnect_examples_configuration.md index cf544fbeb76cc1..f51250e9662b49 100644 --- a/docs/guides/nrfconnect_examples_configuration.md +++ b/docs/guides/nrfconnect_examples_configuration.md @@ -107,7 +107,7 @@ them default values for any application. The application configuration is specified using Kconfig configuration files (`*.conf`), where available Kconfig options can be used and their default values -overrided. Typically, there are many files having impact on the final +overridden. Typically, there are many files having impact on the final configuration shape. There is no need to modify all these files separately. See the following list diff --git a/docs/guides/nxp_k32w_android_commissioning.md b/docs/guides/nxp_k32w_android_commissioning.md index 4d7b7232aee010..bdeb564ccd227c 100644 --- a/docs/guides/nxp_k32w_android_commissioning.md +++ b/docs/guides/nxp_k32w_android_commissioning.md @@ -27,7 +27,7 @@ onto a CHIP-enabled Thread network. The commissioning process is composed of the following main stages: -- K32W061 (CHIP accessory) device is put in BLE advertisment mode by pressing +- K32W061 (CHIP accessory) device is put in BLE advertisement mode by pressing the USERINTERFACE button; - CHIPTool discovers the CHIP accessory over BLE; - CHIPTool establishes a secure channel with the accessory using a SPAKE2+ @@ -182,7 +182,7 @@ To make your PC work as a Thread Border Router, complete the following tasks: - On System startup, dnsmasq will not wait for wlan0 interface to initialize and will fail. We need to tell systemd to launch it after - networks get ready, so we will modify dnsmasq service file by specifing + networks get ready, so we will modify dnsmasq service file by specifying the initialization order under the _After=_ and _Wants=_ sections: $ sudo vim /lib/systemd/system/dnsmasq.service diff --git a/docs/guides/python_chip_controller_advanced_usage.md b/docs/guides/python_chip_controller_advanced_usage.md index 845967714c9b92..8a324b15b06a6c 100644 --- a/docs/guides/python_chip_controller_advanced_usage.md +++ b/docs/guides/python_chip_controller_advanced_usage.md @@ -110,7 +110,7 @@ Reading symbols from python3... ``` The Python will create lots of threads due to main loop, so you may want to -supress thread related outputs first by running the following command: +suppress thread related outputs first by running the following command: ``` (gdb) set print thread-events off @@ -247,4 +247,4 @@ then you can use `bt` (for `backtrace`) to see the backtrace of the call stack. ``` The frame #0 and frame #1 are the function frames in the CHIP C++ library, the -other frames live in the Python intepreter so you can ignore it. +other frames live in the Python interpreter so you can ignore it. diff --git a/docs/guides/python_chip_controller_building.md b/docs/guides/python_chip_controller_building.md index d52e8f7c3f592d..032b72953d4372 100644 --- a/docs/guides/python_chip_controller_building.md +++ b/docs/guides/python_chip_controller_building.md @@ -223,7 +223,7 @@ with network credentials. Done ``` - Matter specifiction does not define how the Thread or Wi-Fi credentials are + Matter specification does not define how the Thread or Wi-Fi credentials are obtained by Controller. For example, for Thread, instead of fetching datasets directly from the Thread Border Router, you might also use a different out-of-band method. @@ -248,7 +248,7 @@ with network credentials. #### Commissioning a Wi-Fi device 1. Assuming your Wi-Fi SSID is _TESTSSID_, and your Wi-Fi password is - _P455W4RD_, inject the credentials to the device by excuting the following + _P455W4RD_, inject the credentials to the device by executing the following command: ``` @@ -396,7 +396,7 @@ If no nodeid given, a random Node ID will be used. ### `close-session ` -If case there eixsts an open session (PASE or CASE) to the device with a given +If case there exists an open session (PASE or CASE) to the device with a given Node ID, mark it as expired. ### `discover` @@ -470,7 +470,7 @@ chip-device-ctrl > zcl LevelControl MoveWithOnOff 12344321 1 0 moveMode=1 rate=2 For any integer and char string (null terminated) types, just use `key=value`, for example: `rate=2`, `string=123`, `string_2="123 456"` -For byte string type, use `key=encoding:value`, currectly, we support `str` and +For byte string type, use `key=encoding:value`, currently, we support `str` and `hex` encoding, the `str` encoding will encode a NULL terminated string. For example, `networkId=hex:0123456789abcdef` (for `[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]`), `ssid=str:Test` (for diff --git a/examples/all-clusters-app/esp32/README.md b/examples/all-clusters-app/esp32/README.md index 32cc78bb0be677..b9f730ae9edd12 100644 --- a/examples/all-clusters-app/esp32/README.md +++ b/examples/all-clusters-app/esp32/README.md @@ -224,7 +224,7 @@ commissioning and cluster control. `chip-device-ctrl > zcl LevelControl MoveToLevel 135246 1 1 level=10 transitionTime=0 optionMask=0 optionOverride=0` -- For ESP32C3-DevKitM, use the ColorContorl cluster commands to control the +- For ESP32C3-DevKitM, use the ColorControl cluster commands to control the CurrentHue and CurrentSaturation attribute. This allows you to control the color of on-board LED. diff --git a/examples/chip-tool/README.md b/examples/chip-tool/README.md index e68ee541649fdb..3071b86114e525 100644 --- a/examples/chip-tool/README.md +++ b/examples/chip-tool/README.md @@ -64,7 +64,7 @@ where: - ssid is the Wi-Fi SSID either as a string, or in the form hex:XXXXXXXX where the bytes of the SSID are encoded as two-digit hex numbers. -- paswword is the Wi-Fi password, again either as a string or as hex data +- password is the Wi-Fi password, again either as a string or as hex data - The 0 is the fabric id, until more complete support for multiple fabrics is implemented in our commissioning process. diff --git a/examples/lighting-app/efr32/README.md b/examples/lighting-app/efr32/README.md index 6f689e04a3d6a2..6be09ad47bb191 100644 --- a/examples/lighting-app/efr32/README.md +++ b/examples/lighting-app/efr32/README.md @@ -221,7 +221,7 @@ combination with JLinkRTTClient as follows: - _Press and Release_ : Start, or restart, BLE advertisement in fast mode. It will advertise in this mode for 30 seconds. The device will then switch to a slower interval advertisement. - After 15 minutes, the adverstiment stops. + After 15 minutes, the advertisement stops. - _Pressed and hold for 6 s_ : Initiates the factory reset of the device. Releasing the button within the 6-second window cancels the factory reset @@ -280,7 +280,7 @@ via 2002::2 - To use the chip-rpc console after it has been installed run: `python3 -m chip_rpc.console --device /dev/tty. -b 115200 -o //pw_log.out` -- Then you can simulate a button press or realease using the following command +- Then you can simulate a button press or release using the following command where : idx = 0 or 1 for Button PB0 or PB1 action = 0 for PRESSED, 1 for RELEASE Test toggling the LED with `rpcs.chip.rpc.Button.Event(idx=1, pushed=True)` diff --git a/examples/lighting-app/nxp/linux-imx/imx8m/README.md b/examples/lighting-app/nxp/linux-imx/imx8m/README.md index 479b9668c552e7..cfad7440f7b945 100644 --- a/examples/lighting-app/nxp/linux-imx/imx8m/README.md +++ b/examples/lighting-app/nxp/linux-imx/imx8m/README.md @@ -155,7 +155,7 @@ The generated executable file supports to work with below commandline argument: - Prerequisites By following the [Building](#building) section of this document, the Yocto - image is cross-compiled and programed to a microSD card. + image is cross-compiled and programmed to a microSD card. Follow the steps below to setup the environment needed to run the example on the i.MX 8M Mini EVK: diff --git a/examples/lighting-app/telink/Readme.md b/examples/lighting-app/telink/Readme.md index a77fde9064daa8..ac578d743f3067 100644 --- a/examples/lighting-app/telink/Readme.md +++ b/examples/lighting-app/telink/Readme.md @@ -15,7 +15,7 @@ ``` here `${CHIP_BASE}` is directory which contains CHIP repo files **!!!Pay - attention that OUTPUT_DIR should conatins ABSOLUTE path to output dir** + attention that OUTPUT_DIR should contains ABSOLUTE path to output dir** 1. Bootstrap the build environment: @@ -79,7 +79,7 @@ $ BORDER_ROUTING=0 NETWORK_MANAGER=1 ./script/setup ### Setup IPv6 -Pay attention that border router shoud be configured as IPv6 access point. +Pay attention that border router should be configured as IPv6 access point. 1. To do so perform the following command: ``` @@ -94,7 +94,7 @@ Pay attention that border router shoud be configured as IPv6 access point. ### Config network Use [Web GUI](https://openthread.io/guides/border-router/web-gui) to config -Thread network **tlsr9518adk80d** board supports only static comissioning with +Thread network **tlsr9518adk80d** board supports only static commissioning with predefined Thread credentials shown in table below: | Item | Value | @@ -123,11 +123,11 @@ To get output from device, connect UART to following pins: The following buttons are available on **tlsr9518adk80d** board: -| Name | Function | Description | -| :------- | :--------------- | :---------------------------------------------------------------------------------------------------- | -| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommisioned state | -| Button 2 | Lighting control | Manually triggers the lighting state | -| Button 3 | Thread start | Comission thread with static credentials and enables the Thread on device | +| Name | Function | Description | +| :------- | :--------------- | :----------------------------------------------------------------------------------------------------- | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | +| Button 2 | Lighting control | Manually triggers the lighting state | +| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | ### LEDs @@ -136,7 +136,7 @@ following states: | State | Description | | :-------------------------- | :--------------------------------------------------------------------------- | -| Blinks with short pulses | Device is not commisioned to Thread, Thred is disabled | +| Blinks with short pulses | Device is not commissioned to Thread, Thread is disabled | | Blinls with frequent pulses | Device is commissioned, Thread enabled. Device trying to JOIN thread network | | Blinks with whde pulses | Device commissioned and joined to thread network as CHILD | @@ -147,7 +147,7 @@ following states: 1. With your client device (PC, Laptop etc.) connect to BorderRouterAP WiFi 2. Press Button 3 on **tlsr9518adk80d** board and wait till it joins to Thread network -3. Find ajusted IPv6 address in UART output of **tlsr9518adk80d** +3. Find adjusted IPv6 address in UART output of **tlsr9518adk80d** 4. Perform following command on your client device: ``` ping -6 ${IP_ADDRESS_OF_CHIP_DEVICE} diff --git a/examples/lock-app/cc13x2x7_26x2x7/README.md b/examples/lock-app/cc13x2x7_26x2x7/README.md index 8d0a9753add908..857dc6bf552159 100644 --- a/examples/lock-app/cc13x2x7_26x2x7/README.md +++ b/examples/lock-app/cc13x2x7_26x2x7/README.md @@ -265,7 +265,7 @@ fully provisioned, BLE advertising will stop. #### Bluetooth LE Rendezvous -To commission and control this application wtihin a CHIP-eanbled Thread network, +To commission and control this application within a CHIP-enabled Thread network, consult the [CHIPTool README](../../../src/android/CHIPTool/README.md) for information on the Android smartphone application. Reference the Device Configuration information printed in the Logging Output of this application. diff --git a/examples/lock-app/efr32/README.md b/examples/lock-app/efr32/README.md index 8018eb06343f49..abb69a2a9613ac 100644 --- a/examples/lock-app/efr32/README.md +++ b/examples/lock-app/efr32/README.md @@ -210,7 +210,7 @@ combination with JLinkRTTClient as follows: - _Press and Release_ : Start, or restart, BLE advertisement in fast mode. It will advertise in this mode for 30 seconds. The device will then switch to a slower interval advertisement. - After 15 minutes, the adverstiment stops. + After 15 minutes, the advertisement stops. - _Pressed and hold for 6 s_ : Initiates the factory reset of the device. Releasing the button within the 6-second window cancels the factory reset diff --git a/examples/lock-app/k32w/README.md b/examples/lock-app/k32w/README.md index 67bb30da1dc8f3..fffceabcd9b82e 100644 --- a/examples/lock-app/k32w/README.md +++ b/examples/lock-app/k32w/README.md @@ -256,7 +256,7 @@ below: ![POWER_VIEW](../../platform/k32w/doc/images/power_view.JPG) Please note that that the Power Measurement Tool is not very accurate and -professional tools must be used if exact power consumption needs to be kwnown. +professional tools must be used if exact power consumption needs to be known. ## Known issues diff --git a/examples/minimal-mdns/README.md b/examples/minimal-mdns/README.md index c728d40196998e..8e781f852424ff 100644 --- a/examples/minimal-mdns/README.md +++ b/examples/minimal-mdns/README.md @@ -85,7 +85,7 @@ discovery. ### Advertising to test client listings -#### Simulated uncommisioned node +#### Simulated uncommissioned node ```sh dns-sd -R DD200C20D25AE5F7 _matterc._udp,S52,L840,V123 . 11111 D=840 VP=123+456 @@ -99,11 +99,11 @@ S52._sub._matterc._udp.local. PTR DD200C20D25AE5F7._matterc._udp.loca L840._sub._matterc._udp.local. PTR DD200C20D25AE5F7._matterc._udp.local. V123._sub._matterc._udp.local. PTR DD200C20D25AE5F7._matterc._udp.local. DD200C20D25AE5F7._matterc._udp.local. TXT "D=840" "VP=123+456" -DD200C20D25AE5F7._mattterc._udp.local. SRV 0 0 11111 B75AFB458ECD.local. +DD200C20D25AE5F7._matterc._udp.local. SRV 0 0 11111 B75AFB458ECD.local. B75AFB458ECD.local. AAAA ba2a:b311:742e:b44c:f515:576f:9783:3f30 ``` -#### Simulated commisioning node +#### Simulated commissioning node ```sh dns-sd -R DD200C20D25AE5F7 _matterd._udp,S52,L840,V123 . 11111 D=840 VP=123+456 PH=3 @@ -121,7 +121,7 @@ DD200C20D25AE5F7._matterd._udp.local. SRV 0 0 11111 B75AFB458ECD.local. B75AFB458ECD.local. AAAA ba2a:b311:742e:b44c:f515:576f:9783:3f30 ``` -#### Simulated commisioned node +#### Simulated commissioned node ```sh dns-sd -R 2906C908D115D362-8FC7772401CD0696 _matter._tcp . 22222 @@ -132,15 +132,15 @@ dns-sd -R 2906C908D115D362-8FC7772401CD0696 _matter._tcp . 22222 Nodes: ```sh -dns-sd -B _matterc._udp # Nodes awaiting commisioning -dns-sd -B _matterc._udp,S52 # Nodes awaiting commisioning with short discriminator 52 -dns-sd -B _matterc._udp,L840 # Nodes awaiting commisioning with long discriminator 840 -dns-sd -B _matterc._udp,V123 # Nodes awaiting commisioning with vendor id 123 - -dns-sd -B _matterd._udp # Commisionable nodes -dns-sd -B _matterd._udp,S52 # Commisionable nodes with short discriminator 52 -dns-sd -B _matterd._udp,L840 # Commisionable nodes with long discriminator 840 -dns-sd -B _matterd._udp,V123 # Commisionable nodes with vendor id 123 +dns-sd -B _matterc._udp # Nodes awaiting commissioning +dns-sd -B _matterc._udp,S52 # Nodes awaiting commissioning with short discriminator 52 +dns-sd -B _matterc._udp,L840 # Nodes awaiting commissioning with long discriminator 840 +dns-sd -B _matterc._udp,V123 # Nodes awaiting commissioning with vendor id 123 + +dns-sd -B _matterd._udp # Commissionable nodes +dns-sd -B _matterd._udp,S52 # Commissionable nodes with short discriminator 52 +dns-sd -B _matterd._udp,L840 # Commissionable nodes with long discriminator 840 +dns-sd -B _matterd._udp,V123 # Commissionable nodes with vendor id 123 ``` IP Address: diff --git a/examples/persistent-storage/efr32/README.md b/examples/persistent-storage/efr32/README.md index 5b03331557057a..2f3b5773821006 100644 --- a/examples/persistent-storage/efr32/README.md +++ b/examples/persistent-storage/efr32/README.md @@ -29,7 +29,7 @@ platforms. ## EFR32 The EFR32 platform KVS is fully implemented, the KVS is enabled and configured -using theese defines: +using these defines: ``` defines = [ diff --git a/examples/pump-app/cc13x2x7_26x2x7/doc/programming-ccs.md b/examples/pump-app/cc13x2x7_26x2x7/doc/programming-ccs.md index f56fc6057011c9..ac31ab8bbea1f0 100644 --- a/examples/pump-app/cc13x2x7_26x2x7/doc/programming-ccs.md +++ b/examples/pump-app/cc13x2x7_26x2x7/doc/programming-ccs.md @@ -106,7 +106,7 @@ file) in the `Load Program` dialog. Click `OK` to begin loading the target. ![CCS step 9](images/ccs-12.jpg) -- After loacating the source file for `main.cpp` we can step through the code +- After locating the source file for `main.cpp` we can step through the code as it executes. ![CCS step 9](images/ccs-13.jpg) diff --git a/examples/pump-controller-app/cc13x2x7_26x2x7/doc/programming-ccs.md b/examples/pump-controller-app/cc13x2x7_26x2x7/doc/programming-ccs.md index f56fc6057011c9..ac31ab8bbea1f0 100644 --- a/examples/pump-controller-app/cc13x2x7_26x2x7/doc/programming-ccs.md +++ b/examples/pump-controller-app/cc13x2x7_26x2x7/doc/programming-ccs.md @@ -106,7 +106,7 @@ file) in the `Load Program` dialog. Click `OK` to begin loading the target. ![CCS step 9](images/ccs-12.jpg) -- After loacating the source file for `main.cpp` we can step through the code +- After locating the source file for `main.cpp` we can step through the code as it executes. ![CCS step 9](images/ccs-13.jpg) diff --git a/examples/tv-casting-app/linux/README.md b/examples/tv-casting-app/linux/README.md index bd1d16dbcfe08d..6eba225d7c8c3e 100644 --- a/examples/tv-casting-app/linux/README.md +++ b/examples/tv-casting-app/linux/README.md @@ -3,7 +3,7 @@ This is a CHIP TV Casting app that can be used to cast content to a TV. This app discovers TVs on the local network that act as commissioners, lets the user select one, sends the TV a User Directed Commissioning request, enters -commisioning mode, advertises itself as a Commissionable Node and gets +commissioning mode, advertises itself as a Commissionable Node and gets commissioned. Then it allows the user to send CHIP ContentLauncher commands to the TV. diff --git a/examples/window-app/efr32/README.md b/examples/window-app/efr32/README.md index cdd98f67749c89..79ad30072ff490 100644 --- a/examples/window-app/efr32/README.md +++ b/examples/window-app/efr32/README.md @@ -223,7 +223,7 @@ combination with JLinkRTTClient as follows: - _Blinking slowly_ ; The window cover is half-open, either by tilt, or lift - _Blinking quickly_ ; The window cover is being automatically open or closed - **Push Button 0** Increase seither tilt or lift, and factory reset + **Push Button 0** Increase either tilt or lift, and factory reset - Pressed and release: The lift/tilt increases by 10% @@ -240,9 +240,9 @@ combination with JLinkRTTClient as follows: **Push Button0 and Button1** Switch between lift and tilt - - Pressing and release both buttons at the same time: switches between lift and tilt modes. Most window covering types support either lift only, or tilt only, but type 0x08 suport both (default) + - Pressing and release both buttons at the same time: switches between lift and tilt modes. Most window covering types support either lift only, or tilt only, but type 0x08 support both (default) - - Pressing and hold both buttons at the same time: Cycles betwen window covering 1, and window covering 2. + - Pressing and hold both buttons at the same time: Cycles between window covering 1, and window covering 2. * Once the device is provisioned, it will join the Thread network is established, look for the RTT log @@ -274,7 +274,7 @@ combination with JLinkRTTClient as follows: The [Python Controller](https://github.com/project-chip/connectedhomeip/blob/master/src/controller/python/README.md) can now be used to send ZCL commands to the window covering device. For - instance, to set the window covering lift by percentantage: + instance, to set the window covering lift by percentage: $ sudo chip-device-ctrl diff --git a/scripts/tools/memory/README.md b/scripts/tools/memory/README.md index b2546ebe14dcdc..9ccd4a2560813e 100644 --- a/scripts/tools/memory/README.md +++ b/scripts/tools/memory/README.md @@ -12,7 +12,7 @@ The following options are common to _most_ of the scripts, where applicable: - `--verbose`, `-v` Show informational messages; repeat for debugging messages. - `--config-file` _FILE_ Read configuration _FILE_. Typically this is a file - from the `plaform/` subdirectory providing platform-specific option + from the `platform/` subdirectory providing platform-specific option defaults. Command line options override the configuration file. ### input options: @@ -36,7 +36,7 @@ The following options are common to _most_ of the scripts, where applicable: ## output options: - `--output-file` _FILENAME_, `--output` _FILENAME_, `-O` _FILENAME_ Output - file. Defautls to standard output. For `csv` and `tsv` formats, this is + file. Defaults to standard output. For `csv` and `tsv` formats, this is actually an output file name prefix. - `--output-format` _FORMAT_, `--to` _FORMAT_, `-t` _FORMAT_ Output format. One of: diff --git a/src/README.md b/src/README.md index edf63ac6ff9c88..5d25de7f39f6d4 100644 --- a/src/README.md +++ b/src/README.md @@ -26,6 +26,6 @@ The CHIP src directory is structured as follows: ##### Near Field Communication Tag Reading NFC Tag Reading is disabled by default because a paid Apple developer account is -requird to have it enabled. If you want to enable it and you have a paid Apple +required to have it enabled. If you want to enable it and you have a paid Apple developer account, go to the CHIPTool iOS target and turn on Near Field Communication Tag Reading under the Capabilities tab. diff --git a/src/platform/Linux/README.md b/src/platform/Linux/README.md index aa7178d4928bf0..0fcdb7ec14f26a 100644 --- a/src/platform/Linux/README.md +++ b/src/platform/Linux/README.md @@ -35,7 +35,7 @@ code will have parallels in any new adaptation. - Concrete implementation of ThreadStackManager interface - Supports Thread stack initialization and core event loop processing - Relies on GenericThreadStackManagerImpl_OpenThread/POSIX<> classes to - implement most API functionaltiy + implement most API functionality `include/platform/Linux/BLEManagerImpl.h`
`Linux/BLEManagerImpl.cpp` diff --git a/src/platform/README.md b/src/platform/README.md index cc68a9c32e5cfd..bb64ef41b8f737 100644 --- a/src/platform/README.md +++ b/src/platform/README.md @@ -297,10 +297,10 @@ class ConfigurationManagerImpl final }; ``` -In many cases, the generic implementation base class itself will directy provide -some or all of the implementation methods needed to satisfy the component’s -interface. The rules of C++ method resolution are such that calls to a -forwarding method on the interface class are mapped directly to the base class +In many cases, the generic implementation base class itself will directly +provide some or all of the implementation methods needed to satisfy the +component’s interface. The rules of C++ method resolution are such that calls to +a forwarding method on the interface class are mapped directly to the base class method. In this situation, the derived implementation class needn't declare a version of the target method at all, and method calls are forwarded statically, at compile time, without overhead. diff --git a/src/platform/Zephyr/README.md b/src/platform/Zephyr/README.md index c5acee50033579..280dd0a28c1902 100644 --- a/src/platform/Zephyr/README.md +++ b/src/platform/Zephyr/README.md @@ -27,7 +27,7 @@ code will have parallels in any new adaptation. - Concrete implementation of ThreadStackManager interface - Supports Thread stack initialization and core event loop processing - Relies on GenericThreadStackManagerImpl_OpenThread/POSIX<> classes to - implement most API functionaltiy + implement most API functionality `include/platform/Zephyr/BLEManagerImpl.h`
`Zephyr/BLEManagerImpl.cpp` diff --git a/src/platform/qpg/README.md b/src/platform/qpg/README.md index 723aefd1904351..e6be8af7b457e5 100644 --- a/src/platform/qpg/README.md +++ b/src/platform/qpg/README.md @@ -34,7 +34,7 @@ will have parallels in any new adaptation. - Concrete implementation of ThreadStackManager interface - Supports Thread stack initialization and core event loop processing - Relies on GenericThreadStackManagerImpl_OpenThread/FreeRTOS/LwIP<> classes - to implement most API functionaltiy + to implement most API functionality `BLEManagerImpl.h`
`BLEManagerImpl.cpp` diff --git a/src/test_driver/esp32/README.md b/src/test_driver/esp32/README.md index 0d53ff2d0d3f55..757a490f90caf9 100644 --- a/src/test_driver/esp32/README.md +++ b/src/test_driver/esp32/README.md @@ -1,6 +1,6 @@ # CHIP Tests on Device -An appplication that runs CHIP's unit tests on ESP32 device or QEMU. +An application that runs CHIP's unit tests on ESP32 device or QEMU. --- diff --git a/src/test_driver/linux-cirque/README.md b/src/test_driver/linux-cirque/README.md index bbe04047ea1743..11d2ce28f375df 100644 --- a/src/test_driver/linux-cirque/README.md +++ b/src/test_driver/linux-cirque/README.md @@ -47,7 +47,7 @@ You can run the tests by: scripts/tests/cirque_tests.sh run_all_tests ``` -You can get more infomation from the terminal output (like the location of +You can get more information from the terminal output (like the location of logs). > Note: The container (as well as the networks) will be preserved for debugging. @@ -74,7 +74,7 @@ The output of the test will be written to `stdout` and `stderr`. ## Specify log directory -To specify log directory, simplily set `LOG_DIR` variable. +To specify log directory, simply set `LOG_DIR` variable. ``` export LOG_DIR=/some/log/directory @@ -131,5 +131,5 @@ It will print the container id in log, you can execute commands inside them. After you finished you test, press `Ctrl-C` and it will clean up testing environment. -Refer to `test-manual.py`, `ManualTest.sh`, and tolologies file under +Refer to `test-manual.py`, `ManualTest.sh`, and topologies file under `topologies` for detail. From 085998040e14281476fa096296fe29c0ee407f82 Mon Sep 17 00:00:00 2001 From: Trevor Holbrook Date: Tue, 14 Sep 2021 10:16:51 -0700 Subject: [PATCH 035/255] Add OTA Requestor Attributes to example apps (#9446) * fix ota-requestor attribute definitions and add write to chip-tool * add ota requestor attributes to all-clusters-app * generate for missing files * add OTA Requestor Cluster to Endpoint 0 for Darwin tests * regenerate files after darwin endpoint change * regen files after master merge * regen after master merge --- .../all-clusters-common/all-clusters-app.zap | 112 ++- .../zcl/data-model/chip/chip-ota.xml | 4 +- src/app/zap_cluster_list.py | 2 +- .../data_model/controller-clusters.zap | 91 ++ .../java/zap-generated/CHIPClusters-JNI.cpp | 215 +++++ .../chip/devicecontroller/ChipClusters.java | 55 ++ .../python/chip/clusters/CHIPClusters.cpp | 59 ++ .../python/chip/clusters/CHIPClusters.py | 64 ++ src/darwin/Framework/CHIP/templates/helper.js | 1 + .../CHIP/zap-generated/CHIPClustersObjc.h | 21 + .../CHIP/zap-generated/CHIPClustersObjc.mm | 49 ++ .../zap-generated/CHIPClustersObjc_internal.h | 4 + .../Framework/CHIPTests/CHIPClustersTests.m | 85 ++ .../zap-generated/callback-stub.cpp | 8 + .../zap-generated/endpoint_config.h | 827 +++++++++--------- .../zap-generated/gen_config.h | 6 + .../app-common/zap-generated/attribute-id.h | 4 +- .../zap-generated/attributes/Accessors.cpp | 15 + .../zap-generated/attributes/Accessors.h | 7 + .../app-common/zap-generated/ids/Attributes.h | 9 + .../zap-generated/cluster/Commands.h | 236 +++++ .../zap-generated/CHIPClusters.cpp | 114 +++ .../zap-generated/CHIPClusters.h | 22 + .../zap-generated/callback-stub.cpp | 8 + .../zap-generated/endpoint_config.h | 101 ++- .../zap-generated/gen_config.h | 5 + 26 files changed, 1639 insertions(+), 485 deletions(-) diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index cbe78c7faef49f..4a1597875a8ae3 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -1297,6 +1297,88 @@ } ] }, + { + "name": "OTA Software Update Requestor", + "code": 42, + "mfgCode": null, + "define": "OTA_REQUESTOR_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "OTA Software Update Requestor", + "code": 42, + "mfgCode": null, + "define": "OTA_REQUESTOR_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [], + "attributes": [ + { + "name": "default ota provider", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "update possible", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, { "name": "General Commissioning", "code": 48, @@ -7679,36 +7761,6 @@ "enabled": 0, "commands": [], "attributes": [ - { - "name": "default ota provider", - "code": 0, - "mfgCode": null, - "side": "client", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0", - "reportable": 0, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - }, - { - "name": "update possible", - "code": 1, - "mfgCode": null, - "side": "client", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "true", - "reportable": 0, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - }, { "name": "ClusterRevision", "code": 65533, diff --git a/src/app/zap-templates/zcl/data-model/chip/chip-ota.xml b/src/app/zap-templates/zcl/data-model/chip/chip-ota.xml index 723315b9393a3a..dbd37034b689c1 100644 --- a/src/app/zap-templates/zcl/data-model/chip/chip-ota.xml +++ b/src/app/zap-templates/zcl/data-model/chip/chip-ota.xml @@ -91,8 +91,8 @@ limitations under the License. OTA_REQUESTOR_CLUSTER true true - default ota provider - update possible + default ota provider + update possible Notify OTA Provider that an update was applied diff --git a/src/app/zap_cluster_list.py b/src/app/zap_cluster_list.py index 4da2cda3253373..82b934d587cd0e 100755 --- a/src/app/zap_cluster_list.py +++ b/src/app/zap_cluster_list.py @@ -111,7 +111,7 @@ 'OPERATIONAL_CREDENTIALS_CLUSTER': [], 'OTA_BOOTLOAD_CLUSTER': [], 'OTA_PROVIDER_CLUSTER': [], - 'OTA_REQUESTOR_CLUSTER': ['ota-provider'], + 'OTA_REQUESTOR_CLUSTER': [], 'POWER_CONFIG_CLUSTER': [], 'PRESSURE_MEASUREMENT_CLUSTER': [], 'PUMP_CONFIG_CONTROL_CLUSTER': ['pump-configuration-and-control-client'], diff --git a/src/controller/data_model/controller-clusters.zap b/src/controller/data_model/controller-clusters.zap index df5212187e1a18..c2aa6222b8bcf1 100644 --- a/src/controller/data_model/controller-clusters.zap +++ b/src/controller/data_model/controller-clusters.zap @@ -1575,6 +1575,97 @@ } ] }, + { + "name": "OTA Software Update Requestor", + "code": 42, + "mfgCode": null, + "define": "OTA_REQUESTOR_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "AnnounceOtaProvider", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "OTA Software Update Requestor", + "code": 42, + "mfgCode": null, + "define": "OTA_REQUESTOR_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [], + "attributes": [ + { + "name": "default ota provider", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "update possible", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, { "name": "General Commissioning", "code": 48, diff --git a/src/controller/java/zap-generated/CHIPClusters-JNI.cpp b/src/controller/java/zap-generated/CHIPClusters-JNI.cpp index 5dbb9c9e44eff1..6ff99e833b24f8 100644 --- a/src/controller/java/zap-generated/CHIPClusters-JNI.cpp +++ b/src/controller/java/zap-generated/CHIPClusters-JNI.cpp @@ -20427,6 +20427,221 @@ JNI_METHOD(void, OtaSoftwareUpdateProviderCluster, readClusterRevisionAttribute) ReturnIllegalStateException(env, callback, "Error reading attribute", err.AsInteger()); } } +JNI_METHOD(jlong, OtaSoftwareUpdateRequestorCluster, initWithDevice)(JNIEnv * env, jobject self, jlong devicePtr, jint endpointId) +{ + StackLockGuard lock(JniReferences::GetInstance().GetStackLock()); + OtaSoftwareUpdateRequestorCluster * cppCluster = new OtaSoftwareUpdateRequestorCluster(); + + cppCluster->Associate(reinterpret_cast(devicePtr), endpointId); + return reinterpret_cast(cppCluster); +} + +JNI_METHOD(void, OtaSoftwareUpdateRequestorCluster, announceOtaProvider) +(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jbyteArray serverLocation, jint vendorId, jint announcementReason, + jbyteArray metadataForNode) +{ + StackLockGuard lock(JniReferences::GetInstance().GetStackLock()); + CHIP_ERROR err = CHIP_NO_ERROR; + OtaSoftwareUpdateRequestorCluster * cppCluster; + + JniByteArray serverLocationArr(env, serverLocation); + JniByteArray metadataForNodeArr(env, metadataForNode); + CHIPDefaultSuccessCallback * onSuccess; + CHIPDefaultFailureCallback * onFailure; + + cppCluster = reinterpret_cast(clusterPtr); + VerifyOrExit(cppCluster != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + + onSuccess = new CHIPDefaultSuccessCallback(callback); + VerifyOrExit(onSuccess != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + onFailure = new CHIPDefaultFailureCallback(callback); + VerifyOrExit(onFailure != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + + err = cppCluster->AnnounceOtaProvider(onSuccess->Cancel(), onFailure->Cancel(), + chip::ByteSpan((const uint8_t *) serverLocationArr.data(), serverLocationArr.size()), + vendorId, announcementReason, + chip::ByteSpan((const uint8_t *) metadataForNodeArr.data(), metadataForNodeArr.size())); + SuccessOrExit(err); + +exit: + if (err != CHIP_NO_ERROR) + { + delete onSuccess; + delete onFailure; + + jthrowable exception; + jmethodID method; + + err = JniReferences::GetInstance().FindMethod(env, callback, "onError", "(Ljava/lang/Exception;)V", &method); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Error throwing IllegalStateException %" CHIP_ERROR_FORMAT, err.Format()); + return; + } + + err = CreateIllegalStateException(env, "Error invoking cluster", err.Format(), exception); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Error throwing IllegalStateException %" CHIP_ERROR_FORMAT, err.Format()); + return; + } + env->CallVoidMethod(callback, method, exception); + } +} + +JNI_METHOD(void, OtaSoftwareUpdateRequestorCluster, readDefaultOtaProviderAttribute) +(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback) +{ + StackLockGuard lock(JniReferences::GetInstance().GetStackLock()); + CHIPOctetStringAttributeCallback * onSuccess = new CHIPOctetStringAttributeCallback(callback); + if (!onSuccess) + { + ReturnIllegalStateException(env, callback, "Error creating native success callback", CHIP_ERROR_NO_MEMORY.AsInteger()); + return; + } + + CHIPDefaultFailureCallback * onFailure = new CHIPDefaultFailureCallback(callback); + if (!onFailure) + { + delete onSuccess; + ReturnIllegalStateException(env, callback, "Error creating native failure callback", CHIP_ERROR_NO_MEMORY.AsInteger()); + return; + } + + CHIP_ERROR err = CHIP_NO_ERROR; + OtaSoftwareUpdateRequestorCluster * cppCluster = reinterpret_cast(clusterPtr); + if (cppCluster == nullptr) + { + delete onSuccess; + delete onFailure; + ReturnIllegalStateException(env, callback, "Could not get native cluster", CHIP_ERROR_INCORRECT_STATE.AsInteger()); + return; + } + + err = cppCluster->ReadAttributeDefaultOtaProvider(onSuccess->Cancel(), onFailure->Cancel()); + if (err != CHIP_NO_ERROR) + { + delete onSuccess; + delete onFailure; + ReturnIllegalStateException(env, callback, "Error reading attribute", err.AsInteger()); + } +} + +JNI_METHOD(void, OtaSoftwareUpdateRequestorCluster, writeDefaultOtaProviderAttribute) +(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jbyteArray value) +{ + StackLockGuard lock(JniReferences::GetInstance().GetStackLock()); + CHIPDefaultSuccessCallback * onSuccess = new CHIPDefaultSuccessCallback(callback); + if (!onSuccess) + { + ReturnIllegalStateException(env, callback, "Error creating native success callback", CHIP_ERROR_NO_MEMORY.AsInteger()); + return; + } + + CHIPDefaultFailureCallback * onFailure = new CHIPDefaultFailureCallback(callback); + if (!onFailure) + { + delete onSuccess; + ReturnIllegalStateException(env, callback, "Error creating native failure callback", CHIP_ERROR_NO_MEMORY.AsInteger()); + return; + } + + CHIP_ERROR err = CHIP_NO_ERROR; + OtaSoftwareUpdateRequestorCluster * cppCluster = reinterpret_cast(clusterPtr); + if (cppCluster == nullptr) + { + delete onSuccess; + delete onFailure; + ReturnIllegalStateException(env, callback, "Could not get native cluster", CHIP_ERROR_INCORRECT_STATE.AsInteger()); + return; + } + + JniByteArray jniArr(env, value); + err = cppCluster->WriteAttributeDefaultOtaProvider(onSuccess->Cancel(), onFailure->Cancel(), + chip::ByteSpan((const uint8_t *) jniArr.data(), jniArr.size())); + if (err != CHIP_NO_ERROR) + { + delete onSuccess; + delete onFailure; + ReturnIllegalStateException(env, callback, "Error writing attribute", err.AsInteger()); + } +} + +JNI_METHOD(void, OtaSoftwareUpdateRequestorCluster, readUpdatePossibleAttribute) +(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback) +{ + StackLockGuard lock(JniReferences::GetInstance().GetStackLock()); + CHIPBooleanAttributeCallback * onSuccess = new CHIPBooleanAttributeCallback(callback); + if (!onSuccess) + { + ReturnIllegalStateException(env, callback, "Error creating native success callback", CHIP_ERROR_NO_MEMORY.AsInteger()); + return; + } + + CHIPDefaultFailureCallback * onFailure = new CHIPDefaultFailureCallback(callback); + if (!onFailure) + { + delete onSuccess; + ReturnIllegalStateException(env, callback, "Error creating native failure callback", CHIP_ERROR_NO_MEMORY.AsInteger()); + return; + } + + CHIP_ERROR err = CHIP_NO_ERROR; + OtaSoftwareUpdateRequestorCluster * cppCluster = reinterpret_cast(clusterPtr); + if (cppCluster == nullptr) + { + delete onSuccess; + delete onFailure; + ReturnIllegalStateException(env, callback, "Could not get native cluster", CHIP_ERROR_INCORRECT_STATE.AsInteger()); + return; + } + + err = cppCluster->ReadAttributeUpdatePossible(onSuccess->Cancel(), onFailure->Cancel()); + if (err != CHIP_NO_ERROR) + { + delete onSuccess; + delete onFailure; + ReturnIllegalStateException(env, callback, "Error reading attribute", err.AsInteger()); + } +} + +JNI_METHOD(void, OtaSoftwareUpdateRequestorCluster, readClusterRevisionAttribute) +(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback) +{ + StackLockGuard lock(JniReferences::GetInstance().GetStackLock()); + CHIPInt16uAttributeCallback * onSuccess = new CHIPInt16uAttributeCallback(callback); + if (!onSuccess) + { + ReturnIllegalStateException(env, callback, "Error creating native success callback", CHIP_ERROR_NO_MEMORY.AsInteger()); + return; + } + + CHIPDefaultFailureCallback * onFailure = new CHIPDefaultFailureCallback(callback); + if (!onFailure) + { + delete onSuccess; + ReturnIllegalStateException(env, callback, "Error creating native failure callback", CHIP_ERROR_NO_MEMORY.AsInteger()); + return; + } + + CHIP_ERROR err = CHIP_NO_ERROR; + OtaSoftwareUpdateRequestorCluster * cppCluster = reinterpret_cast(clusterPtr); + if (cppCluster == nullptr) + { + delete onSuccess; + delete onFailure; + ReturnIllegalStateException(env, callback, "Could not get native cluster", CHIP_ERROR_INCORRECT_STATE.AsInteger()); + return; + } + + err = cppCluster->ReadAttributeClusterRevision(onSuccess->Cancel(), onFailure->Cancel()); + if (err != CHIP_NO_ERROR) + { + delete onSuccess; + delete onFailure; + ReturnIllegalStateException(env, callback, "Error reading attribute", err.AsInteger()); + } +} JNI_METHOD(jlong, OccupancySensingCluster, initWithDevice)(JNIEnv * env, jobject self, jlong devicePtr, jint endpointId) { StackLockGuard lock(JniReferences::GetInstance().GetStackLock()); diff --git a/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java b/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java index 2939bc7c172b9b..68419bbfa66b5d 100644 --- a/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java @@ -3632,6 +3632,61 @@ private native void readClusterRevisionAttribute( long chipClusterPtr, IntegerAttributeCallback callback); } + public static class OtaSoftwareUpdateRequestorCluster extends BaseChipCluster { + public OtaSoftwareUpdateRequestorCluster(long devicePtr, int endpointId) { + super(devicePtr, endpointId); + } + + @Override + public native long initWithDevice(long devicePtr, int endpointId); + + public void announceOtaProvider( + DefaultClusterCallback callback, + byte[] serverLocation, + int vendorId, + int announcementReason, + byte[] metadataForNode) { + announceOtaProvider( + chipClusterPtr, callback, serverLocation, vendorId, announcementReason, metadataForNode); + } + + private native void announceOtaProvider( + long chipClusterPtr, + DefaultClusterCallback callback, + byte[] serverLocation, + int vendorId, + int announcementReason, + byte[] metadataForNode); + + public void readDefaultOtaProviderAttribute(OctetStringAttributeCallback callback) { + readDefaultOtaProviderAttribute(chipClusterPtr, callback); + } + + public void writeDefaultOtaProviderAttribute(DefaultClusterCallback callback, byte[] value) { + writeDefaultOtaProviderAttribute(chipClusterPtr, callback, value); + } + + public void readUpdatePossibleAttribute(BooleanAttributeCallback callback) { + readUpdatePossibleAttribute(chipClusterPtr, callback); + } + + public void readClusterRevisionAttribute(IntegerAttributeCallback callback) { + readClusterRevisionAttribute(chipClusterPtr, callback); + } + + private native void readDefaultOtaProviderAttribute( + long chipClusterPtr, OctetStringAttributeCallback callback); + + private native void writeDefaultOtaProviderAttribute( + long chipClusterPtr, DefaultClusterCallback callback, byte[] value); + + private native void readUpdatePossibleAttribute( + long chipClusterPtr, BooleanAttributeCallback callback); + + private native void readClusterRevisionAttribute( + long chipClusterPtr, IntegerAttributeCallback callback); + } + public static class OccupancySensingCluster extends BaseChipCluster { public OccupancySensingCluster(long devicePtr, int endpointId) { super(devicePtr, endpointId); diff --git a/src/controller/python/chip/clusters/CHIPClusters.cpp b/src/controller/python/chip/clusters/CHIPClusters.cpp index 49c92376101e76..5ebcee90bfa4b4 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.cpp +++ b/src/controller/python/chip/clusters/CHIPClusters.cpp @@ -3614,6 +3614,65 @@ chip::ChipError::StorageType chip_ime_ReadAttribute_OtaSoftwareUpdateProvider_Cl } // End of Cluster OtaSoftwareUpdateProvider +// Cluster OtaSoftwareUpdateRequestor + +chip::ChipError::StorageType chip_ime_AppendCommand_OtaSoftwareUpdateRequestor_AnnounceOtaProvider( + chip::Controller::Device * device, chip::EndpointId ZCLendpointId, chip::GroupId, const uint8_t * serverLocation, + uint32_t serverLocation_Len, uint16_t vendorId, uint8_t announcementReason, const uint8_t * metadataForNode, + uint32_t metadataForNode_Len) +{ + VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT.AsInteger()); + chip::Controller::OtaSoftwareUpdateRequestorCluster cluster; + cluster.Associate(device, ZCLendpointId); + return cluster + .AnnounceOtaProvider(nullptr, nullptr, chip::ByteSpan(serverLocation, serverLocation_Len), vendorId, announcementReason, + chip::ByteSpan(metadataForNode, metadataForNode_Len)) + .AsInteger(); +} + +chip::ChipError::StorageType chip_ime_ReadAttribute_OtaSoftwareUpdateRequestor_DefaultOtaProvider(chip::Controller::Device * device, + chip::EndpointId ZCLendpointId, + chip::GroupId /* ZCLgroupId */) +{ + VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT.AsInteger()); + chip::Controller::OtaSoftwareUpdateRequestorCluster cluster; + cluster.Associate(device, ZCLendpointId); + return cluster.ReadAttributeDefaultOtaProvider(gOctetStringAttributeCallback.Cancel(), gDefaultFailureCallback.Cancel()) + .AsInteger(); +} + +chip::ChipError::StorageType chip_ime_WriteAttribute_OtaSoftwareUpdateRequestor_DefaultOtaProvider( + chip::Controller::Device * device, chip::EndpointId ZCLendpointId, chip::GroupId, uint8_t * value, size_t len) +{ + VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT.AsInteger()); + chip::Controller::OtaSoftwareUpdateRequestorCluster cluster; + cluster.Associate(device, ZCLendpointId); + return cluster + .WriteAttributeDefaultOtaProvider(gDefaultSuccessCallback.Cancel(), gDefaultFailureCallback.Cancel(), + chip::ByteSpan(value, len)) + .AsInteger(); +} +chip::ChipError::StorageType chip_ime_ReadAttribute_OtaSoftwareUpdateRequestor_UpdatePossible(chip::Controller::Device * device, + chip::EndpointId ZCLendpointId, + chip::GroupId /* ZCLgroupId */) +{ + VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT.AsInteger()); + chip::Controller::OtaSoftwareUpdateRequestorCluster cluster; + cluster.Associate(device, ZCLendpointId); + return cluster.ReadAttributeUpdatePossible(gBooleanAttributeCallback.Cancel(), gDefaultFailureCallback.Cancel()).AsInteger(); +} + +chip::ChipError::StorageType chip_ime_ReadAttribute_OtaSoftwareUpdateRequestor_ClusterRevision(chip::Controller::Device * device, + chip::EndpointId ZCLendpointId, + chip::GroupId /* ZCLgroupId */) +{ + VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT.AsInteger()); + chip::Controller::OtaSoftwareUpdateRequestorCluster cluster; + cluster.Associate(device, ZCLendpointId); + return cluster.ReadAttributeClusterRevision(gInt16uAttributeCallback.Cancel(), gDefaultFailureCallback.Cancel()).AsInteger(); +} + +// End of Cluster OtaSoftwareUpdateRequestor // Cluster OccupancySensing chip::ChipError::StorageType chip_ime_ReadAttribute_OccupancySensing_Occupancy(chip::Controller::Device * device, diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 9c255daabb6eba..c53b12368765e3 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -2079,6 +2079,40 @@ class ChipClusters: }, }, } + _OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER_INFO = { + "clusterName": "OtaSoftwareUpdateRequestor", + "clusterId": 0x0000002A, + "commands": { + 0x00000000: { + "commandId": 0x00000000, + "commandName": "AnnounceOtaProvider", + "args": { + "serverLocation": "bytes", + "vendorId": "int", + "announcementReason": "int", + "metadataForNode": "bytes", + }, + }, + }, + "attributes": { + 0x00000001: { + "attributeName": "DefaultOtaProvider", + "attributeId": 0x00000001, + "type": "bytes", + "writable": True, + }, + 0x00000002: { + "attributeName": "UpdatePossible", + "attributeId": 0x00000002, + "type": "bool", + }, + 0x0000FFFD: { + "attributeName": "ClusterRevision", + "attributeId": 0x0000FFFD, + "type": "int", + }, + }, + } _OCCUPANCY_SENSING_CLUSTER_INFO = { "clusterName": "OccupancySensing", "clusterId": 0x00000406, @@ -3589,6 +3623,7 @@ class ChipClusters: 0x00000506: _MEDIA_PLAYBACK_CLUSTER_INFO, 0x00000031: _NETWORK_COMMISSIONING_CLUSTER_INFO, 0x00000029: _OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER_INFO, + 0x0000002A: _OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER_INFO, 0x00000406: _OCCUPANCY_SENSING_CLUSTER_INFO, 0x00000006: _ON_OFF_CLUSTER_INFO, 0x00000007: _ON_OFF_SWITCH_CONFIGURATION_CLUSTER_INFO, @@ -3643,6 +3678,7 @@ class ChipClusters: "MediaPlayback": _MEDIA_PLAYBACK_CLUSTER_INFO, "NetworkCommissioning": _NETWORK_COMMISSIONING_CLUSTER_INFO, "OtaSoftwareUpdateProvider": _OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER_INFO, + "OtaSoftwareUpdateRequestor": _OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER_INFO, "OccupancySensing": _OCCUPANCY_SENSING_CLUSTER_INFO, "OnOff": _ON_OFF_CLUSTER_INFO, "OnOffSwitchConfiguration": _ON_OFF_SWITCH_CONFIGURATION_CLUSTER_INFO, @@ -4172,6 +4208,10 @@ def ClusterOtaSoftwareUpdateProvider_CommandQueryImage(self, device: ctypes.c_vo return self._chipLib.chip_ime_AppendCommand_OtaSoftwareUpdateProvider_QueryImage( device, ZCLendpoint, ZCLgroupid, vendorId, productId, imageType, hardwareVersion, currentVersion, protocolsSupported, location, len(location), requestorCanConsent, metadataForProvider, len(metadataForProvider) ) + def ClusterOtaSoftwareUpdateRequestor_CommandAnnounceOtaProvider(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int, serverLocation: bytes, vendorId: int, announcementReason: int, metadataForNode: bytes): + return self._chipLib.chip_ime_AppendCommand_OtaSoftwareUpdateRequestor_AnnounceOtaProvider( + device, ZCLendpoint, ZCLgroupid, serverLocation, len(serverLocation), vendorId, announcementReason, metadataForNode, len(metadataForNode) + ) def ClusterOnOff_CommandOff(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int): return self._chipLib.chip_ime_AppendCommand_OnOff_Off( device, ZCLendpoint, ZCLgroupid @@ -4766,6 +4806,14 @@ def ClusterNetworkCommissioning_ReadAttributeClusterRevision(self, device: ctype return self._chipLib.chip_ime_ReadAttribute_NetworkCommissioning_ClusterRevision(device, ZCLendpoint, ZCLgroupid) def ClusterOtaSoftwareUpdateProvider_ReadAttributeClusterRevision(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int): return self._chipLib.chip_ime_ReadAttribute_OtaSoftwareUpdateProvider_ClusterRevision(device, ZCLendpoint, ZCLgroupid) + def ClusterOtaSoftwareUpdateRequestor_ReadAttributeDefaultOtaProvider(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int): + return self._chipLib.chip_ime_ReadAttribute_OtaSoftwareUpdateRequestor_DefaultOtaProvider(device, ZCLendpoint, ZCLgroupid) + def ClusterOtaSoftwareUpdateRequestor_WriteAttributeDefaultOtaProvider(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int, value: bytes): + return self._chipLib.chip_ime_WriteAttribute_OtaSoftwareUpdateRequestor_DefaultOtaProvider(device, ZCLendpoint, ZCLgroupid, value, len(value)) + def ClusterOtaSoftwareUpdateRequestor_ReadAttributeUpdatePossible(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int): + return self._chipLib.chip_ime_ReadAttribute_OtaSoftwareUpdateRequestor_UpdatePossible(device, ZCLendpoint, ZCLgroupid) + def ClusterOtaSoftwareUpdateRequestor_ReadAttributeClusterRevision(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int): + return self._chipLib.chip_ime_ReadAttribute_OtaSoftwareUpdateRequestor_ClusterRevision(device, ZCLendpoint, ZCLgroupid) def ClusterOccupancySensing_ReadAttributeOccupancy(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int): return self._chipLib.chip_ime_ReadAttribute_OccupancySensing_Occupancy(device, ZCLendpoint, ZCLgroupid) def ClusterOccupancySensing_ConfigureAttributeOccupancy(self, device: ctypes.c_void_p, ZCLendpoint: int, minInterval: int, maxInterval: int, change: int): @@ -6229,6 +6277,22 @@ def InitLib(self, chipLib): # Cluster OtaSoftwareUpdateProvider ReadAttribute ClusterRevision self._chipLib.chip_ime_ReadAttribute_OtaSoftwareUpdateProvider_ClusterRevision.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16] self._chipLib.chip_ime_ReadAttribute_OtaSoftwareUpdateProvider_ClusterRevision.restype = ctypes.c_uint32 + # Cluster OtaSoftwareUpdateRequestor + # Cluster OtaSoftwareUpdateRequestor Command AnnounceOtaProvider + self._chipLib.chip_ime_AppendCommand_OtaSoftwareUpdateRequestor_AnnounceOtaProvider.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16, ctypes.c_char_p, ctypes.c_uint32, ctypes.c_uint16, ctypes.c_uint8, ctypes.c_char_p, ctypes.c_uint32] + self._chipLib.chip_ime_AppendCommand_OtaSoftwareUpdateRequestor_AnnounceOtaProvider.restype = ctypes.c_uint32 + # Cluster OtaSoftwareUpdateRequestor ReadAttribute DefaultOtaProvider + self._chipLib.chip_ime_ReadAttribute_OtaSoftwareUpdateRequestor_DefaultOtaProvider.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16] + self._chipLib.chip_ime_ReadAttribute_OtaSoftwareUpdateRequestor_DefaultOtaProvider.restype = ctypes.c_uint32 + # Cluster OtaSoftwareUpdateRequestor WriteAttribute DefaultOtaProvider + self._chipLib.chip_ime_WriteAttribute_OtaSoftwareUpdateRequestor_DefaultOtaProvider.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16, ctypes.c_char_p, ctypes.c_uint32] + self._chipLib.chip_ime_WriteAttribute_OtaSoftwareUpdateRequestor_DefaultOtaProvider.restype = ctypes.c_uint32 + # Cluster OtaSoftwareUpdateRequestor ReadAttribute UpdatePossible + self._chipLib.chip_ime_ReadAttribute_OtaSoftwareUpdateRequestor_UpdatePossible.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16] + self._chipLib.chip_ime_ReadAttribute_OtaSoftwareUpdateRequestor_UpdatePossible.restype = ctypes.c_uint32 + # Cluster OtaSoftwareUpdateRequestor ReadAttribute ClusterRevision + self._chipLib.chip_ime_ReadAttribute_OtaSoftwareUpdateRequestor_ClusterRevision.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16] + self._chipLib.chip_ime_ReadAttribute_OtaSoftwareUpdateRequestor_ClusterRevision.restype = ctypes.c_uint32 # Cluster OccupancySensing # Cluster OccupancySensing ReadAttribute Occupancy self._chipLib.chip_ime_ReadAttribute_OccupancySensing_Occupancy.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16] diff --git a/src/darwin/Framework/CHIP/templates/helper.js b/src/darwin/Framework/CHIP/templates/helper.js index 6a8d7af854dd05..09ad83bc250c1a 100644 --- a/src/darwin/Framework/CHIP/templates/helper.js +++ b/src/darwin/Framework/CHIP/templates/helper.js @@ -42,6 +42,7 @@ function asExpectedEndpointForCluster(clusterName) case 'OperationalCredentials': case 'TrustedRootCertificates': case 'OtaSoftwareUpdateProvider': + case 'OtaSoftwareUpdateRequestor': return 0; } return 1; diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h index 08c29203977e78..72a0faa4354b6b 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h @@ -1012,6 +1012,27 @@ NS_ASSUME_NONNULL_BEGIN @end +/** + * Cluster OTA Software Update Requestor + * + */ +@interface CHIPOtaSoftwareUpdateRequestor : CHIPCluster + +- (void)announceOtaProvider:(NSData *)serverLocation + vendorId:(uint16_t)vendorId + announcementReason:(uint8_t)announcementReason + metadataForNode:(NSData *)metadataForNode + responseHandler:(ResponseHandler)responseHandler; + +- (void)readAttributeDefaultOtaProviderWithResponseHandler:(ResponseHandler)responseHandler; +- (void)writeAttributeDefaultOtaProviderWithValue:(NSData *)value responseHandler:(ResponseHandler)responseHandler; + +- (void)readAttributeUpdatePossibleWithResponseHandler:(ResponseHandler)responseHandler; + +- (void)readAttributeClusterRevisionWithResponseHandler:(ResponseHandler)responseHandler; + +@end + /** * Cluster Occupancy Sensing * diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm index 48aca92da368f4..442aed0fe4ac13 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm @@ -2882,6 +2882,55 @@ new CHIPInt16uAttributeCallbackBridge(self.callbackQueue, responseHandler, ^(Can @end +@implementation CHIPOtaSoftwareUpdateRequestor + +- (chip::Controller::ClusterBase *)getCluster +{ + return &_cppCluster; +} + +- (void)announceOtaProvider:(NSData *)serverLocation + vendorId:(uint16_t)vendorId + announcementReason:(uint8_t)announcementReason + metadataForNode:(NSData *)metadataForNode + responseHandler:(ResponseHandler)responseHandler +{ + new CHIPDefaultSuccessCallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { + return self.cppCluster.AnnounceOtaProvider( + success, failure, [self asSpan:serverLocation], vendorId, announcementReason, [self asSpan:metadataForNode]); + }); +} + +- (void)readAttributeDefaultOtaProviderWithResponseHandler:(ResponseHandler)responseHandler +{ + new CHIPOctetStringAttributeCallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { + return self.cppCluster.ReadAttributeDefaultOtaProvider(success, failure); + }); +} + +- (void)writeAttributeDefaultOtaProviderWithValue:(NSData *)value responseHandler:(ResponseHandler)responseHandler +{ + new CHIPDefaultSuccessCallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { + return self.cppCluster.WriteAttributeDefaultOtaProvider(success, failure, [self asSpan:value]); + }); +} + +- (void)readAttributeUpdatePossibleWithResponseHandler:(ResponseHandler)responseHandler +{ + new CHIPBooleanAttributeCallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { + return self.cppCluster.ReadAttributeUpdatePossible(success, failure); + }); +} + +- (void)readAttributeClusterRevisionWithResponseHandler:(ResponseHandler)responseHandler +{ + new CHIPInt16uAttributeCallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { + return self.cppCluster.ReadAttributeClusterRevision(success, failure); + }); +} + +@end + @implementation CHIPOccupancySensing - (chip::Controller::ClusterBase *)getCluster diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc_internal.h b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc_internal.h index bb5e5b5071e3e0..ab00b17afb4bd4 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc_internal.h +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc_internal.h @@ -145,6 +145,10 @@ @property (readonly) chip::Controller::OtaSoftwareUpdateProviderCluster cppCluster; @end +@interface CHIPOtaSoftwareUpdateRequestor () +@property (readonly) chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster; +@end + @interface CHIPOccupancySensing () @property (readonly) chip::Controller::OccupancySensingCluster cppCluster; @end diff --git a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m index e249b7fedc88d6..c894e573096b3d 100644 --- a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m +++ b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m @@ -8513,6 +8513,91 @@ - (void)testSendClusterOtaSoftwareUpdateProviderReadAttributeClusterRevisionWith [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; } +- (void)testSendClusterOtaSoftwareUpdateRequestorReadAttributeDefaultOtaProviderWithResponseHandler +{ + XCTestExpectation * expectation = + [self expectationWithDescription:@"OtaSoftwareUpdateRequestorReadAttributeDefaultOtaProviderWithResponseHandler"]; + + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPOtaSoftwareUpdateRequestor * cluster = [[CHIPOtaSoftwareUpdateRequestor alloc] initWithDevice:device + endpoint:0 + queue:queue]; + XCTAssertNotNil(cluster); + + [cluster readAttributeDefaultOtaProviderWithResponseHandler:^(NSError * err, NSDictionary * values) { + NSLog(@"OtaSoftwareUpdateRequestor DefaultOtaProvider Error: %@", err); + XCTAssertEqual(err.code, 0); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} + +- (void)testSendClusterOtaSoftwareUpdateRequestorWriteAttributeDefaultOtaProviderWithValue +{ + XCTestExpectation * expectation = + [self expectationWithDescription:@"OtaSoftwareUpdateRequestorWriteAttributeDefaultOtaProviderWithValue"]; + + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPOtaSoftwareUpdateRequestor * cluster = [[CHIPOtaSoftwareUpdateRequestor alloc] initWithDevice:device + endpoint:0 + queue:queue]; + XCTAssertNotNil(cluster); + + NSData * value = [@"Test" dataUsingEncoding:NSUTF8StringEncoding]; + [cluster writeAttributeDefaultOtaProviderWithValue:value + responseHandler:^(NSError * err, NSDictionary * values) { + NSLog(@"OtaSoftwareUpdateRequestor DefaultOtaProvider Error: %@", err); + XCTAssertEqual(err.code, 0); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} +- (void)testSendClusterOtaSoftwareUpdateRequestorReadAttributeUpdatePossibleWithResponseHandler +{ + XCTestExpectation * expectation = + [self expectationWithDescription:@"OtaSoftwareUpdateRequestorReadAttributeUpdatePossibleWithResponseHandler"]; + + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPOtaSoftwareUpdateRequestor * cluster = [[CHIPOtaSoftwareUpdateRequestor alloc] initWithDevice:device + endpoint:0 + queue:queue]; + XCTAssertNotNil(cluster); + + [cluster readAttributeUpdatePossibleWithResponseHandler:^(NSError * err, NSDictionary * values) { + NSLog(@"OtaSoftwareUpdateRequestor UpdatePossible Error: %@", err); + XCTAssertEqual(err.code, 0); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} + +- (void)testSendClusterOtaSoftwareUpdateRequestorReadAttributeClusterRevisionWithResponseHandler +{ + XCTestExpectation * expectation = + [self expectationWithDescription:@"OtaSoftwareUpdateRequestorReadAttributeClusterRevisionWithResponseHandler"]; + + CHIPDevice * device = GetPairedDevice(kDeviceId); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPOtaSoftwareUpdateRequestor * cluster = [[CHIPOtaSoftwareUpdateRequestor alloc] initWithDevice:device + endpoint:0 + queue:queue]; + XCTAssertNotNil(cluster); + + [cluster readAttributeClusterRevisionWithResponseHandler:^(NSError * err, NSDictionary * values) { + NSLog(@"OtaSoftwareUpdateRequestor ClusterRevision Error: %@", err); + XCTAssertEqual(err.code, 0); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} + - (void)testSendClusterOccupancySensingReadAttributeOccupancyWithResponseHandler { XCTestExpectation * expectation = diff --git a/zzz_generated/all-clusters-app/zap-generated/callback-stub.cpp b/zzz_generated/all-clusters-app/zap-generated/callback-stub.cpp index a3d295bca21877..b7b195a055b557 100644 --- a/zzz_generated/all-clusters-app/zap-generated/callback-stub.cpp +++ b/zzz_generated/all-clusters-app/zap-generated/callback-stub.cpp @@ -124,6 +124,9 @@ void emberAfClusterInitCallback(EndpointId endpoint, ClusterId clusterId) case ZCL_OTA_PROVIDER_CLUSTER_ID: emberAfOtaSoftwareUpdateProviderClusterInitCallback(endpoint); break; + case ZCL_OTA_REQUESTOR_CLUSTER_ID: + emberAfOtaSoftwareUpdateRequestorClusterInitCallback(endpoint); + break; case ZCL_OCCUPANCY_SENSING_CLUSTER_ID: emberAfOccupancySensingClusterInitCallback(endpoint); break; @@ -350,6 +353,11 @@ void __attribute__((weak)) emberAfOtaSoftwareUpdateProviderClusterInitCallback(E // To prevent warning (void) endpoint; } +void __attribute__((weak)) emberAfOtaSoftwareUpdateRequestorClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} void __attribute__((weak)) emberAfOccupancySensingClusterInitCallback(EndpointId endpoint) { // To prevent warning diff --git a/zzz_generated/all-clusters-app/zap-generated/endpoint_config.h b/zzz_generated/all-clusters-app/zap-generated/endpoint_config.h index 3354ee00583c46..3135cf3294d15c 100644 --- a/zzz_generated/all-clusters-app/zap-generated/endpoint_config.h +++ b/zzz_generated/all-clusters-app/zap-generated/endpoint_config.h @@ -155,12 +155,17 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ + /* Endpoint: 0, Cluster: OTA Software Update Requestor (server), big-endian */ \ + \ + /* 1654 - default ota provider, */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + \ /* Endpoint: 0, Cluster: General Commissioning (server), big-endian */ \ \ - /* 1654 - Breadcrumb, */ \ + /* 1671 - Breadcrumb, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 1662 - BasicCommissioningInfoList, */ \ + /* 1679 - BasicCommissioningInfoList, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -178,12 +183,12 @@ \ /* Endpoint: 0, Cluster: Network Commissioning (server), big-endian */ \ \ - /* 1916 - FeatureMap, */ \ + /* 1933 - FeatureMap, */ \ 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 0, Cluster: General Diagnostics (server), big-endian */ \ \ - /* 1920 - NetworkInterfaces, */ \ + /* 1937 - NetworkInterfaces, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -201,24 +206,24 @@ \ /* Endpoint: 0, Cluster: Software Diagnostics (server), big-endian */ \ \ - /* 2174 - CurrentHeapHighWatermark, */ \ + /* 2191 - CurrentHeapHighWatermark, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 0, Cluster: Thread Network Diagnostics (server), big-endian */ \ \ - /* 2182 - NetworkName, */ \ + /* 2199 - NetworkName, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2199 - ExtendedPanId, */ \ + /* 2216 - ExtendedPanId, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2207 - MeshLocalPrefix, */ \ + /* 2224 - MeshLocalPrefix, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2225 - OverrunCount, */ \ + /* 2242 - OverrunCount, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2233 - NeighborTableList, */ \ + /* 2250 - NeighborTableList, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -234,7 +239,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2487 - RouteTableList, */ \ + /* 2504 - RouteTableList, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -250,166 +255,166 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2741 - PartitionId, */ \ + /* 2758 - PartitionId, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2745 - TxTotalCount, */ \ + /* 2762 - TxTotalCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2749 - TxUnicastCount, */ \ + /* 2766 - TxUnicastCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2753 - TxBroadcastCount, */ \ + /* 2770 - TxBroadcastCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2757 - TxAckRequestedCount, */ \ + /* 2774 - TxAckRequestedCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2761 - TxAckedCount, */ \ + /* 2778 - TxAckedCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2765 - TxNoAckRequestedCount, */ \ + /* 2782 - TxNoAckRequestedCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2769 - TxDataCount, */ \ + /* 2786 - TxDataCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2773 - TxDataPollCount, */ \ + /* 2790 - TxDataPollCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2777 - TxBeaconCount, */ \ + /* 2794 - TxBeaconCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2781 - TxBeaconRequestCount, */ \ + /* 2798 - TxBeaconRequestCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2785 - TxOtherCount, */ \ + /* 2802 - TxOtherCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2789 - TxRetryCount, */ \ + /* 2806 - TxRetryCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2793 - TxDirectMaxRetryExpiryCount, */ \ + /* 2810 - TxDirectMaxRetryExpiryCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2797 - TxIndirectMaxRetryExpiryCount, */ \ + /* 2814 - TxIndirectMaxRetryExpiryCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2801 - TxErrCcaCount, */ \ + /* 2818 - TxErrCcaCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2805 - TxErrAbortCount, */ \ + /* 2822 - TxErrAbortCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2809 - TxErrBusyChannelCount, */ \ + /* 2826 - TxErrBusyChannelCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2813 - RxTotalCount, */ \ + /* 2830 - RxTotalCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2817 - RxUnicastCount, */ \ + /* 2834 - RxUnicastCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2821 - RxBroadcastCount, */ \ + /* 2838 - RxBroadcastCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2825 - RxDataCount, */ \ + /* 2842 - RxDataCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2829 - RxDataPollCount, */ \ + /* 2846 - RxDataPollCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2833 - RxBeaconCount, */ \ + /* 2850 - RxBeaconCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2837 - RxBeaconRequestCount, */ \ + /* 2854 - RxBeaconRequestCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2841 - RxOtherCount, */ \ + /* 2858 - RxOtherCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2845 - RxAddressFilteredCount, */ \ + /* 2862 - RxAddressFilteredCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2849 - RxDestAddrFilteredCount, */ \ + /* 2866 - RxDestAddrFilteredCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2853 - RxDuplicatedCount, */ \ + /* 2870 - RxDuplicatedCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2857 - RxErrNoFrameCount, */ \ + /* 2874 - RxErrNoFrameCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2861 - RxErrUnknownNeighborCount, */ \ + /* 2878 - RxErrUnknownNeighborCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2865 - RxErrInvalidSrcAddrCount, */ \ + /* 2882 - RxErrInvalidSrcAddrCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2869 - RxErrSecCount, */ \ + /* 2886 - RxErrSecCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2873 - RxErrFcsCount, */ \ + /* 2890 - RxErrFcsCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2877 - RxErrOtherCount, */ \ + /* 2894 - RxErrOtherCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2881 - SecurityPolicy, */ \ + /* 2898 - SecurityPolicy, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2886 - OperationalDatasetComponents, */ \ + /* 2903 - OperationalDatasetComponents, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2900 - ActiveNetworkFaultsList, */ \ + /* 2917 - ActiveNetworkFaultsList, */ \ 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 0, Cluster: WiFi Network Diagnostics (server), big-endian */ \ \ - /* 2904 - bssid, */ \ + /* 2921 - bssid, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2911 - BeaconLostCount, */ \ + /* 2928 - BeaconLostCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2915 - BeaconRxCount, */ \ + /* 2932 - BeaconRxCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2919 - PacketMulticastRxCount, */ \ + /* 2936 - PacketMulticastRxCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2923 - PacketMulticastTxCount, */ \ + /* 2940 - PacketMulticastTxCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2927 - PacketUnicastRxCount, */ \ + /* 2944 - PacketUnicastRxCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2931 - PacketUnicastTxCount, */ \ + /* 2948 - PacketUnicastTxCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2935 - CurrentMaxRate, */ \ + /* 2952 - CurrentMaxRate, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 0, Cluster: Ethernet Network Diagnostics (server), big-endian */ \ \ - /* 2943 - PacketRxCount, */ \ + /* 2960 - PacketRxCount, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2951 - PacketTxCount, */ \ + /* 2968 - PacketTxCount, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2959 - TxErrCount, */ \ + /* 2976 - TxErrCount, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2967 - CollisionCount, */ \ + /* 2984 - CollisionCount, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2975 - OverrunCount, */ \ + /* 2992 - OverrunCount, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 0, Cluster: Operational Credentials (server), big-endian */ \ \ - /* 2983 - fabrics list, */ \ + /* 3000 - fabrics list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -428,7 +433,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 3303 - TrustedRootCertificates, */ \ + /* 3320 - TrustedRootCertificates, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -454,7 +459,7 @@ \ /* Endpoint: 0, Cluster: Group Key Management (server), big-endian */ \ \ - /* 3703 - groups, */ \ + /* 3720 - groups, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -470,7 +475,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 3957 - group keys, */ \ + /* 3974 - group keys, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -488,12 +493,12 @@ \ /* Endpoint: 1, Cluster: On/Off (server), big-endian */ \ \ - /* 4211 - FeatureMap, */ \ + /* 4228 - FeatureMap, */ \ 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 1, Cluster: Descriptor (server), big-endian */ \ \ - /* 4215 - device list, */ \ + /* 4232 - device list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -509,7 +514,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 4469 - server list, */ \ + /* 4486 - server list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -525,7 +530,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 4723 - client list, */ \ + /* 4740 - client list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -541,7 +546,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 4977 - parts list, */ \ + /* 4994 - parts list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -559,37 +564,37 @@ \ /* Endpoint: 1, Cluster: Bridged Device Basic (server), big-endian */ \ \ - /* 5231 - VendorName, */ \ + /* 5248 - VendorName, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 5264 - ProductName, */ \ + /* 5281 - ProductName, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 5297 - UserLabel, */ \ + /* 5314 - UserLabel, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 5330 - HardwareVersionString, */ \ + /* 5347 - HardwareVersionString, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 5395 - SoftwareVersion, */ \ + /* 5412 - SoftwareVersion, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 5399 - SoftwareVersionString, */ \ + /* 5416 - SoftwareVersionString, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 5464 - ManufacturingDate, */ \ + /* 5481 - ManufacturingDate, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 5481 - PartNumber, */ \ + /* 5498 - PartNumber, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -605,7 +610,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 5736 - ProductURL, */ \ + /* 5753 - ProductURL, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -621,19 +626,19 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 5991 - ProductLabel, */ \ + /* 6008 - ProductLabel, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 6056 - SerialNumber, */ \ + /* 6073 - SerialNumber, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 1, Cluster: Fixed Label (server), big-endian */ \ \ - /* 6089 - label list, */ \ + /* 6106 - label list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -651,12 +656,12 @@ \ /* Endpoint: 1, Cluster: Thermostat (server), big-endian */ \ \ - /* 6343 - FeatureMap, */ \ + /* 6360 - FeatureMap, */ \ 0x00, 0x00, 0x00, 0x0B, \ \ /* Endpoint: 1, Cluster: Color Control (server), big-endian */ \ \ - /* 6347 - compensation text, */ \ + /* 6364 - compensation text, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -674,18 +679,18 @@ \ /* Endpoint: 1, Cluster: IAS Zone (server), big-endian */ \ \ - /* 6602 - IAS CIE address, */ \ + /* 6619 - IAS CIE address, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 1, Cluster: Wake on LAN (server), big-endian */ \ \ - /* 6610 - wake on lan mac address, */ \ + /* 6627 - wake on lan mac address, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 1, Cluster: TV Channel (server), big-endian */ \ \ - /* 6643 - tv channel list, */ \ + /* 6660 - tv channel list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -701,17 +706,17 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 6897 - tv channel lineup, */ \ + /* 6914 - tv channel lineup, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 6930 - current tv channel, */ \ + /* 6947 - current tv channel, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 1, Cluster: Target Navigator (server), big-endian */ \ \ - /* 6963 - target navigator list, */ \ + /* 6980 - target navigator list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -729,7 +734,7 @@ \ /* Endpoint: 1, Cluster: Media Input (server), big-endian */ \ \ - /* 7217 - media input list, */ \ + /* 7234 - media input list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -747,7 +752,7 @@ \ /* Endpoint: 1, Cluster: Content Launcher (server), big-endian */ \ \ - /* 7471 - accepts header list, */ \ + /* 7488 - accepts header list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -763,7 +768,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 7725 - supported streaming types, */ \ + /* 7742 - supported streaming types, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -781,7 +786,7 @@ \ /* Endpoint: 1, Cluster: Audio Output (server), big-endian */ \ \ - /* 7979 - audio output list, */ \ + /* 7996 - audio output list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -799,7 +804,7 @@ \ /* Endpoint: 1, Cluster: Application Launcher (server), big-endian */ \ \ - /* 8233 - application launcher list, */ \ + /* 8250 - application launcher list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -817,45 +822,45 @@ \ /* Endpoint: 1, Cluster: Application Basic (server), big-endian */ \ \ - /* 8487 - vendor name, */ \ + /* 8504 - vendor name, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 8520 - application name, */ \ + /* 8537 - application name, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 8553 - application id, */ \ + /* 8570 - application id, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 1, Cluster: Test Cluster (server), big-endian */ \ \ - /* 8586 - bitmap32, */ \ + /* 8603 - bitmap32, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 8590 - bitmap64, */ \ + /* 8607 - bitmap64, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 8598 - int32u, */ \ + /* 8615 - int32u, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 8602 - int64u, */ \ + /* 8619 - int64u, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 8610 - int32s, */ \ + /* 8627 - int32s, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 8614 - int64s, */ \ + /* 8631 - int64s, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 8622 - octet_string, */ \ + /* 8639 - octet_string, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 8633 - list_int8u, */ \ + /* 8650 - list_int8u, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 8643 - list_octet_string, */ \ + /* 8660 - list_octet_string, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -871,7 +876,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 8897 - list_struct_octet_string, */ \ + /* 8914 - list_struct_octet_string, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -887,7 +892,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 9151 - long_octet_string, */ \ + /* 9168 - long_octet_string, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -942,10 +947,10 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 10153 - char_string, */ \ + /* 10170 - char_string, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 10164 - long_char_string, */ \ + /* 10181 - long_char_string, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1002,15 +1007,15 @@ \ /* Endpoint: 1, Cluster: Electrical Measurement (server), big-endian */ \ \ - /* 11166 - measurement type, */ \ + /* 11183 - measurement type, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 11170 - total active power, */ \ + /* 11187 - total active power, */ \ 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 2, Cluster: On/Off (server), big-endian */ \ \ - /* 11174 - FeatureMap, */ \ + /* 11191 - FeatureMap, */ \ 0x00, 0x00, 0x00, 0x00, \ } @@ -1146,12 +1151,17 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ + /* Endpoint: 0, Cluster: OTA Software Update Requestor (server), little-endian */ \ + \ + /* 1654 - default ota provider, */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + \ /* Endpoint: 0, Cluster: General Commissioning (server), little-endian */ \ \ - /* 1654 - Breadcrumb, */ \ + /* 1671 - Breadcrumb, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 1662 - BasicCommissioningInfoList, */ \ + /* 1679 - BasicCommissioningInfoList, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1169,12 +1179,12 @@ \ /* Endpoint: 0, Cluster: Network Commissioning (server), little-endian */ \ \ - /* 1916 - FeatureMap, */ \ + /* 1933 - FeatureMap, */ \ 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 0, Cluster: General Diagnostics (server), little-endian */ \ \ - /* 1920 - NetworkInterfaces, */ \ + /* 1937 - NetworkInterfaces, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1192,24 +1202,24 @@ \ /* Endpoint: 0, Cluster: Software Diagnostics (server), little-endian */ \ \ - /* 2174 - CurrentHeapHighWatermark, */ \ + /* 2191 - CurrentHeapHighWatermark, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 0, Cluster: Thread Network Diagnostics (server), little-endian */ \ \ - /* 2182 - NetworkName, */ \ + /* 2199 - NetworkName, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2199 - ExtendedPanId, */ \ + /* 2216 - ExtendedPanId, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2207 - MeshLocalPrefix, */ \ + /* 2224 - MeshLocalPrefix, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2225 - OverrunCount, */ \ + /* 2242 - OverrunCount, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2233 - NeighborTableList, */ \ + /* 2250 - NeighborTableList, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1225,7 +1235,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2487 - RouteTableList, */ \ + /* 2504 - RouteTableList, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1241,166 +1251,166 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2741 - PartitionId, */ \ + /* 2758 - PartitionId, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2745 - TxTotalCount, */ \ + /* 2762 - TxTotalCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2749 - TxUnicastCount, */ \ + /* 2766 - TxUnicastCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2753 - TxBroadcastCount, */ \ + /* 2770 - TxBroadcastCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2757 - TxAckRequestedCount, */ \ + /* 2774 - TxAckRequestedCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2761 - TxAckedCount, */ \ + /* 2778 - TxAckedCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2765 - TxNoAckRequestedCount, */ \ + /* 2782 - TxNoAckRequestedCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2769 - TxDataCount, */ \ + /* 2786 - TxDataCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2773 - TxDataPollCount, */ \ + /* 2790 - TxDataPollCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2777 - TxBeaconCount, */ \ + /* 2794 - TxBeaconCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2781 - TxBeaconRequestCount, */ \ + /* 2798 - TxBeaconRequestCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2785 - TxOtherCount, */ \ + /* 2802 - TxOtherCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2789 - TxRetryCount, */ \ + /* 2806 - TxRetryCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2793 - TxDirectMaxRetryExpiryCount, */ \ + /* 2810 - TxDirectMaxRetryExpiryCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2797 - TxIndirectMaxRetryExpiryCount, */ \ + /* 2814 - TxIndirectMaxRetryExpiryCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2801 - TxErrCcaCount, */ \ + /* 2818 - TxErrCcaCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2805 - TxErrAbortCount, */ \ + /* 2822 - TxErrAbortCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2809 - TxErrBusyChannelCount, */ \ + /* 2826 - TxErrBusyChannelCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2813 - RxTotalCount, */ \ + /* 2830 - RxTotalCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2817 - RxUnicastCount, */ \ + /* 2834 - RxUnicastCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2821 - RxBroadcastCount, */ \ + /* 2838 - RxBroadcastCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2825 - RxDataCount, */ \ + /* 2842 - RxDataCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2829 - RxDataPollCount, */ \ + /* 2846 - RxDataPollCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2833 - RxBeaconCount, */ \ + /* 2850 - RxBeaconCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2837 - RxBeaconRequestCount, */ \ + /* 2854 - RxBeaconRequestCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2841 - RxOtherCount, */ \ + /* 2858 - RxOtherCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2845 - RxAddressFilteredCount, */ \ + /* 2862 - RxAddressFilteredCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2849 - RxDestAddrFilteredCount, */ \ + /* 2866 - RxDestAddrFilteredCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2853 - RxDuplicatedCount, */ \ + /* 2870 - RxDuplicatedCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2857 - RxErrNoFrameCount, */ \ + /* 2874 - RxErrNoFrameCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2861 - RxErrUnknownNeighborCount, */ \ + /* 2878 - RxErrUnknownNeighborCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2865 - RxErrInvalidSrcAddrCount, */ \ + /* 2882 - RxErrInvalidSrcAddrCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2869 - RxErrSecCount, */ \ + /* 2886 - RxErrSecCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2873 - RxErrFcsCount, */ \ + /* 2890 - RxErrFcsCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2877 - RxErrOtherCount, */ \ + /* 2894 - RxErrOtherCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2881 - SecurityPolicy, */ \ + /* 2898 - SecurityPolicy, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2886 - OperationalDatasetComponents, */ \ + /* 2903 - OperationalDatasetComponents, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2900 - ActiveNetworkFaultsList, */ \ + /* 2917 - ActiveNetworkFaultsList, */ \ 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 0, Cluster: WiFi Network Diagnostics (server), little-endian */ \ \ - /* 2904 - bssid, */ \ + /* 2921 - bssid, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2911 - BeaconLostCount, */ \ + /* 2928 - BeaconLostCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2915 - BeaconRxCount, */ \ + /* 2932 - BeaconRxCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2919 - PacketMulticastRxCount, */ \ + /* 2936 - PacketMulticastRxCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2923 - PacketMulticastTxCount, */ \ + /* 2940 - PacketMulticastTxCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2927 - PacketUnicastRxCount, */ \ + /* 2944 - PacketUnicastRxCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2931 - PacketUnicastTxCount, */ \ + /* 2948 - PacketUnicastTxCount, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 2935 - CurrentMaxRate, */ \ + /* 2952 - CurrentMaxRate, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 0, Cluster: Ethernet Network Diagnostics (server), little-endian */ \ \ - /* 2943 - PacketRxCount, */ \ + /* 2960 - PacketRxCount, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2951 - PacketTxCount, */ \ + /* 2968 - PacketTxCount, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2959 - TxErrCount, */ \ + /* 2976 - TxErrCount, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2967 - CollisionCount, */ \ + /* 2984 - CollisionCount, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 2975 - OverrunCount, */ \ + /* 2992 - OverrunCount, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 0, Cluster: Operational Credentials (server), little-endian */ \ \ - /* 2983 - fabrics list, */ \ + /* 3000 - fabrics list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1419,7 +1429,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 3303 - TrustedRootCertificates, */ \ + /* 3320 - TrustedRootCertificates, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1445,7 +1455,7 @@ \ /* Endpoint: 0, Cluster: Group Key Management (server), little-endian */ \ \ - /* 3703 - groups, */ \ + /* 3720 - groups, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1461,7 +1471,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 3957 - group keys, */ \ + /* 3974 - group keys, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1479,12 +1489,12 @@ \ /* Endpoint: 1, Cluster: On/Off (server), little-endian */ \ \ - /* 4211 - FeatureMap, */ \ + /* 4228 - FeatureMap, */ \ 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 1, Cluster: Descriptor (server), little-endian */ \ \ - /* 4215 - device list, */ \ + /* 4232 - device list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1500,7 +1510,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 4469 - server list, */ \ + /* 4486 - server list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1516,7 +1526,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 4723 - client list, */ \ + /* 4740 - client list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1532,7 +1542,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 4977 - parts list, */ \ + /* 4994 - parts list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1550,37 +1560,37 @@ \ /* Endpoint: 1, Cluster: Bridged Device Basic (server), little-endian */ \ \ - /* 5231 - VendorName, */ \ + /* 5248 - VendorName, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 5264 - ProductName, */ \ + /* 5281 - ProductName, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 5297 - UserLabel, */ \ + /* 5314 - UserLabel, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 5330 - HardwareVersionString, */ \ + /* 5347 - HardwareVersionString, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 5395 - SoftwareVersion, */ \ + /* 5412 - SoftwareVersion, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 5399 - SoftwareVersionString, */ \ + /* 5416 - SoftwareVersionString, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 5464 - ManufacturingDate, */ \ + /* 5481 - ManufacturingDate, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 5481 - PartNumber, */ \ + /* 5498 - PartNumber, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1596,7 +1606,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 5736 - ProductURL, */ \ + /* 5753 - ProductURL, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1612,19 +1622,19 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 5991 - ProductLabel, */ \ + /* 6008 - ProductLabel, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 6056 - SerialNumber, */ \ + /* 6073 - SerialNumber, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 1, Cluster: Fixed Label (server), little-endian */ \ \ - /* 6089 - label list, */ \ + /* 6106 - label list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1642,12 +1652,12 @@ \ /* Endpoint: 1, Cluster: Thermostat (server), little-endian */ \ \ - /* 6343 - FeatureMap, */ \ + /* 6360 - FeatureMap, */ \ 0x00, 0x00, 0x00, 0x0B, \ \ /* Endpoint: 1, Cluster: Color Control (server), little-endian */ \ \ - /* 6347 - compensation text, */ \ + /* 6364 - compensation text, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1665,18 +1675,18 @@ \ /* Endpoint: 1, Cluster: IAS Zone (server), little-endian */ \ \ - /* 6602 - IAS CIE address, */ \ + /* 6619 - IAS CIE address, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 1, Cluster: Wake on LAN (server), little-endian */ \ \ - /* 6610 - wake on lan mac address, */ \ + /* 6627 - wake on lan mac address, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 1, Cluster: TV Channel (server), little-endian */ \ \ - /* 6643 - tv channel list, */ \ + /* 6660 - tv channel list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1692,17 +1702,17 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 6897 - tv channel lineup, */ \ + /* 6914 - tv channel lineup, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 6930 - current tv channel, */ \ + /* 6947 - current tv channel, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 1, Cluster: Target Navigator (server), little-endian */ \ \ - /* 6963 - target navigator list, */ \ + /* 6980 - target navigator list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1720,7 +1730,7 @@ \ /* Endpoint: 1, Cluster: Media Input (server), little-endian */ \ \ - /* 7217 - media input list, */ \ + /* 7234 - media input list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1738,7 +1748,7 @@ \ /* Endpoint: 1, Cluster: Content Launcher (server), little-endian */ \ \ - /* 7471 - accepts header list, */ \ + /* 7488 - accepts header list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1754,7 +1764,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 7725 - supported streaming types, */ \ + /* 7742 - supported streaming types, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1772,7 +1782,7 @@ \ /* Endpoint: 1, Cluster: Audio Output (server), little-endian */ \ \ - /* 7979 - audio output list, */ \ + /* 7996 - audio output list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1790,7 +1800,7 @@ \ /* Endpoint: 1, Cluster: Application Launcher (server), little-endian */ \ \ - /* 8233 - application launcher list, */ \ + /* 8250 - application launcher list, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1808,45 +1818,45 @@ \ /* Endpoint: 1, Cluster: Application Basic (server), little-endian */ \ \ - /* 8487 - vendor name, */ \ + /* 8504 - vendor name, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 8520 - application name, */ \ + /* 8537 - application name, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 8553 - application id, */ \ + /* 8570 - application id, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 1, Cluster: Test Cluster (server), little-endian */ \ \ - /* 8586 - bitmap32, */ \ + /* 8603 - bitmap32, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 8590 - bitmap64, */ \ + /* 8607 - bitmap64, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 8598 - int32u, */ \ + /* 8615 - int32u, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 8602 - int64u, */ \ + /* 8619 - int64u, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 8610 - int32s, */ \ + /* 8627 - int32s, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 8614 - int64s, */ \ + /* 8631 - int64s, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 8622 - octet_string, */ \ + /* 8639 - octet_string, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 8633 - list_int8u, */ \ + /* 8650 - list_int8u, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 8643 - list_octet_string, */ \ + /* 8660 - list_octet_string, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1862,7 +1872,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 8897 - list_struct_octet_string, */ \ + /* 8914 - list_struct_octet_string, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1878,7 +1888,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 9151 - long_octet_string, */ \ + /* 9168 - long_octet_string, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1933,10 +1943,10 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 10153 - char_string, */ \ + /* 10170 - char_string, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ \ - /* 10164 - long_char_string, */ \ + /* 10181 - long_char_string, */ \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -1993,21 +2003,21 @@ \ /* Endpoint: 1, Cluster: Electrical Measurement (server), little-endian */ \ \ - /* 11166 - measurement type, */ \ + /* 11183 - measurement type, */ \ 0x00, 0x00, 0x00, 0x00, \ \ - /* 11170 - total active power, */ \ + /* 11187 - total active power, */ \ 0x00, 0x00, 0x00, 0x00, \ \ /* Endpoint: 2, Cluster: On/Off (server), little-endian */ \ \ - /* 11174 - FeatureMap, */ \ + /* 11191 - FeatureMap, */ \ 0x00, 0x00, 0x00, 0x00, \ } #endif // BIGENDIAN_CPU -#define GENERATED_DEFAULTS_COUNT (130) +#define GENERATED_DEFAULTS_COUNT (131) #define ZAP_TYPE(type) ZCL_##type##_ATTRIBUTE_TYPE #define ZAP_LONG_DEFAULTS_INDEX(index) \ @@ -2035,7 +2045,7 @@ #define ZAP_ATTRIBUTE_MASK(mask) ATTRIBUTE_MASK_##mask // This is an array of EmberAfAttributeMetadata structures. -#define GENERATED_ATTRIBUTE_COUNT 400 +#define GENERATED_ATTRIBUTE_COUNT 403 #define GENERATED_ATTRIBUTES \ { \ \ @@ -2078,35 +2088,41 @@ /* Endpoint: 0, Cluster: OTA Software Update Provider (server) */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ + /* Endpoint: 0, Cluster: OTA Software Update Requestor (server) */ \ + { 0x0001, ZAP_TYPE(OCTET_STRING), 17, ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_LONG_DEFAULTS_INDEX(1654) }, /* default ota provider */ \ + { 0x0002, ZAP_TYPE(BOOLEAN), 1, 0, ZAP_EMPTY_DEFAULT() }, /* update possible */ \ + { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ /* Endpoint: 0, Cluster: General Commissioning (server) */ \ - { 0x0000, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(1654) }, /* Breadcrumb */ \ - { 0x0001, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(1662) }, /* BasicCommissioningInfoList */ \ + { 0x0000, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(1671) }, /* Breadcrumb */ \ + { 0x0001, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(1679) }, /* BasicCommissioningInfoList */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 0, Cluster: Network Commissioning (server) */ \ - { 0xFFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_LONG_DEFAULTS_INDEX(1916) }, /* FeatureMap */ \ + { 0xFFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_LONG_DEFAULTS_INDEX(1933) }, /* FeatureMap */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 0, Cluster: General Diagnostics (server) */ \ - { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(1920) }, /* NetworkInterfaces */ \ + { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(1937) }, /* NetworkInterfaces */ \ { 0x0001, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0000) }, /* RebootCount */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 0, Cluster: Software Diagnostics (server) */ \ - { 0x0003, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2174) }, /* CurrentHeapHighWatermark */ \ + { 0x0003, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2191) }, /* CurrentHeapHighWatermark */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 0, Cluster: Thread Network Diagnostics (server) */ \ { 0x0000, ZAP_TYPE(INT8U), 1, 0, ZAP_EMPTY_DEFAULT() }, /* channel */ \ { 0x0001, ZAP_TYPE(ENUM8), 1, 0, ZAP_EMPTY_DEFAULT() }, /* RoutingRole */ \ - { 0x0002, ZAP_TYPE(OCTET_STRING), 17, 0, ZAP_LONG_DEFAULTS_INDEX(2182) }, /* NetworkName */ \ + { 0x0002, ZAP_TYPE(OCTET_STRING), 17, 0, ZAP_LONG_DEFAULTS_INDEX(2199) }, /* NetworkName */ \ { 0x0003, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0000) }, /* PanId */ \ - { 0x0004, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2199) }, /* ExtendedPanId */ \ - { 0x0005, ZAP_TYPE(OCTET_STRING), 18, 0, ZAP_LONG_DEFAULTS_INDEX(2207) }, /* MeshLocalPrefix */ \ - { 0x0006, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2225) }, /* OverrunCount */ \ - { 0x0007, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(2233) }, /* NeighborTableList */ \ - { 0x0008, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(2487) }, /* RouteTableList */ \ - { 0x0009, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2741) }, /* PartitionId */ \ + { 0x0004, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2216) }, /* ExtendedPanId */ \ + { 0x0005, ZAP_TYPE(OCTET_STRING), 18, 0, ZAP_LONG_DEFAULTS_INDEX(2224) }, /* MeshLocalPrefix */ \ + { 0x0006, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2242) }, /* OverrunCount */ \ + { 0x0007, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(2250) }, /* NeighborTableList */ \ + { 0x0008, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(2504) }, /* RouteTableList */ \ + { 0x0009, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2758) }, /* PartitionId */ \ { 0x000A, ZAP_TYPE(INT8U), 1, 0, ZAP_EMPTY_DEFAULT() }, /* weighting */ \ { 0x000B, ZAP_TYPE(INT8U), 1, 0, ZAP_EMPTY_DEFAULT() }, /* DataVersion */ \ { 0x000C, ZAP_TYPE(INT8U), 1, 0, ZAP_EMPTY_DEFAULT() }, /* StableDataVersion */ \ @@ -2119,77 +2135,77 @@ { 0x0013, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0000) }, /* PartitionIdChangeCount */ \ { 0x0014, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0000) }, /* BetterPartitionAttachAttemptCount */ \ { 0x0015, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0000) }, /* ParentChangeCount */ \ - { 0x0016, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2745) }, /* TxTotalCount */ \ - { 0x0017, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2749) }, /* TxUnicastCount */ \ - { 0x0018, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2753) }, /* TxBroadcastCount */ \ - { 0x0019, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2757) }, /* TxAckRequestedCount */ \ - { 0x001A, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2761) }, /* TxAckedCount */ \ - { 0x001B, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2765) }, /* TxNoAckRequestedCount */ \ - { 0x001C, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2769) }, /* TxDataCount */ \ - { 0x001D, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2773) }, /* TxDataPollCount */ \ - { 0x001E, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2777) }, /* TxBeaconCount */ \ - { 0x001F, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2781) }, /* TxBeaconRequestCount */ \ - { 0x0020, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2785) }, /* TxOtherCount */ \ - { 0x0021, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2789) }, /* TxRetryCount */ \ - { 0x0022, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2793) }, /* TxDirectMaxRetryExpiryCount */ \ - { 0x0023, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2797) }, /* TxIndirectMaxRetryExpiryCount */ \ - { 0x0024, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2801) }, /* TxErrCcaCount */ \ - { 0x0025, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2805) }, /* TxErrAbortCount */ \ - { 0x0026, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2809) }, /* TxErrBusyChannelCount */ \ - { 0x0027, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2813) }, /* RxTotalCount */ \ - { 0x0028, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2817) }, /* RxUnicastCount */ \ - { 0x0029, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2821) }, /* RxBroadcastCount */ \ - { 0x002A, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2825) }, /* RxDataCount */ \ - { 0x002B, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2829) }, /* RxDataPollCount */ \ - { 0x002C, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2833) }, /* RxBeaconCount */ \ - { 0x002D, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2837) }, /* RxBeaconRequestCount */ \ - { 0x002E, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2841) }, /* RxOtherCount */ \ - { 0x002F, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2845) }, /* RxAddressFilteredCount */ \ - { 0x0030, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2849) }, /* RxDestAddrFilteredCount */ \ - { 0x0031, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2853) }, /* RxDuplicatedCount */ \ - { 0x0032, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2857) }, /* RxErrNoFrameCount */ \ - { 0x0033, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2861) }, /* RxErrUnknownNeighborCount */ \ - { 0x0034, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2865) }, /* RxErrInvalidSrcAddrCount */ \ - { 0x0035, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2869) }, /* RxErrSecCount */ \ - { 0x0036, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2873) }, /* RxErrFcsCount */ \ - { 0x0037, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2877) }, /* RxErrOtherCount */ \ - { 0x003B, ZAP_TYPE(ARRAY), 5, 0, ZAP_LONG_DEFAULTS_INDEX(2881) }, /* SecurityPolicy */ \ + { 0x0016, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2762) }, /* TxTotalCount */ \ + { 0x0017, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2766) }, /* TxUnicastCount */ \ + { 0x0018, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2770) }, /* TxBroadcastCount */ \ + { 0x0019, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2774) }, /* TxAckRequestedCount */ \ + { 0x001A, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2778) }, /* TxAckedCount */ \ + { 0x001B, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2782) }, /* TxNoAckRequestedCount */ \ + { 0x001C, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2786) }, /* TxDataCount */ \ + { 0x001D, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2790) }, /* TxDataPollCount */ \ + { 0x001E, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2794) }, /* TxBeaconCount */ \ + { 0x001F, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2798) }, /* TxBeaconRequestCount */ \ + { 0x0020, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2802) }, /* TxOtherCount */ \ + { 0x0021, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2806) }, /* TxRetryCount */ \ + { 0x0022, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2810) }, /* TxDirectMaxRetryExpiryCount */ \ + { 0x0023, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2814) }, /* TxIndirectMaxRetryExpiryCount */ \ + { 0x0024, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2818) }, /* TxErrCcaCount */ \ + { 0x0025, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2822) }, /* TxErrAbortCount */ \ + { 0x0026, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2826) }, /* TxErrBusyChannelCount */ \ + { 0x0027, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2830) }, /* RxTotalCount */ \ + { 0x0028, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2834) }, /* RxUnicastCount */ \ + { 0x0029, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2838) }, /* RxBroadcastCount */ \ + { 0x002A, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2842) }, /* RxDataCount */ \ + { 0x002B, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2846) }, /* RxDataPollCount */ \ + { 0x002C, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2850) }, /* RxBeaconCount */ \ + { 0x002D, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2854) }, /* RxBeaconRequestCount */ \ + { 0x002E, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2858) }, /* RxOtherCount */ \ + { 0x002F, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2862) }, /* RxAddressFilteredCount */ \ + { 0x0030, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2866) }, /* RxDestAddrFilteredCount */ \ + { 0x0031, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2870) }, /* RxDuplicatedCount */ \ + { 0x0032, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2874) }, /* RxErrNoFrameCount */ \ + { 0x0033, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2878) }, /* RxErrUnknownNeighborCount */ \ + { 0x0034, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2882) }, /* RxErrInvalidSrcAddrCount */ \ + { 0x0035, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2886) }, /* RxErrSecCount */ \ + { 0x0036, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2890) }, /* RxErrFcsCount */ \ + { 0x0037, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2894) }, /* RxErrOtherCount */ \ + { 0x003B, ZAP_TYPE(ARRAY), 5, 0, ZAP_LONG_DEFAULTS_INDEX(2898) }, /* SecurityPolicy */ \ { 0x003C, ZAP_TYPE(INT8U), 1, 0, ZAP_SIMPLE_DEFAULT(0x0000) }, /* ChannelMask */ \ - { 0x003D, ZAP_TYPE(ARRAY), 14, 0, ZAP_LONG_DEFAULTS_INDEX(2886) }, /* OperationalDatasetComponents */ \ - { 0x003E, ZAP_TYPE(ARRAY), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2900) }, /* ActiveNetworkFaultsList */ \ + { 0x003D, ZAP_TYPE(ARRAY), 14, 0, ZAP_LONG_DEFAULTS_INDEX(2903) }, /* OperationalDatasetComponents */ \ + { 0x003E, ZAP_TYPE(ARRAY), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2917) }, /* ActiveNetworkFaultsList */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 0, Cluster: WiFi Network Diagnostics (server) */ \ - { 0x0000, ZAP_TYPE(OCTET_STRING), 7, 0, ZAP_LONG_DEFAULTS_INDEX(2904) }, /* bssid */ \ + { 0x0000, ZAP_TYPE(OCTET_STRING), 7, 0, ZAP_LONG_DEFAULTS_INDEX(2921) }, /* bssid */ \ { 0x0001, ZAP_TYPE(ENUM8), 1, 0, ZAP_EMPTY_DEFAULT() }, /* SecurityType */ \ { 0x0002, ZAP_TYPE(ENUM8), 1, 0, ZAP_EMPTY_DEFAULT() }, /* WiFiVersion */ \ { 0x0003, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0000) }, /* ChannelNumber */ \ { 0x0004, ZAP_TYPE(INT8S), 1, 0, ZAP_SIMPLE_DEFAULT(0x00) }, /* Rssi */ \ - { 0x0005, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2911) }, /* BeaconLostCount */ \ - { 0x0006, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2915) }, /* BeaconRxCount */ \ - { 0x0007, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2919) }, /* PacketMulticastRxCount */ \ - { 0x0008, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2923) }, /* PacketMulticastTxCount */ \ - { 0x0009, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2927) }, /* PacketUnicastRxCount */ \ - { 0x000A, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2931) }, /* PacketUnicastTxCount */ \ - { 0x000B, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2935) }, /* CurrentMaxRate */ \ + { 0x0005, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2928) }, /* BeaconLostCount */ \ + { 0x0006, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2932) }, /* BeaconRxCount */ \ + { 0x0007, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2936) }, /* PacketMulticastRxCount */ \ + { 0x0008, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2940) }, /* PacketMulticastTxCount */ \ + { 0x0009, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2944) }, /* PacketUnicastRxCount */ \ + { 0x000A, ZAP_TYPE(INT32U), 4, 0, ZAP_LONG_DEFAULTS_INDEX(2948) }, /* PacketUnicastTxCount */ \ + { 0x000B, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2952) }, /* CurrentMaxRate */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 0, Cluster: Ethernet Network Diagnostics (server) */ \ - { 0x0002, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2943) }, /* PacketRxCount */ \ - { 0x0003, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2951) }, /* PacketTxCount */ \ - { 0x0004, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2959) }, /* TxErrCount */ \ - { 0x0005, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2967) }, /* CollisionCount */ \ - { 0x0006, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2975) }, /* OverrunCount */ \ + { 0x0002, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2960) }, /* PacketRxCount */ \ + { 0x0003, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2968) }, /* PacketTxCount */ \ + { 0x0004, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2976) }, /* TxErrCount */ \ + { 0x0005, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2984) }, /* CollisionCount */ \ + { 0x0006, ZAP_TYPE(INT64U), 8, 0, ZAP_LONG_DEFAULTS_INDEX(2992) }, /* OverrunCount */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 0, Cluster: AdministratorCommissioning (server) */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 0, Cluster: Operational Credentials (server) */ \ - { 0x0001, ZAP_TYPE(ARRAY), 320, 0, ZAP_LONG_DEFAULTS_INDEX(2983) }, /* fabrics list */ \ + { 0x0001, ZAP_TYPE(ARRAY), 320, 0, ZAP_LONG_DEFAULTS_INDEX(3000) }, /* fabrics list */ \ { 0x0002, ZAP_TYPE(INT8U), 1, 0, ZAP_EMPTY_DEFAULT() }, /* SupportedFabrics */ \ { 0x0003, ZAP_TYPE(INT8U), 1, 0, ZAP_EMPTY_DEFAULT() }, /* CommissionedFabrics */ \ - { 0x0004, ZAP_TYPE(ARRAY), 400, 0, ZAP_LONG_DEFAULTS_INDEX(3303) }, /* TrustedRootCertificates */ \ + { 0x0004, ZAP_TYPE(ARRAY), 400, 0, ZAP_LONG_DEFAULTS_INDEX(3320) }, /* TrustedRootCertificates */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 0, Cluster: Relative Humidity Measurement (server) */ \ @@ -2202,8 +2218,8 @@ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 0, Cluster: Group Key Management (server) */ \ - { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(3703) }, /* groups */ \ - { 0x0001, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(3957) }, /* group keys */ \ + { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(3720) }, /* groups */ \ + { 0x0001, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(3974) }, /* group keys */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Identify (server) */ \ @@ -2228,7 +2244,7 @@ { 0x4001, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0x0000) }, /* OnTime */ \ { 0x4002, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0x0000) }, /* OffWaitTime */ \ { 0x4003, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_EMPTY_DEFAULT() }, /* StartUpOnOff */ \ - { 0xFFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_LONG_DEFAULTS_INDEX(4211) }, /* FeatureMap */ \ + { 0xFFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_LONG_DEFAULTS_INDEX(4228) }, /* FeatureMap */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(3) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: On/off Switch Configuration (server) */ \ @@ -2250,32 +2266,32 @@ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Descriptor (server) */ \ - { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(4215) }, /* device list */ \ - { 0x0001, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(4469) }, /* server list */ \ - { 0x0002, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(4723) }, /* client list */ \ - { 0x0003, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(4977) }, /* parts list */ \ + { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(4232) }, /* device list */ \ + { 0x0001, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(4486) }, /* server list */ \ + { 0x0002, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(4740) }, /* client list */ \ + { 0x0003, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(4994) }, /* parts list */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Bridged Device Basic (server) */ \ - { 0x0001, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_LONG_DEFAULTS_INDEX(5231) }, /* VendorName */ \ + { 0x0001, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_LONG_DEFAULTS_INDEX(5248) }, /* VendorName */ \ { 0x0002, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_EMPTY_DEFAULT() }, /* VendorID */ \ - { 0x0003, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_LONG_DEFAULTS_INDEX(5264) }, /* ProductName */ \ + { 0x0003, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_LONG_DEFAULTS_INDEX(5281) }, /* ProductName */ \ { 0x0005, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(SINGLETON) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ - ZAP_LONG_DEFAULTS_INDEX(5297) }, /* UserLabel */ \ + ZAP_LONG_DEFAULTS_INDEX(5314) }, /* UserLabel */ \ { 0x0007, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_SIMPLE_DEFAULT(0x00) }, /* HardwareVersion */ \ { 0x0008, ZAP_TYPE(CHAR_STRING), 65, ZAP_ATTRIBUTE_MASK(SINGLETON), \ - ZAP_LONG_DEFAULTS_INDEX(5330) }, /* HardwareVersionString */ \ - { 0x0009, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_LONG_DEFAULTS_INDEX(5395) }, /* SoftwareVersion */ \ + ZAP_LONG_DEFAULTS_INDEX(5347) }, /* HardwareVersionString */ \ + { 0x0009, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_LONG_DEFAULTS_INDEX(5412) }, /* SoftwareVersion */ \ { 0x000A, ZAP_TYPE(CHAR_STRING), 65, ZAP_ATTRIBUTE_MASK(SINGLETON), \ - ZAP_LONG_DEFAULTS_INDEX(5399) }, /* SoftwareVersionString */ \ + ZAP_LONG_DEFAULTS_INDEX(5416) }, /* SoftwareVersionString */ \ { 0x000B, ZAP_TYPE(CHAR_STRING), 17, ZAP_ATTRIBUTE_MASK(SINGLETON), \ - ZAP_LONG_DEFAULTS_INDEX(5464) }, /* ManufacturingDate */ \ - { 0x000C, ZAP_TYPE(CHAR_STRING), 255, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_LONG_DEFAULTS_INDEX(5481) }, /* PartNumber */ \ - { 0x000D, ZAP_TYPE(CHAR_STRING), 255, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_LONG_DEFAULTS_INDEX(5736) }, /* ProductURL */ \ + ZAP_LONG_DEFAULTS_INDEX(5481) }, /* ManufacturingDate */ \ + { 0x000C, ZAP_TYPE(CHAR_STRING), 255, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_LONG_DEFAULTS_INDEX(5498) }, /* PartNumber */ \ + { 0x000D, ZAP_TYPE(CHAR_STRING), 255, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_LONG_DEFAULTS_INDEX(5753) }, /* ProductURL */ \ { 0x000E, ZAP_TYPE(CHAR_STRING), 65, ZAP_ATTRIBUTE_MASK(SINGLETON), \ - ZAP_LONG_DEFAULTS_INDEX(5991) }, /* ProductLabel */ \ + ZAP_LONG_DEFAULTS_INDEX(6008) }, /* ProductLabel */ \ { 0x000F, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(SINGLETON), \ - ZAP_LONG_DEFAULTS_INDEX(6056) }, /* SerialNumber */ \ + ZAP_LONG_DEFAULTS_INDEX(6073) }, /* SerialNumber */ \ { 0x0011, ZAP_TYPE(BOOLEAN), 1, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_SIMPLE_DEFAULT(0x00) }, /* Reachable */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ \ @@ -2285,7 +2301,7 @@ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Fixed Label (server) */ \ - { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(6089) }, /* label list */ \ + { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(6106) }, /* label list */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Door Lock (server) */ \ @@ -2356,7 +2372,7 @@ { 0x0020, ZAP_TYPE(ENUM8), 1, 0, ZAP_SIMPLE_DEFAULT(0) }, /* start of week */ \ { 0x0021, ZAP_TYPE(INT8U), 1, 0, ZAP_SIMPLE_DEFAULT(7) }, /* number of weekly transitions */ \ { 0x0022, ZAP_TYPE(INT8U), 1, 0, ZAP_SIMPLE_DEFAULT(4) }, /* number of daily transitions */ \ - { 0xFFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_LONG_DEFAULTS_INDEX(6343) }, /* FeatureMap */ \ + { 0xFFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_LONG_DEFAULTS_INDEX(6360) }, /* FeatureMap */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(3) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Thermostat User Interface Configuration (server) */ \ @@ -2373,7 +2389,7 @@ { 0x0003, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x616B) }, /* current x */ \ { 0x0004, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x607D) }, /* current y */ \ { 0x0005, ZAP_TYPE(ENUM8), 1, 0, ZAP_EMPTY_DEFAULT() }, /* drift compensation */ \ - { 0x0006, ZAP_TYPE(CHAR_STRING), 255, 0, ZAP_LONG_DEFAULTS_INDEX(6347) }, /* compensation text */ \ + { 0x0006, ZAP_TYPE(CHAR_STRING), 255, 0, ZAP_LONG_DEFAULTS_INDEX(6364) }, /* compensation text */ \ { 0x0007, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x00FA) }, /* color temperature */ \ { 0x0008, ZAP_TYPE(ENUM8), 1, 0, ZAP_SIMPLE_DEFAULT(0x01) }, /* color mode */ \ { 0x000F, ZAP_TYPE(BITMAP8), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0x00) }, /* color control options */ \ @@ -2456,29 +2472,29 @@ { 0x0000, ZAP_TYPE(ENUM8), 1, 0, ZAP_SIMPLE_DEFAULT(0x00) }, /* zone state */ \ { 0x0001, ZAP_TYPE(ENUM16), 2, 0, ZAP_EMPTY_DEFAULT() }, /* zone type */ \ { 0x0002, ZAP_TYPE(BITMAP16), 2, 0, ZAP_SIMPLE_DEFAULT(0x0000) }, /* zone status */ \ - { 0x0010, ZAP_TYPE(NODE_ID), 8, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(6602) }, /* IAS CIE address */ \ + { 0x0010, ZAP_TYPE(NODE_ID), 8, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(6619) }, /* IAS CIE address */ \ { 0x0011, ZAP_TYPE(INT8U), 1, 0, ZAP_SIMPLE_DEFAULT(0xff) }, /* Zone ID */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(2) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Wake on LAN (server) */ \ - { 0x0000, ZAP_TYPE(CHAR_STRING), 33, 0, ZAP_LONG_DEFAULTS_INDEX(6610) }, /* wake on lan mac address */ \ + { 0x0000, ZAP_TYPE(CHAR_STRING), 33, 0, ZAP_LONG_DEFAULTS_INDEX(6627) }, /* wake on lan mac address */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: TV Channel (server) */ \ - { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(6643) }, /* tv channel list */ \ - { 0x0001, ZAP_TYPE(OCTET_STRING), 33, 0, ZAP_LONG_DEFAULTS_INDEX(6897) }, /* tv channel lineup */ \ - { 0x0002, ZAP_TYPE(OCTET_STRING), 33, 0, ZAP_LONG_DEFAULTS_INDEX(6930) }, /* current tv channel */ \ + { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(6660) }, /* tv channel list */ \ + { 0x0001, ZAP_TYPE(OCTET_STRING), 33, 0, ZAP_LONG_DEFAULTS_INDEX(6914) }, /* tv channel lineup */ \ + { 0x0002, ZAP_TYPE(OCTET_STRING), 33, 0, ZAP_LONG_DEFAULTS_INDEX(6947) }, /* current tv channel */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Target Navigator (server) */ \ - { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(6963) }, /* target navigator list */ \ + { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(6980) }, /* target navigator list */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Media Playback (server) */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Media Input (server) */ \ - { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(7217) }, /* media input list */ \ + { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(7234) }, /* media input list */ \ { 0x0001, ZAP_TYPE(INT8U), 1, 0, ZAP_SIMPLE_DEFAULT(0x00) }, /* current media input */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ @@ -2489,27 +2505,27 @@ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Content Launcher (server) */ \ - { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(7471) }, /* accepts header list */ \ - { 0x0001, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(7725) }, /* supported streaming types */ \ + { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(7488) }, /* accepts header list */ \ + { 0x0001, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(7742) }, /* supported streaming types */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Audio Output (server) */ \ - { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(7979) }, /* audio output list */ \ + { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(7996) }, /* audio output list */ \ { 0x0001, ZAP_TYPE(INT8U), 1, 0, ZAP_SIMPLE_DEFAULT(0x00) }, /* current audio output */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Application Launcher (server) */ \ - { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(8233) }, /* application launcher list */ \ + { 0x0000, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(8250) }, /* application launcher list */ \ { 0x0001, ZAP_TYPE(INT8U), 1, 0, ZAP_SIMPLE_DEFAULT(0x00) }, /* catalog vendor id */ \ { 0x0002, ZAP_TYPE(INT8U), 1, 0, ZAP_SIMPLE_DEFAULT(0x00) }, /* application id */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Application Basic (server) */ \ - { 0x0000, ZAP_TYPE(CHAR_STRING), 33, 0, ZAP_LONG_DEFAULTS_INDEX(8487) }, /* vendor name */ \ + { 0x0000, ZAP_TYPE(CHAR_STRING), 33, 0, ZAP_LONG_DEFAULTS_INDEX(8504) }, /* vendor name */ \ { 0x0001, ZAP_TYPE(INT16U), 2, 0, ZAP_EMPTY_DEFAULT() }, /* vendor id */ \ - { 0x0002, ZAP_TYPE(CHAR_STRING), 33, 0, ZAP_LONG_DEFAULTS_INDEX(8520) }, /* application name */ \ + { 0x0002, ZAP_TYPE(CHAR_STRING), 33, 0, ZAP_LONG_DEFAULTS_INDEX(8537) }, /* application name */ \ { 0x0003, ZAP_TYPE(INT16U), 2, 0, ZAP_EMPTY_DEFAULT() }, /* product id */ \ - { 0x0005, ZAP_TYPE(CHAR_STRING), 33, 0, ZAP_LONG_DEFAULTS_INDEX(8553) }, /* application id */ \ + { 0x0005, ZAP_TYPE(CHAR_STRING), 33, 0, ZAP_LONG_DEFAULTS_INDEX(8570) }, /* application id */ \ { 0x0006, ZAP_TYPE(INT16U), 2, 0, ZAP_EMPTY_DEFAULT() }, /* catalog vendor id */ \ { 0x0007, ZAP_TYPE(ENUM8), 1, 0, ZAP_SIMPLE_DEFAULT(0x01) }, /* application status */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ @@ -2521,33 +2537,33 @@ { 0x0000, ZAP_TYPE(BOOLEAN), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(false) }, /* boolean */ \ { 0x0001, ZAP_TYPE(BITMAP8), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0) }, /* bitmap8 */ \ { 0x0002, ZAP_TYPE(BITMAP16), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0) }, /* bitmap16 */ \ - { 0x0003, ZAP_TYPE(BITMAP32), 4, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(8586) }, /* bitmap32 */ \ - { 0x0004, ZAP_TYPE(BITMAP64), 8, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(8590) }, /* bitmap64 */ \ + { 0x0003, ZAP_TYPE(BITMAP32), 4, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(8603) }, /* bitmap32 */ \ + { 0x0004, ZAP_TYPE(BITMAP64), 8, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(8607) }, /* bitmap64 */ \ { 0x0005, ZAP_TYPE(INT8U), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0) }, /* int8u */ \ { 0x0006, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0) }, /* int16u */ \ - { 0x0008, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(8598) }, /* int32u */ \ - { 0x000C, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(8602) }, /* int64u */ \ + { 0x0008, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(8615) }, /* int32u */ \ + { 0x000C, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(8619) }, /* int64u */ \ { 0x000D, ZAP_TYPE(INT8S), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0) }, /* int8s */ \ { 0x000E, ZAP_TYPE(INT16S), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0) }, /* int16s */ \ - { 0x0010, ZAP_TYPE(INT32S), 4, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(8610) }, /* int32s */ \ - { 0x0014, ZAP_TYPE(INT64S), 8, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(8614) }, /* int64s */ \ + { 0x0010, ZAP_TYPE(INT32S), 4, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(8627) }, /* int32s */ \ + { 0x0014, ZAP_TYPE(INT64S), 8, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(8631) }, /* int64s */ \ { 0x0015, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0) }, /* enum8 */ \ { 0x0016, ZAP_TYPE(ENUM16), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0) }, /* enum16 */ \ { 0x0019, ZAP_TYPE(OCTET_STRING), 11, ZAP_ATTRIBUTE_MASK(WRITABLE), \ - ZAP_LONG_DEFAULTS_INDEX(8622) }, /* octet_string */ \ - { 0x001A, ZAP_TYPE(ARRAY), 10, 0, ZAP_LONG_DEFAULTS_INDEX(8633) }, /* list_int8u */ \ - { 0x001B, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(8643) }, /* list_octet_string */ \ - { 0x001C, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(8897) }, /* list_struct_octet_string */ \ + ZAP_LONG_DEFAULTS_INDEX(8639) }, /* octet_string */ \ + { 0x001A, ZAP_TYPE(ARRAY), 10, 0, ZAP_LONG_DEFAULTS_INDEX(8650) }, /* list_int8u */ \ + { 0x001B, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(8660) }, /* list_octet_string */ \ + { 0x001C, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(8914) }, /* list_struct_octet_string */ \ { 0x001D, ZAP_TYPE(LONG_OCTET_STRING), 1002, ZAP_ATTRIBUTE_MASK(WRITABLE), \ - ZAP_LONG_DEFAULTS_INDEX(9151) }, /* long_octet_string */ \ - { 0x001E, ZAP_TYPE(CHAR_STRING), 11, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(10153) }, /* char_string */ \ + ZAP_LONG_DEFAULTS_INDEX(9168) }, /* long_octet_string */ \ + { 0x001E, ZAP_TYPE(CHAR_STRING), 11, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(10170) }, /* char_string */ \ { 0x001F, ZAP_TYPE(LONG_CHAR_STRING), 1002, ZAP_ATTRIBUTE_MASK(WRITABLE), \ - ZAP_LONG_DEFAULTS_INDEX(10164) }, /* long_char_string */ \ + ZAP_LONG_DEFAULTS_INDEX(10181) }, /* long_char_string */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: Electrical Measurement (server) */ \ - { 0x0000, ZAP_TYPE(BITMAP32), 4, 0, ZAP_LONG_DEFAULTS_INDEX(11166) }, /* measurement type */ \ - { 0x0304, ZAP_TYPE(INT32S), 4, 0, ZAP_LONG_DEFAULTS_INDEX(11170) }, /* total active power */ \ + { 0x0000, ZAP_TYPE(BITMAP32), 4, 0, ZAP_LONG_DEFAULTS_INDEX(11183) }, /* measurement type */ \ + { 0x0304, ZAP_TYPE(INT32S), 4, 0, ZAP_LONG_DEFAULTS_INDEX(11187) }, /* total active power */ \ { 0x0505, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0xffff) }, /* rms voltage */ \ { 0x0506, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x8000) }, /* rms voltage min */ \ { 0x0507, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x8000) }, /* rms voltage max */ \ @@ -2568,7 +2584,7 @@ { 0x4001, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0) }, /* OnTime */ \ { 0x4002, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0) }, /* OffWaitTime */ \ { 0x4003, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_EMPTY_DEFAULT() }, /* StartUpOnOff */ \ - { 0xFFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_LONG_DEFAULTS_INDEX(11174) }, /* FeatureMap */ \ + { 0xFFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_LONG_DEFAULTS_INDEX(11191) }, /* FeatureMap */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(2) }, /* ClusterRevision */ \ \ /* Endpoint: 2, Cluster: Occupancy Sensing (server) */ \ @@ -2622,7 +2638,7 @@ }; #define ZAP_CLUSTER_MASK(mask) CLUSTER_MASK_##mask -#define GENERATED_CLUSTER_COUNT 57 +#define GENERATED_CLUSTER_COUNT 58 #define GENERATED_CLUSTERS \ { \ { \ @@ -2638,202 +2654,205 @@ 0x0029, ZAP_ATTRIBUTE_INDEX(24), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: OTA Software Update Provider (server) */ \ { \ - 0x0030, ZAP_ATTRIBUTE_INDEX(25), 3, 264, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x002A, ZAP_ATTRIBUTE_INDEX(25), 3, 20, ZAP_CLUSTER_MASK(SERVER), NULL \ + }, /* Endpoint: 0, Cluster: OTA Software Update Requestor (server) */ \ + { \ + 0x0030, ZAP_ATTRIBUTE_INDEX(28), 3, 264, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: General Commissioning (server) */ \ { \ - 0x0031, ZAP_ATTRIBUTE_INDEX(28), 2, 6, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0031, ZAP_ATTRIBUTE_INDEX(31), 2, 6, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Network Commissioning (server) */ \ { \ - 0x0032, ZAP_ATTRIBUTE_INDEX(30), 0, 0, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0032, ZAP_ATTRIBUTE_INDEX(33), 0, 0, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Diagnostic Logs (server) */ \ { \ - 0x0033, ZAP_ATTRIBUTE_INDEX(30), 3, 258, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0033, ZAP_ATTRIBUTE_INDEX(33), 3, 258, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: General Diagnostics (server) */ \ { \ - 0x0034, ZAP_ATTRIBUTE_INDEX(33), 2, 10, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0034, ZAP_ATTRIBUTE_INDEX(36), 2, 10, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Software Diagnostics (server) */ \ { \ - 0x0035, ZAP_ATTRIBUTE_INDEX(35), 61, 749, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0035, ZAP_ATTRIBUTE_INDEX(38), 61, 749, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Thread Network Diagnostics (server) */ \ { \ - 0x0036, ZAP_ATTRIBUTE_INDEX(96), 13, 46, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0036, ZAP_ATTRIBUTE_INDEX(99), 13, 46, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: WiFi Network Diagnostics (server) */ \ { \ - 0x0037, ZAP_ATTRIBUTE_INDEX(109), 6, 42, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0037, ZAP_ATTRIBUTE_INDEX(112), 6, 42, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Ethernet Network Diagnostics (server) */ \ { \ - 0x003C, ZAP_ATTRIBUTE_INDEX(115), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x003C, ZAP_ATTRIBUTE_INDEX(118), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: AdministratorCommissioning (server) */ \ { \ - 0x003E, ZAP_ATTRIBUTE_INDEX(116), 5, 724, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x003E, ZAP_ATTRIBUTE_INDEX(119), 5, 724, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Operational Credentials (server) */ \ { \ - 0x0405, ZAP_ATTRIBUTE_INDEX(121), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0405, ZAP_ATTRIBUTE_INDEX(124), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Relative Humidity Measurement (server) */ \ { \ - 0xF000, ZAP_ATTRIBUTE_INDEX(125), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0xF000, ZAP_ATTRIBUTE_INDEX(128), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Binding (server) */ \ { \ - 0xF004, ZAP_ATTRIBUTE_INDEX(126), 3, 510, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0xF004, ZAP_ATTRIBUTE_INDEX(129), 3, 510, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Group Key Management (server) */ \ { 0x0003, \ - ZAP_ATTRIBUTE_INDEX(129), \ + ZAP_ATTRIBUTE_INDEX(132), \ 2, \ 4, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(ATTRIBUTE_CHANGED_FUNCTION), \ chipFuncArrayIdentifyServer }, /* Endpoint: 1, Cluster: Identify (server) */ \ { 0x0004, \ - ZAP_ATTRIBUTE_INDEX(131), \ + ZAP_ATTRIBUTE_INDEX(134), \ 2, \ 3, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayGroupsServer }, /* Endpoint: 1, Cluster: Groups (server) */ \ { 0x0005, \ - ZAP_ATTRIBUTE_INDEX(133), \ + ZAP_ATTRIBUTE_INDEX(136), \ 6, \ 8, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayScenesServer }, /* Endpoint: 1, Cluster: Scenes (server) */ \ { 0x0006, \ - ZAP_ATTRIBUTE_INDEX(139), \ + ZAP_ATTRIBUTE_INDEX(142), \ 7, \ 13, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayOnOffServer }, /* Endpoint: 1, Cluster: On/Off (server) */ \ { \ - 0x0007, ZAP_ATTRIBUTE_INDEX(146), 3, 4, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0007, ZAP_ATTRIBUTE_INDEX(149), 3, 4, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: On/off Switch Configuration (server) */ \ { 0x0008, \ - ZAP_ATTRIBUTE_INDEX(149), \ + ZAP_ATTRIBUTE_INDEX(152), \ 5, \ 7, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayLevelControlServer }, /* Endpoint: 1, Cluster: Level Control (server) */ \ { \ - 0x000F, ZAP_ATTRIBUTE_INDEX(154), 4, 5, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x000F, ZAP_ATTRIBUTE_INDEX(157), 4, 5, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Binary Input (Basic) (server) */ \ { \ - 0x001D, ZAP_ATTRIBUTE_INDEX(158), 5, 1018, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x001D, ZAP_ATTRIBUTE_INDEX(161), 5, 1018, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Descriptor (server) */ \ { \ - 0x0039, ZAP_ATTRIBUTE_INDEX(163), 15, 865, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0039, ZAP_ATTRIBUTE_INDEX(166), 15, 865, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Bridged Device Basic (server) */ \ { \ - 0x003B, ZAP_ATTRIBUTE_INDEX(178), 3, 4, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x003B, ZAP_ATTRIBUTE_INDEX(181), 3, 4, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Switch (server) */ \ { \ - 0x0040, ZAP_ATTRIBUTE_INDEX(181), 2, 256, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0040, ZAP_ATTRIBUTE_INDEX(184), 2, 256, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Fixed Label (server) */ \ { 0x0101, \ - ZAP_ATTRIBUTE_INDEX(183), \ + ZAP_ATTRIBUTE_INDEX(186), \ 4, \ 5, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(ATTRIBUTE_CHANGED_FUNCTION), \ chipFuncArrayDoorLockServer }, /* Endpoint: 1, Cluster: Door Lock (server) */ \ { \ - 0x0102, ZAP_ATTRIBUTE_INDEX(187), 19, 31, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0102, ZAP_ATTRIBUTE_INDEX(190), 19, 31, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Window Covering (server) */ \ { \ - 0x0103, ZAP_ATTRIBUTE_INDEX(206), 5, 7, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0103, ZAP_ATTRIBUTE_INDEX(209), 5, 7, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Barrier Control (server) */ \ { \ 0x0200, \ - ZAP_ATTRIBUTE_INDEX(211), \ + ZAP_ATTRIBUTE_INDEX(214), \ 8, \ 13, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(ATTRIBUTE_CHANGED_FUNCTION), \ chipFuncArrayPumpConfigurationAndControlServer \ }, /* Endpoint: 1, Cluster: Pump Configuration and Control (server) */ \ { \ - 0x0201, ZAP_ATTRIBUTE_INDEX(219), 18, 33, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0201, ZAP_ATTRIBUTE_INDEX(222), 18, 33, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Thermostat (server) */ \ { \ - 0x0204, ZAP_ATTRIBUTE_INDEX(237), 4, 5, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0204, ZAP_ATTRIBUTE_INDEX(240), 4, 5, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Thermostat User Interface Configuration (server) */ \ { 0x0300, \ - ZAP_ATTRIBUTE_INDEX(241), \ + ZAP_ATTRIBUTE_INDEX(244), \ 53, \ 341, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayColorControlServer }, /* Endpoint: 1, Cluster: Color Control (server) */ \ { \ - 0x0402, ZAP_ATTRIBUTE_INDEX(294), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0402, ZAP_ATTRIBUTE_INDEX(297), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Temperature Measurement (server) */ \ { \ - 0x0403, ZAP_ATTRIBUTE_INDEX(298), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0403, ZAP_ATTRIBUTE_INDEX(301), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Pressure Measurement (server) */ \ { \ - 0x0404, ZAP_ATTRIBUTE_INDEX(302), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0404, ZAP_ATTRIBUTE_INDEX(305), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Flow Measurement (server) */ \ { \ - 0x0405, ZAP_ATTRIBUTE_INDEX(306), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0405, ZAP_ATTRIBUTE_INDEX(309), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Relative Humidity Measurement (server) */ \ { 0x0406, \ - ZAP_ATTRIBUTE_INDEX(310), \ + ZAP_ATTRIBUTE_INDEX(313), \ 4, \ 5, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayOccupancySensingServer }, /* Endpoint: 1, Cluster: Occupancy Sensing (server) */ \ { 0x0500, \ - ZAP_ATTRIBUTE_INDEX(314), \ + ZAP_ATTRIBUTE_INDEX(317), \ 6, \ 16, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION) | \ ZAP_CLUSTER_MASK(MESSAGE_SENT_FUNCTION), \ chipFuncArrayIasZoneServer }, /* Endpoint: 1, Cluster: IAS Zone (server) */ \ { \ - 0x0503, ZAP_ATTRIBUTE_INDEX(320), 2, 35, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0503, ZAP_ATTRIBUTE_INDEX(323), 2, 35, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Wake on LAN (server) */ \ { \ - 0x0504, ZAP_ATTRIBUTE_INDEX(322), 4, 322, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0504, ZAP_ATTRIBUTE_INDEX(325), 4, 322, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: TV Channel (server) */ \ { \ - 0x0505, ZAP_ATTRIBUTE_INDEX(326), 2, 256, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0505, ZAP_ATTRIBUTE_INDEX(329), 2, 256, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Target Navigator (server) */ \ { \ - 0x0506, ZAP_ATTRIBUTE_INDEX(328), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0506, ZAP_ATTRIBUTE_INDEX(331), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Media Playback (server) */ \ { \ - 0x0507, ZAP_ATTRIBUTE_INDEX(329), 3, 257, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0507, ZAP_ATTRIBUTE_INDEX(332), 3, 257, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Media Input (server) */ \ { \ - 0x0508, ZAP_ATTRIBUTE_INDEX(332), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0508, ZAP_ATTRIBUTE_INDEX(335), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Low Power (server) */ \ { \ - 0x0509, ZAP_ATTRIBUTE_INDEX(333), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0509, ZAP_ATTRIBUTE_INDEX(336), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Keypad Input (server) */ \ { \ - 0x050A, ZAP_ATTRIBUTE_INDEX(334), 3, 510, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050A, ZAP_ATTRIBUTE_INDEX(337), 3, 510, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Content Launcher (server) */ \ { \ - 0x050B, ZAP_ATTRIBUTE_INDEX(337), 3, 257, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050B, ZAP_ATTRIBUTE_INDEX(340), 3, 257, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Audio Output (server) */ \ { \ - 0x050C, ZAP_ATTRIBUTE_INDEX(340), 4, 258, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050C, ZAP_ATTRIBUTE_INDEX(343), 4, 258, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Application Launcher (server) */ \ { \ - 0x050D, ZAP_ATTRIBUTE_INDEX(344), 8, 108, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050D, ZAP_ATTRIBUTE_INDEX(347), 8, 108, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Application Basic (server) */ \ { \ - 0x050E, ZAP_ATTRIBUTE_INDEX(352), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050E, ZAP_ATTRIBUTE_INDEX(355), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Account Login (server) */ \ { \ - 0x050F, ZAP_ATTRIBUTE_INDEX(353), 23, 2595, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050F, ZAP_ATTRIBUTE_INDEX(356), 23, 2595, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Test Cluster (server) */ \ { \ - 0x0B04, ZAP_ATTRIBUTE_INDEX(376), 12, 28, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0B04, ZAP_ATTRIBUTE_INDEX(379), 12, 28, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Electrical Measurement (server) */ \ { \ - 0xF000, ZAP_ATTRIBUTE_INDEX(388), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0xF000, ZAP_ATTRIBUTE_INDEX(391), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Binding (server) */ \ { 0x0006, \ - ZAP_ATTRIBUTE_INDEX(389), \ + ZAP_ATTRIBUTE_INDEX(392), \ 7, \ 13, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayOnOffServer }, /* Endpoint: 2, Cluster: On/Off (server) */ \ { 0x0406, \ - ZAP_ATTRIBUTE_INDEX(396), \ + ZAP_ATTRIBUTE_INDEX(399), \ 4, \ 5, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ @@ -2845,7 +2864,7 @@ // This is an array of EmberAfEndpointType structures. #define GENERATED_ENDPOINT_TYPES \ { \ - { ZAP_CLUSTER_INDEX(0), 16, 4293 }, { ZAP_CLUSTER_INDEX(16), 39, 7311 }, { ZAP_CLUSTER_INDEX(55), 2, 18 }, \ + { ZAP_CLUSTER_INDEX(0), 17, 4313 }, { ZAP_CLUSTER_INDEX(17), 39, 7311 }, { ZAP_CLUSTER_INDEX(56), 2, 18 }, \ } // Largest attribute size is needed for various buffers @@ -2855,7 +2874,7 @@ #define ATTRIBUTE_SINGLETONS_SIZE (1517) // Total size of attribute storage -#define ATTRIBUTE_MAX_SIZE (11622) +#define ATTRIBUTE_MAX_SIZE (11642) // Number of fixed endpoints #define FIXED_ENDPOINT_COUNT (3) diff --git a/zzz_generated/all-clusters-app/zap-generated/gen_config.h b/zzz_generated/all-clusters-app/zap-generated/gen_config.h index b7dd7f4ee589e4..69372caa890039 100644 --- a/zzz_generated/all-clusters-app/zap-generated/gen_config.h +++ b/zzz_generated/all-clusters-app/zap-generated/gen_config.h @@ -61,6 +61,7 @@ #define EMBER_AF_MEDIA_PLAYBACK_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_NETWORK_COMMISSIONING_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_OTA_PROVIDER_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_OTA_REQUESTOR_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT (2) #define EMBER_AF_ON_OFF_CLUSTER_SERVER_ENDPOINT_COUNT (2) #define EMBER_AF_ON_OFF_SWITCH_CONFIG_CLUSTER_SERVER_ENDPOINT_COUNT (1) @@ -254,6 +255,11 @@ #define EMBER_AF_PLUGIN_OTA_SOFTWARE_UPDATE_PROVIDER_SERVER #define EMBER_AF_PLUGIN_OTA_SOFTWARE_UPDATE_PROVIDER +// Use this macro to check if the server side of the OTA Software Update Requestor cluster is included +#define ZCL_USING_OTA_REQUESTOR_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_OTA_SOFTWARE_UPDATE_REQUESTOR_SERVER +#define EMBER_AF_PLUGIN_OTA_SOFTWARE_UPDATE_REQUESTOR + // Use this macro to check if the server side of the Occupancy Sensing cluster is included #define ZCL_USING_OCCUPANCY_SENSING_CLUSTER_SERVER #define EMBER_AF_PLUGIN_OCCUPANCY_SENSING_SERVER diff --git a/zzz_generated/app-common/app-common/zap-generated/attribute-id.h b/zzz_generated/app-common/app-common/zap-generated/attribute-id.h index 478e98d7e904e0..14735a96a522ff 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attribute-id.h +++ b/zzz_generated/app-common/app-common/zap-generated/attribute-id.h @@ -283,10 +283,10 @@ // Attribute ids for cluster: OTA Software Update Requestor // Client attributes -#define ZCL_DEFAULT_OTA_PROVIDER_ATTRIBUTE_ID (0x0000) -#define ZCL_UPDATE_POSSIBLE_ATTRIBUTE_ID (0x0001) // Server attributes +#define ZCL_DEFAULT_OTA_PROVIDER_ATTRIBUTE_ID (0x0001) +#define ZCL_UPDATE_POSSIBLE_ATTRIBUTE_ID (0x0002) // Attribute ids for cluster: General Commissioning diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index 03d91efa30c8ed..416bd79b73c923 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -1348,6 +1348,21 @@ EmberAfStatus SetReachable(chip::EndpointId endpoint, bool reachable) } // namespace Attributes } // namespace Basic +namespace OtaSoftwareUpdateRequestor { +namespace Attributes { +EmberAfStatus GetUpdatePossible(chip::EndpointId endpoint, bool * updatePossible) +{ + return emberAfReadServerAttribute(endpoint, OtaSoftwareUpdateRequestor::Id, Ids::UpdatePossible, (uint8_t *) updatePossible, + sizeof(*updatePossible)); +} +EmberAfStatus SetUpdatePossible(chip::EndpointId endpoint, bool updatePossible) +{ + return emberAfWriteServerAttribute(endpoint, OtaSoftwareUpdateRequestor::Id, Ids::UpdatePossible, (uint8_t *) &updatePossible, + ZCL_BOOLEAN_ATTRIBUTE_TYPE); +} +} // namespace Attributes +} // namespace OtaSoftwareUpdateRequestor + namespace GeneralCommissioning { namespace Attributes { EmberAfStatus GetBreadcrumb(chip::EndpointId endpoint, uint64_t * breadcrumb) diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index eee95e65a9bcac..5faf14f6a6c634 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -371,6 +371,13 @@ EmberAfStatus SetReachable(chip::EndpointId endpoint, bool reachable); } // namespace Attributes } // namespace Basic +namespace OtaSoftwareUpdateRequestor { +namespace Attributes { +EmberAfStatus GetUpdatePossible(chip::EndpointId endpoint, bool * updatePossible); // boolean +EmberAfStatus SetUpdatePossible(chip::EndpointId endpoint, bool updatePossible); +} // namespace Attributes +} // namespace OtaSoftwareUpdateRequestor + namespace GeneralCommissioning { namespace Attributes { EmberAfStatus GetBreadcrumb(chip::EndpointId endpoint, uint64_t * breadcrumb); // int64u diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h index b724b08faa0e22..b79a559cba383f 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h @@ -298,6 +298,15 @@ static constexpr AttributeId Reachable = 0x00000011; } // namespace Attributes } // namespace Basic +namespace OtaSoftwareUpdateRequestor { +namespace Attributes { +namespace Ids { +static constexpr AttributeId DefaultOtaProvider = 0x00000001; +static constexpr AttributeId UpdatePossible = 0x00000002; +} // namespace Ids +} // namespace Attributes +} // namespace OtaSoftwareUpdateRequestor + namespace GeneralCommissioning { namespace Attributes { namespace Ids { diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index e226cea0ad9128..58611b7a871db9 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -1157,6 +1157,7 @@ static void OnThreadNetworkDiagnosticsActiveNetworkFaultsListListAttributeRespon | MediaPlayback | 0x0506 | | NetworkCommissioning | 0x0031 | | OtaSoftwareUpdateProvider | 0x0029 | +| OtaSoftwareUpdateRequestor | 0x002A | | OccupancySensing | 0x0406 | | OnOff | 0x0006 | | OnOffSwitchConfiguration | 0x0007 | @@ -1210,6 +1211,7 @@ constexpr chip::ClusterId kMediaInputClusterId = 0x050 constexpr chip::ClusterId kMediaPlaybackClusterId = 0x0506; constexpr chip::ClusterId kNetworkCommissioningClusterId = 0x0031; constexpr chip::ClusterId kOtaSoftwareUpdateProviderClusterId = 0x0029; +constexpr chip::ClusterId kOtaSoftwareUpdateRequestorClusterId = 0x002A; constexpr chip::ClusterId kOccupancySensingClusterId = 0x0406; constexpr chip::ClusterId kOnOffClusterId = 0x0006; constexpr chip::ClusterId kOnOffSwitchConfigurationClusterId = 0x0007; @@ -13732,6 +13734,224 @@ class ReadOtaSoftwareUpdateProviderClusterRevision : public ModelCommand new chip::Callback::Callback(OnDefaultFailureResponse, this); }; +/*----------------------------------------------------------------------------*\ +| Cluster OtaSoftwareUpdateRequestor | 0x002A | +|------------------------------------------------------------------------------| +| Commands: | | +| * AnnounceOtaProvider | 0x00 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * DefaultOtaProvider | 0x0001 | +| * UpdatePossible | 0x0002 | +| * ClusterRevision | 0xFFFD | +\*----------------------------------------------------------------------------*/ + +/* + * Command AnnounceOtaProvider + */ +class OtaSoftwareUpdateRequestorAnnounceOtaProvider : public ModelCommand +{ +public: + OtaSoftwareUpdateRequestorAnnounceOtaProvider() : ModelCommand("announce-ota-provider") + { + AddArgument("ServerLocation", &mServerLocation); + AddArgument("VendorId", 0, UINT16_MAX, &mVendorId); + AddArgument("AnnouncementReason", 0, UINT8_MAX, &mAnnouncementReason); + AddArgument("MetadataForNode", &mMetadataForNode); + ModelCommand::AddArguments(); + } + ~OtaSoftwareUpdateRequestorAnnounceOtaProvider() + { + delete onSuccessCallback; + delete onFailureCallback; + } + + CHIP_ERROR SendCommand(ChipDevice * device, uint8_t endpointId) override + { + ChipLogProgress(chipTool, "Sending cluster (0x002A) command (0x00) on endpoint %" PRIu8, endpointId); + + chip::Controller::OtaSoftwareUpdateRequestorCluster cluster; + cluster.Associate(device, endpointId); + return cluster.AnnounceOtaProvider(onSuccessCallback->Cancel(), onFailureCallback->Cancel(), mServerLocation, mVendorId, + mAnnouncementReason, mMetadataForNode); + } + +private: + chip::Callback::Callback * onSuccessCallback = + new chip::Callback::Callback(OnDefaultSuccessResponse, this); + chip::Callback::Callback * onFailureCallback = + new chip::Callback::Callback(OnDefaultFailureResponse, this); + chip::ByteSpan mServerLocation; + uint16_t mVendorId; + uint8_t mAnnouncementReason; + chip::ByteSpan mMetadataForNode; +}; + +/* + * Discover Attributes + */ +class DiscoverOtaSoftwareUpdateRequestorAttributes : public ModelCommand +{ +public: + DiscoverOtaSoftwareUpdateRequestorAttributes() : ModelCommand("discover") { ModelCommand::AddArguments(); } + + ~DiscoverOtaSoftwareUpdateRequestorAttributes() + { + delete onSuccessCallback; + delete onFailureCallback; + } + + CHIP_ERROR SendCommand(ChipDevice * device, uint8_t endpointId) override + { + ChipLogProgress(chipTool, "Sending cluster (0x0000) command (0x0C) on endpoint %" PRIu8, endpointId); + + chip::Controller::OtaSoftwareUpdateRequestorCluster cluster; + cluster.Associate(device, endpointId); + return cluster.DiscoverAttributes(onSuccessCallback->Cancel(), onFailureCallback->Cancel()); + } + +private: + chip::Callback::Callback * onSuccessCallback = + new chip::Callback::Callback(OnDefaultSuccessResponse, this); + chip::Callback::Callback * onFailureCallback = + new chip::Callback::Callback(OnDefaultFailureResponse, this); +}; + +/* + * Attribute DefaultOtaProvider + */ +class ReadOtaSoftwareUpdateRequestorDefaultOtaProvider : public ModelCommand +{ +public: + ReadOtaSoftwareUpdateRequestorDefaultOtaProvider() : ModelCommand("read") + { + AddArgument("attr-name", "default-ota-provider"); + ModelCommand::AddArguments(); + } + + ~ReadOtaSoftwareUpdateRequestorDefaultOtaProvider() + { + delete onSuccessCallback; + delete onFailureCallback; + } + + CHIP_ERROR SendCommand(ChipDevice * device, uint8_t endpointId) override + { + ChipLogProgress(chipTool, "Sending cluster (0x002A) command (0x00) on endpoint %" PRIu8, endpointId); + + chip::Controller::OtaSoftwareUpdateRequestorCluster cluster; + cluster.Associate(device, endpointId); + return cluster.ReadAttributeDefaultOtaProvider(onSuccessCallback->Cancel(), onFailureCallback->Cancel()); + } + +private: + chip::Callback::Callback * onSuccessCallback = + new chip::Callback::Callback(OnOctetStringAttributeResponse, this); + chip::Callback::Callback * onFailureCallback = + new chip::Callback::Callback(OnDefaultFailureResponse, this); +}; + +class WriteOtaSoftwareUpdateRequestorDefaultOtaProvider : public ModelCommand +{ +public: + WriteOtaSoftwareUpdateRequestorDefaultOtaProvider() : ModelCommand("write") + { + AddArgument("attr-name", "default-ota-provider"); + AddArgument("attr-value", &mValue); + ModelCommand::AddArguments(); + } + + ~WriteOtaSoftwareUpdateRequestorDefaultOtaProvider() + { + delete onSuccessCallback; + delete onFailureCallback; + } + + CHIP_ERROR SendCommand(ChipDevice * device, uint8_t endpointId) override + { + ChipLogProgress(chipTool, "Sending cluster (0x002A) command (0x01) on endpoint %" PRIu8, endpointId); + + chip::Controller::OtaSoftwareUpdateRequestorCluster cluster; + cluster.Associate(device, endpointId); + return cluster.WriteAttributeDefaultOtaProvider(onSuccessCallback->Cancel(), onFailureCallback->Cancel(), mValue); + } + +private: + chip::Callback::Callback * onSuccessCallback = + new chip::Callback::Callback(OnDefaultSuccessResponse, this); + chip::Callback::Callback * onFailureCallback = + new chip::Callback::Callback(OnDefaultFailureResponse, this); + chip::ByteSpan mValue; +}; + +/* + * Attribute UpdatePossible + */ +class ReadOtaSoftwareUpdateRequestorUpdatePossible : public ModelCommand +{ +public: + ReadOtaSoftwareUpdateRequestorUpdatePossible() : ModelCommand("read") + { + AddArgument("attr-name", "update-possible"); + ModelCommand::AddArguments(); + } + + ~ReadOtaSoftwareUpdateRequestorUpdatePossible() + { + delete onSuccessCallback; + delete onFailureCallback; + } + + CHIP_ERROR SendCommand(ChipDevice * device, uint8_t endpointId) override + { + ChipLogProgress(chipTool, "Sending cluster (0x002A) command (0x00) on endpoint %" PRIu8, endpointId); + + chip::Controller::OtaSoftwareUpdateRequestorCluster cluster; + cluster.Associate(device, endpointId); + return cluster.ReadAttributeUpdatePossible(onSuccessCallback->Cancel(), onFailureCallback->Cancel()); + } + +private: + chip::Callback::Callback * onSuccessCallback = + new chip::Callback::Callback(OnBooleanAttributeResponse, this); + chip::Callback::Callback * onFailureCallback = + new chip::Callback::Callback(OnDefaultFailureResponse, this); +}; + +/* + * Attribute ClusterRevision + */ +class ReadOtaSoftwareUpdateRequestorClusterRevision : public ModelCommand +{ +public: + ReadOtaSoftwareUpdateRequestorClusterRevision() : ModelCommand("read") + { + AddArgument("attr-name", "cluster-revision"); + ModelCommand::AddArguments(); + } + + ~ReadOtaSoftwareUpdateRequestorClusterRevision() + { + delete onSuccessCallback; + delete onFailureCallback; + } + + CHIP_ERROR SendCommand(ChipDevice * device, uint8_t endpointId) override + { + ChipLogProgress(chipTool, "Sending cluster (0x002A) command (0x00) on endpoint %" PRIu8, endpointId); + + chip::Controller::OtaSoftwareUpdateRequestorCluster cluster; + cluster.Associate(device, endpointId); + return cluster.ReadAttributeClusterRevision(onSuccessCallback->Cancel(), onFailureCallback->Cancel()); + } + +private: + chip::Callback::Callback * onSuccessCallback = + new chip::Callback::Callback(OnInt16uAttributeResponse, this); + chip::Callback::Callback * onFailureCallback = + new chip::Callback::Callback(OnDefaultFailureResponse, this); +}; + /*----------------------------------------------------------------------------*\ | Cluster OccupancySensing | 0x0406 | |------------------------------------------------------------------------------| @@ -25260,6 +25480,21 @@ void registerClusterOtaSoftwareUpdateProvider(Commands & commands) commands.Register(clusterName, clusterCommands); } +void registerClusterOtaSoftwareUpdateRequestor(Commands & commands) +{ + const char * clusterName = "OtaSoftwareUpdateRequestor"; + + commands_list clusterCommands = { + make_unique(), // + make_unique(), // + make_unique(), // + make_unique(), // + make_unique(), // + make_unique(), // + }; + + commands.Register(clusterName, clusterCommands); +} void registerClusterOccupancySensing(Commands & commands) { const char * clusterName = "OccupancySensing"; @@ -25780,6 +26015,7 @@ void registerClusters(Commands & commands) registerClusterMediaPlayback(commands); registerClusterNetworkCommissioning(commands); registerClusterOtaSoftwareUpdateProvider(commands); + registerClusterOtaSoftwareUpdateRequestor(commands); registerClusterOccupancySensing(commands); registerClusterOnOff(commands); registerClusterOnOffSwitchConfiguration(commands); diff --git a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp index 1beb29f92d5fe1..a9ac7d2926b5b3 100644 --- a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp +++ b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp @@ -7760,6 +7760,120 @@ CHIP_ERROR OtaSoftwareUpdateProviderCluster::ReadAttributeClusterRevision(Callba BasicAttributeFilter); } +// OtaSoftwareUpdateRequestor Cluster Commands +CHIP_ERROR OtaSoftwareUpdateRequestorCluster::AnnounceOtaProvider(Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback, + chip::ByteSpan serverLocation, uint16_t vendorId, + uint8_t announcementReason, chip::ByteSpan metadataForNode) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + app::CommandSender * sender = nullptr; + TLV::TLVWriter * writer = nullptr; + uint8_t argSeqNumber = 0; + + // Used when encoding non-empty command. Suppress error message when encoding empty commands. + (void) writer; + (void) argSeqNumber; + + VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE); + + app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, + OtaSoftwareUpdateRequestor::Commands::Ids::AnnounceOtaProvider, + (app::CommandPathFlags::kEndpointIdValid) }; + + SuccessOrExit(err = app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender)); + + SuccessOrExit(err = sender->PrepareCommand(cmdParams)); + + VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + // serverLocation: octetString + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), serverLocation)); + // vendorId: int16u + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), vendorId)); + // announcementReason: oTAAnnouncementReason + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), announcementReason)); + // metadataForNode: octetString + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), metadataForNode)); + + SuccessOrExit(err = sender->FinishCommand()); + + // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate. + mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback); + + err = mDevice->SendCommands(sender); + +exit: + // On error, we are responsible to close the sender. + if (err != CHIP_NO_ERROR && sender != nullptr) + { + sender->Shutdown(); + } + return err; +} + +// OtaSoftwareUpdateRequestor Cluster Attributes +CHIP_ERROR OtaSoftwareUpdateRequestorCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback) +{ + COMMAND_HEADER("DiscoverOtaSoftwareUpdateRequestorAttributes", OtaSoftwareUpdateRequestor::Id); + buf.Put8(kFrameControlGlobalCommand).Put8(seqNum).Put32(Globals::Commands::Ids::DiscoverAttributes).Put32(0x0000).Put8(0xFF); + COMMAND_FOOTER(); +} + +CHIP_ERROR OtaSoftwareUpdateRequestorCluster::ReadAttributeDefaultOtaProvider(Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback) +{ + app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = 0x00000001; + attributePath.mFlags.Set(app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback, + BasicAttributeFilter); +} + +CHIP_ERROR OtaSoftwareUpdateRequestorCluster::WriteAttributeDefaultOtaProvider(Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback, + chip::ByteSpan value) +{ + app::WriteClientHandle handle; + chip::app::AttributePathParams attributePath; + attributePath.mNodeId = mDevice->GetDeviceId(); + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = 0x00000001; + attributePath.mFlags.Set(chip::app::AttributePathParams::Flags::kFieldIdValid); + + ReturnErrorOnFailure(app::InteractionModelEngine::GetInstance()->NewWriteClient(handle)); + ReturnErrorOnFailure(handle.EncodeScalarAttributeWritePayload(attributePath, value)); + + return mDevice->SendWriteAttributeRequest(std::move(handle), onSuccessCallback, onFailureCallback); +} + +CHIP_ERROR OtaSoftwareUpdateRequestorCluster::ReadAttributeUpdatePossible(Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback) +{ + app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = 0x00000002; + attributePath.mFlags.Set(app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback, + BasicAttributeFilter); +} + +CHIP_ERROR OtaSoftwareUpdateRequestorCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback) +{ + app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = 0x0000FFFD; + attributePath.mFlags.Set(app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback, + BasicAttributeFilter); +} + // OccupancySensing Cluster Commands // OccupancySensing Cluster Attributes CHIP_ERROR OccupancySensingCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, diff --git a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h index 24a5aab675b80b..92b41039b5f6f5 100644 --- a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h +++ b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h @@ -885,6 +885,28 @@ class DLL_EXPORT OtaSoftwareUpdateProviderCluster : public ClusterBase private: }; +class DLL_EXPORT OtaSoftwareUpdateRequestorCluster : public ClusterBase +{ +public: + OtaSoftwareUpdateRequestorCluster() : ClusterBase(app::Clusters::OtaSoftwareUpdateRequestor::Id) {} + ~OtaSoftwareUpdateRequestorCluster() {} + + // Cluster Commands + CHIP_ERROR AnnounceOtaProvider(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, + chip::ByteSpan serverLocation, uint16_t vendorId, uint8_t announcementReason, + chip::ByteSpan metadataForNode); + + // Cluster Attributes + CHIP_ERROR DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); + CHIP_ERROR ReadAttributeDefaultOtaProvider(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); + CHIP_ERROR ReadAttributeUpdatePossible(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); + CHIP_ERROR ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); + CHIP_ERROR WriteAttributeDefaultOtaProvider(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, + chip::ByteSpan value); + +private: +}; + class DLL_EXPORT OccupancySensingCluster : public ClusterBase { public: diff --git a/zzz_generated/controller-clusters/zap-generated/callback-stub.cpp b/zzz_generated/controller-clusters/zap-generated/callback-stub.cpp index fa9e08e1414e5b..3e3e7a459466a3 100644 --- a/zzz_generated/controller-clusters/zap-generated/callback-stub.cpp +++ b/zzz_generated/controller-clusters/zap-generated/callback-stub.cpp @@ -121,6 +121,9 @@ void emberAfClusterInitCallback(EndpointId endpoint, ClusterId clusterId) case ZCL_OTA_PROVIDER_CLUSTER_ID: emberAfOtaSoftwareUpdateProviderClusterInitCallback(endpoint); break; + case ZCL_OTA_REQUESTOR_CLUSTER_ID: + emberAfOtaSoftwareUpdateRequestorClusterInitCallback(endpoint); + break; case ZCL_OCCUPANCY_SENSING_CLUSTER_ID: emberAfOccupancySensingClusterInitCallback(endpoint); break; @@ -342,6 +345,11 @@ void __attribute__((weak)) emberAfOtaSoftwareUpdateProviderClusterInitCallback(E // To prevent warning (void) endpoint; } +void __attribute__((weak)) emberAfOtaSoftwareUpdateRequestorClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} void __attribute__((weak)) emberAfOccupancySensingClusterInitCallback(EndpointId endpoint) { // To prevent warning diff --git a/zzz_generated/controller-clusters/zap-generated/endpoint_config.h b/zzz_generated/controller-clusters/zap-generated/endpoint_config.h index c541b1a62da665..9ef10698ffb575 100644 --- a/zzz_generated/controller-clusters/zap-generated/endpoint_config.h +++ b/zzz_generated/controller-clusters/zap-generated/endpoint_config.h @@ -63,7 +63,7 @@ #define ZAP_ATTRIBUTE_MASK(mask) ATTRIBUTE_MASK_##mask // This is an array of EmberAfAttributeMetadata structures. -#define GENERATED_ATTRIBUTE_COUNT 50 +#define GENERATED_ATTRIBUTE_COUNT 51 #define GENERATED_ATTRIBUTES \ { \ \ @@ -98,6 +98,9 @@ /* Endpoint: 1, Cluster: OTA Software Update Provider (client) */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(CLIENT), ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ + /* Endpoint: 1, Cluster: OTA Software Update Requestor (client) */ \ + { 0xFFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(CLIENT), ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ /* Endpoint: 1, Cluster: General Commissioning (client) */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(CLIENT), ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ @@ -227,7 +230,7 @@ #define GENERATED_FUNCTION_ARRAYS #define ZAP_CLUSTER_MASK(mask) CLUSTER_MASK_##mask -#define GENERATED_CLUSTER_COUNT 51 +#define GENERATED_CLUSTER_COUNT 52 #define GENERATED_CLUSTERS \ { \ { 0x0003, ZAP_ATTRIBUTE_INDEX(0), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL }, /* Endpoint: 1, Cluster: Identify (client) */ \ @@ -251,125 +254,128 @@ 0x0029, ZAP_ATTRIBUTE_INDEX(9), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: OTA Software Update Provider (client) */ \ { \ - 0x0030, ZAP_ATTRIBUTE_INDEX(10), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x002A, ZAP_ATTRIBUTE_INDEX(10), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + }, /* Endpoint: 1, Cluster: OTA Software Update Requestor (client) */ \ + { \ + 0x0030, ZAP_ATTRIBUTE_INDEX(11), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: General Commissioning (client) */ \ { \ - 0x0031, ZAP_ATTRIBUTE_INDEX(11), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0031, ZAP_ATTRIBUTE_INDEX(12), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Network Commissioning (client) */ \ { \ - 0x0032, ZAP_ATTRIBUTE_INDEX(12), 0, 0, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0032, ZAP_ATTRIBUTE_INDEX(13), 0, 0, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Diagnostic Logs (client) */ \ { \ - 0x0033, ZAP_ATTRIBUTE_INDEX(12), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0033, ZAP_ATTRIBUTE_INDEX(13), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: General Diagnostics (client) */ \ { \ - 0x0034, ZAP_ATTRIBUTE_INDEX(13), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0034, ZAP_ATTRIBUTE_INDEX(14), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Software Diagnostics (client) */ \ { \ - 0x0035, ZAP_ATTRIBUTE_INDEX(14), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0035, ZAP_ATTRIBUTE_INDEX(15), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Thread Network Diagnostics (client) */ \ { \ - 0x0036, ZAP_ATTRIBUTE_INDEX(15), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0036, ZAP_ATTRIBUTE_INDEX(16), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: WiFi Network Diagnostics (client) */ \ { \ - 0x0037, ZAP_ATTRIBUTE_INDEX(16), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0037, ZAP_ATTRIBUTE_INDEX(17), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Ethernet Network Diagnostics (client) */ \ { \ - 0x0039, ZAP_ATTRIBUTE_INDEX(17), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0039, ZAP_ATTRIBUTE_INDEX(18), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Bridged Device Basic (client) */ \ - { 0x003B, ZAP_ATTRIBUTE_INDEX(18), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL }, /* Endpoint: 1, Cluster: Switch (client) */ \ + { 0x003B, ZAP_ATTRIBUTE_INDEX(19), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL }, /* Endpoint: 1, Cluster: Switch (client) */ \ { \ - 0x003C, ZAP_ATTRIBUTE_INDEX(19), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x003C, ZAP_ATTRIBUTE_INDEX(20), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: AdministratorCommissioning (client) */ \ { \ - 0x003E, ZAP_ATTRIBUTE_INDEX(20), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x003E, ZAP_ATTRIBUTE_INDEX(21), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Operational Credentials (client) */ \ { \ - 0x0040, ZAP_ATTRIBUTE_INDEX(21), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0040, ZAP_ATTRIBUTE_INDEX(22), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Fixed Label (client) */ \ { \ - 0x0101, ZAP_ATTRIBUTE_INDEX(22), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0101, ZAP_ATTRIBUTE_INDEX(23), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Door Lock (client) */ \ { \ - 0x0102, ZAP_ATTRIBUTE_INDEX(23), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0102, ZAP_ATTRIBUTE_INDEX(24), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Window Covering (client) */ \ { \ - 0x0103, ZAP_ATTRIBUTE_INDEX(24), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0103, ZAP_ATTRIBUTE_INDEX(25), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Barrier Control (client) */ \ { \ - 0x0200, ZAP_ATTRIBUTE_INDEX(25), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0200, ZAP_ATTRIBUTE_INDEX(26), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Pump Configuration and Control (client) */ \ { \ - 0x0201, ZAP_ATTRIBUTE_INDEX(26), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0201, ZAP_ATTRIBUTE_INDEX(27), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Thermostat (client) */ \ { \ - 0x0204, ZAP_ATTRIBUTE_INDEX(27), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0204, ZAP_ATTRIBUTE_INDEX(28), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Thermostat User Interface Configuration (client) */ \ { \ - 0x0300, ZAP_ATTRIBUTE_INDEX(28), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0300, ZAP_ATTRIBUTE_INDEX(29), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Color Control (client) */ \ { \ - 0x0402, ZAP_ATTRIBUTE_INDEX(29), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0402, ZAP_ATTRIBUTE_INDEX(30), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Temperature Measurement (client) */ \ { \ - 0x0403, ZAP_ATTRIBUTE_INDEX(30), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0403, ZAP_ATTRIBUTE_INDEX(31), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Pressure Measurement (client) */ \ { \ - 0x0404, ZAP_ATTRIBUTE_INDEX(31), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0404, ZAP_ATTRIBUTE_INDEX(32), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Flow Measurement (client) */ \ { \ - 0x0405, ZAP_ATTRIBUTE_INDEX(32), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0405, ZAP_ATTRIBUTE_INDEX(33), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Relative Humidity Measurement (client) */ \ { \ - 0x0406, ZAP_ATTRIBUTE_INDEX(33), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0406, ZAP_ATTRIBUTE_INDEX(34), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Occupancy Sensing (client) */ \ { \ - 0x0503, ZAP_ATTRIBUTE_INDEX(34), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0503, ZAP_ATTRIBUTE_INDEX(35), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Wake on LAN (client) */ \ { \ - 0x0504, ZAP_ATTRIBUTE_INDEX(35), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0504, ZAP_ATTRIBUTE_INDEX(36), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: TV Channel (client) */ \ { \ - 0x0505, ZAP_ATTRIBUTE_INDEX(36), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0505, ZAP_ATTRIBUTE_INDEX(37), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Target Navigator (client) */ \ { \ - 0x0506, ZAP_ATTRIBUTE_INDEX(37), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0506, ZAP_ATTRIBUTE_INDEX(38), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Media Playback (client) */ \ { \ - 0x0507, ZAP_ATTRIBUTE_INDEX(38), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0507, ZAP_ATTRIBUTE_INDEX(39), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Media Input (client) */ \ { \ - 0x0508, ZAP_ATTRIBUTE_INDEX(39), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0508, ZAP_ATTRIBUTE_INDEX(40), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Low Power (client) */ \ { \ - 0x0509, ZAP_ATTRIBUTE_INDEX(40), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0509, ZAP_ATTRIBUTE_INDEX(41), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Keypad Input (client) */ \ { \ - 0x050A, ZAP_ATTRIBUTE_INDEX(41), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x050A, ZAP_ATTRIBUTE_INDEX(42), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Content Launcher (client) */ \ { \ - 0x050B, ZAP_ATTRIBUTE_INDEX(42), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x050B, ZAP_ATTRIBUTE_INDEX(43), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Audio Output (client) */ \ { \ - 0x050C, ZAP_ATTRIBUTE_INDEX(43), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x050C, ZAP_ATTRIBUTE_INDEX(44), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Application Launcher (client) */ \ { \ - 0x050D, ZAP_ATTRIBUTE_INDEX(44), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x050D, ZAP_ATTRIBUTE_INDEX(45), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Application Basic (client) */ \ { \ - 0x050E, ZAP_ATTRIBUTE_INDEX(45), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x050E, ZAP_ATTRIBUTE_INDEX(46), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Account Login (client) */ \ { \ - 0x050F, ZAP_ATTRIBUTE_INDEX(46), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x050F, ZAP_ATTRIBUTE_INDEX(47), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Test Cluster (client) */ \ { \ - 0x0B04, ZAP_ATTRIBUTE_INDEX(47), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0x0B04, ZAP_ATTRIBUTE_INDEX(48), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Electrical Measurement (client) */ \ { \ - 0xF000, ZAP_ATTRIBUTE_INDEX(48), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0xF000, ZAP_ATTRIBUTE_INDEX(49), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Binding (client) */ \ { \ - 0xF004, ZAP_ATTRIBUTE_INDEX(49), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + 0xF004, ZAP_ATTRIBUTE_INDEX(50), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: Group Key Management (client) */ \ } @@ -378,7 +384,7 @@ // This is an array of EmberAfEndpointType structures. #define GENERATED_ENDPOINT_TYPES \ { \ - { ZAP_CLUSTER_INDEX(0), 51, 100 }, \ + { ZAP_CLUSTER_INDEX(0), 52, 102 }, \ } // Largest attribute size is needed for various buffers @@ -388,7 +394,7 @@ #define ATTRIBUTE_SINGLETONS_SIZE (4) // Total size of attribute storage -#define ATTRIBUTE_MAX_SIZE (100) +#define ATTRIBUTE_MAX_SIZE (102) // Number of fixed endpoints #define FIXED_ENDPOINT_COUNT (1) @@ -432,7 +438,7 @@ // Array of EmberAfCommandMetadata structs. #define ZAP_COMMAND_MASK(mask) COMMAND_MASK_##mask -#define EMBER_AF_GENERATED_COMMAND_COUNT (232) +#define EMBER_AF_GENERATED_COMMAND_COUNT (233) #define GENERATED_COMMANDS \ { \ \ @@ -499,6 +505,9 @@ { 0x0029, 0x03, ZAP_COMMAND_MASK(INCOMING_CLIENT) }, /* QueryImageResponse */ \ { 0x0029, 0x04, ZAP_COMMAND_MASK(INCOMING_CLIENT) }, /* ApplyUpdateRequestResponse */ \ \ + /* Endpoint: 1, Cluster: OTA Software Update Requestor (client) */ \ + { 0x002A, 0x00, ZAP_COMMAND_MASK(OUTGOING_CLIENT) }, /* AnnounceOtaProvider */ \ + \ /* Endpoint: 1, Cluster: General Commissioning (client) */ \ { 0x0030, 0x00, ZAP_COMMAND_MASK(INCOMING_SERVER) }, /* ArmFailSafe */ \ { 0x0030, 0x01, ZAP_COMMAND_MASK(INCOMING_CLIENT) }, /* ArmFailSafeResponse */ \ diff --git a/zzz_generated/controller-clusters/zap-generated/gen_config.h b/zzz_generated/controller-clusters/zap-generated/gen_config.h index cb9c6e1c8ba9ff..50c03fe40014e1 100644 --- a/zzz_generated/controller-clusters/zap-generated/gen_config.h +++ b/zzz_generated/controller-clusters/zap-generated/gen_config.h @@ -60,6 +60,7 @@ #define EMBER_AF_MEDIA_PLAYBACK_CLUSTER_CLIENT_ENDPOINT_COUNT (1) #define EMBER_AF_NETWORK_COMMISSIONING_CLUSTER_CLIENT_ENDPOINT_COUNT (1) #define EMBER_AF_OTA_PROVIDER_CLUSTER_CLIENT_ENDPOINT_COUNT (1) +#define EMBER_AF_OTA_REQUESTOR_CLUSTER_CLIENT_ENDPOINT_COUNT (1) #define EMBER_AF_OCCUPANCY_SENSING_CLUSTER_CLIENT_ENDPOINT_COUNT (1) #define EMBER_AF_ON_OFF_CLUSTER_CLIENT_ENDPOINT_COUNT (1) #define EMBER_AF_ON_OFF_SWITCH_CONFIG_CLUSTER_CLIENT_ENDPOINT_COUNT (1) @@ -207,6 +208,10 @@ #define ZCL_USING_OTA_PROVIDER_CLUSTER_CLIENT #define EMBER_AF_PLUGIN_OTA_SOFTWARE_UPDATE_PROVIDER_CLIENT +// Use this macro to check if the client side of the OTA Software Update Requestor cluster is included +#define ZCL_USING_OTA_REQUESTOR_CLUSTER_CLIENT +#define EMBER_AF_PLUGIN_OTA_SOFTWARE_UPDATE_REQUESTOR_CLIENT + // Use this macro to check if the client side of the Occupancy Sensing cluster is included #define ZCL_USING_OCCUPANCY_SENSING_CLUSTER_CLIENT #define EMBER_AF_PLUGIN_OCCUPANCY_SENSING_CLIENT From 6fd3811cc1606f0be8970b7203aa9b58d555c04c Mon Sep 17 00:00:00 2001 From: Kevin Schoedel <67607049+kpschoedel@users.noreply.github.com> Date: Tue, 14 Sep 2021 13:22:09 -0400 Subject: [PATCH 036/255] Make platform PlatformManager::PostEvent() return status (#9573) * Make platform PlatformManager::PostEvent() return status #### Problem `void PlatformManager::PostEvent()` can fail on some platforms, but does not report this to callers. In the #9543 case, an intermediate layer unconditionally returned `CHIP_NO_ERROR`, and `Inet` code assumed it could actually test whether `PostEvent()` succeeded. Fixes #9543 _PacketBuffer leak_ #### Change overview Made `PlatformManager::PostEvent()` return `CHIP_ERROR`. Marked it `[[nodiscard]]` to catch all uses, and made callers propagate or at least log any error. #### Testing CI. * address review comments * restyle * replace PostEventLoggingErrors with PostEventOrDie * fix P6 --- src/include/platform/PlatformManager.h | 14 +++++++-- .../GenericConfigurationManagerImpl.cpp | 13 ++++++-- .../GenericConnectivityManagerImpl_Thread.cpp | 6 +++- .../internal/GenericPlatformManagerImpl.cpp | 6 +++- .../GenericPlatformManagerImpl_FreeRTOS.cpp | 18 ++++++----- .../GenericPlatformManagerImpl_FreeRTOS.h | 2 +- .../GenericPlatformManagerImpl_POSIX.cpp | 3 +- .../GenericPlatformManagerImpl_POSIX.h | 2 +- .../GenericPlatformManagerImpl_Zephyr.cpp | 13 +++++--- .../GenericPlatformManagerImpl_Zephyr.h | 2 +- src/platform/Darwin/PlatformManagerImpl.cpp | 3 +- src/platform/Darwin/PlatformManagerImpl.h | 2 +- src/platform/DeviceControlServer.cpp | 9 ++++-- src/platform/EFR32/BLEManagerImpl.cpp | 16 +++++----- .../ESP32/ConnectivityManagerImpl.cpp | 12 +++---- src/platform/ESP32/PlatformManagerImpl.cpp | 2 +- .../ESP32/bluedroid/BLEManagerImpl.cpp | 18 +++++------ src/platform/ESP32/nimble/BLEManagerImpl.cpp | 16 +++++----- src/platform/K32W/BLEManagerImpl.cpp | 19 ++++++------ src/platform/Linux/BLEManagerImpl.cpp | 28 ++++++++--------- .../Linux/ConnectivityManagerImpl.cpp | 2 +- src/platform/Linux/PlatformManagerImpl.cpp | 6 +++- src/platform/Linux/ThreadStackManagerImpl.cpp | 16 +++++++--- src/platform/LwIPEventSupport.cpp | 4 +-- ...nericThreadStackManagerImpl_OpenThread.cpp | 14 ++++++--- ...ThreadStackManagerImpl_OpenThread_LwIP.cpp | 6 +++- src/platform/P6/BLEManagerImpl.cpp | 31 ++++++++++++++----- src/platform/P6/ConnectivityManagerImpl.cpp | 6 ++-- src/platform/Zephyr/BLEManagerImpl.cpp | 18 +++++------ src/platform/cc13x2_26x2/BLEManagerImpl.cpp | 10 +++--- src/platform/fake/PlatformManagerImpl.h | 2 +- src/platform/mbed/BLEManagerImpl.cpp | 16 +++++----- src/platform/mbed/ConnectivityManagerImpl.cpp | 16 +++++----- src/platform/mbed/PlatformManagerImpl.cpp | 4 ++- src/platform/mbed/PlatformManagerImpl.h | 3 +- src/platform/qpg/BLEManagerImpl.cpp | 14 ++++----- 36 files changed, 224 insertions(+), 148 deletions(-) diff --git a/src/include/platform/PlatformManager.h b/src/include/platform/PlatformManager.h index cceeb432027a2d..7f902b6a9c8829 100644 --- a/src/include/platform/PlatformManager.h +++ b/src/include/platform/PlatformManager.h @@ -190,7 +190,8 @@ class PlatformManager * processing, the event might get dispatched (on the work item processing * thread) before PostEvent returns. */ - void PostEvent(const ChipDeviceEvent * event); + [[nodiscard]] CHIP_ERROR PostEvent(const ChipDeviceEvent * event); + void PostEventOrDie(const ChipDeviceEvent * event); void DispatchEvent(const ChipDeviceEvent * event); CHIP_ERROR StartChipTimer(uint32_t durationMS); @@ -354,9 +355,16 @@ inline void PlatformManager::UnlockChipStack() static_cast(this)->_UnlockChipStack(); } -inline void PlatformManager::PostEvent(const ChipDeviceEvent * event) +inline CHIP_ERROR PlatformManager::PostEvent(const ChipDeviceEvent * event) { - static_cast(this)->_PostEvent(event); + return static_cast(this)->_PostEvent(event); +} + +inline void PlatformManager::PostEventOrDie(const ChipDeviceEvent * event) +{ + CHIP_ERROR status = static_cast(this)->_PostEvent(event); + VerifyOrDieWithMsg(status == CHIP_NO_ERROR, DeviceLayer, "Failed to post event %d: %" CHIP_ERROR_FORMAT, + static_cast(event->Type), status.Format()); } inline void PlatformManager::DispatchEvent(const ChipDeviceEvent * event) diff --git a/src/include/platform/internal/GenericConfigurationManagerImpl.cpp b/src/include/platform/internal/GenericConfigurationManagerImpl.cpp index bac6cca73583ee..383946f9bf58c2 100644 --- a/src/include/platform/internal/GenericConfigurationManagerImpl.cpp +++ b/src/include/platform/internal/GenericConfigurationManagerImpl.cpp @@ -781,11 +781,14 @@ CHIP_ERROR GenericConfigurationManagerImpl::_StoreServiceProvisioning template CHIP_ERROR GenericConfigurationManagerImpl::_ClearServiceProvisioningData() { + CHIP_ERROR err = CHIP_NO_ERROR; + Impl()->ClearConfigValue(ImplClass::kConfigKey_ServiceId); Impl()->ClearConfigValue(ImplClass::kConfigKey_ServiceConfig); Impl()->ClearConfigValue(ImplClass::kConfigKey_PairedAccountId); // TODO: Move these behaviors out of configuration manager. + // Also, should the flags be cleared even if the corresponding notification fails to post? // If necessary, post an event alerting other subsystems to the change in // the account pairing state. @@ -794,7 +797,7 @@ CHIP_ERROR GenericConfigurationManagerImpl::_ClearServiceProvisioning ChipDeviceEvent event; event.Type = DeviceEventType::kAccountPairingChange; event.AccountPairingChange.IsPairedToAccount = false; - PlatformMgr().PostEvent(&event); + err = PlatformMgr().PostEvent(&event); } // If necessary, post an event alerting other subsystems to the change in @@ -805,13 +808,17 @@ CHIP_ERROR GenericConfigurationManagerImpl::_ClearServiceProvisioning event.Type = DeviceEventType::kServiceProvisioningChange; event.ServiceProvisioningChange.IsServiceProvisioned = false; event.ServiceProvisioningChange.ServiceConfigUpdated = false; - PlatformMgr().PostEvent(&event); + CHIP_ERROR postError = PlatformMgr().PostEvent(&event); + if (err == CHIP_NO_ERROR) + { + err = postError; + } } mFlags.Clear(Flags::kIsServiceProvisioned); mFlags.Clear(Flags::kIsPairedToAccount); - return CHIP_NO_ERROR; + return err; } template diff --git a/src/include/platform/internal/GenericConnectivityManagerImpl_Thread.cpp b/src/include/platform/internal/GenericConnectivityManagerImpl_Thread.cpp index 672f404637a10d..b02aed72f903a3 100644 --- a/src/include/platform/internal/GenericConnectivityManagerImpl_Thread.cpp +++ b/src/include/platform/internal/GenericConnectivityManagerImpl_Thread.cpp @@ -109,7 +109,11 @@ void GenericConnectivityManagerImpl_Thread::UpdateServiceConnectivity event.ServiceConnectivityChange.ViaThread.Result = (haveServiceConnectivity) ? kConnectivity_Established : kConnectivity_Lost; event.ServiceConnectivityChange.Overall.Result = event.ServiceConnectivityChange.ViaThread.Result; - PlatformMgr().PostEvent(&event); + CHIP_ERROR status = PlatformMgr().PostEvent(&event); + if (status != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to post thread connectivity change: %" CHIP_ERROR_FORMAT, status.Format()); + } } } } diff --git a/src/include/platform/internal/GenericPlatformManagerImpl.cpp b/src/include/platform/internal/GenericPlatformManagerImpl.cpp index 6114df23b82e24..e388f424eb700c 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl.cpp +++ b/src/include/platform/internal/GenericPlatformManagerImpl.cpp @@ -207,7 +207,11 @@ void GenericPlatformManagerImpl::_ScheduleWork(AsyncWorkFunct workFun event.CallWorkFunct.WorkFunct = workFunct; event.CallWorkFunct.Arg = arg; - Impl()->PostEvent(&event); + CHIP_ERROR status = Impl()->PostEvent(&event); + if (status != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to schedule work: %" CHIP_ERROR_FORMAT, status.Format()); + } } template diff --git a/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.cpp b/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.cpp index 7848e1dd8ce1e5..7963e6a3d026ad 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.cpp +++ b/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.cpp @@ -98,15 +98,19 @@ void GenericPlatformManagerImpl_FreeRTOS::_UnlockChipStack(void) } template -void GenericPlatformManagerImpl_FreeRTOS::_PostEvent(const ChipDeviceEvent * event) +CHIP_ERROR GenericPlatformManagerImpl_FreeRTOS::_PostEvent(const ChipDeviceEvent * event) { - if (mChipEventQueue != NULL) + if (mChipEventQueue == NULL) { - if (!xQueueSend(mChipEventQueue, event, 1)) - { - ChipLogError(DeviceLayer, "Failed to post event to CHIP Platform event queue"); - } + return CHIP_ERROR_INTERNAL; + } + BaseType_t status = xQueueSend(mChipEventQueue, event, 1); + if (status != pdTRUE) + { + ChipLogError(DeviceLayer, "Failed to post event to CHIP Platform event queue"); + return CHIP_ERROR(chip::ChipError::Range::kOS, status); } + return CHIP_NO_ERROR; } template @@ -218,7 +222,7 @@ CHIP_ERROR GenericPlatformManagerImpl_FreeRTOS::_StartChipTimer(uint3 { ChipDeviceEvent event; event.Type = DeviceEventType::kNoOp; - Impl()->PostEvent(&event); + ReturnErrorOnFailure(Impl()->PostEvent(&event)); } return CHIP_NO_ERROR; diff --git a/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.h b/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.h index 24c5a65a4d864c..8382a4cb757bfd 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.h +++ b/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.h @@ -68,7 +68,7 @@ class GenericPlatformManagerImpl_FreeRTOS : public GenericPlatformManagerImpl::_StartChipTimer(int64_t } template -void GenericPlatformManagerImpl_POSIX::_PostEvent(const ChipDeviceEvent * event) +CHIP_ERROR GenericPlatformManagerImpl_POSIX::_PostEvent(const ChipDeviceEvent * event) { mChipEventQueue.Push(*event); SystemLayerSocketsLoop().Signal(); // Trigger wake select on CHIP thread + return CHIP_NO_ERROR; } template diff --git a/src/include/platform/internal/GenericPlatformManagerImpl_POSIX.h b/src/include/platform/internal/GenericPlatformManagerImpl_POSIX.h index 2916cb0ca789a7..de0250e039673f 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl_POSIX.h +++ b/src/include/platform/internal/GenericPlatformManagerImpl_POSIX.h @@ -89,7 +89,7 @@ class GenericPlatformManagerImpl_POSIX : public GenericPlatformManagerImpl template inherits. #include +#include #include #define DEFAULT_MIN_SLEEP_PERIOD (60 * 60 * 24 * 30) // Month [sec] @@ -107,15 +108,19 @@ CHIP_ERROR GenericPlatformManagerImpl_Zephyr::_Shutdown(void) } template -void GenericPlatformManagerImpl_Zephyr::_PostEvent(const ChipDeviceEvent * event) +CHIP_ERROR GenericPlatformManagerImpl_Zephyr::_PostEvent(const ChipDeviceEvent * event) { // For some reasons mentioned in https://github.com/zephyrproject-rtos/zephyr/issues/22301 // k_msgq_put takes `void*` instead of `const void*`. Nonetheless, it should be safe to // const_cast here and there are components in Zephyr itself which do the same. - if (k_msgq_put(&mChipEventQueue, const_cast(event), K_NO_WAIT) == 0) - SystemLayerSocketsLoop().Signal(); // Trigger wake on CHIP thread - else + int status = k_msgq_put(&mChipEventQueue, const_cast(event), K_NO_WAIT); + if (status != 0) + { ChipLogError(DeviceLayer, "Failed to post event to CHIP Platform event queue"); + return System::MapErrorZephyr(status); + } + SystemLayerSocketsLoop().Signal(); // Trigger wake on CHIP thread + return CHIP_NO_ERROR; } template diff --git a/src/include/platform/internal/GenericPlatformManagerImpl_Zephyr.h b/src/include/platform/internal/GenericPlatformManagerImpl_Zephyr.h index 1ac68adae4955e..6c4a6a2eda1094 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl_Zephyr.h +++ b/src/include/platform/internal/GenericPlatformManagerImpl_Zephyr.h @@ -73,7 +73,7 @@ class GenericPlatformManagerImpl_Zephyr : public GenericPlatformManagerImpl::_Shutdown(); } -void PlatformManagerImpl::_PostEvent(const ChipDeviceEvent * event) +CHIP_ERROR PlatformManagerImpl::_PostEvent(const ChipDeviceEvent * event) { const ChipDeviceEvent eventCopy = *event; dispatch_async(mWorkQueue, ^{ Impl()->DispatchEvent(&eventCopy); }); + return CHIP_NO_ERROR; } } // namespace DeviceLayer diff --git a/src/platform/Darwin/PlatformManagerImpl.h b/src/platform/Darwin/PlatformManagerImpl.h index d0990b6e3e3179..1c58a1c0d54b56 100644 --- a/src/platform/Darwin/PlatformManagerImpl.h +++ b/src/platform/Darwin/PlatformManagerImpl.h @@ -65,7 +65,7 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener void _LockChipStack(){}; bool _TryLockChipStack() { return false; }; void _UnlockChipStack(){}; - void _PostEvent(const ChipDeviceEvent * event); + CHIP_ERROR _PostEvent(const ChipDeviceEvent * event); #if CHIP_STACK_LOCK_TRACKING_ENABLED bool _IsChipStackLockedByCurrentThread() const { return false; }; diff --git a/src/platform/DeviceControlServer.cpp b/src/platform/DeviceControlServer.cpp index e945cf480861c5..98e9c6e5b4f789 100644 --- a/src/platform/DeviceControlServer.cpp +++ b/src/platform/DeviceControlServer.cpp @@ -46,7 +46,11 @@ void DeviceControlServer::CommissioningFailedTimerComplete() ChipDeviceEvent event; event.Type = DeviceEventType::kCommissioningComplete; event.CommissioningComplete.status = CHIP_ERROR_TIMEOUT; - PlatformMgr().PostEvent(&event); + CHIP_ERROR status = PlatformMgr().PostEvent(&event); + if (status != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to post commissioning complete: %" CHIP_ERROR_FORMAT, status.Format()); + } } CHIP_ERROR DeviceControlServer::ArmFailSafe(uint16_t expiryLengthSeconds) @@ -68,8 +72,7 @@ CHIP_ERROR DeviceControlServer::CommissioningComplete() ChipDeviceEvent event; event.Type = DeviceEventType::kCommissioningComplete; event.CommissioningComplete.status = CHIP_NO_ERROR; - PlatformMgr().PostEvent(&event); - return CHIP_NO_ERROR; + return PlatformMgr().PostEvent(&event); } CHIP_ERROR DeviceControlServer::SetRegulatoryConfig(uint8_t location, const char * countryCode, uint64_t breadcrumb) diff --git a/src/platform/EFR32/BLEManagerImpl.cpp b/src/platform/EFR32/BLEManagerImpl.cpp index f98305c4a8c3e6..bbbf59105bdba5 100644 --- a/src/platform/EFR32/BLEManagerImpl.cpp +++ b/src/platform/EFR32/BLEManagerImpl.cpp @@ -423,7 +423,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLESubscribe"); HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX); connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; - PlatformMgr().PostEvent(&connEstEvent); + PlatformMgr().PostEventOrDie(&connEstEvent); } break; @@ -523,7 +523,7 @@ bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUU { event.Type = DeviceEventType::kCHIPoBLENotifyConfirm; event.CHIPoBLENotifyConfirm.ConId = conId; - PlatformMgr().PostEvent(&event); + err = PlatformMgr().PostEvent(&event); } exit: @@ -881,7 +881,7 @@ void BLEManagerImpl::HandleConnectionCloseEvent(volatile sl_bt_msg_t * evt) ChipLogProgress(DeviceLayer, "BLE GATT connection closed (con %u, reason %u)", connHandle, conn_evt->reason); - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); // Arrange to re-enable connectable advertising in case it was disabled due to the // maximum connection limit being reached. @@ -931,7 +931,7 @@ void BLEManagerImpl::HandleTXCharCCCDWrite(volatile sl_bt_msg_t * evt) { event.Type = DeviceEventType::kCHIPoBLESubscribe; event.CHIPoBLESubscribe.ConId = evt->data.evt_gatt_server_user_write_request.connection; - PlatformMgr().PostEvent(&event); + err = PlatformMgr().PostEvent(&event); } } } @@ -940,7 +940,7 @@ void BLEManagerImpl::HandleTXCharCCCDWrite(volatile sl_bt_msg_t * evt) bleConnState->subscribed = 0; event.Type = DeviceEventType::kCHIPoBLEUnsubscribe; event.CHIPoBLESubscribe.ConId = evt->data.evt_gatt_server_user_write_request.connection; - PlatformMgr().PostEvent(&event); + err = PlatformMgr().PostEvent(&event); } exit: @@ -970,7 +970,7 @@ void BLEManagerImpl::HandleRXCharWrite(volatile sl_bt_msg_t * evt) event.Type = DeviceEventType::kCHIPoBLEWriteReceived; event.CHIPoBLEWriteReceived.ConId = evt->data.evt_gatt_server_user_write_request.connection; event.CHIPoBLEWriteReceived.Data = std::move(buf).UnsafeRelease(); - PlatformMgr().PostEvent(&event); + err = PlatformMgr().PostEvent(&event); } exit: @@ -996,7 +996,7 @@ void BLEManagerImpl::HandleTxConfirmationEvent(BLE_CONNECTION_OBJECT conId) event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; event.CHIPoBLEIndicateConfirm.ConId = conId; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } void BLEManagerImpl::HandleSoftTimerEvent(volatile sl_bt_msg_t * evt) @@ -1011,7 +1011,7 @@ void BLEManagerImpl::HandleSoftTimerEvent(volatile sl_bt_msg_t * evt) event.CHIPoBLEConnectionError.ConId = mIndConfId[evt->data.evt_system_soft_timer.handle]; sInstance.mIndConfId[evt->data.evt_system_soft_timer.handle] = kUnusedIndex; event.CHIPoBLEConnectionError.Reason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } } diff --git a/src/platform/ESP32/ConnectivityManagerImpl.cpp b/src/platform/ESP32/ConnectivityManagerImpl.cpp index 8087adcd1e5f83..7790c45fac90b8 100644 --- a/src/platform/ESP32/ConnectivityManagerImpl.cpp +++ b/src/platform/ESP32/ConnectivityManagerImpl.cpp @@ -667,7 +667,7 @@ void ConnectivityManagerImpl::OnStationConnected() ChipDeviceEvent event; event.Type = DeviceEventType::kWiFiConnectivityChange; event.WiFiConnectivityChange.Result = kConnectivity_Established; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); UpdateInternetConnectivityState(); } @@ -680,7 +680,7 @@ void ConnectivityManagerImpl::OnStationDisconnected() ChipDeviceEvent event; event.Type = DeviceEventType::kWiFiConnectivityChange; event.WiFiConnectivityChange.Result = kConnectivity_Lost; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); UpdateInternetConnectivityState(); } @@ -950,7 +950,7 @@ void ConnectivityManagerImpl::UpdateInternetConnectivityState(void) event.InternetConnectivityChange.IPv4 = GetConnectivityChange(hadIPv4Conn, haveIPv4Conn); event.InternetConnectivityChange.IPv6 = GetConnectivityChange(hadIPv6Conn, haveIPv6Conn); addr.ToString(event.InternetConnectivityChange.address); - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); if (haveIPv4Conn != hadIPv4Conn) { @@ -981,7 +981,7 @@ void ConnectivityManagerImpl::OnStationIPv4AddressAvailable(const ip_event_got_i ChipDeviceEvent event; event.Type = DeviceEventType::kInterfaceIpAddressChanged; event.InterfaceIpAddressChanged.Type = InterfaceIpChangeType::kIpV4_Assigned; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } void ConnectivityManagerImpl::OnStationIPv4AddressLost(void) @@ -995,7 +995,7 @@ void ConnectivityManagerImpl::OnStationIPv4AddressLost(void) ChipDeviceEvent event; event.Type = DeviceEventType::kInterfaceIpAddressChanged; event.InterfaceIpAddressChanged.Type = InterfaceIpChangeType::kIpV4_Lost; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } void ConnectivityManagerImpl::OnIPv6AddressAvailable(const ip_event_got_ip6_t & got_ip) @@ -1014,7 +1014,7 @@ void ConnectivityManagerImpl::OnIPv6AddressAvailable(const ip_event_got_ip6_t & ChipDeviceEvent event; event.Type = DeviceEventType::kInterfaceIpAddressChanged; event.InterfaceIpAddressChanged.Type = InterfaceIpChangeType::kIpV6_Assigned; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } void ConnectivityManagerImpl::RefreshMessageLayer(void) {} diff --git a/src/platform/ESP32/PlatformManagerImpl.cpp b/src/platform/ESP32/PlatformManagerImpl.cpp index f6e7ef64bbf216..48ecb5e6ab81dc 100644 --- a/src/platform/ESP32/PlatformManagerImpl.cpp +++ b/src/platform/ESP32/PlatformManagerImpl.cpp @@ -192,7 +192,7 @@ void PlatformManagerImpl::HandleESPSystemEvent(void * arg, esp_event_base_t even } } - sInstance.PostEvent(&event); + sInstance.PostEventOrDie(&event); } } // namespace DeviceLayer diff --git a/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp b/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp index 3815cc8d2687d6..694fae36fc6288 100644 --- a/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp +++ b/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp @@ -280,7 +280,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) { ChipDeviceEvent connectionEvent; connectionEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; - PlatformMgr().PostEvent(&connectionEvent); + PlatformMgr().PostEventOrDie(&connectionEvent); } break; @@ -1007,7 +1007,7 @@ void BLEManagerImpl::HandleRXCharWrite(esp_ble_gatts_cb_param_t * param) event.Type = DeviceEventType::kCHIPoBLEWriteReceived; event.CHIPoBLEWriteReceived.ConId = param->write.conn_id; event.CHIPoBLEWriteReceived.Data = std::move(buf).UnsafeRelease(); - PlatformMgr().PostEvent(&event); + err = PlatformMgr().PostEvent(&event); } exit: @@ -1099,7 +1099,7 @@ void BLEManagerImpl::HandleTXCharCCCDWrite(esp_ble_gatts_cb_param_t * param) ChipDeviceEvent event; event.Type = (indicationsEnabled) ? DeviceEventType::kCHIPoBLESubscribe : DeviceEventType::kCHIPoBLEUnsubscribe; event.CHIPoBLESubscribe.ConId = param->write.conn_id; - PlatformMgr().PostEvent(&event); + err = PlatformMgr().PostEvent(&event); } ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", indicationsEnabled ? "subscribe" : "unsubscribe"); @@ -1131,7 +1131,7 @@ void BLEManagerImpl::HandleTXCharConfirm(CHIPoBLEConState * conState, esp_ble_ga ChipDeviceEvent event; event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; event.CHIPoBLEIndicateConfirm.ConId = param->conf.conn_id; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } else @@ -1140,7 +1140,7 @@ void BLEManagerImpl::HandleTXCharConfirm(CHIPoBLEConState * conState, esp_ble_ga event.Type = DeviceEventType::kCHIPoBLEConnectionError; event.CHIPoBLEConnectionError.ConId = param->disconnect.conn_id; event.CHIPoBLEConnectionError.Reason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } } @@ -1168,11 +1168,11 @@ void BLEManagerImpl::HandleDisconnect(esp_ble_gatts_cb_param_t * param) event.CHIPoBLEConnectionError.Reason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT; break; } - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); ChipDeviceEvent disconnectEvent; disconnectEvent.Type = DeviceEventType::kCHIPoBLEConnectionClosed; - PlatformMgr().PostEvent(&disconnectEvent); + PlatformMgr().PostEventOrDie(&disconnectEvent); // Force a refresh of the advertising state. mFlags.Set(Flags::kAdvertisingRefreshNeeded); @@ -1305,7 +1305,7 @@ void BLEManagerImpl::HandleGAPEvent(esp_gap_ble_cb_event_t event, esp_ble_gap_cb ChipDeviceEvent advChange; advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Started; - PlatformMgr().PostEvent(&advChange); + err = PlatformMgr().PostEvent(&advChange); } } @@ -1340,7 +1340,7 @@ void BLEManagerImpl::HandleGAPEvent(esp_gap_ble_cb_event_t event, esp_ble_gap_cb ChipDeviceEvent advChange; advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped; - PlatformMgr().PostEvent(&advChange); + err = PlatformMgr().PostEvent(&advChange); } } diff --git a/src/platform/ESP32/nimble/BLEManagerImpl.cpp b/src/platform/ESP32/nimble/BLEManagerImpl.cpp index bd29932eccad1d..09084da45900f1 100644 --- a/src/platform/ESP32/nimble/BLEManagerImpl.cpp +++ b/src/platform/ESP32/nimble/BLEManagerImpl.cpp @@ -279,7 +279,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) { ChipDeviceEvent connectionEvent; connectionEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; - PlatformMgr().PostEvent(&connectionEvent); + PlatformMgr().PostEventOrDie(&connectionEvent); } break; @@ -533,7 +533,7 @@ void BLEManagerImpl::DriveBLEState(void) ChipDeviceEvent advChange; advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Started; - PlatformMgr().PostEvent(&advChange); + err = PlatformMgr().PostEvent(&advChange); } } } @@ -568,7 +568,7 @@ void BLEManagerImpl::DriveBLEState(void) ChipDeviceEvent advChange; advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped; - PlatformMgr().PostEvent(&advChange); + err = PlatformMgr().PostEvent(&advChange); } } @@ -754,7 +754,7 @@ void BLEManagerImpl::HandleRXCharWrite(struct ble_gatt_char_context * param) event.Type = DeviceEventType::kCHIPoBLEWriteReceived; event.CHIPoBLEWriteReceived.ConId = param->conn_handle; event.CHIPoBLEWriteReceived.Data = std::move(buf).UnsafeRelease(); - PlatformMgr().PostEvent(&event); + err = PlatformMgr().PostEvent(&event); } exit: @@ -818,7 +818,7 @@ void BLEManagerImpl::HandleTXCharCCCDWrite(struct ble_gap_event * gapEvent) event.Type = (indicationsEnabled || notificationsEnabled) ? DeviceEventType::kCHIPoBLESubscribe : DeviceEventType::kCHIPoBLEUnsubscribe; event.CHIPoBLESubscribe.ConId = gapEvent->subscribe.conn_handle; - PlatformMgr().PostEvent(&event); + err = PlatformMgr().PostEvent(&event); } ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", @@ -846,7 +846,7 @@ CHIP_ERROR BLEManagerImpl::HandleTXComplete(struct ble_gap_event * gapEvent) ChipDeviceEvent event; event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; event.CHIPoBLEIndicateConfirm.ConId = gapEvent->notify_tx.conn_handle; - PlatformMgr().PostEvent(&event); + ReturnErrorOnFailure(PlatformMgr().PostEvent(&event)); } else @@ -855,7 +855,7 @@ CHIP_ERROR BLEManagerImpl::HandleTXComplete(struct ble_gap_event * gapEvent) event.Type = DeviceEventType::kCHIPoBLEConnectionError; event.CHIPoBLEConnectionError.ConId = gapEvent->notify_tx.conn_handle; event.CHIPoBLEConnectionError.Reason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT; - PlatformMgr().PostEvent(&event); + ReturnErrorOnFailure(PlatformMgr().PostEvent(&event)); } return CHIP_NO_ERROR; @@ -924,7 +924,7 @@ CHIP_ERROR BLEManagerImpl::HandleGAPDisconnect(struct ble_gap_event * gapEvent) ChipDeviceEvent disconnectEvent; disconnectEvent.Type = DeviceEventType::kCHIPoBLEConnectionClosed; - PlatformMgr().PostEvent(&disconnectEvent); + ReturnErrorOnFailure(PlatformMgr().PostEvent(&disconnectEvent)); // Force a reconfiguration of advertising in case we switched to non-connectable mode when // the BLE connection was established. diff --git a/src/platform/K32W/BLEManagerImpl.cpp b/src/platform/K32W/BLEManagerImpl.cpp index 76c0f13c6fd43e..69cbda3df32a56 100644 --- a/src/platform/K32W/BLEManagerImpl.cpp +++ b/src/platform/K32W/BLEManagerImpl.cpp @@ -403,7 +403,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX); connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; - PlatformMgr().PostEvent(&connEstEvent); + PlatformMgr().PostEventOrDie(&connEstEvent); break; case DeviceEventType::kCHIPoBLEUnsubscribe: @@ -510,7 +510,7 @@ bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUU { event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; event.CHIPoBLEIndicateConfirm.ConId = conId; - PlatformMgr().PostEvent(&event); + err = PlatformMgr().PostEvent(&event); } if (err != CHIP_NO_ERROR) @@ -908,7 +908,7 @@ CHIP_ERROR BLEManagerImpl::StartAdvertising(void) ChipDeviceEvent advChange; advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Started; - PlatformMgr().PostEvent(&advChange); + err = PlatformMgr().PostEvent(&advChange); } return err; @@ -917,6 +917,7 @@ CHIP_ERROR BLEManagerImpl::StartAdvertising(void) CHIP_ERROR BLEManagerImpl::StopAdvertising(void) { ble_err_t err; + CHIP_ERROR error = CHIP_NO_ERROR; if (mFlags.Has(Flags::kAdvertising)) { @@ -936,13 +937,13 @@ CHIP_ERROR BLEManagerImpl::StopAdvertising(void) ChipDeviceEvent advChange; advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped; - PlatformMgr().PostEvent(&advChange); + error = PlatformMgr().PostEvent(&advChange); } } } CancelBleAdvTimeoutTimer(); - return CHIP_NO_ERROR; + return error; } void BLEManagerImpl::DriveBLEState(void) @@ -1074,7 +1075,7 @@ void BLEManagerImpl::HandleConnectionCloseEvent(blekw_msg_t * msg) event.CHIPoBLEConnectionError.ConId = device_id_loc; event.CHIPoBLEConnectionError.Reason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); mFlags.Set(Flags::kRestartAdvertising); mFlags.Set(Flags::kFastAdvertisingEnabled); PlatformMgr().ScheduleWork(DriveBLEState, 0); @@ -1148,7 +1149,7 @@ void BLEManagerImpl::HandleTXCharCCCDWrite(blekw_msg_t * msg) { event.Type = DeviceEventType::kCHIPoBLESubscribe; event.CHIPoBLESubscribe.ConId = att_wr_data->device_id; - PlatformMgr().PostEvent(&event); + err = PlatformMgr().PostEvent(&event); } } } @@ -1157,7 +1158,7 @@ void BLEManagerImpl::HandleTXCharCCCDWrite(blekw_msg_t * msg) bleConnState->subscribed = 0; event.Type = DeviceEventType::kCHIPoBLEUnsubscribe; event.CHIPoBLESubscribe.ConId = att_wr_data->device_id; - PlatformMgr().PostEvent(&event); + err = PlatformMgr().PostEvent(&event); } exit: @@ -1195,7 +1196,7 @@ void BLEManagerImpl::HandleRXCharWrite(blekw_msg_t * msg) event.Type = DeviceEventType::kCHIPoBLEWriteReceived; event.CHIPoBLEWriteReceived.ConId = att_wr_data->device_id; event.CHIPoBLEWriteReceived.Data = std::move(buf).UnsafeRelease(); - PlatformMgr().PostEvent(&event); + err = PlatformMgr().PostEvent(&event); } exit: if (err != CHIP_NO_ERROR) diff --git a/src/platform/Linux/BLEManagerImpl.cpp b/src/platform/Linux/BLEManagerImpl.cpp index 0ff302258cab93..9a6ea424e02934 100644 --- a/src/platform/Linux/BLEManagerImpl.cpp +++ b/src/platform/Linux/BLEManagerImpl.cpp @@ -222,7 +222,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) { ChipDeviceEvent connectionEvent; connectionEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; - PlatformMgr().PostEvent(&connectionEvent); + PlatformMgr().PostEventOrDie(&connectionEvent); } break; @@ -439,7 +439,7 @@ void BLEManagerImpl::HandleNewConnection(BLE_CONNECTION_OBJECT conId) ChipDeviceEvent event; event.Type = DeviceEventType::kPlatformLinuxBLECentralConnected; event.Platform.BLECentralConnected.mConnection = conId; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } } @@ -450,7 +450,7 @@ void BLEManagerImpl::HandleConnectFailed(CHIP_ERROR error) ChipDeviceEvent event; event.Type = DeviceEventType::kPlatformLinuxBLECentralConnectFailed; event.Platform.BLECentralConnectFailed.mError = error; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } } @@ -459,7 +459,7 @@ void BLEManagerImpl::HandleWriteComplete(BLE_CONNECTION_OBJECT conId) ChipDeviceEvent event; event.Type = DeviceEventType::kPlatformLinuxBLEWriteComplete; event.Platform.BLEWriteComplete.mConnection = conId; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } void BLEManagerImpl::HandleSubscribeOpComplete(BLE_CONNECTION_OBJECT conId, bool subscribed) @@ -468,7 +468,7 @@ void BLEManagerImpl::HandleSubscribeOpComplete(BLE_CONNECTION_OBJECT conId, bool event.Type = DeviceEventType::kPlatformLinuxBLESubscribeOpComplete; event.Platform.BLESubscribeOpComplete.mConnection = conId; event.Platform.BLESubscribeOpComplete.mIsSubscribed = subscribed; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } void BLEManagerImpl::HandleTXCharChanged(BLE_CONNECTION_OBJECT conId, const uint8_t * value, size_t len) @@ -484,7 +484,7 @@ void BLEManagerImpl::HandleTXCharChanged(BLE_CONNECTION_OBJECT conId, const uint event.Type = DeviceEventType::kPlatformLinuxBLEIndicationReceived; event.Platform.BLEIndicationReceived.mConnection = conId; event.Platform.BLEIndicationReceived.mData = std::move(buf).UnsafeRelease(); - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); exit: if (err != CHIP_NO_ERROR) @@ -507,7 +507,7 @@ void BLEManagerImpl::HandleRXCharWrite(BLE_CONNECTION_OBJECT conId, const uint8_ ChipLogProgress(Ble, "Write request received debug %p", conId); event.CHIPoBLEWriteReceived.ConId = conId; event.CHIPoBLEWriteReceived.Data = std::move(buf).UnsafeRelease(); - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } exit: @@ -527,7 +527,7 @@ void BLEManagerImpl::CHIPoBluez_ConnectionClosed(BLE_CONNECTION_OBJECT conId) event.Type = DeviceEventType::kCHIPoBLEConnectionError; event.CHIPoBLEConnectionError.ConId = conId; event.CHIPoBLEConnectionError.Reason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } } @@ -546,7 +546,7 @@ void BLEManagerImpl::HandleTXCharCCCDWrite(BLE_CONNECTION_OBJECT conId) ChipDeviceEvent event; event.Type = connection->mIsNotify ? DeviceEventType::kCHIPoBLESubscribe : DeviceEventType::kCHIPoBLEUnsubscribe; event.CHIPoBLESubscribe.ConId = connection; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", connection->mIsNotify ? "subscribe" : "unsubscribe"); @@ -565,7 +565,7 @@ void BLEManagerImpl::HandleTXComplete(BLE_CONNECTION_OBJECT conId) ChipDeviceEvent event; event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; event.CHIPoBLEIndicateConfirm.ConId = conId; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } void BLEManagerImpl::DriveBLEState() @@ -745,7 +745,7 @@ void BLEManagerImpl::NotifyBLEPeripheralRegisterAppComplete(bool aIsSuccess, voi event.Type = DeviceEventType::kPlatformLinuxBLEPeripheralRegisterAppComplete; event.Platform.BLEPeripheralRegisterAppComplete.mIsSuccess = aIsSuccess; event.Platform.BLEPeripheralRegisterAppComplete.mpAppstate = apAppstate; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } void BLEManagerImpl::NotifyBLEPeripheralAdvConfiguredComplete(bool aIsSuccess, void * apAppstate) @@ -754,7 +754,7 @@ void BLEManagerImpl::NotifyBLEPeripheralAdvConfiguredComplete(bool aIsSuccess, v event.Type = DeviceEventType::kPlatformLinuxBLEPeripheralAdvConfiguredComplete; event.Platform.BLEPeripheralAdvConfiguredComplete.mIsSuccess = aIsSuccess; event.Platform.BLEPeripheralAdvConfiguredComplete.mpAppstate = apAppstate; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } void BLEManagerImpl::NotifyBLEPeripheralAdvStartComplete(bool aIsSuccess, void * apAppstate) @@ -763,7 +763,7 @@ void BLEManagerImpl::NotifyBLEPeripheralAdvStartComplete(bool aIsSuccess, void * event.Type = DeviceEventType::kPlatformLinuxBLEPeripheralAdvStartComplete; event.Platform.BLEPeripheralAdvStartComplete.mIsSuccess = aIsSuccess; event.Platform.BLEPeripheralAdvStartComplete.mpAppstate = apAppstate; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } void BLEManagerImpl::NotifyBLEPeripheralAdvStopComplete(bool aIsSuccess, void * apAppstate) @@ -772,7 +772,7 @@ void BLEManagerImpl::NotifyBLEPeripheralAdvStopComplete(bool aIsSuccess, void * event.Type = DeviceEventType::kPlatformLinuxBLEPeripheralAdvStopComplete; event.Platform.BLEPeripheralAdvStopComplete.mIsSuccess = aIsSuccess; event.Platform.BLEPeripheralAdvStopComplete.mpAppstate = apAppstate; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } void BLEManagerImpl::OnDeviceScanned(BluezDevice1 * device, const chip::Ble::ChipBLEDeviceIdentificationInfo & info) diff --git a/src/platform/Linux/ConnectivityManagerImpl.cpp b/src/platform/Linux/ConnectivityManagerImpl.cpp index 1aa807a8802c8e..4476e0093eae30 100644 --- a/src/platform/Linux/ConnectivityManagerImpl.cpp +++ b/src/platform/Linux/ConnectivityManagerImpl.cpp @@ -1042,7 +1042,7 @@ CHIP_ERROR ConnectivityManagerImpl::ProvisionWiFiNetwork(const char * ssid, cons ChipLogDetail(DeviceLayer, "Got IP address on interface: %s IP: %s", ifName, event.InternetConnectivityChange.address); - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } } } diff --git a/src/platform/Linux/PlatformManagerImpl.cpp b/src/platform/Linux/PlatformManagerImpl.cpp index 4604f34d1f3821..015221b74cc6de 100644 --- a/src/platform/Linux/PlatformManagerImpl.cpp +++ b/src/platform/Linux/PlatformManagerImpl.cpp @@ -107,7 +107,11 @@ void PlatformManagerImpl::WiFIIPChangeListener() ChipLogDetail(DeviceLayer, "Got IP address on interface: %s IP: %s", name, event.InternetConnectivityChange.address); - PlatformMgr().PostEvent(&event); + CHIP_ERROR status = PlatformMgr().PostEvent(&event); + if (status != CHIP_NO_ERROR) + { + ChipLogDetail(DeviceLayer, "Failed to report IP address: %" CHIP_ERROR_FORMAT, status.Format()); + } } routeInfo = RTA_NEXT(routeInfo, rtl); } diff --git a/src/platform/Linux/ThreadStackManagerImpl.cpp b/src/platform/Linux/ThreadStackManagerImpl.cpp index bbc3ca55d62bd2..8e8509ae47870b 100644 --- a/src/platform/Linux/ThreadStackManagerImpl.cpp +++ b/src/platform/Linux/ThreadStackManagerImpl.cpp @@ -107,13 +107,21 @@ void ThreadStackManagerImpl::ThreadDevcieRoleChangedHandler(const gchar * role) event.Type = DeviceEventType::kThreadConnectivityChange; event.ThreadConnectivityChange.Result = attached ? ConnectivityChange::kConnectivity_Established : ConnectivityChange::kConnectivity_Lost; - PlatformMgr().PostEvent(&event); + CHIP_ERROR status = PlatformMgr().PostEvent(&event); + if (status != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to post thread connectivity change: %" CHIP_ERROR_FORMAT, status.Format()); + } } mAttached = attached; event.Type = DeviceEventType::kThreadStateChange; event.ThreadStateChange.RoleChanged = true; - PlatformMgr().PostEvent(&event); + CHIP_ERROR status = PlatformMgr().PostEvent(&event); + if (status != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to post thread state change: %" CHIP_ERROR_FORMAT, status.Format()); + } } void ThreadStackManagerImpl::_ProcessThreadActivity() {} @@ -212,9 +220,7 @@ CHIP_ERROR ThreadStackManagerImpl::_SetThreadProvision(ByteSpan netInfo) ChipDeviceEvent event; event.Type = DeviceEventType::kServiceProvisioningChange; event.ServiceProvisioningChange.IsServiceProvisioned = true; - PlatformMgr().PostEvent(&event); - - return CHIP_NO_ERROR; + return PlatformMgr().PostEvent(&event); } CHIP_ERROR ThreadStackManagerImpl::_GetThreadProvision(ByteSpan & netInfo) diff --git a/src/platform/LwIPEventSupport.cpp b/src/platform/LwIPEventSupport.cpp index 9f92385092e484..f51a02b6689d7b 100644 --- a/src/platform/LwIPEventSupport.cpp +++ b/src/platform/LwIPEventSupport.cpp @@ -43,9 +43,7 @@ CHIP_ERROR PlatformEventing::PostEvent(System::Layer & aLayer, System::Object & event.ChipSystemLayerEvent.Target = &aTarget; event.ChipSystemLayerEvent.Argument = aArgument; - PlatformMgr().PostEvent(&event); - - return CHIP_NO_ERROR; + return PlatformMgr().PostEvent(&event); } CHIP_ERROR PlatformEventing::DispatchEvents(System::Layer & aLayer) diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp index 140df4b25ef605..b2d504477011a5 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp @@ -89,7 +89,11 @@ void GenericThreadStackManagerImpl_OpenThread::OnOpenThreadStateChang event.ThreadStateChange.ChildNodesChanged = (flags & (OT_CHANGED_THREAD_CHILD_ADDED | OT_CHANGED_THREAD_CHILD_REMOVED)) != 0; event.ThreadStateChange.OpenThread.Flags = flags; - PlatformMgr().PostEvent(&event); + CHIP_ERROR status = PlatformMgr().PostEvent(&event); + if (status != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to post Thread state change: %" CHIP_ERROR_FORMAT, status.Format()); + } } template @@ -240,14 +244,16 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_SetThreadProvis Impl()->LockThreadStack(); otErr = otDatasetSetActiveTlvs(mOTInst, &tlvs); Impl()->UnlockThreadStack(); + if (otErr != OT_ERROR_NONE) + { + return MapOpenThreadError(otErr); + } // post an event alerting other subsystems about change in provisioning state ChipDeviceEvent event; event.Type = DeviceEventType::kServiceProvisioningChange; event.ServiceProvisioningChange.IsServiceProvisioned = true; - PlatformMgr().PostEvent(&event); - - return MapOpenThreadError(otErr); + return PlatformMgr().PostEvent(&event); } template diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp index d73665f0a6f057..63e760a05e5677 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp @@ -153,7 +153,11 @@ void GenericThreadStackManagerImpl_OpenThread_LwIP::UpdateThreadInter event.Clear(); event.Type = DeviceEventType::kThreadConnectivityChange; event.ThreadConnectivityChange.Result = (isInterfaceUp) ? kConnectivity_Established : kConnectivity_Lost; - PlatformMgr().PostEvent(&event); + CHIP_ERROR status = PlatformMgr().PostEvent(&event); + if (status != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to post Thread connectivity change: %" CHIP_ERROR_FORMAT, status.Format()); + } } // Presume the interface addresses are also changing. diff --git a/src/platform/P6/BLEManagerImpl.cpp b/src/platform/P6/BLEManagerImpl.cpp index 6bc03659006835..5d28ec216217f8 100644 --- a/src/platform/P6/BLEManagerImpl.cpp +++ b/src/platform/P6/BLEManagerImpl.cpp @@ -80,7 +80,10 @@ wiced_result_t BLEManagerImpl::BLEManagerCallback(wiced_bt_management_evt_t even ChipDeviceEvent bleEvent; bleEvent.Type = DeviceEventType::kP6BLEEnabledEvt; - PlatformMgr().PostEvent(&bleEvent); + if (PlatformMgr().PostEvent(&bleEvent) != CHIP_NO_ERROR) + { + return WICED_BT_ERROR; + } } break; } @@ -238,7 +241,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) { ChipDeviceEvent _event; _event.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; - PlatformMgr().PostEvent(&_event); + PlatformMgr().PostEventOrDie(&_event); } break; @@ -428,7 +431,7 @@ void BLEManagerImpl::DriveBLEState(void) ChipDeviceEvent advChange; advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Started; - PlatformMgr().PostEvent(&advChange); + err = PlatformMgr().PostEvent(&advChange); } } } @@ -553,13 +556,18 @@ wiced_bt_gatt_status_t BLEManagerImpl::HandleGattServiceWrite(uint16_t conn_id, event.Type = DeviceEventType::kCHIPoBLEWriteReceived; event.CHIPoBLEWriteReceived.ConId = conn_id; event.CHIPoBLEWriteReceived.Data = buf; - PlatformMgr().PostEvent(&event); + CHIP_ERROR status = PlatformMgr().PostEvent(&event); + if (status != CHIP_NO_ERROR) + { + result = WICED_BT_GATT_INTERNAL_ERROR; + } buf = NULL; } } else { ChipLogError(DeviceLayer, "BLEManagerImpl: Out of buffers during CHIPoBLE RX"); + result = WICED_BT_GATT_NO_RESOURCES; } } else @@ -584,7 +592,10 @@ wiced_bt_gatt_status_t BLEManagerImpl::HandleGattServiceWrite(uint16_t conn_id, event.Type = (app_chip_service_char_tx_client_char_config[0] != 0) ? DeviceEventType::kCHIPoBLESubscribe : DeviceEventType::kCHIPoBLEUnsubscribe; event.CHIPoBLESubscribe.ConId = conn_id; - PlatformMgr().PostEvent(&event); + if (PlatformMgr().PostEvent(&event) != CHIP_NO_ERROR) + { + return WICED_BT_GATT_INTERNAL_ERROR; + } } ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", @@ -617,7 +628,10 @@ wiced_bt_gatt_status_t BLEManagerImpl::HandleGattServiceIndCfm(uint16_t conn_id, ChipDeviceEvent event; event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; event.CHIPoBLEIndicateConfirm.ConId = conn_id; - PlatformMgr().PostEvent(&event); + if (PlatformMgr().PostEvent(&event) != CHIP_NO_ERROR) + { + return WICED_BT_GATT_INTERNAL_ERROR; + } } return WICED_BT_GATT_SUCCESS; } @@ -691,7 +705,10 @@ wiced_bt_gatt_status_t BLEManagerImpl::HandleGattConnectEvent(wiced_bt_gatt_conn ChipLogProgress(DeviceLayer, "BLE GATT connection closed (con %u, reason %u)", p_conn_status->conn_id, p_conn_status->reason); - PlatformMgr().PostEvent(&event); + if (PlatformMgr().PostEvent(&event) != CHIP_NO_ERROR) + { + return WICED_BT_GATT_INTERNAL_ERROR; + } // Arrange to re-enable connectable advertising in case it was disabled due to the // maximum connection limit being reached. diff --git a/src/platform/P6/ConnectivityManagerImpl.cpp b/src/platform/P6/ConnectivityManagerImpl.cpp index 98e7849e1ea7f4..1dd9d940d4f04e 100644 --- a/src/platform/P6/ConnectivityManagerImpl.cpp +++ b/src/platform/P6/ConnectivityManagerImpl.cpp @@ -611,7 +611,7 @@ void ConnectivityManagerImpl::UpdateInternetConnectivityState(void) ChipDeviceEvent event; event.Type = DeviceEventType::kInterfaceIpAddressChanged; event.InterfaceIpAddressChanged.Type = InterfaceIpChangeType::kIpV4_Assigned; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } // Search among the IPv6 addresses assigned to the interface for a Global Unicast // address (2000::/3) that is in the valid state. If such an address is found... @@ -624,7 +624,7 @@ void ConnectivityManagerImpl::UpdateInternetConnectivityState(void) ChipDeviceEvent event; event.Type = DeviceEventType::kInterfaceIpAddressChanged; event.InterfaceIpAddressChanged.Type = InterfaceIpChangeType::kIpV6_Assigned; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } } } @@ -642,7 +642,7 @@ void ConnectivityManagerImpl::UpdateInternetConnectivityState(void) event.InternetConnectivityChange.IPv4 = GetConnectivityChange(hadIPv4Conn, haveIPv4Conn); event.InternetConnectivityChange.IPv6 = GetConnectivityChange(hadIPv6Conn, haveIPv6Conn); addr.ToString(event.InternetConnectivityChange.address); - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); if (haveIPv4Conn != hadIPv4Conn) { diff --git a/src/platform/Zephyr/BLEManagerImpl.cpp b/src/platform/Zephyr/BLEManagerImpl.cpp index b5196ccba871f2..0ad70bdc7cc349 100644 --- a/src/platform/Zephyr/BLEManagerImpl.cpp +++ b/src/platform/Zephyr/BLEManagerImpl.cpp @@ -285,7 +285,7 @@ CHIP_ERROR BLEManagerImpl::StartAdvertising(void) ChipDeviceEvent advChange; advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Started; - PlatformMgr().PostEvent(&advChange); + ReturnErrorOnFailure(PlatformMgr().PostEvent(&advChange)); } if (mFlags.Has(Flags::kFastAdvertisingEnabled)) @@ -324,7 +324,7 @@ CHIP_ERROR BLEManagerImpl::StopAdvertising(void) ChipDeviceEvent advChange; advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped; - PlatformMgr().PostEvent(&advChange); + ReturnErrorOnFailure(PlatformMgr().PostEvent(&advChange)); } // Cancel timer event disabling CHIPoBLE advertisement after timeout expiration @@ -469,7 +469,7 @@ CHIP_ERROR BLEManagerImpl::HandleGAPDisconnect(const ChipDeviceEvent * event) ChipDeviceEvent disconnectEvent; disconnectEvent.Type = DeviceEventType::kCHIPoBLEConnectionClosed; - PlatformMgr().PostEvent(&disconnectEvent); + ReturnErrorOnFailure(PlatformMgr().PostEvent(&disconnectEvent)); // Force a reconfiguration of advertising in case we switched to non-connectable mode when // the BLE connection was established. @@ -499,7 +499,7 @@ CHIP_ERROR BLEManagerImpl::HandleTXCharCCCDWrite(const ChipDeviceEvent * event) { ChipDeviceEvent conEstEvent; conEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; - PlatformMgr().PostEvent(&conEstEvent); + ReturnErrorOnFailure(PlatformMgr().PostEvent(&conEstEvent)); } } else @@ -764,7 +764,7 @@ ssize_t BLEManagerImpl::HandleRXWrite(struct bt_conn * conId, const struct bt_ga event.Type = DeviceEventType::kPlatformZephyrBleOutOfBuffersEvent; } - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); return len; } @@ -782,7 +782,7 @@ ssize_t BLEManagerImpl::HandleTXCCCWrite(struct bt_conn * conId, const struct bt event.Platform.BleCCCWriteEvent.BtConn = bt_conn_ref(conId); event.Platform.BleCCCWriteEvent.Value = value; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); return sizeof(value); } @@ -794,7 +794,7 @@ void BLEManagerImpl::HandleTXCompleted(struct bt_conn * conId, void * /* param * event.Type = DeviceEventType::kPlatformZephyrBleTXComplete; event.Platform.BleTXCompleteEvent.BtConn = bt_conn_ref(conId); - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } void BLEManagerImpl::HandleConnect(struct bt_conn * conId, uint8_t err) @@ -810,7 +810,7 @@ void BLEManagerImpl::HandleConnect(struct bt_conn * conId, uint8_t err) event.Platform.BleConnEvent.BtConn = bt_conn_ref(conId); event.Platform.BleConnEvent.HciResult = err; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); exit: PlatformMgr().UnlockChipStack(); @@ -829,7 +829,7 @@ void BLEManagerImpl::HandleDisconnect(struct bt_conn * conId, uint8_t reason) event.Platform.BleConnEvent.BtConn = bt_conn_ref(conId); event.Platform.BleConnEvent.HciResult = reason; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); exit: PlatformMgr().UnlockChipStack(); diff --git a/src/platform/cc13x2_26x2/BLEManagerImpl.cpp b/src/platform/cc13x2_26x2/BLEManagerImpl.cpp index 38f2ec2a0d39ac..8f8905c96c5254 100644 --- a/src/platform/cc13x2_26x2/BLEManagerImpl.cpp +++ b/src/platform/cc13x2_26x2/BLEManagerImpl.cpp @@ -241,7 +241,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; - PlatformMgr().PostEvent(&connEstEvent); + PlatformMgr().PostEventOrDie(&connEstEvent); } break; @@ -900,7 +900,7 @@ void BLEManagerImpl::ProcessEvtHdrMsg(QueuedEvt_t * pMsg) event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; event.CHIPoBLEIndicateConfirm.ConId = connHandle; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); dealloc = TRUE; } @@ -984,7 +984,7 @@ void BLEManagerImpl::ProcessEvtHdrMsg(QueuedEvt_t * pMsg) // Post event to CHIP event.CHIPoBLESubscribe.ConId = (void *) connHandle; } - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } break; @@ -1144,7 +1144,7 @@ void BLEManagerImpl::ProcessGapMessage(gapEventHdr_t * pMsg) event.Type = DeviceEventType::kCHIPoBLEConnectionError; event.CHIPoBLEConnectionError.ConId = (void *) &pPkt->connectionHandle; event.CHIPoBLEConnectionError.Reason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); DriveBLEState(); @@ -1248,7 +1248,7 @@ uint8_t BLEManagerImpl::ProcessGATTMsg(gattMsgEvent_t * pMsg) event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; event.CHIPoBLEIndicateConfirm.ConId = connHandle; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); BLEMGR_LOG("BLEMGR: ProcessGATTMsg, ATT_HANDLE_VALUE_CFM:"); } diff --git a/src/platform/fake/PlatformManagerImpl.h b/src/platform/fake/PlatformManagerImpl.h index 7e726374e909cd..0483a4c88d0893 100644 --- a/src/platform/fake/PlatformManagerImpl.h +++ b/src/platform/fake/PlatformManagerImpl.h @@ -50,7 +50,7 @@ class PlatformManagerImpl final : public PlatformManager void _RunEventLoop() {} CHIP_ERROR _StartEventLoopTask() { return CHIP_ERROR_NOT_IMPLEMENTED; } CHIP_ERROR _StopEventLoopTask() { return CHIP_ERROR_NOT_IMPLEMENTED; } - void _PostEvent(const ChipDeviceEvent * event) {} + CHIP_ERROR _PostEvent(const ChipDeviceEvent * event) { return CHIP_NO_ERROR; } void _DispatchEvent(const ChipDeviceEvent * event) {} CHIP_ERROR _StartChipTimer(int64_t durationMS) { return CHIP_ERROR_NOT_IMPLEMENTED; } diff --git a/src/platform/mbed/BLEManagerImpl.cpp b/src/platform/mbed/BLEManagerImpl.cpp index 7b8733bc4a6836..e297d26331cb96 100644 --- a/src/platform/mbed/BLEManagerImpl.cpp +++ b/src/platform/mbed/BLEManagerImpl.cpp @@ -184,7 +184,7 @@ class GapEventHandler : private mbed::NonCopyable, public ble:: ChipDeviceEvent chip_event; chip_event.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; chip_event.CHIPoBLEAdvertisingChange.Result = kActivity_Started; - PlatformMgrImpl().PostEvent(&chip_event); + PlatformMgrImpl().PostEventOrDie(&chip_event); PlatformMgr().ScheduleWork(ble_manager.DriveBLEState, 0); } @@ -208,7 +208,7 @@ class GapEventHandler : private mbed::NonCopyable, public ble:: ChipDeviceEvent chip_event; chip_event.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; chip_event.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped; - PlatformMgrImpl().PostEvent(&chip_event); + PlatformMgrImpl().PostEventOrDie(&chip_event); if (event.isConnected()) { @@ -305,7 +305,7 @@ class GapEventHandler : private mbed::NonCopyable, public ble:: chip_event.CHIPoBLEConnectionError.Reason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT; break; } - PlatformMgrImpl().PostEvent(&chip_event); + PlatformMgrImpl().PostEventOrDie(&chip_event); ChipLogProgress(DeviceLayer, "BLE connection terminated, mbed-os reason: %d", reason.value()); ChipLogProgress(DeviceLayer, "Current number of connections: %" PRIu16 "/%d", ble_manager.NumConnections(), @@ -397,7 +397,7 @@ struct CHIPService : public ble::GattServer::EventHandler chip_event.Type = DeviceEventType::kCHIPoBLEWriteReceived; chip_event.CHIPoBLEWriteReceived.ConId = params->connHandle; chip_event.CHIPoBLEWriteReceived.Data = std::move(buf).UnsafeRelease(); - PlatformMgrImpl().PostEvent(&chip_event); + PlatformMgrImpl().PostEventOrDie(&chip_event); } else { @@ -447,7 +447,7 @@ struct CHIPService : public ble::GattServer::EventHandler ChipDeviceEvent chip_event; chip_event.Type = DeviceEventType::kCHIPoBLESubscribe; chip_event.CHIPoBLESubscribe.ConId = params.connHandle; - PlatformMgrImpl().PostEvent(&chip_event); + PlatformMgrImpl().PostEventOrDie(&chip_event); } } @@ -460,7 +460,7 @@ struct CHIPService : public ble::GattServer::EventHandler ChipDeviceEvent chip_event; chip_event.Type = DeviceEventType::kCHIPoBLEUnsubscribe; chip_event.CHIPoBLEUnsubscribe.ConId = params.connHandle; - PlatformMgrImpl().PostEvent(&chip_event); + PlatformMgrImpl().PostEventOrDie(&chip_event); } } @@ -473,7 +473,7 @@ struct CHIPService : public ble::GattServer::EventHandler ChipDeviceEvent chip_event; chip_event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; chip_event.CHIPoBLEIndicateConfirm.ConId = params.connHandle; - PlatformMgrImpl().PostEvent(&chip_event); + PlatformMgrImpl().PostEventOrDie(&chip_event); } } @@ -926,7 +926,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) ChipLogDetail(DeviceLayer, "_OnPlatformEvent kCHIPoBLESubscribe"); HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX); connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; - PlatformMgrImpl().PostEvent(&connEstEvent); + PlatformMgrImpl().PostEventOrDie(&connEstEvent); } break; diff --git a/src/platform/mbed/ConnectivityManagerImpl.cpp b/src/platform/mbed/ConnectivityManagerImpl.cpp index c2a24562f1b949..81edfdaddf7c24 100644 --- a/src/platform/mbed/ConnectivityManagerImpl.cpp +++ b/src/platform/mbed/ConnectivityManagerImpl.cpp @@ -246,7 +246,7 @@ CHIP_ERROR ConnectivityManagerImpl::OnStationConnected() ChipDeviceEvent event; event.Type = DeviceEventType::kWiFiConnectivityChange; event.WiFiConnectivityChange.Result = kConnectivity_Established; - PlatformMgr().PostEvent(&event); + ReturnErrorOnFailure(PlatformMgr().PostEvent(&event)); ChipLogProgress(DeviceLayer, "Event - StationConnected"); } @@ -263,7 +263,7 @@ CHIP_ERROR ConnectivityManagerImpl::OnStationConnected() event.Type = DeviceEventType::kInternetConnectivityChange; event.InternetConnectivityChange.IPv4 = kConnectivity_Lost; event.InternetConnectivityChange.IPv6 = kConnectivity_NoChange; - PlatformMgr().PostEvent(&event); + ReturnErrorOnFailure(PlatformMgr().PostEvent(&event)); ChipLogError(DeviceLayer, "Unnexpected loss of Ip4 address"); } } @@ -277,7 +277,7 @@ CHIP_ERROR ConnectivityManagerImpl::OnStationConnected() event.Type = DeviceEventType::kInternetConnectivityChange; event.InternetConnectivityChange.IPv4 = kConnectivity_Established; event.InternetConnectivityChange.IPv6 = kConnectivity_NoChange; - PlatformMgr().PostEvent(&event); + ReturnErrorOnFailure(PlatformMgr().PostEvent(&event)); ChipLogProgress(DeviceLayer, "New Ip4 address set: %s", address.get_ip_address()); } } @@ -294,7 +294,7 @@ CHIP_ERROR ConnectivityManagerImpl::OnStationConnected() event.Type = DeviceEventType::kInternetConnectivityChange; event.InternetConnectivityChange.IPv4 = kConnectivity_NoChange; event.InternetConnectivityChange.IPv6 = kConnectivity_Lost; - PlatformMgr().PostEvent(&event); + ReturnErrorOnFailure(PlatformMgr().PostEvent(&event)); ChipLogError(DeviceLayer, "Unnexpected loss of Ip6 address"); } } @@ -308,7 +308,7 @@ CHIP_ERROR ConnectivityManagerImpl::OnStationConnected() event.Type = DeviceEventType::kInternetConnectivityChange; event.InternetConnectivityChange.IPv4 = kConnectivity_NoChange; event.InternetConnectivityChange.IPv6 = kConnectivity_Established; - PlatformMgr().PostEvent(&event); + ReturnErrorOnFailure(PlatformMgr().PostEvent(&event)); ChipLogProgress(DeviceLayer, "New Ip6 address set %s", address.get_ip_address()); } } @@ -326,7 +326,7 @@ CHIP_ERROR ConnectivityManagerImpl::OnStationDisconnected() ChipDeviceEvent event; event.Type = DeviceEventType::kWiFiConnectivityChange; event.WiFiConnectivityChange.Result = kConnectivity_Lost; - PlatformMgr().PostEvent(&event); + ReturnErrorOnFailure(PlatformMgr().PostEvent(&event)); ChipLogProgress(DeviceLayer, "Event - StationDisconnected"); } @@ -339,7 +339,7 @@ CHIP_ERROR ConnectivityManagerImpl::OnStationDisconnected() event.Type = DeviceEventType::kInternetConnectivityChange; event.InternetConnectivityChange.IPv4 = kConnectivity_Lost; event.InternetConnectivityChange.IPv6 = kConnectivity_NoChange; - PlatformMgr().PostEvent(&event); + ReturnErrorOnFailure(PlatformMgr().PostEvent(&event)); ChipLogError(DeviceLayer, "Loss of Ip4 address"); } @@ -351,7 +351,7 @@ CHIP_ERROR ConnectivityManagerImpl::OnStationDisconnected() event.Type = DeviceEventType::kInternetConnectivityChange; event.InternetConnectivityChange.IPv4 = kConnectivity_NoChange; event.InternetConnectivityChange.IPv6 = kConnectivity_Lost; - PlatformMgr().PostEvent(&event); + ReturnErrorOnFailure(PlatformMgr().PostEvent(&event)); ChipLogError(DeviceLayer, "Loss of Ip6 address"); } diff --git a/src/platform/mbed/PlatformManagerImpl.cpp b/src/platform/mbed/PlatformManagerImpl.cpp index 66235a1437e233..2ddb6e2a7efb06 100644 --- a/src/platform/mbed/PlatformManagerImpl.cpp +++ b/src/platform/mbed/PlatformManagerImpl.cpp @@ -106,7 +106,7 @@ void PlatformManagerImpl::_UnlockChipStack() mChipStackMutex.unlock(); } -void PlatformManagerImpl::_PostEvent(const ChipDeviceEvent * eventPtr) +CHIP_ERROR PlatformManagerImpl::_PostEvent(const ChipDeviceEvent * eventPtr) { auto handle = mQueue.call([event = *eventPtr, this] { LockChipStack(); @@ -117,7 +117,9 @@ void PlatformManagerImpl::_PostEvent(const ChipDeviceEvent * eventPtr) if (!handle) { ChipLogError(DeviceLayer, "Error posting event: Not enough memory"); + return CHIP_ERROR_NO_MEMORY; } + return CHIP_NO_ERROR; } void PlatformManagerImpl::ProcessDeviceEvents() diff --git a/src/platform/mbed/PlatformManagerImpl.h b/src/platform/mbed/PlatformManagerImpl.h index ad9cff5c552d3e..ff5c04e558e5e9 100644 --- a/src/platform/mbed/PlatformManagerImpl.h +++ b/src/platform/mbed/PlatformManagerImpl.h @@ -77,7 +77,7 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener void _LockChipStack(); bool _TryLockChipStack(); void _UnlockChipStack(); - void _PostEvent(const ChipDeviceEvent * event); + CHIP_ERROR _PostEvent(const ChipDeviceEvent * event); void _RunEventLoop(); CHIP_ERROR _StartEventLoopTask(); CHIP_ERROR _StopEventLoopTask(); @@ -96,6 +96,7 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener friend class Internal::CHIPService; using PlatformManager::PostEvent; + using PlatformManager::PostEventOrDie; static PlatformManagerImpl sInstance; // ===== Members for internal use. diff --git a/src/platform/qpg/BLEManagerImpl.cpp b/src/platform/qpg/BLEManagerImpl.cpp index 3133972ec7ec25..ab210702860f06 100644 --- a/src/platform/qpg/BLEManagerImpl.cpp +++ b/src/platform/qpg/BLEManagerImpl.cpp @@ -199,7 +199,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLESubscribe"); HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; - PlatformMgr().PostEvent(&connEstEvent); + PlatformMgr().PostEventOrDie(&connEstEvent); } break; @@ -559,7 +559,7 @@ CHIP_ERROR BLEManagerImpl::StopAdvertising(void) ChipDeviceEvent advChange; advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped; - PlatformMgr().PostEvent(&advChange); + err = PlatformMgr().PostEvent(&advChange); } } @@ -612,7 +612,7 @@ void BLEManagerImpl::HandleRXCharWrite(uint16_t connId, uint16_t handle, uint8_t event.Type = DeviceEventType::kCHIPoBLEWriteReceived; event.CHIPoBLEWriteReceived.ConId = connId; event.CHIPoBLEWriteReceived.Data = std::move(buf).UnsafeRelease(); - PlatformMgr().PostEvent(&event); + err = PlatformMgr().PostEvent(&event); } exit: @@ -658,7 +658,7 @@ void BLEManagerImpl::HandleTXCharCCCDWrite(qvCHIP_Ble_AttsCccEvt_t * pEvt) ChipDeviceEvent event; event.Type = (notificationsEnabled) ? DeviceEventType::kCHIPoBLESubscribe : DeviceEventType::kCHIPoBLEUnsubscribe; event.CHIPoBLESubscribe.ConId = pEvt->hdr.param; - PlatformMgr().PostEvent(&event); + err = PlatformMgr().PostEvent(&event); } ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", notificationsEnabled ? "subscribe" : "unsubscribe"); @@ -706,7 +706,7 @@ void BLEManagerImpl::HandleDmMsg(qvCHIP_Ble_DmEvt_t * pDmEvt) ChipDeviceEvent advChange; advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Started; - PlatformMgr().PostEvent(&advChange); + PlatformMgr().PostEventOrDie(&advChange); } } break; @@ -764,7 +764,7 @@ void BLEManagerImpl::HandleDmMsg(qvCHIP_Ble_DmEvt_t * pDmEvt) event.CHIPoBLEConnectionError.Reason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT; break; } - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); } mFlags.Set(Flags::kAdvertisingRefreshNeeded); @@ -793,7 +793,7 @@ void BLEManagerImpl::HandleAttMsg(qvCHIP_Ble_AttEvt_t * pAttEvt) event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; event.CHIPoBLEIndicateConfirm.ConId = pAttEvt->hdr.param; - PlatformMgr().PostEvent(&event); + PlatformMgr().PostEventOrDie(&event); break; } case QVCHIP_ATTC_FIND_BY_TYPE_VALUE_RSP: From 97d9f7ea368735ed8c4b68dea8114f3df398032e Mon Sep 17 00:00:00 2001 From: chrisdecenzo <61757564+chrisdecenzo@users.noreply.github.com> Date: Tue, 14 Sep 2021 10:37:29 -0700 Subject: [PATCH 037/255] Address 9154 and CM/AC DNS-SD convergence (#9348) * Address 9154 and CM/AC DNS-SD convergence * Attempt to fix CI build caused by weird branch confusion * Merge with TOT * fix merge * fix unit tests, non-linux builds * fix CI * fix CI * fix CI * fix CI * fix unit tests * fix CI * fix CI * Address feedback, move Mdns to MdnsServer singleton * Address feedback * Address feedback * Fix build * editorial - rearrange header file * fix python * fix build * address comments --- .../esp32/main/DeviceCallbacks.cpp | 6 +- examples/all-clusters-app/esp32/main/main.cpp | 3 +- .../bridge-app/esp32/main/DeviceCallbacks.cpp | 6 +- .../DiscoverCommissionablesCommand.cpp | 2 +- examples/lighting-app/mbed/main/AppTask.cpp | 2 +- .../lock-app/esp32/main/DeviceCallbacks.cpp | 6 +- examples/lock-app/mbed/main/AppTask.cpp | 2 +- examples/lock-app/p6/src/AppTask.cpp | 2 +- examples/minimal-mdns/advertiser.cpp | 63 +++-- examples/minimal-mdns/client.cpp | 5 +- .../linux/CommissioneeShellCommands.cpp | 29 ++- .../platform/nrfconnect/util/ThreadUtil.cpp | 2 +- .../esp32/main/DeviceCallbacks.cpp | 6 +- examples/tv-casting-app/linux/main.cpp | 4 +- .../operational-credentials-server.cpp | 4 +- src/app/server/Mdns.cpp | 231 ++++++++++++++---- src/app/server/Mdns.h | 125 +++++++--- src/app/server/RendezvousServer.cpp | 10 +- src/app/server/Server.cpp | 8 +- ...issionableNodeController-ScriptBinding.cpp | 2 +- .../ChipDeviceController-ScriptBinding.cpp | 20 +- src/controller/python/chip-device-ctrl.py | 13 +- src/controller/python/chip/ChipDeviceCtrl.py | 14 +- src/include/platform/CHIPDeviceConfig.h | 23 ++ src/lib/mdns/Advertiser.h | 23 +- src/lib/mdns/Advertiser_ImplMinimalMdns.cpp | 34 +-- src/lib/mdns/Discovery_ImplPlatform.cpp | 25 +- src/lib/mdns/Resolver.h | 30 +-- src/lib/mdns/ServiceNaming.cpp | 14 +- src/lib/mdns/TxtFields.cpp | 12 - src/lib/mdns/TxtFields.h | 1 - src/lib/mdns/minimal/tests/TestAdvertiser.cpp | 105 +++++--- src/lib/mdns/platform/tests/TestPlatform.cpp | 95 ++++--- src/lib/mdns/tests/TestServiceNaming.cpp | 41 +--- src/lib/mdns/tests/TestTxtFields.cpp | 30 +-- src/lib/shell/commands/Dns.cpp | 4 - 36 files changed, 588 insertions(+), 414 deletions(-) diff --git a/examples/all-clusters-app/esp32/main/DeviceCallbacks.cpp b/examples/all-clusters-app/esp32/main/DeviceCallbacks.cpp index 0cff5a0d0fd203..37974e44d537de 100644 --- a/examples/all-clusters-app/esp32/main/DeviceCallbacks.cpp +++ b/examples/all-clusters-app/esp32/main/DeviceCallbacks.cpp @@ -81,7 +81,7 @@ void DeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, intptr_ // will not trigger a 'internet connectivity change' as there is no internet // connectivity. MDNS still wants to refresh its listening interfaces to include the // newly selected address. - chip::app::Mdns::StartServer(); + chip::app::MdnsServer::Instance().StartServer(); } break; } @@ -127,7 +127,7 @@ void DeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event { ESP_LOGI(TAG, "Server ready at: %s:%d", event->InternetConnectivityChange.address, CHIP_PORT); wifiLED.Set(true); - chip::app::Mdns::StartServer(); + chip::app::MdnsServer::Instance().StartServer(); } else if (event->InternetConnectivityChange.IPv4 == kConnectivity_Lost) { @@ -137,7 +137,7 @@ void DeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event if (event->InternetConnectivityChange.IPv6 == kConnectivity_Established) { ESP_LOGI(TAG, "IPv6 Server ready..."); - chip::app::Mdns::StartServer(); + chip::app::MdnsServer::Instance().StartServer(); } else if (event->InternetConnectivityChange.IPv6 == kConnectivity_Lost) { diff --git a/examples/all-clusters-app/esp32/main/main.cpp b/examples/all-clusters-app/esp32/main/main.cpp index b03f796547d431..605daed52ec57b 100644 --- a/examples/all-clusters-app/esp32/main/main.cpp +++ b/examples/all-clusters-app/esp32/main/main.cpp @@ -354,7 +354,8 @@ class SetupListModel : public ListScreen::Model } else if (i == 2) { - app::Mdns::AdvertiseCommissionableNode(app::Mdns::CommissioningMode::kEnabledBasic); + app::MdnsServer::Instance().StartServer(Mdns::CommissioningMode::kEnabledBasic); + chip::Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow( ResetFabrics::kYes, kNoCommissioningTimeout, CommissioningWindowAdvertisement::kMdns); } diff --git a/examples/bridge-app/esp32/main/DeviceCallbacks.cpp b/examples/bridge-app/esp32/main/DeviceCallbacks.cpp index 2f13dac65addf3..3836f26a64f99a 100644 --- a/examples/bridge-app/esp32/main/DeviceCallbacks.cpp +++ b/examples/bridge-app/esp32/main/DeviceCallbacks.cpp @@ -51,7 +51,7 @@ void DeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, intptr_ // will not trigger a 'internet connectivity change' as there is no internet // connectivity. MDNS still wants to refresh its listening interfaces to include the // newly selected address. - chip::app::Mdns::StartServer(); + chip::app::MdnsServer::Instance().StartServer(); } break; } @@ -71,7 +71,7 @@ void DeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event if (event->InternetConnectivityChange.IPv4 == kConnectivity_Established) { ESP_LOGI(TAG, "Server ready at: %s:%d", event->InternetConnectivityChange.address, CHIP_PORT); - chip::app::Mdns::StartServer(); + chip::app::MdnsServer::Instance().StartServer(); } else if (event->InternetConnectivityChange.IPv4 == kConnectivity_Lost) { @@ -80,7 +80,7 @@ void DeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event if (event->InternetConnectivityChange.IPv6 == kConnectivity_Established) { ESP_LOGI(TAG, "IPv6 Server ready..."); - chip::app::Mdns::StartServer(); + chip::app::MdnsServer::Instance().StartServer(); } else if (event->InternetConnectivityChange.IPv6 == kConnectivity_Lost) { diff --git a/examples/chip-tool/commands/discover/DiscoverCommissionablesCommand.cpp b/examples/chip-tool/commands/discover/DiscoverCommissionablesCommand.cpp index 949685d9963e00..cf43ea2b1a705b 100644 --- a/examples/chip-tool/commands/discover/DiscoverCommissionablesCommand.cpp +++ b/examples/chip-tool/commands/discover/DiscoverCommissionablesCommand.cpp @@ -43,10 +43,10 @@ void DiscoverCommissionablesCommand::Shutdown() ChipLogProgress(Discovery, "Commissionable Node %d", i); ChipLogProgress(Discovery, "\tHost name:\t\t%s", dnsSdInfo->hostName); + ChipLogProgress(Discovery, "\tPort:\t\t\t%u", dnsSdInfo->port); ChipLogProgress(Discovery, "\tLong discriminator:\t%u", dnsSdInfo->longDiscriminator); ChipLogProgress(Discovery, "\tVendor ID:\t\t%u", dnsSdInfo->vendorId); ChipLogProgress(Discovery, "\tProduct ID:\t\t%u", dnsSdInfo->productId); - ChipLogProgress(Discovery, "\tAdditional Pairing\t%u", dnsSdInfo->additionalPairing); ChipLogProgress(Discovery, "\tCommissioning Mode\t%u", dnsSdInfo->commissioningMode); ChipLogProgress(Discovery, "\tDevice Type\t\t%u", dnsSdInfo->deviceType); ChipLogProgress(Discovery, "\tDevice Name\t\t%s", dnsSdInfo->deviceName); diff --git a/examples/lighting-app/mbed/main/AppTask.cpp b/examples/lighting-app/mbed/main/AppTask.cpp index 08f48fb5c11405..8494c3f7060404 100644 --- a/examples/lighting-app/mbed/main/AppTask.cpp +++ b/examples/lighting-app/mbed/main/AppTask.cpp @@ -87,7 +87,7 @@ int AppTask::Init() if (event->InternetConnectivityChange.IPv4 == kConnectivity_Established || event->InternetConnectivityChange.IPv6 == kConnectivity_Established) { - chip::app::Mdns::StartServer(); + chip::app::MdnsServer::Instance().StartServer(); } } }, diff --git a/examples/lock-app/esp32/main/DeviceCallbacks.cpp b/examples/lock-app/esp32/main/DeviceCallbacks.cpp index 2532387b162cc3..0157f5402b223b 100644 --- a/examples/lock-app/esp32/main/DeviceCallbacks.cpp +++ b/examples/lock-app/esp32/main/DeviceCallbacks.cpp @@ -61,7 +61,7 @@ void DeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, intptr_ // will not trigger a 'internet connectivity change' as there is no internet // connectivity. MDNS still wants to refresh its listening interfaces to include the // newly selected address. - chip::app::Mdns::StartServer(); + chip::app::MdnsServer::Instance().StartServer(); } break; } @@ -93,7 +93,7 @@ void DeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event if (event->InternetConnectivityChange.IPv4 == kConnectivity_Established) { ESP_LOGI(TAG, "Server ready at: %s:%d", event->InternetConnectivityChange.address, CHIP_PORT); - chip::app::Mdns::StartServer(); + chip::app::MdnsServer::Instance().StartServer(); } else if (event->InternetConnectivityChange.IPv4 == kConnectivity_Lost) { @@ -102,7 +102,7 @@ void DeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event if (event->InternetConnectivityChange.IPv6 == kConnectivity_Established) { ESP_LOGI(TAG, "IPv6 Server ready..."); - chip::app::Mdns::StartServer(); + chip::app::MdnsServer::Instance().StartServer(); } else if (event->InternetConnectivityChange.IPv6 == kConnectivity_Lost) { diff --git a/examples/lock-app/mbed/main/AppTask.cpp b/examples/lock-app/mbed/main/AppTask.cpp index 33a96bb4946768..df3e88189c7ab4 100644 --- a/examples/lock-app/mbed/main/AppTask.cpp +++ b/examples/lock-app/mbed/main/AppTask.cpp @@ -89,7 +89,7 @@ int AppTask::Init() if (event->InternetConnectivityChange.IPv4 == kConnectivity_Established || event->InternetConnectivityChange.IPv6 == kConnectivity_Established) { - chip::app::Mdns::StartServer(); + chip::app::MdnsServer::Instance().StartServer(); } } }, diff --git a/examples/lock-app/p6/src/AppTask.cpp b/examples/lock-app/p6/src/AppTask.cpp index 746e3d4ae71210..64d8b1f15b40a7 100644 --- a/examples/lock-app/p6/src/AppTask.cpp +++ b/examples/lock-app/p6/src/AppTask.cpp @@ -96,7 +96,7 @@ CHIP_ERROR AppTask::Init() if (event->InternetConnectivityChange.IPv4 == kConnectivity_Established || event->InternetConnectivityChange.IPv6 == kConnectivity_Established) { - chip::app::Mdns::StartServer(); + chip::app::MdnsServer::Instance().StartServer(); } } }, diff --git a/examples/minimal-mdns/advertiser.cpp b/examples/minimal-mdns/advertiser.cpp index 393250b164fc80..74ea7163d1d3dd 100644 --- a/examples/minimal-mdns/advertiser.cpp +++ b/examples/minimal-mdns/advertiser.cpp @@ -49,10 +49,9 @@ struct Options Optional deviceName; // commisionable node params - uint8_t shortDiscriminator = 52; - uint16_t longDiscriminator = 840; - bool commissioningMode = false; - bool commissioningModeOpenWindow = false; + uint8_t shortDiscriminator = 52; + uint16_t longDiscriminator = 840; + Mdns::CommissioningMode commissioningMode = Mdns::CommissioningMode::kDisabled; Optional rotatingId; Optional pairingInstr; Optional pairingHint; @@ -78,14 +77,14 @@ constexpr uint16_t kOptionCommisioningPairingHint = 0x300; constexpr uint16_t kOptionCommisioningDeviceType = 0x400; constexpr uint16_t kOptionCommisioningDeviceName = 0x500; constexpr uint16_t kOptionCommisioningMode = 0x600; -constexpr uint16_t kOptionCommisioningModeOpenWindow = 0x700; -constexpr uint16_t kOptionCommisioningRotatingId = 0x800; +constexpr uint16_t kOptionCommisioningRotatingId = 0x700; constexpr uint16_t kOptionOperationalFabricId = 'f'; constexpr uint16_t kOptionOperationalNodeId = 'n'; bool HandleOptions(const char * aProgram, OptionSet * aOptions, int aIdentifier, const char * aName, const char * aValue) { + uint8_t cm; switch (aIdentifier) { case kOptionEnableIpV4: @@ -124,10 +123,15 @@ bool HandleOptions(const char * aProgram, OptionSet * aOptions, int aIdentifier, gOptions.productId = Optional::Value(static_cast(atoi(aValue))); return true; case kOptionCommisioningMode: - gOptions.commissioningMode = true; - return true; - case kOptionCommisioningModeOpenWindow: - gOptions.commissioningModeOpenWindow = true; + cm = static_cast(atoi(aValue)); + if (cm == 1) + { + gOptions.commissioningMode = Mdns::CommissioningMode::kEnabledBasic; + } + if (cm == 2) + { + gOptions.commissioningMode = Mdns::CommissioningMode::kEnabledEnhanced; + } return true; case kOptionCommisioningDeviceType: gOptions.deviceType = Optional::Value(static_cast(atoi(aValue))); @@ -174,8 +178,7 @@ OptionDef cmdLineOptionsDef[] = { { "long-discriminator", kArgumentRequired, kOptionCommisioningLongDiscriminaotr }, { "vendor-id", kArgumentRequired, kOptionCommisioningVendorId }, { "product-id", kArgumentRequired, kOptionCommisioningProductId }, - { "commissioning-mode-enabled", kNoArgument, kOptionCommisioningMode }, - { "commissioning-mode-open-window", kNoArgument, kOptionCommisioningModeOpenWindow }, + { "commissioning-mode", kNoArgument, kOptionCommisioningMode }, { "device-type", kArgumentRequired, kOptionCommisioningDeviceType }, { "device-name", kArgumentRequired, kOptionCommisioningDeviceName }, { "rotating-id", kArgumentRequired, kOptionCommisioningRotatingId }, @@ -207,10 +210,8 @@ OptionSet cmdLineOptions = { HandleOptions, cmdLineOptionsDef, "PROGRAM OPTIONS" " --product-id \n" " -p \n" " Commisioning/commisionable product id.\n" - " --commissioning-mode-enabled\n" - " Commissioning Mode Enabled.\n" - " --commissioning-mode-open-window\n" - " Commissioning Mode as a result of Open Commissioning Window.\n" + " --commissioning-mode \n" + " Commissioning Mode (0=disabled, 1=basic, 2=enhanced).\n" " --device-type \n" " Device type id.\n" " --device-name \n" @@ -265,22 +266,20 @@ int main(int argc, char ** args) if (gOptions.advertisingMode == AdvertisingMode::kCommissionableNode) { printf("Advertise Commissionable Node\n"); - err = chip::Mdns::ServiceAdvertiser::Instance().Advertise( - chip::Mdns::CommissionAdvertisingParameters() - .EnableIpV4(gOptions.enableIpV4) - .SetPort(CHIP_PORT) - .SetShortDiscriminator(gOptions.shortDiscriminator) - .SetLongDiscriminator(gOptions.longDiscriminator) - .SetMac(chip::ByteSpan(gOptions.mac, 6)) - .SetVendorId(gOptions.vendorId) - .SetProductId(gOptions.productId) - .SetCommissioningMode(gOptions.commissioningMode) - .SetAdditionalCommissioning(gOptions.commissioningModeOpenWindow) - .SetDeviceType(gOptions.deviceType) - .SetDeviceName(gOptions.deviceName) - .SetRotatingId(gOptions.rotatingId) - .SetPairingInstr(gOptions.pairingInstr) - .SetPairingHint(gOptions.pairingHint)); + err = chip::Mdns::ServiceAdvertiser::Instance().Advertise(chip::Mdns::CommissionAdvertisingParameters() + .EnableIpV4(gOptions.enableIpV4) + .SetPort(CHIP_PORT) + .SetShortDiscriminator(gOptions.shortDiscriminator) + .SetLongDiscriminator(gOptions.longDiscriminator) + .SetMac(chip::ByteSpan(gOptions.mac, 6)) + .SetVendorId(gOptions.vendorId) + .SetProductId(gOptions.productId) + .SetCommissioningMode(gOptions.commissioningMode) + .SetDeviceType(gOptions.deviceType) + .SetDeviceName(gOptions.deviceName) + .SetRotatingId(gOptions.rotatingId) + .SetPairingInstr(gOptions.pairingInstr) + .SetPairingHint(gOptions.pairingHint)); } else if (gOptions.advertisingMode == AdvertisingMode::kOperational) { diff --git a/examples/minimal-mdns/client.cpp b/examples/minimal-mdns/client.cpp index 3637f41b9c248b..947202c166a6f7 100644 --- a/examples/minimal-mdns/client.cpp +++ b/examples/minimal-mdns/client.cpp @@ -309,6 +309,7 @@ int main(int argc, char ** args) mdns::Minimal::Server<20> mdnsServer; ReportDelegate reporter; + CHIP_ERROR err; mdnsServer.SetDelegate(&reporter); @@ -316,7 +317,7 @@ int main(int argc, char ** args) MdnsExample::AllInterfaces allInterfaces(gOptions.enableIpV4); - CHIP_ERROR err = mdnsServer.Listen(&chip::DeviceLayer::InetLayer, &allInterfaces, gOptions.listenPort); + err = mdnsServer.Listen(&chip::DeviceLayer::InetLayer, &allInterfaces, gOptions.listenPort); if (err != CHIP_NO_ERROR) { printf("Server failed to listen on all interfaces: %s\n", chip::ErrorStr(err)); @@ -326,7 +327,7 @@ int main(int argc, char ** args) BroadcastPacket(&mdnsServer); - CHIP_ERROR err = DeviceLayer::SystemLayer().StartTimer( + err = DeviceLayer::SystemLayer().StartTimer( gOptions.runtimeMs, [](System::Layer *, void *) { DeviceLayer::PlatformMgr().StopEventLoopTask(); diff --git a/examples/platform/linux/CommissioneeShellCommands.cpp b/examples/platform/linux/CommissioneeShellCommands.cpp index 24bb09856ffe66..a379080b9b3246 100644 --- a/examples/platform/linux/CommissioneeShellCommands.cpp +++ b/examples/platform/linux/CommissioneeShellCommands.cpp @@ -62,6 +62,13 @@ static CHIP_ERROR PrintAllCommands() streamer_printf(sout, " sendudc
Send UDC message to address. Usage: commissionee sendudc 127.0.0.1 5543\r\n"); #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT + streamer_printf( + sout, " setdiscoverytimeout Set discovery timeout in seconds. Usage: commissionee setdiscoverytimeout 30\r\n"); +#if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY + streamer_printf(sout, + " setextendeddiscoverytimeout Set extendeddiscovery timeout in seconds. Usage: commissionee " + "setextendeddiscoverytimeout 30\r\n"); +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY streamer_printf(sout, " restartmdns (disabled|enabled_basic|enabled_enhanced) Start Mdns with given " "settings. Usage: commissionee " @@ -89,6 +96,22 @@ static CHIP_ERROR CommissioneeHandler(int argc, char ** argv) return error = SendUDC(true, chip::Transport::PeerAddress::UDP(commissioner, port)); } #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT + else if (strcmp(argv[0], "setdiscoverytimeout") == 0) + { + char * eptr; + int16_t timeout = (int16_t) strtol(argv[1], &eptr, 10); + chip::app::MdnsServer::Instance().SetDiscoveryTimeoutSecs(timeout); + return CHIP_NO_ERROR; + } +#if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY + else if (strcmp(argv[0], "setextendeddiscoverytimeout") == 0) + { + char * eptr; + int16_t timeout = (int16_t) strtol(argv[1], &eptr, 10); + chip::app::MdnsServer::Instance().SetExtendedDiscoveryTimeoutSecs(timeout); + return CHIP_NO_ERROR; + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY else if (strcmp(argv[0], "restartmdns") == 0) { if (argc < 2) @@ -97,17 +120,17 @@ static CHIP_ERROR CommissioneeHandler(int argc, char ** argv) } if (strcmp(argv[1], "disabled") == 0) { - chip::app::Mdns::StartServer(chip::app::Mdns::CommissioningMode::kDisabled); + chip::app::MdnsServer::Instance().StartServer(chip::Mdns::CommissioningMode::kDisabled); return CHIP_NO_ERROR; } if (strcmp(argv[1], "enabled_basic") == 0) { - chip::app::Mdns::StartServer(chip::app::Mdns::CommissioningMode::kEnabledBasic); + chip::app::MdnsServer::Instance().StartServer(chip::Mdns::CommissioningMode::kEnabledBasic); return CHIP_NO_ERROR; } else if (strcmp(argv[1], "enabled_enhanced") == 0) { - chip::app::Mdns::StartServer(chip::app::Mdns::CommissioningMode::kEnabledEnhanced); + chip::app::MdnsServer::Instance().StartServer(chip::Mdns::CommissioningMode::kEnabledEnhanced); return CHIP_NO_ERROR; } return PrintAllCommands(); diff --git a/examples/platform/nrfconnect/util/ThreadUtil.cpp b/examples/platform/nrfconnect/util/ThreadUtil.cpp index eb7ef6d933584f..84e7ea17d69bf2 100644 --- a/examples/platform/nrfconnect/util/ThreadUtil.cpp +++ b/examples/platform/nrfconnect/util/ThreadUtil.cpp @@ -46,5 +46,5 @@ void StartDefaultThreadNetwork(void) chip::DeviceLayer::ThreadStackMgr().SetThreadProvision(dataset.AsByteSpan()); chip::DeviceLayer::ThreadStackMgr().SetThreadEnabled(true); - chip::app::Mdns::StartServer(); + chip::app::MdnsServer::Instance().StartServer(); } diff --git a/examples/temperature-measurement-app/esp32/main/DeviceCallbacks.cpp b/examples/temperature-measurement-app/esp32/main/DeviceCallbacks.cpp index 7935d6a9bb0123..05477dd95d7001 100644 --- a/examples/temperature-measurement-app/esp32/main/DeviceCallbacks.cpp +++ b/examples/temperature-measurement-app/esp32/main/DeviceCallbacks.cpp @@ -57,7 +57,7 @@ void DeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, intptr_ // will not trigger a 'internet connectivity change' as there is no internet // connectivity. MDNS still wants to refresh its listening interfaces to include the // newly selected address. - chip::app::Mdns::StartServer(); + chip::app::MdnsServer::Instance().StartServer(); } break; } @@ -82,7 +82,7 @@ void DeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event if (event->InternetConnectivityChange.IPv4 == kConnectivity_Established) { ESP_LOGI(TAG, "Server ready at: %s:%d", event->InternetConnectivityChange.address, CHIP_PORT); - chip::app::Mdns::StartServer(); + chip::app::MdnsServer::Instance().StartServer(); } else if (event->InternetConnectivityChange.IPv4 == kConnectivity_Lost) { @@ -91,7 +91,7 @@ void DeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event if (event->InternetConnectivityChange.IPv6 == kConnectivity_Established) { ESP_LOGI(TAG, "IPv6 Server ready..."); - chip::app::Mdns::StartServer(); + chip::app::MdnsServer::Instance().StartServer(); } else if (event->InternetConnectivityChange.IPv6 == kConnectivity_Lost) { diff --git a/examples/tv-casting-app/linux/main.cpp b/examples/tv-casting-app/linux/main.cpp index 542c46a37329d8..12353f99de8c33 100644 --- a/examples/tv-casting-app/linux/main.cpp +++ b/examples/tv-casting-app/linux/main.cpp @@ -53,10 +53,10 @@ void PrepareForCommissioning(const Mdns::DiscoveredNodeData * selectedCommission if (selectedCommissioner != nullptr) { // Advertise self as Commissionable Node over mDNS - ReturnOnFailure(app::Mdns::AdvertiseCommissionableNode(app::Mdns::CommissioningMode::kEnabledBasic)); + app::MdnsServer::Instance().StartServer(Mdns::CommissioningMode::kEnabledBasic); // Send User Directed commissioning request - ReturnOnFailure(SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress::UDP( + ReturnOnFailure(Server::GetInstance().SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress::UDP( selectedCommissioner->ipAddress[0], selectedCommissioner->port, selectedCommissioner->interfaceId[0]))); } #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT diff --git a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp index 68a84e83e63697..a638e085bbf573 100644 --- a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp +++ b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp @@ -406,7 +406,7 @@ bool emberAfOperationalCredentialsClusterAddNOCCallback(EndpointId endpoint, app VerifyOrExit(err == CHIP_NO_ERROR, nocResponse = ConvertToNOCResponseStatus(err)); // We might have a new operational identity, so we should start advertising it right away. - chip::app::Mdns::AdvertiseOperational(); + app::MdnsServer::Instance().AdvertiseOperational(); exit: @@ -443,7 +443,7 @@ bool emberAfOperationalCredentialsClusterUpdateNOCCallback(EndpointId endpoint, // can't just wait until we get network configuration commands, because we // might be on the operational network already, in which case we are // expected to be live with our new identity at this point. - app::Mdns::AdvertiseOperational(); + app::MdnsServer::Instance().AdvertiseOperational(); exit: diff --git a/src/app/server/Mdns.cpp b/src/app/server/Mdns.cpp index 92d03782307a2e..aa40927efd5211 100644 --- a/src/app/server/Mdns.cpp +++ b/src/app/server/Mdns.cpp @@ -27,16 +27,16 @@ #include #include #include +#include #include #include +#include #include #include namespace chip { namespace app { -namespace Mdns { - namespace { bool HaveOperationalCredentials() @@ -78,37 +78,172 @@ chip::ByteSpan FillMAC(uint8_t (&mac)[8]) } // namespace -uint16_t gSecuredPort = CHIP_PORT; -uint16_t gUnsecuredPort = CHIP_UDC_PORT; +#if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY + +constexpr const char kExtendedDiscoveryTimeoutKeypairStorage[] = "ExtDiscKey"; + +void MdnsServer::SetExtendedDiscoveryTimeoutSecs(int16_t secs) +{ + ChipLogDetail(Discovery, "SetExtendedDiscoveryTimeoutSecs %d", secs); + chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Put(kExtendedDiscoveryTimeoutKeypairStorage, &secs, sizeof(secs)); +} + +int16_t MdnsServer::GetExtendedDiscoveryTimeoutSecs() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + int16_t secs; + + err = chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Get(kExtendedDiscoveryTimeoutKeypairStorage, &secs, sizeof(secs)); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Discovery, "Failed to get extended timeout configuration err: %s", chip::ErrorStr(err)); + secs = CHIP_DEVICE_CONFIG_EXTENDED_DISCOVERY_TIMEOUT_SECS; + } + + ChipLogDetail(Discovery, "GetExtendedDiscoveryTimeoutSecs %d", secs); + return secs; +} + +/// Callback from Extended Discovery Expiration timer +void HandleExtendedDiscoveryExpiration(System::Layer * aSystemLayer, void * aAppState) +{ + MdnsServer::Instance().OnExtendedDiscoveryExpiration(aSystemLayer, aAppState); +} -void SetSecuredPort(uint16_t port) +void MdnsServer::OnExtendedDiscoveryExpiration(System::Layer * aSystemLayer, void * aAppState) { - gSecuredPort = port; + if (!MdnsServer::OnExpiration(mExtendedDiscoveryExpirationMs)) + { + ChipLogDetail(Discovery, "OnExtendedDiscoveryExpiration callback for cleared session"); + return; + } + + ChipLogDetail(Discovery, "OnExtendedDiscoveryExpiration callback for valid session"); + + mExtendedDiscoveryExpirationMs = TIMEOUT_CLEARED; +} +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY + +/// Callback from Discovery Expiration timer +void HandleDiscoveryExpiration(System::Layer * aSystemLayer, void * aAppState) +{ + MdnsServer::Instance().OnDiscoveryExpiration(aSystemLayer, aAppState); +} + +bool MdnsServer::OnExpiration(uint64_t expirationMs) +{ + if (expirationMs == TIMEOUT_CLEARED) + { + ChipLogDetail(Discovery, "OnExpiration callback for cleared session"); + return false; + } + uint64_t now = mTimeSource.GetCurrentMonotonicTimeMs(); + if (expirationMs > now) + { + ChipLogDetail(Discovery, "OnExpiration callback for reset session"); + return false; + } + + ChipLogDetail(Discovery, "OnExpiration - valid time out"); + + // reset advertising + CHIP_ERROR err; + err = chip::Mdns::ServiceAdvertiser::Instance().StopPublishDevice(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Discovery, "Failed to stop ServiceAdvertiser: %s", chip::ErrorStr(err)); + } + err = chip::Mdns::ServiceAdvertiser::Instance().Start(&chip::DeviceLayer::InetLayer, chip::Mdns::kMdnsPort); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Discovery, "Failed to start ServiceAdvertiser: %s", chip::ErrorStr(err)); + } + + // restart operational (if needed) + err = AdvertiseOperational(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Discovery, "Failed to advertise operational node: %s", chip::ErrorStr(err)); + } + +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY + err = AdvertiseCommissioner(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Discovery, "Failed to advertise commissioner: %s", chip::ErrorStr(err)); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY + + return true; } -uint16_t GetSecuredPort() +void MdnsServer::OnDiscoveryExpiration(System::Layer * aSystemLayer, void * aAppState) { - return gSecuredPort; + if (!MdnsServer::OnExpiration(mDiscoveryExpirationMs)) + { + ChipLogDetail(Discovery, "OnDiscoveryExpiration callback for cleared session"); + return; + } + + ChipLogDetail(Discovery, "OnDiscoveryExpiration callback for valid session"); + +#if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY + int16_t extTimeout = GetExtendedDiscoveryTimeoutSecs(); + if (extTimeout != CHIP_DEVICE_CONFIG_DISCOVERY_DISABLED) + { + CHIP_ERROR err = AdvertiseCommissionableNode(chip::Mdns::CommissioningMode::kDisabled); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Discovery, "Failed to advertise extended commissionable node: %s", chip::ErrorStr(err)); + } + // set timeout + ScheduleExtendedDiscoveryExpiration(); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY + + mDiscoveryExpirationMs = TIMEOUT_CLEARED; } -void SetUnsecuredPort(uint16_t port) +CHIP_ERROR MdnsServer::ScheduleDiscoveryExpiration() { - gUnsecuredPort = port; + if (mDiscoveryTimeoutSecs == CHIP_DEVICE_CONFIG_DISCOVERY_NO_TIMEOUT) + { + return CHIP_NO_ERROR; + } + ChipLogDetail(Discovery, "Scheduling Discovery timeout in secs=%d", mDiscoveryTimeoutSecs); + + mDiscoveryExpirationMs = mTimeSource.GetCurrentMonotonicTimeMs() + static_cast(mDiscoveryTimeoutSecs) * 1000; + + return DeviceLayer::SystemLayer().StartTimer(static_cast(mDiscoveryTimeoutSecs) * 1000, HandleDiscoveryExpiration, + nullptr); } -uint16_t GetUnsecuredPort() +#if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY +CHIP_ERROR MdnsServer::ScheduleExtendedDiscoveryExpiration() { - return gUnsecuredPort; + int16_t extendedDiscoveryTimeoutSecs = GetExtendedDiscoveryTimeoutSecs(); + if (extendedDiscoveryTimeoutSecs == CHIP_DEVICE_CONFIG_DISCOVERY_NO_TIMEOUT) + { + return CHIP_NO_ERROR; + } + ChipLogDetail(Discovery, "Scheduling Extended Discovery timeout in secs=%d", extendedDiscoveryTimeoutSecs); + + mExtendedDiscoveryExpirationMs = + mTimeSource.GetCurrentMonotonicTimeMs() + static_cast(extendedDiscoveryTimeoutSecs) * 1000; + + return DeviceLayer::SystemLayer().StartTimer(static_cast(extendedDiscoveryTimeoutSecs) * 1000, + HandleExtendedDiscoveryExpiration, nullptr); } +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY -CHIP_ERROR GetCommissionableInstanceName(char * buffer, size_t bufferLen) +CHIP_ERROR MdnsServer::GetCommissionableInstanceName(char * buffer, size_t bufferLen) { auto & mdnsAdvertiser = chip::Mdns::ServiceAdvertiser::Instance(); return mdnsAdvertiser.GetCommissionableInstanceName(buffer, bufferLen); } /// Set MDNS operational advertisement -CHIP_ERROR AdvertiseOperational() +CHIP_ERROR MdnsServer::AdvertiseOperational() { for (const Transport::FabricInfo & fabricInfo : Server::GetInstance().GetFabricTable()) { @@ -137,24 +272,15 @@ CHIP_ERROR AdvertiseOperational() return CHIP_NO_ERROR; } -/// Overloaded utility method for commissioner and commissionable advertisement -/// This method is used for both commissioner discovery and commissionable node discovery since -/// they share many fields. -/// commissionableNode = true : advertise commissionable node -/// commissionableNode = false : advertise commissioner -CHIP_ERROR Advertise(bool commissionableNode, CommissioningMode mode) +CHIP_ERROR MdnsServer::Advertise(bool commissionableNode, chip::Mdns::CommissioningMode mode) { - bool commissioningMode = (mode != CommissioningMode::kDisabled); - bool additionalCommissioning = (mode == CommissioningMode::kEnabledEnhanced); - auto advertiseParameters = chip::Mdns::CommissionAdvertisingParameters() .SetPort(commissionableNode ? GetSecuredPort() : GetUnsecuredPort()) .EnableIpV4(true); advertiseParameters.SetCommissionAdvertiseMode(commissionableNode ? chip::Mdns::CommssionAdvertiseMode::kCommissionableNode : chip::Mdns::CommssionAdvertiseMode::kCommissioner); - advertiseParameters.SetCommissioningMode(commissioningMode); - advertiseParameters.SetAdditionalCommissioning(additionalCommissioning); + advertiseParameters.SetCommissioningMode(mode); char pairingInst[chip::Mdns::kKeyPairingInstructionMaxLength + 1]; @@ -206,7 +332,7 @@ CHIP_ERROR Advertise(bool commissionableNode, CommissioningMode mode) advertiseParameters.SetRotatingId(chip::Optional::Value(rotatingDeviceIdHexBuffer)); #endif - if (!additionalCommissioning) + if (mode != chip::Mdns::CommissioningMode::kEnabledEnhanced) { if (DeviceLayer::ConfigurationMgr().GetInitialPairingHint(value) != CHIP_NO_ERROR) { @@ -255,26 +381,36 @@ CHIP_ERROR Advertise(bool commissionableNode, CommissioningMode mode) return mdnsAdvertiser.Advertise(advertiseParameters); } -/// Set MDNS commissioner advertisement -CHIP_ERROR AdvertiseCommissioner() +CHIP_ERROR MdnsServer::AdvertiseCommissioner() { - return Advertise(false /* commissionableNode */, CommissioningMode::kDisabled); + return Advertise(false /* commissionableNode */, chip::Mdns::CommissioningMode::kDisabled); } -/// Set MDNS commissionable node advertisement -CHIP_ERROR AdvertiseCommissionableNode(CommissioningMode mode) +CHIP_ERROR MdnsServer::AdvertiseCommissionableNode(chip::Mdns::CommissioningMode mode) { return Advertise(true /* commissionableNode */, mode); } -/// (Re-)starts the minmdns server -/// - if device has not yet been commissioned, then commissioning mode will show as enabled (CM=1, AC=0) -/// - if device has been commissioned, then commissioning mode will reflect the state of mode argument -void StartServer(CommissioningMode mode) +void MdnsServer::StartServer(chip::Mdns::CommissioningMode mode) { - CHIP_ERROR err = chip::Mdns::ServiceAdvertiser::Instance().Start(&chip::DeviceLayer::InetLayer, chip::Mdns::kMdnsPort); + ChipLogDetail(Discovery, "Mdns StartServer mode=%d", static_cast(mode)); - err = app::Mdns::AdvertiseOperational(); + ClearTimeouts(); + + CHIP_ERROR err; + err = chip::Mdns::ServiceAdvertiser::Instance().StopPublishDevice(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Discovery, "Failed to stop ServiceAdvertiser: %s", chip::ErrorStr(err)); + } + + err = chip::Mdns::ServiceAdvertiser::Instance().Start(&chip::DeviceLayer::InetLayer, chip::Mdns::kMdnsPort); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Discovery, "Failed to start ServiceAdvertiser: %s", chip::ErrorStr(err)); + } + + err = AdvertiseOperational(); if (err != CHIP_NO_ERROR) { ChipLogError(Discovery, "Failed to advertise operational node: %s", chip::ErrorStr(err)); @@ -282,22 +418,26 @@ void StartServer(CommissioningMode mode) if (HaveOperationalCredentials()) { - if (mode != CommissioningMode::kDisabled) + ChipLogError(Discovery, "Have operational credentials"); + if (mode != chip::Mdns::CommissioningMode::kDisabled) { - err = app::Mdns::AdvertiseCommissionableNode(mode); + err = AdvertiseCommissionableNode(mode); if (err != CHIP_NO_ERROR) { ChipLogError(Discovery, "Failed to advertise commissionable node: %s", chip::ErrorStr(err)); } + // no need to set timeout because callers are currently doing that and their timeout might be longer than the default } #if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY - else + else if (GetExtendedDiscoveryTimeoutSecs() != CHIP_DEVICE_CONFIG_DISCOVERY_DISABLED) { - err = app::Mdns::AdvertiseCommissionableNode(mode); + err = AdvertiseCommissionableNode(mode); if (err != CHIP_NO_ERROR) { ChipLogError(Discovery, "Failed to advertise extended commissionable node: %s", chip::ErrorStr(err)); } + // set timeout + ScheduleExtendedDiscoveryExpiration(); } #endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY } @@ -305,16 +445,18 @@ void StartServer(CommissioningMode mode) { #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DISCOVERY ChipLogProgress(Discovery, "Start dns-sd server - no current nodeId"); - err = app::Mdns::AdvertiseCommissionableNode(CommissioningMode::kEnabledBasic); + err = AdvertiseCommissionableNode(chip::Mdns::CommissioningMode::kEnabledBasic); if (err != CHIP_NO_ERROR) { ChipLogError(Discovery, "Failed to advertise unprovisioned commissionable node: %s", chip::ErrorStr(err)); } + // set timeout + ScheduleDiscoveryExpiration(); #endif } #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY - err = app::Mdns::AdvertiseCommissioner(); + err = AdvertiseCommissioner(); if (err != CHIP_NO_ERROR) { ChipLogError(Discovery, "Failed to advertise commissioner: %s", chip::ErrorStr(err)); @@ -323,7 +465,7 @@ void StartServer(CommissioningMode mode) } #if CHIP_ENABLE_ROTATING_DEVICE_ID -CHIP_ERROR GenerateRotatingDeviceId(char rotatingDeviceIdHexBuffer[], size_t rotatingDeviceIdHexBufferSize) +CHIP_ERROR MdnsServer::GenerateRotatingDeviceId(char rotatingDeviceIdHexBuffer[], size_t rotatingDeviceIdHexBufferSize) { char serialNumber[chip::DeviceLayer::ConfigurationManager::kMaxSerialNumberLength + 1]; size_t serialNumberSize = 0; @@ -339,6 +481,5 @@ CHIP_ERROR GenerateRotatingDeviceId(char rotatingDeviceIdHexBuffer[], size_t rot } #endif -} // namespace Mdns } // namespace app } // namespace chip diff --git a/src/app/server/Mdns.h b/src/app/server/Mdns.h index 2e8d60d468ea8b..671f313bc000a1 100644 --- a/src/app/server/Mdns.h +++ b/src/app/server/Mdns.h @@ -18,50 +18,119 @@ #pragma once #include +#include +#include #include +#include namespace chip { namespace app { -namespace Mdns { -enum class CommissioningMode +#define TIMEOUT_CLEARED 0 +class DLL_EXPORT MdnsServer { - kDisabled, // Commissioning Mode is disabled, CM=0, AC=0 in DNS-SD key/value pairs - kEnabledBasic, // Basic Commissioning Mode, CM=1, AC=0 in DNS-SD key/value pairs - kEnabledEnhanced // Enhanced Commissioning Mode, CM=1, AC=1 in DNS-SD key/value pairs -}; +public: + /// Provides the system-wide implementation of the service advertiser + static MdnsServer & Instance() + { + static MdnsServer instance; + return instance; + } + + /// Sets the secure Matter port + void SetSecuredPort(uint16_t port) { mSecuredPort = port; } + + /// Gets the secure Matter port + uint16_t GetSecuredPort() { return mSecuredPort; } + + /// Sets the unsecure Matter port + void SetUnsecuredPort(uint16_t port) { mUnsecuredPort = port; } + + /// Gets the unsecure Matter port + uint16_t GetUnsecuredPort() { return mUnsecuredPort; } + + /// Sets the factory-new state commissionable node discovery timeout + void SetDiscoveryTimeoutSecs(int16_t secs) { mDiscoveryTimeoutSecs = secs; } + + /// Gets the factory-new state commissionable node discovery timeout + int16_t GetDiscoveryTimeoutSecs() { return mDiscoveryTimeoutSecs; } + + /// Callback from Discovery Expiration timer + /// Checks if discovery has expired and if so, + /// kicks off extend discovery (when enabled) + /// otherwise, stops commissionable node advertising + /// Discovery Expiration refers here to commissionable node advertising when in commissioning mode + void OnDiscoveryExpiration(System::Layer * aSystemLayer, void * aAppState); -/// Sets the secure Matter port -void SetSecuredPort(uint16_t port); +#if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY + /// Sets the extended discovery timeout. Value will be persisted across reboots + void SetExtendedDiscoveryTimeoutSecs(int16_t secs); -/// Gets the secure Matter port -uint16_t GetSecuredPort(); + /// Callback from Extended Discovery Expiration timer + /// Checks if extended discovery has expired and if so, + /// stops commissionable node advertising + /// Extended Discovery Expiration refers here to commissionable node advertising when NOT in commissioning mode + void OnExtendedDiscoveryExpiration(System::Layer * aSystemLayer, void * aAppState); +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY -/// Sets the unsecure Matter port -void SetUnsecuredPort(uint16_t port); + /// Start operational advertising + CHIP_ERROR AdvertiseOperational(); -/// Gets the unsecure Matter port -uint16_t GetUnsecuredPort(); + /// (Re-)starts the minmdns server + /// - if device has not yet been commissioned, then commissioning mode will show as enabled (CM=1, AC=0) + /// - if device has been commissioned, then commissioning mode will reflect the state of mode argument + void StartServer(chip::Mdns::CommissioningMode mode = chip::Mdns::CommissioningMode::kDisabled); -/// Start operational advertising -CHIP_ERROR AdvertiseOperational(); + CHIP_ERROR GenerateRotatingDeviceId(char rotatingDeviceIdHexBuffer[], size_t rotatingDeviceIdHexBufferSize); -/// Set MDNS commissioner advertisement -CHIP_ERROR AdvertiseCommissioner(); + /// Generates the (random) instance name that a CHIP device is to use for pre-commissioning DNS-SD + CHIP_ERROR GetCommissionableInstanceName(char * buffer, size_t bufferLen); -/// Set MDNS commissionable node advertisement -CHIP_ERROR AdvertiseCommissionableNode(CommissioningMode mode); +private: + /// Overloaded utility method for commissioner and commissionable advertisement + /// This method is used for both commissioner discovery and commissionable node discovery since + /// they share many fields. + /// commissionableNode = true : advertise commissionable node + /// commissionableNode = false : advertise commissioner + CHIP_ERROR Advertise(bool commissionableNode, chip::Mdns::CommissioningMode mode); -/// (Re-)starts the minmdns server -/// - if device has not yet been commissioned, then commissioning mode will show as enabled (CM=1, AC=0) -/// - if device has been commissioned, then commissioning mode will reflect the state of mode argument -void StartServer(CommissioningMode mode = CommissioningMode::kDisabled); + /// Set MDNS commissioner advertisement + CHIP_ERROR AdvertiseCommissioner(); -CHIP_ERROR GenerateRotatingDeviceId(char rotatingDeviceIdHexBuffer[], size_t rotatingDeviceIdHexBufferSize); + /// Set MDNS commissionable node advertisement + CHIP_ERROR AdvertiseCommissionableNode(chip::Mdns::CommissioningMode mode); -/// Generates the (random) instance name that a CHIP device is to use for pre-commissioning DNS-SD -CHIP_ERROR GetCommissionableInstanceName(char * buffer, size_t bufferLen); + Time::TimeSource mTimeSource; + + void ClearTimeouts() + { + mDiscoveryExpirationMs = TIMEOUT_CLEARED; +#if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY + mExtendedDiscoveryExpirationMs = TIMEOUT_CLEARED; +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY + } + + uint16_t mSecuredPort = CHIP_PORT; + uint16_t mUnsecuredPort = CHIP_UDC_PORT; + + /// schedule next discovery expiration + CHIP_ERROR ScheduleDiscoveryExpiration(); + int16_t mDiscoveryTimeoutSecs = CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS; + uint64_t mDiscoveryExpirationMs = TIMEOUT_CLEARED; + + /// return true if expirationMs is valid (not cleared and not in the future) + bool OnExpiration(uint64_t expirationMs); + +#if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY + /// get the current extended discovery timeout (from persistent storage) + int16_t GetExtendedDiscoveryTimeoutSecs(); + + /// schedule next extended discovery expiration + CHIP_ERROR ScheduleExtendedDiscoveryExpiration(); + + uint64_t mExtendedDiscoveryExpirationMs = TIMEOUT_CLEARED; +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY +}; -} // namespace Mdns } // namespace app } // namespace chip diff --git a/src/app/server/RendezvousServer.cpp b/src/app/server/RendezvousServer.cpp index 06eff52b32a898..422f4ca624ff59 100644 --- a/src/app/server/RendezvousServer.cpp +++ b/src/app/server/RendezvousServer.cpp @@ -56,11 +56,11 @@ void RendezvousServer::OnPlatformEvent(const DeviceLayer::ChipDeviceEvent * even event->CommissioningComplete.status.Format()); } // reset all advertising - app::Mdns::StartServer(app::Mdns::CommissioningMode::kDisabled); + app::MdnsServer::Instance().StartServer(Mdns::CommissioningMode::kDisabled); } else if (event->Type == DeviceLayer::DeviceEventType::kOperationalNetworkEnabled) { - app::Mdns::AdvertiseOperational(); + app::MdnsServer::Instance().AdvertiseOperational(); ChipLogError(Discovery, "Operational advertising enabled"); } } @@ -96,8 +96,8 @@ CHIP_ERROR RendezvousServer::WaitForPairing(const RendezvousParameters & params, // reset all advertising, indicating we are in commissioningMode // and we were put into this state via a command for additional commissioning // NOTE: when device has never been commissioned, Rendezvous will ensure AP is false - app::Mdns::StartServer(params.HasPASEVerifier() ? app::Mdns::CommissioningMode::kEnabledBasic - : app::Mdns::CommissioningMode::kEnabledEnhanced); + app::MdnsServer::Instance().StartServer(params.HasPASEVerifier() ? Mdns::CommissioningMode::kEnabledBasic + : Mdns::CommissioningMode::kEnabledEnhanced); mSessionMgr = sessionMgr; mExchangeManager = exchangeManager; @@ -133,7 +133,7 @@ void RendezvousServer::Cleanup() } // reset all advertising - app::Mdns::StartServer(app::Mdns::CommissioningMode::kDisabled); + app::MdnsServer::Instance().StartServer(Mdns::CommissioningMode::kDisabled); } void RendezvousServer::OnSessionEstablishmentError(CHIP_ERROR err) diff --git a/src/app/server/Server.cpp b/src/app/server/Server.cpp index 8582271f92118a..924d5fbf33497e 100644 --- a/src/app/server/Server.cpp +++ b/src/app/server/Server.cpp @@ -152,15 +152,15 @@ CHIP_ERROR Server::Init(AppDelegate * delegate, uint16_t secureServicePort, uint } #if CHIP_DEVICE_CONFIG_ENABLE_MDNS - app::Mdns::SetSecuredPort(mSecuredServicePort); - app::Mdns::SetUnsecuredPort(mUnsecuredServicePort); + app::MdnsServer::Instance().SetSecuredPort(mSecuredServicePort); + app::MdnsServer::Instance().SetUnsecuredPort(mUnsecuredServicePort); #endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS // TODO @bzbarsky-apple @cecille Move to examples // ESP32 and Mbed OS examples have a custom logic for enabling DNS-SD #if CHIP_DEVICE_CONFIG_ENABLE_MDNS && !CHIP_DEVICE_LAYER_TARGET_ESP32 && !CHIP_DEVICE_LAYER_TARGET_MBED // StartServer only enables commissioning mode if device has not been commissioned - app::Mdns::StartServer(); + app::MdnsServer::Instance().StartServer(); #endif // TODO @pan-apple Use IM protocol ID. @@ -210,7 +210,7 @@ CHIP_ERROR Server::SendUserDirectedCommissioningRequest(chip::Transport::PeerAdd CHIP_ERROR err; char nameBuffer[chip::Mdns::kMaxInstanceNameSize + 1]; - err = app::Mdns::GetCommissionableInstanceName(nameBuffer, sizeof(nameBuffer)); + err = app::MdnsServer::Instance().GetCommissionableInstanceName(nameBuffer, sizeof(nameBuffer)); if (err != CHIP_NO_ERROR) { ChipLogError(AppServer, "Failed to get mdns instance name error: %s", ErrorStr(err)); diff --git a/src/controller/python/ChipCommissionableNodeController-ScriptBinding.cpp b/src/controller/python/ChipCommissionableNodeController-ScriptBinding.cpp index 2f6dd98602438f..7c6e7bb1d67a7a 100644 --- a/src/controller/python/ChipCommissionableNodeController-ScriptBinding.cpp +++ b/src/controller/python/ChipCommissionableNodeController-ScriptBinding.cpp @@ -87,10 +87,10 @@ void pychip_CommissionableNodeController_PrintDiscoveredCommissioners( ChipLogProgress(Discovery, "Commissioner %d", i); ChipLogProgress(Discovery, "\tHost name:\t\t%s", dnsSdInfo->hostName); + ChipLogProgress(Discovery, "\tPort:\t\t\t%u", dnsSdInfo->port); ChipLogProgress(Discovery, "\tLong discriminator:\t%u", dnsSdInfo->longDiscriminator); ChipLogProgress(Discovery, "\tVendor ID:\t\t%u", dnsSdInfo->vendorId); ChipLogProgress(Discovery, "\tProduct ID:\t\t%u", dnsSdInfo->productId); - ChipLogProgress(Discovery, "\tAdditional Pairing\t%u", dnsSdInfo->additionalPairing); ChipLogProgress(Discovery, "\tCommissioning Mode\t%u", dnsSdInfo->commissioningMode); ChipLogProgress(Discovery, "\tDevice Type\t\t%u", dnsSdInfo->deviceType); ChipLogProgress(Discovery, "\tDevice Name\t\t%s", dnsSdInfo->deviceName); diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp index 9ecf1bc4135b78..485b55b076cbdb 100644 --- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp +++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp @@ -122,13 +122,9 @@ ChipError::StorageType pychip_DeviceController_DiscoverCommissionableNodesVendor ChipError::StorageType pychip_DeviceController_DiscoverCommissionableNodesDeviceType(chip::Controller::DeviceCommissioner * devCtrl, uint16_t device_type); ChipError::StorageType -pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabled(chip::Controller::DeviceCommissioner * devCtrl, - uint16_t enabled); +pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabled(chip::Controller::DeviceCommissioner * devCtrl); ChipError::StorageType pychip_DeviceController_PostTaskOnChipThread(ChipThreadTaskRunnerFunct callback, void * pythonContext); -ChipError::StorageType -pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabledFromCommand(chip::Controller::DeviceCommissioner * devCtrl); - ChipError::StorageType pychip_DeviceController_OpenCommissioningWindow(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid, uint16_t timeout, uint16_t iteration, uint16_t discriminator, uint8_t option); @@ -366,17 +362,9 @@ ChipError::StorageType pychip_DeviceController_DiscoverCommissionableNodesDevice } ChipError::StorageType -pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabled(chip::Controller::DeviceCommissioner * devCtrl, - uint16_t enabled) -{ - Mdns::DiscoveryFilter filter(Mdns::DiscoveryFilterType::kCommissioningMode, enabled); - return devCtrl->DiscoverCommissionableNodes(filter).AsInteger(); -} - -ChipError::StorageType -pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabledFromCommand(chip::Controller::DeviceCommissioner * devCtrl) +pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabled(chip::Controller::DeviceCommissioner * devCtrl) { - Mdns::DiscoveryFilter filter(Mdns::DiscoveryFilterType::kCommissioningModeFromCommand, 1); + Mdns::DiscoveryFilter filter(Mdns::DiscoveryFilterType::kCommissioningMode); return devCtrl->DiscoverCommissionableNodes(filter).AsInteger(); } @@ -401,10 +389,10 @@ void pychip_DeviceController_PrintDiscoveredDevices(chip::Controller::DeviceComm ChipLogProgress(Discovery, "Commissionable Node %d", i); ChipLogProgress(Discovery, "\tHost name:\t\t%s", dnsSdInfo->hostName); + ChipLogProgress(Discovery, "\tPort:\t\t\t%u", dnsSdInfo->port); ChipLogProgress(Discovery, "\tLong discriminator:\t%u", dnsSdInfo->longDiscriminator); ChipLogProgress(Discovery, "\tVendor ID:\t\t%u", dnsSdInfo->vendorId); ChipLogProgress(Discovery, "\tProduct ID:\t\t%u", dnsSdInfo->productId); - ChipLogProgress(Discovery, "\tAdditional Pairing\t%u", dnsSdInfo->additionalPairing); ChipLogProgress(Discovery, "\tCommissioning Mode\t%u", dnsSdInfo->commissioningMode); ChipLogProgress(Discovery, "\tDevice Type\t\t%u", dnsSdInfo->deviceType); ChipLogProgress(Discovery, "\tDevice Name\t\t%s", dnsSdInfo->deviceName); diff --git a/src/controller/python/chip-device-ctrl.py b/src/controller/python/chip-device-ctrl.py index 01e0cc001dc1e3..bde5bf1e7638a2 100755 --- a/src/controller/python/chip-device-ctrl.py +++ b/src/controller/python/chip-device-ctrl.py @@ -617,8 +617,7 @@ def do_discover(self, line): discover -s short_discriminator discover -v vendor_id discover -t device_type - discover -c commissioning_enabled - discover -a + discover -c discover command is used to discover available devices. """ @@ -643,9 +642,7 @@ def do_discover(self, line): group.add_argument( '-t', help='discover commissionable nodes with given device type', type=int) group.add_argument( - '-c', help='discover commissionable nodes with given commissioning mode', type=int) - group.add_argument( - '-a', help='discover commissionable nodes put in commissioning mode from command', action='store_true') + '-c', help='discover commissionable nodes in commissioning mode', action='store_true') args = parser.parse_args(arglist) if args.all: self.commissionableNodeCtrl.DiscoverCommissioners() @@ -677,11 +674,7 @@ def do_discover(self, line): ctypes.c_uint16(args.t)) self.wait_for_many_discovered_devices() elif args.c is not None: - self.devCtrl.DiscoverCommissionableNodesCommissioningEnabled( - ctypes.c_uint16(args.c)) - self.wait_for_many_discovered_devices() - elif args.a is not None: - self.devCtrl.DiscoverCommissionableNodesCommissioningEnabledFromCommand() + self.devCtrl.DiscoverCommissionableNodesCommissioningEnabled() self.wait_for_many_discovered_devices() else: self.do_help("discover") diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index 119c722186facf..606de90ba8fb3d 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -241,15 +241,9 @@ def DiscoverCommissionableNodesDeviceType(self, device_type): self.devCtrl, device_type) ) - def DiscoverCommissionableNodesCommissioningEnabled(self, enabled): + def DiscoverCommissionableNodesCommissioningEnabled(self): return self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabled( - self.devCtrl, enabled) - ) - - def DiscoverCommissionableNodesCommissioningEnabledFromCommand(self): - return self._ChipStack.Call( - lambda: self._dmLib.pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabledFromCommand( self.devCtrl) ) @@ -441,12 +435,8 @@ def _InitLib(self): self._dmLib.pychip_DeviceController_DiscoverCommissionableNodesDeviceType.restype = c_uint32 self._dmLib.pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabled.argtypes = [ - c_void_p, c_uint16] - self._dmLib.pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabled.restype = c_uint32 - - self._dmLib.pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabledFromCommand.argtypes = [ c_void_p] - self._dmLib.pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabledFromCommand.restype = c_uint32 + self._dmLib.pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabled.restype = c_uint32 self._dmLib.pychip_DeviceController_PrintDiscoveredDevices.argtypes = [ c_void_p] diff --git a/src/include/platform/CHIPDeviceConfig.h b/src/include/platform/CHIPDeviceConfig.h index a0dec8aa5c0a42..bd93d5e0d83931 100644 --- a/src/include/platform/CHIPDeviceConfig.h +++ b/src/include/platform/CHIPDeviceConfig.h @@ -1110,6 +1110,17 @@ #endif #endif +/** + * CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS + * + * Time in seconds that a factory new device will advertise commissionable node discovery. + * + * Only valid when CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DISCOVERY==1 + */ +#ifndef CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS +#define CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS 15 * 60 +#endif + /** * CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES * @@ -1166,6 +1177,18 @@ #define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 0 #endif +/** + * CHIP_DEVICE_CONFIG_EXTENDED_DISCOVERY_TIMEOUT_SECS + * + * Default time in seconds that a device will advertise commissionable node discovery + * after commissioning mode ends. This value can be overridden by the user. + * + * Only valid when CCHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY==1 + */ +#define CHIP_DEVICE_CONFIG_DISCOVERY_DISABLED 0 +#define CHIP_DEVICE_CONFIG_DISCOVERY_NO_TIMEOUT -1 +#define CHIP_DEVICE_CONFIG_EXTENDED_DISCOVERY_TIMEOUT_SECS CHIP_DEVICE_CONFIG_DISCOVERY_NO_TIMEOUT + /** * CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DEVICE_TYPE * diff --git a/src/lib/mdns/Advertiser.h b/src/lib/mdns/Advertiser.h index c5ce216f803bfc..43e69d8b6b0981 100644 --- a/src/lib/mdns/Advertiser.h +++ b/src/lib/mdns/Advertiser.h @@ -69,6 +69,13 @@ enum class CommssionAdvertiseMode : uint8_t kCommissioner, }; +enum class CommissioningMode +{ + kDisabled, // Commissioning Mode is disabled, CM=0 in DNS-SD key/value pairs + kEnabledBasic, // Basic Commissioning Mode, CM=1 in DNS-SD key/value pairs + kEnabledEnhanced // Enhanced Commissioning Mode, CM=2 in DNS-SD key/value pairs +}; + template class BaseAdvertisingParams { @@ -180,19 +187,12 @@ class CommissionAdvertisingParameters : public BaseAdvertisingParams GetProductId() const { return mProductId; } - CommissionAdvertisingParameters & SetCommissioningMode(bool modeEnabled) - { - mCommissioningModeEnabled = modeEnabled; - return *this; - } - bool GetCommissioningMode() const { return mCommissioningModeEnabled; } - - CommissionAdvertisingParameters & SetAdditionalCommissioning(bool additionalCommissioningEnabled) + CommissionAdvertisingParameters & SetCommissioningMode(CommissioningMode mode) { - mAdditionalCommissioningEnabled = additionalCommissioningEnabled; + mCommissioningMode = mode; return *this; } - bool GetAdditionalCommissioning() const { return mAdditionalCommissioningEnabled; } + CommissioningMode GetCommissioningMode() const { return mCommissioningMode; } CommissionAdvertisingParameters & SetDeviceType(Optional deviceType) { @@ -273,8 +273,7 @@ class CommissionAdvertisingParameters : public BaseAdvertisingParams mVendorId; chip::Optional mProductId; chip::Optional mDeviceType; diff --git a/src/lib/mdns/Advertiser_ImplMinimalMdns.cpp b/src/lib/mdns/Advertiser_ImplMinimalMdns.cpp index 8bc0a4387f090f..46bec41c7b8e4b 100644 --- a/src/lib/mdns/Advertiser_ImplMinimalMdns.cpp +++ b/src/lib/mdns/Advertiser_ImplMinimalMdns.cpp @@ -486,9 +486,9 @@ CHIP_ERROR AdvertiserMinMdns::Advertise(const CommissionAdvertisingParameters & } } + if (params.GetCommissioningMode() != CommissioningMode::kDisabled) { - MakeServiceSubtype(nameBuffer, sizeof(nameBuffer), - DiscoveryFilter(DiscoveryFilterType::kCommissioningMode, params.GetCommissioningMode() ? 1 : 0)); + MakeServiceSubtype(nameBuffer, sizeof(nameBuffer), DiscoveryFilter(DiscoveryFilterType::kCommissioningMode)); FullQName longServiceName = allocator->AllocateQName(nameBuffer, kSubtypeServiceNamePart, serviceType, kCommissionProtocol, kLocalDomain); ReturnErrorCodeIf(longServiceName.nameCount == 0, CHIP_ERROR_NO_MEMORY); @@ -501,23 +501,6 @@ CHIP_ERROR AdvertiserMinMdns::Advertise(const CommissionAdvertisingParameters & return CHIP_ERROR_NO_MEMORY; } } - - if (params.GetCommissioningMode() && params.GetAdditionalCommissioning()) - { - MakeServiceSubtype(nameBuffer, sizeof(nameBuffer), - DiscoveryFilter(DiscoveryFilterType::kCommissioningModeFromCommand, 1)); - FullQName longServiceName = - allocator->AllocateQName(nameBuffer, kSubtypeServiceNamePart, serviceType, kCommissionProtocol, kLocalDomain); - ReturnErrorCodeIf(longServiceName.nameCount == 0, CHIP_ERROR_NO_MEMORY); - if (!allocator->AddResponder(longServiceName, instanceName) - .SetReportAdditional(instanceName) - .SetReportInServiceListing(true) - .IsValid()) - { - ChipLogError(Discovery, "Failed to add open window commissioning mode PTR record mDNS responder"); - return CHIP_ERROR_NO_MEMORY; - } - } } if (!allocator->AddResponder(TxtResourceRecord(instanceName, GetCommisioningTextEntries(params))) @@ -542,8 +525,8 @@ CHIP_ERROR AdvertiserMinMdns::Advertise(const CommissionAdvertisingParameters & FullQName AdvertiserMinMdns::GetCommisioningTextEntries(const CommissionAdvertisingParameters & params) { - // Max number of TXT fields from the spec is 9: D, VP, AP, CM, DT, DN, RI, PI, PH. - constexpr size_t kMaxTxtFields = 9; + // Max number of TXT fields from the spec is 8: D, VP, CM, DT, DN, RI, PI, PH. + constexpr size_t kMaxTxtFields = 8; const char * txtFields[kMaxTxtFields]; size_t numTxtFields = 0; @@ -586,16 +569,9 @@ FullQName AdvertiserMinMdns::GetCommisioningTextEntries(const CommissionAdvertis txtFields[numTxtFields++] = txtDiscriminator; char txtCommissioningMode[chip::Mdns::kKeyCommissioningModeMaxLength + 4]; - snprintf(txtCommissioningMode, sizeof(txtCommissioningMode), "CM=%d", params.GetCommissioningMode() ? 1 : 0); + snprintf(txtCommissioningMode, sizeof(txtCommissioningMode), "CM=%d", static_cast(params.GetCommissioningMode())); txtFields[numTxtFields++] = txtCommissioningMode; - char txtAdditionalCommissioning[chip::Mdns::kKeyAdditionalCommissioningMaxLength + 4]; - if (params.GetCommissioningMode() && params.GetAdditionalCommissioning()) - { - snprintf(txtAdditionalCommissioning, sizeof(txtAdditionalCommissioning), "AP=1"); - txtFields[numTxtFields++] = txtAdditionalCommissioning; - } - char txtRotatingDeviceId[chip::Mdns::kKeyRotatingIdMaxLength + 4]; if (params.GetRotatingId().HasValue()) { diff --git a/src/lib/mdns/Discovery_ImplPlatform.cpp b/src/lib/mdns/Discovery_ImplPlatform.cpp index 23c7a5e00f4eef..692deadde939f5 100644 --- a/src/lib/mdns/Discovery_ImplPlatform.cpp +++ b/src/lib/mdns/Discovery_ImplPlatform.cpp @@ -131,7 +131,6 @@ CHIP_ERROR DiscoveryImplPlatform::Advertise(const CommissionAdvertisingParameter char discriminatorBuf[kKeyDiscriminatorMaxLength + 1]; char vendorProductBuf[kKeyVendorProductMaxLength + 1]; char commissioningModeBuf[kKeyCommissioningModeMaxLength + 1]; - char additionalCommissioningingBuf[kKeyAdditionalCommissioningMaxLength + 1]; char deviceTypeBuf[kKeyDeviceTypeMaxLength + 1]; char deviceNameBuf[kKeyDeviceNameMaxLength + 1]; char rotatingIdBuf[kKeyRotatingIdMaxLength + 1]; @@ -145,7 +144,6 @@ CHIP_ERROR DiscoveryImplPlatform::Advertise(const CommissionAdvertisingParameter char longDiscriminatorSubtype[kSubTypeLongDiscriminatorMaxLength + 1]; char vendorSubType[kSubTypeVendorMaxLength + 1]; char commissioningModeSubType[kSubTypeCommissioningModeMaxLength + 1]; - char additionalCommissioningSubType[kSubTypeAdditionalCommissioningMaxLength + 1]; char deviceTypeSubType[kSubTypeDeviceTypeMaxLength + 1]; // size of subTypes array should be count of SubTypes above const char * subTypes[kSubTypeMaxNumber]; @@ -211,17 +209,10 @@ CHIP_ERROR DiscoveryImplPlatform::Advertise(const CommissionAdvertisingParameter textEntries[textEntrySize++] = { "D", reinterpret_cast(discriminatorBuf), strnlen(discriminatorBuf, sizeof(discriminatorBuf)) }; - snprintf(commissioningModeBuf, sizeof(commissioningModeBuf), "%u", params.GetCommissioningMode() ? 1 : 0); + snprintf(commissioningModeBuf, sizeof(commissioningModeBuf), "%u", static_cast(params.GetCommissioningMode())); textEntries[textEntrySize++] = { "CM", reinterpret_cast(commissioningModeBuf), strnlen(commissioningModeBuf, sizeof(commissioningModeBuf)) }; - if (params.GetCommissioningMode() && params.GetAdditionalCommissioning()) - { - snprintf(additionalCommissioningingBuf, sizeof(additionalCommissioningingBuf), "1"); - textEntries[textEntrySize++] = { "AP", reinterpret_cast(additionalCommissioningingBuf), - strnlen(additionalCommissioningingBuf, sizeof(additionalCommissioningingBuf)) }; - } - if (params.GetRotatingId().HasValue()) { snprintf(rotatingIdBuf, sizeof(rotatingIdBuf), "%s", params.GetRotatingId().Value()); @@ -253,20 +244,12 @@ CHIP_ERROR DiscoveryImplPlatform::Advertise(const CommissionAdvertisingParameter { subTypes[subTypeSize++] = longDiscriminatorSubtype; } - if (MakeServiceSubtype(commissioningModeSubType, sizeof(commissioningModeSubType), - DiscoveryFilter(DiscoveryFilterType::kCommissioningMode, params.GetCommissioningMode() ? 1 : 0)) == - CHIP_NO_ERROR) + if ((params.GetCommissioningMode() != CommissioningMode::kDisabled) && + (MakeServiceSubtype(commissioningModeSubType, sizeof(commissioningModeSubType), + DiscoveryFilter(DiscoveryFilterType::kCommissioningMode)) == CHIP_NO_ERROR)) { subTypes[subTypeSize++] = commissioningModeSubType; } - if (params.GetCommissioningMode() && params.GetAdditionalCommissioning()) - { - if (MakeServiceSubtype(additionalCommissioningSubType, sizeof(additionalCommissioningSubType), - DiscoveryFilter(DiscoveryFilterType::kCommissioningModeFromCommand, 1)) == CHIP_NO_ERROR) - { - subTypes[subTypeSize++] = additionalCommissioningSubType; - } - } } if (params.GetVendorId().HasValue()) diff --git a/src/lib/mdns/Resolver.h b/src/lib/mdns/Resolver.h index f8badf5ba10521..5654e3c4321b44 100644 --- a/src/lib/mdns/Resolver.h +++ b/src/lib/mdns/Resolver.h @@ -86,7 +86,6 @@ struct DiscoveredNodeData uint16_t longDiscriminator; uint16_t vendorId; uint16_t productId; - uint8_t additionalPairing; uint8_t commissioningMode; // TODO: possibly 32-bit - see spec issue #3226 uint16_t deviceType; @@ -110,7 +109,6 @@ struct DiscoveredNodeData longDiscriminator = 0; vendorId = 0; productId = 0; - additionalPairing = 0; commissioningMode = 0; deviceType = 0; memset(deviceName, 0, sizeof(deviceName)); @@ -154,54 +152,50 @@ struct DiscoveredNodeData #endif // CHIP_ENABLE_ROTATING_DEVICE_ID if (strlen(deviceName) != 0) { - ChipLogDetail(Discovery, "Device Name: %s", deviceName); + ChipLogDetail(Discovery, "\tDevice Name: %s", deviceName); } if (vendorId > 0) { - ChipLogDetail(Discovery, "Vendor ID: %u", vendorId); + ChipLogDetail(Discovery, "\tVendor ID: %u", vendorId); } if (productId > 0) { - ChipLogDetail(Discovery, "Product ID: %u", productId); + ChipLogDetail(Discovery, "\tProduct ID: %u", productId); } if (deviceType > 0) { - ChipLogDetail(Discovery, "Device Type: %u", deviceType); + ChipLogDetail(Discovery, "\tDevice Type: %u", deviceType); } if (longDiscriminator > 0) { - ChipLogDetail(Discovery, "Long Discriminator: %u", longDiscriminator); - } - if (additionalPairing > 0) - { - ChipLogDetail(Discovery, "Additional Pairing: %u", additionalPairing); + ChipLogDetail(Discovery, "\tLong Discriminator: %u", longDiscriminator); } if (strlen(pairingInstruction) != 0) { - ChipLogDetail(Discovery, "Pairing Instruction: %s", pairingInstruction); + ChipLogDetail(Discovery, "\tPairing Instruction: %s", pairingInstruction); } if (pairingHint > 0) { - ChipLogDetail(Discovery, "Pairing Hint: 0x%x", pairingHint); + ChipLogDetail(Discovery, "\tPairing Hint: 0x%x", pairingHint); } if (!IsHost("")) { - ChipLogDetail(Discovery, "Hostname: %s", hostName); + ChipLogDetail(Discovery, "\tHostname: %s", hostName); } for (int j = 0; j < numIPs; j++) { #if CHIP_DETAIL_LOGGING char buf[Inet::kMaxIPAddressStringLength]; char * ipAddressOut = ipAddress[j].ToString(buf); - ChipLogDetail(Discovery, "IP Address #%d: %s", j + 1, ipAddressOut); + ChipLogDetail(Discovery, "\tIP Address #%d: %s", j + 1, ipAddressOut); (void) ipAddressOut; #endif // CHIP_DETAIL_LOGGING } if (port > 0) { - ChipLogDetail(Discovery, "Port: %u", port); + ChipLogDetail(Discovery, "\tPort: %u", port); } - ChipLogDetail(Discovery, "Commissioning Mode: %u", commissioningMode); + ChipLogDetail(Discovery, "\tCommissioning Mode: %u", commissioningMode); } }; @@ -213,7 +207,6 @@ enum class DiscoveryFilterType : uint8_t kVendor, kDeviceType, kCommissioningMode, - kCommissioningModeFromCommand, kInstanceName, kCommissioner }; @@ -223,6 +216,7 @@ struct DiscoveryFilter uint16_t code; const char * instanceName; DiscoveryFilter() : type(DiscoveryFilterType::kNone), code(0) {} + DiscoveryFilter(DiscoveryFilterType newType) : type(newType) {} DiscoveryFilter(DiscoveryFilterType newType, uint16_t newCode) : type(newType), code(newCode) {} DiscoveryFilter(DiscoveryFilterType newType, const char * newInstanceName) : type(newType), instanceName(newInstanceName) {} }; diff --git a/src/lib/mdns/ServiceNaming.cpp b/src/lib/mdns/ServiceNaming.cpp index 85453a96d1689d..218c54201d48a5 100644 --- a/src/lib/mdns/ServiceNaming.cpp +++ b/src/lib/mdns/ServiceNaming.cpp @@ -123,11 +123,7 @@ CHIP_ERROR MakeServiceSubtype(char * buffer, size_t bufferLen, DiscoveryFilter s requiredSize = snprintf(buffer, bufferLen, "_T%u", subtype.code); break; case DiscoveryFilterType::kCommissioningMode: - if (subtype.code > 1) - { - return CHIP_ERROR_INVALID_ARGUMENT; - } - requiredSize = snprintf(buffer, bufferLen, "_C%u", subtype.code); + requiredSize = snprintf(buffer, bufferLen, "_CM"); break; case DiscoveryFilterType::kCommissioner: if (subtype.code > 1) @@ -136,14 +132,6 @@ CHIP_ERROR MakeServiceSubtype(char * buffer, size_t bufferLen, DiscoveryFilter s } requiredSize = snprintf(buffer, bufferLen, "_D%u", subtype.code); break; - case DiscoveryFilterType::kCommissioningModeFromCommand: - // 1 is the only valid value - if (subtype.code != 1) - { - return CHIP_ERROR_INVALID_ARGUMENT; - } - requiredSize = snprintf(buffer, bufferLen, "_A1"); - break; case DiscoveryFilterType::kInstanceName: requiredSize = snprintf(buffer, bufferLen, "%s", subtype.instanceName); break; diff --git a/src/lib/mdns/TxtFields.cpp b/src/lib/mdns/TxtFields.cpp index a4ad7f394e424a..389535d2f27988 100644 --- a/src/lib/mdns/TxtFields.cpp +++ b/src/lib/mdns/TxtFields.cpp @@ -140,11 +140,6 @@ uint16_t GetLongDiscriminator(const ByteSpan & value) return MakeU16FromAsciiDecimal(value); } -uint8_t GetAdditionalPairing(const ByteSpan & value) -{ - return MakeU8FromAsciiDecimal(value); -} - uint8_t GetCommissioningMode(const ByteSpan & value) { return MakeU8FromAsciiDecimal(value); @@ -196,10 +191,6 @@ TxtFieldKey GetTxtFieldKey(const ByteSpan & key) { return TxtFieldKey::kVendorProduct; } - else if (IsKey(key, "AP")) - { - return TxtFieldKey::kAdditionalPairing; - } else if (IsKey(key, "CM")) { return TxtFieldKey::kCommissioningMode; @@ -256,9 +247,6 @@ void FillNodeDataFromTxt(const ByteSpan & key, const ByteSpan & val, DiscoveredN nodeData.vendorId = Internal::GetVendor(val); nodeData.productId = Internal::GetProduct(val); break; - case Internal::TxtFieldKey::kAdditionalPairing: - nodeData.additionalPairing = Internal::GetAdditionalPairing(val); - break; case Internal::TxtFieldKey::kCommissioningMode: nodeData.commissioningMode = Internal::GetCommissioningMode(val); break; diff --git a/src/lib/mdns/TxtFields.h b/src/lib/mdns/TxtFields.h index 0046a3547a6a69..2f63009cdda7d2 100644 --- a/src/lib/mdns/TxtFields.h +++ b/src/lib/mdns/TxtFields.h @@ -52,7 +52,6 @@ TxtFieldKey GetTxtFieldKey(const ByteSpan & key); uint16_t GetProduct(const ByteSpan & value); uint16_t GetVendor(const ByteSpan & value); uint16_t GetLongDiscriminator(const ByteSpan & value); -uint8_t GetAdditionalPairing(const ByteSpan & value); uint8_t GetCommissioningMode(const ByteSpan & value); // TODO: possibly 32-bit? see spec issue #3226 uint16_t GetDeviceType(const ByteSpan & value); diff --git a/src/lib/mdns/minimal/tests/TestAdvertiser.cpp b/src/lib/mdns/minimal/tests/TestAdvertiser.cpp index 9099110871c5bf..1f281a0308e1ae 100644 --- a/src/lib/mdns/minimal/tests/TestAdvertiser.cpp +++ b/src/lib/mdns/minimal/tests/TestAdvertiser.cpp @@ -88,33 +88,27 @@ TxtResourceRecord txtOperational2 = TxtResourceRecord(kInstanceName2, kTxt const QNamePart kMatterCommissionableNodeQueryParts[3] = { "_matterc", "_udp", "local" }; const QNamePart kLongSubPartsFullLen[] = { "_L4094", "_sub", "_matterc", "_udp", "local" }; const QNamePart kShortSubPartsFullLen[] = { "_S15", "_sub", "_matterc", "_udp", "local" }; -const QNamePart kCmSubParts0[] = { "_C0", "_sub", "_matterc", "_udp", "local" }; +const QNamePart kCmSubParts[] = { "_CM", "_sub", "_matterc", "_udp", "local" }; const QNamePart kLongSubParts[] = { "_L22", "_sub", "_matterc", "_udp", "local" }; const QNamePart kShortSubParts[] = { "_S2", "_sub", "_matterc", "_udp", "local" }; const QNamePart kVendorSubParts[] = { "_V555", "_sub", "_matterc", "_udp", "local" }; const QNamePart kDeviceTypeSubParts[] = { "_T25", "_sub", "_matterc", "_udp", "local" }; -const QNamePart kCmSubParts1[] = { "_C1", "_sub", "_matterc", "_udp", "local" }; -const QNamePart kOpenWindowSubParts[] = { "_A1", "_sub", "_matterc", "_udp", "local" }; const FullQName kMatterCommissionableNodeQueryName = FullQName(kMatterCommissionableNodeQueryParts); FullQName kLongSubFullLenName = FullQName(kLongSubPartsFullLen); FullQName kShortSubFullLenName = FullQName(kShortSubPartsFullLen); -FullQName kCmSub0Name = FullQName(kCmSubParts0); +FullQName kCmSubName = FullQName(kCmSubParts); FullQName kLongSubName = FullQName(kLongSubParts); FullQName kShortSubName = FullQName(kShortSubParts); -FullQName kCmSub1Name = FullQName(kCmSubParts1); FullQName kVendorSubName = FullQName(kVendorSubParts); FullQName kDeviceTypeSubName = FullQName(kDeviceTypeSubParts); -FullQName kOpenWindowSubName = FullQName(kOpenWindowSubParts); PtrResourceRecord ptrCommissionableNodeService = PtrResourceRecord(kDnsSdQueryName, kMatterCommissionableNodeQueryName); PtrResourceRecord ptrServiceSubLFullLen = PtrResourceRecord(kDnsSdQueryName, kLongSubFullLenName); PtrResourceRecord ptrServiceSubSFullLen = PtrResourceRecord(kDnsSdQueryName, kShortSubFullLenName); -PtrResourceRecord ptrServiceSubC0 = PtrResourceRecord(kDnsSdQueryName, kCmSub0Name); +PtrResourceRecord ptrServiceSubCM = PtrResourceRecord(kDnsSdQueryName, kCmSubName); PtrResourceRecord ptrServiceSubLong = PtrResourceRecord(kDnsSdQueryName, kLongSubName); PtrResourceRecord ptrServiceSubShort = PtrResourceRecord(kDnsSdQueryName, kShortSubName); -PtrResourceRecord ptrServiceSubC1 = PtrResourceRecord(kDnsSdQueryName, kCmSub1Name); PtrResourceRecord ptrServiceSubVendor = PtrResourceRecord(kDnsSdQueryName, kVendorSubName); PtrResourceRecord ptrServiceSubDeviceType = PtrResourceRecord(kDnsSdQueryName, kDeviceTypeSubName); -PtrResourceRecord ptrServiceSubOpenWindow = PtrResourceRecord(kDnsSdQueryName, kOpenWindowSubName); // For commissioning, the instance name is chosen randomly by the advertiser, so we have to get this value from it. We can, however, // pre-populate the records with the ptr. @@ -130,13 +124,12 @@ CommissionAdvertisingParameters commissionableNodeParamsSmall = .SetMac(ByteSpan(kMac)) .SetLongDiscriminator(0xFFE) .SetShortDiscriminator(0xF) - .SetCommissioningMode(false) - .SetAdditionalCommissioning(false); + .SetCommissioningMode(CommissioningMode::kDisabled); const QNamePart txtCommissionableNodeParamsSmallParts[] = { "CM=0", "D=4094" }; FullQName txtCommissionableNodeParamsSmallName = FullQName(txtCommissionableNodeParamsSmallParts); TxtResourceRecord txtCommissionableNodeParamsSmall = TxtResourceRecord(instanceName, txtCommissionableNodeParamsSmallName); -CommissionAdvertisingParameters commissionableNodeParamsLarge = +CommissionAdvertisingParameters commissionableNodeParamsLargeBasic = CommissionAdvertisingParameters() .SetCommissionAdvertiseMode(CommssionAdvertiseMode::kCommissionableNode) .SetMac(ByteSpan(kMac, sizeof(kMac))) @@ -144,17 +137,37 @@ CommissionAdvertisingParameters commissionableNodeParamsLarge = .SetShortDiscriminator(2) .SetVendorId(chip::Optional(555)) .SetDeviceType(chip::Optional(25)) - .SetCommissioningMode(true) - .SetAdditionalCommissioning(true) + .SetCommissioningMode(CommissioningMode::kEnabledBasic) .SetDeviceName(chip::Optional("testy-test")) .SetPairingHint(chip::Optional(3)) .SetPairingInstr(chip::Optional("Pair me")) .SetProductId(chip::Optional(897)) .SetRotatingId(chip::Optional("id_that_spins")); -QNamePart txtCommissionableNodeParamsLargeParts[] = { "D=22", "VP=555+897", "AP=1", "CM=1", "DT=25", - "DN=testy-test", "RI=id_that_spins", "PI=Pair me", "PH=3" }; -FullQName txtCommissionableNodeParamsLargeName = FullQName(txtCommissionableNodeParamsLargeParts); -TxtResourceRecord txtCommissionableNodeParamsLarge = TxtResourceRecord(instanceName, txtCommissionableNodeParamsLargeName); +QNamePart txtCommissionableNodeParamsLargeBasicParts[] = { "D=22", "VP=555+897", "CM=1", "DT=25", + "DN=testy-test", "RI=id_that_spins", "PI=Pair me", "PH=3" }; +FullQName txtCommissionableNodeParamsLargeBasicName = FullQName(txtCommissionableNodeParamsLargeBasicParts); +TxtResourceRecord txtCommissionableNodeParamsLargeBasic = + TxtResourceRecord(instanceName, txtCommissionableNodeParamsLargeBasicName); + +CommissionAdvertisingParameters commissionableNodeParamsLargeEnhanced = + CommissionAdvertisingParameters() + .SetCommissionAdvertiseMode(CommssionAdvertiseMode::kCommissionableNode) + .SetMac(ByteSpan(kMac, sizeof(kMac))) + .SetLongDiscriminator(22) + .SetShortDiscriminator(2) + .SetVendorId(chip::Optional(555)) + .SetDeviceType(chip::Optional(25)) + .SetCommissioningMode(CommissioningMode::kEnabledEnhanced) + .SetDeviceName(chip::Optional("testy-test")) + .SetPairingHint(chip::Optional(3)) + .SetPairingInstr(chip::Optional("Pair me")) + .SetProductId(chip::Optional(897)) + .SetRotatingId(chip::Optional("id_that_spins")); +QNamePart txtCommissionableNodeParamsLargeEnhancedParts[] = { "D=22", "VP=555+897", "CM=2", "DT=25", + "DN=testy-test", "RI=id_that_spins", "PI=Pair me", "PH=3" }; +FullQName txtCommissionableNodeParamsLargeEnhancedName = FullQName(txtCommissionableNodeParamsLargeEnhancedParts); +TxtResourceRecord txtCommissionableNodeParamsLargeEnhanced = + TxtResourceRecord(instanceName, txtCommissionableNodeParamsLargeEnhancedName); // Our server doesn't do anything with this, blank is fine. Inet::IPPacketInfo packetInfo; @@ -316,7 +329,6 @@ void CommissionableAdverts(nlTestSuite * inSuite, void * inContext) server.AddExpectedRecord(&ptrCommissionableNodeService); server.AddExpectedRecord(&ptrServiceSubLFullLen); server.AddExpectedRecord(&ptrServiceSubSFullLen); - server.AddExpectedRecord(&ptrServiceSubC0); NL_TEST_ASSERT(inSuite, SendQuery(kDnsSdQueryName) == CHIP_NO_ERROR); // These check that the requested records added are sent out correctly. NL_TEST_ASSERT(inSuite, server.GetSendCalled()); @@ -348,34 +360,64 @@ void CommissionableAdverts(nlTestSuite * inSuite, void * inContext) // Add more parameters, check that the subtypes and TXT values get set correctly. // Also check that we get proper values when the discriminators are small (no leading 0's) - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(commissionableNodeParamsLarge) == CHIP_NO_ERROR); - ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local for large parameters"); + NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(commissionableNodeParamsLargeBasic) == CHIP_NO_ERROR); + ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local for large basic parameters"); + server.Reset(); + server.AddExpectedRecord(&ptrCommissionableNodeService); + server.AddExpectedRecord(&ptrServiceSubLong); + server.AddExpectedRecord(&ptrServiceSubShort); + server.AddExpectedRecord(&ptrServiceSubCM); + server.AddExpectedRecord(&ptrServiceSubVendor); + server.AddExpectedRecord(&ptrServiceSubDeviceType); + NL_TEST_ASSERT(inSuite, SendQuery(kDnsSdQueryName) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, server.GetSendCalled()); + NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + + ChipLogProgress(Discovery, "Testing response to _matterc._udp.local for large basic parameters"); + server.Reset(); + server.AddExpectedRecord(&ptrCommissionableNode); + server.AddExpectedRecord(&srvCommissionableNode); + server.AddExpectedRecord(&txtCommissionableNodeParamsLargeBasic); + NL_TEST_ASSERT(inSuite, SendQuery(kMatterCommissionableNodeQueryName) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, server.GetSendCalled()); + NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + + ChipLogProgress(Discovery, "Testing response to instance name for large basic parameters"); + server.Reset(); + // Just the SRV and TXT should return + server.AddExpectedRecord(&srvCommissionableNode); + server.AddExpectedRecord(&txtCommissionableNodeParamsLargeBasic); + NL_TEST_ASSERT(inSuite, SendQuery(instanceName) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, server.GetSendCalled()); + NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); + + NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(commissionableNodeParamsLargeEnhanced) == CHIP_NO_ERROR); + ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local for large enhanced parameters"); server.Reset(); server.AddExpectedRecord(&ptrCommissionableNodeService); server.AddExpectedRecord(&ptrServiceSubLong); server.AddExpectedRecord(&ptrServiceSubShort); - server.AddExpectedRecord(&ptrServiceSubC1); + server.AddExpectedRecord(&ptrServiceSubCM); server.AddExpectedRecord(&ptrServiceSubVendor); server.AddExpectedRecord(&ptrServiceSubDeviceType); - server.AddExpectedRecord(&ptrServiceSubOpenWindow); NL_TEST_ASSERT(inSuite, SendQuery(kDnsSdQueryName) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, server.GetSendCalled()); NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); - ChipLogProgress(Discovery, "Testing response to _matterc._udp.local for large parameters"); + ChipLogProgress(Discovery, "Testing response to _matterc._udp.local for large enhanced parameters"); server.Reset(); server.AddExpectedRecord(&ptrCommissionableNode); server.AddExpectedRecord(&srvCommissionableNode); - server.AddExpectedRecord(&txtCommissionableNodeParamsLarge); + server.AddExpectedRecord(&txtCommissionableNodeParamsLargeEnhanced); NL_TEST_ASSERT(inSuite, SendQuery(kMatterCommissionableNodeQueryName) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, server.GetSendCalled()); NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); - ChipLogProgress(Discovery, "Testing response to instance name for large parameters"); + ChipLogProgress(Discovery, "Testing response to instance name for large enhanced parameters"); server.Reset(); // Just the SRV and TXT should return server.AddExpectedRecord(&srvCommissionableNode); - server.AddExpectedRecord(&txtCommissionableNodeParamsLarge); + server.AddExpectedRecord(&txtCommissionableNodeParamsLargeEnhanced); NL_TEST_ASSERT(inSuite, SendQuery(instanceName) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, server.GetSendCalled()); NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); @@ -392,7 +434,7 @@ void CommissionableAndOperationalAdverts(nlTestSuite * inSuite, void * inContext // Add two operational and a commissionable and test that we get the correct values back. NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(operationalParams1) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(operationalParams2) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(commissionableNodeParamsLarge) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, mdnsAdvertiser.Advertise(commissionableNodeParamsLargeEnhanced) == CHIP_NO_ERROR); // Services listing should have two operational ptrs, the base commissionable node ptr and the various _sub ptrs ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local"); @@ -402,10 +444,9 @@ void CommissionableAndOperationalAdverts(nlTestSuite * inSuite, void * inContext server.AddExpectedRecord(&ptrCommissionableNodeService); server.AddExpectedRecord(&ptrServiceSubLong); server.AddExpectedRecord(&ptrServiceSubShort); - server.AddExpectedRecord(&ptrServiceSubC1); + server.AddExpectedRecord(&ptrServiceSubCM); server.AddExpectedRecord(&ptrServiceSubVendor); server.AddExpectedRecord(&ptrServiceSubDeviceType); - server.AddExpectedRecord(&ptrServiceSubOpenWindow); NL_TEST_ASSERT(inSuite, SendQuery(kDnsSdQueryName) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, server.GetSendCalled()); NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); @@ -428,7 +469,7 @@ void CommissionableAndOperationalAdverts(nlTestSuite * inSuite, void * inContext server.Reset(); server.AddExpectedRecord(&ptrCommissionableNode); server.AddExpectedRecord(&srvCommissionableNode); - server.AddExpectedRecord(&txtCommissionableNodeParamsLarge); + server.AddExpectedRecord(&txtCommissionableNodeParamsLargeEnhanced); NL_TEST_ASSERT(inSuite, SendQuery(kMatterCommissionableNodeQueryName) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, server.GetSendCalled()); NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); @@ -456,7 +497,7 @@ void CommissionableAndOperationalAdverts(nlTestSuite * inSuite, void * inContext server.Reset(); // Just the SRV and TXT should return server.AddExpectedRecord(&srvCommissionableNode); - server.AddExpectedRecord(&txtCommissionableNodeParamsLarge); + server.AddExpectedRecord(&txtCommissionableNodeParamsLargeEnhanced); NL_TEST_ASSERT(inSuite, SendQuery(instanceName) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, server.GetSendCalled()); NL_TEST_ASSERT(inSuite, server.GetHeaderFound()); diff --git a/src/lib/mdns/platform/tests/TestPlatform.cpp b/src/lib/mdns/platform/tests/TestPlatform.cpp index 3214bdd56bdb38..9422c0b841f436 100644 --- a/src/lib/mdns/platform/tests/TestPlatform.cpp +++ b/src/lib/mdns/platform/tests/TestPlatform.cpp @@ -70,8 +70,7 @@ CommissionAdvertisingParameters commissionableNodeParamsSmall = .SetMac(ByteSpan(kMac)) .SetLongDiscriminator(0xFFE) .SetShortDiscriminator(0xF) - .SetCommissioningMode(false) - .SetAdditionalCommissioning(false); + .SetCommissioningMode(CommissioningMode::kDisabled); // Instance names need to be obtained from the advertiser, so they are not set here. test::ExpectedCall commissionableSmall = test::ExpectedCall() .SetProtocol(MdnsServiceProtocol::kMdnsProtocolUdp) @@ -80,9 +79,8 @@ test::ExpectedCall commissionableSmall = test::ExpectedCall() .AddTxt("CM", "0") .AddTxt("D", "4094") .AddSubtype("_S15") - .AddSubtype("_L4094") - .AddSubtype("_C0"); -CommissionAdvertisingParameters commissionableNodeParamsLarge = + .AddSubtype("_L4094"); +CommissionAdvertisingParameters commissionableNodeParamsLargeBasic = CommissionAdvertisingParameters() .SetCommissionAdvertiseMode(CommssionAdvertiseMode::kCommissionableNode) .SetMac(ByteSpan(kMac, sizeof(kMac))) @@ -90,33 +88,62 @@ CommissionAdvertisingParameters commissionableNodeParamsLarge = .SetShortDiscriminator(2) .SetVendorId(chip::Optional(555)) .SetDeviceType(chip::Optional(25)) - .SetCommissioningMode(true) - .SetAdditionalCommissioning(true) + .SetCommissioningMode(CommissioningMode::kEnabledBasic) .SetDeviceName(chip::Optional("testy-test")) .SetPairingHint(chip::Optional(3)) .SetPairingInstr(chip::Optional("Pair me")) .SetProductId(chip::Optional(897)) .SetRotatingId(chip::Optional("id_that_spins")); -test::ExpectedCall commissionableLarge = test::ExpectedCall() - .SetProtocol(MdnsServiceProtocol::kMdnsProtocolUdp) - .SetServiceName("_matterc") - .SetHostName(host) - .AddTxt("D", "22") - .AddTxt("VP", "555+897") - .AddTxt("AP", "1") - .AddTxt("CM", "1") - .AddTxt("DT", "25") - .AddTxt("DN", "testy-test") - .AddTxt("RI", "id_that_spins") - .AddTxt("PI", "Pair me") - .AddTxt("PH", "3") - .AddSubtype("_S2") - .AddSubtype("_L22") - .AddSubtype("_V555") - .AddSubtype("_T25") - .AddSubtype("_C1") - .AddSubtype("_A1"); +test::ExpectedCall commissionableLargeBasic = test::ExpectedCall() + .SetProtocol(MdnsServiceProtocol::kMdnsProtocolUdp) + .SetServiceName("_matterc") + .SetHostName(host) + .AddTxt("D", "22") + .AddTxt("VP", "555+897") + .AddTxt("CM", "1") + .AddTxt("DT", "25") + .AddTxt("DN", "testy-test") + .AddTxt("RI", "id_that_spins") + .AddTxt("PI", "Pair me") + .AddTxt("PH", "3") + .AddSubtype("_S2") + .AddSubtype("_L22") + .AddSubtype("_V555") + .AddSubtype("_T25") + .AddSubtype("_CM"); +CommissionAdvertisingParameters commissionableNodeParamsLargeEnhanced = + CommissionAdvertisingParameters() + .SetCommissionAdvertiseMode(CommssionAdvertiseMode::kCommissionableNode) + .SetMac(ByteSpan(kMac, sizeof(kMac))) + .SetLongDiscriminator(22) + .SetShortDiscriminator(2) + .SetVendorId(chip::Optional(555)) + .SetDeviceType(chip::Optional(25)) + .SetCommissioningMode(CommissioningMode::kEnabledEnhanced) + .SetDeviceName(chip::Optional("testy-test")) + .SetPairingHint(chip::Optional(3)) + .SetPairingInstr(chip::Optional("Pair me")) + .SetProductId(chip::Optional(897)) + .SetRotatingId(chip::Optional("id_that_spins")); + +test::ExpectedCall commissionableLargeEnhanced = test::ExpectedCall() + .SetProtocol(MdnsServiceProtocol::kMdnsProtocolUdp) + .SetServiceName("_matterc") + .SetHostName(host) + .AddTxt("D", "22") + .AddTxt("VP", "555+897") + .AddTxt("CM", "2") + .AddTxt("DT", "25") + .AddTxt("DN", "testy-test") + .AddTxt("RI", "id_that_spins") + .AddTxt("PI", "Pair me") + .AddTxt("PH", "3") + .AddSubtype("_S2") + .AddSubtype("_L22") + .AddSubtype("_V555") + .AddSubtype("_T25") + .AddSubtype("_CM"); void TestStub(nlTestSuite * inSuite, void * inContext) { // This is a test of the fake platform impl. We want @@ -166,10 +193,18 @@ void TestCommissionableNode(nlTestSuite * inSuite, void * inContext) test::Reset(); commissionableLarge.callType = test::CallType::kStart; NL_TEST_ASSERT(inSuite, - mdnsPlatform.GetCommissionableInstanceName(commissionableLarge.instanceName, - sizeof(commissionableLarge.instanceName)) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, test::AddExpectedCall(commissionableLarge) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, mdnsPlatform.Advertise(commissionableNodeParamsLarge) == CHIP_NO_ERROR); + mdnsPlatform.GetCommissionableInstanceName(commissionableLargeBasic.instanceName, + sizeof(commissionableLargeBasic.instanceName)) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, test::AddExpectedCall(commissionableLargeBasic) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, mdnsPlatform.Advertise(commissionableNodeParamsLargeBasic) == CHIP_NO_ERROR); + + test::Reset(); + commissionableLarge.callType = test::CallType::kStart; + NL_TEST_ASSERT(inSuite, + mdnsPlatform.GetCommissionableInstanceName(commissionableLargeEnhanced.instanceName, + sizeof(commissionableLargeEnhanced.instanceName)) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, test::AddExpectedCall(commissionableLargeEnhanced) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, mdnsPlatform.Advertise(commissionableNodeParamsLargeEnhanced) == CHIP_NO_ERROR); } const nlTest sTests[] = { diff --git a/src/lib/mdns/tests/TestServiceNaming.cpp b/src/lib/mdns/tests/TestServiceNaming.cpp index eddbfbc135f1b0..b3968929cdbe44 100644 --- a/src/lib/mdns/tests/TestServiceNaming.cpp +++ b/src/lib/mdns/tests/TestServiceNaming.cpp @@ -147,22 +147,8 @@ void TestMakeServiceNameSubtype(nlTestSuite * inSuite, void * inContext) // Commisioning mode tests filter.type = DiscoveryFilterType::kCommissioningMode; - filter.code = 0; NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, strcmp(buffer, "_C0") == 0); - filter.code = 1; - NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, strcmp(buffer, "_C1") == 0); - filter.code = 2; // only or or 1 allwoed - NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) != CHIP_NO_ERROR); - - // Commissioning mode open from command - filter.type = DiscoveryFilterType::kCommissioningModeFromCommand; - filter.code = 1; - NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, strcmp(buffer, "_A1") == 0); - filter.code = 0; // 1 is only value allowed - NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) != CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, strcmp(buffer, "_CM") == 0); // None tests. filter.type = DiscoveryFilterType::kNone; @@ -233,27 +219,9 @@ void TestMakeServiceTypeName(nlTestSuite * inSuite, void * inContext) // Commisioning mode tests filter.type = DiscoveryFilterType::kCommissioningMode; - filter.code = 0; - NL_TEST_ASSERT(inSuite, - MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, strcmp(buffer, "_C0._sub._matterc") == 0); - filter.code = 1; NL_TEST_ASSERT(inSuite, MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, strcmp(buffer, "_C1._sub._matterc") == 0); - filter.code = 2; // only or or 1 allwoed - NL_TEST_ASSERT(inSuite, - MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) != CHIP_NO_ERROR); - - // Commissioning mode open from command - filter.type = DiscoveryFilterType::kCommissioningModeFromCommand; - filter.code = 1; - NL_TEST_ASSERT(inSuite, - MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, strcmp(buffer, "_A1._sub._matterc") == 0); - filter.code = 0; // 1 is only value allowed - NL_TEST_ASSERT(inSuite, - MakeServiceTypeName(buffer, sizeof(buffer), filter, DiscoveryType::kCommissionableNode) != CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, strcmp(buffer, "_CM._sub._matterc") == 0); // None tests filter.type = DiscoveryFilterType::kNone; @@ -274,11 +242,10 @@ void TestMakeServiceTypeName(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, MakeServiceTypeName(buffer, 9, filter, DiscoveryType::kCommissionableNode) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, strcmp(buffer, "_matterc") == 0); - // Test buffer exactly the right size for subtype - "_C1._sub._matterc" = 17 + nullchar = 18 + // Test buffer exactly the right size for subtype - "_CM._sub._matterc" = 17 + nullchar = 18 filter.type = DiscoveryFilterType::kCommissioningMode; - filter.code = 1; NL_TEST_ASSERT(inSuite, MakeServiceTypeName(buffer, 18, filter, DiscoveryType::kCommissionableNode) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, strcmp(buffer, "_C1._sub._matterc") == 0); + NL_TEST_ASSERT(inSuite, strcmp(buffer, "_CM._sub._matterc") == 0); } const nlTest sTests[] = { diff --git a/src/lib/mdns/tests/TestTxtFields.cpp b/src/lib/mdns/tests/TestTxtFields.cpp index 989a85f4f89106..ee12d392fea5cd 100644 --- a/src/lib/mdns/tests/TestTxtFields.cpp +++ b/src/lib/mdns/tests/TestTxtFields.cpp @@ -49,9 +49,6 @@ void TestGetTxtFieldKey(nlTestSuite * inSuite, void * inContext) sprintf(key, "VP"); NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kVendorProduct); - sprintf(key, "AP"); - NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kAdditionalPairing); - sprintf(key, "CM"); NL_TEST_ASSERT(inSuite, GetTxtFieldKey(GetSpan(key)) == TxtFieldKey::kCommissioningMode); @@ -153,17 +150,6 @@ void TestGetLongDiscriminator(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, GetLongDiscriminator(GetSpan(ld)) == 0); } -void TestGetAdditionalPairing(nlTestSuite * inSuite, void * inContext) -{ - char ap[64]; - sprintf(ap, "1"); - NL_TEST_ASSERT(inSuite, GetAdditionalPairing(GetSpan(ap)) == 1); - - // overflow a uint8 - sprintf(ap, "%u", static_cast(std::numeric_limits::max()) + 1); - NL_TEST_ASSERT(inSuite, GetAdditionalPairing(GetSpan(ap)) == 0); -} - void TestGetCommissioningMode(nlTestSuite * inSuite, void * inContext) { char cm[64]; @@ -173,6 +159,9 @@ void TestGetCommissioningMode(nlTestSuite * inSuite, void * inContext) sprintf(cm, "1"); NL_TEST_ASSERT(inSuite, GetCommissioningMode(GetSpan(cm)) == 1); + sprintf(cm, "2"); + NL_TEST_ASSERT(inSuite, GetCommissioningMode(GetSpan(cm)) == 2); + // overflow a uint8 sprintf(cm, "%u", static_cast(std::numeric_limits::max()) + 1); NL_TEST_ASSERT(inSuite, GetCommissioningMode(GetSpan(cm)) == 0); @@ -291,8 +280,8 @@ void TestGetPairingInstruction(nlTestSuite * inSuite, void * inContext) bool NodeDataIsEmpty(const DiscoveredNodeData & node) { - if (node.longDiscriminator != 0 || node.vendorId != 0 || node.productId != 0 || node.additionalPairing != 0 || - node.commissioningMode != 0 || node.deviceType != 0 || node.rotatingIdLen != 0 || node.pairingHint != 0 || + if (node.longDiscriminator != 0 || node.vendorId != 0 || node.productId != 0 || node.commissioningMode != 0 || + node.deviceType != 0 || node.rotatingIdLen != 0 || node.pairingHint != 0 || node.mrpRetryIntervalIdle != kUndefinedRetryInterval || node.mrpRetryIntervalActive != kUndefinedRetryInterval || node.supportsTcp) { @@ -337,14 +326,6 @@ void TestFillDiscoveredNodeDataFromTxt(nlTestSuite * inSuite, void * inContext) filled.productId = 0; NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(filled)); - // Additional Pairing - sprintf(key, "AP"); - sprintf(val, "1"); - FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled); - NL_TEST_ASSERT(inSuite, filled.additionalPairing == 1); - filled.additionalPairing = 0; - NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(filled)); - // Commissioning mode sprintf(key, "CM"); sprintf(val, "1"); @@ -587,7 +568,6 @@ const nlTest sTests[] = { NL_TEST_DEF("TxtFieldProduct", TestGetProduct), // NL_TEST_DEF("TxtFieldVendor", TestGetVendor), // NL_TEST_DEF("TxtFieldLongDiscriminator", TestGetLongDiscriminator), // - NL_TEST_DEF("TxtFieldAdditionalPairing", TestGetAdditionalPairing), // NL_TEST_DEF("TxtFieldCommissioningMode", TestGetCommissioningMode), // NL_TEST_DEF("TxtFieldDeviceType", TestGetDeviceType), // NL_TEST_DEF("TxtFieldDeviceName", TestGetDeviceName), // diff --git a/src/lib/shell/commands/Dns.cpp b/src/lib/shell/commands/Dns.cpp index b108cb58783f04..5172e153787cce 100644 --- a/src/lib/shell/commands/Dns.cpp +++ b/src/lib/shell/commands/Dns.cpp @@ -82,7 +82,6 @@ class DnsShellResolverDelegate : public Mdns::ResolverDelegate streamer_printf(streamer_get(), " Device type: %" PRIu16 "\n", nodeData.deviceType); streamer_printf(streamer_get(), " Device name: %s\n", nodeData.deviceName); streamer_printf(streamer_get(), " Commissioning mode: %d\n", static_cast(nodeData.commissioningMode)); - streamer_printf(streamer_get(), " Additional pairing: %d\n", static_cast(nodeData.additionalPairing)); streamer_printf(streamer_get(), " Pairing hint: %" PRIu16 "\n", nodeData.pairingHint); streamer_printf(streamer_get(), " Pairing instruction: %s\n", nodeData.pairingInstruction); streamer_printf(streamer_get(), " Rotating ID %s\n", rotatingId); @@ -159,9 +158,6 @@ bool ParseSubType(int argc, char ** argv, Mdns::DiscoveryFilter & filter) case 'C': filterType = Mdns::DiscoveryFilterType::kCommissioningMode; break; - case 'A': - filterType = Mdns::DiscoveryFilterType::kCommissioningModeFromCommand; - break; default: return false; } From 88fc6951066a93816b2a0b532d9c710739b62d85 Mon Sep 17 00:00:00 2001 From: Michael Spang Date: Tue, 14 Sep 2021 14:20:57 -0400 Subject: [PATCH 038/255] Remove redundant src/platform/ESP32/args.gni (#9672) The args file that applies to ESP32 is the one in config/esp32/args.gni and the ones in src/platform/ESP32/args.gni are dead code (those would have been used if ESP32 was in the unified build and thus used the toolchain construct to set up the build, but currently this is not done because ESP32 must be built from within the cmake build). Remove src/platform/ESP32/args.gni and always use the one in config/. --- config/esp32/toolchain/BUILD.gn | 2 +- src/platform/ESP32/args.gni | 26 -------------------------- 2 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 src/platform/ESP32/args.gni diff --git a/config/esp32/toolchain/BUILD.gn b/config/esp32/toolchain/BUILD.gn index 24641b945f1554..b3c289933d7747 100644 --- a/config/esp32/toolchain/BUILD.gn +++ b/config/esp32/toolchain/BUILD.gn @@ -33,6 +33,6 @@ gcc_toolchain("esp32") { current_os = "freertos" current_cpu = esp32_cpu is_clang = false - import("${chip_root}/src/platform/ESP32/args.gni") + import("${chip_root}/config/esp32/args.gni") } } diff --git a/src/platform/ESP32/args.gni b/src/platform/ESP32/args.gni deleted file mode 100644 index 4c4c7f9c4b595f..00000000000000 --- a/src/platform/ESP32/args.gni +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (c) 2020 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build_overrides/chip.gni") - -chip_device_platform = "esp32" - -lwip_platform = "external" -mbedtls_target = "//mbedtls:mbedtls" - -chip_build_tests = false -chip_inet_config_enable_dns_resolver = false -chip_inet_config_enable_tun_endpoint = false -chip_inet_config_enable_tcp_endpoint = true -chip_inet_config_enable_udp_endpoint = true From e71f2d73e35ce8a8bf8a7cf231e2f37dd7be9e5c Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Tue, 14 Sep 2021 14:34:50 -0400 Subject: [PATCH 039/255] Increase ESP32 build time to 10min instead of 5m (#9697) Also remove some extra 'Copy build artifacts'. Bloat check should be sufficient on the all-clusters-app only. --- .github/workflows/examples-esp32.yaml | 79 +++------------------------ 1 file changed, 8 insertions(+), 71 deletions(-) diff --git a/.github/workflows/examples-esp32.yaml b/.github/workflows/examples-esp32.yaml index dfb4cf96f42243..2832aa54363c15 100644 --- a/.github/workflows/examples-esp32.yaml +++ b/.github/workflows/examples-esp32.yaml @@ -26,7 +26,7 @@ jobs: # TODO ESP32 https://github.com/project-chip/connectedhomeip/issues/1510 esp32: name: ESP32 - timeout-minutes: 60 + timeout-minutes: 70 env: BUILD_TYPE: esp32 @@ -84,89 +84,26 @@ jobs: example_binaries/$BUILD_TYPE-build/chip-all-clusters-app.elf \ /tmp/bloat_reports/ - name: Build example Pigweed App - timeout-minutes: 5 + timeout-minutes: 10 run: scripts/examples/esp_example.sh pigweed-app sdkconfig.defaults - - name: Copy aside build products - run: | - mkdir -p example_binaries/$BUILD_TYPE-build - cp examples/pigweed-app/esp32/build/chip-pigweed-app.elf \ - example_binaries/$BUILD_TYPE-build/chip-pigweed-app.elf - .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ - esp32 default pigweed-app \ - example_binaries/$BUILD_TYPE-build/chip-pigweed-app.elf \ - /tmp/bloat_reports/ - name: Build example Lock App - timeout-minutes: 5 + timeout-minutes: 10 run: scripts/examples/esp_example.sh lock-app sdkconfig.defaults - - name: Copy aside build products - run: | - mkdir -p example_binaries/$BUILD_TYPE-build - cp examples/lock-app/esp32/build/chip-lock-app.elf \ - example_binaries/$BUILD_TYPE-build/chip-lock-app.elf - .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ - esp32 default lock-app \ - example_binaries/$BUILD_TYPE-build/chip-lock-app.elf \ - /tmp/bloat_reports/ - name: Build example Bridge App - timeout-minutes: 5 + timeout-minutes: 10 run: scripts/examples/esp_example.sh bridge-app - - name: Copy aside build products - run: | - mkdir -p example_binaries/$BUILD_TYPE-build - cp examples/bridge-app/esp32/build/chip-bridge-app.elf \ - example_binaries/$BUILD_TYPE-build/chip-bridge-app.elf - .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ - esp32 default bridge-app \ - example_binaries/$BUILD_TYPE-build/chip-bridge-app.elf \ - /tmp/bloat_reports/ - name: Build example Persistent Storage App - timeout-minutes: 5 + timeout-minutes: 10 run: scripts/examples/esp_example.sh persistent-storage sdkconfig.defaults - - name: Copy aside build products - run: | - mkdir -p example_binaries/$BUILD_TYPE-build - cp examples/persistent-storage/esp32/build/chip-persistent-storage.elf \ - example_binaries/$BUILD_TYPE-build/chip-persistent-storage.elf - .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ - esp32 default persistent-storage \ - example_binaries/$BUILD_TYPE-build/chip-persistent-storage.elf \ - /tmp/bloat_reports/ - name: Build example Shell App - timeout-minutes: 5 + timeout-minutes: 10 run: scripts/examples/esp_example.sh shell sdkconfig.defaults - - name: Copy aside build products - run: | - mkdir -p example_binaries/$BUILD_TYPE-build - cp examples/shell/esp32/build/chip-shell.elf \ - example_binaries/$BUILD_TYPE-build/chip-shell.elf - .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ - esp32 default shell \ - example_binaries/$BUILD_TYPE-build/chip-shell.elf \ - /tmp/bloat_reports/ - name: Build example Temperature Measurement App - timeout-minutes: 5 + timeout-minutes: 10 run: scripts/examples/esp_example.sh temperature-measurement-app sdkconfig.optimize.defaults - - name: Copy aside build products - run: | - mkdir -p example_binaries/$BUILD_TYPE-build - cp examples/temperature-measurement-app/esp32/build/chip-temperature-measurement-app.elf \ - example_binaries/$BUILD_TYPE-build/chip-temperature-measurement-app.elf - .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ - esp32 optimize temperature-measurement-app \ - example_binaries/$BUILD_TYPE-build/chip-temperature-measurement-app.elf \ - /tmp/bloat_reports/ - name: Build example IPv6 Only App - timeout-minutes: 5 + timeout-minutes: 10 run: scripts/examples/esp_example.sh ipv6only-app sdkconfig.defaults - - name: Copy aside build products - run: | - mkdir -p example_binaries/$BUILD_TYPE-build - cp examples/ipv6only-app/esp32/build/chip-ipv6only-app.elf \ - example_binaries/$BUILD_TYPE-build/chip-ipv6only-app.elf - .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ - esp32 default ipv6only-app \ - example_binaries/$BUILD_TYPE-build/chip-ipv6only-app.elf \ - /tmp/bloat_reports/ - name: Binary artifact suffix id: outsuffix uses: haya14busa/action-cond@v1.0.0 From cfacfda4c03a2b83e339de312c79954660b3011e Mon Sep 17 00:00:00 2001 From: Sharad Binjola <31142146+sharadb-amazon@users.noreply.github.com> Date: Tue, 14 Sep 2021 14:01:04 -0700 Subject: [PATCH 040/255] Adding cmd line args to tv-casting-app for device type of commissioners to be discovered (#9572) * Adding cmd line args to tv-casting-app for device type of commissioners to be discovered * Addressing comments from andy31415, bzbarsky-apple * Switching logging module to AppServer * Switching to lib/support/SafeInt.h for Cirque build * Fixing compiler errors * Accepting both text and numeric representations of cmd line arg for device type, defaulting to 'all' * Fixing merge error/typo --- examples/tv-casting-app/linux/main.cpp | 110 ++++++++++++++++++++----- 1 file changed, 88 insertions(+), 22 deletions(-) diff --git a/examples/tv-casting-app/linux/main.cpp b/examples/tv-casting-app/linux/main.cpp index 12353f99de8c33..bcd7c5dd5f8d63 100644 --- a/examples/tv-casting-app/linux/main.cpp +++ b/examples/tv-casting-app/linux/main.cpp @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include #include @@ -26,13 +28,72 @@ using namespace chip; using namespace chip::Controller; +using chip::ArgParser::HelpOptions; +using chip::ArgParser::OptionDef; +using chip::ArgParser::OptionSet; -constexpr int kTvDeviceType = 35; -constexpr uint16_t commissioningWindowTimeoutInSec = 3 * 60; -constexpr uint32_t commissionerDiscoveryTimeoutInMs = 5 * 1000; +struct DeviceType +{ + const char * name; + uint16_t id; +}; + +constexpr DeviceType kKnownDeviceTypes[] = { { "video-player", 35 }, { "dimmable-light", 257 } }; +constexpr int kKnownDeviceTypesCount = sizeof kKnownDeviceTypes / sizeof *kKnownDeviceTypes; +constexpr uint16_t kOptionDeviceType = 't'; +constexpr uint16_t kCommissioningWindowTimeoutInSec = 3 * 60; +constexpr uint32_t kCommissionerDiscoveryTimeoutInMs = 5 * 1000; -CommissionableNodeController commissionableNodeController; -chip::System::SocketWatchToken token; +CommissionableNodeController gCommissionableNodeController; +chip::System::SocketWatchToken gToken; +Mdns::DiscoveryFilter gDiscoveryFilter = Mdns::DiscoveryFilter(); + +bool HandleOptions(const char * aProgram, OptionSet * aOptions, int aIdentifier, const char * aName, const char * aValue) +{ + switch (aIdentifier) + { + case kOptionDeviceType: { + char * endPtr; + long deviceType = strtol(aValue, &endPtr, 10); + if (*endPtr == '\0' && deviceType > 0 && CanCastTo(deviceType)) + { + gDiscoveryFilter = Mdns::DiscoveryFilter(Mdns::DiscoveryFilterType::kDeviceType, static_cast(deviceType)); + return true; + } + else + { + for (int i = 0; i < kKnownDeviceTypesCount; i++) + { + if (strcasecmp(aValue, kKnownDeviceTypes[i].name) == 0) + { + gDiscoveryFilter = Mdns::DiscoveryFilter(Mdns::DiscoveryFilterType::kDeviceType, kKnownDeviceTypes[i].id); + return true; + } + } + } + ChipLogError(AppServer, "%s: INTERNAL ERROR: Unhandled option value: %s %s", aProgram, aName, aValue); + return false; + } + default: + ChipLogError(AppServer, "%s: INTERNAL ERROR: Unhandled option: %s", aProgram, aName); + return false; + } +} + +OptionDef cmdLineOptionsDef[] = { + { "device-type", chip::ArgParser::kArgumentRequired, kOptionDeviceType }, + {}, +}; + +OptionSet cmdLineOptions = { HandleOptions, cmdLineOptionsDef, "PROGRAM OPTIONS", + " -t \n" + " --device-type \n" + " Device type of the commissioner to discover and request commissioning from. Specify value as " + "a decimal integer or a known text representation. Defaults to all device types\n" }; + +HelpOptions helpOptions("tv-casting-app", "Usage: tv-casting-app [options]", "1.0"); + +OptionSet * allOptions[] = { &cmdLineOptions, &helpOptions, nullptr }; /** * Enters commissioning mode, opens commissioning window, logs onboarding payload. @@ -44,7 +105,7 @@ void PrepareForCommissioning(const Mdns::DiscoveredNodeData * selectedCommission // Enter commissioning mode, open commissioning window Server::GetInstance().Init(); ReturnOnFailure(Server::GetInstance().GetCommissionManager().OpenBasicCommissioningWindow(ResetFabrics::kYes, - commissioningWindowTimeoutInSec)); + kCommissioningWindowTimeoutInSec)); // Display onboarding payload chip::DeviceLayer::ConfigurationMgr().LogDeviceConfig(); @@ -74,11 +135,11 @@ void RequestUserDirectedCommissioning(System::SocketEvents events, intptr_t data int selectedCommissionerNumber = CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES; scanf("%d", &selectedCommissionerNumber); printf("%d\n", selectedCommissionerNumber); - chip::DeviceLayer::SystemLayerSockets().StopWatchingSocket(&token); + chip::DeviceLayer::SystemLayerSockets().StopWatchingSocket(&gToken); const Mdns::DiscoveredNodeData * selectedCommissioner = - commissionableNodeController.GetDiscoveredCommissioner(selectedCommissionerNumber - 1); - VerifyOrReturn(selectedCommissioner != nullptr, ChipLogError(Zcl, "No such commissioner!")); + gCommissionableNodeController.GetDiscoveredCommissioner(selectedCommissionerNumber - 1); + VerifyOrReturn(selectedCommissioner != nullptr, ChipLogError(AppServer, "No such commissioner!")); PrepareForCommissioning(selectedCommissioner); } @@ -89,31 +150,31 @@ void InitCommissioningFlow(intptr_t commandArg) // Display discovered commissioner TVs to ask user to select one for (int i = 0; i < CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES; i++) { - const Mdns::DiscoveredNodeData * commissioner = commissionableNodeController.GetDiscoveredCommissioner(i); + const Mdns::DiscoveredNodeData * commissioner = gCommissionableNodeController.GetDiscoveredCommissioner(i); if (commissioner != nullptr) { - ChipLogProgress(Zcl, "Discovered Commissioner #%d", ++commissionerCount); + ChipLogProgress(AppServer, "Discovered Commissioner #%d", ++commissionerCount); commissioner->LogDetail(); } } if (commissionerCount > 0) { - ChipLogProgress( - Zcl, "%d commissioner(s) discovered. Select one (by number# above) to request commissioning from: ", commissionerCount); + ChipLogProgress(AppServer, "%d commissioner(s) discovered. Select one (by number# above) to request commissioning from: ", + commissionerCount); // Setup for async/non-blocking user input from stdin int flags = fcntl(STDIN_FILENO, F_GETFL, 0); VerifyOrReturn(fcntl(0, F_SETFL, flags | O_NONBLOCK) == 0, - ChipLogError(Zcl, "Could not set non-blocking mode for user input!")); - ReturnOnFailure(chip::DeviceLayer::SystemLayerSockets().StartWatchingSocket(STDIN_FILENO, &token)); + ChipLogError(AppServer, "Could not set non-blocking mode for user input!")); + ReturnOnFailure(chip::DeviceLayer::SystemLayerSockets().StartWatchingSocket(STDIN_FILENO, &gToken)); ReturnOnFailure( - chip::DeviceLayer::SystemLayerSockets().SetCallback(token, RequestUserDirectedCommissioning, (intptr_t) NULL)); - ReturnOnFailure(chip::DeviceLayer::SystemLayerSockets().RequestCallbackOnPendingRead(token)); + chip::DeviceLayer::SystemLayerSockets().SetCallback(gToken, RequestUserDirectedCommissioning, (intptr_t) NULL)); + ReturnOnFailure(chip::DeviceLayer::SystemLayerSockets().RequestCallbackOnPendingRead(gToken)); } else { - ChipLogError(Zcl, "No commissioner discovered, commissioning must be initiated manually!"); + ChipLogError(AppServer, "No commissioner discovered, commissioning must be initiated manually!"); PrepareForCommissioning(); } } @@ -121,16 +182,21 @@ void InitCommissioningFlow(intptr_t commandArg) int main(int argc, char * argv[]) { CHIP_ERROR err = CHIP_NO_ERROR; + SuccessOrExit(err = chip::Platform::MemoryInit()); SuccessOrExit(err = chip::DeviceLayer::PlatformMgr().InitChipStack()); + if (!chip::ArgParser::ParseArgs(argv[0], argc, argv, allOptions)) + { + return 1; + } + // Send discover commissioners request - SuccessOrExit(err = commissionableNodeController.DiscoverCommissioners( - Mdns::DiscoveryFilter(Mdns::DiscoveryFilterType::kDeviceType, kTvDeviceType))); + SuccessOrExit(err = gCommissionableNodeController.DiscoverCommissioners(gDiscoveryFilter)); // Give commissioners some time to respond and then ScheduleWork to initiate commissioning DeviceLayer::SystemLayer().StartTimer( - commissionerDiscoveryTimeoutInMs, + kCommissionerDiscoveryTimeoutInMs, [](System::Layer *, void *) { chip::DeviceLayer::PlatformMgr().ScheduleWork(InitCommissioningFlow); }, nullptr); // TBD: Content casting commands @@ -139,7 +205,7 @@ int main(int argc, char * argv[]) exit: if (err != CHIP_NO_ERROR) { - ChipLogError(Zcl, "Failed to run TV Casting App: %s", ErrorStr(err)); + ChipLogError(AppServer, "Failed to run TV Casting App: %s", ErrorStr(err)); // End the program with non zero error code to indicate an error. return 1; } From eef1141303281e52aaf969bd8e31fd20322e67d9 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Tue, 14 Sep 2021 17:44:19 -0400 Subject: [PATCH 041/255] Fix compile error on TestPlatform. (#9707) --- src/lib/mdns/platform/tests/TestPlatform.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/mdns/platform/tests/TestPlatform.cpp b/src/lib/mdns/platform/tests/TestPlatform.cpp index 9422c0b841f436..21f412ed516139 100644 --- a/src/lib/mdns/platform/tests/TestPlatform.cpp +++ b/src/lib/mdns/platform/tests/TestPlatform.cpp @@ -191,7 +191,7 @@ void TestCommissionableNode(nlTestSuite * inSuite, void * inContext) // TODO: Right now, platform impl doesn't stop commissionable node before starting a new one. Add stop call here once that is // fixed. test::Reset(); - commissionableLarge.callType = test::CallType::kStart; + commissionableLargeBasic.callType = test::CallType::kStart; NL_TEST_ASSERT(inSuite, mdnsPlatform.GetCommissionableInstanceName(commissionableLargeBasic.instanceName, sizeof(commissionableLargeBasic.instanceName)) == CHIP_NO_ERROR); @@ -199,7 +199,7 @@ void TestCommissionableNode(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, mdnsPlatform.Advertise(commissionableNodeParamsLargeBasic) == CHIP_NO_ERROR); test::Reset(); - commissionableLarge.callType = test::CallType::kStart; + commissionableLargeEnhanced.callType = test::CallType::kStart; NL_TEST_ASSERT(inSuite, mdnsPlatform.GetCommissionableInstanceName(commissionableLargeEnhanced.instanceName, sizeof(commissionableLargeEnhanced.instanceName)) == CHIP_NO_ERROR); From 181ab6685f2c9e705c5ee3f64792d358c8d5a6ce Mon Sep 17 00:00:00 2001 From: Alexandr Kolosov Date: Wed, 15 Sep 2021 01:03:21 +0300 Subject: [PATCH 042/255] [Telink]: Fix entropy source failed crash on boot (#9635) * [Telink]: Fix entropy source failed crash on boot * [Telink]: Fix restyled check fail * [Telink]: Fix review remarks * [Telink]: Fix nrfconnect build fail * Update src/platform/Zephyr/PlatformManagerImpl.cpp * Update src/platform/Zephyr/PlatformManagerImpl.cpp Co-authored-by: Boris Zbarsky --- src/platform/Zephyr/PlatformManagerImpl.cpp | 38 ++++++++++++++++++--- src/platform/telink/BUILD.gn | 2 ++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/platform/Zephyr/PlatformManagerImpl.cpp b/src/platform/Zephyr/PlatformManagerImpl.cpp index a31916b8fc20c9..b63fc13c1028d4 100644 --- a/src/platform/Zephyr/PlatformManagerImpl.cpp +++ b/src/platform/Zephyr/PlatformManagerImpl.cpp @@ -21,6 +21,10 @@ * for Zephyr platforms. */ +#if !CONFIG_NORDIC_SECURITY_BACKEND +#include // nogncheck +#endif // !CONFIG_NORDIC_SECURITY_BACKEND + #include #include @@ -37,19 +41,43 @@ static K_THREAD_STACK_DEFINE(sChipThreadStack, CHIP_DEVICE_CONFIG_CHIP_TASK_STAC PlatformManagerImpl PlatformManagerImpl::sInstance{ sChipThreadStack }; +#if !CONFIG_NORDIC_SECURITY_BACKEND +static int app_entropy_source(void * data, unsigned char * output, size_t len, size_t * olen) +{ + const struct device * entropy = device_get_binding(DT_CHOSEN_ZEPHYR_ENTROPY_LABEL); + int ret = entropy_get_entropy(entropy, output, len); + + if (ret == 0) + { + *olen = len; + } + else + { + *olen = 0; + } + + return ret; +} +#endif // !CONFIG_NORDIC_SECURITY_BACKEND + CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) { CHIP_ERROR err; - const struct device * entropy = device_get_binding(DT_CHOSEN_ZEPHYR_ENTROPY_LABEL); - unsigned int seed; + +#if !CONFIG_NORDIC_SECURITY_BACKEND + // Minimum required from source before entropy is released ( with mbedtls_entropy_func() ) (in bytes) + const size_t kThreshold = 16; +#endif // !CONFIG_NORDIC_SECURITY_BACKEND // Initialize the configuration system. err = Internal::ZephyrConfig::Init(); SuccessOrExit(err); - // Get entropy to initialize seed for pseudorandom operations. - SuccessOrExit(entropy_get_entropy(entropy, reinterpret_cast(&seed), sizeof(seed))); - srand(seed); +#if !CONFIG_NORDIC_SECURITY_BACKEND + // Add entropy source based on Zephyr entropy driver + err = chip::Crypto::add_entropy_source(app_entropy_source, NULL, kThreshold); + SuccessOrExit(err); +#endif // !CONFIG_NORDIC_SECURITY_BACKEND // Call _InitChipStack() on the generic implementation base class to finish the initialization process. err = Internal::GenericPlatformManagerImpl_Zephyr::_InitChipStack(); diff --git a/src/platform/telink/BUILD.gn b/src/platform/telink/BUILD.gn index 36dbbdaeb9e34f..6ef5bf7162dd5c 100644 --- a/src/platform/telink/BUILD.gn +++ b/src/platform/telink/BUILD.gn @@ -58,4 +58,6 @@ static_library("telink") { deps += [ "${chip_root}/src/lib/mdns:platform_header" ] } } + + public_deps += [ "${chip_root}/src/crypto" ] } From b384bded2860f37e40036e422a1bef7b31bd098b Mon Sep 17 00:00:00 2001 From: Zang MingJie Date: Wed, 15 Sep 2021 07:02:56 +0800 Subject: [PATCH 043/255] TestUDP: use ephemeral port (#9692) --- src/transport/raw/UDP.cpp | 8 ++++++++ src/transport/raw/UDP.h | 2 ++ src/transport/raw/tests/TestUDP.cpp | 6 +++--- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/transport/raw/UDP.cpp b/src/transport/raw/UDP.cpp index a09c462e5660d1..cfef98cf48b429 100644 --- a/src/transport/raw/UDP.cpp +++ b/src/transport/raw/UDP.cpp @@ -61,6 +61,8 @@ CHIP_ERROR UDP::Init(UdpListenParameters & params) mState = State::kInitialized; + ChipLogDetail(Inet, "UDP::Init bound to port=%d", mUDPEndPoint->GetBoundPort()); + exit: if (err != CHIP_NO_ERROR) { @@ -75,6 +77,12 @@ CHIP_ERROR UDP::Init(UdpListenParameters & params) return err; } +uint16_t UDP::GetBoundPort() +{ + VerifyOrDie(mUDPEndPoint != nullptr); + return mUDPEndPoint->GetBoundPort(); +} + void UDP::Close() { if (mUDPEndPoint) diff --git a/src/transport/raw/UDP.h b/src/transport/raw/UDP.h index 8827ab7984a00a..d5628295720321 100644 --- a/src/transport/raw/UDP.h +++ b/src/transport/raw/UDP.h @@ -105,6 +105,8 @@ class DLL_EXPORT UDP : public Base */ CHIP_ERROR Init(UdpListenParameters & params); + uint16_t GetBoundPort(); + /** * Close the open endpoint without destroying the object */ diff --git a/src/transport/raw/tests/TestUDP.cpp b/src/transport/raw/tests/TestUDP.cpp index 3a9aadf58012fc..85bb9e8ae2d441 100644 --- a/src/transport/raw/tests/TestUDP.cpp +++ b/src/transport/raw/tests/TestUDP.cpp @@ -90,7 +90,7 @@ void CheckSimpleInitTest(nlTestSuite * inSuite, void * inContext, Inet::IPAddres Transport::UDP udp; - CHIP_ERROR err = udp.Init(Transport::UdpListenParameters(&ctx.GetInetLayer()).SetAddressType(type)); + CHIP_ERROR err = udp.Init(Transport::UdpListenParameters(&ctx.GetInetLayer()).SetAddressType(type).SetListenPort(0)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); } @@ -122,7 +122,7 @@ void CheckMessageTest(nlTestSuite * inSuite, void * inContext, const IPAddress & Transport::UDP udp; - err = udp.Init(Transport::UdpListenParameters(&ctx.GetInetLayer()).SetAddressType(addr.Type())); + err = udp.Init(Transport::UdpListenParameters(&ctx.GetInetLayer()).SetAddressType(addr.Type()).SetListenPort(0)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); MockTransportMgrDelegate gMockTransportMgrDelegate(inSuite); @@ -139,7 +139,7 @@ void CheckMessageTest(nlTestSuite * inSuite, void * inContext, const IPAddress & NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); // Should be able to send a message to itself by just calling send. - err = udp.SendMessage(Transport::PeerAddress::UDP(addr), std::move(buffer)); + err = udp.SendMessage(Transport::PeerAddress::UDP(addr, udp.GetBoundPort()), std::move(buffer)); if (err == System::MapErrorPOSIX(EADDRNOTAVAIL)) { // TODO(#2698): the underlying system does not support IPV6. This early return From 2666b55c5b0fbd6eefdc0bf1dfb329eef6fc0610 Mon Sep 17 00:00:00 2001 From: Michael Spang Date: Tue, 14 Sep 2021 19:08:41 -0400 Subject: [PATCH 044/255] Add manifest to esp32 flashing script build (#9666) For our interop testing we use packaged firmware from infrastructure rather than building locally. Currently ESP32 can produce the script but since it does not generate a list of the files the script requires, we cannot package it. Add the missing manifest and enable packaged flashable firmware for ESP32. Tested via: scripts/build/build_examples.py --board m5stack --app all-clusters --enable-flashbundle build --create-archives /tmp --- examples/common/cmake/idf_flashing.cmake | 26 ++++++++++++++++++------ scripts/build/builders/esp32.py | 9 ++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/examples/common/cmake/idf_flashing.cmake b/examples/common/cmake/idf_flashing.cmake index 112131363e905c..b2406f0661edeb 100644 --- a/examples/common/cmake/idf_flashing.cmake +++ b/examples/common/cmake/idf_flashing.cmake @@ -44,8 +44,14 @@ macro(flashing_script) set(flashing_utils_dir "${project_path}/third_party/connectedhomeip/scripts/flashing/") set(board_firmware_utils "${board_type}_firmware_utils.py") + set(common_firmware_utils "firmware_utils.py") + set(application "${CMAKE_PROJECT_NAME}.bin") + set(bootloader "bootloader/bootloader.bin") + set(partition_table "partition_table/partition-table.bin") + set(flashing_script "${CMAKE_PROJECT_NAME}.flash.py") + set(manifest "${CMAKE_PROJECT_NAME}.flashbundle.txt") configure_file("${flashing_utils_dir}/${board_firmware_utils}" "${build_dir}/${board_firmware_utils}" COPYONLY) - configure_file("${flashing_utils_dir}/firmware_utils.py" "${build_dir}/firmware_utils.py" COPYONLY) + configure_file("${flashing_utils_dir}/${common_firmware_utils}" "${build_dir}/${common_firmware_utils}" COPYONLY) get_additional_flashing_depends(${ARGN}) foreach(dep IN LISTS additional_flashing_depends) @@ -54,18 +60,26 @@ macro(flashing_script) list(APPEND build_dir_depends "${build_dir}/${filename}") endforeach(dep) + set(manifest_files ${application} ${bootloader} ${partition_table} ${flashing_script} ${board_firmware_utils} ${common_firmware_utils}) + list(JOIN manifest_files "\n" manifest_content) + + file(GENERATE + OUTPUT "${build_dir}/${manifest}" + CONTENT "${manifest_content}\n") + add_custom_target(flashing_script + ALL COMMAND ${python} "${project_path}/../../../scripts/flashing/gen_flashing_script.py" ${board_type} - --output "${build_dir}/${CMAKE_PROJECT_NAME}.flash.py" + --output "${build_dir}/${flashing_script}" --port "$ENV{ESPPORT}" --baud 460800 --before ${CONFIG_ESPTOOLPY_BEFORE} --after ${CONFIG_ESPTOOLPY_AFTER} - --application "${CMAKE_PROJECT_NAME}.bin" - --bootloader "bootloader/bootloader.bin" - --partition "partition_table/partition-table.bin" - --use-partition-file "${build_dir}/partition_table/partition-table.bin" + --application "${application}" + --bootloader "${bootloader}" + --partition "${partition_table}" + --use-partition-file "${build_dir}/${partition_table}" --use-parttool ${idf_path}/components/partition_table/parttool.py --use-sdkconfig ${project_path}/sdkconfig WORKING_DIRECTORY ${build_dir} diff --git a/scripts/build/builders/esp32.py b/scripts/build/builders/esp32.py index c58ab6021dd6d9..a3096dee26acc9 100644 --- a/scripts/build/builders/esp32.py +++ b/scripts/build/builders/esp32.py @@ -64,6 +64,9 @@ def AppNamePrefix(self): else: raise Exception('Unknown app type: %r' % self) + def FlashBundleName(self): + return self.AppNamePrefix + '.flashbundle.txt' + def DefaultsFileName(board: Esp32Board, app: Esp32App): if app != Esp32App.ALL_CLUSTERS: @@ -129,3 +132,9 @@ def build_outputs(self): self.app.AppNamePrefix + '.map': os.path.join(self.output_dir, self.app.AppNamePrefix + '.map'), } + + def flashbundle(self): + with open(os.path.join(self.output_dir, self.app.FlashBundleName()), 'r') as fp: + return { + l.strip(): os.path.join(self.output_dir, l.strip()) for l in fp.readlines() if l.strip() + } From 2579d8f766b41b249f478401e6179e5941703830 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 14 Sep 2021 19:09:49 -0400 Subject: [PATCH 045/255] Rename OperationalCredentialsCluster.yaml so CI finds the test. (#9650) CI looks for test files whose names start with "Test", and this file does not do that now. --- .../chip-tool/templates/tests-commands.zapt | 2 +- ... => TestOperationalCredentialsCluster.yaml} | 0 .../CHIP/templates/clusters-tests.zapt | 2 +- .../Framework/CHIPTests/CHIPClustersTests.m | 4 ++-- .../chip-tool/zap-generated/test/Commands.h | 18 +++++++++--------- 5 files changed, 13 insertions(+), 13 deletions(-) rename src/app/tests/suites/{OperationalCredentialsCluster.yaml => TestOperationalCredentialsCluster.yaml} (100%) diff --git a/examples/chip-tool/templates/tests-commands.zapt b/examples/chip-tool/templates/tests-commands.zapt index f667107cb8a2c9..936f4e68e63a62 100644 --- a/examples/chip-tool/templates/tests-commands.zapt +++ b/examples/chip-tool/templates/tests-commands.zapt @@ -4,5 +4,5 @@ #include -{{>test_cluster tests="TV_TargetNavigatorCluster, TV_AudioOutputCluster, TV_ApplicationLauncherCluster, TV_KeypadInputCluster, TV_AccountLoginCluster, TV_WakeOnLanCluster, TV_ApplicationBasicCluster, TV_MediaPlaybackCluster, TV_TvChannelCluster, TV_LowPowerCluster, TV_MediaInputCluster, TestCluster, TestConstraints, TestDelayCommands, TestSubscribe_OnOff, Test_TC_OO_1_1, Test_TC_OO_2_1, Test_TC_OO_2_2, Test_TC_DM_1_1, Test_TC_DM_3_1, Test_TC_CC_3_4, Test_TC_CC_5, Test_TC_CC_6, Test_TC_CC_7, Test_TC_CC_8, Test_TC_WNCV_1_1, Test_TC_WNCV_2_1, Test_TC_BI_1_1, Test_TC_FLW_1_1, Test_TC_TM_1_1, Test_TC_OCC_1_1, OperationalCredentialsCluster"}} +{{>test_cluster tests="TV_TargetNavigatorCluster, TV_AudioOutputCluster, TV_ApplicationLauncherCluster, TV_KeypadInputCluster, TV_AccountLoginCluster, TV_WakeOnLanCluster, TV_ApplicationBasicCluster, TV_MediaPlaybackCluster, TV_TvChannelCluster, TV_LowPowerCluster, TV_MediaInputCluster, TestCluster, TestConstraints, TestDelayCommands, TestSubscribe_OnOff, Test_TC_OO_1_1, Test_TC_OO_2_1, Test_TC_OO_2_2, Test_TC_DM_1_1, Test_TC_DM_3_1, Test_TC_CC_3_4, Test_TC_CC_5, Test_TC_CC_6, Test_TC_CC_7, Test_TC_CC_8, Test_TC_WNCV_1_1, Test_TC_WNCV_2_1, Test_TC_BI_1_1, Test_TC_FLW_1_1, Test_TC_TM_1_1, Test_TC_OCC_1_1, TestOperationalCredentialsCluster"}} diff --git a/src/app/tests/suites/OperationalCredentialsCluster.yaml b/src/app/tests/suites/TestOperationalCredentialsCluster.yaml similarity index 100% rename from src/app/tests/suites/OperationalCredentialsCluster.yaml rename to src/app/tests/suites/TestOperationalCredentialsCluster.yaml diff --git a/src/darwin/Framework/CHIP/templates/clusters-tests.zapt b/src/darwin/Framework/CHIP/templates/clusters-tests.zapt index 8281b816da0379..0fd3140ebc1f68 100644 --- a/src/darwin/Framework/CHIP/templates/clusters-tests.zapt +++ b/src/darwin/Framework/CHIP/templates/clusters-tests.zapt @@ -142,7 +142,7 @@ CHIPDevice * GetPairedDevice(uint64_t deviceId) [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; } -{{>test_cluster tests="TestCluster, TestConstraints, TestDelayCommands, TestSubscribe_OnOff, Test_TC_OO_1_1, Test_TC_OO_2_1, Test_TC_OO_2_2, Test_TC_DM_1_1, Test_TC_DM_3_1, Test_TC_CC_3_4, Test_TC_CC_5, Test_TC_CC_6, Test_TC_CC_7, Test_TC_CC_8, Test_TC_WNCV_1_1, Test_TC_WNCV_2_1, Test_TC_BI_1_1, Test_TC_FLW_1_1, Test_TC_TM_1_1, Test_TC_OCC_1_1, OperationalCredentialsCluster"}} +{{>test_cluster tests="TestCluster, TestConstraints, TestDelayCommands, TestSubscribe_OnOff, Test_TC_OO_1_1, Test_TC_OO_2_1, Test_TC_OO_2_2, Test_TC_DM_1_1, Test_TC_DM_3_1, Test_TC_CC_3_4, Test_TC_CC_5, Test_TC_CC_6, Test_TC_CC_7, Test_TC_CC_8, Test_TC_WNCV_1_1, Test_TC_WNCV_2_1, Test_TC_BI_1_1, Test_TC_FLW_1_1, Test_TC_TM_1_1, Test_TC_OCC_1_1, TestOperationalCredentialsCluster"}} {{#chip_client_clusters}} {{#unless (isStrEqual "Test Cluster" name)}} diff --git a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m index c894e573096b3d..f23ac1db223289 100644 --- a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m +++ b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m @@ -5217,7 +5217,7 @@ - (void)testSendClusterTest_TC_OCC_1_1_000001_ReadAttribute [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; } -- (void)testSendClusterOperationalCredentialsCluster_000000_ReadAttribute +- (void)testSendClusterTestOperationalCredentialsCluster_000000_ReadAttribute { XCTestExpectation * expectation = [self expectationWithDescription:@"Read number of supported fabrics"]; CHIPDevice * device = GetPairedDevice(kDeviceId); @@ -5235,7 +5235,7 @@ - (void)testSendClusterOperationalCredentialsCluster_000000_ReadAttribute [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; } -- (void)testSendClusterOperationalCredentialsCluster_000001_ReadAttribute +- (void)testSendClusterTestOperationalCredentialsCluster_000001_ReadAttribute { XCTestExpectation * expectation = [self expectationWithDescription:@"Read number of commissioned fabrics"]; CHIPDevice * device = GetPairedDevice(kDeviceId); diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index 616105d61766f7..53d217738a0ccf 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -20325,10 +20325,10 @@ class Test_TC_OCC_1_1 : public TestCommand } }; -class OperationalCredentialsCluster : public TestCommand +class TestOperationalCredentialsCluster : public TestCommand { public: - OperationalCredentialsCluster() : TestCommand("OperationalCredentialsCluster"), mTestIndex(0) {} + TestOperationalCredentialsCluster() : TestCommand("TestOperationalCredentialsCluster"), mTestIndex(0) {} /////////// TestCommand Interface ///////// void NextTest() override @@ -20337,7 +20337,7 @@ class OperationalCredentialsCluster : public TestCommand if (mTestCount == mTestIndex) { - ChipLogProgress(chipTool, "OperationalCredentialsCluster: Test complete"); + ChipLogProgress(chipTool, "TestOperationalCredentialsCluster: Test complete"); SetCommandExitStatus(CHIP_NO_ERROR); } @@ -20357,7 +20357,7 @@ class OperationalCredentialsCluster : public TestCommand if (CHIP_NO_ERROR != err) { - ChipLogProgress(chipTool, "OperationalCredentialsCluster: %s", chip::ErrorStr(err)); + ChipLogProgress(chipTool, "TestOperationalCredentialsCluster: %s", chip::ErrorStr(err)); SetCommandExitStatus(err); } } @@ -20399,7 +20399,7 @@ class OperationalCredentialsCluster : public TestCommand { ChipLogProgress(chipTool, "Operational Credentials - Read number of supported fabrics: Failure Response"); - OperationalCredentialsCluster * runner = reinterpret_cast(context); + TestOperationalCredentialsCluster * runner = reinterpret_cast(context); if (runner->mIsFailureExpected_0 == false) { @@ -20416,7 +20416,7 @@ class OperationalCredentialsCluster : public TestCommand { ChipLogProgress(chipTool, "Operational Credentials - Read number of supported fabrics: Success Response"); - OperationalCredentialsCluster * runner = reinterpret_cast(context); + TestOperationalCredentialsCluster * runner = reinterpret_cast(context); if (runner->mIsFailureExpected_0 == true) { @@ -20466,7 +20466,7 @@ class OperationalCredentialsCluster : public TestCommand { ChipLogProgress(chipTool, "Operational Credentials - Read number of commissioned fabrics: Failure Response"); - OperationalCredentialsCluster * runner = reinterpret_cast(context); + TestOperationalCredentialsCluster * runner = reinterpret_cast(context); if (runner->mIsFailureExpected_1 == false) { @@ -20483,7 +20483,7 @@ class OperationalCredentialsCluster : public TestCommand { ChipLogProgress(chipTool, "Operational Credentials - Read number of commissioned fabrics: Success Response"); - OperationalCredentialsCluster * runner = reinterpret_cast(context); + TestOperationalCredentialsCluster * runner = reinterpret_cast(context); if (runner->mIsFailureExpected_1 == true) { @@ -20542,7 +20542,7 @@ void registerCommandsTests(Commands & commands) make_unique(), make_unique(), make_unique(), - make_unique(), + make_unique(), }; commands.Register(clusterName, clusterCommands); From aff443354a55fdcfa6bba217b09d11ced1d8e984 Mon Sep 17 00:00:00 2001 From: Evgeny Margolis Date: Tue, 14 Sep 2021 16:14:47 -0700 Subject: [PATCH 046/255] Eliminate Use of Certificate Arrays. (#9616) -- Removed all methods that process Cert Arrays from CHIPCert. -- Updated AddNOC and UpdateNOC commands in the Operational Credentials Cluster. -- Refactored CASE Code: -- Use separate NOC and ICAC structures -- Factored out code that signs TBS data: ConstructTBSData() -- Refactored FabricTable code: -- Use ByteSpans to store Root, ICAC, and NOC certs -- Removed mRootPubkey and mRootKeyId members. Using ExtractPublicKeyFromChipCert() and ExtractSKIDFromChipCert() to extract those values from mRootCert when needed. --- .../operational-credentials-server.cpp | 22 +- .../chip/operational-credentials-cluster.xml | 6 +- src/controller/CHIPDevice.cpp | 15 +- src/controller/CHIPDevice.h | 22 +- src/controller/CHIPDeviceController.cpp | 41 +- src/controller/CHIPDeviceController.h | 4 +- .../java/zap-generated/CHIPClusters-JNI.cpp | 18 +- .../chip/devicecontroller/ChipClusters.java | 14 +- .../python/chip/clusters/CHIPClusters.cpp | 23 +- .../python/chip/clusters/CHIPClusters.py | 18 +- src/credentials/CHIPCert.cpp | 104 ++---- src/credentials/CHIPCert.h | 84 +---- src/credentials/CHIPCertFromX509.cpp | 103 ------ src/credentials/CHIPCertToX509.cpp | 4 +- src/credentials/tests/TestChipCert.cpp | 350 ++++-------------- .../CHIP/zap-generated/CHIPClustersObjc.h | 5 +- .../CHIP/zap-generated/CHIPClustersObjc.mm | 11 +- src/protocols/secure_channel/CASESession.cpp | 221 +++++------ src/protocols/secure_channel/CASESession.h | 7 +- .../secure_channel/tests/TestCASESession.cpp | 15 +- src/transport/FabricTable.cpp | 162 +++----- src/transport/FabricTable.h | 90 ++--- src/transport/tests/TestFabricTable.cpp | 2 +- .../zap-generated/IMClusterCommandHandler.cpp | 42 ++- .../app-common/zap-generated/callback.h | 4 +- .../zap-generated/client-command-macro.h | 15 +- .../zap-generated/IMClusterCommandHandler.cpp | 42 ++- .../zap-generated/cluster/Commands.h | 18 +- .../zap-generated/CHIPClusters.cpp | 19 +- .../zap-generated/CHIPClusters.h | 6 +- .../zap-generated/IMClusterCommandHandler.cpp | 42 ++- .../zap-generated/IMClusterCommandHandler.cpp | 42 ++- .../zap-generated/IMClusterCommandHandler.cpp | 24 +- .../zap-generated/IMClusterCommandHandler.cpp | 42 ++- .../zap-generated/IMClusterCommandHandler.cpp | 42 ++- .../zap-generated/IMClusterCommandHandler.cpp | 42 ++- .../zap-generated/IMClusterCommandHandler.cpp | 42 ++- .../tv-app/zap-generated/CHIPClusters.cpp | 10 +- .../tv-app/zap-generated/CHIPClusters.h | 4 +- .../zap-generated/IMClusterCommandHandler.cpp | 42 ++- .../zap-generated/IMClusterCommandHandler.cpp | 42 ++- .../zap-generated/IMClusterCommandHandler.cpp | 42 ++- 42 files changed, 788 insertions(+), 1115 deletions(-) diff --git a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp index a638e085bbf573..899927a32ebb1c 100644 --- a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp +++ b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp @@ -86,7 +86,7 @@ EmberAfStatus writeFabricAttribute(uint8_t * buffer, int32_t index = -1) } EmberAfStatus writeFabric(FabricIndex fabricIndex, FabricId fabricId, NodeId nodeId, uint16_t vendorId, const uint8_t * fabricLabel, - const Crypto::P256PublicKey & rootPubkey, uint8_t index) + Credentials::P256PublicKeySpan rootPubkey, uint8_t index) { EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS; @@ -94,7 +94,7 @@ EmberAfStatus writeFabric(FabricIndex fabricIndex, FabricId fabricId, NodeId nod VerifyOrReturnError(fabricDescriptor != nullptr, EMBER_ZCL_STATUS_FAILURE); fabricDescriptor->FabricIndex = fabricIndex; - fabricDescriptor->RootPublicKey = ByteSpan(rootPubkey.ConstBytes(), rootPubkey.Length()); + fabricDescriptor->RootPublicKey = ByteSpan(rootPubkey.data(), rootPubkey.size()); fabricDescriptor->VendorId = vendorId; fabricDescriptor->FabricId = fabricId; @@ -384,8 +384,9 @@ bool emberAfOperationalCredentialsClusterRemoveAllFabricsCallback(EndpointId end return true; } -bool emberAfOperationalCredentialsClusterAddNOCCallback(EndpointId endpoint, app::CommandHandler * commandObj, ByteSpan NOCArray, - ByteSpan IPKValue, NodeId adminNodeId, uint16_t adminVendorId) +bool emberAfOperationalCredentialsClusterAddNOCCallback(EndpointId endpoint, app::CommandHandler * commandObj, ByteSpan NOCValue, + ByteSpan ICACValue, ByteSpan IPKValue, NodeId adminNodeId, + uint16_t adminVendorId) { EmberAfNodeOperationalCertStatus nocResponse = EMBER_ZCL_NODE_OPERATIONAL_CERT_STATUS_SUCCESS; @@ -394,7 +395,10 @@ bool emberAfOperationalCredentialsClusterAddNOCCallback(EndpointId endpoint, app emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: commissioner has added an Op Cert"); - err = gFabricBeingCommissioned.SetOperationalCertsFromCertArray(NOCArray); + err = gFabricBeingCommissioned.SetNOCCert(NOCValue); + VerifyOrExit(err == CHIP_NO_ERROR, nocResponse = ConvertToNOCResponseStatus(err)); + + err = gFabricBeingCommissioned.SetICACert(ICACValue); VerifyOrExit(err == CHIP_NO_ERROR, nocResponse = ConvertToNOCResponseStatus(err)); gFabricBeingCommissioned.SetVendorId(adminVendorId); @@ -421,7 +425,8 @@ bool emberAfOperationalCredentialsClusterAddNOCCallback(EndpointId endpoint, app return true; } -bool emberAfOperationalCredentialsClusterUpdateNOCCallback(EndpointId endpoint, app::CommandHandler * commandObj, ByteSpan NOCArray) +bool emberAfOperationalCredentialsClusterUpdateNOCCallback(EndpointId endpoint, app::CommandHandler * commandObj, ByteSpan NOCValue, + ByteSpan ICACValue) { EmberAfNodeOperationalCertStatus nocResponse = EMBER_ZCL_NODE_OPERATIONAL_CERT_STATUS_SUCCESS; @@ -434,7 +439,10 @@ bool emberAfOperationalCredentialsClusterUpdateNOCCallback(EndpointId endpoint, FabricInfo * fabric = retrieveCurrentFabric(); VerifyOrExit(fabric != nullptr, nocResponse = ConvertToNOCResponseStatus(CHIP_ERROR_INVALID_FABRIC_ID)); - err = fabric->SetOperationalCertsFromCertArray(NOCArray); + err = fabric->SetNOCCert(NOCValue); + VerifyOrExit(err == CHIP_NO_ERROR, nocResponse = ConvertToNOCResponseStatus(err)); + + err = fabric->SetICACert(ICACValue); VerifyOrExit(err == CHIP_NO_ERROR, nocResponse = ConvertToNOCResponseStatus(err)); fabricIndex = fabric->GetFabricIndex(); diff --git a/src/app/zap-templates/zcl/data-model/chip/operational-credentials-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/operational-credentials-cluster.xml index 592a5ca466b8c6..56829de26132a2 100644 --- a/src/app/zap-templates/zcl/data-model/chip/operational-credentials-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/operational-credentials-cluster.xml @@ -71,7 +71,8 @@ limitations under the License. Sender is requesting to add the new node operational certificates. - + + @@ -79,7 +80,8 @@ limitations under the License. Sender is requesting to update the node operational certificates. - + + diff --git a/src/controller/CHIPDevice.cpp b/src/controller/CHIPDevice.cpp index 94b6e799c03ce5..270e16b2b9fa55 100644 --- a/src/controller/CHIPDevice.cpp +++ b/src/controller/CHIPDevice.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020-2021 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -796,10 +796,17 @@ Device::~Device() } } -CHIP_ERROR Device::ReduceNOCChainBufferSize(size_t new_size) +CHIP_ERROR Device::SetNOCCertBufferSize(size_t new_size) { - ReturnErrorCodeIf(new_size > sizeof(mNOCChainBuffer), CHIP_ERROR_INVALID_ARGUMENT); - mNOCChainBufferSize = new_size; + ReturnErrorCodeIf(new_size > sizeof(mNOCCertBuffer), CHIP_ERROR_INVALID_ARGUMENT); + mNOCCertBufferSize = new_size; + return CHIP_NO_ERROR; +} + +CHIP_ERROR Device::SetICACertBufferSize(size_t new_size) +{ + ReturnErrorCodeIf(new_size > sizeof(mICACertBuffer), CHIP_ERROR_INVALID_ARGUMENT); + mICACertBufferSize = new_size; return CHIP_NO_ERROR; } diff --git a/src/controller/CHIPDevice.h b/src/controller/CHIPDevice.h index 73c7cbb54e2bb5..220a24d20b938b 100644 --- a/src/controller/CHIPDevice.h +++ b/src/controller/CHIPDevice.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020-2021 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -419,11 +419,17 @@ class DLL_EXPORT Device : public Messaging::ExchangeDelegate, public SessionEsta ByteSpan GetCSRNonce() const { return ByteSpan(mCSRNonce, sizeof(mCSRNonce)); } - MutableByteSpan GetMutableNOCChain() { return MutableByteSpan(mNOCChainBuffer, sizeof(mNOCChainBuffer)); } + MutableByteSpan GetMutableNOCCert() { return MutableByteSpan(mNOCCertBuffer, sizeof(mNOCCertBuffer)); } - CHIP_ERROR ReduceNOCChainBufferSize(size_t new_size); + CHIP_ERROR SetNOCCertBufferSize(size_t new_size); - ByteSpan GetNOCChain() const { return ByteSpan(mNOCChainBuffer, mNOCChainBufferSize); } + ByteSpan GetNOCCert() const { return ByteSpan(mNOCCertBuffer, mNOCCertBufferSize); } + + MutableByteSpan GetMutableICACert() { return MutableByteSpan(mICACertBuffer, sizeof(mICACertBuffer)); } + + CHIP_ERROR SetICACertBufferSize(size_t new_size); + + ByteSpan GetICACert() const { return ByteSpan(mICACertBuffer, mICACertBufferSize); } /* * This function can be called to establish a secure session with the device. @@ -535,9 +541,11 @@ class DLL_EXPORT Device : public Messaging::ExchangeDelegate, public SessionEsta uint8_t mCSRNonce[kOpCSRNonceLength]; - // The chain can contain ICAC and OpCert - uint8_t mNOCChainBuffer[Credentials::kMaxCHIPCertLength * 2]; - size_t mNOCChainBufferSize = 0; + uint8_t mNOCCertBuffer[Credentials::kMaxCHIPCertLength]; + size_t mNOCCertBufferSize = 0; + + uint8_t mICACertBuffer[Credentials::kMaxCHIPCertLength]; + size_t mICACertBufferSize = 0; SessionIDAllocator * mIDAllocator = nullptr; diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 7186c53e4f87f3..25f8a2102d30c8 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -215,7 +215,7 @@ CHIP_ERROR DeviceController::ProcessControllerNOCChain(const ControllerInitParam ReturnErrorCodeIf(params.ephemeralKeypair == nullptr, CHIP_ERROR_INVALID_ARGUMENT); newFabric.SetEphemeralKey(params.ephemeralKeypair); - constexpr uint32_t chipCertAllocatedLen = kMaxCHIPCertLength * 2; + constexpr uint32_t chipCertAllocatedLen = kMaxCHIPCertLength; chip::Platform::ScopedMemoryBuffer chipCert; ReturnErrorCodeIf(!chipCert.Alloc(chipCertAllocatedLen), CHIP_ERROR_NO_MEMORY); @@ -228,11 +228,18 @@ CHIP_ERROR DeviceController::ProcessControllerNOCChain(const ControllerInitParam { ChipLogProgress(Controller, "Intermediate CA is not needed"); } + else + { + chipCertSpan = MutableByteSpan(chipCert.Get(), chipCertAllocatedLen); + + ReturnErrorOnFailure(ConvertX509CertToChipCert(params.controllerICAC, chipCertSpan)); + ReturnErrorOnFailure(newFabric.SetICACert(chipCertSpan)); + } chipCertSpan = MutableByteSpan(chipCert.Get(), chipCertAllocatedLen); - ReturnErrorOnFailure(ConvertX509CertsToChipCertArray(params.controllerNOC, params.controllerICAC, chipCertSpan)); - ReturnErrorOnFailure(newFabric.SetOperationalCertsFromCertArray(chipCertSpan)); + ReturnErrorOnFailure(ConvertX509CertToChipCert(params.controllerNOC, chipCertSpan)); + ReturnErrorOnFailure(newFabric.SetNOCCert(chipCertSpan)); newFabric.SetVendorId(params.controllerVendorId); Transport::FabricInfo * fabric = mFabrics.FindFabricWithIndex(mFabricIndex); @@ -1263,7 +1270,8 @@ void DeviceCommissioner::OnDeviceNOCChainGeneration(void * context, CHIP_ERROR s device = &commissioner->mActiveDevices[commissioner->mDeviceBeingPaired]; { - MutableByteSpan rootCert = device->GetMutableNOCChain(); + // Reuse NOC Cert buffer for temporary store Root Cert. + MutableByteSpan rootCert = device->GetMutableNOCCert(); err = ConvertX509CertToChipCert(rcac, rootCert); SuccessOrExit(err); @@ -1272,13 +1280,24 @@ void DeviceCommissioner::OnDeviceNOCChainGeneration(void * context, CHIP_ERROR s SuccessOrExit(err); } + if (!icac.empty()) + { + MutableByteSpan icaCert = device->GetMutableICACert(); + + err = ConvertX509CertToChipCert(icac, icaCert); + SuccessOrExit(err); + + err = device->SetICACertBufferSize(icaCert.size()); + SuccessOrExit(err); + } + { - MutableByteSpan certChain = device->GetMutableNOCChain(); + MutableByteSpan nocCert = device->GetMutableNOCCert(); - err = ConvertX509CertsToChipCertArray(noc, icac, certChain); + err = ConvertX509CertToChipCert(noc, nocCert); SuccessOrExit(err); - err = device->ReduceNOCChainBufferSize(certChain.size()); + err = device->SetNOCCertBufferSize(nocCert.size()); SuccessOrExit(err); } @@ -1306,7 +1325,7 @@ CHIP_ERROR DeviceCommissioner::ProcessOpCSR(const ByteSpan & NOCSRElements, cons ByteSpan(), &mDeviceNOCChainCallback); } -CHIP_ERROR DeviceCommissioner::SendOperationalCertificate(Device * device, const ByteSpan & opCertBuf) +CHIP_ERROR DeviceCommissioner::SendOperationalCertificate(Device * device, const ByteSpan & nocCertBuf, const ByteSpan & icaCertBuf) { VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT); chip::Controller::OperationalCredentialsCluster cluster; @@ -1315,8 +1334,8 @@ CHIP_ERROR DeviceCommissioner::SendOperationalCertificate(Device * device, const Callback::Cancelable * successCallback = mNOCResponseCallback.Cancel(); Callback::Cancelable * failureCallback = mOnCertFailureCallback.Cancel(); - ReturnErrorOnFailure( - cluster.AddNOC(successCallback, failureCallback, opCertBuf, ByteSpan(nullptr, 0), mLocalId.GetNodeId(), mVendorId)); + ReturnErrorOnFailure(cluster.AddNOC(successCallback, failureCallback, nocCertBuf, icaCertBuf, ByteSpan(nullptr, 0), + mLocalId.GetNodeId(), mVendorId)); ChipLogProgress(Controller, "Sent operational certificate to the device"); @@ -1428,7 +1447,7 @@ void DeviceCommissioner::OnRootCertSuccessResponse(void * context) device = &commissioner->mActiveDevices[commissioner->mDeviceBeingPaired]; ChipLogProgress(Controller, "Sending operational certificate chain to the device"); - err = commissioner->SendOperationalCertificate(device, device->GetNOCChain()); + err = commissioner->SendOperationalCertificate(device, device->GetNOCCert(), device->GetICACert()); SuccessOrExit(err); exit: diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 79a2966e09a4a4..a549a01d758844 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020-2021 Project CHIP Authors * Copyright (c) 2013-2017 Nest Labs, Inc. * All rights reserved. * @@ -632,7 +632,7 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, /* This function sends the operational credentials to the device. The function does not hold a refernce to the device object. */ - CHIP_ERROR SendOperationalCertificate(Device * device, const ByteSpan & opCertBuf); + CHIP_ERROR SendOperationalCertificate(Device * device, const ByteSpan & nocCertBuf, const ByteSpan & icaCertBuf); /* This function sends the trusted root certificate to the device. The function does not hold a refernce to the device object. */ diff --git a/src/controller/java/zap-generated/CHIPClusters-JNI.cpp b/src/controller/java/zap-generated/CHIPClusters-JNI.cpp index 6ff99e833b24f8..0f49163c27a565 100644 --- a/src/controller/java/zap-generated/CHIPClusters-JNI.cpp +++ b/src/controller/java/zap-generated/CHIPClusters-JNI.cpp @@ -21624,14 +21624,15 @@ JNI_METHOD(jlong, OperationalCredentialsCluster, initWithDevice)(JNIEnv * env, j } JNI_METHOD(void, OperationalCredentialsCluster, addNOC) -(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jbyteArray nOCArray, jbyteArray iPKValue, jlong caseAdminNode, - jint adminVendorId) +(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jbyteArray nOCValue, jbyteArray iCACValue, jbyteArray iPKValue, + jlong caseAdminNode, jint adminVendorId) { StackLockGuard lock(JniReferences::GetInstance().GetStackLock()); CHIP_ERROR err = CHIP_NO_ERROR; OperationalCredentialsCluster * cppCluster; - JniByteArray nOCArrayArr(env, nOCArray); + JniByteArray nOCValueArr(env, nOCValue); + JniByteArray iCACValueArr(env, iCACValue); JniByteArray iPKValueArr(env, iPKValue); CHIPOperationalCredentialsClusterNOCResponseCallback * onSuccess; CHIPDefaultFailureCallback * onFailure; @@ -21645,7 +21646,8 @@ JNI_METHOD(void, OperationalCredentialsCluster, addNOC) VerifyOrExit(onFailure != nullptr, err = CHIP_ERROR_INCORRECT_STATE); err = cppCluster->AddNOC( - onSuccess->Cancel(), onFailure->Cancel(), chip::ByteSpan((const uint8_t *) nOCArrayArr.data(), nOCArrayArr.size()), + onSuccess->Cancel(), onFailure->Cancel(), chip::ByteSpan((const uint8_t *) nOCValueArr.data(), nOCValueArr.size()), + chip::ByteSpan((const uint8_t *) iCACValueArr.data(), iCACValueArr.size()), chip::ByteSpan((const uint8_t *) iPKValueArr.data(), iPKValueArr.size()), caseAdminNode, adminVendorId); SuccessOrExit(err); @@ -21915,13 +21917,14 @@ JNI_METHOD(void, OperationalCredentialsCluster, updateFabricLabel) } } JNI_METHOD(void, OperationalCredentialsCluster, updateNOC) -(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jbyteArray nOCArray) +(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jbyteArray nOCValue, jbyteArray iCACValue) { StackLockGuard lock(JniReferences::GetInstance().GetStackLock()); CHIP_ERROR err = CHIP_NO_ERROR; OperationalCredentialsCluster * cppCluster; - JniByteArray nOCArrayArr(env, nOCArray); + JniByteArray nOCValueArr(env, nOCValue); + JniByteArray iCACValueArr(env, iCACValue); CHIPOperationalCredentialsClusterNOCResponseCallback * onSuccess; CHIPDefaultFailureCallback * onFailure; @@ -21934,7 +21937,8 @@ JNI_METHOD(void, OperationalCredentialsCluster, updateNOC) VerifyOrExit(onFailure != nullptr, err = CHIP_ERROR_INCORRECT_STATE); err = cppCluster->UpdateNOC(onSuccess->Cancel(), onFailure->Cancel(), - chip::ByteSpan((const uint8_t *) nOCArrayArr.data(), nOCArrayArr.size())); + chip::ByteSpan((const uint8_t *) nOCValueArr.data(), nOCValueArr.size()), + chip::ByteSpan((const uint8_t *) iCACValueArr.data(), iCACValueArr.size())); SuccessOrExit(err); exit: diff --git a/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java b/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java index 68419bbfa66b5d..035cae7d460e7a 100644 --- a/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java @@ -3892,11 +3892,12 @@ public OperationalCredentialsCluster(long devicePtr, int endpointId) { public void addNOC( NOCResponseCallback callback, - byte[] nOCArray, + byte[] nOCValue, + byte[] iCACValue, byte[] iPKValue, long caseAdminNode, int adminVendorId) { - addNOC(chipClusterPtr, callback, nOCArray, iPKValue, caseAdminNode, adminVendorId); + addNOC(chipClusterPtr, callback, nOCValue, iCACValue, iPKValue, caseAdminNode, adminVendorId); } public void addTrustedRootCertificate(DefaultClusterCallback callback, byte[] rootCertificate) { @@ -3920,14 +3921,15 @@ public void updateFabricLabel(NOCResponseCallback callback, String label) { updateFabricLabel(chipClusterPtr, callback, label); } - public void updateNOC(NOCResponseCallback callback, byte[] nOCArray) { - updateNOC(chipClusterPtr, callback, nOCArray); + public void updateNOC(NOCResponseCallback callback, byte[] nOCValue, byte[] iCACValue) { + updateNOC(chipClusterPtr, callback, nOCValue, iCACValue); } private native void addNOC( long chipClusterPtr, NOCResponseCallback callback, - byte[] nOCArray, + byte[] nOCValue, + byte[] iCACValue, byte[] iPKValue, long caseAdminNode, int adminVendorId); @@ -3948,7 +3950,7 @@ private native void updateFabricLabel( long chipClusterPtr, NOCResponseCallback callback, String label); private native void updateNOC( - long chipClusterPtr, NOCResponseCallback callback, byte[] nOCArray); + long chipClusterPtr, NOCResponseCallback callback, byte[] nOCValue, byte[] iCACValue); public interface NOCResponseCallback { void onSuccess(int StatusCode, int FabricIndex, byte[] DebugText); diff --git a/src/controller/python/chip/clusters/CHIPClusters.cpp b/src/controller/python/chip/clusters/CHIPClusters.cpp index 5ebcee90bfa4b4..a83a82f388d81b 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.cpp +++ b/src/controller/python/chip/clusters/CHIPClusters.cpp @@ -3936,16 +3936,18 @@ chip::ChipError::StorageType chip_ime_ReadAttribute_OnOffSwitchConfiguration_Clu // End of Cluster OnOffSwitchConfiguration // Cluster OperationalCredentials -chip::ChipError::StorageType chip_ime_AppendCommand_OperationalCredentials_AddNOC( - chip::Controller::Device * device, chip::EndpointId ZCLendpointId, chip::GroupId, const uint8_t * nOCArray, - uint32_t nOCArray_Len, const uint8_t * iPKValue, uint32_t iPKValue_Len, chip::NodeId caseAdminNode, uint16_t adminVendorId) +chip::ChipError::StorageType +chip_ime_AppendCommand_OperationalCredentials_AddNOC(chip::Controller::Device * device, chip::EndpointId ZCLendpointId, + chip::GroupId, const uint8_t * nOCValue, uint32_t nOCValue_Len, + const uint8_t * iCACValue, uint32_t iCACValue_Len, const uint8_t * iPKValue, + uint32_t iPKValue_Len, chip::NodeId caseAdminNode, uint16_t adminVendorId) { VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT.AsInteger()); chip::Controller::OperationalCredentialsCluster cluster; cluster.Associate(device, ZCLendpointId); return cluster - .AddNOC(nullptr, nullptr, chip::ByteSpan(nOCArray, nOCArray_Len), chip::ByteSpan(iPKValue, iPKValue_Len), caseAdminNode, - adminVendorId) + .AddNOC(nullptr, nullptr, chip::ByteSpan(nOCValue, nOCValue_Len), chip::ByteSpan(iCACValue, iCACValue_Len), + chip::ByteSpan(iPKValue, iPKValue_Len), caseAdminNode, adminVendorId) .AsInteger(); } chip::ChipError::StorageType chip_ime_AppendCommand_OperationalCredentials_AddTrustedRootCertificate( @@ -3996,15 +3998,16 @@ chip::ChipError::StorageType chip_ime_AppendCommand_OperationalCredentials_Updat cluster.Associate(device, ZCLendpointId); return cluster.UpdateFabricLabel(nullptr, nullptr, chip::ByteSpan(label, label_Len)).AsInteger(); } -chip::ChipError::StorageType chip_ime_AppendCommand_OperationalCredentials_UpdateNOC(chip::Controller::Device * device, - chip::EndpointId ZCLendpointId, chip::GroupId, - const uint8_t * nOCArray, - uint32_t nOCArray_Len) +chip::ChipError::StorageType +chip_ime_AppendCommand_OperationalCredentials_UpdateNOC(chip::Controller::Device * device, chip::EndpointId ZCLendpointId, + chip::GroupId, const uint8_t * nOCValue, uint32_t nOCValue_Len, + const uint8_t * iCACValue, uint32_t iCACValue_Len) { VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT.AsInteger()); chip::Controller::OperationalCredentialsCluster cluster; cluster.Associate(device, ZCLendpointId); - return cluster.UpdateNOC(nullptr, nullptr, chip::ByteSpan(nOCArray, nOCArray_Len)).AsInteger(); + return cluster.UpdateNOC(nullptr, nullptr, chip::ByteSpan(nOCValue, nOCValue_Len), chip::ByteSpan(iCACValue, iCACValue_Len)) + .AsInteger(); } chip::ChipError::StorageType chip_ime_ReadAttribute_OperationalCredentials_FabricsList(chip::Controller::Device * device, diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index c53b12368765e3..f63e206e3e3b6f 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -2262,7 +2262,8 @@ class ChipClusters: "commandId": 0x00000006, "commandName": "AddNOC", "args": { - "nOCArray": "bytes", + "nOCValue": "bytes", + "iCACValue": "bytes", "iPKValue": "bytes", "caseAdminNode": "int", "adminVendorId": "int", @@ -2307,7 +2308,8 @@ class ChipClusters: "commandId": 0x00000007, "commandName": "UpdateNOC", "args": { - "nOCArray": "bytes", + "nOCValue": "bytes", + "iCACValue": "bytes", }, }, }, @@ -4236,9 +4238,9 @@ def ClusterOnOff_CommandToggle(self, device: ctypes.c_void_p, ZCLendpoint: int, return self._chipLib.chip_ime_AppendCommand_OnOff_Toggle( device, ZCLendpoint, ZCLgroupid ) - def ClusterOperationalCredentials_CommandAddNOC(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int, nOCArray: bytes, iPKValue: bytes, caseAdminNode: int, adminVendorId: int): + def ClusterOperationalCredentials_CommandAddNOC(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int, nOCValue: bytes, iCACValue: bytes, iPKValue: bytes, caseAdminNode: int, adminVendorId: int): return self._chipLib.chip_ime_AppendCommand_OperationalCredentials_AddNOC( - device, ZCLendpoint, ZCLgroupid, nOCArray, len(nOCArray), iPKValue, len(iPKValue), caseAdminNode, adminVendorId + device, ZCLendpoint, ZCLgroupid, nOCValue, len(nOCValue), iCACValue, len(iCACValue), iPKValue, len(iPKValue), caseAdminNode, adminVendorId ) def ClusterOperationalCredentials_CommandAddTrustedRootCertificate(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int, rootCertificate: bytes): return self._chipLib.chip_ime_AppendCommand_OperationalCredentials_AddTrustedRootCertificate( @@ -4261,9 +4263,9 @@ def ClusterOperationalCredentials_CommandUpdateFabricLabel(self, device: ctypes. return self._chipLib.chip_ime_AppendCommand_OperationalCredentials_UpdateFabricLabel( device, ZCLendpoint, ZCLgroupid, label, len(label) ) - def ClusterOperationalCredentials_CommandUpdateNOC(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int, nOCArray: bytes): + def ClusterOperationalCredentials_CommandUpdateNOC(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int, nOCValue: bytes, iCACValue: bytes): return self._chipLib.chip_ime_AppendCommand_OperationalCredentials_UpdateNOC( - device, ZCLendpoint, ZCLgroupid, nOCArray, len(nOCArray) + device, ZCLendpoint, ZCLgroupid, nOCValue, len(nOCValue), iCACValue, len(iCACValue) ) def ClusterScenes_CommandAddScene(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int, groupId: int, sceneId: int, transitionTime: int, sceneName: bytes, clusterId: int, length: int, value: int): sceneName = sceneName.encode("utf-8") + b'\x00' @@ -6376,7 +6378,7 @@ def InitLib(self, chipLib): self._chipLib.chip_ime_ReadAttribute_OnOffSwitchConfiguration_ClusterRevision.restype = ctypes.c_uint32 # Cluster OperationalCredentials # Cluster OperationalCredentials Command AddNOC - self._chipLib.chip_ime_AppendCommand_OperationalCredentials_AddNOC.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16, ctypes.c_char_p, ctypes.c_uint32, ctypes.c_char_p, ctypes.c_uint32, ctypes.c_uint64, ctypes.c_uint16] + self._chipLib.chip_ime_AppendCommand_OperationalCredentials_AddNOC.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16, ctypes.c_char_p, ctypes.c_uint32, ctypes.c_char_p, ctypes.c_uint32, ctypes.c_char_p, ctypes.c_uint32, ctypes.c_uint64, ctypes.c_uint16] self._chipLib.chip_ime_AppendCommand_OperationalCredentials_AddNOC.restype = ctypes.c_uint32 # Cluster OperationalCredentials Command AddTrustedRootCertificate self._chipLib.chip_ime_AppendCommand_OperationalCredentials_AddTrustedRootCertificate.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16, ctypes.c_char_p, ctypes.c_uint32] @@ -6394,7 +6396,7 @@ def InitLib(self, chipLib): self._chipLib.chip_ime_AppendCommand_OperationalCredentials_UpdateFabricLabel.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16, ctypes.c_char_p, ctypes.c_uint32] self._chipLib.chip_ime_AppendCommand_OperationalCredentials_UpdateFabricLabel.restype = ctypes.c_uint32 # Cluster OperationalCredentials Command UpdateNOC - self._chipLib.chip_ime_AppendCommand_OperationalCredentials_UpdateNOC.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16, ctypes.c_char_p, ctypes.c_uint32] + self._chipLib.chip_ime_AppendCommand_OperationalCredentials_UpdateNOC.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16, ctypes.c_char_p, ctypes.c_uint32, ctypes.c_char_p, ctypes.c_uint32] self._chipLib.chip_ime_AppendCommand_OperationalCredentials_UpdateNOC.restype = ctypes.c_uint32 # Cluster OperationalCredentials ReadAttribute FabricsList self._chipLib.chip_ime_ReadAttribute_OperationalCredentials_FabricsList.argtypes = [ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16] diff --git a/src/credentials/CHIPCert.cpp b/src/credentials/CHIPCert.cpp index 344c60f0cbd9f3..589f7bbf469e6a 100644 --- a/src/credentials/CHIPCert.cpp +++ b/src/credentials/CHIPCert.cpp @@ -133,18 +133,10 @@ void ChipCertificateSet::Clear() CHIP_ERROR ChipCertificateSet::LoadCert(const ByteSpan chipCert, BitFlags decodeFlags) { TLVReader reader; - TLVType type; - uint64_t tag; reader.Init(chipCert); - ReturnErrorOnFailure(reader.Next()); - - type = reader.GetType(); - tag = reader.GetTag(); - - VerifyOrReturnError((type == kTLVType_Structure || type == kTLVType_Array) && (tag == AnonymousTag), - CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); + ReturnErrorOnFailure(reader.Next(kTLVType_Structure, AnonymousTag)); return LoadCert(reader, decodeFlags, chipCert); } @@ -233,73 +225,6 @@ CHIP_ERROR ChipCertificateSet::LoadCert(TLVReader & reader, BitFlags decodeFlags) -{ - TLVReader reader; - TLVType type; - uint64_t tag; - - reader.Init(chipCert); - - ReturnErrorOnFailure(reader.Next()); - - type = reader.GetType(); - tag = reader.GetTag(); - - VerifyOrReturnError((type == kTLVType_Structure || type == kTLVType_Array) && (tag == AnonymousTag), - CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); - - return LoadCerts(reader, decodeFlags); -} - -CHIP_ERROR ChipCertificateSet::LoadCerts(TLVReader & reader, BitFlags decodeFlags) -{ - CHIP_ERROR err; - uint8_t initialCertCount = mCertCount; - - // If positioned on a structure, we assume that structure is a single certificate. - if (reader.GetType() == kTLVType_Structure) - { - err = LoadCert(reader, decodeFlags); - SuccessOrExit(err); - } - - // Other we expect to be positioned on an Array that contains a sequence of - // zero or more certificates... - else - { - TLVType containerType; - - err = reader.EnterContainer(containerType); - SuccessOrExit(err); - - while ((err = reader.Next()) == CHIP_NO_ERROR) - { - VerifyOrExit(reader.GetTag() == AnonymousTag, err = CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); - - err = LoadCert(reader, decodeFlags); - SuccessOrExit(err); - } - err = reader.VerifyEndOfContainer(); - SuccessOrExit(err); - - err = reader.ExitContainer(containerType); - SuccessOrExit(err); - } - -exit: - if (err != CHIP_NO_ERROR) - { - for (uint8_t i = initialCertCount; i < mCertCount; i++) - { - mCerts[i].~ChipCertificateData(); - } - mCertCount = initialCertCount; - } - - return err; -} - CHIP_ERROR ChipCertificateSet::ReleaseLastCert() { ChipCertificateData * lastCert = (mCertCount > 0) ? &mCerts[mCertCount - 1] : nullptr; @@ -972,13 +897,30 @@ CHIP_ERROR ExtractNodeIdFabricIdFromOpCert(const ByteSpan & opcert, NodeId * nod return ExtractNodeIdFabricIdFromOpCert(certSet.GetCertSet()[0], nodeId, fabricId); } -CHIP_ERROR ExtractNodeIdFabricIdFromOpCertArray(const ByteSpan & opcertarray, NodeId * nodeId, FabricId * fabricId) +CHIP_ERROR ExtractPublicKeyFromChipCert(const ByteSpan & chipCert, P256PublicKeySpan & publicKey) { - ByteSpan noc; - ByteSpan icac; - ReturnErrorOnFailure(ExtractCertsFromCertArray(opcertarray, noc, icac)); + ChipCertificateSet certSet; + + ReturnErrorOnFailure(certSet.Init(1)); - return ExtractNodeIdFabricIdFromOpCert(noc, nodeId, fabricId); + ReturnErrorOnFailure(certSet.LoadCert(chipCert, BitFlags())); + + publicKey = certSet.GetLastCert()->mPublicKey; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR ExtractSKIDFromChipCert(const ByteSpan & chipCert, CertificateKeyId & skid) +{ + ChipCertificateSet certSet; + + ReturnErrorOnFailure(certSet.Init(1)); + + ReturnErrorOnFailure(certSet.LoadCert(chipCert, BitFlags())); + + skid = certSet.GetLastCert()->mSubjectKeyId; + + return CHIP_NO_ERROR; } } // namespace Credentials diff --git a/src/credentials/CHIPCert.h b/src/credentials/CHIPCert.h index c04dbdd39e6dc5..10da55961028db 100644 --- a/src/credentials/CHIPCert.h +++ b/src/credentials/CHIPCert.h @@ -51,9 +51,6 @@ static constexpr uint16_t kX509NoWellDefinedExpirationDateYear = 9999; static constexpr uint32_t kMaxCHIPCertLength = 400; static constexpr uint32_t kMaxDERCertLength = 600; -// The certificate array has additional overhead due to array encoding -static constexpr uint32_t kMaxCHIPOpCertArrayLength = (2 * kMaxCHIPCertLength + 32); - // The decode buffer is used to reconstruct TBS section of X.509 certificate, which doesn't include signature. static constexpr uint32_t kMaxCHIPCertDecodeBufLength = kMaxDERCertLength - Crypto::kMax_ECDSA_Signature_Length_Der; @@ -448,33 +445,6 @@ class DLL_EXPORT ChipCertificateSet **/ CHIP_ERROR LoadCert(chip::TLV::TLVReader & reader, BitFlags decodeFlags, ByteSpan chipCert = ByteSpan()); - /** - * @brief Load CHIP certificates into set. - * It is required that the CHIP certificates in the chipCerts buffer stays valid while - * the certificates data in the set is used. - * In case of an error the certificate set is left in the same state as prior to this call. - * - * @param chipCerts Buffer containing array of certificates or a single certificate encoded in CHIP TLV form. - * @param decodeFlags Certificate decoding option flags. - * - * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise - **/ - CHIP_ERROR LoadCerts(const ByteSpan chipCerts, BitFlags decodeFlags); - - /** - * @brief Load CHIP certificates into set. - * It is required that the CHIP certificates in the reader's underlying buffer stays valid while - * the certificates data in the set is used. - * In case of an error the certificate set is left in the same state as prior to this call. - * - * @param reader A TLVReader positioned at the CHIP certificates TLV array - * or TLV structure for a single certificate. - * @param decodeFlags Certificate decoding option flags. - * - * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise - **/ - CHIP_ERROR LoadCerts(chip::TLV::TLVReader & reader, BitFlags decodeFlags); - CHIP_ERROR ReleaseLastCert(); /** @@ -631,40 +601,6 @@ CHIP_ERROR DecodeChipDN(chip::TLV::TLVReader & reader, ChipDN & dn); **/ CHIP_ERROR ConvertX509CertToChipCert(const ByteSpan x509Cert, MutableByteSpan & chipCert); -/** - * @brief Convert standard X.509 certificates to CHIP certificate array. - * This function takes NOC, and ICA cert X.509 certificates and - * encodes into CHIP certificate array. - * - * NOC certificate must be provided. - * ICA certificate is optional. It can be omitted by providing a 0 length ByteSpan. - * - * The API enforces that the NOC is issued by ICA (if ICA is provided). - * - * @param x509NOC Node operational credentials certificate in X.509 DER encoding. - * @param x509ICAC Intermediate CA certificate in X.509 DER encoding. - * @param chipCertArray Buffer to store converted certificates in CHIP format. - * - * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise - **/ -CHIP_ERROR ConvertX509CertsToChipCertArray(const ByteSpan & x509NOC, const ByteSpan & x509ICAC, MutableByteSpan & chipCertArray); - -/** - * @brief Extract NOC and ICA Certificates from a CHIP certificate array. - * This function takes a CHIP certificate array and splits it into single - * NOC and ICA CHIP certificates. - * - * NOC certificate must be provided. - * ICA certificate is optional. It will be omitted (nullptr, 0) if the CHIP certificate array contains only one entry. - * - * @param[in] opCertArray Chip certificate array. - * @param[out] noc Node operational credentials certificate in CHIP format. - * @param[out] icac Intermediate CA certificate in CHIP format. - * - * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise - **/ -CHIP_ERROR ExtractCertsFromCertArray(const ByteSpan & opCertArray, ByteSpan & noc, ByteSpan & icac); - /** * @brief Convert CHIP certificate to the standard X.509 DER encoded certificate. * @@ -872,14 +808,22 @@ CHIP_ERROR ExtractNodeIdFabricIdFromOpCert(const ChipCertificateData & opcert, N CHIP_ERROR ExtractNodeIdFabricIdFromOpCert(const ByteSpan & opcert, NodeId * nodeId, FabricId * fabricId); /** - * Extract Node ID and Fabric ID from an operational certificate array in ByteSpan - * TLV-encoded form. This does not perform any sort of validation on the - * certificate structure other than parsing it. + * Extract Public Key from a chip certificate in ByteSpan TLV-encoded form. + * This does not perform any sort of validation on the certificate structure + * structure than parsing it. * - * Can return any error that can be returned from parsing the array or from the - * ChipCertificateData* version of ExtractNodeIdFabricIdFromOpCert. + * Can return any error that can be returned from parsing the cert. + */ +CHIP_ERROR ExtractPublicKeyFromChipCert(const ByteSpan & chipCert, P256PublicKeySpan & publicKey); + +/** + * Extract Subject Key Identifier from a chip certificate in ByteSpan TLV-encoded form. + * This does not perform any sort of validation on the certificate structure + * structure than parsing it. + * + * Can return any error that can be returned from parsing the cert. */ -CHIP_ERROR ExtractNodeIdFabricIdFromOpCertArray(const ByteSpan & opcertarray, NodeId * nodeId, FabricId * fabricId); +CHIP_ERROR ExtractSKIDFromChipCert(const ByteSpan & chipCert, CertificateKeyId & skid); } // namespace Credentials } // namespace chip diff --git a/src/credentials/CHIPCertFromX509.cpp b/src/credentials/CHIPCertFromX509.cpp index a0c9a74a58770b..ed81db065ca3e9 100644 --- a/src/credentials/CHIPCertFromX509.cpp +++ b/src/credentials/CHIPCertFromX509.cpp @@ -724,108 +724,5 @@ CHIP_ERROR ConvertX509CertToChipCert(const ByteSpan x509Cert, MutableByteSpan & return CHIP_NO_ERROR; } -CHIP_ERROR ConvertX509CertsToChipCertArray(const ByteSpan & x509NOC, const ByteSpan & x509ICAC, MutableByteSpan & chipCertArray) -{ - // NOC is mandatory - VerifyOrReturnError(!x509NOC.empty(), CHIP_ERROR_INVALID_ARGUMENT); - - TLVWriter writer; - - writer.Init(chipCertArray); - - TLVType outerContainer; - ReturnErrorOnFailure(writer.StartContainer(AnonymousTag, kTLVType_Array, outerContainer)); - - ASN1Reader reader; - reader.Init(x509NOC); - - uint64_t nocIssuer, nocSubject; - Optional nocFabric; - ReturnErrorOnFailure(ConvertCertificate(reader, writer, AnonymousTag, nocIssuer, nocSubject, nocFabric)); - VerifyOrReturnError(nocFabric.HasValue(), CHIP_ERROR_INVALID_ARGUMENT); - - // ICAC is optional - if (!x509ICAC.empty()) - { - VerifyOrReturnError(CanCastTo(x509ICAC.size()), CHIP_ERROR_INVALID_ARGUMENT); - reader.Init(x509ICAC.data(), static_cast(x509ICAC.size())); - uint64_t icaIssuer, icaSubject; - Optional icaFabric; - ReturnErrorOnFailure(ConvertCertificate(reader, writer, AnonymousTag, icaIssuer, icaSubject, icaFabric)); - VerifyOrReturnError(icaSubject == nocIssuer, CHIP_ERROR_INVALID_ARGUMENT); - if (icaFabric.HasValue()) - { - // Match ICA's fabric ID if the ICA certificate has provided it - VerifyOrReturnError(icaFabric == nocFabric, CHIP_ERROR_INVALID_ARGUMENT); - } - } - - ReturnErrorOnFailure(writer.EndContainer(outerContainer)); - ReturnErrorOnFailure(writer.Finalize()); - - // This error return is a bit weird... if we already overran our buffer, - // then fail??? - ReturnErrorCodeIf(writer.GetLengthWritten() > chipCertArray.size(), CHIP_ERROR_INTERNAL); - chipCertArray.reduce_size(writer.GetLengthWritten()); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR ExtractCertsFromCertArray(const ByteSpan & opCertArray, ByteSpan & noc, ByteSpan & icac) -{ - TLVType outerContainerType; - TLVReader reader; - reader.Init(opCertArray); - - if (reader.GetType() == kTLVType_NotSpecified) - { - ReturnErrorOnFailure(reader.Next()); - } - VerifyOrReturnError(reader.GetType() == kTLVType_Array, CHIP_ERROR_WRONG_TLV_TYPE); - ReturnErrorOnFailure(reader.EnterContainer(outerContainerType)); - - { - TLVType nocContainerType; - const uint8_t * nocBegin = reader.GetReadPoint(); - - if (reader.GetType() == kTLVType_NotSpecified) - { - ReturnErrorOnFailure(reader.Next()); - } - VerifyOrReturnError(reader.GetType() == kTLVType_Structure, CHIP_ERROR_WRONG_TLV_TYPE); - VerifyOrReturnError(reader.GetTag() == AnonymousTag, CHIP_ERROR_INVALID_TLV_TAG); - - ReturnErrorOnFailure(reader.EnterContainer(nocContainerType)); - ReturnErrorOnFailure(reader.ExitContainer(nocContainerType)); - noc = ByteSpan(nocBegin, static_cast(reader.GetReadPoint() - nocBegin)); - } - - { - TLVType icacContainerType; - const uint8_t * icacBegin = reader.GetReadPoint(); - - if (reader.GetType() == kTLVType_NotSpecified) - { - CHIP_ERROR err = reader.Next(); - if (err == CHIP_END_OF_TLV) - { - icac = ByteSpan(nullptr, 0); - return CHIP_NO_ERROR; - } - ReturnErrorOnFailure(err); - } - VerifyOrReturnError(reader.GetType() == kTLVType_Structure, CHIP_ERROR_WRONG_TLV_TYPE); - VerifyOrReturnError(reader.GetTag() == AnonymousTag, CHIP_ERROR_INVALID_TLV_TAG); - - ReturnErrorOnFailure(reader.EnterContainer(icacContainerType)); - ReturnErrorOnFailure(reader.ExitContainer(icacContainerType)); - icac = ByteSpan(icacBegin, static_cast(reader.GetReadPoint() - icacBegin)); - } - - ReturnErrorOnFailure(reader.ExitContainer(outerContainerType)); - - return CHIP_NO_ERROR; -} - } // namespace Credentials } // namespace chip diff --git a/src/credentials/CHIPCertToX509.cpp b/src/credentials/CHIPCertToX509.cpp index a16580d3a060c2..ee40b578084ab4 100644 --- a/src/credentials/CHIPCertToX509.cpp +++ b/src/credentials/CHIPCertToX509.cpp @@ -790,7 +790,6 @@ CHIP_ERROR DecodeConvertTBSCert(TLVReader & reader, ASN1Writer & writer, ChipCer static CHIP_ERROR DecodeConvertCert(TLVReader & reader, ASN1Writer & writer, ChipCertificateData & certData) { CHIP_ERROR err; - uint64_t tag; TLVType containerType; if (reader.GetType() == kTLVType_NotSpecified) @@ -799,8 +798,7 @@ static CHIP_ERROR DecodeConvertCert(TLVReader & reader, ASN1Writer & writer, Chi SuccessOrExit(err); } VerifyOrExit(reader.GetType() == kTLVType_Structure, err = CHIP_ERROR_WRONG_TLV_TYPE); - tag = reader.GetTag(); - VerifyOrExit(tag == AnonymousTag, err = CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); + VerifyOrExit(reader.GetTag() == AnonymousTag, err = CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); err = reader.EnterContainer(containerType); SuccessOrExit(err); diff --git a/src/credentials/tests/TestChipCert.cpp b/src/credentials/tests/TestChipCert.cpp index 77225820623197..ac4eb1514ff5e8 100644 --- a/src/credentials/tests/TestChipCert.cpp +++ b/src/credentials/tests/TestChipCert.cpp @@ -959,7 +959,7 @@ static void TestChipCert_VerifyGeneratedCerts(nlTestSuite * inSuite, void * inCo NL_TEST_ASSERT(inSuite, certSet.FindValidCert(subjectDN, subjectKeyId, validContext, &resultCert) == CHIP_NO_ERROR); } -static void TestChipCert_X509ToChipArray(nlTestSuite * inSuite, void * inContext) +static void TestChipCert_VerifyGeneratedCertsNoICA(nlTestSuite * inSuite, void * inContext) { // Generate a new keypair for cert signing P256Keypair keypair; @@ -971,273 +971,30 @@ static void TestChipCert_X509ToChipArray(nlTestSuite * inSuite, void * inContext MutableByteSpan root_cert_span(root_cert); NL_TEST_ASSERT(inSuite, NewRootX509Cert(root_params, keypair, root_cert_span) == CHIP_NO_ERROR); - static uint8_t ica_cert[kMaxDERCertLength]; - - X509CertRequestParams ica_params = { 1234, 0xabcdabcd, 631161876, 729942000, true, 0x8888, false, 0 }; - P256Keypair ica_keypair; - NL_TEST_ASSERT(inSuite, ica_keypair.Initialize() == CHIP_NO_ERROR); - - MutableByteSpan ica_cert_span(ica_cert); - NL_TEST_ASSERT(inSuite, NewICAX509Cert(ica_params, 0xaabbccdd, ica_keypair.Pubkey(), keypair, ica_cert_span) == CHIP_NO_ERROR); - - static uint8_t noc_cert[kMaxDERCertLength]; - - X509CertRequestParams noc_params = { 1234, 0xaabbccdd, 631161876, 729942000, true, 0x8888, true, 0x1234 }; - P256Keypair noc_keypair; - NL_TEST_ASSERT(inSuite, noc_keypair.Initialize() == CHIP_NO_ERROR); - - MutableByteSpan noc_cert_span(noc_cert); - NL_TEST_ASSERT(inSuite, - NewNodeOperationalX509Cert(noc_params, kIssuerIsIntermediateCA, noc_keypair.Pubkey(), ica_keypair, - noc_cert_span) == CHIP_NO_ERROR); - - static uint8_t chipCertArrayBuf[kMaxCHIPCertLength * 2]; - static uint8_t chipRootCertBuf[kMaxCHIPCertLength]; - MutableByteSpan chipCertArray(chipCertArrayBuf); - MutableByteSpan chipRootCert(chipRootCertBuf); - - NL_TEST_ASSERT(inSuite, ConvertX509CertsToChipCertArray(noc_cert_span, ica_cert_span, chipCertArray) == CHIP_NO_ERROR); - - ChipCertificateSet certSet; - NL_TEST_ASSERT(inSuite, certSet.Init(3) == CHIP_NO_ERROR); - - NL_TEST_ASSERT(inSuite, certSet.LoadCerts(chipCertArray, sGenTBSHashFlag) == CHIP_NO_ERROR); - - NL_TEST_ASSERT(inSuite, ConvertX509CertToChipCert(root_cert_span, chipRootCert) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, certSet.LoadCert(chipRootCert, sTrustAnchorFlag) == CHIP_NO_ERROR); - - ValidationContext validContext; - - validContext.Reset(); - NL_TEST_ASSERT(inSuite, SetEffectiveTime(validContext, 2022, 1, 1) == CHIP_NO_ERROR); - validContext.mRequiredKeyUsages.Set(KeyUsageFlags::kDigitalSignature); - validContext.mRequiredKeyPurposes.Set(KeyPurposeFlags::kServerAuth); - validContext.mRequiredKeyPurposes.Set(KeyPurposeFlags::kClientAuth); - - // Locate the subject DN and key id that will be used as input the FindValidCert() method. - const ChipDN & subjectDN = certSet.GetCertSet()[0].mSubjectDN; - const CertificateKeyId & subjectKeyId = certSet.GetCertSet()[0].mSubjectKeyId; - - const ChipCertificateData * resultCert = nullptr; - NL_TEST_ASSERT(inSuite, certSet.FindValidCert(subjectDN, subjectKeyId, validContext, &resultCert) == CHIP_NO_ERROR); -} - -static void TestChipCert_X509ToChipArrayNoICA(nlTestSuite * inSuite, void * inContext) -{ - // Generate a new keypair for cert signing - P256Keypair keypair; - NL_TEST_ASSERT(inSuite, keypair.Initialize() == CHIP_NO_ERROR); - - static uint8_t root_cert[kMaxDERCertLength]; - - X509CertRequestParams root_params = { 1234, 0xabcdabcd, 631161876, 729942000, true, 0x8888, false, 0 }; - MutableByteSpan root_cert_span(root_cert, sizeof(root_cert)); - NL_TEST_ASSERT(inSuite, NewRootX509Cert(root_params, keypair, root_cert_span) == CHIP_NO_ERROR); - static uint8_t noc_cert[kMaxDERCertLength]; X509CertRequestParams noc_params = { 1234, 0xabcdabcd, 631161876, 729942000, true, 0x8888, true, 0x1234 }; P256Keypair noc_keypair; NL_TEST_ASSERT(inSuite, noc_keypair.Initialize() == CHIP_NO_ERROR); - MutableByteSpan noc_cert_span(noc_cert, sizeof(noc_cert)); + MutableByteSpan noc_cert_span(noc_cert); NL_TEST_ASSERT(inSuite, NewNodeOperationalX509Cert(noc_params, kIssuerIsRootCA, noc_keypair.Pubkey(), keypair, noc_cert_span) == CHIP_NO_ERROR); - static uint8_t chipCertArrayBuf[kMaxCHIPCertLength]; - static uint8_t chipRootCertBuf[kMaxCHIPCertLength]; - MutableByteSpan chipCertArray(chipCertArrayBuf); - MutableByteSpan chipRootCert(chipRootCertBuf); - - NL_TEST_ASSERT(inSuite, ConvertX509CertsToChipCertArray(noc_cert_span, ByteSpan(nullptr, 0), chipCertArray) == CHIP_NO_ERROR); - ChipCertificateSet certSet; NL_TEST_ASSERT(inSuite, certSet.Init(2) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, certSet.LoadCerts(chipCertArray, sGenTBSHashFlag) == CHIP_NO_ERROR); - - NL_TEST_ASSERT(inSuite, ConvertX509CertToChipCert(root_cert_span, chipRootCert) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, certSet.LoadCert(chipRootCert, sTrustAnchorFlag) == CHIP_NO_ERROR); - - ValidationContext validContext; - - validContext.Reset(); - NL_TEST_ASSERT(inSuite, SetEffectiveTime(validContext, 2022, 1, 1) == CHIP_NO_ERROR); - validContext.mRequiredKeyUsages.Set(KeyUsageFlags::kDigitalSignature); - validContext.mRequiredKeyPurposes.Set(KeyPurposeFlags::kServerAuth); - validContext.mRequiredKeyPurposes.Set(KeyPurposeFlags::kClientAuth); - - // Locate the subject DN and key id that will be used as input the FindValidCert() method. - const ChipDN & subjectDN = certSet.GetCertSet()[0].mSubjectDN; - const CertificateKeyId & subjectKeyId = certSet.GetCertSet()[0].mSubjectKeyId; - - const ChipCertificateData * resultCert = nullptr; - NL_TEST_ASSERT(inSuite, certSet.FindValidCert(subjectDN, subjectKeyId, validContext, &resultCert) == CHIP_NO_ERROR); -} - -static void TestChipCert_X509ToChipArrayErrorScenarios(nlTestSuite * inSuite, void * inContext) -{ - // Generate a new keypair for cert signing - P256Keypair keypair; - NL_TEST_ASSERT(inSuite, keypair.Initialize() == CHIP_NO_ERROR); - - static uint8_t root_cert[kMaxDERCertLength]; - - X509CertRequestParams root_params = { 1234, 0xabcdabcd, 631161876, 729942000, true, 0x8888, false, 0 }; - MutableByteSpan root_cert_span(root_cert); - NL_TEST_ASSERT(inSuite, NewRootX509Cert(root_params, keypair, root_cert_span) == CHIP_NO_ERROR); - - static uint8_t ica_cert[kMaxDERCertLength]; - - X509CertRequestParams ica_params = { 1234, 0xabcdabcd, 631161876, 729942000, true, 0x8888, false, 0 }; - P256Keypair ica_keypair; - NL_TEST_ASSERT(inSuite, ica_keypair.Initialize() == CHIP_NO_ERROR); - - MutableByteSpan ica_cert_span(ica_cert, sizeof(ica_cert)); - NL_TEST_ASSERT(inSuite, NewICAX509Cert(ica_params, 0xaabbccdd, ica_keypair.Pubkey(), keypair, ica_cert_span) == CHIP_NO_ERROR); - - static uint8_t noc_cert[kMaxDERCertLength]; - - X509CertRequestParams noc_params = { 1234, 0xaabbccdd, 631161876, 729942000, true, 0x8888, true, 0x1234 }; - P256Keypair noc_keypair; - NL_TEST_ASSERT(inSuite, noc_keypair.Initialize() == CHIP_NO_ERROR); - - MutableByteSpan noc_cert_span(noc_cert, sizeof(noc_cert)); - NL_TEST_ASSERT(inSuite, - NewNodeOperationalX509Cert(noc_params, kIssuerIsIntermediateCA, noc_keypair.Pubkey(), ica_keypair, - noc_cert_span) == CHIP_NO_ERROR); - - static uint8_t chipCertArrayBuf[kMaxCHIPCertLength * 2]; - MutableByteSpan chipCertArray(chipCertArrayBuf); - // Test that NOC is mandatory - NL_TEST_ASSERT(inSuite, - ConvertX509CertsToChipCertArray(ByteSpan(), ica_cert_span, chipCertArray) == CHIP_ERROR_INVALID_ARGUMENT); - - // Test that NOC issuer must match ICA - NL_TEST_ASSERT(inSuite, - ConvertX509CertsToChipCertArray(noc_cert_span, root_cert_span, chipCertArray) == CHIP_ERROR_INVALID_ARGUMENT); - - X509CertRequestParams ica_params_wrong_fabric = { 1234, 0xabcdabcd, 631161876, 729942000, true, 0x9999, false, 0 }; - - MutableByteSpan ica_cert_span1(ica_cert, sizeof(ica_cert)); - NL_TEST_ASSERT(inSuite, - NewICAX509Cert(ica_params_wrong_fabric, 0xaabbccdd, ica_keypair.Pubkey(), keypair, ica_cert_span1) == - CHIP_NO_ERROR); - // Test that NOC fabric must match ICA fabric - NL_TEST_ASSERT(inSuite, - ConvertX509CertsToChipCertArray(noc_cert_span, ica_cert_span, chipCertArray) == CHIP_ERROR_INVALID_ARGUMENT); -} - -static void TestChipCert_ChipArrayToChipCerts(nlTestSuite * inSuite, void * inContext) -{ - // Generate a new keypair for cert signing - P256Keypair keypair; - NL_TEST_ASSERT(inSuite, keypair.Initialize() == CHIP_NO_ERROR); - - static uint8_t root_cert[kMaxDERCertLength]; - - X509CertRequestParams root_params = { 1234, 0xabcdabcd, 631161876, 729942000, true, 0x8888, false, 0 }; - MutableByteSpan root_cert_span(root_cert); - NL_TEST_ASSERT(inSuite, NewRootX509Cert(root_params, keypair, root_cert_span) == CHIP_NO_ERROR); - - static uint8_t ica_cert[kMaxDERCertLength]; - - X509CertRequestParams ica_params = { 1234, 0xabcdabcd, 631161876, 729942000, true, 0x8888, false, 0 }; - P256Keypair ica_keypair; - NL_TEST_ASSERT(inSuite, ica_keypair.Initialize() == CHIP_NO_ERROR); - - MutableByteSpan ica_cert_span(ica_cert); - NL_TEST_ASSERT(inSuite, NewICAX509Cert(ica_params, 0xaabbccdd, ica_keypair.Pubkey(), keypair, ica_cert_span) == CHIP_NO_ERROR); - - static uint8_t noc_cert[kMaxDERCertLength]; - - X509CertRequestParams noc_params = { 1234, 0xaabbccdd, 631161876, 729942000, true, 0x8888, true, 0x1234 }; - P256Keypair noc_keypair; - NL_TEST_ASSERT(inSuite, noc_keypair.Initialize() == CHIP_NO_ERROR); - - MutableByteSpan noc_cert_span(noc_cert); - NL_TEST_ASSERT(inSuite, - NewNodeOperationalX509Cert(noc_params, kIssuerIsIntermediateCA, noc_keypair.Pubkey(), ica_keypair, - noc_cert_span) == CHIP_NO_ERROR); - - static uint8_t chipCertArrayBuf[kMaxCHIPCertLength * 2]; static uint8_t chipRootCertBuf[kMaxCHIPCertLength]; - MutableByteSpan chipCertArray(chipCertArrayBuf); + static uint8_t chipNOCCertBuf[kMaxCHIPCertLength]; MutableByteSpan chipRootCert(chipRootCertBuf); - NL_TEST_ASSERT(inSuite, ConvertX509CertsToChipCertArray(noc_cert_span, ica_cert_span, chipCertArray) == CHIP_NO_ERROR); - - ByteSpan noc_chip_cert; - ByteSpan ica_chip_cert; - NL_TEST_ASSERT(inSuite, ExtractCertsFromCertArray(chipCertArray, noc_chip_cert, ica_chip_cert) == CHIP_NO_ERROR); - - ChipCertificateSet certSet; - NL_TEST_ASSERT(inSuite, certSet.Init(3) == CHIP_NO_ERROR); - - NL_TEST_ASSERT(inSuite, certSet.LoadCert(noc_chip_cert, sGenTBSHashFlag) == CHIP_NO_ERROR); - - NL_TEST_ASSERT(inSuite, certSet.LoadCert(ica_chip_cert, sGenTBSHashFlag) == CHIP_NO_ERROR); + MutableByteSpan chipNOCCert(chipNOCCertBuf); NL_TEST_ASSERT(inSuite, ConvertX509CertToChipCert(root_cert_span, chipRootCert) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, certSet.LoadCert(chipRootCert, sTrustAnchorFlag) == CHIP_NO_ERROR); - ValidationContext validContext; - - validContext.Reset(); - NL_TEST_ASSERT(inSuite, SetEffectiveTime(validContext, 2022, 1, 1) == CHIP_NO_ERROR); - validContext.mRequiredKeyUsages.Set(KeyUsageFlags::kDigitalSignature); - validContext.mRequiredKeyPurposes.Set(KeyPurposeFlags::kServerAuth); - - // Locate the subject DN and key id that will be used as input the FindValidCert() method. - const ChipDN & subjectDN = certSet.GetCertSet()[0].mSubjectDN; - const CertificateKeyId & subjectKeyId = certSet.GetCertSet()[0].mSubjectKeyId; - - const ChipCertificateData * resultCert = nullptr; - NL_TEST_ASSERT(inSuite, certSet.FindValidCert(subjectDN, subjectKeyId, validContext, &resultCert) == CHIP_NO_ERROR); -} - -static void TestChipCert_ChipArrayToChipCertsNoICA(nlTestSuite * inSuite, void * inContext) -{ - // Generate a new keypair for cert signing - P256Keypair keypair; - NL_TEST_ASSERT(inSuite, keypair.Initialize() == CHIP_NO_ERROR); - - static uint8_t root_cert[kMaxDERCertLength]; - - X509CertRequestParams root_params = { 1234, 0xabcdabcd, 631161876, 729942000, true, 0x8888, false, 0 }; - MutableByteSpan root_cert_span(root_cert); - NL_TEST_ASSERT(inSuite, NewRootX509Cert(root_params, keypair, root_cert_span) == CHIP_NO_ERROR); - - static uint8_t noc_cert[kMaxDERCertLength]; - - X509CertRequestParams noc_params = { 1234, 0xabcdabcd, 631161876, 729942000, true, 0x8888, true, 0x1234 }; - P256Keypair noc_keypair; - NL_TEST_ASSERT(inSuite, noc_keypair.Initialize() == CHIP_NO_ERROR); - - MutableByteSpan noc_cert_span(noc_cert); - NL_TEST_ASSERT(inSuite, - NewNodeOperationalX509Cert(noc_params, kIssuerIsRootCA, noc_keypair.Pubkey(), keypair, noc_cert_span) == - CHIP_NO_ERROR); - - static uint8_t chipCertArrayBuf[kMaxCHIPCertLength]; - static uint8_t chipRootCertBuf[kMaxCHIPCertLength]; - MutableByteSpan chipCertArray(chipCertArrayBuf); - MutableByteSpan chipRootCert(chipRootCertBuf); - NL_TEST_ASSERT(inSuite, ConvertX509CertsToChipCertArray(noc_cert_span, ByteSpan(), chipCertArray) == CHIP_NO_ERROR); - - ByteSpan noc_chip_cert; - ByteSpan ica_chip_cert; - NL_TEST_ASSERT(inSuite, ExtractCertsFromCertArray(chipCertArray, noc_chip_cert, ica_chip_cert) == CHIP_NO_ERROR); - - NL_TEST_ASSERT(inSuite, ica_chip_cert.data() == nullptr && ica_chip_cert.size() == 0); - - ChipCertificateSet certSet; - NL_TEST_ASSERT(inSuite, certSet.Init(2) == CHIP_NO_ERROR); - - NL_TEST_ASSERT(inSuite, certSet.LoadCert(noc_chip_cert, sGenTBSHashFlag) == CHIP_NO_ERROR); - - NL_TEST_ASSERT(inSuite, ConvertX509CertToChipCert(root_cert_span, chipRootCert) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, certSet.LoadCert(chipRootCert, sTrustAnchorFlag) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, ConvertX509CertToChipCert(noc_cert_span, chipNOCCert) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, certSet.LoadCert(chipNOCCert, sGenTBSHashFlag) == CHIP_NO_ERROR); ValidationContext validContext; @@ -1245,10 +1002,11 @@ static void TestChipCert_ChipArrayToChipCertsNoICA(nlTestSuite * inSuite, void * NL_TEST_ASSERT(inSuite, SetEffectiveTime(validContext, 2022, 1, 1) == CHIP_NO_ERROR); validContext.mRequiredKeyUsages.Set(KeyUsageFlags::kDigitalSignature); validContext.mRequiredKeyPurposes.Set(KeyPurposeFlags::kServerAuth); + validContext.mRequiredKeyPurposes.Set(KeyPurposeFlags::kClientAuth); // Locate the subject DN and key id that will be used as input the FindValidCert() method. - const ChipDN & subjectDN = certSet.GetCertSet()[0].mSubjectDN; - const CertificateKeyId & subjectKeyId = certSet.GetCertSet()[0].mSubjectKeyId; + const ChipDN & subjectDN = certSet.GetCertSet()[1].mSubjectDN; + const CertificateKeyId & subjectKeyId = certSet.GetCertSet()[1].mSubjectKeyId; const ChipCertificateData * resultCert = nullptr; NL_TEST_ASSERT(inSuite, certSet.FindValidCert(subjectDN, subjectKeyId, validContext, &resultCert) == CHIP_NO_ERROR); @@ -1314,31 +1072,82 @@ static void TestChipCert_ExtractPeerId(nlTestSuite * inSuite, void * inContext) certSet.Release(); } - // Test extraction from cert array form. + // Test extraction from the parsed form. for (auto & testCase : sTestCases) { - ByteSpan cert; - CHIP_ERROR err = GetTestCert(testCase.Cert, sDerFormFlag, cert); + CHIP_ERROR err = certSet.Init(1); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ByteSpan icaCert; - if (testCase.ICACert != TestCert::kNone) - { - err = GetTestCert(testCase.ICACert, sDerFormFlag, icaCert); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - } - - uint8_t certArray[kMaxCHIPCertLength * 2]; - MutableByteSpan certs(certArray); - err = ConvertX509CertsToChipCertArray(cert, icaCert, certs); + err = LoadTestCert(certSet, testCase.Cert, sNullLoadFlag, sNullDecodeFlag); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - NodeId nodeId; FabricId fabricId; - err = ExtractNodeIdFabricIdFromOpCertArray(certs, &nodeId, &fabricId); + err = ExtractFabricIdFromCert(certSet.GetCertSet()[0], &fabricId); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, nodeId == testCase.ExpectedNodeId); NL_TEST_ASSERT(inSuite, fabricId == testCase.ExpectedFabricId); + certSet.Release(); + } + + // Test extraction from the parsed form of ICA Cert that doesn't have FabricId. + { + CHIP_ERROR err = certSet.Init(1); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + + err = LoadTestCert(certSet, TestCert::kICA01, sNullLoadFlag, sNullDecodeFlag); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + + FabricId fabricId; + err = ExtractFabricIdFromCert(certSet.GetCertSet()[0], &fabricId); + NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INVALID_ARGUMENT); + certSet.Release(); + } +} + +static void TestChipCert_ExtractPublicKeyAndSKID(nlTestSuite * inSuite, void * inContext) +{ + struct TestCase + { + uint8_t Cert; + const uint8_t * ExpectedPublicKey; + const uint8_t * ExpectedSKID; + }; + + // clang-format off + static constexpr TestCase sTestCases[] = { + // Cert ExpectedPublicKey ExpectedSKID + // ======================================================================================= + { TestCert::kRoot01, sTestCert_Root01_PublicKey, sTestCert_Root01_SubjectKeyId }, + { TestCert::kRoot02, sTestCert_Root02_PublicKey, sTestCert_Root02_SubjectKeyId }, + { TestCert::kICA01, sTestCert_ICA01_PublicKey, sTestCert_ICA01_SubjectKeyId }, + { TestCert::kICA02, sTestCert_ICA02_PublicKey, sTestCert_ICA02_SubjectKeyId }, + { TestCert::kICA01_1, sTestCert_ICA01_1_PublicKey, sTestCert_ICA01_1_SubjectKeyId }, + { TestCert::kNode01_01, sTestCert_Node01_01_PublicKey, sTestCert_Node01_01_SubjectKeyId }, + { TestCert::kNode01_02, sTestCert_Node01_02_PublicKey, sTestCert_Node01_02_SubjectKeyId }, + { TestCert::kNode02_01, sTestCert_Node02_01_PublicKey, sTestCert_Node02_01_SubjectKeyId }, + { TestCert::kNode02_02, sTestCert_Node02_02_PublicKey, sTestCert_Node02_02_SubjectKeyId }, + { TestCert::kNode02_03, sTestCert_Node02_03_PublicKey, sTestCert_Node02_03_SubjectKeyId }, + { TestCert::kNode02_04, sTestCert_Node02_04_PublicKey, sTestCert_Node02_04_SubjectKeyId }, + { TestCert::kNode02_05, sTestCert_Node02_05_PublicKey, sTestCert_Node02_05_SubjectKeyId }, + { TestCert::kNode02_06, sTestCert_Node02_06_PublicKey, sTestCert_Node02_06_SubjectKeyId }, + { TestCert::kNode02_07, sTestCert_Node02_07_PublicKey, sTestCert_Node02_07_SubjectKeyId }, + }; + // clang-format on + + for (auto & testCase : sTestCases) + { + ByteSpan cert; + CHIP_ERROR err = GetTestCert(testCase.Cert, sNullLoadFlag, cert); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + + P256PublicKeySpan publicKey; + err = ExtractPublicKeyFromChipCert(cert, publicKey); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, publicKey.data_equal(P256PublicKeySpan(testCase.ExpectedPublicKey))); + + CertificateKeyId skid; + err = ExtractSKIDFromChipCert(cert, skid); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, skid.data_equal(CertificateKeyId(testCase.ExpectedSKID))); } } @@ -1385,12 +1194,9 @@ static const nlTest sTests[] = { NL_TEST_DEF("Test CHIP Generate NOC using Root", TestChipCert_GenerateNOCRoot), NL_TEST_DEF("Test CHIP Generate NOC using ICA", TestChipCert_GenerateNOCICA), NL_TEST_DEF("Test CHIP Verify Generated Cert Chain", TestChipCert_VerifyGeneratedCerts), - NL_TEST_DEF("Test CHIP Certificates X509 to CHIP Array Conversion", TestChipCert_X509ToChipArray), - NL_TEST_DEF("Test CHIP Certificates X509 No ICA to CHIP Array Conversion", TestChipCert_X509ToChipArrayNoICA), - NL_TEST_DEF("Test CHIP Certificates X509 to CHIP Array Conversion Error Scenarios", TestChipCert_X509ToChipArrayErrorScenarios), - NL_TEST_DEF("Test CHIP Array to Chip Certificates Conversion", TestChipCert_ChipArrayToChipCerts), - NL_TEST_DEF("Test No ICA CHIP Array to Chip Certificates Conversion", TestChipCert_ChipArrayToChipCertsNoICA), + NL_TEST_DEF("Test CHIP Verify Generated Cert Chain No ICA", TestChipCert_VerifyGeneratedCertsNoICA), NL_TEST_DEF("Test extracting PeerId from node certificate", TestChipCert_ExtractPeerId), + NL_TEST_DEF("Test extracting PublicKey and SKID from chip certificate", TestChipCert_ExtractPublicKeyAndSKID), NL_TEST_SENTINEL() }; // clang-format on diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h index 72a0faa4354b6b..a66991557e6313 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h @@ -1113,7 +1113,8 @@ NS_ASSUME_NONNULL_BEGIN */ @interface CHIPOperationalCredentials : CHIPCluster -- (void)addNOC:(NSData *)nOCArray +- (void)addNOC:(NSData *)nOCValue + iCACValue:(NSData *)iCACValue iPKValue:(NSData *)iPKValue caseAdminNode:(uint64_t)caseAdminNode adminVendorId:(uint16_t)adminVendorId @@ -1123,7 +1124,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)removeFabric:(uint8_t)fabricIndex responseHandler:(ResponseHandler)responseHandler; - (void)removeTrustedRootCertificate:(NSData *)trustedRootIdentifier responseHandler:(ResponseHandler)responseHandler; - (void)updateFabricLabel:(NSString *)label responseHandler:(ResponseHandler)responseHandler; -- (void)updateNOC:(NSData *)nOCArray responseHandler:(ResponseHandler)responseHandler; +- (void)updateNOC:(NSData *)nOCValue iCACValue:(NSData *)iCACValue responseHandler:(ResponseHandler)responseHandler; - (void)readAttributeFabricsListWithResponseHandler:(ResponseHandler)responseHandler; diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm index 442aed0fe4ac13..af7d8bd04a9692 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm @@ -3174,7 +3174,8 @@ @implementation CHIPOperationalCredentials return &_cppCluster; } -- (void)addNOC:(NSData *)nOCArray +- (void)addNOC:(NSData *)nOCValue + iCACValue:(NSData *)iCACValue iPKValue:(NSData *)iPKValue caseAdminNode:(uint64_t)caseAdminNode adminVendorId:(uint16_t)adminVendorId @@ -3182,8 +3183,8 @@ - (void)addNOC:(NSData *)nOCArray { new CHIPOperationalCredentialsClusterNOCResponseCallbackBridge( self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { - return self.cppCluster.AddNOC( - success, failure, [self asSpan:nOCArray], [self asSpan:iPKValue], caseAdminNode, adminVendorId); + return self.cppCluster.AddNOC(success, failure, [self asSpan:nOCValue], [self asSpan:iCACValue], [self asSpan:iPKValue], + caseAdminNode, adminVendorId); }); } @@ -3225,11 +3226,11 @@ new CHIPOperationalCredentialsClusterNOCResponseCallbackBridge( }); } -- (void)updateNOC:(NSData *)nOCArray responseHandler:(ResponseHandler)responseHandler +- (void)updateNOC:(NSData *)nOCValue iCACValue:(NSData *)iCACValue responseHandler:(ResponseHandler)responseHandler { new CHIPOperationalCredentialsClusterNOCResponseCallbackBridge( self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { - return self.cppCluster.UpdateNOC(success, failure, [self asSpan:nOCArray]); + return self.cppCluster.UpdateNOC(success, failure, [self asSpan:nOCValue], [self asSpan:iCACValue]); }); } diff --git a/src/protocols/secure_channel/CASESession.cpp b/src/protocols/secure_channel/CASESession.cpp index 29f27d0ccf8709..77311422f33aba 100644 --- a/src/protocols/secure_channel/CASESession.cpp +++ b/src/protocols/secure_channel/CASESession.cpp @@ -61,6 +61,13 @@ static_assert(sizeof(kTBEData2_Nonce) == sizeof(kTBEData3_Nonce), "TBEData2_Nonc // TODO: move this constant over to src/crypto/CHIPCryptoPAL.h - name it CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES constexpr size_t kTAGSize = 16; +enum +{ + kTag_TBEData_SenderNOC = 1, + kTag_TBEData_SenderICAC = 2, + kTag_TBEData_Signature = 3, +}; + #ifdef ENABLE_HSM_HKDF using HKDF_sha_crypto = HKDF_shaHSM; #else @@ -447,24 +454,13 @@ CHIP_ERROR CASESession::SendSigmaR2() uint8_t sr2k[kAEADKeySize]; P256ECDSASignature tbsData2Signature; - uint32_t opcredsLen = 0; - chip::Platform::ScopedMemoryBuffer opcreds; - ByteSpan opcredsSpan; + ByteSpan icaCert; + ByteSpan nocCert; VerifyOrExit(mFabricInfo != nullptr, err = CHIP_ERROR_INCORRECT_STATE); - VerifyOrExit(opcreds.Alloc(mFabricInfo->GetOperationalCredentialsLength()), err = CHIP_ERROR_NO_MEMORY); - - { - MutableByteSpan opcredsMutableSpan(opcreds.Get(), mFabricInfo->GetOperationalCredentialsLength()); - err = mFabricInfo->GetOperationalCredentials(opcredsMutableSpan); - SuccessOrExit(err); - - opcredsSpan = opcredsMutableSpan; - } - - VerifyOrExit(CanCastTo(opcredsSpan.size()), err = CHIP_ERROR_INVALID_ARGUMENT); - opcredsLen = static_cast(opcredsSpan.size()); + SuccessOrExit(err = mFabricInfo->GetICACert(icaCert)); + SuccessOrExit(err = mFabricInfo->GetNOCCert(nocCert)); mTrustedRootId = mFabricInfo->GetTrustedRootId(); VerifyOrExit(!mTrustedRootId.empty(), err = CHIP_ERROR_INTERNAL); @@ -496,24 +492,12 @@ CHIP_ERROR CASESession::SendSigmaR2() } // Construct Sigma2 TBS Data - msg_r2_signed_len = EstimateTLVStructOverhead(opcredsLen + kP256_PublicKey_Length * 2, 3); + msg_r2_signed_len = EstimateTLVStructOverhead(nocCert.size() + icaCert.size() + kP256_PublicKey_Length * 2, 4); VerifyOrExit(msg_R2_Signed.Alloc(msg_r2_signed_len), err = CHIP_ERROR_NO_MEMORY); - { - TLV::TLVWriter tlvWriter; - TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; - - tlvWriter.Init(msg_R2_Signed.Get(), msg_r2_signed_len); - SuccessOrExit(err = tlvWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, outerContainerType)); - SuccessOrExit(err = tlvWriter.PutBytes(TLV::ContextTag(1), opcredsSpan.data(), opcredsLen)); - SuccessOrExit(err = tlvWriter.PutBytes(TLV::ContextTag(2), mEphemeralKey.Pubkey(), - static_cast(mEphemeralKey.Pubkey().Length()))); - SuccessOrExit(err = tlvWriter.PutBytes(TLV::ContextTag(3), mRemotePubKey, static_cast(mRemotePubKey.Length()))); - SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType)); - SuccessOrExit(err = tlvWriter.Finalize()); - msg_r2_signed_len = static_cast(tlvWriter.GetLengthWritten()); - } + SuccessOrExit(err = ConstructTBSData(nocCert, icaCert, ByteSpan(mEphemeralKey.Pubkey(), mEphemeralKey.Pubkey().Length()), + ByteSpan(mRemotePubKey, mRemotePubKey.Length()), msg_R2_Signed.Get(), msg_r2_signed_len)); // Generate a Signature VerifyOrExit(mFabricInfo->GetOperationalKey() != nullptr, err = CHIP_ERROR_INCORRECT_STATE); @@ -521,7 +505,7 @@ CHIP_ERROR CASESession::SendSigmaR2() SuccessOrExit(err); // Construct Sigma2 TBE Data - msg_r2_signed_enc_len = EstimateTLVStructOverhead(opcredsLen + tbsData2Signature.Length(), 2); + msg_r2_signed_enc_len = EstimateTLVStructOverhead(nocCert.size() + icaCert.size() + tbsData2Signature.Length(), 3); VerifyOrExit(msg_R2_Encrypted.Alloc(msg_r2_signed_enc_len + kTAGSize), err = CHIP_ERROR_NO_MEMORY); @@ -531,9 +515,13 @@ CHIP_ERROR CASESession::SendSigmaR2() tlvWriter.Init(msg_R2_Encrypted.Get(), msg_r2_signed_enc_len); SuccessOrExit(err = tlvWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, outerContainerType)); - SuccessOrExit(err = tlvWriter.PutBytes(TLV::ContextTag(1), opcredsSpan.data(), opcredsLen)); - SuccessOrExit( - err = tlvWriter.PutBytes(TLV::ContextTag(2), tbsData2Signature, static_cast(tbsData2Signature.Length()))); + SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(kTag_TBEData_SenderNOC), nocCert)); + if (!icaCert.empty()) + { + SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(kTag_TBEData_SenderICAC), icaCert)); + } + SuccessOrExit(err = tlvWriter.PutBytes(TLV::ContextTag(kTag_TBEData_Signature), tbsData2Signature, + static_cast(tbsData2Signature.Length()))); SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType)); SuccessOrExit(err = tlvWriter.Finalize()); msg_r2_signed_enc_len = static_cast(tlvWriter.GetLengthWritten()); @@ -622,9 +610,8 @@ CHIP_ERROR CASESession::HandleSigmaR2(System::PacketBufferHandle && msg) P256PublicKey remoteCredential; uint8_t responderRandom[kSigmaParamRandomNumberSize]; - // Responder opCert must fit up to 2x TLV certificates in an array - uint8_t responderOpCert[EstimateTLVStructOverhead(kMaxCHIPOpCertArrayLength, 2)]; - size_t responderOpCertLen; + ByteSpan responderNOC; + ByteSpan responderICAC; uint16_t responderSessionId = 0; @@ -686,35 +673,37 @@ CHIP_ERROR CASESession::HandleSigmaR2(System::PacketBufferHandle && msg) msg_R2_Encrypted.Get() + msg_r2_encrypted_len, kTAGSize, sr2k, kAEADKeySize, kTBEData2_Nonce, kTBEDataNonceLength, msg_R2_Encrypted.Get())); - decodeTagIdSeq = 0; decryptedDataTlvReader.Init(msg_R2_Encrypted.Get(), msg_r2_encrypted_len); containerType = TLV::kTLVType_Structure; SuccessOrExit(err = decryptedDataTlvReader.Next(containerType, TLV::AnonymousTag)); SuccessOrExit(err = decryptedDataTlvReader.EnterContainer(containerType)); - SuccessOrExit(err = decryptedDataTlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(decryptedDataTlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = decryptedDataTlvReader.Next(TLV::kTLVType_ByteString, TLV::ContextTag(kTag_TBEData_SenderNOC))); + SuccessOrExit(err = decryptedDataTlvReader.Get(responderNOC)); - responderOpCertLen = static_cast(decryptedDataTlvReader.GetLength()); - // We use `sizeof(responderOpCert)` rather than `responderOpCertLen` since GetBytes() - // validates that the destination buffer is large enough for the equivalent of GetLength(). - // If we used untrusted `responderOpCertLen` directly, and a bad value was provided, - // it could overrun stack without being caught. - SuccessOrExit(err = decryptedDataTlvReader.GetBytes(responderOpCert, sizeof(responderOpCert))); + SuccessOrExit(err = decryptedDataTlvReader.Next()); + if (TLV::TagNumFromTag(decryptedDataTlvReader.GetTag()) == kTag_TBEData_SenderICAC) + { + VerifyOrExit(decryptedDataTlvReader.GetType() == TLV::kTLVType_ByteString, err = CHIP_ERROR_WRONG_TLV_TYPE); + SuccessOrExit(err = decryptedDataTlvReader.Get(responderICAC)); + SuccessOrExit(err = decryptedDataTlvReader.Next(TLV::kTLVType_ByteString, TLV::ContextTag(kTag_TBEData_Signature))); + } // Validate responder identity located in msg_r2_encrypted // Constructing responder identity - SuccessOrExit(err = Validate_and_RetrieveResponderID(ByteSpan(responderOpCert, responderOpCertLen), remoteCredential)); + SuccessOrExit(err = Validate_and_RetrieveResponderID(responderNOC, responderICAC, remoteCredential)); // Construct msg_R2_Signed and validate the signature in msg_r2_encrypted - msg_r2_signed_len = EstimateTLVStructOverhead(sizeof(uint16_t) + responderOpCertLen + kP256_PublicKey_Length * 2, 3); + msg_r2_signed_len = + EstimateTLVStructOverhead(sizeof(uint16_t) + responderNOC.size() + responderICAC.size() + kP256_PublicKey_Length * 2, 4); VerifyOrExit(msg_R2_Signed.Alloc(msg_r2_signed_len), err = CHIP_ERROR_NO_MEMORY); - SuccessOrExit(err = ConstructTBS2Data(ByteSpan(responderOpCert, responderOpCertLen), msg_R2_Signed.Get(), msg_r2_signed_len)); + SuccessOrExit(err = ConstructTBSData(responderNOC, responderICAC, ByteSpan(mRemotePubKey, mRemotePubKey.Length()), + ByteSpan(mEphemeralKey.Pubkey(), mEphemeralKey.Pubkey().Length()), msg_R2_Signed.Get(), + msg_r2_signed_len)); - SuccessOrExit(err = decryptedDataTlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(decryptedDataTlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + VerifyOrExit(TLV::TagNumFromTag(decryptedDataTlvReader.GetTag()) == kTag_TBEData_Signature, err = CHIP_ERROR_INVALID_TLV_TAG); VerifyOrExit(tbsData2Signature.Capacity() >= decryptedDataTlvReader.GetLength(), err = CHIP_ERROR_INVALID_TLV_ELEMENT); tbsData2Signature.SetLength(decryptedDataTlvReader.GetLength()); SuccessOrExit(err = decryptedDataTlvReader.GetBytes(tbsData2Signature, tbsData2Signature.Length())); @@ -756,47 +745,24 @@ CHIP_ERROR CASESession::SendSigmaR3() ChipLogDetail(SecureChannel, "Sending SigmaR3"); - uint32_t opcredsLen = 0; - chip::Platform::ScopedMemoryBuffer opcreds; - ByteSpan opcredsSpan; + ByteSpan icaCert; + ByteSpan nocCert; VerifyOrExit(mFabricInfo != nullptr, err = CHIP_ERROR_INCORRECT_STATE); - VerifyOrExit(opcreds.Alloc(mFabricInfo->GetOperationalCredentialsLength()), err = CHIP_ERROR_NO_MEMORY); - - { - MutableByteSpan opcredsMutableSpan(opcreds.Get(), mFabricInfo->GetOperationalCredentialsLength()); - err = mFabricInfo->GetOperationalCredentials(opcredsMutableSpan); - SuccessOrExit(err); - - opcredsSpan = opcredsMutableSpan; - } - - VerifyOrExit(CanCastTo(opcredsSpan.size()), err = CHIP_ERROR_INVALID_ARGUMENT); - opcredsLen = static_cast(opcredsSpan.size()); + SuccessOrExit(err = mFabricInfo->GetICACert(icaCert)); + SuccessOrExit(err = mFabricInfo->GetNOCCert(nocCert)); mTrustedRootId = mFabricInfo->GetTrustedRootId(); VerifyOrExit(!mTrustedRootId.empty(), err = CHIP_ERROR_INTERNAL); // Prepare SigmaR3 TBS Data Blob - msg_r3_signed_len = EstimateTLVStructOverhead(opcredsLen + kP256_PublicKey_Length * 2, 3); + msg_r3_signed_len = EstimateTLVStructOverhead(icaCert.size() + nocCert.size() + kP256_PublicKey_Length * 2, 4); VerifyOrExit(msg_R3_Signed.Alloc(msg_r3_signed_len), err = CHIP_ERROR_NO_MEMORY); - { - TLV::TLVWriter tlvWriter; - TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; - - tlvWriter.Init(msg_R3_Signed.Get(), msg_r3_signed_len); - SuccessOrExit(err = tlvWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, outerContainerType)); - SuccessOrExit(err = tlvWriter.PutBytes(TLV::ContextTag(1), opcredsSpan.data(), opcredsLen)); - SuccessOrExit(err = tlvWriter.PutBytes(TLV::ContextTag(2), mEphemeralKey.Pubkey(), - static_cast(mEphemeralKey.Pubkey().Length()))); - SuccessOrExit(err = tlvWriter.PutBytes(TLV::ContextTag(3), mRemotePubKey, static_cast(mRemotePubKey.Length()))); - SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType)); - SuccessOrExit(err = tlvWriter.Finalize()); - msg_r3_signed_len = static_cast(tlvWriter.GetLengthWritten()); - } + SuccessOrExit(err = ConstructTBSData(nocCert, icaCert, ByteSpan(mEphemeralKey.Pubkey(), mEphemeralKey.Pubkey().Length()), + ByteSpan(mRemotePubKey, mRemotePubKey.Length()), msg_R3_Signed.Get(), msg_r3_signed_len)); // Generate a signature VerifyOrExit(mFabricInfo->GetOperationalKey() != nullptr, err = CHIP_ERROR_INCORRECT_STATE); @@ -804,7 +770,7 @@ CHIP_ERROR CASESession::SendSigmaR3() SuccessOrExit(err); // Prepare SigmaR3 TBE Data Blob - msg_r3_encrypted_len = EstimateTLVStructOverhead(opcredsLen + tbsData3Signature.Length(), 2); + msg_r3_encrypted_len = EstimateTLVStructOverhead(nocCert.size() + icaCert.size() + tbsData3Signature.Length(), 3); VerifyOrExit(msg_R3_Encrypted.Alloc(msg_r3_encrypted_len + kTAGSize), err = CHIP_ERROR_NO_MEMORY); @@ -814,9 +780,13 @@ CHIP_ERROR CASESession::SendSigmaR3() tlvWriter.Init(msg_R3_Encrypted.Get(), msg_r3_encrypted_len); SuccessOrExit(err = tlvWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, outerContainerType)); - SuccessOrExit(err = tlvWriter.PutBytes(TLV::ContextTag(1), opcredsSpan.data(), opcredsLen)); - SuccessOrExit( - err = tlvWriter.PutBytes(TLV::ContextTag(2), tbsData3Signature, static_cast(tbsData3Signature.Length()))); + SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(kTag_TBEData_SenderNOC), nocCert)); + if (!icaCert.empty()) + { + SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(kTag_TBEData_SenderICAC), icaCert)); + } + SuccessOrExit(err = tlvWriter.PutBytes(TLV::ContextTag(kTag_TBEData_Signature), tbsData3Signature, + static_cast(tbsData3Signature.Length()))); SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType)); SuccessOrExit(err = tlvWriter.Finalize()); msg_r3_encrypted_len = static_cast(tlvWriter.GetLengthWritten()); @@ -913,9 +883,8 @@ CHIP_ERROR CASESession::HandleSigmaR3(System::PacketBufferHandle && msg) P256PublicKey remoteCredential; - // Initiator opCert must fit up to 2x TLV certificates in an array - uint8_t initiatorOpCert[EstimateTLVStructOverhead(kMaxCHIPOpCertArrayLength, 2)]; - size_t initiatorOpCertLen; + ByteSpan initiatorNOC; + ByteSpan initiatorICAC; uint8_t msg_salt[kIPKSize + kSHA256_Hash_Length]; @@ -957,36 +926,38 @@ CHIP_ERROR CASESession::HandleSigmaR3(System::PacketBufferHandle && msg) msg_R3_Encrypted.Get() + msg_r3_encrypted_len, kTAGSize, sr3k, kAEADKeySize, kTBEData3_Nonce, kTBEDataNonceLength, msg_R3_Encrypted.Get())); - decodeTagIdSeq = 0; decryptedDataTlvReader.Init(msg_R3_Encrypted.Get(), msg_r3_encrypted_len); containerType = TLV::kTLVType_Structure; SuccessOrExit(err = decryptedDataTlvReader.Next(containerType, TLV::AnonymousTag)); SuccessOrExit(err = decryptedDataTlvReader.EnterContainer(containerType)); - SuccessOrExit(err = decryptedDataTlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(decryptedDataTlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = decryptedDataTlvReader.Next(TLV::kTLVType_ByteString, TLV::ContextTag(kTag_TBEData_SenderNOC))); + SuccessOrExit(err = decryptedDataTlvReader.Get(initiatorNOC)); - initiatorOpCertLen = static_cast(decryptedDataTlvReader.GetLength()); - // We use `sizeof(initiatorOpCert)` rather than `initiatorOpCertLen` since GetBytes() - // validates that the destination buffer is large enough for the equivalent of GetLength(). - // If we used untrusted `initiatorOpCertLen` directly, and a bad value was provided, - // it could overrun stack without being caught. - SuccessOrExit(err = decryptedDataTlvReader.GetBytes(initiatorOpCert, sizeof(initiatorOpCert))); + SuccessOrExit(err = decryptedDataTlvReader.Next()); + if (TLV::TagNumFromTag(decryptedDataTlvReader.GetTag()) == kTag_TBEData_SenderICAC) + { + VerifyOrExit(decryptedDataTlvReader.GetType() == TLV::kTLVType_ByteString, err = CHIP_ERROR_WRONG_TLV_TYPE); + SuccessOrExit(err = decryptedDataTlvReader.Get(initiatorICAC)); + SuccessOrExit(err = decryptedDataTlvReader.Next(TLV::kTLVType_ByteString, TLV::ContextTag(kTag_TBEData_Signature))); + } // Step 5/6 // Validate initiator identity located in msg->Start() // Constructing responder identity - SuccessOrExit(err = Validate_and_RetrieveResponderID(ByteSpan(initiatorOpCert, initiatorOpCertLen), remoteCredential)); + SuccessOrExit(err = Validate_and_RetrieveResponderID(initiatorNOC, initiatorICAC, remoteCredential)); // Step 4 - Construct SigmaR3 TBS Data - msg_r3_signed_len = EstimateTLVStructOverhead(sizeof(uint16_t) + initiatorOpCertLen + kP256_PublicKey_Length * 2, 3); + msg_r3_signed_len = + EstimateTLVStructOverhead(sizeof(uint16_t) + initiatorNOC.size() + initiatorICAC.size() + kP256_PublicKey_Length * 2, 4); VerifyOrExit(msg_R3_Signed.Alloc(msg_r3_signed_len), err = CHIP_ERROR_NO_MEMORY); - SuccessOrExit(err = ConstructTBS3Data(ByteSpan(initiatorOpCert, initiatorOpCertLen), msg_R3_Signed.Get(), msg_r3_signed_len)); + SuccessOrExit(err = ConstructTBSData(initiatorNOC, initiatorICAC, ByteSpan(mRemotePubKey, mRemotePubKey.Length()), + ByteSpan(mEphemeralKey.Pubkey(), mEphemeralKey.Pubkey().Length()), msg_R3_Signed.Get(), + msg_r3_signed_len)); - SuccessOrExit(err = decryptedDataTlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(decryptedDataTlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + VerifyOrExit(TLV::TagNumFromTag(decryptedDataTlvReader.GetTag()) == kTag_TBEData_Signature, err = CHIP_ERROR_INVALID_TLV_TAG); VerifyOrExit(tbsData3Signature.Capacity() >= decryptedDataTlvReader.GetLength(), err = CHIP_ERROR_INVALID_TLV_ELEMENT); tbsData3Signature.SetLength(decryptedDataTlvReader.GetLength()); SuccessOrExit(err = decryptedDataTlvReader.GetBytes(tbsData3Signature, tbsData3Signature.Length())); @@ -1080,7 +1051,8 @@ CHIP_ERROR CASESession::ConstructSaltSigmaR3(const ByteSpan & ipk, MutableByteSp return CHIP_NO_ERROR; } -CHIP_ERROR CASESession::Validate_and_RetrieveResponderID(const ByteSpan & responderOpCert, Crypto::P256PublicKey & responderID) +CHIP_ERROR CASESession::Validate_and_RetrieveResponderID(const ByteSpan & responderNOC, const ByteSpan & responderICAC, + Crypto::P256PublicKey & responderID) { ReturnErrorCodeIf(mFabricInfo == nullptr, CHIP_ERROR_INCORRECT_STATE); @@ -1088,44 +1060,37 @@ CHIP_ERROR CASESession::Validate_and_RetrieveResponderID(const ByteSpan & respon PeerId peerId; FabricId rawFabricId; - ReturnErrorOnFailure(mFabricInfo->VerifyCredentials(responderOpCert, mValidContext, peerId, rawFabricId, responderID)); + ReturnErrorOnFailure( + mFabricInfo->VerifyCredentials(responderNOC, responderICAC, mValidContext, peerId, rawFabricId, responderID)); SetPeerNodeId(peerId.GetNodeId()); return CHIP_NO_ERROR; } -CHIP_ERROR CASESession::ConstructTBS2Data(const ByteSpan & responderOpCert, uint8_t * tbsData, size_t & tbsDataLen) +CHIP_ERROR CASESession::ConstructTBSData(const ByteSpan & senderNOC, const ByteSpan & senderICAC, const ByteSpan & senderPubKey, + const ByteSpan & receiverPubKey, uint8_t * tbsData, size_t & tbsDataLen) { TLV::TLVWriter tlvWriter; TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; - tlvWriter.Init(tbsData, tbsDataLen); - ReturnErrorOnFailure(tlvWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, outerContainerType)); - ReturnErrorOnFailure( - tlvWriter.PutBytes(TLV::ContextTag(1), responderOpCert.data(), static_cast(responderOpCert.size()))); - ReturnErrorOnFailure(tlvWriter.PutBytes(TLV::ContextTag(2), mRemotePubKey, static_cast(mRemotePubKey.Length()))); - ReturnErrorOnFailure( - tlvWriter.PutBytes(TLV::ContextTag(3), mEphemeralKey.Pubkey(), static_cast(mEphemeralKey.Pubkey().Length()))); - ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType)); - ReturnErrorOnFailure(tlvWriter.Finalize()); - tbsDataLen = static_cast(tlvWriter.GetLengthWritten()); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR CASESession::ConstructTBS3Data(const ByteSpan & responderOpCert, uint8_t * tbsData, size_t & tbsDataLen) -{ - TLV::TLVWriter tlvWriter; - TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; + enum + { + kTag_TBSData_SenderNOC = 1, + kTag_TBSData_SenderICAC = 2, + kTag_TBSData_SenderPubKey = 3, + kTag_TBSData_ReceiverPubKey = 4, + }; tlvWriter.Init(tbsData, tbsDataLen); ReturnErrorOnFailure(tlvWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, outerContainerType)); - ReturnErrorOnFailure( - tlvWriter.PutBytes(TLV::ContextTag(1), responderOpCert.data(), static_cast(responderOpCert.size()))); - ReturnErrorOnFailure(tlvWriter.PutBytes(TLV::ContextTag(2), mRemotePubKey, static_cast(mRemotePubKey.Length()))); - ReturnErrorOnFailure( - tlvWriter.PutBytes(TLV::ContextTag(3), mEphemeralKey.Pubkey(), static_cast(mEphemeralKey.Pubkey().Length()))); + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(kTag_TBSData_SenderNOC), senderNOC)); + if (!senderICAC.empty()) + { + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(kTag_TBSData_SenderICAC), senderICAC)); + } + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(kTag_TBSData_SenderPubKey), senderPubKey)); + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(kTag_TBSData_ReceiverPubKey), receiverPubKey)); ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType)); ReturnErrorOnFailure(tlvWriter.Finalize()); tbsDataLen = static_cast(tlvWriter.GetLengthWritten()); diff --git a/src/protocols/secure_channel/CASESession.h b/src/protocols/secure_channel/CASESession.h index b8774104f61e38..31159ae2686d59 100644 --- a/src/protocols/secure_channel/CASESession.h +++ b/src/protocols/secure_channel/CASESession.h @@ -198,10 +198,11 @@ class DLL_EXPORT CASESession : public Messaging::ExchangeDelegate, public Pairin CHIP_ERROR ConstructSaltSigmaR2(const ByteSpan & rand, const Crypto::P256PublicKey & pubkey, const ByteSpan & ipk, MutableByteSpan & salt); - CHIP_ERROR Validate_and_RetrieveResponderID(const ByteSpan & responderOpCert, Crypto::P256PublicKey & responderID); + CHIP_ERROR Validate_and_RetrieveResponderID(const ByteSpan & responderNOC, const ByteSpan & responderICAC, + Crypto::P256PublicKey & responderID); CHIP_ERROR ConstructSaltSigmaR3(const ByteSpan & ipk, MutableByteSpan & salt); - CHIP_ERROR ConstructTBS2Data(const ByteSpan & responderOpCert, uint8_t * tbsData, size_t & tbsDataLen); - CHIP_ERROR ConstructTBS3Data(const ByteSpan & responderOpCert, uint8_t * tbsData, size_t & tbsDataLen); + CHIP_ERROR ConstructTBSData(const ByteSpan & senderNOC, const ByteSpan & senderICAC, const ByteSpan & senderPubKey, + const ByteSpan & receiverPubKey, uint8_t * tbsData, size_t & tbsDataLen); CHIP_ERROR RetrieveIPK(FabricId fabricId, MutableByteSpan & ipk); static constexpr size_t EstimateTLVStructOverhead(size_t dataLen, size_t nFields) diff --git a/src/protocols/secure_channel/tests/TestCASESession.cpp b/src/protocols/secure_channel/tests/TestCASESession.cpp index 67f39cd35e2b47..fa340a8f9e7995 100644 --- a/src/protocols/secure_channel/tests/TestCASESession.cpp +++ b/src/protocols/secure_channel/tests/TestCASESession.cpp @@ -122,13 +122,8 @@ static CHIP_ERROR InitCredentialSets() ReturnErrorOnFailure(commissionerFabric.SetEphemeralKey(&opKey)); ReturnErrorOnFailure(commissionerFabric.SetRootCert(ByteSpan(sTestCert_Root01_Chip, sTestCert_Root01_Chip_Len))); - - uint8_t certChainBuf[kMaxCHIPCertLength * 2]; - MutableByteSpan certChain(certChainBuf); - - ReturnErrorOnFailure(ConvertX509CertsToChipCertArray(ByteSpan(sTestCert_Node01_01_DER, sTestCert_Node01_01_DER_Len), - ByteSpan(sTestCert_ICA01_DER, sTestCert_ICA01_DER_Len), certChain)); - ReturnErrorOnFailure(commissionerFabric.SetOperationalCertsFromCertArray(certChain)); + ReturnErrorOnFailure(commissionerFabric.SetICACert(ByteSpan(sTestCert_ICA01_Chip, sTestCert_ICA01_Chip_Len))); + ReturnErrorOnFailure(commissionerFabric.SetNOCCert(ByteSpan(sTestCert_Node01_01_Chip, sTestCert_Node01_01_Chip_Len))); ReturnErrorOnFailure(gCommissionerFabrics.AddNewFabric(commissionerFabric, &gCommissionerFabricIndex)); @@ -144,10 +139,8 @@ static CHIP_ERROR InitCredentialSets() ReturnErrorOnFailure(deviceFabric.SetEphemeralKey(&opKey)); ReturnErrorOnFailure(deviceFabric.SetRootCert(ByteSpan(sTestCert_Root01_Chip, sTestCert_Root01_Chip_Len))); - - ReturnErrorOnFailure(ConvertX509CertsToChipCertArray(ByteSpan(sTestCert_Node01_01_DER, sTestCert_Node01_01_DER_Len), - ByteSpan(sTestCert_ICA01_DER, sTestCert_ICA01_DER_Len), certChain)); - ReturnErrorOnFailure(deviceFabric.SetOperationalCertsFromCertArray(certChain)); + ReturnErrorOnFailure(deviceFabric.SetICACert(ByteSpan(sTestCert_ICA01_Chip, sTestCert_ICA01_Chip_Len))); + ReturnErrorOnFailure(deviceFabric.SetNOCCert(ByteSpan(sTestCert_Node01_01_Chip, sTestCert_Node01_01_Chip_Len))); ReturnErrorOnFailure(gDeviceFabrics.AddNewFabric(deviceFabric, &gDeviceFabricIndex)); diff --git a/src/transport/FabricTable.cpp b/src/transport/FabricTable.cpp index 023b28a8dbac6b..41c2e869795ab5 100644 --- a/src/transport/FabricTable.cpp +++ b/src/transport/FabricTable.cpp @@ -74,24 +74,37 @@ CHIP_ERROR FabricInfo::StoreIntoKVS(PersistentStorageDelegate * kvs) SuccessOrExit(err = keypair.Serialize(info->mOperationalKey)); } - if (mRootCert == nullptr || mRootCertLen == 0) + if (mRootCert.empty()) { info->mRootCertLen = 0; } else { - info->mRootCertLen = Encoding::LittleEndian::HostSwap16(mRootCertLen); - memcpy(info->mRootCert, mRootCert, mRootCertLen); + VerifyOrExit(CanCastTo(mRootCert.size()), err = CHIP_ERROR_INVALID_ARGUMENT); + info->mRootCertLen = Encoding::LittleEndian::HostSwap16(static_cast(mRootCert.size())); + memcpy(info->mRootCert, mRootCert.data(), mRootCert.size()); } - if (mOperationalCerts == nullptr || mOperationalCertsLen == 0) + if (mICACert.empty()) { - info->mOperationalCertsLen = 0; + info->mICACertLen = 0; } else { - info->mOperationalCertsLen = Encoding::LittleEndian::HostSwap16(mOperationalCertsLen); - memcpy(info->mOperationalCerts, mOperationalCerts, mOperationalCertsLen); + VerifyOrExit(CanCastTo(mICACert.size()), err = CHIP_ERROR_INVALID_ARGUMENT); + info->mICACertLen = Encoding::LittleEndian::HostSwap16(static_cast(mICACert.size())); + memcpy(info->mICACert, mICACert.data(), mICACert.size()); + } + + if (mNOCCert.empty()) + { + info->mNOCCertLen = 0; + } + else + { + VerifyOrExit(CanCastTo(mNOCCert.size()), err = CHIP_ERROR_INVALID_ARGUMENT); + info->mNOCCertLen = Encoding::LittleEndian::HostSwap16(static_cast(mNOCCert.size())); + memcpy(info->mNOCCert, mNOCCert.data(), mNOCCert.size()); } err = kvs->SyncSetKeyValue(key, info, sizeof(StorableFabricInfo)); @@ -120,7 +133,7 @@ CHIP_ERROR FabricInfo::FetchFromKVS(PersistentStorageDelegate * kvs) uint16_t infoSize = sizeof(StorableFabricInfo); uint16_t id; - uint16_t rootCertLen, opCertsLen; + uint16_t rootCertLen, icaCertLen, nocCertLen; size_t stringLength; NodeId nodeId; @@ -132,7 +145,8 @@ CHIP_ERROR FabricInfo::FetchFromKVS(PersistentStorageDelegate * kvs) id = Encoding::LittleEndian::HostSwap16(info->mFabric); mVendorId = Encoding::LittleEndian::HostSwap16(info->mVendorId); rootCertLen = Encoding::LittleEndian::HostSwap16(info->mRootCertLen); - opCertsLen = Encoding::LittleEndian::HostSwap16(info->mOperationalCertsLen); + icaCertLen = Encoding::LittleEndian::HostSwap16(info->mICACertLen); + nocCertLen = Encoding::LittleEndian::HostSwap16(info->mNOCCertLen); stringLength = strnlen(info->mFabricLabel, kFabricLabelMaxLengthInBytes); memcpy(mFabricLabel, info->mFabricLabel, stringLength); @@ -160,7 +174,8 @@ CHIP_ERROR FabricInfo::FetchFromKVS(PersistentStorageDelegate * kvs) // parts of the code. SuccessOrExit(err = GetCompressedId(mFabricId, nodeId, &mOperationalId)); - SuccessOrExit(err = SetOperationalCertsFromCertArray(ByteSpan(info->mOperationalCerts, opCertsLen))); + SuccessOrExit(err = SetICACert(ByteSpan(info->mICACert, icaCertLen))); + SuccessOrExit(err = SetNOCCert(ByteSpan(info->mNOCCert, nocCertLen))); exit: if (info != nullptr) @@ -175,7 +190,8 @@ CHIP_ERROR FabricInfo::GetCompressedId(FabricId fabricId, NodeId nodeId, PeerId ReturnErrorCodeIf(compressedPeerId == nullptr, CHIP_ERROR_INVALID_ARGUMENT); uint8_t compressedFabricIdBuf[sizeof(uint64_t)]; MutableByteSpan compressedFabricIdSpan(compressedFabricIdBuf); - ReturnErrorOnFailure(GenerateCompressedFabricId(mRootPubkey, fabricId, compressedFabricIdSpan)); + P256PublicKey rootPubkey(GetRootPubkey()); + ReturnErrorOnFailure(GenerateCompressedFabricId(rootPubkey, fabricId, compressedFabricIdSpan)); // Decode compressed fabric ID accounting for endianness, as GenerateCompressedFabricId() // returns a binary buffer and is agnostic of usage of the output as an integer type. @@ -226,129 +242,65 @@ CHIP_ERROR FabricInfo::SetEphemeralKey(const P256Keypair * key) return mOperationalKey->Deserialize(serialized); } -void FabricInfo::ReleaseRootCert() +void FabricInfo::ReleaseCert(MutableByteSpan & cert) { - if (mRootCert != nullptr) + if (cert.data() != nullptr) { - chip::Platform::MemoryFree(mRootCert); + chip::Platform::MemoryFree(cert.data()); } - mRootCertAllocatedLen = 0; - mRootCertLen = 0; - mRootCert = nullptr; + cert = MutableByteSpan(); } -CHIP_ERROR FabricInfo::SetRootCert(const ByteSpan & cert) +CHIP_ERROR FabricInfo::SetCert(MutableByteSpan & dstCert, const ByteSpan & srcCert) { - if (cert.size() == 0) + ReleaseCert(dstCert); + if (srcCert.data() == nullptr || srcCert.size() == 0) { - ReleaseRootCert(); return CHIP_NO_ERROR; } - VerifyOrReturnError(cert.size() <= kMaxCHIPCertLength, CHIP_ERROR_INVALID_ARGUMENT); - if (mRootCertLen != 0 && mRootCertAllocatedLen < cert.size()) - { - ReleaseRootCert(); - } - - if (mRootCert == nullptr) - { - mRootCert = static_cast(chip::Platform::MemoryAlloc(cert.size())); - } - VerifyOrReturnError(mRootCert != nullptr, CHIP_ERROR_NO_MEMORY); - VerifyOrReturnError(CanCastTo(cert.size()), CHIP_ERROR_INVALID_ARGUMENT); - mRootCertLen = static_cast(cert.size()); - - // Find root key ID - ChipCertificateData certData; - ReturnErrorOnFailure(DecodeChipCert(cert, certData)); - VerifyOrReturnError(certData.mAuthKeyId.size() <= sizeof(mRootKeyId), CHIP_ERROR_INVALID_ARGUMENT); - - memcpy(mRootKeyId, certData.mAuthKeyId.data(), certData.mAuthKeyId.size()); - mRootKeyIdLen = certData.mAuthKeyId.size(); - - mRootCertAllocatedLen = (mRootCertLen > mRootCertAllocatedLen) ? mRootCertLen : mRootCertAllocatedLen; - memcpy(mRootCert, cert.data(), mRootCertLen); - - mRootPubkey = P256PublicKey(certData.mPublicKey); - - return CHIP_NO_ERROR; -} - -void FabricInfo::ReleaseOperationalCerts() -{ - if (mOperationalCerts != nullptr) - { - chip::Platform::MemoryFree(mOperationalCerts); - } - mOperationalCertsLen = 0; - mOperationalCerts = nullptr; -} - -CHIP_ERROR FabricInfo::SetOperationalCertsFromCertArray(const ByteSpan & certArray) -{ - if (certArray.size() == 0) - { - ReleaseOperationalCerts(); - return CHIP_NO_ERROR; - } + VerifyOrReturnError(srcCert.size() <= kMaxCHIPCertLength, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(CanCastTo(srcCert.size()), CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnError(certArray.size() <= kMaxCHIPOpCertArrayLength, CHIP_ERROR_INVALID_ARGUMENT); - if (mOperationalCertsLen != 0) - { - ReleaseOperationalCerts(); - } + dstCert = MutableByteSpan(static_cast(chip::Platform::MemoryAlloc(srcCert.size())), srcCert.size()); + VerifyOrReturnError(dstCert.data() != nullptr, CHIP_ERROR_NO_MEMORY); - VerifyOrReturnError(CanCastTo(certArray.size()), CHIP_ERROR_INVALID_ARGUMENT); - if (mOperationalCerts == nullptr) - { - mOperationalCerts = static_cast(chip::Platform::MemoryAlloc(certArray.size())); - } - VerifyOrReturnError(mOperationalCerts != nullptr, CHIP_ERROR_NO_MEMORY); - mOperationalCertsLen = static_cast(certArray.size()); - memcpy(mOperationalCerts, certArray.data(), mOperationalCertsLen); + memcpy(dstCert.data(), srcCert.data(), srcCert.size()); return CHIP_NO_ERROR; } -CHIP_ERROR FabricInfo::VerifyCredentials(const ByteSpan & opCertArray, ValidationContext & context, PeerId & nocPeerId, - FabricId & fabricId, Crypto::P256PublicKey & nocPubkey) const +CHIP_ERROR FabricInfo::VerifyCredentials(const ByteSpan & noc, const ByteSpan & icac, ValidationContext & context, + PeerId & nocPeerId, FabricId & fabricId, Crypto::P256PublicKey & nocPubkey) const { // TODO - Optimize credentials verification logic // The certificate chain construction and verification is a compute and memory intensive operation. // It can be optimized by not loading certificate (i.e. rcac) that's local and implicitly trusted. // The FindValidCert() algorithm will need updates to achieve this refactor. - ByteSpan rcac(mRootCert, mRootCertLen); - ByteSpan noc, icac; - - ReturnErrorOnFailure(ExtractCertsFromCertArray(opCertArray, noc, icac)); - constexpr uint8_t kMaxNumCertsInOpCreds = 3; - uint8_t nocCertIndex = 1; ChipCertificateSet certificates; ReturnErrorOnFailure(certificates.Init(kMaxNumCertsInOpCreds)); - ReturnErrorOnFailure(certificates.LoadCert(rcac, BitFlags(CertDecodeFlags::kIsTrustAnchor))); + ReturnErrorOnFailure(certificates.LoadCert(mRootCert, BitFlags(CertDecodeFlags::kIsTrustAnchor))); if (!icac.empty()) { ReturnErrorOnFailure(certificates.LoadCert(icac, BitFlags(CertDecodeFlags::kGenerateTBSHash))); - nocCertIndex = 2; } ReturnErrorOnFailure(certificates.LoadCert(noc, BitFlags(CertDecodeFlags::kGenerateTBSHash))); - const ChipDN & nocSubjectDN = certificates.GetCertSet()[nocCertIndex].mSubjectDN; - const CertificateKeyId & nocSubjectKeyId = certificates.GetCertSet()[nocCertIndex].mSubjectKeyId; + const ChipDN & nocSubjectDN = certificates.GetLastCert()[0].mSubjectDN; + const CertificateKeyId & nocSubjectKeyId = certificates.GetLastCert()[0].mSubjectKeyId; const ChipCertificateData * resultCert = nullptr; - // FindValidCert() checks the certificate set constructed by loading noc, icac and rcac. - // It confirms that the certs link correctly (noc -> icac -> rcac), and have been correctly signed. + // FindValidCert() checks the certificate set constructed by loading noc, icac and mRootCert. + // It confirms that the certs link correctly (noc -> icac -> mRootCert), and have been correctly signed. ReturnErrorOnFailure(certificates.FindValidCert(nocSubjectDN, nocSubjectKeyId, context, &resultCert)); NodeId nodeId; - ReturnErrorOnFailure(ExtractNodeIdFabricIdFromOpCert(certificates.GetCertSet()[nocCertIndex], &nodeId, &fabricId)); + ReturnErrorOnFailure(ExtractNodeIdFabricIdFromOpCert(certificates.GetLastCert()[0], &nodeId, &fabricId)); if (!icac.empty()) { @@ -360,7 +312,7 @@ CHIP_ERROR FabricInfo::VerifyCredentials(const ByteSpan & opCertArray, Validatio } ReturnErrorOnFailure(GetCompressedId(fabricId, nodeId, &nocPeerId)); - nocPubkey = P256PublicKey(certificates.GetCertSet()[nocCertIndex].mPublicKey); + nocPubkey = P256PublicKey(certificates.GetLastCert()[0].mPublicKey); return CHIP_NO_ERROR; } @@ -373,11 +325,18 @@ CHIP_ERROR FabricInfo::GenerateDestinationID(const ByteSpan & ipk, const ByteSpa kSigmaParamRandomNumberSize + kP256_PublicKey_Length + sizeof(FabricId) + sizeof(NodeId); HMAC_sha hmac; uint8_t destinationMessage[kDestinationMessageLen]; + P256PublicKeySpan rootPubkeySpan = GetRootPubkey(); Encoding::LittleEndian::BufferWriter bbuf(destinationMessage, sizeof(destinationMessage)); bbuf.Put(random.data(), random.size()); - bbuf.Put(mRootPubkey.ConstBytes(), mRootPubkey.Length()); + // TODO: In the current implementation this check is required because in some cases the + // GenerateDestinationID() is called before mRootCert is initialized and GetRootPubkey() returns + // empty Span. + if (!rootPubkeySpan.empty()) + { + bbuf.Put(rootPubkeySpan.data(), rootPubkeySpan.size()); + } bbuf.Put64(mFabricId); bbuf.Put64(destNodeId); @@ -490,13 +449,14 @@ CHIP_ERROR FabricInfo::SetFabricInfo(FabricInfo & newFabric) validContext.mRequiredKeyPurposes.Set(KeyPurposeFlags::kServerAuth); SetEphemeralKey(newFabric.GetOperationalKey()); - SetRootCert(ByteSpan(newFabric.mRootCert, newFabric.mRootCertLen)); + SetRootCert(newFabric.mRootCert); ChipLogProgress(Discovery, "Verifying the received credentials"); - ReturnErrorOnFailure(VerifyCredentials(ByteSpan(newFabric.mOperationalCerts, newFabric.mOperationalCertsLen), validContext, - mOperationalId, mFabricId, pubkey)); + ReturnErrorOnFailure( + VerifyCredentials(newFabric.mNOCCert, newFabric.mICACert, validContext, mOperationalId, mFabricId, pubkey)); - SetOperationalCertsFromCertArray(ByteSpan(newFabric.mOperationalCerts, newFabric.mOperationalCertsLen)); + SetICACert(newFabric.mICACert); + SetNOCCert(newFabric.mNOCCert); SetVendorId(newFabric.GetVendorId()); SetFabricLabel(newFabric.GetFabricLabel()); ChipLogProgress(Discovery, "Added new fabric at index: %d, Initialized: %d", GetFabricIndex(), IsInitialized()); diff --git a/src/transport/FabricTable.h b/src/transport/FabricTable.h index f6016254d9acd8..8e3f96ec1e6b08 100644 --- a/src/transport/FabricTable.h +++ b/src/transport/FabricTable.h @@ -90,7 +90,6 @@ class DLL_EXPORT FabricInfo { chip::Platform::Delete(mOperationalKey); } - ReleaseRootCert(); ReleaseOperationalCerts(); } @@ -117,16 +116,12 @@ class DLL_EXPORT FabricInfo } CHIP_ERROR SetEphemeralKey(const Crypto::P256Keypair * key); - bool AreCredentialsAvailable() const - { - return (mRootCert != nullptr && mOperationalCerts != nullptr && mRootCertLen != 0 && mOperationalCertsLen != 0); - } - // TODO - Update these APIs to take ownership of the buffer, instead of copying // internally. // TODO - Optimize persistent storage of NOC and Root Cert in FabricInfo. - CHIP_ERROR SetOperationalCertsFromCertArray(const chip::ByteSpan & certArray); - CHIP_ERROR SetRootCert(const chip::ByteSpan & cert); + CHIP_ERROR SetRootCert(const chip::ByteSpan & cert) { return SetCert(mRootCert, cert); } + CHIP_ERROR SetICACert(const chip::ByteSpan & cert) { return SetCert(mICACert, cert); } + CHIP_ERROR SetNOCCert(const chip::ByteSpan & cert) { return SetCert(mNOCCert, cert); } const AccessControlList & GetACL() const { return mACL; } AccessControlList & GetACL() { return mACL; } @@ -140,35 +135,45 @@ class DLL_EXPORT FabricInfo CHIP_ERROR MatchDestinationID(const ByteSpan & destinationId, const ByteSpan & initiatorRandom, const ByteSpan * ipkList, size_t ipkListEntries); - CHIP_ERROR GetOperationalCredentials(MutableByteSpan & credentials) + // TODO - Refactor storing and loading of fabric info from persistent storage. + // The op cert array doesn't need to be in RAM except when it's being + // transmitted to peer node during CASE session setup. + CHIP_ERROR GetRootCert(ByteSpan & cert) { - // TODO - Refactor storing and loading of fabric info from persistent storage. - // The op cert array doesn't need to be in RAM except when it's being - // transmitted to peer node during CASE session setup. - ReturnErrorCodeIf(!AreCredentialsAvailable(), CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(credentials.size() < mOperationalCertsLen, CHIP_ERROR_BUFFER_TOO_SMALL); - memcpy(credentials.data(), mOperationalCerts, mOperationalCertsLen); - credentials.reduce_size(mOperationalCertsLen); + ReturnErrorCodeIf(mRootCert.empty(), CHIP_ERROR_INCORRECT_STATE); + cert = mRootCert; return CHIP_NO_ERROR; } - CHIP_ERROR GetRootCert(ByteSpan & cert) + CHIP_ERROR GetICACert(ByteSpan & cert) { - ReturnErrorCodeIf(!AreCredentialsAvailable(), CHIP_ERROR_INCORRECT_STATE); - cert = ByteSpan(mRootCert, mRootCertLen); + cert = mICACert; return CHIP_NO_ERROR; } - uint16_t GetOperationalCredentialsLength() { return mOperationalCertsLen; } + CHIP_ERROR GetNOCCert(ByteSpan & cert) + { + ReturnErrorCodeIf(mNOCCert.empty(), CHIP_ERROR_INCORRECT_STATE); + cert = mNOCCert; + return CHIP_NO_ERROR; + } - Credentials::CertificateKeyId GetTrustedRootId() + Credentials::CertificateKeyId GetTrustedRootId() const { - return mRootKeyIdLen == Credentials::kKeyIdentifierLength ? Credentials::CertificateKeyId(mRootKeyId) - : Credentials::CertificateKeyId(); + Credentials::CertificateKeyId skid; + Credentials::ExtractSKIDFromChipCert(mRootCert, skid); + return skid; } - CHIP_ERROR VerifyCredentials(const ByteSpan & noc, Credentials::ValidationContext & context, PeerId & nocPeerId, - FabricId & fabricId, Crypto::P256PublicKey & nocPubkey) const; + Credentials::P256PublicKeySpan GetRootPubkey() const + { + Credentials::P256PublicKeySpan publicKey; + Credentials::ExtractPublicKeyFromChipCert(mRootCert, publicKey); + return publicKey; + } + + CHIP_ERROR VerifyCredentials(const ByteSpan & noc, const ByteSpan & icac, Credentials::ValidationContext & context, + PeerId & nocPeerId, FabricId & fabricId, Crypto::P256PublicKey & nocPubkey) const; /** * Reset the state to a completely uninitialized status. @@ -184,14 +189,11 @@ class DLL_EXPORT FabricInfo chip::Platform::Delete(mOperationalKey); mOperationalKey = nullptr; } - ReleaseRootCert(); ReleaseOperationalCerts(); } CHIP_ERROR SetFabricInfo(FabricInfo & fabric); - const Crypto::P256PublicKey & GetRootPubkey() const { return mRootPubkey; } - /* Generate a compressed peer ID (containing compressed fabric ID) using provided fabric ID, node ID and root public key of the fabric. The generated compressed ID is returned via compressedPeerId output parameter */ @@ -208,22 +210,15 @@ class DLL_EXPORT FabricInfo AccessControlList mACL; - uint8_t mRootKeyId[Credentials::kKeyIdentifierLength]; - uint16_t mRootKeyIdLen = 0; - #ifdef ENABLE_HSM_CASE_OPS_KEY Crypto::P256KeypairHSM * mOperationalKey = nullptr; #else Crypto::P256Keypair * mOperationalKey = nullptr; #endif - Crypto::P256PublicKey mRootPubkey; - - uint8_t * mRootCert = nullptr; - uint16_t mRootCertLen = 0; - uint16_t mRootCertAllocatedLen = 0; - uint8_t * mOperationalCerts = nullptr; - uint16_t mOperationalCertsLen = 0; + MutableByteSpan mRootCert; + MutableByteSpan mICACert; + MutableByteSpan mNOCCert; FabricId mFabricId = 0; @@ -235,8 +230,15 @@ class DLL_EXPORT FabricInfo CHIP_ERROR FetchFromKVS(PersistentStorageDelegate * kvs); static CHIP_ERROR DeleteFromKVS(PersistentStorageDelegate * kvs, FabricIndex id); - void ReleaseOperationalCerts(); - void ReleaseRootCert(); + void ReleaseCert(MutableByteSpan & cert); + void ReleaseOperationalCerts() + { + ReleaseCert(mRootCert); + ReleaseCert(mICACert); + ReleaseCert(mNOCCert); + } + + CHIP_ERROR SetCert(MutableByteSpan & dstCert, const ByteSpan & srcCert); struct StorableFabricInfo { @@ -245,12 +247,14 @@ class DLL_EXPORT FabricInfo uint64_t mFabricId; /* This field is serialized in LittleEndian byte order */ uint16_t mVendorId; /* This field is serialized in LittleEndian byte order */ - uint16_t mRootCertLen; /* This field is serialized in LittleEndian byte order */ - uint16_t mOperationalCertsLen; /* This field is serialized in LittleEndian byte order */ + uint16_t mRootCertLen; /* This field is serialized in LittleEndian byte order */ + uint16_t mICACertLen; /* This field is serialized in LittleEndian byte order */ + uint16_t mNOCCertLen; /* This field is serialized in LittleEndian byte order */ Crypto::P256SerializedKeypair mOperationalKey; uint8_t mRootCert[Credentials::kMaxCHIPCertLength]; - uint8_t mOperationalCerts[Credentials::kMaxCHIPOpCertArrayLength]; + uint8_t mICACert[Credentials::kMaxCHIPCertLength]; + uint8_t mNOCCert[Credentials::kMaxCHIPCertLength]; char mFabricLabel[kFabricLabelMaxLengthInBytes + 1] = { '\0' }; }; }; diff --git a/src/transport/tests/TestFabricTable.cpp b/src/transport/tests/TestFabricTable.cpp index d774006570ef81..3c31d01ca169e9 100644 --- a/src/transport/tests/TestFabricTable.cpp +++ b/src/transport/tests/TestFabricTable.cpp @@ -54,7 +54,7 @@ void TestGetCompressedFabricID(nlTestSuite * inSuite, void * inContext) { FabricInfo fabricInfo; - fabricInfo.SetRootCert(ByteSpan(sTestRootCert)); + NL_TEST_ASSERT(inSuite, fabricInfo.SetRootCert(ByteSpan(sTestRootCert)) == CHIP_NO_ERROR); PeerId compressedId; NL_TEST_ASSERT(inSuite, fabricInfo.GetCompressedId(1234, 4321, &compressedId) == CHIP_NO_ERROR); diff --git a/zzz_generated/all-clusters-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/all-clusters-app/zap-generated/IMClusterCommandHandler.cpp index f70af5b5135d13..3f6af6541beda0 100644 --- a/zzz_generated/all-clusters-app/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/all-clusters-app/zap-generated/IMClusterCommandHandler.cpp @@ -5866,12 +5866,13 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (aCommandId) { case Clusters::OperationalCredentials::Commands::Ids::AddNOC: { - expectArgumentCount = 4; - chip::ByteSpan NOCArray; + expectArgumentCount = 5; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; chip::ByteSpan IPKValue; chip::NodeId CaseAdminNode; uint16_t AdminVendorId; - bool argExists[4]; + bool argExists[5]; memset(argExists, 0, sizeof argExists); @@ -5884,7 +5885,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 4) + if (currentDecodeTagId < 5) { if (argExists[currentDecodeTagId]) { @@ -5901,15 +5902,18 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); break; case 1: - TLVUnpackError = aDataTlv.Get(IPKValue); + TLVUnpackError = aDataTlv.Get(ICACValue); break; case 2: - TLVUnpackError = aDataTlv.Get(CaseAdminNode); + TLVUnpackError = aDataTlv.Get(IPKValue); break; case 3: + TLVUnpackError = aDataTlv.Get(CaseAdminNode); + break; + case 4: TLVUnpackError = aDataTlv.Get(AdminVendorId); break; default: @@ -5929,10 +5933,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCArray, IPKValue, - CaseAdminNode, AdminVendorId); + wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue, + IPKValue, CaseAdminNode, AdminVendorId); } break; } @@ -6231,9 +6235,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, break; } case Clusters::OperationalCredentials::Commands::Ids::UpdateNOC: { - expectArgumentCount = 1; - chip::ByteSpan NOCArray; - bool argExists[1]; + expectArgumentCount = 2; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; + bool argExists[2]; memset(argExists, 0, sizeof argExists); @@ -6246,7 +6251,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 1) + if (currentDecodeTagId < 2) { if (argExists[currentDecodeTagId]) { @@ -6263,7 +6268,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); + break; + case 1: + TLVUnpackError = aDataTlv.Get(ICACValue); break; default: // Unsupported tag, ignore it. @@ -6282,9 +6290,9 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCArray); + wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue); } break; } diff --git a/zzz_generated/app-common/app-common/zap-generated/callback.h b/zzz_generated/app-common/app-common/zap-generated/callback.h index e1081bf7605fa7..842f7d2063f52c 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -15765,13 +15765,13 @@ bool emberAfOperationalCredentialsClusterOpCSRResponseCallback(chip::EndpointId * @brief Cluster AddNOC Command callback (from client) */ bool emberAfOperationalCredentialsClusterAddNOCCallback(chip::EndpointId endpoint, chip::app::CommandHandler * commandObj, - chip::ByteSpan NOCArray, chip::ByteSpan IPKValue, + chip::ByteSpan NOCValue, chip::ByteSpan ICACValue, chip::ByteSpan IPKValue, chip::NodeId CaseAdminNode, uint16_t AdminVendorId); /** * @brief Cluster UpdateNOC Command callback (from client) */ bool emberAfOperationalCredentialsClusterUpdateNOCCallback(chip::EndpointId endpoint, chip::app::CommandHandler * commandObj, - chip::ByteSpan NOCArray); + chip::ByteSpan NOCValue, chip::ByteSpan ICACValue); /** * @brief Cluster NOCResponse Command callback (from server) */ diff --git a/zzz_generated/app-common/app-common/zap-generated/client-command-macro.h b/zzz_generated/app-common/app-common/zap-generated/client-command-macro.h index d7ee86f4a272b2..685219a6e13dc5 100644 --- a/zzz_generated/app-common/app-common/zap-generated/client-command-macro.h +++ b/zzz_generated/app-common/app-common/zap-generated/client-command-macro.h @@ -2270,26 +2270,29 @@ /** @brief Command description for AddNOC * * Command: AddNOC - * @param NOCArray OCTET_STRING + * @param NOCValue OCTET_STRING + * @param ICACValue OCTET_STRING * @param IPKValue OCTET_STRING * @param CaseAdminNode NODE_ID * @param AdminVendorId INT16U */ #define emberAfFillCommandOperational \ - CredentialsClusterAddNOC(NOCArray, IPKValue, CaseAdminNode, AdminVendorId) \ + CredentialsClusterAddNOC(NOCValue, ICACValue, IPKValue, CaseAdminNode, AdminVendorId) \ emberAfFillExternalBuffer(mask, \ \ - ZCL_ADD_NOC_COMMAND_ID, "uuuu", NOCArray, IPKValue, CaseAdminNode, AdminVendorId); + ZCL_ADD_NOC_COMMAND_ID, "uuuuu", NOCValue, ICACValue, IPKValue, CaseAdminNode, AdminVendorId); /** @brief Command description for UpdateNOC * * Command: UpdateNOC - * @param NOCArray OCTET_STRING + * @param NOCValue OCTET_STRING + * @param ICACValue OCTET_STRING */ #define emberAfFillCommandOperational \ - CredentialsClusterUpdateNOC(NOCArray) emberAfFillExternalBuffer(mask, \ + CredentialsClusterUpdateNOC(NOCValue, ICACValue) \ + emberAfFillExternalBuffer(mask, \ \ - ZCL_UPDATE_NOC_COMMAND_ID, "u", NOCArray); + ZCL_UPDATE_NOC_COMMAND_ID, "uu", NOCValue, ICACValue); /** @brief Command description for NOCResponse * diff --git a/zzz_generated/bridge-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/bridge-app/zap-generated/IMClusterCommandHandler.cpp index 8b4b517d9219f4..06a34d94c3b1e7 100644 --- a/zzz_generated/bridge-app/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/bridge-app/zap-generated/IMClusterCommandHandler.cpp @@ -1790,12 +1790,13 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (aCommandId) { case Clusters::OperationalCredentials::Commands::Ids::AddNOC: { - expectArgumentCount = 4; - chip::ByteSpan NOCArray; + expectArgumentCount = 5; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; chip::ByteSpan IPKValue; chip::NodeId CaseAdminNode; uint16_t AdminVendorId; - bool argExists[4]; + bool argExists[5]; memset(argExists, 0, sizeof argExists); @@ -1808,7 +1809,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 4) + if (currentDecodeTagId < 5) { if (argExists[currentDecodeTagId]) { @@ -1825,15 +1826,18 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); break; case 1: - TLVUnpackError = aDataTlv.Get(IPKValue); + TLVUnpackError = aDataTlv.Get(ICACValue); break; case 2: - TLVUnpackError = aDataTlv.Get(CaseAdminNode); + TLVUnpackError = aDataTlv.Get(IPKValue); break; case 3: + TLVUnpackError = aDataTlv.Get(CaseAdminNode); + break; + case 4: TLVUnpackError = aDataTlv.Get(AdminVendorId); break; default: @@ -1853,10 +1857,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCArray, IPKValue, - CaseAdminNode, AdminVendorId); + wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue, + IPKValue, CaseAdminNode, AdminVendorId); } break; } @@ -2155,9 +2159,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, break; } case Clusters::OperationalCredentials::Commands::Ids::UpdateNOC: { - expectArgumentCount = 1; - chip::ByteSpan NOCArray; - bool argExists[1]; + expectArgumentCount = 2; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; + bool argExists[2]; memset(argExists, 0, sizeof argExists); @@ -2170,7 +2175,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 1) + if (currentDecodeTagId < 2) { if (argExists[currentDecodeTagId]) { @@ -2187,7 +2192,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); + break; + case 1: + TLVUnpackError = aDataTlv.Get(ICACValue); break; default: // Unsupported tag, ignore it. @@ -2206,9 +2214,9 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCArray); + wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue); } break; } diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 58611b7a871db9..7fe2f1f5cfd38c 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -15004,7 +15004,8 @@ class OperationalCredentialsAddNOC : public ModelCommand public: OperationalCredentialsAddNOC() : ModelCommand("add-noc") { - AddArgument("NOCArray", &mNOCArray); + AddArgument("NOCValue", &mNOCValue); + AddArgument("ICACValue", &mICACValue); AddArgument("IPKValue", &mIPKValue); AddArgument("CaseAdminNode", 0, UINT64_MAX, &mCaseAdminNode); AddArgument("AdminVendorId", 0, UINT16_MAX, &mAdminVendorId); @@ -15022,8 +15023,8 @@ class OperationalCredentialsAddNOC : public ModelCommand chip::Controller::OperationalCredentialsCluster cluster; cluster.Associate(device, endpointId); - return cluster.AddNOC(onSuccessCallback->Cancel(), onFailureCallback->Cancel(), mNOCArray, mIPKValue, mCaseAdminNode, - mAdminVendorId); + return cluster.AddNOC(onSuccessCallback->Cancel(), onFailureCallback->Cancel(), mNOCValue, mICACValue, mIPKValue, + mCaseAdminNode, mAdminVendorId); } private: @@ -15032,7 +15033,8 @@ class OperationalCredentialsAddNOC : public ModelCommand this); chip::Callback::Callback * onFailureCallback = new chip::Callback::Callback(OnDefaultFailureResponse, this); - chip::ByteSpan mNOCArray; + chip::ByteSpan mNOCValue; + chip::ByteSpan mICACValue; chip::ByteSpan mIPKValue; chip::NodeId mCaseAdminNode; uint16_t mAdminVendorId; @@ -15221,7 +15223,8 @@ class OperationalCredentialsUpdateNOC : public ModelCommand public: OperationalCredentialsUpdateNOC() : ModelCommand("update-noc") { - AddArgument("NOCArray", &mNOCArray); + AddArgument("NOCValue", &mNOCValue); + AddArgument("ICACValue", &mICACValue); ModelCommand::AddArguments(); } ~OperationalCredentialsUpdateNOC() @@ -15236,7 +15239,7 @@ class OperationalCredentialsUpdateNOC : public ModelCommand chip::Controller::OperationalCredentialsCluster cluster; cluster.Associate(device, endpointId); - return cluster.UpdateNOC(onSuccessCallback->Cancel(), onFailureCallback->Cancel(), mNOCArray); + return cluster.UpdateNOC(onSuccessCallback->Cancel(), onFailureCallback->Cancel(), mNOCValue, mICACValue); } private: @@ -15245,7 +15248,8 @@ class OperationalCredentialsUpdateNOC : public ModelCommand this); chip::Callback::Callback * onFailureCallback = new chip::Callback::Callback(OnDefaultFailureResponse, this); - chip::ByteSpan mNOCArray; + chip::ByteSpan mNOCValue; + chip::ByteSpan mICACValue; }; /* diff --git a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp index a9ac7d2926b5b3..705825ecfe65b4 100644 --- a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp +++ b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp @@ -8415,8 +8415,8 @@ CHIP_ERROR OnOffSwitchConfigurationCluster::ReadAttributeClusterRevision(Callbac // OperationalCredentials Cluster Commands CHIP_ERROR OperationalCredentialsCluster::AddNOC(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, - chip::ByteSpan nOCArray, chip::ByteSpan iPKValue, chip::NodeId caseAdminNode, - uint16_t adminVendorId) + chip::ByteSpan nOCValue, chip::ByteSpan iCACValue, chip::ByteSpan iPKValue, + chip::NodeId caseAdminNode, uint16_t adminVendorId) { CHIP_ERROR err = CHIP_NO_ERROR; app::CommandSender * sender = nullptr; @@ -8437,8 +8437,10 @@ CHIP_ERROR OperationalCredentialsCluster::AddNOC(Callback::Cancelable * onSucces SuccessOrExit(err = sender->PrepareCommand(cmdParams)); VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE); - // nOCArray: octetString - SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), nOCArray)); + // nOCValue: octetString + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), nOCValue)); + // iCACValue: octetString + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), iCACValue)); // iPKValue: octetString SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), iPKValue)); // caseAdminNode: nodeId @@ -8675,7 +8677,8 @@ CHIP_ERROR OperationalCredentialsCluster::UpdateFabricLabel(Callback::Cancelable } CHIP_ERROR OperationalCredentialsCluster::UpdateNOC(Callback::Cancelable * onSuccessCallback, - Callback::Cancelable * onFailureCallback, chip::ByteSpan nOCArray) + Callback::Cancelable * onFailureCallback, chip::ByteSpan nOCValue, + chip::ByteSpan iCACValue) { CHIP_ERROR err = CHIP_NO_ERROR; app::CommandSender * sender = nullptr; @@ -8696,8 +8699,10 @@ CHIP_ERROR OperationalCredentialsCluster::UpdateNOC(Callback::Cancelable * onSuc SuccessOrExit(err = sender->PrepareCommand(cmdParams)); VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE); - // nOCArray: octetString - SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), nOCArray)); + // nOCValue: octetString + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), nOCValue)); + // iCACValue: octetString + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), iCACValue)); SuccessOrExit(err = sender->FinishCommand()); diff --git a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h index 92b41039b5f6f5..4a0248a880d69e 100644 --- a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h +++ b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h @@ -985,8 +985,8 @@ class DLL_EXPORT OperationalCredentialsCluster : public ClusterBase ~OperationalCredentialsCluster() {} // Cluster Commands - CHIP_ERROR AddNOC(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, chip::ByteSpan nOCArray, - chip::ByteSpan iPKValue, chip::NodeId caseAdminNode, uint16_t adminVendorId); + CHIP_ERROR AddNOC(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, chip::ByteSpan nOCValue, + chip::ByteSpan iCACValue, chip::ByteSpan iPKValue, chip::NodeId caseAdminNode, uint16_t adminVendorId); CHIP_ERROR AddTrustedRootCertificate(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, chip::ByteSpan rootCertificate); CHIP_ERROR OpCSRRequest(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, @@ -998,7 +998,7 @@ class DLL_EXPORT OperationalCredentialsCluster : public ClusterBase CHIP_ERROR UpdateFabricLabel(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, chip::ByteSpan label); CHIP_ERROR UpdateNOC(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, - chip::ByteSpan nOCArray); + chip::ByteSpan nOCValue, chip::ByteSpan iCACValue); // Cluster Attributes CHIP_ERROR DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); diff --git a/zzz_generated/lighting-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/lighting-app/zap-generated/IMClusterCommandHandler.cpp index 85daa2b646df31..d28a8cbabff6d7 100644 --- a/zzz_generated/lighting-app/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/lighting-app/zap-generated/IMClusterCommandHandler.cpp @@ -3297,12 +3297,13 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (aCommandId) { case Clusters::OperationalCredentials::Commands::Ids::AddNOC: { - expectArgumentCount = 4; - chip::ByteSpan NOCArray; + expectArgumentCount = 5; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; chip::ByteSpan IPKValue; chip::NodeId CaseAdminNode; uint16_t AdminVendorId; - bool argExists[4]; + bool argExists[5]; memset(argExists, 0, sizeof argExists); @@ -3315,7 +3316,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 4) + if (currentDecodeTagId < 5) { if (argExists[currentDecodeTagId]) { @@ -3332,15 +3333,18 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); break; case 1: - TLVUnpackError = aDataTlv.Get(IPKValue); + TLVUnpackError = aDataTlv.Get(ICACValue); break; case 2: - TLVUnpackError = aDataTlv.Get(CaseAdminNode); + TLVUnpackError = aDataTlv.Get(IPKValue); break; case 3: + TLVUnpackError = aDataTlv.Get(CaseAdminNode); + break; + case 4: TLVUnpackError = aDataTlv.Get(AdminVendorId); break; default: @@ -3360,10 +3364,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCArray, IPKValue, - CaseAdminNode, AdminVendorId); + wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue, + IPKValue, CaseAdminNode, AdminVendorId); } break; } @@ -3662,9 +3666,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, break; } case Clusters::OperationalCredentials::Commands::Ids::UpdateNOC: { - expectArgumentCount = 1; - chip::ByteSpan NOCArray; - bool argExists[1]; + expectArgumentCount = 2; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; + bool argExists[2]; memset(argExists, 0, sizeof argExists); @@ -3677,7 +3682,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 1) + if (currentDecodeTagId < 2) { if (argExists[currentDecodeTagId]) { @@ -3694,7 +3699,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); + break; + case 1: + TLVUnpackError = aDataTlv.Get(ICACValue); break; default: // Unsupported tag, ignore it. @@ -3713,9 +3721,9 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCArray); + wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue); } break; } diff --git a/zzz_generated/lock-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/lock-app/zap-generated/IMClusterCommandHandler.cpp index d4b89cc153a668..0860c66164aca4 100644 --- a/zzz_generated/lock-app/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/lock-app/zap-generated/IMClusterCommandHandler.cpp @@ -1269,12 +1269,13 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (aCommandId) { case Clusters::OperationalCredentials::Commands::Ids::AddNOC: { - expectArgumentCount = 4; - chip::ByteSpan NOCArray; + expectArgumentCount = 5; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; chip::ByteSpan IPKValue; chip::NodeId CaseAdminNode; uint16_t AdminVendorId; - bool argExists[4]; + bool argExists[5]; memset(argExists, 0, sizeof argExists); @@ -1287,7 +1288,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 4) + if (currentDecodeTagId < 5) { if (argExists[currentDecodeTagId]) { @@ -1304,15 +1305,18 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); break; case 1: - TLVUnpackError = aDataTlv.Get(IPKValue); + TLVUnpackError = aDataTlv.Get(ICACValue); break; case 2: - TLVUnpackError = aDataTlv.Get(CaseAdminNode); + TLVUnpackError = aDataTlv.Get(IPKValue); break; case 3: + TLVUnpackError = aDataTlv.Get(CaseAdminNode); + break; + case 4: TLVUnpackError = aDataTlv.Get(AdminVendorId); break; default: @@ -1332,10 +1336,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCArray, IPKValue, - CaseAdminNode, AdminVendorId); + wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue, + IPKValue, CaseAdminNode, AdminVendorId); } break; } @@ -1634,9 +1638,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, break; } case Clusters::OperationalCredentials::Commands::Ids::UpdateNOC: { - expectArgumentCount = 1; - chip::ByteSpan NOCArray; - bool argExists[1]; + expectArgumentCount = 2; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; + bool argExists[2]; memset(argExists, 0, sizeof argExists); @@ -1649,7 +1654,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 1) + if (currentDecodeTagId < 2) { if (argExists[currentDecodeTagId]) { @@ -1666,7 +1671,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); + break; + case 1: + TLVUnpackError = aDataTlv.Get(ICACValue); break; default: // Unsupported tag, ignore it. @@ -1685,9 +1693,9 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCArray); + wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue); } break; } diff --git a/zzz_generated/ota-provider-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/ota-provider-app/zap-generated/IMClusterCommandHandler.cpp index 9faab62cc15bc7..86537fb60c9bc6 100644 --- a/zzz_generated/ota-provider-app/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/ota-provider-app/zap-generated/IMClusterCommandHandler.cpp @@ -334,12 +334,13 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (aCommandId) { case Clusters::OperationalCredentials::Commands::Ids::AddNOC: { - expectArgumentCount = 4; - chip::ByteSpan NOCArray; + expectArgumentCount = 5; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; chip::ByteSpan IPKValue; chip::NodeId CaseAdminNode; uint16_t AdminVendorId; - bool argExists[4]; + bool argExists[5]; memset(argExists, 0, sizeof argExists); @@ -352,7 +353,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 4) + if (currentDecodeTagId < 5) { if (argExists[currentDecodeTagId]) { @@ -369,15 +370,18 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); break; case 1: - TLVUnpackError = aDataTlv.Get(IPKValue); + TLVUnpackError = aDataTlv.Get(ICACValue); break; case 2: - TLVUnpackError = aDataTlv.Get(CaseAdminNode); + TLVUnpackError = aDataTlv.Get(IPKValue); break; case 3: + TLVUnpackError = aDataTlv.Get(CaseAdminNode); + break; + case 4: TLVUnpackError = aDataTlv.Get(AdminVendorId); break; default: @@ -397,10 +401,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCArray, IPKValue, - CaseAdminNode, AdminVendorId); + wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue, + IPKValue, CaseAdminNode, AdminVendorId); } break; } diff --git a/zzz_generated/pump-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/pump-app/zap-generated/IMClusterCommandHandler.cpp index 1f943c431c50db..d70ad161e53b4a 100644 --- a/zzz_generated/pump-app/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/pump-app/zap-generated/IMClusterCommandHandler.cpp @@ -1740,12 +1740,13 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (aCommandId) { case Clusters::OperationalCredentials::Commands::Ids::AddNOC: { - expectArgumentCount = 4; - chip::ByteSpan NOCArray; + expectArgumentCount = 5; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; chip::ByteSpan IPKValue; chip::NodeId CaseAdminNode; uint16_t AdminVendorId; - bool argExists[4]; + bool argExists[5]; memset(argExists, 0, sizeof argExists); @@ -1758,7 +1759,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 4) + if (currentDecodeTagId < 5) { if (argExists[currentDecodeTagId]) { @@ -1775,15 +1776,18 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); break; case 1: - TLVUnpackError = aDataTlv.Get(IPKValue); + TLVUnpackError = aDataTlv.Get(ICACValue); break; case 2: - TLVUnpackError = aDataTlv.Get(CaseAdminNode); + TLVUnpackError = aDataTlv.Get(IPKValue); break; case 3: + TLVUnpackError = aDataTlv.Get(CaseAdminNode); + break; + case 4: TLVUnpackError = aDataTlv.Get(AdminVendorId); break; default: @@ -1803,10 +1807,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCArray, IPKValue, - CaseAdminNode, AdminVendorId); + wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue, + IPKValue, CaseAdminNode, AdminVendorId); } break; } @@ -2105,9 +2109,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, break; } case Clusters::OperationalCredentials::Commands::Ids::UpdateNOC: { - expectArgumentCount = 1; - chip::ByteSpan NOCArray; - bool argExists[1]; + expectArgumentCount = 2; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; + bool argExists[2]; memset(argExists, 0, sizeof argExists); @@ -2120,7 +2125,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 1) + if (currentDecodeTagId < 2) { if (argExists[currentDecodeTagId]) { @@ -2137,7 +2142,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); + break; + case 1: + TLVUnpackError = aDataTlv.Get(ICACValue); break; default: // Unsupported tag, ignore it. @@ -2156,9 +2164,9 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCArray); + wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue); } break; } diff --git a/zzz_generated/pump-controller-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/pump-controller-app/zap-generated/IMClusterCommandHandler.cpp index 7cb4fc4f3f092d..1dc576b647371e 100644 --- a/zzz_generated/pump-controller-app/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/pump-controller-app/zap-generated/IMClusterCommandHandler.cpp @@ -1218,12 +1218,13 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (aCommandId) { case Clusters::OperationalCredentials::Commands::Ids::AddNOC: { - expectArgumentCount = 4; - chip::ByteSpan NOCArray; + expectArgumentCount = 5; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; chip::ByteSpan IPKValue; chip::NodeId CaseAdminNode; uint16_t AdminVendorId; - bool argExists[4]; + bool argExists[5]; memset(argExists, 0, sizeof argExists); @@ -1236,7 +1237,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 4) + if (currentDecodeTagId < 5) { if (argExists[currentDecodeTagId]) { @@ -1253,15 +1254,18 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); break; case 1: - TLVUnpackError = aDataTlv.Get(IPKValue); + TLVUnpackError = aDataTlv.Get(ICACValue); break; case 2: - TLVUnpackError = aDataTlv.Get(CaseAdminNode); + TLVUnpackError = aDataTlv.Get(IPKValue); break; case 3: + TLVUnpackError = aDataTlv.Get(CaseAdminNode); + break; + case 4: TLVUnpackError = aDataTlv.Get(AdminVendorId); break; default: @@ -1281,10 +1285,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCArray, IPKValue, - CaseAdminNode, AdminVendorId); + wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue, + IPKValue, CaseAdminNode, AdminVendorId); } break; } @@ -1583,9 +1587,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, break; } case Clusters::OperationalCredentials::Commands::Ids::UpdateNOC: { - expectArgumentCount = 1; - chip::ByteSpan NOCArray; - bool argExists[1]; + expectArgumentCount = 2; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; + bool argExists[2]; memset(argExists, 0, sizeof argExists); @@ -1598,7 +1603,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 1) + if (currentDecodeTagId < 2) { if (argExists[currentDecodeTagId]) { @@ -1615,7 +1620,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); + break; + case 1: + TLVUnpackError = aDataTlv.Get(ICACValue); break; default: // Unsupported tag, ignore it. @@ -1634,9 +1642,9 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCArray); + wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue); } break; } diff --git a/zzz_generated/temperature-measurement-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/temperature-measurement-app/zap-generated/IMClusterCommandHandler.cpp index 712044832069fa..63a2c515ad7200 100644 --- a/zzz_generated/temperature-measurement-app/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/temperature-measurement-app/zap-generated/IMClusterCommandHandler.cpp @@ -1075,12 +1075,13 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (aCommandId) { case Clusters::OperationalCredentials::Commands::Ids::AddNOC: { - expectArgumentCount = 4; - chip::ByteSpan NOCArray; + expectArgumentCount = 5; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; chip::ByteSpan IPKValue; chip::NodeId CaseAdminNode; uint16_t AdminVendorId; - bool argExists[4]; + bool argExists[5]; memset(argExists, 0, sizeof argExists); @@ -1093,7 +1094,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 4) + if (currentDecodeTagId < 5) { if (argExists[currentDecodeTagId]) { @@ -1110,15 +1111,18 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); break; case 1: - TLVUnpackError = aDataTlv.Get(IPKValue); + TLVUnpackError = aDataTlv.Get(ICACValue); break; case 2: - TLVUnpackError = aDataTlv.Get(CaseAdminNode); + TLVUnpackError = aDataTlv.Get(IPKValue); break; case 3: + TLVUnpackError = aDataTlv.Get(CaseAdminNode); + break; + case 4: TLVUnpackError = aDataTlv.Get(AdminVendorId); break; default: @@ -1138,10 +1142,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCArray, IPKValue, - CaseAdminNode, AdminVendorId); + wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue, + IPKValue, CaseAdminNode, AdminVendorId); } break; } @@ -1440,9 +1444,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, break; } case Clusters::OperationalCredentials::Commands::Ids::UpdateNOC: { - expectArgumentCount = 1; - chip::ByteSpan NOCArray; - bool argExists[1]; + expectArgumentCount = 2; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; + bool argExists[2]; memset(argExists, 0, sizeof argExists); @@ -1455,7 +1460,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 1) + if (currentDecodeTagId < 2) { if (argExists[currentDecodeTagId]) { @@ -1472,7 +1477,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); + break; + case 1: + TLVUnpackError = aDataTlv.Get(ICACValue); break; default: // Unsupported tag, ignore it. @@ -1491,9 +1499,9 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCArray); + wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue); } break; } diff --git a/zzz_generated/thermostat/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/thermostat/zap-generated/IMClusterCommandHandler.cpp index b4623de679826a..3cde7e250502d3 100644 --- a/zzz_generated/thermostat/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/thermostat/zap-generated/IMClusterCommandHandler.cpp @@ -5436,12 +5436,13 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (aCommandId) { case Clusters::OperationalCredentials::Commands::Ids::AddNOC: { - expectArgumentCount = 4; - chip::ByteSpan NOCArray; + expectArgumentCount = 5; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; chip::ByteSpan IPKValue; chip::NodeId CaseAdminNode; uint16_t AdminVendorId; - bool argExists[4]; + bool argExists[5]; memset(argExists, 0, sizeof argExists); @@ -5454,7 +5455,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 4) + if (currentDecodeTagId < 5) { if (argExists[currentDecodeTagId]) { @@ -5471,15 +5472,18 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); break; case 1: - TLVUnpackError = aDataTlv.Get(IPKValue); + TLVUnpackError = aDataTlv.Get(ICACValue); break; case 2: - TLVUnpackError = aDataTlv.Get(CaseAdminNode); + TLVUnpackError = aDataTlv.Get(IPKValue); break; case 3: + TLVUnpackError = aDataTlv.Get(CaseAdminNode); + break; + case 4: TLVUnpackError = aDataTlv.Get(AdminVendorId); break; default: @@ -5499,10 +5503,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCArray, IPKValue, - CaseAdminNode, AdminVendorId); + wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue, + IPKValue, CaseAdminNode, AdminVendorId); } break; } @@ -5801,9 +5805,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, break; } case Clusters::OperationalCredentials::Commands::Ids::UpdateNOC: { - expectArgumentCount = 1; - chip::ByteSpan NOCArray; - bool argExists[1]; + expectArgumentCount = 2; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; + bool argExists[2]; memset(argExists, 0, sizeof argExists); @@ -5816,7 +5821,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 1) + if (currentDecodeTagId < 2) { if (argExists[currentDecodeTagId]) { @@ -5833,7 +5838,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); + break; + case 1: + TLVUnpackError = aDataTlv.Get(ICACValue); break; default: // Unsupported tag, ignore it. @@ -5852,9 +5860,9 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCArray); + wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue); } break; } diff --git a/zzz_generated/tv-app/zap-generated/CHIPClusters.cpp b/zzz_generated/tv-app/zap-generated/CHIPClusters.cpp index a4757924ee49a0..de8cd91a75f9a6 100644 --- a/zzz_generated/tv-app/zap-generated/CHIPClusters.cpp +++ b/zzz_generated/tv-app/zap-generated/CHIPClusters.cpp @@ -531,8 +531,8 @@ CHIP_ERROR NetworkCommissioningCluster::ReadAttributeClusterRevision(Callback::C // OperationalCredentials Cluster Commands CHIP_ERROR OperationalCredentialsCluster::AddNOC(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, - chip::ByteSpan nOCArray, chip::ByteSpan iPKValue, chip::NodeId caseAdminNode, - uint16_t adminVendorId) + chip::ByteSpan nOCValue, chip::ByteSpan iCACValue, chip::ByteSpan iPKValue, + chip::NodeId caseAdminNode, uint16_t adminVendorId) { CHIP_ERROR err = CHIP_NO_ERROR; app::CommandSender * sender = nullptr; @@ -553,8 +553,10 @@ CHIP_ERROR OperationalCredentialsCluster::AddNOC(Callback::Cancelable * onSucces SuccessOrExit(err = sender->PrepareCommand(cmdParams)); VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE); - // nOCArray: octetString - SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), nOCArray)); + // nOCValue: octetString + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), nOCValue)); + // iCACValue: octetString + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), iCACValue)); // iPKValue: octetString SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), iPKValue)); // caseAdminNode: nodeId diff --git a/zzz_generated/tv-app/zap-generated/CHIPClusters.h b/zzz_generated/tv-app/zap-generated/CHIPClusters.h index e77c4d8d05f7ee..90128b8bfca1fe 100644 --- a/zzz_generated/tv-app/zap-generated/CHIPClusters.h +++ b/zzz_generated/tv-app/zap-generated/CHIPClusters.h @@ -87,8 +87,8 @@ class DLL_EXPORT OperationalCredentialsCluster : public ClusterBase ~OperationalCredentialsCluster() {} // Cluster Commands - CHIP_ERROR AddNOC(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, chip::ByteSpan nOCArray, - chip::ByteSpan iPKValue, chip::NodeId caseAdminNode, uint16_t adminVendorId); + CHIP_ERROR AddNOC(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, chip::ByteSpan nOCValue, + chip::ByteSpan iCACValue, chip::ByteSpan iPKValue, chip::NodeId caseAdminNode, uint16_t adminVendorId); CHIP_ERROR AddTrustedRootCertificate(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, chip::ByteSpan rootCertificate); CHIP_ERROR OpCSRRequest(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, diff --git a/zzz_generated/tv-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/tv-app/zap-generated/IMClusterCommandHandler.cpp index aedad853574fe1..a8b22b3abfd6e0 100644 --- a/zzz_generated/tv-app/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/tv-app/zap-generated/IMClusterCommandHandler.cpp @@ -4551,12 +4551,13 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (aCommandId) { case Clusters::OperationalCredentials::Commands::Ids::AddNOC: { - expectArgumentCount = 4; - chip::ByteSpan NOCArray; + expectArgumentCount = 5; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; chip::ByteSpan IPKValue; chip::NodeId CaseAdminNode; uint16_t AdminVendorId; - bool argExists[4]; + bool argExists[5]; memset(argExists, 0, sizeof argExists); @@ -4569,7 +4570,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 4) + if (currentDecodeTagId < 5) { if (argExists[currentDecodeTagId]) { @@ -4586,15 +4587,18 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); break; case 1: - TLVUnpackError = aDataTlv.Get(IPKValue); + TLVUnpackError = aDataTlv.Get(ICACValue); break; case 2: - TLVUnpackError = aDataTlv.Get(CaseAdminNode); + TLVUnpackError = aDataTlv.Get(IPKValue); break; case 3: + TLVUnpackError = aDataTlv.Get(CaseAdminNode); + break; + case 4: TLVUnpackError = aDataTlv.Get(AdminVendorId); break; default: @@ -4614,10 +4618,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCArray, IPKValue, - CaseAdminNode, AdminVendorId); + wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue, + IPKValue, CaseAdminNode, AdminVendorId); } break; } @@ -4916,9 +4920,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, break; } case Clusters::OperationalCredentials::Commands::Ids::UpdateNOC: { - expectArgumentCount = 1; - chip::ByteSpan NOCArray; - bool argExists[1]; + expectArgumentCount = 2; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; + bool argExists[2]; memset(argExists, 0, sizeof argExists); @@ -4931,7 +4936,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 1) + if (currentDecodeTagId < 2) { if (argExists[currentDecodeTagId]) { @@ -4948,7 +4953,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); + break; + case 1: + TLVUnpackError = aDataTlv.Get(ICACValue); break; default: // Unsupported tag, ignore it. @@ -4967,9 +4975,9 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCArray); + wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue); } break; } diff --git a/zzz_generated/tv-casting-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/tv-casting-app/zap-generated/IMClusterCommandHandler.cpp index b10e012e6962b6..48d61afe324711 100644 --- a/zzz_generated/tv-casting-app/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/tv-casting-app/zap-generated/IMClusterCommandHandler.cpp @@ -5386,12 +5386,13 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (aCommandId) { case Clusters::OperationalCredentials::Commands::Ids::AddNOC: { - expectArgumentCount = 4; - chip::ByteSpan NOCArray; + expectArgumentCount = 5; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; chip::ByteSpan IPKValue; chip::NodeId CaseAdminNode; uint16_t AdminVendorId; - bool argExists[4]; + bool argExists[5]; memset(argExists, 0, sizeof argExists); @@ -5404,7 +5405,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 4) + if (currentDecodeTagId < 5) { if (argExists[currentDecodeTagId]) { @@ -5421,15 +5422,18 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); break; case 1: - TLVUnpackError = aDataTlv.Get(IPKValue); + TLVUnpackError = aDataTlv.Get(ICACValue); break; case 2: - TLVUnpackError = aDataTlv.Get(CaseAdminNode); + TLVUnpackError = aDataTlv.Get(IPKValue); break; case 3: + TLVUnpackError = aDataTlv.Get(CaseAdminNode); + break; + case 4: TLVUnpackError = aDataTlv.Get(AdminVendorId); break; default: @@ -5449,10 +5453,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCArray, IPKValue, - CaseAdminNode, AdminVendorId); + wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue, + IPKValue, CaseAdminNode, AdminVendorId); } break; } @@ -5751,9 +5755,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, break; } case Clusters::OperationalCredentials::Commands::Ids::UpdateNOC: { - expectArgumentCount = 1; - chip::ByteSpan NOCArray; - bool argExists[1]; + expectArgumentCount = 2; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; + bool argExists[2]; memset(argExists, 0, sizeof argExists); @@ -5766,7 +5771,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 1) + if (currentDecodeTagId < 2) { if (argExists[currentDecodeTagId]) { @@ -5783,7 +5788,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); + break; + case 1: + TLVUnpackError = aDataTlv.Get(ICACValue); break; default: // Unsupported tag, ignore it. @@ -5802,9 +5810,9 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCArray); + wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue); } break; } diff --git a/zzz_generated/window-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/window-app/zap-generated/IMClusterCommandHandler.cpp index 9b01c9257da7f8..25bbb5717b15d2 100644 --- a/zzz_generated/window-app/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/window-app/zap-generated/IMClusterCommandHandler.cpp @@ -1097,12 +1097,13 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (aCommandId) { case Clusters::OperationalCredentials::Commands::Ids::AddNOC: { - expectArgumentCount = 4; - chip::ByteSpan NOCArray; + expectArgumentCount = 5; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; chip::ByteSpan IPKValue; chip::NodeId CaseAdminNode; uint16_t AdminVendorId; - bool argExists[4]; + bool argExists[5]; memset(argExists, 0, sizeof argExists); @@ -1115,7 +1116,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 4) + if (currentDecodeTagId < 5) { if (argExists[currentDecodeTagId]) { @@ -1132,15 +1133,18 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); break; case 1: - TLVUnpackError = aDataTlv.Get(IPKValue); + TLVUnpackError = aDataTlv.Get(ICACValue); break; case 2: - TLVUnpackError = aDataTlv.Get(CaseAdminNode); + TLVUnpackError = aDataTlv.Get(IPKValue); break; case 3: + TLVUnpackError = aDataTlv.Get(CaseAdminNode); + break; + case 4: TLVUnpackError = aDataTlv.Get(AdminVendorId); break; default: @@ -1160,10 +1164,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCArray, IPKValue, - CaseAdminNode, AdminVendorId); + wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue, + IPKValue, CaseAdminNode, AdminVendorId); } break; } @@ -1462,9 +1466,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, break; } case Clusters::OperationalCredentials::Commands::Ids::UpdateNOC: { - expectArgumentCount = 1; - chip::ByteSpan NOCArray; - bool argExists[1]; + expectArgumentCount = 2; + chip::ByteSpan NOCValue; + chip::ByteSpan ICACValue; + bool argExists[2]; memset(argExists, 0, sizeof argExists); @@ -1477,7 +1482,7 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, continue; } currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); - if (currentDecodeTagId < 1) + if (currentDecodeTagId < 2) { if (argExists[currentDecodeTagId]) { @@ -1494,7 +1499,10 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, switch (currentDecodeTagId) { case 0: - TLVUnpackError = aDataTlv.Get(NOCArray); + TLVUnpackError = aDataTlv.Get(NOCValue); + break; + case 1: + TLVUnpackError = aDataTlv.Get(ICACValue); break; default: // Unsupported tag, ignore it. @@ -1513,9 +1521,9 @@ void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, TLVError = CHIP_NO_ERROR; } - if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount) + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount) { - wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCArray); + wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(aEndpointId, apCommandObj, NOCValue, ICACValue); } break; } From 1a333e08694de1a98aa8fe60baf14a4d5ad40fc4 Mon Sep 17 00:00:00 2001 From: Trevor Holbrook Date: Tue, 14 Sep 2021 16:36:54 -0700 Subject: [PATCH 047/255] ota-requestor-app - initial set of changes of development branch (#9474) * submit WIP ota-requestor-app * restyle * update copyright dates * add missing comma in BUILD.gn --- examples/ota-requestor-app/linux/.gn | 25 + examples/ota-requestor-app/linux/BUILD.gn | 37 + .../linux/PersistentStorage.cpp | 251 ++ .../linux/PersistentStorage.h | 54 + examples/ota-requestor-app/linux/README.md | 29 + examples/ota-requestor-app/linux/args.gni | 17 + .../ota-requestor-app/linux/build_overrides | 1 + examples/ota-requestor-app/linux/main.cpp | 170 + .../linux/third_party/connectedhomeip | 1 + .../ota-requestor-common/BDXDownloader.cpp | 102 + .../ota-requestor-common/BDXDownloader.h | 33 + .../ota-requestor-common/BUILD.gn | 39 + .../ota-requestor-app.zap | 3328 +++++++++++++++++ .../zap-generated/CHIPClientCallbacks.cpp | 641 ++++ .../zap-generated/CHIPClientCallbacks.h | 47 + .../zap-generated/CHIPClusters.cpp | 259 ++ .../zap-generated/CHIPClusters.h | 57 + .../zap-generated/IMClusterCommandHandler.cpp | 424 +++ .../zap-generated/af-gen-event.h | 39 + .../zap-generated/attribute-size.cpp | 111 + .../zap-generated/callback-stub.cpp | 570 +++ .../zap-generated/endpoint_config.h | 207 + .../zap-generated/gen_config.h | 44 + .../zap-generated/gen_tokens.h | 45 + 24 files changed, 6531 insertions(+) create mode 100644 examples/ota-requestor-app/linux/.gn create mode 100644 examples/ota-requestor-app/linux/BUILD.gn create mode 100644 examples/ota-requestor-app/linux/PersistentStorage.cpp create mode 100644 examples/ota-requestor-app/linux/PersistentStorage.h create mode 100644 examples/ota-requestor-app/linux/README.md create mode 100644 examples/ota-requestor-app/linux/args.gni create mode 120000 examples/ota-requestor-app/linux/build_overrides create mode 100644 examples/ota-requestor-app/linux/main.cpp create mode 120000 examples/ota-requestor-app/linux/third_party/connectedhomeip create mode 100644 examples/ota-requestor-app/ota-requestor-common/BDXDownloader.cpp create mode 100644 examples/ota-requestor-app/ota-requestor-common/BDXDownloader.h create mode 100644 examples/ota-requestor-app/ota-requestor-common/BUILD.gn create mode 100644 examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap create mode 100644 zzz_generated/ota-requestor-app/zap-generated/CHIPClientCallbacks.cpp create mode 100644 zzz_generated/ota-requestor-app/zap-generated/CHIPClientCallbacks.h create mode 100644 zzz_generated/ota-requestor-app/zap-generated/CHIPClusters.cpp create mode 100644 zzz_generated/ota-requestor-app/zap-generated/CHIPClusters.h create mode 100644 zzz_generated/ota-requestor-app/zap-generated/IMClusterCommandHandler.cpp create mode 100644 zzz_generated/ota-requestor-app/zap-generated/af-gen-event.h create mode 100644 zzz_generated/ota-requestor-app/zap-generated/attribute-size.cpp create mode 100644 zzz_generated/ota-requestor-app/zap-generated/callback-stub.cpp create mode 100644 zzz_generated/ota-requestor-app/zap-generated/endpoint_config.h create mode 100644 zzz_generated/ota-requestor-app/zap-generated/gen_config.h create mode 100644 zzz_generated/ota-requestor-app/zap-generated/gen_tokens.h diff --git a/examples/ota-requestor-app/linux/.gn b/examples/ota-requestor-app/linux/.gn new file mode 100644 index 00000000000000..70728706ea4a14 --- /dev/null +++ b/examples/ota-requestor-app/linux/.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + import("//args.gni") +} diff --git a/examples/ota-requestor-app/linux/BUILD.gn b/examples/ota-requestor-app/linux/BUILD.gn new file mode 100644 index 00000000000000..b2eaddb6aa29fd --- /dev/null +++ b/examples/ota-requestor-app/linux/BUILD.gn @@ -0,0 +1,37 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +executable("chip-ota-requestor-app") { + sources = [ + "PersistentStorage.cpp", + "main.cpp", + ] + + deps = [ + "${chip_root}/examples/ota-requestor-app/ota-requestor-common", + "${chip_root}/examples/platform/linux:app-main", + "${chip_root}/src/lib", + ] + + cflags = [ "-Wconversion" ] + + output_dir = root_out_dir +} + +group("linux") { + deps = [ ":chip-ota-requestor-app" ] +} diff --git a/examples/ota-requestor-app/linux/PersistentStorage.cpp b/examples/ota-requestor-app/linux/PersistentStorage.cpp new file mode 100644 index 00000000000000..3f4a7a5b1a63e9 --- /dev/null +++ b/examples/ota-requestor-app/linux/PersistentStorage.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "PersistentStorage.h" + +#include +#include +#include + +#include +#include + +using String = std::basic_string; +using Section = std::map; +using Sections = std::map; + +using namespace ::chip; +using namespace ::chip::Controller; +using namespace ::chip::Logging; + +constexpr const char kFilename[] = "/tmp/chip_tool_config.ini"; +constexpr const char kDefaultSectionName[] = "Default"; +constexpr const char kPortKey[] = "ListenPort"; +constexpr const char kLoggingKey[] = "LoggingLevel"; +constexpr const char kLocalNodeIdKey[] = "LocalNodeId"; +constexpr const char kRemoteNodeIdKey[] = "RemoteNodeId"; +constexpr LogCategory kDefaultLoggingLevel = kLogCategory_Detail; + +namespace { + +std::string StringToBase64(const std::string & value) +{ + std::unique_ptr buffer(new char[BASE64_ENCODED_LEN(value.length())]); + + uint32_t len = + chip::Base64Encode32(reinterpret_cast(value.data()), static_cast(value.length()), buffer.get()); + if (len == UINT32_MAX) + { + return ""; + } + + return std::string(buffer.get(), len); +} + +std::string Base64ToString(const std::string & b64Value) +{ + std::unique_ptr buffer(new uint8_t[BASE64_MAX_DECODED_LEN(b64Value.length())]); + + uint32_t len = chip::Base64Decode32(b64Value.data(), static_cast(b64Value.length()), buffer.get()); + if (len == UINT32_MAX) + { + return ""; + } + + return std::string(reinterpret_cast(buffer.get()), len); +} + +} // namespace + +CHIP_ERROR PersistentStorage::Init() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + std::ifstream ifs; + ifs.open(kFilename, std::ifstream::in); + if (!ifs.good()) + { + CommitConfig(); + ifs.open(kFilename, std::ifstream::in); + } + VerifyOrExit(ifs.is_open(), err = CHIP_ERROR_OPEN_FAILED); + + mConfig.parse(ifs); + ifs.close(); + +exit: + return err; +} + +CHIP_ERROR PersistentStorage::SyncGetKeyValue(const char * key, void * value, uint16_t & size) +{ + std::string iniValue; + + auto section = mConfig.sections[kDefaultSectionName]; + auto it = section.find(key); + ReturnErrorCodeIf(it == section.end(), CHIP_ERROR_KEY_NOT_FOUND); + + ReturnErrorCodeIf(!inipp::extract(section[key], iniValue), CHIP_ERROR_INVALID_ARGUMENT); + + iniValue = Base64ToString(iniValue); + + uint16_t dataSize = static_cast(iniValue.size()); + if (dataSize > size) + { + size = dataSize; + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + + size = dataSize; + memcpy(value, iniValue.data(), dataSize); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR PersistentStorage::SyncSetKeyValue(const char * key, const void * value, uint16_t size) +{ + auto section = mConfig.sections[kDefaultSectionName]; + section[key] = StringToBase64(std::string(static_cast(value), size)); + + mConfig.sections[kDefaultSectionName] = section; + return CommitConfig(); +} + +CHIP_ERROR PersistentStorage::SyncDeleteKeyValue(const char * key) +{ + auto section = mConfig.sections[kDefaultSectionName]; + section.erase(key); + + mConfig.sections[kDefaultSectionName] = section; + return CommitConfig(); +} + +CHIP_ERROR PersistentStorage::CommitConfig() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + std::ofstream ofs; + std::string tmpPath = kFilename; + tmpPath.append(".tmp"); + ofs.open(tmpPath, std::ofstream::out | std::ofstream::trunc); + VerifyOrExit(ofs.good(), err = CHIP_ERROR_WRITE_FAILED); + + mConfig.generate(ofs); + ofs.close(); + VerifyOrExit(ofs.good(), err = CHIP_ERROR_WRITE_FAILED); + + VerifyOrExit(rename(tmpPath.c_str(), kFilename) == 0, err = CHIP_ERROR_WRITE_FAILED); + +exit: + return err; +} + +uint16_t PersistentStorage::GetListenPort() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + // By default chip-tool listens on CHIP_PORT + 1. This is done in order to avoid + // having 2 servers listening on CHIP_PORT when one runs an accessory server locally. + uint16_t chipListenPort = CHIP_PORT + 1; + + char value[6]; + uint16_t size = static_cast(sizeof(value)); + err = SyncGetKeyValue(kPortKey, value, size); + if (CHIP_NO_ERROR == err) + { + uint16_t tmpValue; + std::stringstream ss(value); + ss >> tmpValue; + if (!ss.fail() && ss.eof()) + { + chipListenPort = tmpValue; + } + } + + return chipListenPort; +} + +LogCategory PersistentStorage::GetLoggingLevel() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + LogCategory chipLogLevel = kDefaultLoggingLevel; + + char value[9]; + uint16_t size = static_cast(sizeof(value)); + err = SyncGetKeyValue(kLoggingKey, value, size); + if (CHIP_NO_ERROR == err) + { + if (strcasecmp(value, "none") == 0) + { + chipLogLevel = kLogCategory_None; + } + else if (strcasecmp(value, "error") == 0) + { + chipLogLevel = kLogCategory_Error; + } + else if (strcasecmp(value, "progress") == 0) + { + chipLogLevel = kLogCategory_Progress; + } + else if (strcasecmp(value, "detail") == 0) + { + chipLogLevel = kLogCategory_Detail; + } + } + + return chipLogLevel; +} + +NodeId PersistentStorage::GetNodeId(const char * key, NodeId defaultVal) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + uint64_t nodeId; + uint16_t size = static_cast(sizeof(nodeId)); + err = SyncGetKeyValue(key, &nodeId, size); + if (err == CHIP_NO_ERROR) + { + return static_cast(Encoding::LittleEndian::HostSwap64(nodeId)); + } + + return defaultVal; +} + +NodeId PersistentStorage::GetLocalNodeId() +{ + return GetNodeId(kLocalNodeIdKey, kTestControllerNodeId); +} + +NodeId PersistentStorage::GetRemoteNodeId() +{ + return GetNodeId(kRemoteNodeIdKey, kTestDeviceNodeId); +} + +CHIP_ERROR PersistentStorage::SetNodeId(const char * key, NodeId value) +{ + uint64_t nodeId = Encoding::LittleEndian::HostSwap64(value); + return SyncSetKeyValue(key, &nodeId, sizeof(nodeId)); +} + +CHIP_ERROR PersistentStorage::SetLocalNodeId(NodeId nodeId) +{ + return SetNodeId(kLocalNodeIdKey, nodeId); +} + +CHIP_ERROR PersistentStorage::SetRemoteNodeId(NodeId nodeId) +{ + return SetNodeId(kRemoteNodeIdKey, nodeId); +} diff --git a/examples/ota-requestor-app/linux/PersistentStorage.h b/examples/ota-requestor-app/linux/PersistentStorage.h new file mode 100644 index 00000000000000..35cc775f81b8d5 --- /dev/null +++ b/examples/ota-requestor-app/linux/PersistentStorage.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#pragma once + +#include +#include +#include +#include + +class PersistentStorage : public chip::PersistentStorageDelegate +{ +public: + CHIP_ERROR Init(); + + /////////// PersistentStorageDelegate Interface ///////// + CHIP_ERROR SyncGetKeyValue(const char * key, void * buffer, uint16_t & size) override; + CHIP_ERROR SyncSetKeyValue(const char * key, const void * value, uint16_t size) override; + CHIP_ERROR SyncDeleteKeyValue(const char * key) override; + + uint16_t GetListenPort(); + chip::Logging::LogCategory GetLoggingLevel(); + + // Return the stored node ids, or the default ones if nothing is stored. + chip::NodeId GetLocalNodeId(); + chip::NodeId GetRemoteNodeId(); + + // Store node ids. + CHIP_ERROR SetLocalNodeId(chip::NodeId nodeId); + CHIP_ERROR SetRemoteNodeId(chip::NodeId nodeId); + +private: + // Helpers for node ids. + chip::NodeId GetNodeId(const char * key, chip::NodeId defaultVal); + CHIP_ERROR SetNodeId(const char * key, chip::NodeId value); + + CHIP_ERROR CommitConfig(); + inipp::Ini mConfig; +}; diff --git a/examples/ota-requestor-app/linux/README.md b/examples/ota-requestor-app/linux/README.md new file mode 100644 index 00000000000000..85580188a49686 --- /dev/null +++ b/examples/ota-requestor-app/linux/README.md @@ -0,0 +1,29 @@ +# ota-requestor-app (Linux) + +WARNING: this app currently does not build successfully. It is being submitted +as a starting point for further OTA Requestor development. + +This is a reference application that is both a server for the OTA Requestor +Cluster, as well as a client of the OTA Provider Cluster. It should initiate a +Software Update with a given OTA Provider node, and download a file. + +## Current Features / Limitations + +### Features + +- Code for running a full BDX download exists in BDX +- Sends QueryImage command + +### Limitations + +- needs chip-tool to pair to the Provider device first, so it can steal the + CASE session from persisted memory +- uses Controller class to load the CASE session +- Controller does not provide any way to access a new ExchangeContext for the + BDX exchange +- doesn't wait for QueryImageResponse to begin the BDX exchange +- does not verify QueryImageResponse message contents +- stores the downloaded file at a hardcoded filepath +- doesn't close the BDX ExchangeContext when the exchange is over +- only uses hardcoded node IDs +- does not support AnnounceOTAProvider command or OTA Requestor attributes diff --git a/examples/ota-requestor-app/linux/args.gni b/examples/ota-requestor-app/linux/args.gni new file mode 100644 index 00000000000000..a6463ca2c05fae --- /dev/null +++ b/examples/ota-requestor-app/linux/args.gni @@ -0,0 +1,17 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") + +import("${chip_root}/config/standalone/args.gni") diff --git a/examples/ota-requestor-app/linux/build_overrides b/examples/ota-requestor-app/linux/build_overrides new file mode 120000 index 00000000000000..e578e73312ebd1 --- /dev/null +++ b/examples/ota-requestor-app/linux/build_overrides @@ -0,0 +1 @@ +../../build_overrides \ No newline at end of file diff --git a/examples/ota-requestor-app/linux/main.cpp b/examples/ota-requestor-app/linux/main.cpp new file mode 100644 index 00000000000000..aadcd0118ee6c6 --- /dev/null +++ b/examples/ota-requestor-app/linux/main.cpp @@ -0,0 +1,170 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "BDXDownloader.h" +#include "PersistentStorage.h" + +#include +#include + +using chip::ByteSpan; +using chip::EndpointId; +using chip::VendorId; +using chip::bdx::TransferSession; +using chip::Callback::Callback; + +void OnQueryImageResponse(void * context, uint8_t status, uint32_t delayedActionTime, uint8_t * imageURI, uint32_t softwareVersion, + chip::ByteSpan updateToken, bool userConsentNeeded, chip::ByteSpan metadataForRequestor) +{ + ChipLogDetail(SoftwareUpdate, "%s", __FUNCTION__); +} + +void OnFailure(void * context, uint8_t status) +{ + ChipLogDetail(SoftwareUpdate, "Received failure response %d\n", (int) status); +} + +Callback mQueryImageResponseCallback(OnQueryImageResponse, nullptr); +Callback mOnFailureCallback(OnFailure, nullptr); + +chip::Controller::OtaSoftwareUpdateProviderCluster cluster; +const EndpointId kOtaProviderEndpoint = 0; +PersistentStorage mStorage; +chip::Controller::ExampleOperationalCredentialsIssuer mOpCredsIssuer; +chip::Controller::DeviceController mController; +chip::Controller::ControllerInitParams initParams; +chip::Controller::Device * providerDevice; +chip::Messaging::ExchangeManager * exchangeMgr; +BdxDownloader bdxDownloader; + +// QueryImage params +constexpr VendorId testVendorId = VendorId::Common; +constexpr uint16_t testProductId = 77; +constexpr uint16_t testImageType = 0; +constexpr uint16_t testHWVersion = 3; +constexpr uint16_t testCurrentVersion = 101; +constexpr uint8_t testProtocolsSupported = 0; // TODO: blocked because arrays are being generated as uint8_t +uint8_t locationBuf[3] = { 'U', 'S', '\0' }; +ByteSpan location(locationBuf); +constexpr bool clientCanConsent = false; +ByteSpan metadata(locationBuf); + +chip::Protocols::Id FromFullyQualified(uint32_t rawProtocolId) +{ + VendorId vendorId = static_cast(rawProtocolId >> 16); + uint16_t protocolId = static_cast(rawProtocolId & 0x0000FFFF); + return chip::Protocols::Id(vendorId, protocolId); +} + +int main(int argc, char * argv[]) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + chip::Messaging::ExchangeContext * exchange; + + chip::Callback::Cancelable * successCallback = mQueryImageResponseCallback.Cancel(); + chip::Callback::Cancelable * failureCallback = mOnFailureCallback.Cancel(); + + TransferSession::TransferInitData initOptions; + initOptions.TransferCtlFlags = chip::bdx::TransferControlFlags::kReceiverDrive; + initOptions.MaxBlockSize = 1024; + char testFileDes[9] = { "test.txt" }; + initOptions.FileDesLength = static_cast(strlen(testFileDes)); + initOptions.FileDesignator = reinterpret_cast(testFileDes); + + // NOTE: most of the following Init() calls were just copied from chip-tool code + + if (chip::Platform::MemoryInit() != CHIP_NO_ERROR) + { + + fprintf(stderr, "FAILED to initialize memory\n"); + return 1; + } + + if (chip::DeviceLayer::PlatformMgr().InitChipStack() != CHIP_NO_ERROR) + { + fprintf(stderr, "FAILED to initialize chip stack\n"); + return 1; + } + + chip::DeviceLayer::ConfigurationMgr().LogDeviceConfig(); + err = mStorage.Init(); + VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init Storage failure: %s", chip::ErrorStr(err))); + + chip::Logging::SetLogFilter(mStorage.GetLoggingLevel()); + + initParams.storageDelegate = &mStorage; + + err = mOpCredsIssuer.Initialize(mStorage); + VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Operational Cred Issuer: %s", chip::ErrorStr(err))); + + initParams.operationalCredentialsDelegate = &mOpCredsIssuer; + + err = mController.SetUdpListenPort(mStorage.GetListenPort()); + VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Commissioner: %s", chip::ErrorStr(err))); + + err = mController.Init(initParams); + VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Commissioner: %s", chip::ErrorStr(err))); + + err = mController.ServiceEvents(); + VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Run Loop: %s", chip::ErrorStr(err))); + + // WARNING: In order for this to work, you must first pair to the OTA Provider device using chip-tool. + // Currently, that pairing action will persist the CASE session in persistent memory, which will then be read by the following + // call. + err = mController.GetDevice(chip::kTestDeviceNodeId, &providerDevice); + VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "No device found: %s", chip::ErrorStr(err))); + + cluster.Associate(providerDevice, kOtaProviderEndpoint); + cluster.QueryImage(successCallback, failureCallback, testVendorId, testProductId, testImageType, testHWVersion, + testCurrentVersion, testProtocolsSupported, location, clientCanConsent, metadata); + + // WARNING: GetNewExchangeContext() was implemented locally as a workaround to get access to an ExchangeContext, but does not + // exist now. Currently there is GetSecureSession(), but the caller still needs access to the ExchangeManager in order to get a + // new ExchangeContext. + exchange = providerDevice->GetNewExchangeContext(&bdxDownloader); + VerifyOrExit(exchange != nullptr, ChipLogError(BDX, "unable to allocate ec")); + + bdxDownloader.SetInitialExchange(exchange); + + // This will kick of a timer which will regularly check for updates to the bdx::TransferSession state machine. + bdxDownloader.InitiateTransfer(&chip::DeviceLayer::SystemLayer, chip::bdx::TransferRole::kReceiver, initOptions, 20000); + + chip::DeviceLayer::PlatformMgr().RunEventLoop(); + +exit: + ChipLogDetail(BDX, "%s", ErrorStr(err)); + return 0; +} diff --git a/examples/ota-requestor-app/linux/third_party/connectedhomeip b/examples/ota-requestor-app/linux/third_party/connectedhomeip new file mode 120000 index 00000000000000..11a54ed360106c --- /dev/null +++ b/examples/ota-requestor-app/linux/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/examples/ota-requestor-app/ota-requestor-common/BDXDownloader.cpp b/examples/ota-requestor-app/ota-requestor-common/BDXDownloader.cpp new file mode 100644 index 00000000000000..fb50d73581a4f0 --- /dev/null +++ b/examples/ota-requestor-app/ota-requestor-common/BDXDownloader.cpp @@ -0,0 +1,102 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BDXDownloader.h" + +#include +#include +#include + +#include + +bool isTransferComplete = false; + +using namespace chip::bdx; + +uint32_t numBlocksRead = 0; + +void BdxDownloader::SetInitialExchange(chip::Messaging::ExchangeContext * ec) +{ + mExchangeCtx = ec; +} + +void BdxDownloader::HandleTransferSessionOutput(TransferSession::OutputEvent & event) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + ChipLogDetail(BDX, "OutputEvent type: %d", static_cast(event.EventType)); + switch (event.EventType) + { + case TransferSession::OutputEventType::kNone: + if (isTransferComplete) + { + ChipLogDetail(BDX, "Transfer complete!"); + mTransfer.Reset(); + } + break; + case TransferSession::OutputEventType::kMsgToSend: { + chip::Messaging::SendFlags sendFlags; + VerifyOrReturn(mExchangeCtx != nullptr, ChipLogError(BDX, "%s: mExchangeContext is null", __FUNCTION__)); + if (event.msgTypeData.MessageType == static_cast(MessageType::ReceiveInit)) + { + sendFlags.Set(chip::Messaging::SendMessageFlags::kFromInitiator); + } + err = mExchangeCtx->SendMessage(event.msgTypeData.ProtocolId, event.msgTypeData.MessageType, std::move(event.MsgData), + sendFlags); + VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(BDX, "%s: SendMessage failed: %s", __FUNCTION__, chip::ErrorStr(err))); + break; + } + case TransferSession::OutputEventType::kAcceptReceived: + VerifyOrReturn(CHIP_NO_ERROR == mTransfer.PrepareBlockQuery(), + ChipLogError(BDX, "%s: PrepareBlockQuery failed", __FUNCTION__)); + break; + case TransferSession::OutputEventType::kBlockReceived: { + ChipLogDetail(BDX, "Got block length %zu", event.blockdata.Length); + + std::ofstream otaFile("test-ota-out.txt", std::ifstream::out | std::ifstream::ate | std::ifstream::app); + otaFile.write(reinterpret_cast(event.blockdata.Data), event.blockdata.Length); + + if (event.blockdata.IsEof) + { + ReturnOnFailure(mTransfer.PrepareBlockAck()); + } + else + { + ReturnOnFailure(mTransfer.PrepareBlockQuery()); + } + otaFile.close(); + break; + } + case TransferSession::OutputEventType::kStatusReceived: + ChipLogError(BDX, "Got StatusReport %x", static_cast(event.statusData.statusCode)); + mTransfer.Reset(); + break; + case TransferSession::OutputEventType::kInternalError: + ChipLogError(BDX, "InternalError"); + mTransfer.Reset(); + break; + case TransferSession::OutputEventType::kTransferTimeout: + ChipLogError(BDX, "Transfer timed out"); + mTransfer.Reset(); + break; + case TransferSession::OutputEventType::kInitReceived: + case TransferSession::OutputEventType::kAckReceived: + case TransferSession::OutputEventType::kQueryReceived: + case TransferSession::OutputEventType::kAckEOFReceived: + default: + ChipLogError(BDX, "%s: unsupported event type", __FUNCTION__); + } +} diff --git a/examples/ota-requestor-app/ota-requestor-common/BDXDownloader.h b/examples/ota-requestor-app/ota-requestor-common/BDXDownloader.h new file mode 100644 index 00000000000000..0fa98438fef194 --- /dev/null +++ b/examples/ota-requestor-app/ota-requestor-common/BDXDownloader.h @@ -0,0 +1,33 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#pragma once + +class BdxDownloader : public chip::bdx::Initiator +{ +public: + void SetInitialExchange(chip::Messaging::ExchangeContext * ec); + +private: + // inherited from bdx::Endpoint + void HandleTransferSessionOutput(chip::bdx::TransferSession::OutputEvent & event); +}; diff --git a/examples/ota-requestor-app/ota-requestor-common/BUILD.gn b/examples/ota-requestor-app/ota-requestor-common/BUILD.gn new file mode 100644 index 00000000000000..c8f60917a5ee48 --- /dev/null +++ b/examples/ota-requestor-app/ota-requestor-common/BUILD.gn @@ -0,0 +1,39 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") + +import("${chip_root}/src/app/chip_data_model.gni") + +config("config") { + include_dirs = [ "." ] +} + +chip_data_model("ota-requestor-common") { + zap_file = "ota-requestor-app.zap" + + zap_pregenerated_dir = + "${chip_root}/zzz_generated/ota-requestor-app/zap-generated" + + use_default_client_callbacks = true + + deps = [ "${chip_root}/src/lib" ] + + sources = [ + "BDXDownloader.cpp", + "BDXDownloader.h", + ] + + public_configs = [ ":config" ] +} diff --git a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap new file mode 100644 index 00000000000000..670a0ad9321ebb --- /dev/null +++ b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap @@ -0,0 +1,3328 @@ +{ + "featureLevel": 45, + "creator": "zap", + "keyValuePairs": [ + { + "key": "commandDiscovery", + "value": "1" + }, + { + "key": "defaultResponsePolicy", + "value": "always" + }, + { + "key": "manufacturerCodes", + "value": "0x1002" + } + ], + "package": [ + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "version": "ZCL Test Data", + "type": "zcl-properties" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "version": "chip-v1", + "type": "gen-templates-json" + } + ], + "endpointTypes": [ + { + "name": "Anonymous Endpoint Type", + "deviceTypeName": "CHIP-All-Clusters-Server", + "deviceTypeCode": 0, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "IdentifyQuery", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [ + { + "name": "IdentifyQueryResponse", + "code": 0, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "identify time", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Groups", + "code": 4, + "mfgCode": null, + "define": "GROUPS_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "AddGroup", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "ViewGroup", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "GetGroupMembership", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "RemoveGroup", + "code": 3, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "RemoveAllGroups", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "AddGroupIfIdentifying", + "code": 5, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Groups", + "code": 4, + "mfgCode": null, + "define": "GROUPS_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [ + { + "name": "AddGroupResponse", + "code": 0, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "ViewGroupResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "GetGroupMembershipResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "RemoveGroupResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "name support", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Scenes", + "code": 5, + "mfgCode": null, + "define": "SCENES_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "AddScene", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "ViewScene", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "RemoveScene", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "RemoveAllScenes", + "code": 3, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "StoreScene", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "RecallScene", + "code": 5, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "GetSceneMembership", + "code": 6, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Scenes", + "code": 5, + "mfgCode": null, + "define": "SCENES_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [ + { + "name": "AddSceneResponse", + "code": 0, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "ViewSceneResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "RemoveSceneResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "RemoveAllScenesResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "StoreSceneResponse", + "code": 4, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "GetSceneMembershipResponse", + "code": 6, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "scene count", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "current scene", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "current group", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "scene valid", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "name support", + "code": 4, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "On/Off", + "code": 6, + "mfgCode": null, + "define": "ON_OFF_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "Off", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "On", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "Toggle", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "On/Off", + "code": 6, + "mfgCode": null, + "define": "ON_OFF_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [], + "attributes": [ + { + "name": "OnOff", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Level Control", + "code": 8, + "mfgCode": null, + "define": "LEVEL_CONTROL_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "MoveToLevel", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "Move", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "Step", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "Stop", + "code": 3, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "MoveToLevelWithOnOff", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "MoveWithOnOff", + "code": 5, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "StepWithOnOff", + "code": 6, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "StopWithOnOff", + "code": 7, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Level Control", + "code": 8, + "mfgCode": null, + "define": "LEVEL_CONTROL_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [], + "attributes": [ + { + "name": "current level", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Basic", + "code": 40, + "mfgCode": null, + "define": "BASIC_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "MfgSpecificPing", + "code": 0, + "mfgCode": 4098, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "3", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Basic", + "code": 40, + "mfgCode": null, + "define": "BASIC_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [ + { + "name": "StartUp", + "code": 0, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "ShutDown", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "Leave", + "code": 2, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "InteractionModelVersion", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorName", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorID", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductName", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductID", + "code": 4, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UserLabel", + "code": 5, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Location", + "code": 6, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersion", + "code": 7, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "0", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersionString", + "code": 8, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersion", + "code": 9, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "0", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersionString", + "code": 10, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "3", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "OTA Software Update Provider", + "code": 41, + "mfgCode": null, + "define": "OTA_PROVIDER_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "QueryImage", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "ApplyUpdateRequest", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "NotifyUpdateApplied", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "OTA Software Update Provider", + "code": 41, + "mfgCode": null, + "define": "OTA_PROVIDER_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [ + { + "name": "QueryImageResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "ApplyUpdateRequestResponse", + "code": 4, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "OTA Software Update Requestor", + "code": 42, + "mfgCode": null, + "define": "OTA_REQUESTOR_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "AnnounceOtaProvider", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "OTA Software Update Requestor", + "code": 42, + "mfgCode": null, + "define": "OTA_REQUESTOR_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [], + "attributes": [ + { + "name": "default ota provider", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "update possible", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Operational Credentials", + "code": 62, + "mfgCode": null, + "define": "OPERATIONAL_CREDENTIALS_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "OpCSRRequest", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "AddNOC", + "code": 6, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "UpdateNOC", + "code": 7, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "UpdateFabricLabel", + "code": 9, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "RemoveFabric", + "code": 10, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "AddTrustedRootCertificate", + "code": 11, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "RemoveTrustedRootCertificate", + "code": 12, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Operational Credentials", + "code": 62, + "mfgCode": null, + "define": "OPERATIONAL_CREDENTIALS_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [ + { + "name": "OpCSRResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "NOCResponse", + "code": 8, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "fabrics list", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SupportedFabrics", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CommissionedFabrics", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Door Lock", + "code": 257, + "mfgCode": null, + "define": "DOOR_LOCK_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "LockDoor", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "UnlockDoor", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "UnlockWithTimeout", + "code": 3, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "GetLogRecord", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "SetPin", + "code": 5, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "GetPin", + "code": 6, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "ClearPin", + "code": 7, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "ClearAllPins", + "code": 8, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "SetWeekdaySchedule", + "code": 11, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "GetWeekdaySchedule", + "code": 12, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "ClearWeekdaySchedule", + "code": 13, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "SetYeardaySchedule", + "code": 14, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "GetYeardaySchedule", + "code": 15, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "ClearYeardaySchedule", + "code": 16, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "SetHolidaySchedule", + "code": 17, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "GetHolidaySchedule", + "code": 18, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "ClearHolidaySchedule", + "code": 19, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "SetUserType", + "code": 20, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "GetUserType", + "code": 21, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "SetRfid", + "code": 22, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "GetRfid", + "code": 23, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "ClearRfid", + "code": 24, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "ClearAllRfids", + "code": 25, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Door Lock", + "code": 257, + "mfgCode": null, + "define": "DOOR_LOCK_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [ + { + "name": "LockDoorResponse", + "code": 0, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "UnlockDoorResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "lock state", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "lock type", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "actuator enabled", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "door state", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "enable logging", + "code": 32, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "language", + "code": 33, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "led settings", + "code": 34, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "auto relock time", + "code": 35, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "sound volume", + "code": 36, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "operating mode", + "code": 37, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "default configuration register", + "code": 39, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "enable local programming", + "code": 40, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x01", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "enable one touch locking", + "code": 41, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "enable inside status led", + "code": 42, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "enable privacy mode button", + "code": 43, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "wrong code entry limit", + "code": 48, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "user code temporary disable time", + "code": 49, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "send pin over the air", + "code": 50, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "require pin for rf operation", + "code": 51, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "zigbee security level", + "code": 52, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "alarm mask", + "code": 64, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "keypad operation event mask", + "code": 65, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RF operation event mask", + "code": 66, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "manual operation event mask", + "code": 67, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "rfid operation event mask", + "code": 68, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "keypad programming event mask", + "code": 69, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "rf programming event mask", + "code": 70, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "rfid programming event mask", + "code": 71, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Barrier Control", + "code": 259, + "mfgCode": null, + "define": "BARRIER_CONTROL_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "BarrierControlGoToPercent", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "BarrierControlStop", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Barrier Control", + "code": 259, + "mfgCode": null, + "define": "BARRIER_CONTROL_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [], + "attributes": [ + { + "name": "barrier moving state", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "barrier safety status", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "barrier capabilities", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "barrier position", + "code": 10, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Color Control", + "code": 768, + "mfgCode": null, + "define": "COLOR_CONTROL_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "MoveToHue", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "MoveHue", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "StepHue", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "MoveToSaturation", + "code": 3, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "MoveSaturation", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "StepSaturation", + "code": 5, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "MoveToHueAndSaturation", + "code": 6, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "MoveToColor", + "code": 7, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "MoveColor", + "code": 8, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "StepColor", + "code": 9, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "MoveToColorTemperature", + "code": 10, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "StopMoveStep", + "code": 71, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "MoveColorTemperature", + "code": 75, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "StepColorTemperature", + "code": 76, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Color Control", + "code": 768, + "mfgCode": null, + "define": "COLOR_CONTROL_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [], + "attributes": [ + { + "name": "current hue", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "current saturation", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "remaining time", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "current x", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x616B", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "current y", + "code": 4, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x607D", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "drift compensation", + "code": 5, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "compensation text", + "code": 6, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color temperature", + "code": 7, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00FA", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color mode", + "code": 8, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x01", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color control options", + "code": 15, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "number of primaries", + "code": 16, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 1 x", + "code": 17, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 1 y", + "code": 18, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 1 intensity", + "code": 19, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 2 x", + "code": 21, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 2 y", + "code": 22, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 2 intensity", + "code": 23, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 3 x", + "code": 25, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 3 y", + "code": 26, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 3 intensity", + "code": 27, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 4 x", + "code": 32, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 4 y", + "code": 33, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 4 intensity", + "code": 34, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 5 x", + "code": 36, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 5 y", + "code": 37, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 5 intensity", + "code": 38, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 6 x", + "code": 40, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 6 y", + "code": 41, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "primary 6 intensity", + "code": 42, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "white point x", + "code": 48, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "white point y", + "code": 49, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color point r x", + "code": 50, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color point r y", + "code": 51, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color point r intensity", + "code": 52, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color point g x", + "code": 54, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color point g y", + "code": 55, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color point g intensity", + "code": 56, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color point b x", + "code": 58, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color point b y", + "code": 59, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color point b intensity", + "code": 60, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "enhanced current hue", + "code": 16384, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "enhanced color mode", + "code": 16385, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x01", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color loop active", + "code": 16386, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color loop direction", + "code": 16387, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color loop time", + "code": 16388, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0019", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color capabilities", + "code": 16394, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color temp physical min", + "code": 16395, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "color temp physical max", + "code": 16396, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0xFEFF", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "couple color temp to level min-mireds", + "code": 16397, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "start up color temperature mireds", + "code": 16400, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Temperature Measurement", + "code": 1026, + "mfgCode": null, + "define": "TEMP_MEASUREMENT_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Temperature Measurement", + "code": 1026, + "mfgCode": null, + "define": "TEMP_MEASUREMENT_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [], + "attributes": [ + { + "name": "measured value", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "min measured value", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x8000", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "max measured value", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x8000", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "IAS Zone", + "code": 1280, + "mfgCode": null, + "define": "IAS_ZONE_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "ZoneEnrollResponse", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "IAS Zone", + "code": 1280, + "mfgCode": null, + "define": "IAS_ZONE_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [ + { + "name": "ZoneStatusChangeNotification", + "code": 0, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "ZoneEnrollRequest", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "zone state", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "zone type", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "zone status", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "IAS CIE address", + "code": 16, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Zone ID", + "code": 17, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0xff", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 0, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + } + ] + } + ], + "endpoints": [ + { + "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeIndex": 0, + "profileId": 259, + "endpointId": 1, + "networkId": 0, + "endpointVersion": 1, + "deviceIdentifier": 0 + } + ], + "log": [] +} \ No newline at end of file diff --git a/zzz_generated/ota-requestor-app/zap-generated/CHIPClientCallbacks.cpp b/zzz_generated/ota-requestor-app/zap-generated/CHIPClientCallbacks.cpp new file mode 100644 index 00000000000000..acfd1f84546007 --- /dev/null +++ b/zzz_generated/ota-requestor-app/zap-generated/CHIPClientCallbacks.cpp @@ -0,0 +1,641 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// THIS FILE IS GENERATED BY ZAP + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::app::List; + +namespace { +[[maybe_unused]] constexpr uint16_t kByteSpanSizeLengthInBytes = 2; +} // namespace + +#define CHECK_STATUS_WITH_RETVAL(error, retval) \ + if (CHIP_NO_ERROR != error) \ + { \ + ChipLogError(Zcl, "CHECK_STATUS %s", ErrorStr(error)); \ + if (onFailureCallback != nullptr) \ + { \ + Callback::Callback * cb = \ + Callback::Callback::FromCancelable(onFailureCallback); \ + cb->mCall(cb->mContext, static_cast(EMBER_ZCL_STATUS_INVALID_VALUE)); \ + } \ + return retval; \ + } + +#define CHECK_STATUS(error) CHECK_STATUS_WITH_RETVAL(error, true) +#define CHECK_STATUS_VOID(error) CHECK_STATUS_WITH_RETVAL(error, ) + +#define CHECK_MESSAGE_LENGTH_WITH_RETVAL(value, retval) \ + if (!CanCastTo(value)) \ + { \ + ChipLogError(Zcl, "CHECK_MESSAGE_LENGTH expects a uint16_t value, got: %d", value); \ + if (onFailureCallback != nullptr) \ + { \ + Callback::Callback * cb = \ + Callback::Callback::FromCancelable(onFailureCallback); \ + cb->mCall(cb->mContext, static_cast(EMBER_ZCL_STATUS_INVALID_VALUE)); \ + } \ + return retval; \ + } \ + \ + if (messageLen < value) \ + { \ + ChipLogError(Zcl, "Unexpected response length: %d", messageLen); \ + if (onFailureCallback != nullptr) \ + { \ + Callback::Callback * cb = \ + Callback::Callback::FromCancelable(onFailureCallback); \ + cb->mCall(cb->mContext, static_cast(EMBER_ZCL_STATUS_INVALID_VALUE)); \ + } \ + return retval; \ + } \ + \ + messageLen = static_cast(messageLen - static_cast(value)); + +#define CHECK_MESSAGE_LENGTH(value) CHECK_MESSAGE_LENGTH_WITH_RETVAL(value, true) +#define CHECK_MESSAGE_LENGTH_VOID(value) CHECK_MESSAGE_LENGTH_WITH_RETVAL(value, ) + +#define GET_RESPONSE_CALLBACKS(name) \ + Callback::Cancelable * onSuccessCallback = nullptr; \ + Callback::Cancelable * onFailureCallback = nullptr; \ + NodeId sourceId = emberAfCurrentCommand()->SourceNodeId(); \ + uint8_t sequenceNumber = emberAfCurrentCommand()->seqNum; \ + CHIP_ERROR err = gCallbacks.GetResponseCallback(sourceId, sequenceNumber, &onSuccessCallback, &onFailureCallback); \ + \ + if (CHIP_NO_ERROR != err) \ + { \ + if (onSuccessCallback == nullptr) \ + { \ + ChipLogDetail(Zcl, "%s: Missing success callback", name); \ + } \ + \ + if (onFailureCallback == nullptr) \ + { \ + ChipLogDetail(Zcl, "%s: Missing failure callback", name); \ + } \ + \ + return true; \ + } + +#define GET_CLUSTER_RESPONSE_CALLBACKS(name) \ + Callback::Cancelable * onSuccessCallback = nullptr; \ + Callback::Cancelable * onFailureCallback = nullptr; \ + NodeId sourceIdentifier = reinterpret_cast(commandObj); \ + /* #6559: Currently, we only have one commands for the IMInvokeCommands and to a device, so the seqNum is always set to 0. */ \ + CHIP_ERROR err = gCallbacks.GetResponseCallback(sourceIdentifier, 0, &onSuccessCallback, &onFailureCallback); \ + \ + if (CHIP_NO_ERROR != err) \ + { \ + if (onSuccessCallback == nullptr) \ + { \ + ChipLogDetail(Zcl, "%s: Missing success callback", name); \ + } \ + \ + if (onFailureCallback == nullptr) \ + { \ + ChipLogDetail(Zcl, "%s: Missing failure callback", name); \ + } \ + \ + return true; \ + } + +#define GET_ATTRIBUTE_RESPONSE_CALLBACKS(name) + +#define GET_REPORT_CALLBACK(name) \ + Callback::Cancelable * onReportCallback = nullptr; \ + CHIP_ERROR err = gCallbacks.GetReportCallback(sourceId, endpointId, clusterId, attributeId, &onReportCallback); \ + \ + if (CHIP_NO_ERROR != err) \ + { \ + if (onReportCallback == nullptr) \ + { \ + ChipLogDetail(Zcl, "%s: Missing report callback", name); \ + } \ + \ + return true; \ + } + +// TODO: These IM related callbacks contains small or no generated code, should be put into seperate file to reduce the size of +// template. Singleton instance of the callbacks manager + +app::CHIPDeviceCallbacksMgr & gCallbacks = app::CHIPDeviceCallbacksMgr::GetInstance(); + +bool emberAfConfigureReportingResponseCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen) +{ + ChipLogProgress(Zcl, "ConfigureReportingResponseCallback:"); + ChipLogProgress(Zcl, " ClusterId: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); + + GET_RESPONSE_CALLBACKS("emberAfConfigureReportingResponseCallback"); + + // struct configureReportingResponseRecord[] + while (messageLen) + { + CHECK_MESSAGE_LENGTH(1); + uint8_t status = Encoding::Read8(message); // zclStatus + LogStatus(status); + + if (status == EMBER_ZCL_STATUS_SUCCESS) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onSuccessCallback); + cb->mCall(cb->mContext); + } + else + { + CHECK_MESSAGE_LENGTH(1); + uint8_t direction = Encoding::Read8(message); // reportingRole + ChipLogProgress(Zcl, " direction: 0x%02x", direction); + // Silence unused var warning if progress logging is disabled. Note + // that we _do_ want to call Read8 unconditionally here, because we + // want to advance the 'message' pointer even if we don't use + // direction. + UNUSED_VAR(direction); + + CHECK_MESSAGE_LENGTH(4); + AttributeId attributeId = Encoding::LittleEndian::Read32(message); // attribId + ChipLogProgress(Zcl, " attributeId: " ChipLogFormatMEI, ChipLogValueMEI(attributeId)); + // Silence unused var warning if progress logging is disabled. Note + // that we _do_ want to call Read32 unconditionally here, because we + // want to advance the 'message' pointer even if we don't use + // direction. + UNUSED_VAR(attributeId); + + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, status); + } + + // The current code is written matching the current API where there is a single attribute report + // per configure command. So if multiple attributes are configured at the same time, something is wrong + // somewhere. + if (messageLen) + { + ChipLogError(Zcl, "Multiple attributes reports configured at the same time. Something went wrong."); + break; + } + } + + return true; +} + +bool emberAfReadReportingConfigurationResponseCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen) +{ + ChipLogProgress(Zcl, "ReadReportingConfigurationResponse:"); + ChipLogProgress(Zcl, " ClusterId: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); + + GET_RESPONSE_CALLBACKS("emberAfReadReportingConfigurationResponseCallback"); + + // struct readReportingConfigurationResponseRecord[] + while (messageLen) + { + CHECK_MESSAGE_LENGTH(1); + uint8_t direction = Encoding::Read8(message); // reportingRole + ChipLogProgress(Zcl, " direction: 0x%02x", direction); + + CHECK_MESSAGE_LENGTH(4); + AttributeId attributeId = Encoding::LittleEndian::Read32(message); // attribId + ChipLogProgress(Zcl, " attributeId: " ChipLogFormatMEI, ChipLogValueMEI(attributeId)); + // Silence unused var warning if progress logging is disabled. Note + // that we _do_ want to call Read32 unconditionally here, because we + // want to advance the 'message' pointer even if we don't use + // attributeId. + UNUSED_VAR(attributeId); + + if (direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED) + { + CHECK_MESSAGE_LENGTH(1); + uint8_t attributeType = Encoding::Read8(message); // zclType + ChipLogProgress(Zcl, " attributeType: 0x%02x", attributeType); + // Silence unused var warning if progress logging is disabled. Note + // that we _do_ want to call Read8 unconditionally here, because we + // want to advance the 'message' pointer even if we don't use + // attributeType. + UNUSED_VAR(attributeType); + + CHECK_MESSAGE_LENGTH(2); + uint16_t minimumReportingInterval = Encoding::LittleEndian::Read16(message); // uint16 + ChipLogProgress(Zcl, " minimumReportingInterval: %" PRIu16, minimumReportingInterval); + + CHECK_MESSAGE_LENGTH(2); + uint16_t maximumReportingInterval = Encoding::LittleEndian::Read16(message); // uint16 + ChipLogProgress(Zcl, " maximumReportingInterval: %" PRIu16, maximumReportingInterval); + + // FIXME: unk is not supported yet. + + Callback::Callback * cb = + Callback::Callback::FromCancelable(onSuccessCallback); + cb->mCall(cb->mContext, minimumReportingInterval, maximumReportingInterval); + } + else + { + CHECK_MESSAGE_LENGTH(2); + uint16_t timeout = Encoding::LittleEndian::Read16(message); // uint16 + ChipLogProgress(Zcl, " timeout: %" PRIu16, timeout); + + Callback::Callback * cb = + Callback::Callback::FromCancelable(onSuccessCallback); + cb->mCall(cb->mContext, timeout); + } + } + + return true; +} + +bool emberAfDiscoverAttributesResponseCallback(ClusterId clusterId, bool discoveryComplete, uint8_t * message, uint16_t messageLen, + bool extended) +{ + ChipLogProgress(Zcl, "DiscoverAttributesResponse:"); + ChipLogProgress(Zcl, " ClusterId: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); + ChipLogProgress(Zcl, " discoveryComplete: %d", discoveryComplete); + ChipLogProgress(Zcl, " extended: %d", extended); + + GET_RESPONSE_CALLBACKS("emberAfDiscoverAttributesCallback"); + + // struct discoverAttributesResponseRecord[] + while (messageLen) + { + CHECK_MESSAGE_LENGTH(4); + AttributeId attributeId = Encoding::LittleEndian::Read32(message); // attribId + ChipLogProgress(Zcl, " attributeId: " ChipLogFormatMEI, ChipLogValueMEI(attributeId)); + // Silence unused var warning if progress logging is disabled. Note + // that we _do_ want to call Read32 unconditionally here, because we + // want to advance the 'message' pointer even if we don't use + // attributeId. + UNUSED_VAR(attributeId); + + CHECK_MESSAGE_LENGTH(1); + uint8_t attributeType = Encoding::Read8(message); // zclType + ChipLogProgress(Zcl, " attributeType: 0x%02x", attributeType); + // Silence unused var warning if progress logging is disabled. Note + // that we _do_ want to call Read8 unconditionally here, because we want + // to advance the 'message' pointer even if we don't use attributeType. + UNUSED_VAR(attributeType); + } + + Callback::Callback * cb = Callback::Callback::FromCancelable(onSuccessCallback); + cb->mCall(cb->mContext); + return true; +} + +bool emberAfDiscoverCommandsGeneratedResponseCallback(ClusterId clusterId, uint16_t manufacturerCode, bool discoveryComplete, + CommandId * commandIds, uint16_t commandIdCount) +{ + ChipLogProgress(Zcl, "DiscoverCommandsGeneratedResponse:"); + ChipLogProgress(Zcl, " ClusterId: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); + ChipLogProgress(Zcl, " manufacturerCode: 0x%04x", manufacturerCode); + ChipLogProgress(Zcl, " discoveryComplete: %d", discoveryComplete); + ChipLogProgress(Zcl, " commandIdCount: %" PRIu16, commandIdCount); + + for (uint16_t i = 0; i < commandIdCount; i++) + { + ChipLogProgress(Zcl, " commandId: " ChipLogFormatMEI, ChipLogValueMEI(*commandIds)); + commandIds++; + } + + GET_RESPONSE_CALLBACKS("emberAfDiscoverCommandsGeneratedResponseCallback"); + Callback::Callback * cb = Callback::Callback::FromCancelable(onSuccessCallback); + cb->mCall(cb->mContext); + return true; +} + +bool emberAfDiscoverCommandsReceivedResponseCallback(ClusterId clusterId, uint16_t manufacturerCode, bool discoveryComplete, + CommandId * commandIds, uint16_t commandIdCount) +{ + ChipLogProgress(Zcl, "DiscoverCommandsReceivedResponse:"); + ChipLogProgress(Zcl, " ClusterId: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); + ChipLogProgress(Zcl, " manufacturerCode: 0x%04x", manufacturerCode); + ChipLogProgress(Zcl, " discoveryComplete: %d", discoveryComplete); + ChipLogProgress(Zcl, " commandIdCount: %" PRIu16, commandIdCount); + + for (uint16_t i = 0; i < commandIdCount; i++) + { + ChipLogProgress(Zcl, " commandId: " ChipLogFormatMEI, ChipLogValueMEI(*commandIds)); + commandIds++; + } + + GET_RESPONSE_CALLBACKS("emberAfDiscoverCommandsGeneratedResponseCallback"); + Callback::Callback * cb = Callback::Callback::FromCancelable(onSuccessCallback); + cb->mCall(cb->mContext); + return true; +} + +bool emberAfOtaSoftwareUpdateProviderClusterApplyUpdateRequestResponseCallback(EndpointId endpoint, app::CommandSender * commandObj, + uint8_t action, uint32_t delayedActionTime) +{ + ChipLogProgress(Zcl, "ApplyUpdateRequestResponse:"); + ChipLogProgress(Zcl, " action: %" PRIu8 "", action); + ChipLogProgress(Zcl, " delayedActionTime: %" PRIu32 "", delayedActionTime); + + GET_CLUSTER_RESPONSE_CALLBACKS("OtaSoftwareUpdateProviderClusterApplyUpdateRequestResponseCallback"); + + Callback::Callback * cb = + Callback::Callback::FromCancelable(onSuccessCallback); + cb->mCall(cb->mContext, action, delayedActionTime); + return true; +} + +bool emberAfOtaSoftwareUpdateProviderClusterQueryImageResponseCallback(EndpointId endpoint, app::CommandSender * commandObj, + uint8_t status, uint32_t delayedActionTime, + uint8_t * imageURI, uint32_t softwareVersion, + chip::ByteSpan updateToken, bool userConsentNeeded, + chip::ByteSpan metadataForRequestor) +{ + ChipLogProgress(Zcl, "QueryImageResponse:"); + ChipLogProgress(Zcl, " status: %" PRIu8 "", status); + ChipLogProgress(Zcl, " delayedActionTime: %" PRIu32 "", delayedActionTime); + // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits ByteSpan + // ChipLogProgress(Zcl, " imageURI: %.*s", imageURI.size(), imageURI.data()); + ChipLogProgress(Zcl, " softwareVersion: %" PRIu32 "", softwareVersion); + ChipLogProgress(Zcl, " updateToken: %zu", updateToken.size()); + ChipLogProgress(Zcl, " userConsentNeeded: %d", userConsentNeeded); + ChipLogProgress(Zcl, " metadataForRequestor: %zu", metadataForRequestor.size()); + + GET_CLUSTER_RESPONSE_CALLBACKS("OtaSoftwareUpdateProviderClusterQueryImageResponseCallback"); + + Callback::Callback * cb = + Callback::Callback::FromCancelable(onSuccessCallback); + cb->mCall(cb->mContext, status, delayedActionTime, imageURI, softwareVersion, updateToken, userConsentNeeded, + metadataForRequestor); + return true; +} + +bool emberAfReportAttributesCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen) +{ + ChipLogProgress(Zcl, "emberAfReportAttributeCallback:"); + ChipLogProgress(Zcl, " ClusterId: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); + + NodeId sourceId = emberAfCurrentCommand()->SourceNodeId(); + ChipLogProgress(Zcl, " Source NodeId: %" PRIu64, sourceId); + + EndpointId endpointId = emberAfCurrentCommand()->apsFrame->sourceEndpoint; + ChipLogProgress(Zcl, " Source EndpointId: 0x%04x", endpointId); + + // TODO onFailureCallback is just here because of the CHECK_MESSAGE_LENGTH macro. It needs to be removed. + Callback::Cancelable * onFailureCallback = nullptr; + + while (messageLen) + { + CHECK_MESSAGE_LENGTH(4); + AttributeId attributeId = Encoding::LittleEndian::Read32(message); // attribId + ChipLogProgress(Zcl, " attributeId: " ChipLogFormatMEI, ChipLogValueMEI(attributeId)); + + GET_REPORT_CALLBACK("emberAfReportAttributesCallback"); + + CHECK_MESSAGE_LENGTH(1); + uint8_t attributeType = Encoding::Read8(message); + ChipLogProgress(Zcl, " attributeType: 0x%02x", attributeType); + + switch (attributeType) + { + case 0x00: // nodata / No data + case 0x0A: // data24 / 24-bit data + case 0x0C: // data40 / 40-bit data + case 0x0D: // data48 / 48-bit data + case 0x0E: // data56 / 56-bit data + case 0x1A: // map24 / 24-bit bitmap + case 0x1C: // map40 / 40-bit bitmap + case 0x1D: // map48 / 48-bit bitmap + case 0x1E: // map56 / 56-bit bitmap + case 0x22: // uint24 / Unsigned 24-bit integer + case 0x24: // uint40 / Unsigned 40-bit integer + case 0x25: // uint48 / Unsigned 48-bit integer + case 0x26: // uint56 / Unsigned 56-bit integer + case 0x2A: // int24 / Signed 24-bit integer + case 0x2C: // int40 / Signed 40-bit integer + case 0x2D: // int48 / Signed 48-bit integer + case 0x2E: // int56 / Signed 56-bit integer + case 0x38: // semi / Semi-precision + case 0x39: // single / Single precision + case 0x3A: // double / Double precision + case 0x48: // array / Array + case 0x49: // struct / Structure + case 0x50: // set / Set + case 0x51: // bag / Bag + case 0xE0: // ToD / Time of day + { + ChipLogError(Zcl, "attributeType 0x%02x is not supported", attributeType); + return true; + } + + case 0x41: // octstr / Octet string + case 0x42: // string / Character string + { + // Short Strings must contains at least one byte for the length + CHECK_MESSAGE_LENGTH(1); + uint8_t length = Encoding::Read8(message); + ChipLogProgress(Zcl, " length: 0x%02x", length); + + // When the length is set to 0xFF, it represents a non-value. In this case the data field is zero length. + if (length == 0xFF) + { + length = 0; + } + + CHECK_MESSAGE_LENGTH(length); + if (attributeType == 0x41) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onReportCallback); + cb->mCall(cb->mContext, ByteSpan(message, length)); + } + else + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onReportCallback); + cb->mCall(cb->mContext, ByteSpan(message, length)); + } + break; + } + + case 0x43: // octstr16 / Long octet string + case 0x44: // string16 / Long character string + { + // Long Strings must contains at least two bytes for the length + CHECK_MESSAGE_LENGTH(2); + uint16_t length = Encoding::LittleEndian::Read16(message); + ChipLogProgress(Zcl, " length: 0x%02x", length); + + // When the length is set to 0xFFFF, it represents a non-value. In this case the data field is zero length. + if (length == 0xFFFF) + { + length = 0; + } + + CHECK_MESSAGE_LENGTH(length); + if (attributeType == 0x43) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onReportCallback); + cb->mCall(cb->mContext, ByteSpan(message, length)); + } + else + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onReportCallback); + cb->mCall(cb->mContext, ByteSpan(message, length)); + } + break; + } + + case 0x08: // data8 / 8-bit data + case 0x18: // map8 / 8-bit bitmap + case 0x20: // uint8 / Unsigned 8-bit integer + case 0x30: // enum8 / 8-bit enumeration + { + CHECK_MESSAGE_LENGTH(1); + uint8_t value = Encoding::Read8(message); + ChipLogProgress(Zcl, " value: 0x%02x", value); + + Callback::Callback * cb = + Callback::Callback::FromCancelable(onReportCallback); + cb->mCall(cb->mContext, value); + break; + } + + case 0x09: // data16 / 16-bit data + case 0x19: // map16 / 16-bit bitmap + case 0x21: // uint16 / Unsigned 16-bit integer + case 0x31: // enum16 / 16-bit enumeration + case 0xE8: // clusterId / Cluster ID + case 0xE9: // attribId / Attribute ID + case 0xEA: // bacOID / BACnet OID + case 0xF1: // key128 / 128-bit security key + case 0xFF: // unk / Unknown + { + CHECK_MESSAGE_LENGTH(2); + uint16_t value = Encoding::LittleEndian::Read16(message); + ChipLogProgress(Zcl, " value: 0x%04x", value); + + Callback::Callback * cb = + Callback::Callback::FromCancelable(onReportCallback); + cb->mCall(cb->mContext, value); + break; + } + + case 0x0B: // data32 / 32-bit data + case 0x1B: // map32 / 32-bit bitmap + case 0x23: // uint32 / Unsigned 32-bit integer + case 0xE1: // date / Date + case 0xE2: // UTC / UTCTime + { + CHECK_MESSAGE_LENGTH(4); + uint32_t value = Encoding::LittleEndian::Read32(message); + ChipLogProgress(Zcl, " value: 0x%08x", value); + + Callback::Callback * cb = + Callback::Callback::FromCancelable(onReportCallback); + cb->mCall(cb->mContext, value); + break; + } + + case 0x0F: // data64 / 64-bit data + case 0x1F: // map64 / 64-bit bitmap + case 0x27: // uint64 / Unsigned 64-bit integer + case 0xF0: // EUI64 / IEEE address + { + CHECK_MESSAGE_LENGTH(8); + uint64_t value = Encoding::LittleEndian::Read64(message); + ChipLogProgress(Zcl, " value: 0x" ChipLogFormatX64, ChipLogValueX64(value)); + + Callback::Callback * cb = + Callback::Callback::FromCancelable(onReportCallback); + cb->mCall(cb->mContext, value); + break; + } + + case 0x10: // bool / Boolean + { + CHECK_MESSAGE_LENGTH(1); + uint8_t value = Encoding::Read8(message); + ChipLogProgress(Zcl, " value: %d", value); + + Callback::Callback * cb = + Callback::Callback::FromCancelable(onReportCallback); + cb->mCall(cb->mContext, value); + break; + } + + case 0x28: // int8 / Signed 8-bit integer + { + CHECK_MESSAGE_LENGTH(1); + int8_t value = CastToSigned(Encoding::Read8(message)); + ChipLogProgress(Zcl, " value: %" PRId8, value); + + Callback::Callback * cb = + Callback::Callback::FromCancelable(onReportCallback); + cb->mCall(cb->mContext, value); + break; + } + + case 0x29: // int16 / Signed 16-bit integer + { + CHECK_MESSAGE_LENGTH(2); + int16_t value = CastToSigned(Encoding::LittleEndian::Read16(message)); + ChipLogProgress(Zcl, " value: %" PRId16, value); + + Callback::Callback * cb = + Callback::Callback::FromCancelable(onReportCallback); + cb->mCall(cb->mContext, value); + break; + } + + case 0x2B: // int32 / Signed 32-bit integer + { + CHECK_MESSAGE_LENGTH(4); + int32_t value = CastToSigned(Encoding::LittleEndian::Read32(message)); + ChipLogProgress(Zcl, " value: %" PRId32, value); + + Callback::Callback * cb = + Callback::Callback::FromCancelable(onReportCallback); + cb->mCall(cb->mContext, value); + break; + } + + case 0x2F: // int64 / Signed 64-bit integer + { + CHECK_MESSAGE_LENGTH(8); + int64_t value = CastToSigned(Encoding::LittleEndian::Read64(message)); + ChipLogProgress(Zcl, " value: %" PRId64, value); + + Callback::Callback * cb = + Callback::Callback::FromCancelable(onReportCallback); + cb->mCall(cb->mContext, value); + break; + } + } + } + + return true; +} diff --git a/zzz_generated/ota-requestor-app/zap-generated/CHIPClientCallbacks.h b/zzz_generated/ota-requestor-app/zap-generated/CHIPClientCallbacks.h new file mode 100644 index 00000000000000..75bcc2c94fc3f0 --- /dev/null +++ b/zzz_generated/ota-requestor-app/zap-generated/CHIPClientCallbacks.h @@ -0,0 +1,47 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// THIS FILE IS GENERATED BY ZAP + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Note: The IMDefaultResponseCallback is a bridge to the old CallbackMgr before IM is landed, so it still accepts EmberAfStatus +// instead of IM status code. +// #6308 should handle IM error code on the application side, either modify this function or remove this. +typedef void (*ReadReportingConfigurationReportedCallback)(void * context, uint16_t minInterval, uint16_t maxInterval); +typedef void (*ReadReportingConfigurationReceivedCallback)(void * context, uint16_t timeout); + +// Cluster Specific Response Callbacks +typedef void (*OtaSoftwareUpdateProviderClusterApplyUpdateRequestResponseCallback)(void * context, uint8_t action, + uint32_t delayedActionTime); +typedef void (*OtaSoftwareUpdateProviderClusterQueryImageResponseCallback)(void * context, uint8_t status, + uint32_t delayedActionTime, uint8_t * imageURI, + uint32_t softwareVersion, chip::ByteSpan updateToken, + bool userConsentNeeded, + chip::ByteSpan metadataForRequestor); + +// List specific responses diff --git a/zzz_generated/ota-requestor-app/zap-generated/CHIPClusters.cpp b/zzz_generated/ota-requestor-app/zap-generated/CHIPClusters.cpp new file mode 100644 index 00000000000000..f766b95a884927 --- /dev/null +++ b/zzz_generated/ota-requestor-app/zap-generated/CHIPClusters.cpp @@ -0,0 +1,259 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// THIS FILE IS GENERATED BY ZAP + +#include "CHIPClusters.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define COMMAND_HEADER(name, clusterId) \ + const char * kName = name; \ + uint8_t seqNum = mDevice->GetNextSequenceNumber(); \ + \ + PacketBufferWriter buf(System::PacketBufferHandle::New(kMaxBufferSize)); \ + if (buf.IsNull()) \ + { \ + ChipLogError(Zcl, "Could not allocate packet buffer while trying to encode %s command", kName); \ + return CHIP_ERROR_INTERNAL; \ + } \ + \ + if (doEncodeApsFrame(buf, clusterId, kSourceEndpoint, mEndpoint, 0, 0, 0, 0, false)) \ + { + +#define COMMAND_FOOTER() \ + } \ + if (!buf.Fit()) \ + { \ + ChipLogError(Zcl, "Command %s can't fit in the allocated buffer", kName); \ + } \ + return SendCommand(seqNum, buf.Finalize(), onSuccessCallback, onFailureCallback); + +namespace chip { +namespace { +// TODO: Find a way to calculate maximum message length for clusters +// https://github.com/project-chip/connectedhomeip/issues/965 +constexpr uint16_t kMaxBufferSize = 1024; + +// This is a global command, so the low bits are 0b00. The command is +// standard, so does not need a manufacturer code, and we're sending client +// to server, so all the remaining bits are 0. +constexpr uint8_t kFrameControlGlobalCommand = 0x00; + +// Pick source endpoint as 1 for now +constexpr EndpointId kSourceEndpoint = 1; + +[[maybe_unused]] const uint8_t kReportingDirectionReported = 0x00; +} // namespace + +using namespace app::Clusters; +using namespace System; +using namespace Encoding::LittleEndian; + +namespace Controller { + +// TODO(#4502): onCompletion is not used by IM for now. +// TODO(#4503): length should be passed to commands when byte string is in argument list. +// TODO(#4503): Commands should take group id as an argument. + +// OtaSoftwareUpdateProvider Cluster Commands +CHIP_ERROR OtaSoftwareUpdateProviderCluster::ApplyUpdateRequest(Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback, + chip::ByteSpan updateToken, uint32_t newVersion) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + app::CommandSender * sender = nullptr; + TLV::TLVWriter * writer = nullptr; + uint8_t argSeqNumber = 0; + + // Used when encoding non-empty command. Suppress error message when encoding empty commands. + (void) writer; + (void) argSeqNumber; + + VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE); + + app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, + OtaSoftwareUpdateProvider::Commands::Ids::ApplyUpdateRequest, + (app::CommandPathFlags::kEndpointIdValid) }; + + SuccessOrExit(err = app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender)); + + SuccessOrExit(err = sender->PrepareCommand(cmdParams)); + + VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + // updateToken: octetString + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), updateToken)); + // newVersion: int32u + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), newVersion)); + + SuccessOrExit(err = sender->FinishCommand()); + + // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate. + mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback); + + err = mDevice->SendCommands(sender); + +exit: + // On error, we are responsible to close the sender. + if (err != CHIP_NO_ERROR && sender != nullptr) + { + sender->Shutdown(); + } + return err; +} + +CHIP_ERROR OtaSoftwareUpdateProviderCluster::NotifyUpdateApplied(Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback, + chip::ByteSpan updateToken, uint32_t currentVersion) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + app::CommandSender * sender = nullptr; + TLV::TLVWriter * writer = nullptr; + uint8_t argSeqNumber = 0; + + // Used when encoding non-empty command. Suppress error message when encoding empty commands. + (void) writer; + (void) argSeqNumber; + + VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE); + + app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, + OtaSoftwareUpdateProvider::Commands::Ids::NotifyUpdateApplied, + (app::CommandPathFlags::kEndpointIdValid) }; + + SuccessOrExit(err = app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender)); + + SuccessOrExit(err = sender->PrepareCommand(cmdParams)); + + VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + // updateToken: octetString + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), updateToken)); + // currentVersion: int32u + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), currentVersion)); + + SuccessOrExit(err = sender->FinishCommand()); + + // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate. + mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback); + + err = mDevice->SendCommands(sender); + +exit: + // On error, we are responsible to close the sender. + if (err != CHIP_NO_ERROR && sender != nullptr) + { + sender->Shutdown(); + } + return err; +} + +CHIP_ERROR OtaSoftwareUpdateProviderCluster::QueryImage(Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback, uint16_t vendorId, + uint16_t productId, uint16_t imageType, uint16_t hardwareVersion, + uint32_t currentVersion, uint8_t protocolsSupported, + chip::ByteSpan location, bool requestorCanConsent, + chip::ByteSpan metadataForProvider) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + app::CommandSender * sender = nullptr; + TLV::TLVWriter * writer = nullptr; + uint8_t argSeqNumber = 0; + + // Used when encoding non-empty command. Suppress error message when encoding empty commands. + (void) writer; + (void) argSeqNumber; + + VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE); + + app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, + OtaSoftwareUpdateProvider::Commands::Ids::QueryImage, + (app::CommandPathFlags::kEndpointIdValid) }; + + SuccessOrExit(err = app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender)); + + SuccessOrExit(err = sender->PrepareCommand(cmdParams)); + + VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + // vendorId: int16u + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), vendorId)); + // productId: int16u + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), productId)); + // imageType: int16u + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), imageType)); + // hardwareVersion: int16u + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), hardwareVersion)); + // currentVersion: int32u + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), currentVersion)); + // protocolsSupported: oTADownloadProtocol + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), protocolsSupported)); + // location: charString + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), location)); + // requestorCanConsent: boolean + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), requestorCanConsent)); + // metadataForProvider: octetString + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), metadataForProvider)); + + SuccessOrExit(err = sender->FinishCommand()); + + // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate. + mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback); + + err = mDevice->SendCommands(sender); + +exit: + // On error, we are responsible to close the sender. + if (err != CHIP_NO_ERROR && sender != nullptr) + { + sender->Shutdown(); + } + return err; +} + +// OtaSoftwareUpdateProvider Cluster Attributes +CHIP_ERROR OtaSoftwareUpdateProviderCluster::DiscoverAttributes(Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback) +{ + COMMAND_HEADER("DiscoverOtaSoftwareUpdateProviderAttributes", OtaSoftwareUpdateProvider::Id); + buf.Put8(kFrameControlGlobalCommand).Put8(seqNum).Put32(Globals::Commands::Ids::DiscoverAttributes).Put32(0x0000).Put8(0xFF); + COMMAND_FOOTER(); +} + +CHIP_ERROR OtaSoftwareUpdateProviderCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback) +{ + app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = 0x0000FFFD; + attributePath.mFlags.Set(app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback, + BasicAttributeFilter); +} + +} // namespace Controller +} // namespace chip diff --git a/zzz_generated/ota-requestor-app/zap-generated/CHIPClusters.h b/zzz_generated/ota-requestor-app/zap-generated/CHIPClusters.h new file mode 100644 index 00000000000000..e59ffa09842c4c --- /dev/null +++ b/zzz_generated/ota-requestor-app/zap-generated/CHIPClusters.h @@ -0,0 +1,57 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// THIS FILE IS GENERATED BY ZAP + +// Prevent multiple inclusion +#pragma once + +#include +#include + +#include +#include +#include + +namespace chip { +namespace Controller { + +class DLL_EXPORT OtaSoftwareUpdateProviderCluster : public ClusterBase +{ +public: + OtaSoftwareUpdateProviderCluster() : ClusterBase(app::Clusters::OtaSoftwareUpdateProvider::Id) {} + ~OtaSoftwareUpdateProviderCluster() {} + + // Cluster Commands + CHIP_ERROR ApplyUpdateRequest(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, + chip::ByteSpan updateToken, uint32_t newVersion); + CHIP_ERROR NotifyUpdateApplied(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, + chip::ByteSpan updateToken, uint32_t currentVersion); + CHIP_ERROR QueryImage(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, uint16_t vendorId, + uint16_t productId, uint16_t imageType, uint16_t hardwareVersion, uint32_t currentVersion, + uint8_t protocolsSupported, chip::ByteSpan location, bool requestorCanConsent, + chip::ByteSpan metadataForProvider); + + // Cluster Attributes + CHIP_ERROR DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); + CHIP_ERROR ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); + +private: +}; + +} // namespace Controller +} // namespace chip diff --git a/zzz_generated/ota-requestor-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/ota-requestor-app/zap-generated/IMClusterCommandHandler.cpp new file mode 100644 index 00000000000000..a99ae32315426c --- /dev/null +++ b/zzz_generated/ota-requestor-app/zap-generated/IMClusterCommandHandler.cpp @@ -0,0 +1,424 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// THIS FILE IS GENERATED BY ZAP + +#include +#include + +#include "app/util/util.h" +#include +#include +#include +#include + +#include + +// Currently we need some work to keep compatible with ember lib. +#include + +namespace chip { +namespace app { + +namespace { +void ReportCommandUnsupported(Command * aCommandObj, EndpointId aEndpointId, ClusterId aClusterId, CommandId aCommandId) +{ + CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + aClusterId, aCommandId, (CommandPathFlags::kEndpointIdValid) }; + aCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound, + Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, ChipLogValueMEI(aCommandId), + ChipLogValueMEI(aClusterId)); +} +} // anonymous namespace + +// Cluster specific command parsing + +namespace clusters { + +namespace OtaSoftwareUpdateProvider { + +void DispatchClientCommand(CommandSender * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv) +{ + // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV + // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error. + // Any error value TLVUnpackError means we have received an illegal value. + // The following variables are used for all commands to save code size. + CHIP_ERROR TLVError = CHIP_NO_ERROR; + CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR; + uint32_t validArgumentCount = 0; + uint32_t expectArgumentCount = 0; + uint32_t currentDecodeTagId = 0; + bool wasHandled = false; + { + switch (aCommandId) + { + case Clusters::OtaSoftwareUpdateProvider::Commands::Ids::ApplyUpdateRequestResponse: { + expectArgumentCount = 2; + uint8_t action; + uint32_t delayedActionTime; + bool argExists[2]; + + memset(argExists, 0, sizeof argExists); + + while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR) + { + // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element. + // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid. + if (!TLV::IsContextTag(aDataTlv.GetTag())) + { + continue; + } + currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); + if (currentDecodeTagId < 2) + { + if (argExists[currentDecodeTagId]) + { + ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag())); + TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT; + break; + } + else + { + argExists[currentDecodeTagId] = true; + validArgumentCount++; + } + } + switch (currentDecodeTagId) + { + case 0: + TLVUnpackError = aDataTlv.Get(action); + break; + case 1: + TLVUnpackError = aDataTlv.Get(delayedActionTime); + break; + default: + // Unsupported tag, ignore it. + ChipLogProgress(Zcl, "Unknown TLV tag during processing."); + break; + } + if (CHIP_NO_ERROR != TLVUnpackError) + { + break; + } + } + + if (CHIP_END_OF_TLV == TLVError) + { + // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error. + TLVError = CHIP_NO_ERROR; + } + + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount) + { + wasHandled = emberAfOtaSoftwareUpdateProviderClusterApplyUpdateRequestResponseCallback(aEndpointId, apCommandObj, + action, delayedActionTime); + } + break; + } + case Clusters::OtaSoftwareUpdateProvider::Commands::Ids::QueryImageResponse: { + expectArgumentCount = 7; + uint8_t status; + uint32_t delayedActionTime; + const uint8_t * imageURI; + uint32_t softwareVersion; + chip::ByteSpan updateToken; + bool userConsentNeeded; + chip::ByteSpan metadataForRequestor; + bool argExists[7]; + + memset(argExists, 0, sizeof argExists); + + while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR) + { + // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element. + // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid. + if (!TLV::IsContextTag(aDataTlv.GetTag())) + { + continue; + } + currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); + if (currentDecodeTagId < 7) + { + if (argExists[currentDecodeTagId]) + { + ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag())); + TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT; + break; + } + else + { + argExists[currentDecodeTagId] = true; + validArgumentCount++; + } + } + switch (currentDecodeTagId) + { + case 0: + TLVUnpackError = aDataTlv.Get(status); + break; + case 1: + TLVUnpackError = aDataTlv.Get(delayedActionTime); + break; + case 2: + // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types. + TLVUnpackError = aDataTlv.GetDataPtr(imageURI); + break; + case 3: + TLVUnpackError = aDataTlv.Get(softwareVersion); + break; + case 4: + TLVUnpackError = aDataTlv.Get(updateToken); + break; + case 5: + TLVUnpackError = aDataTlv.Get(userConsentNeeded); + break; + case 6: + TLVUnpackError = aDataTlv.Get(metadataForRequestor); + break; + default: + // Unsupported tag, ignore it. + ChipLogProgress(Zcl, "Unknown TLV tag during processing."); + break; + } + if (CHIP_NO_ERROR != TLVUnpackError) + { + break; + } + } + + if (CHIP_END_OF_TLV == TLVError) + { + // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error. + TLVError = CHIP_NO_ERROR; + } + + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 7 == validArgumentCount) + { + wasHandled = emberAfOtaSoftwareUpdateProviderClusterQueryImageResponseCallback( + aEndpointId, apCommandObj, status, delayedActionTime, const_cast(imageURI), softwareVersion, + updateToken, userConsentNeeded, metadataForRequestor); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::OtaSoftwareUpdateProvider::Id, aCommandId); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled) + { + CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::OtaSoftwareUpdateProvider::Id, aCommandId, + (CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest, + Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand); + ChipLogProgress(Zcl, + "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT + ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32, + validArgumentCount, expectArgumentCount, TLVError.Format(), TLVUnpackError.Format(), currentDecodeTagId); + // A command with no arguments would never write currentDecodeTagId. If + // progress logging is also disabled, it would look unused. Silence that + // warning. + UNUSED_VAR(currentDecodeTagId); + } +} + +} // namespace OtaSoftwareUpdateProvider + +namespace OtaSoftwareUpdateRequestor { + +void DispatchServerCommand(CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv) +{ + // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV + // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error. + // Any error value TLVUnpackError means we have received an illegal value. + // The following variables are used for all commands to save code size. + CHIP_ERROR TLVError = CHIP_NO_ERROR; + CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR; + uint32_t validArgumentCount = 0; + uint32_t expectArgumentCount = 0; + uint32_t currentDecodeTagId = 0; + bool wasHandled = false; + { + switch (aCommandId) + { + case Clusters::OtaSoftwareUpdateRequestor::Commands::Ids::AnnounceOtaProvider: { + expectArgumentCount = 4; + chip::ByteSpan serverLocation; + uint16_t vendorId; + uint8_t announcementReason; + chip::ByteSpan metadataForNode; + bool argExists[4]; + + memset(argExists, 0, sizeof argExists); + + while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR) + { + // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element. + // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid. + if (!TLV::IsContextTag(aDataTlv.GetTag())) + { + continue; + } + currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); + if (currentDecodeTagId < 4) + { + if (argExists[currentDecodeTagId]) + { + ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag())); + TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT; + break; + } + else + { + argExists[currentDecodeTagId] = true; + validArgumentCount++; + } + } + switch (currentDecodeTagId) + { + case 0: + TLVUnpackError = aDataTlv.Get(serverLocation); + break; + case 1: + TLVUnpackError = aDataTlv.Get(vendorId); + break; + case 2: + TLVUnpackError = aDataTlv.Get(announcementReason); + break; + case 3: + TLVUnpackError = aDataTlv.Get(metadataForNode); + break; + default: + // Unsupported tag, ignore it. + ChipLogProgress(Zcl, "Unknown TLV tag during processing."); + break; + } + if (CHIP_NO_ERROR != TLVUnpackError) + { + break; + } + } + + if (CHIP_END_OF_TLV == TLVError) + { + // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error. + TLVError = CHIP_NO_ERROR; + } + + if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount) + { + wasHandled = emberAfOtaSoftwareUpdateRequestorClusterAnnounceOtaProviderCallback( + aEndpointId, apCommandObj, serverLocation, vendorId, announcementReason, metadataForNode); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::OtaSoftwareUpdateRequestor::Id, aCommandId); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled) + { + CommandPathParams returnStatusParam = { aEndpointId, + 0, // GroupId + Clusters::OtaSoftwareUpdateRequestor::Id, aCommandId, + (CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest, + Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand); + ChipLogProgress(Zcl, + "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT + ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32, + validArgumentCount, expectArgumentCount, TLVError.Format(), TLVUnpackError.Format(), currentDecodeTagId); + // A command with no arguments would never write currentDecodeTagId. If + // progress logging is also disabled, it would look unused. Silence that + // warning. + UNUSED_VAR(currentDecodeTagId); + } +} + +} // namespace OtaSoftwareUpdateRequestor + +} // namespace clusters + +void DispatchSingleClusterCommand(ClusterId aClusterId, CommandId aCommandId, EndpointId aEndPointId, TLV::TLVReader & aReader, + CommandHandler * apCommandObj) +{ + ChipLogDetail(Zcl, "Received Cluster Command: Cluster=" ChipLogFormatMEI " Command=" ChipLogFormatMEI " Endpoint=%" PRIx16, + ChipLogValueMEI(aClusterId), ChipLogValueMEI(aCommandId), aEndPointId); + Compatibility::SetupEmberAfObjects(apCommandObj, aClusterId, aCommandId, aEndPointId); + TLV::TLVType dataTlvType; + SuccessOrExit(aReader.EnterContainer(dataTlvType)); + switch (aClusterId) + { + case Clusters::OtaSoftwareUpdateRequestor::Id: + clusters::OtaSoftwareUpdateRequestor::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader); + break; + default: + // Unrecognized cluster ID, error status will apply. + CommandPathParams returnStatusParam = { aEndPointId, + 0, // GroupId + aClusterId, aCommandId, (CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound, + Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand); + ChipLogError(Zcl, "Unknown cluster %" PRIx32, aClusterId); + break; + } +exit: + Compatibility::ResetEmberAfObjects(); + aReader.ExitContainer(dataTlvType); +} + +void DispatchSingleClusterResponseCommand(ClusterId aClusterId, CommandId aCommandId, EndpointId aEndPointId, + TLV::TLVReader & aReader, CommandSender * apCommandObj) +{ + ChipLogDetail(Zcl, "Received Cluster Command: Cluster=%" PRIx32 " Command=%" PRIx32 " Endpoint=%" PRIx16, aClusterId, + aCommandId, aEndPointId); + Compatibility::SetupEmberAfObjects(apCommandObj, aClusterId, aCommandId, aEndPointId); + TLV::TLVType dataTlvType; + SuccessOrExit(aReader.EnterContainer(dataTlvType)); + switch (aClusterId) + { + case Clusters::OtaSoftwareUpdateProvider::Id: + clusters::OtaSoftwareUpdateProvider::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader); + break; + default: + // Unrecognized cluster ID, error status will apply. + CommandPathParams returnStatusParam = { aEndPointId, + 0, // GroupId + aClusterId, aCommandId, (CommandPathFlags::kEndpointIdValid) }; + apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound, + Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand); + ChipLogError(Zcl, "Unknown cluster " ChipLogFormatMEI, ChipLogValueMEI(aClusterId)); + break; + } +exit: + Compatibility::ResetEmberAfObjects(); + aReader.ExitContainer(dataTlvType); +} + +} // namespace app +} // namespace chip diff --git a/zzz_generated/ota-requestor-app/zap-generated/af-gen-event.h b/zzz_generated/ota-requestor-app/zap-generated/af-gen-event.h new file mode 100644 index 00000000000000..814d4aab6b8bec --- /dev/null +++ b/zzz_generated/ota-requestor-app/zap-generated/af-gen-event.h @@ -0,0 +1,39 @@ +/** + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * + * Copyright (c) 2020 Silicon Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Enclosing macro to prevent multiple inclusion +#ifndef __AF_GEN_EVENT__ +#define __AF_GEN_EVENT__ + +#endif // __AF_GEN_EVENT__ diff --git a/zzz_generated/ota-requestor-app/zap-generated/attribute-size.cpp b/zzz_generated/ota-requestor-app/zap-generated/attribute-size.cpp new file mode 100644 index 00000000000000..d06e4b2c339a7e --- /dev/null +++ b/zzz_generated/ota-requestor-app/zap-generated/attribute-size.cpp @@ -0,0 +1,111 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// THIS FILE IS GENERATED BY ZAP + +#include +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app::List; + +// The first 2 bytes specify the number of entries. A value of 0xFFFF means the list in invalid +// and data is undefined. +constexpr uint16_t kSizeLengthInBytes = 2u; + +void copyListMember(uint8_t * dest, uint8_t * src, bool write, uint16_t * offset, uint16_t length) +{ + if (write) + { + memmove(dest + *offset, src, length); + } + else + { + memmove(dest, src + *offset, length); + } + + *offset = static_cast(*offset + length); +} + +uint16_t emberAfCopyList(ClusterId clusterId, EmberAfAttributeMetadata * am, bool write, uint8_t * dest, uint8_t * src, + int32_t index) +{ + if (index == -1) + { + memmove(dest, src, am->size); + return am->size; + } + + if (index == 0) + { + if (write) + { + // src is a pointer to native-endian uint16_t, dest is pointer to buffer that should hold little-endian value + emberAfCopyInt16u(dest, 0, *reinterpret_cast(src)); + } + else + { + // src is pointer to buffer holding little-endian value, dest is a pointer to native-endian uint16_t + *reinterpret_cast(dest) = emberAfGetInt16u(src, 0, kSizeLengthInBytes); + } + return kSizeLengthInBytes; + } + + if (!CanCastTo(index)) + { + ChipLogError(Zcl, "Index %" PRId32 " is invalid. Should be between 1 and 65534", index); + return 0; + } + + uint16_t entryLength = 0; + switch (clusterId) + { + } + + return entryLength; +} + +// A list is a collection of entries of the same data type. The data type may be any defined data type. +uint16_t emberAfAttributeValueListSize(ClusterId clusterId, AttributeId attributeId, const uint8_t * buffer) +{ + // The first 2 bytes specify the number of entries. A value of 0xFFFF means the list in invalid + // and data is undefined. + uint16_t entryCount = emberAfGetInt16u(buffer, 0, kSizeLengthInBytes); + if (entryCount == 0xFFFF) + { + return 0; + } + + uint16_t entryLength = 0; + switch (clusterId) + { + } + + uint32_t totalSize = kSizeLengthInBytes + (entryCount * entryLength); + if (!CanCastTo(totalSize)) + { + ChipLogError(Zcl, "Cluster " ChipLogFormatMEI ": Size of attribute " ChipLogFormatMEI " is too large.", + ChipLogValueMEI(clusterId), ChipLogValueMEI(attributeId)); + return 0; + } + + return static_cast(totalSize); +} diff --git a/zzz_generated/ota-requestor-app/zap-generated/callback-stub.cpp b/zzz_generated/ota-requestor-app/zap-generated/callback-stub.cpp new file mode 100644 index 00000000000000..d254e68094bb83 --- /dev/null +++ b/zzz_generated/ota-requestor-app/zap-generated/callback-stub.cpp @@ -0,0 +1,570 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// THIS FILE IS GENERATED BY ZAP + +#include +#include +#include + +using namespace chip; + +// Cluster Init Functions +void emberAfClusterInitCallback(EndpointId endpoint, ClusterId clusterId) +{ + switch (clusterId) + { + case ZCL_OTA_PROVIDER_CLUSTER_ID: + emberAfOtaSoftwareUpdateProviderClusterInitCallback(endpoint); + break; + case ZCL_OTA_REQUESTOR_CLUSTER_ID: + emberAfOtaSoftwareUpdateRequestorClusterInitCallback(endpoint); + break; + default: + // Unrecognized cluster ID + break; + } +} + +void __attribute__((weak)) emberAfOtaSoftwareUpdateProviderClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfOtaSoftwareUpdateRequestorClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} + +// +// Non-Cluster Related Callbacks +// + +/** @brief Add To Current App Tasks + * + * This function is only useful to sleepy end devices. This function will note + * the passed item as part of a set of tasks the application has outstanding + * (e.g. message sent requiring APS acknwoledgement). This will affect how the + * application behaves with regard to sleeping and polling. Until the + * outstanding task is completed, the device may poll more frequently and sleep + * less often. + * + * @param tasks Ver.: always + */ +void __attribute__((weak)) emberAfAddToCurrentAppTasksCallback(EmberAfApplicationTask tasks) {} + +/** @brief Remove From Current App Tasks + * + * This function is only useful to sleepy end devices. This function will + * remove the passed item from the set of tasks the application has outstanding + * (e.g. message sent requiring APS acknwoledgement). This will affect how the + * application behaves with regard to sleeping and polling. Removing the item + * from the list of outstanding tasks may allow the device to sleep longer and + * poll less frequently. If there are other outstanding tasks the system may + * still have to stay away and poll more often. + * + * @param tasks Ver.: always + */ +void __attribute__((weak)) emberAfRemoveFromCurrentAppTasksCallback(EmberAfApplicationTask tasks) {} + +/** @brief Allow Network Write Attribute + * + * This function is called by the application framework before it writes an + * attribute in response to a write attribute request from an external device. + * The value passed into this callback is the value to which the attribute is to + * be set by the framework. + Example: In mirroring simple metering data + * on an Energy Services Interface (ESI) (formerly called Energy Service Portal + * (ESP) in SE 1.0).), a mirrored simple meter needs to write read-only + * attributes on its mirror. The-meter-mirror sample application, located in + * app/framework/sample-apps, uses this callback to allow the mirrored device to + * write simple metering attributes on the mirror regardless of the fact that + * most simple metering attributes are defined as read-only by the ZigBee + * specification. + Note: The ZCL specification does not (as of this + * writing) specify any permission-level security for writing writeable + * attributes. As far as the ZCL specification is concerned, if an attribute is + * writeable, any device that has a link key for the device should be able to + * write that attribute. Furthermore if an attribute is read only, it should not + * be written over the air. Thus, if you implement permissions for writing + * attributes as a feature, you MAY be operating outside the specification. This + * is unlikely to be a problem for writing read-only attributes, but it may be a + * problem for attributes that are writeable according to the specification but + * restricted by the application implementing this callback. + * + * @param endpoint Ver.: always + * @param clusterId Ver.: always + * @param attributeId Ver.: always + * @param mask Ver.: always + * @param manufacturerCode Ver.: always + * @param value Ver.: always + * @param type Ver.: always + */ +EmberAfAttributeWritePermission __attribute__((weak)) +emberAfAllowNetworkWriteAttributeCallback(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId, uint8_t mask, + uint16_t manufacturerCode, uint8_t * value, uint8_t type) +{ + return EMBER_ZCL_ATTRIBUTE_WRITE_PERMISSION_ALLOW_WRITE_NORMAL; // Default +} + +/** @brief Attribute Read Access + * + * This function is called whenever the Application Framework needs to check + * access permission for an attribute read. + * + * @param endpoint Ver.: always + * @param clusterId Ver.: always + * @param manufacturerCode Ver.: always + * @param attributeId Ver.: always + */ +bool __attribute__((weak)) +emberAfAttributeReadAccessCallback(EndpointId endpoint, ClusterId clusterId, uint16_t manufacturerCode, AttributeId attributeId) +{ + return true; +} + +/** @brief Attribute Write Access + * + * This function is called whenever the Application Framework needs to check + * access permission for an attribute write. + * + * @param endpoint Ver.: always + * @param clusterId Ver.: always + * @param manufacturerCode Ver.: always + * @param attributeId Ver.: always + */ +bool __attribute__((weak)) +emberAfAttributeWriteAccessCallback(EndpointId endpoint, ClusterId clusterId, uint16_t manufacturerCode, AttributeId attributeId) +{ + return true; +} + +/** @brief Default Response + * + * This function is called by the application framework when a Default Response + * command is received from an external device. The application should return + * true if the message was processed or false if it was not. + * + * @param clusterId The cluster identifier of this response. Ver.: always + * @param commandId The command identifier to which this is a response. Ver.: + * always + * @param status Specifies either SUCCESS or the nature of the error that was + * detected in the received command. Ver.: always + */ +bool __attribute__((weak)) emberAfDefaultResponseCallback(ClusterId clusterId, CommandId commandId, EmberAfStatus status) +{ + return false; +} + +/** @brief Configure Reporting Response + * + * This function is called by the application framework when a Configure + * Reporting Response command is received from an external device. The + * application should return true if the message was processed or false if it + * was not. + * + * @param clusterId The cluster identifier of this response. Ver.: always + * @param buffer Buffer containing the list of attribute status records. Ver.: + * always + * @param bufLen The length in bytes of the list. Ver.: always + */ +bool __attribute__((weak)) emberAfConfigureReportingResponseCallback(ClusterId clusterId, uint8_t * buffer, uint16_t bufLen) +{ + return false; +} + +/** @brief Read Reporting Configuration Response + * + * This function is called by the application framework when a Read Reporting + * Configuration Response command is received from an external device. The + * application should return true if the message was processed or false if it + * was not. + * + * @param clusterId The cluster identifier of this response. Ver.: always + * @param buffer Buffer containing the list of attribute reporting configuration + * records. Ver.: always + * @param bufLen The length in bytes of the list. Ver.: always + */ +bool __attribute__((weak)) emberAfReadReportingConfigurationResponseCallback(ClusterId clusterId, uint8_t * buffer, uint16_t bufLen) +{ + return false; +} + +/** @brief Discover Attributes Response + * + * This function is called by the application framework when a Discover + * Attributes Response or Discover Attributes Extended Response command is + * received from an external device. The Discover Attributes Response command + * contains a bool indicating if discovery is complete and a list of zero or + * more attribute identifier/type records. The final argument indicates whether + * the response is in the extended format or not. The application should return + * true if the message was processed or false if it was not. + * + * @param clusterId The cluster identifier of this response. Ver.: always + * @param discoveryComplete Indicates whether there are more attributes to be + * discovered. true if there are no more attributes to be discovered. Ver.: + * always + * @param buffer Buffer containing the list of attribute identifier/type + * records. Ver.: always + * @param bufLen The length in bytes of the list. Ver.: always + * @param extended Indicates whether the response is in the extended format or + * not. Ver.: always + */ +bool __attribute__((weak)) emberAfDiscoverAttributesResponseCallback(ClusterId clusterId, bool discoveryComplete, uint8_t * buffer, + uint16_t bufLen, bool extended) +{ + return false; +} + +/** @brief Discover Commands Generated Response + * + * This function is called by the framework when Discover Commands Generated + * Response is received. + * + * @param clusterId The cluster identifier of this response. Ver.: always + * @param manufacturerCode Manufacturer code Ver.: always + * @param discoveryComplete Indicates whether there are more commands to be + * discovered. Ver.: always + * @param commandIds Buffer containing the list of command identifiers. Ver.: + * always + * @param commandIdCount The length of bytes of the list, whish is the same as + * the number of identifiers. Ver.: always + */ +bool __attribute__((weak)) +emberAfDiscoverCommandsGeneratedResponseCallback(ClusterId clusterId, uint16_t manufacturerCode, bool discoveryComplete, + CommandId * commandIds, uint16_t commandIdCount) +{ + return false; +} + +/** @brief Discover Commands Received Response + * + * This function is called by the framework when Discover Commands Received + * Response is received. + * + * @param clusterId The cluster identifier of this response. Ver.: always + * @param manufacturerCode Manufacturer code Ver.: always + * @param discoveryComplete Indicates whether there are more commands to be + * discovered. Ver.: always + * @param commandIds Buffer containing the list of command identifiers. Ver.: + * always + * @param commandIdCount The length of bytes of the list, whish is the same as + * the number of identifiers. Ver.: always + */ +bool __attribute__((weak)) +emberAfDiscoverCommandsReceivedResponseCallback(ClusterId clusterId, uint16_t manufacturerCode, bool discoveryComplete, + CommandId * commandIds, uint16_t commandIdCount) +{ + return false; +} + +/** @brief Pre Command Received + * + * This callback is the second in the Application Framework's message processing + * chain. At this point in the processing of incoming over-the-air messages, the + * application has determined that the incoming message is a ZCL command. It + * parses enough of the message to populate an EmberAfClusterCommand struct. The + * Application Framework defines this struct value in a local scope to the + * command processing but also makes it available through a global pointer + * called emberAfCurrentCommand, in app/framework/util/util.c. When command + * processing is complete, this pointer is cleared. + * + * @param cmd Ver.: always + */ +bool __attribute__((weak)) emberAfPreCommandReceivedCallback(EmberAfClusterCommand * cmd) +{ + return false; +} + +/** @brief Pre Message Send + * + * This function is called by the framework when it is about to pass a message + * to the stack primitives for sending. This message may or may not be ZCL, + * ZDO, or some other protocol. This is called prior to + any ZigBee + * fragmentation that may be done. If the function returns true it is assumed + * the callback has consumed and processed the message. The callback must also + * set the EmberStatus status code to be passed back to the caller. The + * framework will do no further processing on the message. + If the + * function returns false then it is assumed that the callback has not processed + * the mesasge and the framework will continue to process accordingly. + * + * @param messageStruct The structure containing the parameters of the APS + * message to be sent. Ver.: always + * @param status A pointer to the status code value that will be returned to the + * caller. Ver.: always + */ +bool __attribute__((weak)) emberAfPreMessageSendCallback(EmberAfMessageStruct * messageStruct, EmberStatus * status) +{ + return false; +} + +/** @brief Message Sent + * + * This function is called by the application framework from the message sent + * handler, when it is informed by the stack regarding the message sent status. + * All of the values passed to the emberMessageSentHandler are passed on to this + * callback. This provides an opportunity for the application to verify that its + * message has been sent successfully and take the appropriate action. This + * callback should return a bool value of true or false. A value of true + * indicates that the message sent notification has been handled and should not + * be handled by the application framework. + * + * @param type Ver.: always + * @param destination Ver.: always + * @param apsFrame Ver.: always + * @param msgLen Ver.: always + * @param message Ver.: always + * @param status Ver.: always + */ +bool __attribute__((weak)) emberAfMessageSentCallback(const MessageSendDestination & destination, EmberApsFrame * apsFrame, + uint16_t msgLen, uint8_t * message, EmberStatus status) +{ + return false; +} + +/** @brief Pre Attribute Change + * + * This function is called by the application framework before it changes an + * attribute value. The value passed into this callback is the value to which + * the attribute is to be set by the framework. The application should return + * ::EMBER_ZCL_STATUS_SUCCESS to permit the change or any other ::EmberAfStatus + * to reject it. + * + * @param endpoint Ver.: always + * @param clusterId Ver.: always + * @param attributeId Ver.: always + * @param mask Ver.: always + * @param manufacturerCode Ver.: always + * @param type Ver.: always + * @param size Ver.: always + * @param value Ver.: always + */ +EmberAfStatus __attribute__((weak)) +emberAfPreAttributeChangeCallback(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId, uint8_t mask, + uint16_t manufacturerCode, uint8_t type, uint16_t size, uint8_t * value) +{ + return EMBER_ZCL_STATUS_SUCCESS; +} + +/** @brief Post Attribute Change + * + * This function is called by the application framework after it changes an + * attribute value. The value passed into this callback is the value to which + * the attribute was set by the framework. + * + * @param endpoint Ver.: always + * @param clusterId Ver.: always + * @param attributeId Ver.: always + * @param mask Ver.: always + * @param manufacturerCode Ver.: always + * @param type Ver.: always + * @param size Ver.: always + * @param value Ver.: always + */ +void __attribute__((weak)) +emberAfPostAttributeChangeCallback(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId, uint8_t mask, + uint16_t manufacturerCode, uint8_t type, uint16_t size, uint8_t * value) +{} + +/** @brief External Attribute Read + * + * Like emberAfExternalAttributeWriteCallback above, this function is called + * when the framework needs to read an attribute that is not stored within the + * Application Framework's data structures. + All of the important + * information about the attribute itself is passed as a pointer to an + * EmberAfAttributeMetadata struct, which is stored within the application and + * used to manage the attribute. A complete description of the + * EmberAfAttributeMetadata struct is provided in + * app/framework/include/af-types.h + This function assumes that the + * application is able to read the attribute, write it into the passed buffer, + * and return immediately. Any attributes that require a state machine for + * reading and writing are not really candidates for externalization at the + * present time. The Application Framework does not currently include a state + * machine for reading or writing attributes that must take place across a + * series of application ticks. Attributes that cannot be read in a timely + * manner should be stored within the Application Framework and updated + * occasionally by the application code from within the + * emberAfMainTickCallback. + If the application was successfully able to + * read the attribute and write it into the passed buffer, it should return a + * value of EMBER_ZCL_STATUS_SUCCESS. Ensure that the size of the externally + * managed attribute value is smaller than what the buffer can hold. In the case + * of a buffer overflow throw an appropriate error such as + * EMBER_ZCL_STATUS_INSUFFICIENT_SPACE. Any other return value indicates the + * application was not able to read the attribute. + * + * @param endpoint Ver.: always + * @param clusterId Ver.: always + * @param attributeMetadata Ver.: always + * @param manufacturerCode Ver.: always + * @param buffer Ver.: always + * @param maxReadLength Ver.: always + * @param index Ver.: always + */ +EmberAfStatus __attribute__((weak)) +emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId, EmberAfAttributeMetadata * attributeMetadata, + uint16_t manufacturerCode, uint8_t * buffer, uint16_t maxReadLength, int32_t index) +{ + return EMBER_ZCL_STATUS_FAILURE; +} + +/** @brief External Attribute Write + * + * This function is called whenever the Application Framework needs to write an + * attribute which is not stored within the data structures of the Application + * Framework itself. One of the new features in Version 2 is the ability to + * store attributes outside the Framework. This is particularly useful for + * attributes that do not need to be stored because they can be read off the + * hardware when they are needed, or are stored in some central location used by + * many modules within the system. In this case, you can indicate that the + * attribute is stored externally. When the framework needs to write an external + * attribute, it makes a call to this callback. + This callback is very + * useful for host micros which need to store attributes in persistent memory. + * Because each host micro (used with an Ember NCP) has its own type of + * persistent memory storage, the Application Framework does not include the + * ability to mark attributes as stored in flash the way that it does for Ember + * SoCs like the EM35x. On a host micro, any attributes that need to be stored + * in persistent memory should be marked as external and accessed through the + * external read and write callbacks. Any host code associated with the + * persistent storage should be implemented within this callback. + All of + * the important information about the attribute itself is passed as a pointer + * to an EmberAfAttributeMetadata struct, which is stored within the application + * and used to manage the attribute. A complete description of the + * EmberAfAttributeMetadata struct is provided in + * app/framework/include/af-types.h. + This function assumes that the + * application is able to write the attribute and return immediately. Any + * attributes that require a state machine for reading and writing are not + * candidates for externalization at the present time. The Application Framework + * does not currently include a state machine for reading or writing attributes + * that must take place across a series of application ticks. Attributes that + * cannot be written immediately should be stored within the Application + * Framework and updated occasionally by the application code from within the + * emberAfMainTickCallback. + If the application was successfully able to + * write the attribute, it returns a value of EMBER_ZCL_STATUS_SUCCESS. Any + * other return value indicates the application was not able to write the + * attribute. + * + * @param endpoint Ver.: always + * @param clusterId Ver.: always + * @param attributeMetadata Ver.: always + * @param manufacturerCode Ver.: always + * @param buffer Ver.: always + * @param index Ver.: always + */ +EmberAfStatus __attribute__((weak)) +emberAfExternalAttributeWriteCallback(EndpointId endpoint, ClusterId clusterId, EmberAfAttributeMetadata * attributeMetadata, + uint16_t manufacturerCode, uint8_t * buffer, int32_t index) +{ + return EMBER_ZCL_STATUS_FAILURE; +} + +/** @brief Report Attributes + * + * This function is called by the application framework when a Report Attributes + * command is received from an external device. The application should return + * true if the message was processed or false if it was not. + * + * @param clusterId The cluster identifier of this command. Ver.: always + * @param buffer Buffer containing the list of attribute report records. Ver.: + * always + * @param bufLen The length in bytes of the list. Ver.: always + */ +bool __attribute__((weak)) emberAfReportAttributesCallback(ClusterId clusterId, uint8_t * buffer, uint16_t bufLen) +{ + return false; +} + +/** @brief Get Current Time + * + * This callback is called when device attempts to get current time from the + * hardware. If this device has means to retrieve exact time, then this method + * should implement it. If the callback can't provide the exact time it should + * return 0 to indicate failure. Default action is to return 0, which indicates + * that device does not have access to real time. + * + */ +uint32_t __attribute__((weak)) emberAfGetCurrentTimeCallback() +{ + return 0; +} + +/** @brief Get Endpoint Info + * + * This function is a callback to an application implemented endpoint that + * operates outside the normal application framework. When the framework wishes + * to perform operations with that endpoint it uses this callback to retrieve + * the endpoint's information. If the endpoint exists and the application can + * provide data then true shall be returned. Otherwise the callback must return + * false. + * + * @param endpoint The endpoint to retrieve data for. Ver.: always + * @param returnNetworkIndex The index corresponding to the ZigBee network the + * endpoint belongs to. If not using a multi-network device, 0 must be + * returned. Otherwise on a multi-network device the stack will switch to this + * network before sending the message. Ver.: always + * @param returnEndpointInfo A pointer to a data struct that will be written + * with information about the endpoint. Ver.: always + */ +bool __attribute__((weak)) +emberAfGetEndpointInfoCallback(EndpointId endpoint, uint8_t * returnNetworkIndex, EmberAfEndpointInfoStruct * returnEndpointInfo) +{ + return false; +} + +/** @brief Registration Abort + * + * This callback is called when the device should abort the registration + * process. + * + */ +void __attribute__((weak)) emberAfRegistrationAbortCallback() {} + +/** @brief Interpan Send Message + * + * This function will send a raw MAC message with interpan frame format using + * the passed parameters. + * + * @param header Interpan header info Ver.: always + * @param messageLength The length of the message received or to send Ver.: + * always + * @param message The message data received or to send. Ver.: always + */ +EmberStatus __attribute__((weak)) +emberAfInterpanSendMessageCallback(EmberAfInterpanHeader * header, uint16_t messageLength, uint8_t * message) +{ + return EMBER_LIBRARY_NOT_PRESENT; +} + +/** @brief Start Move + * + * This function is called to initiate the process for a device to move (rejoin) + * to a new parent. + * + */ +bool __attribute__((weak)) emberAfStartMoveCallback() +{ + return false; +} diff --git a/zzz_generated/ota-requestor-app/zap-generated/endpoint_config.h b/zzz_generated/ota-requestor-app/zap-generated/endpoint_config.h new file mode 100644 index 00000000000000..75d8b264bf09c6 --- /dev/null +++ b/zzz_generated/ota-requestor-app/zap-generated/endpoint_config.h @@ -0,0 +1,207 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// THIS FILE IS GENERATED BY ZAP + +// Prevent multiple inclusion +#pragma once + +// Default values for the attributes longer than a pointer, +// in a form of a binary blob +// Separate block is generated for big-endian and little-endian cases. +#if BIGENDIAN_CPU +#define GENERATED_DEFAULTS \ + { \ + } + +#else // !BIGENDIAN_CPU +#define GENERATED_DEFAULTS \ + { \ + } + +#endif // BIGENDIAN_CPU + +#define GENERATED_DEFAULTS_COUNT (0) + +#define ZAP_TYPE(type) ZCL_##type##_ATTRIBUTE_TYPE +#define ZAP_LONG_DEFAULTS_INDEX(index) \ + { \ + (uint8_t *) (&generatedDefaults[index]) \ + } +#define ZAP_MIN_MAX_DEFAULTS_INDEX(index) \ + { \ + (uint8_t *) (&minMaxDefault[index]) \ + } +#define ZAP_EMPTY_DEFAULT() \ + { \ + (uint16_t) 0 \ + } +#define ZAP_SIMPLE_DEFAULT(x) \ + { \ + (uint16_t) x \ + } + +// This is an array of EmberAfAttributeMinMaxValue structures. +#define GENERATED_MIN_MAX_DEFAULT_COUNT 0 +#define GENERATED_MIN_MAX_DEFAULTS \ + { \ + } + +#define ZAP_ATTRIBUTE_MASK(mask) ATTRIBUTE_MASK_##mask +// This is an array of EmberAfAttributeMetadata structures. +#define GENERATED_ATTRIBUTE_COUNT 2 +#define GENERATED_ATTRIBUTES \ + { \ + \ + /* Endpoint: 1, Cluster: OTA Software Update Provider (client) */ \ + { 0xFFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(CLIENT), ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 1, Cluster: OTA Software Update Requestor (server) */ \ + { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + } + +// This is an array of EmberAfCluster structures. +#define ZAP_ATTRIBUTE_INDEX(index) ((EmberAfAttributeMetadata *) (&generatedAttributes[index])) + +// Cluster function static arrays +#define GENERATED_FUNCTION_ARRAYS + +#define ZAP_CLUSTER_MASK(mask) CLUSTER_MASK_##mask +#define GENERATED_CLUSTER_COUNT 2 +#define GENERATED_CLUSTERS \ + { \ + { \ + 0x0029, ZAP_ATTRIBUTE_INDEX(0), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ + }, /* Endpoint: 1, Cluster: OTA Software Update Provider (client) */ \ + { \ + 0x002A, ZAP_ATTRIBUTE_INDEX(1), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + }, /* Endpoint: 1, Cluster: OTA Software Update Requestor (server) */ \ + } + +#define ZAP_CLUSTER_INDEX(index) ((EmberAfCluster *) (&generatedClusters[index])) + +// This is an array of EmberAfEndpointType structures. +#define GENERATED_ENDPOINT_TYPES \ + { \ + { ZAP_CLUSTER_INDEX(0), 2, 4 }, \ + } + +// Largest attribute size is needed for various buffers +#define ATTRIBUTE_LARGEST (3) + +// Total size of singleton attributes +#define ATTRIBUTE_SINGLETONS_SIZE (0) + +// Total size of attribute storage +#define ATTRIBUTE_MAX_SIZE (4) + +// Number of fixed endpoints +#define FIXED_ENDPOINT_COUNT (1) + +// Array of endpoints that are supported, the data inside +// the array is the endpoint number. +#define FIXED_ENDPOINT_ARRAY \ + { \ + 0x0001 \ + } + +// Array of profile ids +#define FIXED_PROFILE_IDS \ + { \ + 0x0103 \ + } + +// Array of device ids +#define FIXED_DEVICE_IDS \ + { \ + 0 \ + } + +// Array of device versions +#define FIXED_DEVICE_VERSIONS \ + { \ + 1 \ + } + +// Array of endpoint types supported on each endpoint +#define FIXED_ENDPOINT_TYPES \ + { \ + 0 \ + } + +// Array of networks supported on each endpoint +#define FIXED_NETWORKS \ + { \ + 0 \ + } + +// Array of EmberAfCommandMetadata structs. +#define ZAP_COMMAND_MASK(mask) COMMAND_MASK_##mask +#define EMBER_AF_GENERATED_COMMAND_COUNT (6) +#define GENERATED_COMMANDS \ + { \ + \ + /* Endpoint: 1, Cluster: OTA Software Update Provider (client) */ \ + { 0x0029, 0x00, ZAP_COMMAND_MASK(INCOMING_SERVER) }, /* QueryImage */ \ + { 0x0029, 0x01, ZAP_COMMAND_MASK(INCOMING_SERVER) }, /* ApplyUpdateRequest */ \ + { 0x0029, 0x02, ZAP_COMMAND_MASK(INCOMING_SERVER) }, /* NotifyUpdateApplied */ \ + { 0x0029, 0x03, ZAP_COMMAND_MASK(INCOMING_CLIENT) }, /* QueryImageResponse */ \ + { 0x0029, 0x04, ZAP_COMMAND_MASK(INCOMING_CLIENT) }, /* ApplyUpdateRequestResponse */ \ + \ + /* Endpoint: 1, Cluster: OTA Software Update Requestor (server) */ \ + { 0x002A, 0x00, ZAP_COMMAND_MASK(INCOMING_SERVER) }, /* AnnounceOtaProvider */ \ + } + +// Array of EmberAfManufacturerCodeEntry structures for commands. +#define GENERATED_COMMAND_MANUFACTURER_CODE_COUNT (0) +#define GENERATED_COMMAND_MANUFACTURER_CODES \ + { \ + { \ + 0x00, 0x00 \ + } \ + } + +// This is an array of EmberAfManufacturerCodeEntry structures for clusters. +#define GENERATED_CLUSTER_MANUFACTURER_CODE_COUNT (0) +#define GENERATED_CLUSTER_MANUFACTURER_CODES \ + { \ + { \ + 0x00, 0x00 \ + } \ + } + +// This is an array of EmberAfManufacturerCodeEntry structures for attributes. +#define GENERATED_ATTRIBUTE_MANUFACTURER_CODE_COUNT (0) +#define GENERATED_ATTRIBUTE_MANUFACTURER_CODES \ + { \ + { \ + 0x00, 0x00 \ + } \ + } + +// Array of EmberAfPluginReportingEntry structures. +#define ZRD(x) EMBER_ZCL_REPORTING_DIRECTION_##x +#define ZAP_REPORT_DIRECTION(x) ZRD(x) + +// User options for plugin Reporting +#define EMBER_AF_PLUGIN_REPORTING_TABLE_SIZE (0) +#define EMBER_AF_PLUGIN_REPORTING_ENABLE_GROUP_BOUND_REPORTS + +#define EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE (0) +#define EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS \ + { \ + } diff --git a/zzz_generated/ota-requestor-app/zap-generated/gen_config.h b/zzz_generated/ota-requestor-app/zap-generated/gen_config.h new file mode 100644 index 00000000000000..5b1eeb9f181a50 --- /dev/null +++ b/zzz_generated/ota-requestor-app/zap-generated/gen_config.h @@ -0,0 +1,44 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// THIS FILE IS GENERATED BY ZAP + +// Prevent multiple inclusion +#pragma once + +// User options for plugin Binding Table Library +#define EMBER_BINDING_TABLE_SIZE 10 + +/**** Network Section ****/ +#define EMBER_SUPPORTED_NETWORKS (1) + +#define EMBER_APS_UNICAST_MESSAGE_COUNT 10 + +/**** Cluster endpoint counts ****/ +#define EMBER_AF_OTA_PROVIDER_CLUSTER_CLIENT_ENDPOINT_COUNT (1) +#define EMBER_AF_OTA_REQUESTOR_CLUSTER_SERVER_ENDPOINT_COUNT (1) + +/**** Cluster Plugins ****/ + +// Use this macro to check if the client side of the OTA Software Update Provider cluster is included +#define ZCL_USING_OTA_PROVIDER_CLUSTER_CLIENT +#define EMBER_AF_PLUGIN_OTA_SOFTWARE_UPDATE_PROVIDER_CLIENT + +// Use this macro to check if the server side of the OTA Software Update Requestor cluster is included +#define ZCL_USING_OTA_REQUESTOR_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_OTA_SOFTWARE_UPDATE_REQUESTOR_SERVER +#define EMBER_AF_PLUGIN_OTA_SOFTWARE_UPDATE_REQUESTOR diff --git a/zzz_generated/ota-requestor-app/zap-generated/gen_tokens.h b/zzz_generated/ota-requestor-app/zap-generated/gen_tokens.h new file mode 100644 index 00000000000000..860bf575d35d81 --- /dev/null +++ b/zzz_generated/ota-requestor-app/zap-generated/gen_tokens.h @@ -0,0 +1,45 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// THIS FILE IS GENERATED BY ZAP + +// Prevent multiple inclusion +#pragma once + +// This file contains the tokens for attributes stored in flash + +// Identifier tags for tokens + +// Types for the tokens +#ifdef DEFINETYPES +#endif // DEFINETYPES + +// Actual token definitions +#ifdef DEFINETOKENS +#endif // DEFINETOKENS + +// Macro snippet that loads all the attributes from tokens +#define GENERATED_TOKEN_LOADER(endpoint) \ + do \ + { \ + } while (false) + +// Macro snippet that saves the attribute to token +#define GENERATED_TOKEN_SAVER \ + do \ + { \ + } while (false) From c23ccf222b8260ff0ef057cc8c8a90cf3c8832e4 Mon Sep 17 00:00:00 2001 From: Artur Tynecki <77382963+ATmobica@users.noreply.github.com> Date: Wed, 15 Sep 2021 02:07:46 +0200 Subject: [PATCH 048/255] Mbed OS capsense module support (#9398) * Add mbed cypress capsense lib to third_party Add capsesne support to ligthing-app and lock-app * Update mbed-os-cypress-capsense-button lib version * Changes restyle * Restore gitmodules file formatting * Remove sleep workaround and restyle --- .gitmodules | 4 + examples/lighting-app/mbed/CMakeLists.txt | 5 ++ examples/lighting-app/mbed/main/AppTask.cpp | 79 +++++++++++++++---- .../lighting-app/mbed/main/include/AppEvent.h | 5 ++ .../lighting-app/mbed/main/include/AppTask.h | 2 + examples/lighting-app/mbed/main/main.cpp | 8 ++ examples/lighting-app/mbed/mbed_app.json | 4 +- examples/lock-app/mbed/CMakeLists.txt | 5 ++ examples/lock-app/mbed/main/AppTask.cpp | 31 +++++--- examples/lock-app/mbed/main/main.cpp | 8 ++ examples/lock-app/mbed/mbed_app.json | 6 +- .../mbed-os-cypress-capsense-button/repo | 1 + 12 files changed, 125 insertions(+), 33 deletions(-) create mode 160000 third_party/mbed-os-cypress-capsense-button/repo diff --git a/.gitmodules b/.gitmodules index 1a555556f64788..8d180217361302 100644 --- a/.gitmodules +++ b/.gitmodules @@ -95,6 +95,10 @@ path = third_party/mbed-os-posix-socket/repo url = https://github.com/ARMmbed/mbed-os-posix-socket.git branch = main +[submodule "mbed-os-cypress-capsense-button"] + path = third_party/mbed-os-cypress-capsense-button/repo + url = https://github.com/ARMmbed/mbed-os-cypress-capsense-button.git + branch = main [submodule "p6/abstraction-rtos"] path = third_party/p6/p6_sdk/libs/abstraction-rtos url = https://github.com/Infineon/abstraction-rtos diff --git a/examples/lighting-app/mbed/CMakeLists.txt b/examples/lighting-app/mbed/CMakeLists.txt index 09b957bc817706..95382b0918a451 100644 --- a/examples/lighting-app/mbed/CMakeLists.txt +++ b/examples/lighting-app/mbed/CMakeLists.txt @@ -121,6 +121,11 @@ if("WHD" IN_LIST MBED_TARGET_LABELS) ) endif() +if("capsense" IN_LIST MBED_TARGET_LABELS) + add_subdirectory(${CHIP_ROOT}/third_party/mbed-os-cypress-capsense-button/repo ./capsense_build) + target_link_libraries(${APP_TARGET} capsense) +endif() + mbed_set_post_build(${APP_TARGET}) option(VERBOSE_BUILD "Have a verbose build process") diff --git a/examples/lighting-app/mbed/main/AppTask.cpp b/examples/lighting-app/mbed/main/AppTask.cpp index 8494c3f7060404..043b1791e7f783 100644 --- a/examples/lighting-app/mbed/main/AppTask.cpp +++ b/examples/lighting-app/mbed/main/AppTask.cpp @@ -21,6 +21,10 @@ #include "LightingManager.h" #include +#ifdef CAPSENSE_ENABLED +#include "capsense.h" +#endif + // FIXME: Undefine the `sleep()` function included by the CHIPDeviceLayer.h // from unistd.h to avoid a conflicting declaration with the `sleep()` provided // by Mbed-OS in mbed_power_mgmt.h. @@ -58,13 +62,16 @@ static LEDWidget sStatusLED(MBED_CONF_APP_SYSTEM_STATE_LED); static mbed::InterruptIn sLightingButton(LIGHTING_BUTTON); static mbed::InterruptIn sFunctionButton(FUNCTION_BUTTON); - +#ifdef CAPSENSE_ENABLED +static mbed::CapsenseButton CapFunctionButton(Capsense::getInstance(), 0); +static mbed::CapsenseButton CapLockButton(Capsense::getInstance(), 1); +static mbed::CapsenseSlider CapSlider(Capsense::getInstance()); +#endif static bool sIsWiFiStationProvisioned = false; static bool sIsWiFiStationEnabled = false; static bool sIsWiFiStationConnected = false; static bool sIsPairedToAccount = false; static bool sHaveBLEConnections = false; -static bool sHaveServiceConnectivity = false; static mbed::Timeout sFunctionTimer; @@ -95,10 +102,17 @@ int AppTask::Init() //------------- // Initialize button +#ifdef CAPSENSE_ENABLED + CapFunctionButton.fall(mbed::callback(this, &AppTask::FunctionButtonPressEventHandler)); + CapFunctionButton.rise(mbed::callback(this, &AppTask::FunctionButtonReleaseEventHandler)); + CapLockButton.fall(mbed::callback(this, &AppTask::LightingButtonPressEventHandler)); + CapSlider.on_move(mbed::callback(this, &AppTask::SliderEventHandler)); +#else sLightingButton.fall(mbed::callback(this, &AppTask::LightingButtonPressEventHandler)); sFunctionButton.fall(mbed::callback(this, &AppTask::FunctionButtonPressEventHandler)); sFunctionButton.rise(mbed::callback(this, &AppTask::FunctionButtonReleaseEventHandler)); - //---------------- +#endif + // Initialize lighting manager LightingMgr().Init(MBED_CONF_APP_LIGHTING_STATE_LED); LightingMgr().SetCallbacks(ActionInitiated, ActionCompleted); @@ -153,20 +167,14 @@ int AppTask::StartApp() sIsWiFiStationEnabled = ConnectivityMgr().IsWiFiStationEnabled(); sIsWiFiStationConnected = ConnectivityMgr().IsWiFiStationConnected(); sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0); - sHaveServiceConnectivity = ConnectivityMgr().HaveServiceConnectivity(); PlatformMgr().UnlockChipStack(); } - // Consider the system to be "fully connected" if it has service - // connectivity and it is able to interact with the service on a regular basis. - bool isFullyConnected = sHaveServiceConnectivity; - // Update the status LED if factory reset has not been initiated. // - // If system has "full connectivity", keep the LED On constantly. + // If system is connected to Wi-Fi station, keep the LED On constantly. // - // If thread and service provisioned, but not attached to the thread network yet OR no - // connectivity to the service OR subscriptions are not fully established + // If Wi-Fi is provisioned, but not connected to Wi-Fi station yet // THEN blink the LED Off for a short period of time. // // If the system has ble connection(s) uptill the stage above, THEN blink the LEDs at an even @@ -175,12 +183,11 @@ int AppTask::StartApp() // Otherwise, blink the LED ON for a very short time. if (sAppTask.mFunction != kFunction_FactoryReset) { - if (isFullyConnected) + if (sIsWiFiStationConnected) { sStatusLED.Set(true); } - else if (sIsWiFiStationProvisioned && sIsWiFiStationEnabled && sIsPairedToAccount && - (!sIsWiFiStationConnected || !isFullyConnected)) + else if (sIsWiFiStationProvisioned && sIsWiFiStationEnabled && sIsPairedToAccount && !sIsWiFiStationConnected) { sStatusLED.Blink(950, 50); } @@ -202,7 +209,7 @@ void AppTask::LightingActionEventHandler(AppEvent * aEvent) { LightingManager::Action_t action = LightingManager::INVALID_ACTION; int32_t actor = 0; - + uint8_t value = 0; if (aEvent->Type == AppEvent::kEventType_Lighting) { action = static_cast(aEvent->LightingEvent.Action); @@ -213,8 +220,14 @@ void AppTask::LightingActionEventHandler(AppEvent * aEvent) action = LightingMgr().IsTurnedOn() ? LightingManager::OFF_ACTION : LightingManager::ON_ACTION; actor = AppEvent::kEventType_Button; } + else if (aEvent->Type == AppEvent::kEventType_Slider) + { + action = LightingManager::LEVEL_ACTION; + actor = AppEvent::kEventType_Slider; + value = aEvent->SliderEvent.Value; + } - if (action != LightingManager::INVALID_ACTION && !LightingMgr().InitiateAction(action, actor, 0, NULL)) + if (action != LightingManager::INVALID_ACTION && !LightingMgr().InitiateAction(action, actor, 0, &value)) ChipLogProgress(NotSpecified, "Action is already in progress or active."); } @@ -248,6 +261,40 @@ void AppTask::FunctionButtonReleaseEventHandler() sAppTask.PostEvent(&button_event); } +void AppTask::ButtonEventHandler(uint32_t id, bool pushed) +{ + if (id > 1) + { + ChipLogError(NotSpecified, "Wrong button ID"); + return; + } + + AppEvent button_event; + button_event.Type = AppEvent::kEventType_Button; + button_event.ButtonEvent.Pin = id == 0 ? LIGHTING_BUTTON : FUNCTION_BUTTON; + button_event.ButtonEvent.Action = pushed ? BUTTON_PUSH_EVENT : BUTTON_RELEASE_EVENT; + + if (id == 0) + { + button_event.Handler = LightingActionEventHandler; + } + else + { + button_event.Handler = FunctionHandler; + } + + sAppTask.PostEvent(&button_event); +} + +void AppTask::SliderEventHandler(int slider_pos) +{ + AppEvent slider_event; + slider_event.Type = AppEvent::kEventType_Slider; + slider_event.SliderEvent.Value = slider_pos; + slider_event.Handler = LightingActionEventHandler; + sAppTask.PostEvent(&slider_event); +} + void AppTask::ActionInitiated(LightingManager::Action_t aAction, int32_t aActor) { if (aAction == LightingManager::ON_ACTION) diff --git a/examples/lighting-app/mbed/main/include/AppEvent.h b/examples/lighting-app/mbed/main/include/AppEvent.h index bd411a3313efee..f30b819e6feaf7 100644 --- a/examples/lighting-app/mbed/main/include/AppEvent.h +++ b/examples/lighting-app/mbed/main/include/AppEvent.h @@ -32,6 +32,7 @@ struct AppEvent kEventType_Timer, kEventType_Lighting, kEventType_Install, + kEventType_Slider, }; uint16_t Type; @@ -52,6 +53,10 @@ struct AppEvent uint8_t Action; int32_t Actor; } LightingEvent; + struct + { + uint8_t Value; + } SliderEvent; }; EventHandler Handler; diff --git a/examples/lighting-app/mbed/main/include/AppTask.h b/examples/lighting-app/mbed/main/include/AppTask.h index b016696e93f6df..1ffaf097f40375 100644 --- a/examples/lighting-app/mbed/main/include/AppTask.h +++ b/examples/lighting-app/mbed/main/include/AppTask.h @@ -50,6 +50,8 @@ class AppTask void LightingButtonPressEventHandler(void); void FunctionButtonPressEventHandler(void); void FunctionButtonReleaseEventHandler(void); + void ButtonEventHandler(uint32_t id, bool pushed); + void SliderEventHandler(int slider_pos); void TimerEventHandler(void); void StartTimer(uint32_t aTimeoutInMs); diff --git a/examples/lighting-app/mbed/main/main.cpp b/examples/lighting-app/mbed/main/main.cpp index dcdc747239f0c2..d482d5d33afebb 100644 --- a/examples/lighting-app/mbed/main/main.cpp +++ b/examples/lighting-app/mbed/main/main.cpp @@ -19,6 +19,10 @@ #include "AppTask.h" +#ifdef CAPSENSE_ENABLED +#include "capsense.h" +#endif + #include "mbedtls/platform.h" #include #include @@ -37,6 +41,10 @@ int main() mbed_logging_init(); +#ifdef CAPSENSE_ENABLED + Capsense::getInstance().init(); +#endif + ret = mbedtls_platform_setup(NULL); if (ret) { diff --git a/examples/lighting-app/mbed/mbed_app.json b/examples/lighting-app/mbed/mbed_app.json index 7d2b985b698029..3893ee4bc13324 100644 --- a/examples/lighting-app/mbed/mbed_app.json +++ b/examples/lighting-app/mbed/mbed_app.json @@ -30,11 +30,11 @@ "NL_ASSERT_EXPECT_FLAGS=NL_ASSERT_FLAG_LOG", "WHD_PRINT_DISABLE" ], + "target.components_add": ["capsense"], "led-active-state": 0, "system-state-led": "LED1", "lighting-state-led": "P9_6", - "lighting-button": "USER_BUTTON", - "function-button": "P9_7" + "lighting-button": "USER_BUTTON" } }, "config": { diff --git a/examples/lock-app/mbed/CMakeLists.txt b/examples/lock-app/mbed/CMakeLists.txt index 07f08335ac9658..4674b163e3f54b 100644 --- a/examples/lock-app/mbed/CMakeLists.txt +++ b/examples/lock-app/mbed/CMakeLists.txt @@ -124,6 +124,11 @@ if("WHD" IN_LIST MBED_TARGET_LABELS) ) endif() +if("capsense" IN_LIST MBED_TARGET_LABELS) + add_subdirectory(${CHIP_ROOT}/third_party/mbed-os-cypress-capsense-button/repo ./capsense_build) + target_link_libraries(${APP_TARGET} capsense) +endif() + mbed_set_post_build(${APP_TARGET}) option(VERBOSE_BUILD "Have a verbose build process") diff --git a/examples/lock-app/mbed/main/AppTask.cpp b/examples/lock-app/mbed/main/AppTask.cpp index df3e88189c7ab4..b860f2e50fe7fb 100644 --- a/examples/lock-app/mbed/main/AppTask.cpp +++ b/examples/lock-app/mbed/main/AppTask.cpp @@ -21,6 +21,10 @@ #include "LEDWidget.h" #include +#ifdef CAPSENSE_ENABLED +#include "capsense.h" +#endif + // FIXME: Undefine the `sleep()` function included by the CHIPDeviceLayer.h // from unistd.h to avoid a conflicting declaration with the `sleep()` provided // by Mbed-OS in mbed_power_mgmt.h. @@ -58,15 +62,19 @@ constexpr uint32_t kPublishServicePeriodUs = 5000000; static LEDWidget sStatusLED(MBED_CONF_APP_SYSTEM_STATE_LED); static LEDWidget sLockLED(MBED_CONF_APP_LOCK_STATE_LED); +#ifdef CAPSENSE_ENABLED +static mbed::CapsenseButton CapFunctionButton(Capsense::getInstance(), 0); +static mbed::CapsenseButton CapLockButton(Capsense::getInstance(), 1); +#else static mbed::InterruptIn sLockButton(LOCK_BUTTON); static mbed::InterruptIn sFunctionButton(FUNCTION_BUTTON); +#endif static bool sIsWiFiStationProvisioned = false; static bool sIsWiFiStationEnabled = false; static bool sIsWiFiStationConnected = false; static bool sIsPairedToAccount = false; static bool sHaveBLEConnections = false; -static bool sHaveServiceConnectivity = false; static mbed::Timeout sFunctionTimer; @@ -99,9 +107,15 @@ int AppTask::Init() sLockLED.Set(!BoltLockMgr().IsUnlocked()); // Initialize buttons +#ifdef CAPSENSE_ENABLED + CapFunctionButton.fall(mbed::callback(this, &AppTask::FunctionButtonPressEventHandler)); + CapFunctionButton.rise(mbed::callback(this, &AppTask::FunctionButtonReleaseEventHandler)); + CapLockButton.fall(mbed::callback(this, &AppTask::LockButtonPressEventHandler)); +#else sLockButton.fall(mbed::callback(this, &AppTask::LockButtonPressEventHandler)); sFunctionButton.fall(mbed::callback(this, &AppTask::FunctionButtonPressEventHandler)); sFunctionButton.rise(mbed::callback(this, &AppTask::FunctionButtonReleaseEventHandler)); +#endif // Initialize lock manager BoltLockMgr().Init(); @@ -156,20 +170,14 @@ int AppTask::StartApp() sIsWiFiStationEnabled = ConnectivityMgr().IsWiFiStationEnabled(); sIsWiFiStationConnected = ConnectivityMgr().IsWiFiStationConnected(); sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0); - sHaveServiceConnectivity = ConnectivityMgr().HaveServiceConnectivity(); PlatformMgr().UnlockChipStack(); } - // Consider the system to be "fully connected" if it has service - // connectivity and it is able to interact with the service on a regular basis. - bool isFullyConnected = sHaveServiceConnectivity; - // Update the status LED if factory reset has not been initiated. // - // If system has "full connectivity", keep the LED On constantly. + // If system is connected to Wi-Fi station, keep the LED On constantly. // - // If thread and service provisioned, but not attached to the thread network yet OR no - // connectivity to the service OR subscriptions are not fully established + // If Wi-Fi is provisioned, but not connected to Wi-Fi station yet // THEN blink the LED Off for a short period of time. // // If the system has ble connection(s) uptill the stage above, THEN blink the LEDs at an even @@ -178,12 +186,11 @@ int AppTask::StartApp() // Otherwise, blink the LED ON for a very short time. if (sAppTask.mFunction != kFunction_FactoryReset) { - if (isFullyConnected) + if (sIsWiFiStationConnected) { sStatusLED.Set(true); } - else if (sIsWiFiStationProvisioned && sIsWiFiStationEnabled && sIsPairedToAccount && - (!sIsWiFiStationConnected || !isFullyConnected)) + else if (sIsWiFiStationProvisioned && sIsWiFiStationEnabled && sIsPairedToAccount && !sIsWiFiStationConnected) { sStatusLED.Blink(950, 50); } diff --git a/examples/lock-app/mbed/main/main.cpp b/examples/lock-app/mbed/main/main.cpp index dcdc747239f0c2..d482d5d33afebb 100644 --- a/examples/lock-app/mbed/main/main.cpp +++ b/examples/lock-app/mbed/main/main.cpp @@ -19,6 +19,10 @@ #include "AppTask.h" +#ifdef CAPSENSE_ENABLED +#include "capsense.h" +#endif + #include "mbedtls/platform.h" #include #include @@ -37,6 +41,10 @@ int main() mbed_logging_init(); +#ifdef CAPSENSE_ENABLED + Capsense::getInstance().init(); +#endif + ret = mbedtls_platform_setup(NULL); if (ret) { diff --git a/examples/lock-app/mbed/mbed_app.json b/examples/lock-app/mbed/mbed_app.json index 748871574e8a96..13fb8bc0f74796 100644 --- a/examples/lock-app/mbed/mbed_app.json +++ b/examples/lock-app/mbed/mbed_app.json @@ -30,11 +30,11 @@ "NL_ASSERT_EXPECT_FLAGS=NL_ASSERT_FLAG_LOG", "WHD_PRINT_DISABLE" ], - "led-active-state": 1, + "target.components_add": ["capsense"], + "led-active-state": 0, "system-state-led": "LED1", "lock-state-led": "P9_6", - "lock-button": "USER_BUTTON", - "function-button": "P9_7" + "lock-button": "USER_BUTTON" } }, "config": { diff --git a/third_party/mbed-os-cypress-capsense-button/repo b/third_party/mbed-os-cypress-capsense-button/repo new file mode 160000 index 00000000000000..fef47a05455670 --- /dev/null +++ b/third_party/mbed-os-cypress-capsense-button/repo @@ -0,0 +1 @@ +Subproject commit fef47a05455670206f6c2eb4958cb1f08d698bc1 From d99edbffbc3a978c8819ac6ca7bae654651fbd31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20Kr=C3=B3lik?= <66667989+Damian-Nordic@users.noreply.github.com> Date: Wed, 15 Sep 2021 08:05:19 +0200 Subject: [PATCH 049/255] [Zephyr] Erase key-value store on factory reset (#9683) * [Zephyr] Erase key-value store on factory reset ConfigurationManager::InitiateFactoryReset() method clears all keys added by ConfigurationManager methods, and OpenThread settings. However, the method was not updated when the generic KeyValueStoreManager was added, hence not all persistent data would be erased upon the factory reset. * Restyled by clang-format * Address code review comment Co-authored-by: Restyled.io --- src/include/platform/CHIPDeviceLayer.h | 1 + .../Zephyr/ConfigurationManagerImpl.cpp | 4 +- .../Zephyr/KeyValueStoreManagerImpl.cpp | 84 ++++++++++++++----- .../Zephyr/KeyValueStoreManagerImpl.h | 2 + src/platform/Zephyr/ZephyrConfig.cpp | 9 +- .../nrfconnect/CHIPDevicePlatformConfig.h | 5 ++ .../telink/CHIPDevicePlatformConfig.h | 5 ++ src/platform/tests/TestKeyValueStoreMgr.cpp | 28 ++++++- 8 files changed, 107 insertions(+), 31 deletions(-) diff --git a/src/include/platform/CHIPDeviceLayer.h b/src/include/platform/CHIPDeviceLayer.h index f285cb1917d40c..cce60cc6061ef6 100644 --- a/src/include/platform/CHIPDeviceLayer.h +++ b/src/include/platform/CHIPDeviceLayer.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/src/platform/Zephyr/ConfigurationManagerImpl.cpp b/src/platform/Zephyr/ConfigurationManagerImpl.cpp index 99211c882b5879..2ca0a1894cdfdd 100644 --- a/src/platform/Zephyr/ConfigurationManagerImpl.cpp +++ b/src/platform/Zephyr/ConfigurationManagerImpl.cpp @@ -90,10 +90,10 @@ void ConfigurationManagerImpl::_InitiateFactoryReset() void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) { ChipLogProgress(DeviceLayer, "Performing factory reset"); - const CHIP_ERROR err = FactoryResetConfig(); + const CHIP_ERROR err = PersistedStorage::KeyValueStoreMgrImpl().DoFactoryReset(); if (err != CHIP_NO_ERROR) - ChipLogError(DeviceLayer, "FactoryResetConfig() failed: %s", ErrorStr(err)); + ChipLogError(DeviceLayer, "Factory reset failed: %s", ErrorStr(err)); #if CHIP_DEVICE_CONFIG_ENABLE_THREAD ThreadStackMgr().ErasePersistentInfo(); diff --git a/src/platform/Zephyr/KeyValueStoreManagerImpl.cpp b/src/platform/Zephyr/KeyValueStoreManagerImpl.cpp index dd28022f18430a..cd27bc68bb556a 100644 --- a/src/platform/Zephyr/KeyValueStoreManagerImpl.cpp +++ b/src/platform/Zephyr/KeyValueStoreManagerImpl.cpp @@ -21,26 +21,18 @@ * Platform-specific key value storage implementation for Zephyr */ +#include + #include #include -#include +#include -#include #include -#include - namespace chip { namespace DeviceLayer { namespace PersistedStorage { - -KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; -const char * kChipKeyPrefix = "ch/"; - -void KeyValueStoreManagerImpl::Init() -{ - VerifyOrDie(settings_subsys_init() == 0); -} +namespace { struct ReadEntry { @@ -50,9 +42,22 @@ struct ReadEntry CHIP_ERROR result; // [out] read result }; -static int LoadEntryCallback(const char * name, size_t entrySize, settings_read_cb readCb, void * cbArg, void * param) +struct DeleteSubtreeEntry { - ReadEntry & entry = *reinterpret_cast(param); + CHIP_ERROR result; +}; + +// Prefix the input key with CHIP_DEVICE_CONFIG_SETTINGS_KEY "/" +CHIP_ERROR MakeFullKey(char (&fullKey)[SETTINGS_MAX_NAME_LEN + 1], const char * key) +{ + const int result = snprintf(fullKey, sizeof(fullKey), CHIP_DEVICE_CONFIG_SETTINGS_KEY "/%s", key); + VerifyOrReturnError(result > 0 && static_cast(result) < sizeof(fullKey), CHIP_ERROR_INVALID_ARGUMENT); + return CHIP_NO_ERROR; +} + +int LoadEntryCallback(const char * name, size_t entrySize, settings_read_cb readCb, void * cbArg, void * param) +{ + ReadEntry & entry = *static_cast(param); // If requested a key X, process just node X and ignore all its descendants: X/* if (settings_name_next(name, nullptr) > 0) @@ -74,6 +79,29 @@ static int LoadEntryCallback(const char * name, size_t entrySize, settings_read_ return 0; } +int DeleteSubtreeCallback(const char * name, size_t /* entrySize */, settings_read_cb /* readCb */, void * /* cbArg */, + void * param) +{ + DeleteSubtreeEntry & entry = *static_cast(param); + const CHIP_ERROR error = KeyValueStoreMgr().Delete(name); + + if (entry.result == CHIP_NO_ERROR) + { + entry.result = error; + } + + return 0; +} + +} // namespace + +KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; + +void KeyValueStoreManagerImpl::Init() +{ + VerifyOrDie(settings_subsys_init() == 0); +} + CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size, size_t offset_bytes) const { @@ -83,11 +111,11 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t // Support can be added in the future if this is needed. VerifyOrReturnError(offset_bytes == 0, CHIP_ERROR_NOT_IMPLEMENTED); - // Concatenate key with the "chip/" prefix to separate it from the other Zephyr settings. - std::string fullKey(std::string(kChipKeyPrefix) + key); + char fullKey[SETTINGS_MAX_NAME_LEN + 1]; + ReturnErrorOnFailure(MakeFullKey(fullKey, key)); ReadEntry entry{ value, value_size, 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND }; - settings_load_subtree_direct(fullKey.c_str(), LoadEntryCallback, &entry); + settings_load_subtree_direct(fullKey, LoadEntryCallback, &entry); // Assign readSize only in case read_bytes_size is not nullptr, as it is optional argument if (read_bytes_size) @@ -102,24 +130,34 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, VerifyOrReturnError(value, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(value_size > 0, CHIP_ERROR_INVALID_ARGUMENT); - // Concatenate key with the "chip/" prefix to separate it from the other Zephyr settings. - std::string fullKey(std::string(kChipKeyPrefix) + key); - VerifyOrReturnError(settings_save_one(fullKey.c_str(), value, value_size) == 0, CHIP_ERROR_PERSISTED_STORAGE_FAILED); + char fullKey[SETTINGS_MAX_NAME_LEN + 1]; + ReturnErrorOnFailure(MakeFullKey(fullKey, key)); + + VerifyOrReturnError(settings_save_one(fullKey, value, value_size) == 0, CHIP_ERROR_PERSISTED_STORAGE_FAILED); return CHIP_NO_ERROR; } CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) { - // Concatenate key with the "chip/" prefix to separate it from the other Zephyr settings. - std::string fullKey(std::string(kChipKeyPrefix) + key); + char fullKey[SETTINGS_MAX_NAME_LEN + 1]; + ReturnErrorOnFailure(MakeFullKey(fullKey, key)); - if (settings_delete(fullKey.c_str()) != 0) + if (settings_delete(fullKey) != 0) return CHIP_ERROR_PERSISTED_STORAGE_FAILED; return CHIP_NO_ERROR; } +CHIP_ERROR KeyValueStoreManagerImpl::DoFactoryReset() +{ + DeleteSubtreeEntry entry{ CHIP_NO_ERROR }; + const int result = settings_load_subtree_direct(CHIP_DEVICE_CONFIG_SETTINGS_KEY, DeleteSubtreeCallback, &entry); + + VerifyOrReturnError(result == 0, System::MapErrorZephyr(result)); + return entry.result; +} + } // namespace PersistedStorage } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/Zephyr/KeyValueStoreManagerImpl.h b/src/platform/Zephyr/KeyValueStoreManagerImpl.h index 75639f0dcd086b..daaba1144b497a 100644 --- a/src/platform/Zephyr/KeyValueStoreManagerImpl.h +++ b/src/platform/Zephyr/KeyValueStoreManagerImpl.h @@ -47,6 +47,8 @@ class KeyValueStoreManagerImpl final : public KeyValueStoreManager CHIP_ERROR _Put(const char * key, const void * value, size_t value_size); + CHIP_ERROR DoFactoryReset(); + private: // ===== Members for internal use by the following friends. diff --git a/src/platform/Zephyr/ZephyrConfig.cpp b/src/platform/Zephyr/ZephyrConfig.cpp index bd0d11453130c9..9d82e88b6db333 100644 --- a/src/platform/Zephyr/ZephyrConfig.cpp +++ b/src/platform/Zephyr/ZephyrConfig.cpp @@ -41,11 +41,12 @@ namespace Internal { (key); \ static_assert(sizeof(key) <= SETTINGS_MAX_NAME_LEN, "Config key too long: " key) -// Config namespaces +// Define the configuration keys to be part of the CHIP_DEVICE_CONFIG_SETTINGS_KEY subtree +// so that they get erased when KeyValueStoreManagerImpl::DoFactoryReset() is called. // clang-format off -#define NAMESPACE_FACTORY "chip-fact/" -#define NAMESPACE_CONFIG "chip-conf/" -#define NAMESPACE_COUNTERS "chip-cntr/" +#define NAMESPACE_FACTORY CHIP_DEVICE_CONFIG_SETTINGS_KEY "/fct/" +#define NAMESPACE_CONFIG CHIP_DEVICE_CONFIG_SETTINGS_KEY "/cfg/" +#define NAMESPACE_COUNTERS CHIP_DEVICE_CONFIG_SETTINGS_KEY "/ctr/" // clang-format on // Keys stored in the chip factory nam diff --git a/src/platform/nrfconnect/CHIPDevicePlatformConfig.h b/src/platform/nrfconnect/CHIPDevicePlatformConfig.h index e01be4fbc944fc..d788fc6cd0db97 100644 --- a/src/platform/nrfconnect/CHIPDevicePlatformConfig.h +++ b/src/platform/nrfconnect/CHIPDevicePlatformConfig.h @@ -47,6 +47,11 @@ // These are configuration options that are unique to Zephyr platforms. // These can be overridden by the application as needed. +#ifndef CHIP_DEVICE_CONFIG_SETTINGS_KEY +/// Key for all Matter persistent data stored using the Zephyr Settings API +#define CHIP_DEVICE_CONFIG_SETTINGS_KEY "mt" +#endif // CHIP_DEVICE_CONFIG_SETTINGS_KEY + // ========== Platform-specific Configuration Overrides ========= #ifndef CHIP_DEVICE_CONFIG_CHIP_TASK_PRIORITY diff --git a/src/platform/telink/CHIPDevicePlatformConfig.h b/src/platform/telink/CHIPDevicePlatformConfig.h index 84e43f65ddf3b4..53b146c5309eba 100644 --- a/src/platform/telink/CHIPDevicePlatformConfig.h +++ b/src/platform/telink/CHIPDevicePlatformConfig.h @@ -47,6 +47,11 @@ // These are configuration options that are unique to Zephyr platforms. // These can be overridden by the application as needed. +#ifndef CHIP_DEVICE_CONFIG_SETTINGS_KEY +/// Key for all Matter persistent data stored using the Zephyr Settings API +#define CHIP_DEVICE_CONFIG_SETTINGS_KEY "mt" +#endif // CHIP_DEVICE_CONFIG_SETTINGS_KEY + // ========== Platform-specific Configuration Overrides ========= #ifndef CHIP_DEVICE_CONFIG_CHIP_TASK_PRIORITY diff --git a/src/platform/tests/TestKeyValueStoreMgr.cpp b/src/platform/tests/TestKeyValueStoreMgr.cpp index 94e87d3d91f73b..6c1efa54445666 100644 --- a/src/platform/tests/TestKeyValueStoreMgr.cpp +++ b/src/platform/tests/TestKeyValueStoreMgr.cpp @@ -79,8 +79,8 @@ static void TestKeyValueStoreMgr_StringKey(nlTestSuite * inSuite, void * inConte static void TestKeyValueStoreMgr_Uint32Key(nlTestSuite * inSuite, void * inContext) { CHIP_ERROR err; - const char * kTestKey = "uint32_key"; - const char kTestValue = 5; + const char * kTestKey = "uint32_key"; + const uint32_t kTestValue = 5; uint32_t read_value; err = KeyValueStoreMgr().Put(kTestKey, kTestValue); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); @@ -199,6 +199,27 @@ static void TestKeyValueStoreMgr_MultiReadKey(nlTestSuite * inSuite, void * inCo NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); } +#ifdef __ZEPHYR__ +static void TestKeyValueStoreMgr_DoFactoryReset(nlTestSuite * inSuite, void * inContext) +{ + constexpr const char * kStrKey = "some_string_key"; + constexpr const char * kUintKey = "some_uint_key"; + + NL_TEST_ASSERT(inSuite, KeyValueStoreMgr().Put(kStrKey, "some_string") == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, KeyValueStoreMgr().Put(kUintKey, uint32_t(1234)) == CHIP_NO_ERROR); + + char readString[16]; + uint32_t readValue; + + NL_TEST_ASSERT(inSuite, KeyValueStoreMgr().Get(kStrKey, readString, sizeof(readString)) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, KeyValueStoreMgr().Get(kUintKey, &readValue) == CHIP_NO_ERROR); + + NL_TEST_ASSERT(inSuite, KeyValueStoreMgrImpl().DoFactoryReset() == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, + KeyValueStoreMgr().Get(kStrKey, readString, sizeof(readString)) == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + NL_TEST_ASSERT(inSuite, KeyValueStoreMgr().Get(kUintKey, &readValue) == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); +} +#endif /** * Test Suite. It lists all the test functions. */ @@ -212,6 +233,9 @@ static const nlTest sTests[] = { NL_TEST_DEF("Test KeyValueStoreMgr_EmptyStringK #ifndef __ZEPHYR__ // Zephyr platform does not support partial or offset reads yet. NL_TEST_DEF("Test KeyValueStoreMgr_MultiReadKey", TestKeyValueStoreMgr_MultiReadKey), +#endif +#ifdef __ZEPHYR__ + NL_TEST_DEF("Test TestKeyValueStoreMgr_DoFactoryReset", TestKeyValueStoreMgr_DoFactoryReset), #endif NL_TEST_SENTINEL() }; From 8a20f68cdaf3f7b5a0e8e9de06b65fb2967cbdf8 Mon Sep 17 00:00:00 2001 From: Song GUO Date: Wed, 15 Sep 2021 17:23:22 +0800 Subject: [PATCH 050/255] [hotfix] Rerun codegen after #9474 (#9718) --- .../zap-generated/CHIPClientCallbacks.cpp | 249 ------------------ .../zap-generated/CHIPClusters.cpp | 2 - .../zap-generated/endpoint_config.h | 25 +- 3 files changed, 19 insertions(+), 257 deletions(-) diff --git a/zzz_generated/ota-requestor-app/zap-generated/CHIPClientCallbacks.cpp b/zzz_generated/ota-requestor-app/zap-generated/CHIPClientCallbacks.cpp index acfd1f84546007..f12212010df9f8 100644 --- a/zzz_generated/ota-requestor-app/zap-generated/CHIPClientCallbacks.cpp +++ b/zzz_generated/ota-requestor-app/zap-generated/CHIPClientCallbacks.cpp @@ -390,252 +390,3 @@ bool emberAfOtaSoftwareUpdateProviderClusterQueryImageResponseCallback(EndpointI metadataForRequestor); return true; } - -bool emberAfReportAttributesCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen) -{ - ChipLogProgress(Zcl, "emberAfReportAttributeCallback:"); - ChipLogProgress(Zcl, " ClusterId: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); - - NodeId sourceId = emberAfCurrentCommand()->SourceNodeId(); - ChipLogProgress(Zcl, " Source NodeId: %" PRIu64, sourceId); - - EndpointId endpointId = emberAfCurrentCommand()->apsFrame->sourceEndpoint; - ChipLogProgress(Zcl, " Source EndpointId: 0x%04x", endpointId); - - // TODO onFailureCallback is just here because of the CHECK_MESSAGE_LENGTH macro. It needs to be removed. - Callback::Cancelable * onFailureCallback = nullptr; - - while (messageLen) - { - CHECK_MESSAGE_LENGTH(4); - AttributeId attributeId = Encoding::LittleEndian::Read32(message); // attribId - ChipLogProgress(Zcl, " attributeId: " ChipLogFormatMEI, ChipLogValueMEI(attributeId)); - - GET_REPORT_CALLBACK("emberAfReportAttributesCallback"); - - CHECK_MESSAGE_LENGTH(1); - uint8_t attributeType = Encoding::Read8(message); - ChipLogProgress(Zcl, " attributeType: 0x%02x", attributeType); - - switch (attributeType) - { - case 0x00: // nodata / No data - case 0x0A: // data24 / 24-bit data - case 0x0C: // data40 / 40-bit data - case 0x0D: // data48 / 48-bit data - case 0x0E: // data56 / 56-bit data - case 0x1A: // map24 / 24-bit bitmap - case 0x1C: // map40 / 40-bit bitmap - case 0x1D: // map48 / 48-bit bitmap - case 0x1E: // map56 / 56-bit bitmap - case 0x22: // uint24 / Unsigned 24-bit integer - case 0x24: // uint40 / Unsigned 40-bit integer - case 0x25: // uint48 / Unsigned 48-bit integer - case 0x26: // uint56 / Unsigned 56-bit integer - case 0x2A: // int24 / Signed 24-bit integer - case 0x2C: // int40 / Signed 40-bit integer - case 0x2D: // int48 / Signed 48-bit integer - case 0x2E: // int56 / Signed 56-bit integer - case 0x38: // semi / Semi-precision - case 0x39: // single / Single precision - case 0x3A: // double / Double precision - case 0x48: // array / Array - case 0x49: // struct / Structure - case 0x50: // set / Set - case 0x51: // bag / Bag - case 0xE0: // ToD / Time of day - { - ChipLogError(Zcl, "attributeType 0x%02x is not supported", attributeType); - return true; - } - - case 0x41: // octstr / Octet string - case 0x42: // string / Character string - { - // Short Strings must contains at least one byte for the length - CHECK_MESSAGE_LENGTH(1); - uint8_t length = Encoding::Read8(message); - ChipLogProgress(Zcl, " length: 0x%02x", length); - - // When the length is set to 0xFF, it represents a non-value. In this case the data field is zero length. - if (length == 0xFF) - { - length = 0; - } - - CHECK_MESSAGE_LENGTH(length); - if (attributeType == 0x41) - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - else - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - break; - } - - case 0x43: // octstr16 / Long octet string - case 0x44: // string16 / Long character string - { - // Long Strings must contains at least two bytes for the length - CHECK_MESSAGE_LENGTH(2); - uint16_t length = Encoding::LittleEndian::Read16(message); - ChipLogProgress(Zcl, " length: 0x%02x", length); - - // When the length is set to 0xFFFF, it represents a non-value. In this case the data field is zero length. - if (length == 0xFFFF) - { - length = 0; - } - - CHECK_MESSAGE_LENGTH(length); - if (attributeType == 0x43) - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - else - { - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, ByteSpan(message, length)); - } - break; - } - - case 0x08: // data8 / 8-bit data - case 0x18: // map8 / 8-bit bitmap - case 0x20: // uint8 / Unsigned 8-bit integer - case 0x30: // enum8 / 8-bit enumeration - { - CHECK_MESSAGE_LENGTH(1); - uint8_t value = Encoding::Read8(message); - ChipLogProgress(Zcl, " value: 0x%02x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x09: // data16 / 16-bit data - case 0x19: // map16 / 16-bit bitmap - case 0x21: // uint16 / Unsigned 16-bit integer - case 0x31: // enum16 / 16-bit enumeration - case 0xE8: // clusterId / Cluster ID - case 0xE9: // attribId / Attribute ID - case 0xEA: // bacOID / BACnet OID - case 0xF1: // key128 / 128-bit security key - case 0xFF: // unk / Unknown - { - CHECK_MESSAGE_LENGTH(2); - uint16_t value = Encoding::LittleEndian::Read16(message); - ChipLogProgress(Zcl, " value: 0x%04x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x0B: // data32 / 32-bit data - case 0x1B: // map32 / 32-bit bitmap - case 0x23: // uint32 / Unsigned 32-bit integer - case 0xE1: // date / Date - case 0xE2: // UTC / UTCTime - { - CHECK_MESSAGE_LENGTH(4); - uint32_t value = Encoding::LittleEndian::Read32(message); - ChipLogProgress(Zcl, " value: 0x%08x", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x0F: // data64 / 64-bit data - case 0x1F: // map64 / 64-bit bitmap - case 0x27: // uint64 / Unsigned 64-bit integer - case 0xF0: // EUI64 / IEEE address - { - CHECK_MESSAGE_LENGTH(8); - uint64_t value = Encoding::LittleEndian::Read64(message); - ChipLogProgress(Zcl, " value: 0x" ChipLogFormatX64, ChipLogValueX64(value)); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x10: // bool / Boolean - { - CHECK_MESSAGE_LENGTH(1); - uint8_t value = Encoding::Read8(message); - ChipLogProgress(Zcl, " value: %d", value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x28: // int8 / Signed 8-bit integer - { - CHECK_MESSAGE_LENGTH(1); - int8_t value = CastToSigned(Encoding::Read8(message)); - ChipLogProgress(Zcl, " value: %" PRId8, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x29: // int16 / Signed 16-bit integer - { - CHECK_MESSAGE_LENGTH(2); - int16_t value = CastToSigned(Encoding::LittleEndian::Read16(message)); - ChipLogProgress(Zcl, " value: %" PRId16, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x2B: // int32 / Signed 32-bit integer - { - CHECK_MESSAGE_LENGTH(4); - int32_t value = CastToSigned(Encoding::LittleEndian::Read32(message)); - ChipLogProgress(Zcl, " value: %" PRId32, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - - case 0x2F: // int64 / Signed 64-bit integer - { - CHECK_MESSAGE_LENGTH(8); - int64_t value = CastToSigned(Encoding::LittleEndian::Read64(message)); - ChipLogProgress(Zcl, " value: %" PRId64, value); - - Callback::Callback * cb = - Callback::Callback::FromCancelable(onReportCallback); - cb->mCall(cb->mContext, value); - break; - } - } - } - - return true; -} diff --git a/zzz_generated/ota-requestor-app/zap-generated/CHIPClusters.cpp b/zzz_generated/ota-requestor-app/zap-generated/CHIPClusters.cpp index f766b95a884927..53e400af20843e 100644 --- a/zzz_generated/ota-requestor-app/zap-generated/CHIPClusters.cpp +++ b/zzz_generated/ota-requestor-app/zap-generated/CHIPClusters.cpp @@ -67,8 +67,6 @@ constexpr uint8_t kFrameControlGlobalCommand = 0x00; // Pick source endpoint as 1 for now constexpr EndpointId kSourceEndpoint = 1; - -[[maybe_unused]] const uint8_t kReportingDirectionReported = 0x00; } // namespace using namespace app::Clusters; diff --git a/zzz_generated/ota-requestor-app/zap-generated/endpoint_config.h b/zzz_generated/ota-requestor-app/zap-generated/endpoint_config.h index 75d8b264bf09c6..5194e30333b9db 100644 --- a/zzz_generated/ota-requestor-app/zap-generated/endpoint_config.h +++ b/zzz_generated/ota-requestor-app/zap-generated/endpoint_config.h @@ -26,16 +26,26 @@ #if BIGENDIAN_CPU #define GENERATED_DEFAULTS \ { \ + \ + /* Endpoint: 1, Cluster: OTA Software Update Requestor (server), big-endian */ \ + \ + /* 0 - default ota provider, */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ } #else // !BIGENDIAN_CPU #define GENERATED_DEFAULTS \ { \ + \ + /* Endpoint: 1, Cluster: OTA Software Update Requestor (server), little-endian */ \ + \ + /* 0 - default ota provider, */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ } #endif // BIGENDIAN_CPU -#define GENERATED_DEFAULTS_COUNT (0) +#define GENERATED_DEFAULTS_COUNT (1) #define ZAP_TYPE(type) ZCL_##type##_ATTRIBUTE_TYPE #define ZAP_LONG_DEFAULTS_INDEX(index) \ @@ -63,7 +73,7 @@ #define ZAP_ATTRIBUTE_MASK(mask) ATTRIBUTE_MASK_##mask // This is an array of EmberAfAttributeMetadata structures. -#define GENERATED_ATTRIBUTE_COUNT 2 +#define GENERATED_ATTRIBUTE_COUNT 4 #define GENERATED_ATTRIBUTES \ { \ \ @@ -71,6 +81,9 @@ { 0xFFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(CLIENT), ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ \ /* Endpoint: 1, Cluster: OTA Software Update Requestor (server) */ \ + { 0x0001, ZAP_TYPE(OCTET_STRING), 17, ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_LONG_DEFAULTS_INDEX(0) }, /* default ota provider */ \ + { 0x0002, ZAP_TYPE(BOOLEAN), 1, 0, ZAP_EMPTY_DEFAULT() }, /* update possible */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ } @@ -88,7 +101,7 @@ 0x0029, ZAP_ATTRIBUTE_INDEX(0), 1, 2, ZAP_CLUSTER_MASK(CLIENT), NULL \ }, /* Endpoint: 1, Cluster: OTA Software Update Provider (client) */ \ { \ - 0x002A, ZAP_ATTRIBUTE_INDEX(1), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x002A, ZAP_ATTRIBUTE_INDEX(1), 3, 20, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: OTA Software Update Requestor (server) */ \ } @@ -97,17 +110,17 @@ // This is an array of EmberAfEndpointType structures. #define GENERATED_ENDPOINT_TYPES \ { \ - { ZAP_CLUSTER_INDEX(0), 2, 4 }, \ + { ZAP_CLUSTER_INDEX(0), 2, 22 }, \ } // Largest attribute size is needed for various buffers -#define ATTRIBUTE_LARGEST (3) +#define ATTRIBUTE_LARGEST (18) // Total size of singleton attributes #define ATTRIBUTE_SINGLETONS_SIZE (0) // Total size of attribute storage -#define ATTRIBUTE_MAX_SIZE (4) +#define ATTRIBUTE_MAX_SIZE (22) // Number of fixed endpoints #define FIXED_ENDPOINT_COUNT (1) From 3fd5bf894291c2d7f2d1b642e64676bba34047cc Mon Sep 17 00:00:00 2001 From: Martin Turon Date: Wed, 15 Sep 2021 06:08:47 -0700 Subject: [PATCH 051/255] [msg] Update message version and session id fields to match spec. (#9675) * [msg] Update message format comment. * [msg] Set message version to 0 as required by spec. * [msg] Rename KeyId to SessionId. * [msg] Move Session ID field to fixed portion of message header. * Restyled by clang-format * Restyled by gn * [msg] Rename LocalKeyId. Fix layout of message format comment. * Restyled by clang-format * [msg] merge fixes. * [msg] Fix local variable naming. Add const for unsecured session id. Co-authored-by: Restyled.io --- src/channel/Channel.h | 8 +-- src/channel/ChannelContext.cpp | 2 +- src/controller/CHIPDevice.cpp | 2 +- src/include/platform/CHIPDeviceEvent.h | 2 +- src/lib/core/CHIPKeyIds.cpp | 2 +- src/lib/core/CHIPKeyIds.h | 2 +- src/messaging/tests/TestExchangeMgr.cpp | 4 +- src/protocols/secure_channel/CASESession.cpp | 22 ++++---- src/protocols/secure_channel/CASESession.h | 4 +- src/protocols/secure_channel/PASESession.cpp | 22 ++++---- src/protocols/secure_channel/PASESession.h | 18 +++---- .../UserDirectedCommissioningClient.cpp | 2 +- src/transport/PairingSession.h | 28 +++++----- src/transport/PeerConnectionState.h | 16 +++--- src/transport/PeerConnections.h | 24 ++++----- src/transport/SecureMessageCodec.cpp | 4 +- src/transport/SecureSession.cpp | 8 +-- src/transport/SecureSessionMgr.cpp | 26 +++++----- src/transport/SessionHandle.h | 18 +++---- src/transport/raw/MessageHeader.cpp | 51 +++++++++---------- src/transport/raw/MessageHeader.h | 38 +++++++------- src/transport/raw/tests/BUILD.gn | 5 +- src/transport/raw/tests/TestMessageHeader.cpp | 6 +-- src/transport/tests/TestSecureSessionMgr.cpp | 2 +- 24 files changed, 158 insertions(+), 158 deletions(-) diff --git a/src/channel/Channel.h b/src/channel/Channel.h index d993caa4c982df..f0374d8ce05448 100644 --- a/src/channel/Channel.h +++ b/src/channel/Channel.h @@ -90,10 +90,10 @@ class ChannelBuilder } TransportPreference GetTransportPreference() const { return mTransportPreference; } - uint16_t GetPeerKeyID() const { return mCaseParameters.mPeerKeyId; } - ChannelBuilder & SetPeerKeyID(uint16_t keyId) + uint16_t GetPeerSessionId() const { return mCaseParameters.mPeerSessionId; } + ChannelBuilder & SetPeerSessionId(uint16_t sessionId) { - mCaseParameters.mPeerKeyId = keyId; + mCaseParameters.mPeerSessionId = sessionId; return *this; } @@ -126,7 +126,7 @@ class ChannelBuilder TransportPreference mTransportPreference = TransportPreference::kDefault; struct { - uint16_t mPeerKeyId; + uint16_t mPeerSessionId; Credentials::OperationalCredentialSet * mOperationalCredentialSet; uint8_t mOperationalCredentialSetIndex; } mCaseParameters; diff --git a/src/channel/ChannelContext.cpp b/src/channel/ChannelContext.cpp index 800b24c380ccf2..44627f6ab81ac2 100644 --- a/src/channel/ChannelContext.cpp +++ b/src/channel/ChannelContext.cpp @@ -131,7 +131,7 @@ bool ChannelContext::MatchesSession(SessionHandle session, SecureSessionMgr * ss case PrepareState::kCasePairing: { auto state = ssm->GetPeerConnectionState(session); return (state->GetPeerNodeId() == GetPrepareVars().mBuilder.GetPeerNodeId() && - state->GetPeerKeyID() == GetPrepareVars().mBuilder.GetPeerKeyID()); + state->GetPeerSessionId() == GetPrepareVars().mBuilder.GetPeerSessionId()); } default: return false; diff --git a/src/controller/CHIPDevice.cpp b/src/controller/CHIPDevice.cpp index 270e16b2b9fa55..5347a71da17aeb 100644 --- a/src/controller/CHIPDevice.cpp +++ b/src/controller/CHIPDevice.cpp @@ -591,7 +591,7 @@ CHIP_ERROR Device::WarmupCASESession() void Device::OnSessionEstablishmentError(CHIP_ERROR error) { mState = ConnectionState::NotConnected; - mIDAllocator->Free(mCASESession.GetLocalKeyId()); + mIDAllocator->Free(mCASESession.GetLocalSessionId()); Cancelable ready; mConnectionFailure.DequeueAll(ready); diff --git a/src/include/platform/CHIPDeviceEvent.h b/src/include/platform/CHIPDeviceEvent.h index b52dc23e3b7783..66a27f0cd19fca 100644 --- a/src/include/platform/CHIPDeviceEvent.h +++ b/src/include/platform/CHIPDeviceEvent.h @@ -379,7 +379,7 @@ struct ChipDeviceEvent final { uint64_t PeerNodeId; uint16_t SessionKeyId; - uint8_t EncType; + uint8_t SessionType; bool IsCommissioner; } SessionEstablished; struct diff --git a/src/lib/core/CHIPKeyIds.cpp b/src/lib/core/CHIPKeyIds.cpp index 0b4b70821e2353..5c560aec893e79 100644 --- a/src/lib/core/CHIPKeyIds.cpp +++ b/src/lib/core/CHIPKeyIds.cpp @@ -244,7 +244,7 @@ bool ChipKeyId::IsValidKeyId(uint32_t keyId) * @return true If the identified key can be used to encrypt CHIP messages. * */ -bool ChipKeyId::IsMessageEncryptionKeyId(uint32_t keyId, bool allowLogicalKeys) +bool ChipKeyId::IsMessageSessionId(uint32_t keyId, bool allowLogicalKeys) { switch (GetType(keyId)) { diff --git a/src/lib/core/CHIPKeyIds.h b/src/lib/core/CHIPKeyIds.h index 94d170437e0545..9cfb4f899498be 100644 --- a/src/lib/core/CHIPKeyIds.h +++ b/src/lib/core/CHIPKeyIds.h @@ -357,7 +357,7 @@ class ChipKeyId static uint32_t UpdateEpochKeyId(uint32_t keyId, uint32_t epochKeyId); static bool IsValidKeyId(uint32_t keyId); - static bool IsMessageEncryptionKeyId(uint32_t keyId, bool allowLogicalKeys = true); + static bool IsMessageSessionId(uint32_t keyId, bool allowLogicalKeys = true); static bool IsSameKeyOrGroup(uint32_t keyId1, uint32_t keyId2); static const char * DescribeKey(uint32_t keyId); }; diff --git a/src/messaging/tests/TestExchangeMgr.cpp b/src/messaging/tests/TestExchangeMgr.cpp index 7733d5becd9a09..697084040fd67f 100644 --- a/src/messaging/tests/TestExchangeMgr.cpp +++ b/src/messaging/tests/TestExchangeMgr.cpp @@ -101,7 +101,7 @@ void CheckNewContextTest(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, ec1->GetExchangeId() != 0); auto sessionPeerToLocal = ctx.GetSecureSessionManager().GetPeerConnectionState(ec1->GetSecureSession()); NL_TEST_ASSERT(inSuite, sessionPeerToLocal->GetPeerNodeId() == ctx.GetBobNodeId()); - NL_TEST_ASSERT(inSuite, sessionPeerToLocal->GetPeerKeyID() == ctx.GetBobKeyId()); + NL_TEST_ASSERT(inSuite, sessionPeerToLocal->GetPeerSessionId() == ctx.GetBobKeyId()); NL_TEST_ASSERT(inSuite, ec1->GetDelegate() == &mockAppDelegate); ExchangeContext * ec2 = ctx.NewExchangeToAlice(&mockAppDelegate); @@ -109,7 +109,7 @@ void CheckNewContextTest(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, ec2->GetExchangeId() > ec1->GetExchangeId()); auto sessionLocalToPeer = ctx.GetSecureSessionManager().GetPeerConnectionState(ec2->GetSecureSession()); NL_TEST_ASSERT(inSuite, sessionLocalToPeer->GetPeerNodeId() == ctx.GetAliceNodeId()); - NL_TEST_ASSERT(inSuite, sessionLocalToPeer->GetPeerKeyID() == ctx.GetAliceKeyId()); + NL_TEST_ASSERT(inSuite, sessionLocalToPeer->GetPeerSessionId() == ctx.GetAliceKeyId()); ec1->Close(); ec2->Close(); diff --git a/src/protocols/secure_channel/CASESession.cpp b/src/protocols/secure_channel/CASESession.cpp index 77311422f33aba..37ccc6dadadb0c 100644 --- a/src/protocols/secure_channel/CASESession.cpp +++ b/src/protocols/secure_channel/CASESession.cpp @@ -165,8 +165,8 @@ CHIP_ERROR CASESession::ToSerializable(CASESessionSerializable & serializable) serializable.mIPKLen = static_cast(sizeof(mIPK)); serializable.mPairingComplete = (mPairingComplete) ? 1 : 0; serializable.mPeerNodeId = peerNodeId; - serializable.mLocalKeyId = GetLocalKeyId(); - serializable.mPeerKeyId = GetPeerKeyId(); + serializable.mLocalSessionId = GetLocalSessionId(); + serializable.mPeerSessionId = GetPeerSessionId(); memcpy(serializable.mSharedSecret, mSharedSecret, mSharedSecret.Length()); memcpy(serializable.mMessageDigest, mMessageDigest, sizeof(mMessageDigest)); @@ -189,8 +189,8 @@ CHIP_ERROR CASESession::FromSerializable(const CASESessionSerializable & seriali memcpy(mIPK, serializable.mIPK, serializable.mIPKLen); SetPeerNodeId(serializable.mPeerNodeId); - SetLocalKeyId(serializable.mLocalKeyId); - SetPeerKeyId(serializable.mPeerKeyId); + SetLocalSessionId(serializable.mLocalSessionId); + SetPeerSessionId(serializable.mPeerSessionId); return CHIP_NO_ERROR; } @@ -204,7 +204,7 @@ CHIP_ERROR CASESession::Init(uint16_t myKeyId, SessionEstablishmentDelegate * de ReturnErrorOnFailure(mCommissioningHash.Begin()); mDelegate = delegate; - SetLocalKeyId(myKeyId); + SetLocalSessionId(myKeyId); mValidContext.Reset(); mValidContext.mRequiredKeyUsages.Set(KeyUsageFlags::kDigitalSignature); @@ -336,7 +336,7 @@ CHIP_ERROR CASESession::SendSigmaR1() ReturnErrorOnFailure(tlvWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, outerContainerType)); ReturnErrorOnFailure(tlvWriter.PutBytes(TLV::ContextTag(1), initiatorRandom, sizeof(initiatorRandom))); // Retrieve Session Identifier - ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(2), GetLocalKeyId(), true)); + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(2), GetLocalSessionId(), true)); // Generate a Destination Identifier { MutableByteSpan destinationIdSpan(destinationIdentifier); @@ -379,7 +379,7 @@ CHIP_ERROR CASESession::HandleSigmaR1(System::PacketBufferHandle && msg) System::PacketBufferTLVReader tlvReader; TLV::TLVType containerType = TLV::kTLVType_Structure; - uint16_t initiatorSessionId = 0; + uint16_t initiatorSessionId; uint8_t destinationIdentifier[kSHA256_Hash_Length]; uint8_t initiatorRandom[kSigmaParamRandomNumberSize]; @@ -402,7 +402,7 @@ CHIP_ERROR CASESession::HandleSigmaR1(System::PacketBufferHandle && msg) SuccessOrExit(err = tlvReader.Get(initiatorSessionId)); ChipLogDetail(SecureChannel, "Peer assigned session key ID %d", initiatorSessionId); - SetPeerKeyId(initiatorSessionId); + SetPeerSessionId(initiatorSessionId); SuccessOrExit(err = tlvReader.Next()); VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); @@ -546,7 +546,7 @@ CHIP_ERROR CASESession::SendSigmaR2() tlvWriter.Init(std::move(msg_R2)); SuccessOrExit(err = tlvWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, outerContainerType)); SuccessOrExit(err = tlvWriter.PutBytes(TLV::ContextTag(1), &msg_rand[0], sizeof(msg_rand))); - SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(2), GetLocalKeyId(), true)); + SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(2), GetLocalSessionId(), true)); SuccessOrExit(err = tlvWriter.PutBytes(TLV::ContextTag(3), mEphemeralKey.Pubkey(), static_cast(mEphemeralKey.Pubkey().Length()))); SuccessOrExit(err = tlvWriter.PutBytes(TLV::ContextTag(4), msg_R2_Encrypted.Get(), @@ -613,7 +613,7 @@ CHIP_ERROR CASESession::HandleSigmaR2(System::PacketBufferHandle && msg) ByteSpan responderNOC; ByteSpan responderICAC; - uint16_t responderSessionId = 0; + uint16_t responderSessionId; uint32_t decodeTagIdSeq = 0; @@ -636,7 +636,7 @@ CHIP_ERROR CASESession::HandleSigmaR2(System::PacketBufferHandle && msg) SuccessOrExit(err = tlvReader.Get(responderSessionId)); ChipLogDetail(SecureChannel, "Peer assigned session key ID %d", responderSessionId); - SetPeerKeyId(responderSessionId); + SetPeerSessionId(responderSessionId); // Retrieve Responder's Ephemeral Pubkey SuccessOrExit(err = tlvReader.Next()); diff --git a/src/protocols/secure_channel/CASESession.h b/src/protocols/secure_channel/CASESession.h index 31159ae2686d59..58d37558373279 100644 --- a/src/protocols/secure_channel/CASESession.h +++ b/src/protocols/secure_channel/CASESession.h @@ -71,8 +71,8 @@ struct CASESessionSerializable uint8_t mIPK[kIPKSize]; uint8_t mPairingComplete; NodeId mPeerNodeId; - uint16_t mLocalKeyId; - uint16_t mPeerKeyId; + uint16_t mLocalSessionId; + uint16_t mPeerSessionId; }; class DLL_EXPORT CASESession : public Messaging::ExchangeDelegate, public PairingSession diff --git a/src/protocols/secure_channel/PASESession.cpp b/src/protocols/secure_channel/PASESession.cpp index f47ba8ce5a8e52..97cd2560471eb5 100644 --- a/src/protocols/secure_channel/PASESession.cpp +++ b/src/protocols/secure_channel/PASESession.cpp @@ -157,8 +157,8 @@ CHIP_ERROR PASESession::ToSerializable(PASESessionSerializable & serializable) memset(&serializable, 0, sizeof(serializable)); serializable.mKeLen = static_cast(mKeLen); serializable.mPairingComplete = (mPairingComplete) ? 1 : 0; - serializable.mLocalKeyId = GetLocalKeyId(); - serializable.mPeerKeyId = GetPeerKeyId(); + serializable.mLocalSessionId = GetLocalSessionId(); + serializable.mPeerSessionId = GetPeerSessionId(); memcpy(serializable.mKe, mKe, mKeLen); @@ -174,8 +174,8 @@ CHIP_ERROR PASESession::FromSerializable(const PASESessionSerializable & seriali memset(mKe, 0, sizeof(mKe)); memcpy(mKe, serializable.mKe, mKeLen); - SetLocalKeyId(serializable.mLocalKeyId); - SetPeerKeyId(serializable.mPeerKeyId); + SetLocalSessionId(serializable.mLocalSessionId); + SetPeerSessionId(serializable.mPeerSessionId); return CHIP_NO_ERROR; } @@ -193,7 +193,7 @@ CHIP_ERROR PASESession::Init(uint16_t myKeyId, uint32_t setupCode, SessionEstabl mDelegate = delegate; ChipLogDetail(SecureChannel, "Assigned local session key ID %d", myKeyId); - SetLocalKeyId(myKeyId); + SetLocalSessionId(myKeyId); mSetupPINCode = setupCode; mComputeVerifier = true; @@ -362,7 +362,7 @@ CHIP_ERROR PASESession::SendPBKDFParamRequest() TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; ReturnErrorOnFailure(tlvWriter.StartContainer(TLV::AnonymousTag, TLV::kTLVType_Structure, outerContainerType)); ReturnErrorOnFailure(tlvWriter.PutBytes(TLV::ContextTag(1), mPBKDFLocalRandomData, sizeof(mPBKDFLocalRandomData))); - ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(2), GetLocalKeyId(), true)); + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(2), GetLocalSessionId(), true)); ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(3), mPasscodeID, true)); ReturnErrorOnFailure(tlvWriter.PutBoolean(TLV::ContextTag(4), mHavePBKDFParameters)); // TODO - Add optional MRP parameter support to PASE @@ -389,7 +389,7 @@ CHIP_ERROR PASESession::HandlePBKDFParamRequest(System::PacketBufferHandle && ms System::PacketBufferTLVReader tlvReader; TLV::TLVType containerType = TLV::kTLVType_Structure; - uint16_t initiatorSessionId = 0; + uint16_t initiatorSessionId; uint8_t initiatorRandom[kPBKDFParamRandomNumberSize]; uint32_t decodeTagIdSeq = 0; @@ -413,7 +413,7 @@ CHIP_ERROR PASESession::HandlePBKDFParamRequest(System::PacketBufferHandle && ms ChipLogDetail(SecureChannel, "Peer assigned session ID %d", initiatorSessionId); // TODO - Update KeyId() functions to SessionId() - SetPeerKeyId(initiatorSessionId); + SetPeerSessionId(initiatorSessionId); SuccessOrExit(err = tlvReader.Next()); VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); @@ -454,7 +454,7 @@ CHIP_ERROR PASESession::SendPBKDFParamResponse(ByteSpan initiatorRandom, bool in // The initiator random value is being sent back in the response as required by the specifications ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(1), initiatorRandom)); ReturnErrorOnFailure(tlvWriter.PutBytes(TLV::ContextTag(2), mPBKDFLocalRandomData, sizeof(mPBKDFLocalRandomData))); - ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(3), GetLocalKeyId(), true)); + ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(3), GetLocalSessionId(), true)); if (!initiatorHasPBKDFParams) { @@ -492,7 +492,7 @@ CHIP_ERROR PASESession::HandlePBKDFParamResponse(System::PacketBufferHandle && m System::PacketBufferTLVReader tlvReader; TLV::TLVType containerType = TLV::kTLVType_Structure; - uint16_t responderSessionId = 0; + uint16_t responderSessionId; uint8_t random[kPBKDFParamRandomNumberSize]; uint32_t decodeTagIdSeq = 0; @@ -524,7 +524,7 @@ CHIP_ERROR PASESession::HandlePBKDFParamResponse(System::PacketBufferHandle && m SuccessOrExit(err = tlvReader.Get(responderSessionId)); ChipLogDetail(SecureChannel, "Peer assigned session ID %d", responderSessionId); - SetPeerKeyId(responderSessionId); + SetPeerSessionId(responderSessionId); if (mHavePBKDFParameters) { diff --git a/src/protocols/secure_channel/PASESession.h b/src/protocols/secure_channel/PASESession.h index 2873699fde9a72..d0fa48307f9661 100644 --- a/src/protocols/secure_channel/PASESession.h +++ b/src/protocols/secure_channel/PASESession.h @@ -69,8 +69,8 @@ struct PASESessionSerializable uint16_t mKeLen; uint8_t mKe[kMAX_Hash_Length]; uint8_t mPairingComplete; - uint16_t mLocalKeyId; - uint16_t mPeerKeyId; + uint16_t mLocalSessionId; + uint16_t mPeerSessionId; }; struct PASEVerifier @@ -339,14 +339,14 @@ class SecurePairingUsingTestSecret : public PairingSession public: SecurePairingUsingTestSecret() { - SetLocalKeyId(0); - SetPeerKeyId(0); + SetLocalSessionId(0); + SetPeerSessionId(0); } - SecurePairingUsingTestSecret(uint16_t peerKeyId, uint16_t localKeyId) + SecurePairingUsingTestSecret(uint16_t peerSessionId, uint16_t localSessionId) { - SetLocalKeyId(localKeyId); - SetPeerKeyId(peerKeyId); + SetLocalSessionId(localSessionId); + SetPeerSessionId(peerSessionId); } CHIP_ERROR DeriveSecureSession(SecureSession & session, SecureSession::SessionRole role) override @@ -363,8 +363,8 @@ class SecurePairingUsingTestSecret : public PairingSession memset(&serializable, 0, sizeof(serializable)); serializable.mKeLen = static_cast(secretLen); serializable.mPairingComplete = 1; - serializable.mLocalKeyId = GetLocalKeyId(); - serializable.mPeerKeyId = GetPeerKeyId(); + serializable.mLocalSessionId = GetLocalSessionId(); + serializable.mPeerSessionId = GetPeerSessionId(); memcpy(serializable.mKe, kTestSecret, secretLen); return CHIP_NO_ERROR; diff --git a/src/protocols/user_directed_commissioning/UserDirectedCommissioningClient.cpp b/src/protocols/user_directed_commissioning/UserDirectedCommissioningClient.cpp index 6b67389653aceb..a49611545d8223 100644 --- a/src/protocols/user_directed_commissioning/UserDirectedCommissioningClient.cpp +++ b/src/protocols/user_directed_commissioning/UserDirectedCommissioningClient.cpp @@ -67,7 +67,7 @@ CHIP_ERROR UserDirectedCommissioningClient::EncodeUDCMessage(System::PacketBuffe ReturnErrorOnFailure(payloadHeader.EncodeBeforeData(payload)); - packetHeader.SetEncryptionType(Header::EncryptionType::kEncryptionTypeNone); + packetHeader.SetSessionType(Header::SessionType::kSessionTypeNone); ReturnErrorOnFailure(packetHeader.EncodeBeforeData(payload)); diff --git a/src/transport/PairingSession.h b/src/transport/PairingSession.h index 7fd40de6557c97..2639619447ac8b 100644 --- a/src/transport/PairingSession.h +++ b/src/transport/PairingSession.h @@ -42,17 +42,17 @@ class DLL_EXPORT PairingSession NodeId GetPeerNodeId() const { return mPeerNodeId; } // TODO: the local key id should be allocateed at start - // mLocalKeyId should be const and assigned at the construction, such that GetLocalKeyId will always return a valid key id , and - // SetLocalKeyId is not necessary. - uint16_t GetLocalKeyId() const { return mLocalKeyId; } - bool IsValidLocalKeyId() const { return mLocalKeyId != kInvalidKeyId; } + // mLocalSessionId should be const and assigned at the construction, such that GetLocalSessionId will always return a valid key + // id , and SetLocalSessionId is not necessary. + uint16_t GetLocalSessionId() const { return mLocalSessionId; } + bool IsValidLocalSessionId() const { return mLocalSessionId != kInvalidKeyId; } - uint16_t GetPeerKeyId() const + uint16_t GetPeerSessionId() const { - VerifyOrDie(mPeerKeyId.HasValue()); - return mPeerKeyId.Value(); + VerifyOrDie(mPeerSessionId.HasValue()); + return mPeerSessionId.Value(); } - bool IsValidPeerKeyId() const { return mPeerKeyId.HasValue(); } + bool IsValidPeerSessionId() const { return mPeerSessionId.HasValue(); } // TODO: decouple peer address into transport, such that pairing session do not need to handle peer address const Transport::PeerAddress & GetPeerAddress() const { return mPeerAddress; } @@ -86,8 +86,8 @@ class DLL_EXPORT PairingSession protected: void SetPeerNodeId(NodeId peerNodeId) { mPeerNodeId = peerNodeId; } - void SetPeerKeyId(uint16_t id) { mPeerKeyId.SetValue(id); } - void SetLocalKeyId(uint16_t id) { mLocalKeyId = id; } + void SetPeerSessionId(uint16_t id) { mPeerSessionId.SetValue(id); } + void SetLocalSessionId(uint16_t id) { mLocalSessionId = id; } void SetPeerAddress(const Transport::PeerAddress & address) { mPeerAddress = address; } // TODO: remove Clear, we should create a new instance instead reset the old instance. @@ -95,8 +95,8 @@ class DLL_EXPORT PairingSession { mPeerNodeId = kUndefinedNodeId; mPeerAddress = Transport::PeerAddress::Uninitialized(); - mPeerKeyId.ClearValue(); - mLocalKeyId = kInvalidKeyId; + mPeerSessionId.ClearValue(); + mLocalSessionId = kInvalidKeyId; } private: @@ -105,12 +105,12 @@ class DLL_EXPORT PairingSession // TODO: the local key id should be allocateed at start // then we can remove kInvalidKeyId static constexpr uint16_t kInvalidKeyId = UINT16_MAX; - uint16_t mLocalKeyId = kInvalidKeyId; + uint16_t mLocalSessionId = kInvalidKeyId; // TODO: decouple peer address into transport, such that pairing session do not need to handle peer address Transport::PeerAddress mPeerAddress = Transport::PeerAddress::Uninitialized(); - Optional mPeerKeyId; + Optional mPeerSessionId; }; } // namespace chip diff --git a/src/transport/PeerConnectionState.h b/src/transport/PeerConnectionState.h index dee71a1948960c..2d21fc1a31584e 100644 --- a/src/transport/PeerConnectionState.h +++ b/src/transport/PeerConnectionState.h @@ -65,12 +65,12 @@ class PeerConnectionState NodeId GetPeerNodeId() const { return mPeerNodeId; } void SetPeerNodeId(NodeId peerNodeId) { mPeerNodeId = peerNodeId; } - uint16_t GetPeerKeyID() const { return mPeerKeyID; } - void SetPeerKeyID(uint16_t id) { mPeerKeyID = id; } + uint16_t GetPeerSessionId() const { return mPeerSessionId; } + void SetPeerSessionId(uint16_t id) { mPeerSessionId = id; } // TODO: Rename KeyID to SessionID - uint16_t GetLocalKeyID() const { return mLocalKeyID; } - void SetLocalKeyID(uint16_t id) { mLocalKeyID = id; } + uint16_t GetLocalSessionId() const { return mLocalSessionId; } + void SetLocalSessionId(uint16_t id) { mLocalSessionId = id; } uint64_t GetLastActivityTimeMs() const { return mLastActivityTimeMs; } void SetLastActivityTimeMs(uint64_t value) { mLastActivityTimeMs = value; } @@ -82,8 +82,8 @@ class PeerConnectionState bool IsInitialized() { - return (mPeerAddress.IsInitialized() || mPeerNodeId != kUndefinedNodeId || mPeerKeyID != UINT16_MAX || - mLocalKeyID != UINT16_MAX); + return (mPeerAddress.IsInitialized() || mPeerNodeId != kUndefinedNodeId || mPeerSessionId != UINT16_MAX || + mLocalSessionId != UINT16_MAX); } CHIP_ERROR EncryptBeforeSend(const uint8_t * input, size_t input_length, uint8_t * output, PacketHeader & header, @@ -103,8 +103,8 @@ class PeerConnectionState private: PeerAddress mPeerAddress; NodeId mPeerNodeId = kUndefinedNodeId; - uint16_t mPeerKeyID = UINT16_MAX; - uint16_t mLocalKeyID = UINT16_MAX; + uint16_t mPeerSessionId = UINT16_MAX; + uint16_t mLocalSessionId = UINT16_MAX; uint64_t mLastActivityTimeMs = 0; SecureSession mSecureSession; SessionMessageCounter mSessionMessageCounter; diff --git a/src/transport/PeerConnections.h b/src/transport/PeerConnections.h index 17093b84e7ef65..85d6e4f546182e 100644 --- a/src/transport/PeerConnections.h +++ b/src/transport/PeerConnections.h @@ -86,8 +86,8 @@ class PeerConnections * Allocates a new peer connection state state object out of the internal resource pool. * * @param peerNode represents optional peer Node's ID - * @param peerKeyId represents the encryption key ID assigned by peer node - * @param localKeyId represents the encryption key ID assigned by local node + * @param peerSessionId represents the encryption key ID assigned by peer node + * @param localSessionId represents the encryption key ID assigned by local node * @param state [out] will contain the connection state if one was available. May be null if no return value is desired. * * @note the newly created state will have an 'active' time set based on the current time source. @@ -96,7 +96,7 @@ class PeerConnections * has been reached (with CHIP_ERROR_NO_MEMORY). */ CHECK_RETURN_VALUE - CHIP_ERROR CreateNewPeerConnectionState(const Optional & peerNode, uint16_t peerKeyId, uint16_t localKeyId, + CHIP_ERROR CreateNewPeerConnectionState(const Optional & peerNode, uint16_t peerSessionId, uint16_t localSessionId, PeerConnectionState ** state) { CHIP_ERROR err = CHIP_ERROR_NO_MEMORY; @@ -111,8 +111,8 @@ class PeerConnections if (!mStates[i].IsInitialized()) { mStates[i] = PeerConnectionState(); - mStates[i].SetPeerKeyID(peerKeyId); - mStates[i].SetLocalKeyID(localKeyId); + mStates[i].SetPeerSessionId(peerSessionId); + mStates[i].SetLocalSessionId(localSessionId); mStates[i].SetLastActivityTimeMs(mTimeSource.GetCurrentMonotonicTimeMs()); if (peerNode.ValueOr(kUndefinedNodeId) != kUndefinedNodeId) @@ -203,13 +203,13 @@ class PeerConnections * * @param nodeId is the connection to find (based on nodeId). Note that initial connections * do not have a node id set. Use this if you know the node id should be set. - * @param peerKeyId Encryption key ID used by the peer node. + * @param peerSessionId Encryption key ID used by the peer node. * @param begin If a member of the pool, will start search from the next item. Can be nullptr to search from start. * * @return the state found, nullptr if not found */ CHECK_RETURN_VALUE - PeerConnectionState * FindPeerConnectionState(Optional nodeId, uint16_t peerKeyId, PeerConnectionState * begin) + PeerConnectionState * FindPeerConnectionState(Optional nodeId, uint16_t peerSessionId, PeerConnectionState * begin) { PeerConnectionState * state = nullptr; PeerConnectionState * iter = &mStates[0]; @@ -225,7 +225,7 @@ class PeerConnections { continue; } - if (peerKeyId == kAnyKeyId || iter->GetPeerKeyID() == peerKeyId) + if (peerSessionId == kAnyKeyId || iter->GetPeerSessionId() == peerSessionId) { if (nodeId.ValueOr(kUndefinedNodeId) == kUndefinedNodeId || iter->GetPeerNodeId() == kUndefinedNodeId || iter->GetPeerNodeId() == nodeId.Value()) @@ -266,7 +266,7 @@ class PeerConnections continue; } - if (iter->GetLocalKeyID() == keyId) + if (iter->GetLocalSessionId() == keyId) { state = iter; break; @@ -280,13 +280,13 @@ class PeerConnections * * @param nodeId is the connection to find (based on peer nodeId). Note that initial connections * do not have a node id set. Use this if you know the node id should be set. - * @param localKeyId Encryption key ID used by the local node. + * @param localSessionId Encryption key ID used by the local node. * @param begin If a member of the pool, will start search from the next item. Can be nullptr to search from start. * * @return the state found, nullptr if not found */ CHECK_RETURN_VALUE - PeerConnectionState * FindPeerConnectionStateByLocalKey(Optional nodeId, uint16_t localKeyId, + PeerConnectionState * FindPeerConnectionStateByLocalKey(Optional nodeId, uint16_t localSessionId, PeerConnectionState * begin) { PeerConnectionState * state = nullptr; @@ -303,7 +303,7 @@ class PeerConnections { continue; } - if (iter->GetLocalKeyID() == localKeyId) + if (iter->GetLocalSessionId() == localSessionId) { if (nodeId.ValueOr(kUndefinedNodeId) == kUndefinedNodeId || iter->GetPeerNodeId() == kUndefinedNodeId || iter->GetPeerNodeId() == nodeId.Value()) diff --git a/src/transport/SecureMessageCodec.cpp b/src/transport/SecureMessageCodec.cpp index 05bf96085797bd..1edc6668a5c4e3 100644 --- a/src/transport/SecureMessageCodec.cpp +++ b/src/transport/SecureMessageCodec.cpp @@ -50,7 +50,7 @@ CHIP_ERROR Encode(Transport::PeerConnectionState * state, PayloadHeader & payloa packetHeader .SetMessageCounter(messageCounter) // - .SetEncryptionKeyID(state->GetPeerKeyID()); + .SetSessionId(state->GetPeerSessionId()); packetHeader.GetFlags().Set(Header::FlagValues::kEncryptedMessage); @@ -92,7 +92,7 @@ CHIP_ERROR Decode(Transport::PeerConnectionState * state, PayloadHeader & payloa msg->SetDataLength(len); #endif - uint16_t footerLen = MessageAuthenticationCode::TagLenForEncryptionType(packetHeader.GetEncryptionType()); + uint16_t footerLen = MessageAuthenticationCode::TagLenForSessionType(packetHeader.GetSessionType()); VerifyOrReturnError(footerLen <= len, CHIP_ERROR_INVALID_MESSAGE_LENGTH); uint16_t taglen = 0; diff --git a/src/transport/SecureSession.cpp b/src/transport/SecureSession.cpp index dea77b794cf517..e5cb16761b2f66 100644 --- a/src/transport/SecureSession.cpp +++ b/src/transport/SecureSession.cpp @@ -127,9 +127,9 @@ CHIP_ERROR SecureSession::Encrypt(const uint8_t * input, size_t input_length, ui MessageAuthenticationCode & mac) const { - constexpr Header::EncryptionType encType = Header::EncryptionType::kAESCCMTagLen16; + constexpr Header::SessionType sessionType = Header::SessionType::kAESCCMTagLen16; - const size_t taglen = MessageAuthenticationCode::TagLenForEncryptionType(encType); + const size_t taglen = MessageAuthenticationCode::TagLenForSessionType(sessionType); VerifyOrDie(taglen <= kMaxTagLen); VerifyOrReturnError(mKeyAvailable, CHIP_ERROR_INVALID_USE_OF_SESSION_KEY); @@ -158,7 +158,7 @@ CHIP_ERROR SecureSession::Encrypt(const uint8_t * input, size_t input_length, ui ReturnErrorOnFailure(AES_CCM_encrypt(input, input_length, AAD, aadLen, mKeys[usage], kAES_CCM128_Key_Length, IV, sizeof(IV), output, tag, taglen)); - mac.SetTag(&header, encType, tag, taglen); + mac.SetTag(&header, sessionType, tag, taglen); return CHIP_NO_ERROR; } @@ -166,7 +166,7 @@ CHIP_ERROR SecureSession::Encrypt(const uint8_t * input, size_t input_length, ui CHIP_ERROR SecureSession::Decrypt(const uint8_t * input, size_t input_length, uint8_t * output, const PacketHeader & header, const MessageAuthenticationCode & mac) const { - const size_t taglen = MessageAuthenticationCode::TagLenForEncryptionType(header.GetEncryptionType()); + const size_t taglen = MessageAuthenticationCode::TagLenForSessionType(header.GetSessionType()); const uint8_t * tag = mac.GetTag(); uint8_t IV[kAESCCMIVLen]; uint8_t AAD[kMaxAADLen]; diff --git a/src/transport/SecureSessionMgr.cpp b/src/transport/SecureSessionMgr.cpp index b7092cf592838b..bb15a85bb7e486 100644 --- a/src/transport/SecureSessionMgr.cpp +++ b/src/transport/SecureSessionMgr.cpp @@ -247,10 +247,10 @@ void SecureSessionMgr::ExpireAllPairingsForFabric(FabricIndex fabric) CHIP_ERROR SecureSessionMgr::NewPairing(const Optional & peerAddr, NodeId peerNodeId, PairingSession * pairing, SecureSession::SessionRole direction, FabricIndex fabric) { - uint16_t peerKeyId = pairing->GetPeerKeyId(); - uint16_t localKeyId = pairing->GetLocalKeyId(); + uint16_t peerSessionId = pairing->GetPeerSessionId(); + uint16_t localSessionId = pairing->GetLocalSessionId(); PeerConnectionState * state = - mPeerConnections.FindPeerConnectionStateByLocalKey(Optional::Value(peerNodeId), localKeyId, nullptr); + mPeerConnections.FindPeerConnectionStateByLocalKey(Optional::Value(peerNodeId), localSessionId, nullptr); // Find any existing connection with the same local key ID if (state) @@ -260,10 +260,10 @@ CHIP_ERROR SecureSessionMgr::NewPairing(const Optional & } ChipLogDetail(Inet, "New secure session created for device 0x" ChipLogFormatX64 ", key %d!!", ChipLogValueX64(peerNodeId), - peerKeyId); + peerSessionId); state = nullptr; ReturnErrorOnFailure( - mPeerConnections.CreateNewPeerConnectionState(Optional::Value(peerNodeId), peerKeyId, localKeyId, &state)); + mPeerConnections.CreateNewPeerConnectionState(Optional::Value(peerNodeId), peerSessionId, localSessionId, &state)); ReturnErrorCodeIf(state == nullptr, CHIP_ERROR_NO_MEMORY); state->SetFabricIndex(fabric); @@ -288,7 +288,7 @@ CHIP_ERROR SecureSessionMgr::NewPairing(const Optional & if (mCB != nullptr) { state->GetSessionMessageCounter().GetPeerMessageCounter().SetCounter(pairing->GetPeerCounter()); - mCB->OnNewConnection(SessionHandle(state->GetPeerNodeId(), state->GetLocalKeyID(), state->GetPeerKeyID(), fabric)); + mCB->OnNewConnection(SessionHandle(state->GetPeerNodeId(), state->GetLocalSessionId(), state->GetPeerSessionId(), fabric)); } return CHIP_NO_ERROR; @@ -367,7 +367,7 @@ void SecureSessionMgr::SecureMessageDispatch(const PacketHeader & packetHeader, { CHIP_ERROR err = CHIP_NO_ERROR; - PeerConnectionState * state = mPeerConnections.FindPeerConnectionState(packetHeader.GetEncryptionKeyID(), nullptr); + PeerConnectionState * state = mPeerConnections.FindPeerConnectionState(packetHeader.GetSessionId(), nullptr); PayloadHeader payloadHeader; @@ -377,7 +377,7 @@ void SecureSessionMgr::SecureMessageDispatch(const PacketHeader & packetHeader, if (state == nullptr) { - ChipLogError(Inet, "Data received on an unknown connection (%d). Dropping it!!", packetHeader.GetEncryptionKeyID()); + ChipLogError(Inet, "Data received on an unknown connection (%d). Dropping it!!", packetHeader.GetSessionId()); ExitNow(err = CHIP_ERROR_KEY_NOT_FOUND_FROM_PEER); } @@ -393,7 +393,8 @@ void SecureSessionMgr::SecureMessageDispatch(const PacketHeader & packetHeader, // Queue and start message sync procedure err = mMessageCounterManager->QueueReceivedMessageAndStartSync( packetHeader, - SessionHandle(state->GetPeerNodeId(), state->GetLocalKeyID(), state->GetPeerKeyID(), state->GetFabricIndex()), + SessionHandle(state->GetPeerNodeId(), state->GetLocalSessionId(), state->GetPeerSessionId(), + state->GetFabricIndex()), state, peerAddress, std::move(msg)); if (err != CHIP_NO_ERROR) @@ -457,7 +458,8 @@ void SecureSessionMgr::SecureMessageDispatch(const PacketHeader & packetHeader, if (mCB != nullptr) { - SessionHandle session(state->GetPeerNodeId(), state->GetLocalKeyID(), state->GetPeerKeyID(), state->GetFabricIndex()); + SessionHandle session(state->GetPeerNodeId(), state->GetLocalSessionId(), state->GetPeerSessionId(), + state->GetFabricIndex()); mCB->OnMessageReceived(packetHeader, payloadHeader, session, peerAddress, isDuplicate, std::move(msg)); } @@ -476,7 +478,7 @@ void SecureSessionMgr::HandleConnectionExpired(const Transport::PeerConnectionSt if (mCB != nullptr) { mCB->OnConnectionExpired( - SessionHandle(state.GetPeerNodeId(), state.GetLocalKeyID(), state.GetPeerKeyID(), state.GetFabricIndex())); + SessionHandle(state.GetPeerNodeId(), state.GetLocalSessionId(), state.GetPeerSessionId(), state.GetFabricIndex())); } mTransportMgr->Disconnect(state.GetPeerAddress()); @@ -498,7 +500,7 @@ void SecureSessionMgr::ExpiryTimerCallback(System::Layer * layer, void * param) PeerConnectionState * SecureSessionMgr::GetPeerConnectionState(SessionHandle session) { return mPeerConnections.FindPeerConnectionStateByLocalKey(Optional::Value(session.mPeerNodeId), - session.mLocalKeyId.ValueOr(0), nullptr); + session.mLocalSessionId.ValueOr(0), nullptr); } } // namespace chip diff --git a/src/transport/SessionHandle.h b/src/transport/SessionHandle.h index f701702def5c4e..e5b0178bf699b0 100644 --- a/src/transport/SessionHandle.h +++ b/src/transport/SessionHandle.h @@ -32,11 +32,11 @@ class SessionHandle mPeerNodeId(kPlaceholderNodeId), mFabric(Transport::kUndefinedFabricIndex), mUnauthenticatedSessionHandle(session) {} - SessionHandle(NodeId peerNodeId, uint16_t localKeyId, uint16_t peerKeyId, FabricIndex fabric) : + SessionHandle(NodeId peerNodeId, uint16_t localSessionId, uint16_t peerSessionId, FabricIndex fabric) : mPeerNodeId(peerNodeId), mFabric(fabric) { - mLocalKeyId.SetValue(localKeyId); - mPeerKeyId.SetValue(peerKeyId); + mLocalSessionId.SetValue(localSessionId); + mPeerSessionId.SetValue(peerSessionId); } bool IsSecure() const { return !mUnauthenticatedSessionHandle.HasValue(); } @@ -48,14 +48,14 @@ class SessionHandle bool operator==(const SessionHandle & that) const { // TODO: Temporarily keep the old logic, check why only those two fields are used in comparison. - return mPeerNodeId == that.mPeerNodeId && mPeerKeyId == that.mPeerKeyId; + return mPeerNodeId == that.mPeerNodeId && mPeerSessionId == that.mPeerSessionId; } bool MatchIncomingSession(const SessionHandle & that) const { if (IsSecure()) { - return that.IsSecure() && mLocalKeyId.Value() == that.mLocalKeyId.Value(); + return that.IsSecure() && mLocalSessionId.Value() == that.mLocalSessionId.Value(); } else { @@ -64,8 +64,8 @@ class SessionHandle } NodeId GetPeerNodeId() const { return mPeerNodeId; } - const Optional & GetPeerKeyId() const { return mPeerKeyId; } - const Optional & GetLocalKeyId() const { return mLocalKeyId; } + const Optional & GetPeerSessionId() const { return mPeerSessionId; } + const Optional & GetLocalSessionId() const { return mLocalSessionId; } Transport::UnauthenticatedSessionHandle GetUnauthenticatedSession() { return mUnauthenticatedSessionHandle.Value(); } @@ -74,8 +74,8 @@ class SessionHandle // Fields for secure session NodeId mPeerNodeId; - Optional mLocalKeyId; - Optional mPeerKeyId; + Optional mLocalSessionId; + Optional mPeerSessionId; // TODO: Re-evaluate the storing of Fabric ID in SessionHandle // The Fabric ID will not be available for PASE and group sessions. So need // to identify an approach that'll allow looking up the corresponding information for diff --git a/src/transport/raw/MessageHeader.cpp b/src/transport/raw/MessageHeader.cpp index b0c377a908004c..42e026ec8db910 100644 --- a/src/transport/raw/MessageHeader.cpp +++ b/src/transport/raw/MessageHeader.cpp @@ -37,19 +37,19 @@ * Header format (little endian): * * -------- Unencrypted header ----------------------------------------------------- - * 16 bit: | VERSION: 4 bit | FLAGS: 4 bit | ENCRYPTTYPE: 4 bit | RESERVED: 4 bit | - * 32 bit: | MESSAGE_ID | + * 8 bit: | Message Flags: VERSION: 4 bit | S: 1 bit | RESERVED: 1 bit | DSIZ: 2 bit | + * 8 bit: | Security Flags: P: 1 bit | C: 1 bit | MX: 1 bit | RESERVED: 3 bit | Session Type: 2 bit | + * 16 bit: | Session ID | + * 32 bit: | Message Counter | * 64 bit: | SOURCE_NODE_ID (iff source node flag is set) | * 64 bit: | DEST_NODE_ID (iff destination node flag is set) | - * 16 bit: | Encryption Key ID | - * 16 bit: | Payload Length | * -------- Encrypted header ------------------------------------------------------- - * 8 bit: | Exchange Header | - * 8 bit: | Message Type | - * 16 bit: | Exchange ID | - * 16 bit: | Optional Vendor ID | - * 16 bit: | Protocol ID | - * 32 bit: | Acknowledged Message Counter (if A flag in the Header is set) | + * 8 bit: | Exchange Flags: RESERVED: 3 bit | V: 1 bit | SX: 1 bit | R: 1 bit | A: 1 bit | I: 1 bit | + * 8 bit: | Protocol Opcode | + * 16 bit: | Exchange ID | + * 16 bit: | Protocol ID | + * 16 bit: | Optional Vendor ID | + * 32 bit: | Acknowledged Message Counter (if A flag in the Header is set) | * -------- Encrypted Application Data Start --------------------------------------- * : | Encrypted Data | * -------- Encrypted Application Data End ----------------------------------------- @@ -83,9 +83,9 @@ constexpr uint16_t kVersionMask = 0x00F0; constexpr int kVersionShift = 4; /// Mask to extract just the encryption type part from a 16bit header prefix. -constexpr uint16_t kEncryptionTypeMask = 0x3000; +constexpr uint16_t kSessionTypeMask = 0x3000; /// Shift to convert to/from a masked encryption type 16bit value to a 2bit encryption type. -constexpr int kEncryptionTypeShift = 12; +constexpr int kSessionTypeShift = 12; } // namespace @@ -127,11 +127,11 @@ uint16_t PayloadHeader::EncodeSizeBytes() const return static_cast(size); } -uint16_t MessageAuthenticationCode::TagLenForEncryptionType(Header::EncryptionType encType) +uint16_t MessageAuthenticationCode::TagLenForSessionType(Header::SessionType sessionType) { - switch (encType) + switch (sessionType) { - case Header::EncryptionType::kAESCCMTagLen16: + case Header::SessionType::kAESCCMTagLen16: return 16; default: @@ -151,10 +151,13 @@ CHIP_ERROR PacketHeader::Decode(const uint8_t * const data, uint16_t size, uint1 err = reader.Read16(&header).StatusCode(); SuccessOrExit(err); version = ((header & kVersionMask) >> kVersionShift); - VerifyOrExit(version == kHeaderVersion, err = CHIP_ERROR_VERSION_MISMATCH); + VerifyOrExit(version == kMsgHeaderVersion, err = CHIP_ERROR_VERSION_MISMATCH); mFlags.SetRaw(header); - mEncryptionType = static_cast((header & kEncryptionTypeMask) >> kEncryptionTypeShift); + mSessionType = static_cast((header & kSessionTypeMask) >> kSessionTypeShift); + + err = reader.Read16(&mSessionId).StatusCode(); + SuccessOrExit(err); err = reader.Read32(&mMessageCounter).StatusCode(); SuccessOrExit(err); @@ -183,9 +186,6 @@ CHIP_ERROR PacketHeader::Decode(const uint8_t * const data, uint16_t size, uint1 mDestinationNodeId.ClearValue(); } - err = reader.Read16(&mEncryptionKeyID).StatusCode(); - SuccessOrExit(err); - octets_read = static_cast(reader.OctetsRead()); VerifyOrExit(octets_read == EncodeSizeBytes(), err = CHIP_ERROR_INTERNAL); *decode_len = octets_read; @@ -271,11 +271,12 @@ CHIP_ERROR PacketHeader::Encode(uint8_t * data, uint16_t size, uint16_t * encode encodeFlags.Set(Header::FlagValues::kSourceNodeIdPresent, mSourceNodeId.HasValue()) .Set(Header::FlagValues::kDestinationNodeIdPresent, mDestinationNodeId.HasValue()); - uint16_t header = (kHeaderVersion << kVersionShift) | encodeFlags.Raw(); - header |= (static_cast(static_cast(mEncryptionType) << kEncryptionTypeShift) & kEncryptionTypeMask); + uint16_t header = (kMsgHeaderVersion << kVersionShift) | encodeFlags.Raw(); + header |= (static_cast(static_cast(mSessionType) << kSessionTypeShift) & kSessionTypeMask); uint8_t * p = data; LittleEndian::Write16(p, header); + LittleEndian::Write16(p, mSessionId); LittleEndian::Write32(p, mMessageCounter); if (mSourceNodeId.HasValue()) { @@ -286,8 +287,6 @@ CHIP_ERROR PacketHeader::Encode(uint8_t * data, uint16_t size, uint16_t * encode LittleEndian::Write64(p, mDestinationNodeId.Value()); } - LittleEndian::Write16(p, mEncryptionKeyID); - // Written data size provided to caller on success VerifyOrReturnError(p - data == EncodeSizeBytes(), CHIP_ERROR_INTERNAL); *encode_size = static_cast(p - data); @@ -351,7 +350,7 @@ CHIP_ERROR PayloadHeader::EncodeBeforeData(const System::PacketBufferHandle & bu CHIP_ERROR MessageAuthenticationCode::Decode(const PacketHeader & packetHeader, const uint8_t * const data, uint16_t size, uint16_t * decode_len) { - const uint16_t taglen = TagLenForEncryptionType(packetHeader.GetEncryptionType()); + const uint16_t taglen = TagLenForSessionType(packetHeader.GetSessionType()); VerifyOrReturnError(taglen != 0, CHIP_ERROR_WRONG_ENCRYPTION_TYPE_FROM_PEER); VerifyOrReturnError(size >= taglen, CHIP_ERROR_INVALID_ARGUMENT); @@ -367,7 +366,7 @@ CHIP_ERROR MessageAuthenticationCode::Encode(const PacketHeader & packetHeader, uint16_t * encode_size) const { uint8_t * p = data; - const uint16_t taglen = TagLenForEncryptionType(packetHeader.GetEncryptionType()); + const uint16_t taglen = TagLenForSessionType(packetHeader.GetSessionType()); VerifyOrReturnError(taglen != 0, CHIP_ERROR_WRONG_ENCRYPTION_TYPE); VerifyOrReturnError(size >= taglen, CHIP_ERROR_INVALID_ARGUMENT); diff --git a/src/transport/raw/MessageHeader.h b/src/transport/raw/MessageHeader.h index 854fa6d1720c33..a2c5f6aabec8a3 100644 --- a/src/transport/raw/MessageHeader.h +++ b/src/transport/raw/MessageHeader.h @@ -42,14 +42,16 @@ static constexpr size_t kMaxTagLen = 16; static constexpr size_t kMaxAppMessageLen = 1200; +static constexpr size_t kMsgSessionIdUnsecured = 0x0000; + typedef int PacketHeaderFlags; namespace Header { -enum class EncryptionType +enum class SessionType { - kEncryptionTypeNone = 0, - kAESCCMTagLen16 = 1, + kSessionTypeNone = 0, + kAESCCMTagLen16 = 1, }; /** @@ -134,7 +136,7 @@ class PacketHeader */ const Optional & GetDestinationNodeId() const { return mDestinationNodeId; } - uint16_t GetEncryptionKeyID() const { return mEncryptionKeyID; } + uint16_t GetSessionId() const { return mSessionId; } Header::Flags & GetFlags() { return mFlags; } const Header::Flags & GetFlags() const { return mFlags; } @@ -142,7 +144,7 @@ class PacketHeader /** Check if it's a secure session control message. */ bool IsSecureSessionControlMsg() const { return mFlags.Has(Header::FlagValues::kSecureSessionControlMessage); } - Header::EncryptionType GetEncryptionType() const { return mEncryptionType; } + Header::SessionType GetSessionType() const { return mSessionType; } PacketHeader & SetSecureSessionControlMsg(bool value) { @@ -192,9 +194,9 @@ class PacketHeader return *this; } - PacketHeader & SetEncryptionKeyID(uint16_t id) + PacketHeader & SetSessionId(uint16_t id) { - mEncryptionKeyID = id; + mSessionId = id; return *this; } @@ -204,9 +206,9 @@ class PacketHeader return *this; } - PacketHeader & SetEncryptionType(Header::EncryptionType type) + PacketHeader & SetSessionType(Header::SessionType type) { - mEncryptionType = type; + mSessionType = type; return *this; } @@ -292,7 +294,7 @@ class PacketHeader private: /// Represents the current encode/decode header version - static constexpr int kHeaderVersion = 2; + static constexpr int kMsgHeaderVersion = 0; /// Value expected to be incremented for each message sent. uint32_t mMessageCounter = 0; @@ -303,14 +305,14 @@ class PacketHeader /// Intended recipient of the message. Optional mDestinationNodeId; - /// Encryption Key ID - uint16_t mEncryptionKeyID = 0; + /// Session ID + uint16_t mSessionId = kMsgSessionIdUnsecured; /// Message flags read from the message. Header::Flags mFlags; - /// Represents encryption type used for encrypting current packet - Header::EncryptionType mEncryptionType = Header::EncryptionType::kAESCCMTagLen16; + /// Represents session type used for encrypting current packet + Header::SessionType mSessionType = Header::SessionType::kAESCCMTagLen16; }; /** @@ -550,12 +552,12 @@ class MessageAuthenticationCode const uint8_t * GetTag() const { return &mTag[0]; } /** Set the message auth tag for this header. */ - MessageAuthenticationCode & SetTag(PacketHeader * header, Header::EncryptionType encType, uint8_t * tag, size_t len) + MessageAuthenticationCode & SetTag(PacketHeader * header, Header::SessionType sessionType, uint8_t * tag, size_t len) { - const size_t tagLen = TagLenForEncryptionType(encType); + const size_t tagLen = TagLenForSessionType(sessionType); if (tagLen > 0 && tagLen <= kMaxTagLen && len == tagLen) { - header->SetEncryptionType(encType); + header->SetSessionType(sessionType); memcpy(&mTag, tag, tagLen); } @@ -594,7 +596,7 @@ class MessageAuthenticationCode */ CHIP_ERROR Encode(const PacketHeader & packetHeader, uint8_t * data, uint16_t size, uint16_t * encode_size) const; - static uint16_t TagLenForEncryptionType(Header::EncryptionType encType); + static uint16_t TagLenForSessionType(Header::SessionType sessionType); private: /// Message authentication tag generated at encryption of the message. diff --git a/src/transport/raw/tests/BUILD.gn b/src/transport/raw/tests/BUILD.gn index e54e9ec28383f0..bcc2aada1995fd 100644 --- a/src/transport/raw/tests/BUILD.gn +++ b/src/transport/raw/tests/BUILD.gn @@ -39,10 +39,7 @@ static_library("helpers") { chip_test_suite("tests") { output_name = "libRawTransportTests" - test_sources = [ - "TestMessageHeader.cpp", - "TestUDP.cpp", - ] + test_sources = [ "TestMessageHeader.cpp" ] if (current_os != "mac") { test_sources += [ "TestTCP.cpp" ] diff --git a/src/transport/raw/tests/TestMessageHeader.cpp b/src/transport/raw/tests/TestMessageHeader.cpp index e946a546277049..0b2dbbd9656b82 100644 --- a/src/transport/raw/tests/TestMessageHeader.cpp +++ b/src/transport/raw/tests/TestMessageHeader.cpp @@ -40,7 +40,7 @@ void TestPacketHeaderInitialState(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, !header.IsSecureSessionControlMsg()); NL_TEST_ASSERT(inSuite, header.GetMessageCounter() == 0); - NL_TEST_ASSERT(inSuite, header.GetEncryptionKeyID() == 0); + NL_TEST_ASSERT(inSuite, header.GetSessionId() == 0); NL_TEST_ASSERT(inSuite, !header.GetDestinationNodeId().HasValue()); NL_TEST_ASSERT(inSuite, !header.GetSourceNodeId().HasValue()); } @@ -117,7 +117,7 @@ void TestPacketHeaderEncodeDecode(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, header.GetSourceNodeId() == Optional::Value(77ull)); NL_TEST_ASSERT(inSuite, header.IsSecureSessionControlMsg()); - header.SetMessageCounter(234).SetSourceNodeId(77).SetDestinationNodeId(88).SetEncryptionKeyID(2); + header.SetMessageCounter(234).SetSourceNodeId(77).SetDestinationNodeId(88).SetSessionId(2); NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR); // change it to verify decoding @@ -126,7 +126,7 @@ void TestPacketHeaderEncodeDecode(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, header.GetMessageCounter() == 234); NL_TEST_ASSERT(inSuite, header.GetDestinationNodeId() == Optional::Value(88ull)); NL_TEST_ASSERT(inSuite, header.GetSourceNodeId() == Optional::Value(77ull)); - NL_TEST_ASSERT(inSuite, header.GetEncryptionKeyID() == 2); + NL_TEST_ASSERT(inSuite, header.GetSessionId() == 2); header.SetMessageCounter(234).SetSourceNodeId(77).SetDestinationNodeId(88); NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR); diff --git a/src/transport/tests/TestSecureSessionMgr.cpp b/src/transport/tests/TestSecureSessionMgr.cpp index de5dd54e2051e7..150c2d559d3d6c 100644 --- a/src/transport/tests/TestSecureSessionMgr.cpp +++ b/src/transport/tests/TestSecureSessionMgr.cpp @@ -382,7 +382,7 @@ void SendBadEncryptedPacketTest(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, badKeyIdMsg.ExtractPacketHeader(packetHeader) == CHIP_NO_ERROR); // the secure channel is setup to use key ID 1, and 2. So let's use 3 here. - packetHeader.SetEncryptionKeyID(3); + packetHeader.SetSessionId(3); NL_TEST_ASSERT(inSuite, badKeyIdMsg.InsertPacketHeader(packetHeader) == CHIP_NO_ERROR); err = secureSessionMgr.SendPreparedMessage(localToRemoteSession, badKeyIdMsg); From 10d752139a8fcc177e7a643e6f62482c0ecec76e Mon Sep 17 00:00:00 2001 From: Michael Spang Date: Wed, 15 Sep 2021 11:10:08 -0400 Subject: [PATCH 052/255] Sync sdkconfig_m5stack.defaults from sdkconfig.defaults (#9671) The continuous builds for m5stack crash due to stack overflow on startup. Sync the stack size increase from the main sdkconfig.default to fix this. Also sync the other configuration discrepancies. --- .../all-clusters-app/esp32/sdkconfig_m5stack.defaults | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/all-clusters-app/esp32/sdkconfig_m5stack.defaults b/examples/all-clusters-app/esp32/sdkconfig_m5stack.defaults index 1681a7691decf5..8e79b8ea82df50 100644 --- a/examples/all-clusters-app/esp32/sdkconfig_m5stack.defaults +++ b/examples/all-clusters-app/esp32/sdkconfig_m5stack.defaults @@ -40,7 +40,13 @@ CONFIG_LWIP_IPV6_AUTOCONFIG=y CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +# Vendor and product id +CONFIG_DEVICE_VENDOR_ID=0x235A +CONFIG_DEVICE_PRODUCT_ID=0x4541 + # Main task needs a bit more stack than the default -# default is 3584, bump this up to 4k. -CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096 +# default is 3584, bump this up to 5k. +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 +#enable debug shell +CONFIG_ENABLE_CHIP_SHELL=y From a714f0cdd104c62f731327fb1cc205e1a7d0b704 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Wed, 15 Sep 2021 11:11:19 -0400 Subject: [PATCH 053/255] Ignore on-network flag for QR comissioning. (#9696) Per spec 5.6.4, all devices will need to support on-network commissioning for multi-fabric support. Therefore, we should check for devices on the network regardless of the QR code flags. --- src/controller/python/chip-device-ctrl.py | 53 ++++++++++++----------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/src/controller/python/chip-device-ctrl.py b/src/controller/python/chip-device-ctrl.py index bde5bf1e7638a2..959160bb22f15e 100755 --- a/src/controller/python/chip-device-ctrl.py +++ b/src/controller/python/chip-device-ctrl.py @@ -451,32 +451,33 @@ def ConnectFromSetupPayload(self, setupPayload, nodeid): # Devices may be uncommissioned, or may already be on the network. Need to check both ways. # TODO(cecille): implement soft-ap connection. - if int(setupPayload.attributes["RendezvousInformation"]) & onnetwork: - print("Attempting to find device on Network") - longDiscriminator = ctypes.c_uint16( - int(setupPayload.attributes['Discriminator'])) - self.devCtrl.DiscoverCommissionableNodesLongDiscriminator( - longDiscriminator) - print("Waiting for device responses...") - strlen = 100 - addrStrStorage = ctypes.create_string_buffer(strlen) - # If this device is on the network and we're looking specifically for 1 device, - # expect a quick response. - if self.wait_for_one_discovered_device(): - self.devCtrl.GetIPForDiscoveredDevice( - 0, addrStrStorage, strlen) - addrStr = addrStrStorage.value.decode('utf-8') - print("Connecting to device at " + addrStr) - pincode = ctypes.c_uint32( - int(setupPayload.attributes['SetUpPINCode'])) - try: - self.devCtrl.ConnectIP(addrStrStorage, pincode, nodeid) - print("Connected") - return 0 - except Exception as ex: - print(f"Unable to connect on network: {ex}") - else: - print("Unable to locate device on network") + # Any device that is already commissioned into a fabric needs to use on-network + # pairing, so look first on the network regardless of the QR code contents. + print("Attempting to find device on Network") + longDiscriminator = ctypes.c_uint16( + int(setupPayload.attributes['Discriminator'])) + self.devCtrl.DiscoverCommissionableNodesLongDiscriminator( + longDiscriminator) + print("Waiting for device responses...") + strlen = 100 + addrStrStorage = ctypes.create_string_buffer(strlen) + # If this device is on the network and we're looking specifically for 1 device, + # expect a quick response. + if self.wait_for_one_discovered_device(): + self.devCtrl.GetIPForDiscoveredDevice( + 0, addrStrStorage, strlen) + addrStr = addrStrStorage.value.decode('utf-8') + print("Connecting to device at " + addrStr) + pincode = ctypes.c_uint32( + int(setupPayload.attributes['SetUpPINCode'])) + try: + self.devCtrl.ConnectIP(addrStrStorage, pincode, nodeid) + print("Connected") + return 0 + except Exception as ex: + print(f"Unable to connect on network: {ex}") + else: + print("Unable to locate device on network") if int(setupPayload.attributes["RendezvousInformation"]) & ble: print("Attempting to connect via BLE") From 3c7784a7538d7a18e6d18c79a6d2f3c8c8c02947 Mon Sep 17 00:00:00 2001 From: Zang MingJie Date: Wed, 15 Sep 2021 23:13:52 +0800 Subject: [PATCH 054/255] Fix sleep signature (Add extern "C") (#9720) --- examples/shell/efr32/src/main.cpp | 2 +- examples/shell/k32w/main/main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/shell/efr32/src/main.cpp b/examples/shell/efr32/src/main.cpp index 1c5c20289f1626..7bd0f5871df711 100644 --- a/examples/shell/efr32/src/main.cpp +++ b/examples/shell/efr32/src/main.cpp @@ -82,7 +82,7 @@ void appError(int err) ; } -unsigned int sleep(unsigned int seconds) +extern "C" unsigned int sleep(unsigned int seconds) { const TickType_t xDelay = 1000 * seconds / portTICK_PERIOD_MS; vTaskDelay(xDelay); diff --git a/examples/shell/k32w/main/main.cpp b/examples/shell/k32w/main/main.cpp index 57e61543d1dca6..711e507d393df4 100644 --- a/examples/shell/k32w/main/main.cpp +++ b/examples/shell/k32w/main/main.cpp @@ -55,7 +55,7 @@ extern InitFunc __init_array_end; /* needed for FreeRtos Heap 4 */ uint8_t __attribute__((section(".heap"))) ucHeap[0xF000]; -unsigned int sleep(unsigned int seconds) +extern "C" unsigned int sleep(unsigned int seconds) { const TickType_t xDelay = 1000 * seconds / portTICK_PERIOD_MS; vTaskDelay(xDelay); From 4763c913be4c061fdc829e3742e6b08ef5ff536f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20Kr=C3=B3lik?= <66667989+Damian-Nordic@users.noreply.github.com> Date: Wed, 15 Sep 2021 17:39:43 +0200 Subject: [PATCH 055/255] [nrfconnect] Configure data model sources based on ZAP file (#9719) GN applications can take advantage of chip_data_model.gni module to automatically include data model source files based on the application's ZAP file. Implement a similar module for CMake applications and use it in nRF Connect examples. --- .../lighting-app/nrfconnect/CMakeLists.txt | 54 ++--------- examples/lock-app/nrfconnect/CMakeLists.txt | 46 ++------- examples/pump-app/nrfconnect/CMakeLists.txt | 47 ++------- .../nrfconnect/CMakeLists.txt | 46 ++------- src/app/chip_data_model.cmake | 96 +++++++++++++++++++ 5 files changed, 127 insertions(+), 162 deletions(-) create mode 100644 src/app/chip_data_model.cmake diff --git a/examples/lighting-app/nrfconnect/CMakeLists.txt b/examples/lighting-app/nrfconnect/CMakeLists.txt index d9f311efc10e7d..e6f3f887dd3109 100644 --- a/examples/lighting-app/nrfconnect/CMakeLists.txt +++ b/examples/lighting-app/nrfconnect/CMakeLists.txt @@ -47,6 +47,8 @@ find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) project(chip-nrfconnect-lighting-example) include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) +include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) target_compile_options(app PRIVATE -Werror) @@ -68,51 +70,13 @@ target_sources(app PRIVATE ${GEN_DIR}/lighting-app/zap-generated/callback-stub.cpp ${GEN_DIR}/lighting-app/zap-generated/IMClusterCommandHandler.cpp ${NRFCONNECT_COMMON}/util/LEDWidget.cpp - ${NRFCONNECT_COMMON}/util/ThreadUtil.cpp - ${CHIP_ROOT}/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp - ${CHIP_ROOT}/src/app/util/DataModelHandler.cpp - ${CHIP_ROOT}/src/app/reporting/reporting-default-configuration.cpp - ${CHIP_ROOT}/src/app/reporting/reporting.cpp - ${CHIP_ROOT}/src/app/util/af-event.cpp - ${CHIP_ROOT}/src/app/util/af-main-common.cpp - ${CHIP_ROOT}/src/app/util/attribute-list-byte-span.cpp - ${CHIP_ROOT}/src/app/util/attribute-size-util.cpp - ${CHIP_ROOT}/src/app/util/attribute-storage.cpp - ${CHIP_ROOT}/src/app/util/attribute-table.cpp - ${CHIP_ROOT}/src/app/util/binding-table.cpp - ${CHIP_ROOT}/src/app/util/chip-message-send.cpp - ${CHIP_ROOT}/src/app/util/client-api.cpp - ${CHIP_ROOT}/src/app/util/ember-compatibility-functions.cpp - ${CHIP_ROOT}/src/app/util/ember-print.cpp - ${CHIP_ROOT}/src/app/util/error-mapping.cpp - ${CHIP_ROOT}/src/app/util/message.cpp - ${CHIP_ROOT}/src/app/util/process-cluster-message.cpp - ${CHIP_ROOT}/src/app/util/process-global-message.cpp - ${CHIP_ROOT}/src/app/util/util.cpp - ${CHIP_ROOT}/src/app/server/EchoHandler.cpp - ${CHIP_ROOT}/src/app/server/Mdns.cpp - ${CHIP_ROOT}/src/app/server/OnboardingCodesUtil.cpp - ${CHIP_ROOT}/src/app/server/RendezvousServer.cpp - ${CHIP_ROOT}/src/app/server/Server.cpp - ${CHIP_ROOT}/src/app/server/CommissionManager.cpp - ${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp - ${CHIP_ROOT}/src/app/clusters/basic/basic.cpp - ${CHIP_ROOT}/src/app/clusters/bindings/bindings.cpp - ${CHIP_ROOT}/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp - ${CHIP_ROOT}/src/app/clusters/ethernet_network_diagnostics_server/ethernet_network_diagnostics_server.cpp - ${CHIP_ROOT}/src/app/clusters/thread_network_diagnostics_server/thread_network_diagnostics_server.cpp - ${CHIP_ROOT}/src/app/clusters/wifi_network_diagnostics_server/wifi_network_diagnostics_server.cpp - ${CHIP_ROOT}/src/app/clusters/software_diagnostics_server/software_diagnostics_server.cpp - ${CHIP_ROOT}/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp - ${CHIP_ROOT}/src/app/clusters/on-off-server/on-off-server.cpp - ${CHIP_ROOT}/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp - ${CHIP_ROOT}/src/app/clusters/level-control/level-control.cpp - ${CHIP_ROOT}/src/app/clusters/color-control-server/color-control-server.cpp - ${CHIP_ROOT}/src/app/clusters/occupancy-sensor-server/occupancy-sensor-server.cpp - ${CHIP_ROOT}/src/app/clusters/network-commissioning/network-commissioning-ember.cpp - ${CHIP_ROOT}/src/app/clusters/network-commissioning/network-commissioning.cpp - ) + ${NRFCONNECT_COMMON}/util/ThreadUtil.cpp) +chip_configure_data_model(app + INCLUDE_SERVER + ZAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../lighting-common/lighting-app.zap +) + if(BUILD_WITH_DFU) target_sources(app PRIVATE ${NRFCONNECT_COMMON}/util/DFUOverSMP.cpp) endif() @@ -196,5 +160,3 @@ target_link_libraries(app PRIVATE target_link_libraries(pw_build INTERFACE zephyr_interface) endif(CONFIG_CHIP_PW_RPC) - -include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) diff --git a/examples/lock-app/nrfconnect/CMakeLists.txt b/examples/lock-app/nrfconnect/CMakeLists.txt index 37f2d81233b37e..e3f02522868cb2 100644 --- a/examples/lock-app/nrfconnect/CMakeLists.txt +++ b/examples/lock-app/nrfconnect/CMakeLists.txt @@ -48,6 +48,8 @@ target_compile_options(app PRIVATE -Werror) project(chip-nrfconnect-lock-example) include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) +include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) target_include_directories(app PRIVATE main/include @@ -66,45 +68,13 @@ target_sources(app PRIVATE ${GEN_DIR}/lock-app/zap-generated/callback-stub.cpp ${GEN_DIR}/lock-app/zap-generated/IMClusterCommandHandler.cpp ${NRFCONNECT_COMMON}/util/LEDWidget.cpp - ${NRFCONNECT_COMMON}/util/ThreadUtil.cpp - ${CHIP_ROOT}/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp - ${CHIP_ROOT}/src/app/util/DataModelHandler.cpp - ${CHIP_ROOT}/src/app/reporting/reporting-default-configuration.cpp - ${CHIP_ROOT}/src/app/reporting/reporting.cpp - ${CHIP_ROOT}/src/app/util/af-event.cpp - ${CHIP_ROOT}/src/app/util/af-main-common.cpp - ${CHIP_ROOT}/src/app/util/attribute-list-byte-span.cpp - ${CHIP_ROOT}/src/app/util/attribute-size-util.cpp - ${CHIP_ROOT}/src/app/util/attribute-storage.cpp - ${CHIP_ROOT}/src/app/util/attribute-table.cpp - ${CHIP_ROOT}/src/app/util/binding-table.cpp - ${CHIP_ROOT}/src/app/util/chip-message-send.cpp - ${CHIP_ROOT}/src/app/util/client-api.cpp - ${CHIP_ROOT}/src/app/util/ember-compatibility-functions.cpp - ${CHIP_ROOT}/src/app/util/ember-print.cpp - ${CHIP_ROOT}/src/app/util/error-mapping.cpp - ${CHIP_ROOT}/src/app/util/message.cpp - ${CHIP_ROOT}/src/app/util/process-cluster-message.cpp - ${CHIP_ROOT}/src/app/util/process-global-message.cpp - ${CHIP_ROOT}/src/app/util/util.cpp - ${CHIP_ROOT}/src/app/server/EchoHandler.cpp - ${CHIP_ROOT}/src/app/server/Mdns.cpp - ${CHIP_ROOT}/src/app/server/OnboardingCodesUtil.cpp - ${CHIP_ROOT}/src/app/server/RendezvousServer.cpp - ${CHIP_ROOT}/src/app/server/Server.cpp - ${CHIP_ROOT}/src/app/server/CommissionManager.cpp - ${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp - ${CHIP_ROOT}/src/app/clusters/basic/basic.cpp - ${CHIP_ROOT}/src/app/clusters/bindings/bindings.cpp - ${CHIP_ROOT}/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp - ${CHIP_ROOT}/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp - ${CHIP_ROOT}/src/app/clusters/network-commissioning/network-commissioning-ember.cpp - ${CHIP_ROOT}/src/app/clusters/network-commissioning/network-commissioning.cpp - ${CHIP_ROOT}/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp - ${CHIP_ROOT}/src/app/clusters/on-off-server/on-off-server.cpp) + ${NRFCONNECT_COMMON}/util/ThreadUtil.cpp) + +chip_configure_data_model(app + INCLUDE_SERVER + ZAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../lock-common/lock-app.zap +) if(BUILD_WITH_DFU) target_sources(app PRIVATE ${NRFCONNECT_COMMON}/util/DFUOverSMP.cpp) endif() - -include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) diff --git a/examples/pump-app/nrfconnect/CMakeLists.txt b/examples/pump-app/nrfconnect/CMakeLists.txt index 11ccf3ea1cd0d7..f89e249d29b287 100644 --- a/examples/pump-app/nrfconnect/CMakeLists.txt +++ b/examples/pump-app/nrfconnect/CMakeLists.txt @@ -48,6 +48,8 @@ target_compile_options(app PRIVATE -Werror) project(chip-nrfconnect-pump-example) include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) +include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) target_include_directories(app PRIVATE main/include @@ -66,48 +68,13 @@ target_sources(app PRIVATE ${GEN_DIR}/pump-app/zap-generated/callback-stub.cpp ${GEN_DIR}/pump-app/zap-generated/IMClusterCommandHandler.cpp ${NRFCONNECT_COMMON}/util/LEDWidget.cpp - ${NRFCONNECT_COMMON}/util/ThreadUtil.cpp - ${CHIP_ROOT}/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp - ${CHIP_ROOT}/src/app/util/DataModelHandler.cpp - ${CHIP_ROOT}/src/app/reporting/reporting-default-configuration.cpp - ${CHIP_ROOT}/src/app/reporting/reporting.cpp - ${CHIP_ROOT}/src/app/util/af-event.cpp - ${CHIP_ROOT}/src/app/util/af-main-common.cpp - ${CHIP_ROOT}/src/app/util/attribute-list-byte-span.cpp - ${CHIP_ROOT}/src/app/util/attribute-size-util.cpp - ${CHIP_ROOT}/src/app/util/attribute-storage.cpp - ${CHIP_ROOT}/src/app/util/attribute-table.cpp - ${CHIP_ROOT}/src/app/util/binding-table.cpp - ${CHIP_ROOT}/src/app/util/chip-message-send.cpp - ${CHIP_ROOT}/src/app/util/client-api.cpp - ${CHIP_ROOT}/src/app/util/ember-compatibility-functions.cpp - ${CHIP_ROOT}/src/app/util/ember-print.cpp - ${CHIP_ROOT}/src/app/util/error-mapping.cpp - ${CHIP_ROOT}/src/app/util/message.cpp - ${CHIP_ROOT}/src/app/util/process-cluster-message.cpp - ${CHIP_ROOT}/src/app/util/process-global-message.cpp - ${CHIP_ROOT}/src/app/util/util.cpp - ${CHIP_ROOT}/src/app/server/EchoHandler.cpp - ${CHIP_ROOT}/src/app/server/Mdns.cpp - ${CHIP_ROOT}/src/app/server/OnboardingCodesUtil.cpp - ${CHIP_ROOT}/src/app/server/RendezvousServer.cpp - ${CHIP_ROOT}/src/app/server/Server.cpp - ${CHIP_ROOT}/src/app/server/CommissionManager.cpp - ${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp - ${CHIP_ROOT}/src/app/clusters/basic/basic.cpp - ${CHIP_ROOT}/src/app/clusters/bindings/bindings.cpp - ${CHIP_ROOT}/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp - ${CHIP_ROOT}/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp - ${CHIP_ROOT}/src/app/clusters/level-control/level-control.cpp - ${CHIP_ROOT}/src/app/clusters/network-commissioning/network-commissioning-ember.cpp - ${CHIP_ROOT}/src/app/clusters/network-commissioning/network-commissioning.cpp - ${CHIP_ROOT}/src/app/clusters/on-off-server/on-off-server.cpp - ${CHIP_ROOT}/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp - ${CHIP_ROOT}/src/app/clusters/pump-configuration-and-control-server/pump-configuration-and-control-server.cpp + ${NRFCONNECT_COMMON}/util/ThreadUtil.cpp) + +chip_configure_data_model(app + INCLUDE_SERVER + ZAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../pump-common/pump-app.zap ) if(BUILD_WITH_DFU) target_sources(app PRIVATE ${NRFCONNECT_COMMON}/util/DFUOverSMP.cpp) endif() - -include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) diff --git a/examples/pump-controller-app/nrfconnect/CMakeLists.txt b/examples/pump-controller-app/nrfconnect/CMakeLists.txt index 8e34f835ec2030..09c67962a5ad21 100644 --- a/examples/pump-controller-app/nrfconnect/CMakeLists.txt +++ b/examples/pump-controller-app/nrfconnect/CMakeLists.txt @@ -48,6 +48,8 @@ target_compile_options(app PRIVATE -Werror) project(chip-nrfconnect-pump-controller-example) include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) +include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) target_include_directories(app PRIVATE main/include @@ -66,45 +68,13 @@ target_sources(app PRIVATE ${GEN_DIR}/pump-controller-app/zap-generated/callback-stub.cpp ${GEN_DIR}/pump-controller-app/zap-generated/IMClusterCommandHandler.cpp ${NRFCONNECT_COMMON}/util/LEDWidget.cpp - ${NRFCONNECT_COMMON}/util/ThreadUtil.cpp - ${CHIP_ROOT}/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp - ${CHIP_ROOT}/src/app/util/DataModelHandler.cpp - ${CHIP_ROOT}/src/app/reporting/reporting-default-configuration.cpp - ${CHIP_ROOT}/src/app/reporting/reporting.cpp - ${CHIP_ROOT}/src/app/util/af-event.cpp - ${CHIP_ROOT}/src/app/util/af-main-common.cpp - ${CHIP_ROOT}/src/app/util/attribute-list-byte-span.cpp - ${CHIP_ROOT}/src/app/util/attribute-size-util.cpp - ${CHIP_ROOT}/src/app/util/attribute-storage.cpp - ${CHIP_ROOT}/src/app/util/attribute-table.cpp - ${CHIP_ROOT}/src/app/util/binding-table.cpp - ${CHIP_ROOT}/src/app/util/chip-message-send.cpp - ${CHIP_ROOT}/src/app/util/client-api.cpp - ${CHIP_ROOT}/src/app/util/ember-compatibility-functions.cpp - ${CHIP_ROOT}/src/app/util/ember-print.cpp - ${CHIP_ROOT}/src/app/util/error-mapping.cpp - ${CHIP_ROOT}/src/app/util/message.cpp - ${CHIP_ROOT}/src/app/util/process-cluster-message.cpp - ${CHIP_ROOT}/src/app/util/process-global-message.cpp - ${CHIP_ROOT}/src/app/util/util.cpp - ${CHIP_ROOT}/src/app/server/EchoHandler.cpp - ${CHIP_ROOT}/src/app/server/Mdns.cpp - ${CHIP_ROOT}/src/app/server/OnboardingCodesUtil.cpp - ${CHIP_ROOT}/src/app/server/RendezvousServer.cpp - ${CHIP_ROOT}/src/app/server/Server.cpp - ${CHIP_ROOT}/src/app/server/CommissionManager.cpp - ${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp - ${CHIP_ROOT}/src/app/clusters/basic/basic.cpp - ${CHIP_ROOT}/src/app/clusters/bindings/bindings.cpp - ${CHIP_ROOT}/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp - ${CHIP_ROOT}/src/app/clusters/general-commissioning-server/general-commissioning-server.cpp - ${CHIP_ROOT}/src/app/clusters/network-commissioning/network-commissioning-ember.cpp - ${CHIP_ROOT}/src/app/clusters/network-commissioning/network-commissioning.cpp - ${CHIP_ROOT}/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp - ${CHIP_ROOT}/src/app/clusters/pump-configuration-and-control-client/pump-configuration-and-control-client.cpp) + ${NRFCONNECT_COMMON}/util/ThreadUtil.cpp) + +chip_configure_data_model(app + INCLUDE_SERVER + ZAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../pump-controller-common/pump-controller-app.zap +) if(BUILD_WITH_DFU) target_sources(app PRIVATE ${NRFCONNECT_COMMON}/util/DFUOverSMP.cpp) endif() - -include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) diff --git a/src/app/chip_data_model.cmake b/src/app/chip_data_model.cmake new file mode 100644 index 00000000000000..556d3f25dea5fd --- /dev/null +++ b/src/app/chip_data_model.cmake @@ -0,0 +1,96 @@ +# +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set(CHIP_APP_BASE_DIR ${CMAKE_CURRENT_LIST_DIR}) + +# +# Configure ${APP_TARGET} with source files associated with ${CLUSTER} cluster +# +function(chip_configure_cluster APP_TARGET CLUSTER) + file(GLOB CLUSTER_SOURCES "${CHIP_APP_BASE_DIR}/clusters/${CLUSTER}/*.cpp") + target_sources(${APP_TARGET} PRIVATE ${CLUSTER_SOURCES}) +endfunction() + +# +# Configure ${APP_TARGET} with source files associated with clusters enabled in the ${ZAP_FILE} +# +function(chip_configure_zap_file APP_TARGET ZAP_FILE) + find_package(Python3 REQUIRED) + + execute_process( + COMMAND ${Python3_EXECUTABLE} ${CHIP_APP_BASE_DIR}/zap_cluster_list.py --zap_file ${ZAP_FILE} + OUTPUT_VARIABLE CLUSTER_LIST + ERROR_VARIABLE ERROR_MESSAGE + RESULT_VARIABLE RC + ) + if (NOT RC EQUAL 0) + message(FATAL_ERROR "Failed to execute zap_cluster_list.py: ${ERROR_MESSAGE}") + endif() + + string(REPLACE "\n" ";" CLUSTER_LIST "${CLUSTER_LIST}") + foreach(CLUSTER ${CLUSTER_LIST}) + chip_configure_cluster(${APP_TARGET} ${CLUSTER}) + endforeach() +endfunction() + +# +# Configure ${APP_TARGET} based on the selected data model configuration. +# Available options are: +# INCLUDE_SERVER Include source files from src/app/server directory +# ZAP_FILE Path to the ZAP file, used to determine the list of clusters +# supported by the application. +# +function(chip_configure_data_model APP_TARGET) + cmake_parse_arguments(ARG "INCLUDE_SERVER" "ZAP_FILE" "" ${ARGN}) + + if (ARG_INCLUDE_SERVER) + target_sources(${APP_TARGET} PRIVATE + ${CHIP_APP_BASE_DIR}/server/EchoHandler.cpp + ${CHIP_APP_BASE_DIR}/server/Mdns.cpp + ${CHIP_APP_BASE_DIR}/server/OnboardingCodesUtil.cpp + ${CHIP_APP_BASE_DIR}/server/RendezvousServer.cpp + ${CHIP_APP_BASE_DIR}/server/Server.cpp + ${CHIP_APP_BASE_DIR}/server/CommissionManager.cpp + ) + endif() + + if (ARG_ZAP_FILE) + chip_configure_zap_file(${APP_TARGET} ${ARG_ZAP_FILE}) + endif() + + target_sources(${APP_TARGET} PRIVATE + ${CHIP_APP_BASE_DIR}/../../zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp + ${CHIP_APP_BASE_DIR}/reporting/reporting-default-configuration.cpp + ${CHIP_APP_BASE_DIR}/reporting/reporting.cpp + ${CHIP_APP_BASE_DIR}/util/af-event.cpp + ${CHIP_APP_BASE_DIR}/util/af-main-common.cpp + ${CHIP_APP_BASE_DIR}/util/attribute-list-byte-span.cpp + ${CHIP_APP_BASE_DIR}/util/attribute-size-util.cpp + ${CHIP_APP_BASE_DIR}/util/attribute-storage.cpp + ${CHIP_APP_BASE_DIR}/util/attribute-table.cpp + ${CHIP_APP_BASE_DIR}/util/binding-table.cpp + ${CHIP_APP_BASE_DIR}/util/chip-message-send.cpp + ${CHIP_APP_BASE_DIR}/util/client-api.cpp + ${CHIP_APP_BASE_DIR}/util/DataModelHandler.cpp + ${CHIP_APP_BASE_DIR}/util/ember-compatibility-functions.cpp + ${CHIP_APP_BASE_DIR}/util/ember-print.cpp + ${CHIP_APP_BASE_DIR}/util/error-mapping.cpp + ${CHIP_APP_BASE_DIR}/util/message.cpp + ${CHIP_APP_BASE_DIR}/util/process-cluster-message.cpp + ${CHIP_APP_BASE_DIR}/util/process-global-message.cpp + ${CHIP_APP_BASE_DIR}/util/util.cpp + ) +endfunction() From 8b1cac7b585ecba488a21752b464dfedf9f0462b Mon Sep 17 00:00:00 2001 From: rgoliver Date: Wed, 15 Sep 2021 16:03:57 -0400 Subject: [PATCH 056/255] RPC: Refactor to share common code between examples (#9444) Move the common RPC services into a common location and have default virtual implementations which use the ember API. Applications can customize the behaviour when neccessary by overriding the methods. Also cleanup the lighting proto to better match the spec. --- examples/all-clusters-app/esp32/README.md | 3 + .../esp32/main/CMakeLists.txt | 13 +++ examples/all-clusters-app/esp32/main/Rpc.cpp | 52 ++++----- examples/common/pigweed/BUILD.gn | 23 +++- .../pigweed/protos}/lighting_service.proto | 17 +-- .../pigweed/protos}/locking_service.proto | 0 .../common/pigweed/rpc_console/py/BUILD.gn | 4 +- examples/common/pigweed/rpc_services/Button.h | 38 ++++++ examples/common/pigweed/rpc_services/Device.h | 62 ++++++++++ .../common/pigweed/rpc_services/Lighting.h | 108 ++++++++++++++++++ .../common/pigweed/rpc_services/Locking.h | 58 ++++++++++ .../rpc_services/internal/StatusUtils.h | 56 +++++++++ examples/lighting-app/efr32/BUILD.gn | 2 +- examples/lighting-app/efr32/README.md | 2 +- examples/lighting-app/efr32/src/Rpc.cpp | 64 ++--------- .../lighting-app/lighting-common/BUILD.gn | 11 -- examples/lighting-app/linux/BUILD.gn | 3 +- examples/lighting-app/linux/README.md | 2 +- examples/lighting-app/linux/Rpc.cpp | 75 +----------- .../lighting-app/nrfconnect/CMakeLists.txt | 7 +- examples/lighting-app/nrfconnect/README.md | 5 +- examples/lighting-app/nrfconnect/main/Rpc.cpp | 65 ++--------- .../nrfconnect/main/include/AppTask.h | 2 +- .../nrfconnect/main/include/Rpc.h | 2 +- examples/lock-app/esp32/main/CMakeLists.txt | 5 +- examples/lock-app/esp32/main/Rpc.cpp | 60 +++------- examples/lock-app/lock-common/BUILD.gn | 10 -- src/platform/ESP32/BLEManagerImpl.h | 2 + 28 files changed, 449 insertions(+), 302 deletions(-) rename examples/{lighting-app/lighting-common/lighting_service => common/pigweed/protos}/lighting_service.proto (68%) rename examples/{lock-app/lock-common/locking_service => common/pigweed/protos}/locking_service.proto (100%) create mode 100644 examples/common/pigweed/rpc_services/Button.h create mode 100644 examples/common/pigweed/rpc_services/Device.h create mode 100644 examples/common/pigweed/rpc_services/Lighting.h create mode 100644 examples/common/pigweed/rpc_services/Locking.h create mode 100644 examples/common/pigweed/rpc_services/internal/StatusUtils.h diff --git a/examples/all-clusters-app/esp32/README.md b/examples/all-clusters-app/esp32/README.md index b9f730ae9edd12..72bbeff367c867 100644 --- a/examples/all-clusters-app/esp32/README.md +++ b/examples/all-clusters-app/esp32/README.md @@ -285,3 +285,6 @@ From within the console you can then invoke rpcs: rpcs.chip.rpc.Wifi.Connect(ssid=b"MySSID", secret=b"MyPASSWORD") rpcs.chip.rpc.Wifi.GetIP6Address() + + rpcs.chip.rpc.Lighting.Get() + rpcs.chip.rpc.Lighting.Set(on=True, level=128, color=protos.chip.rpc.LightingColor(hue=5, saturation=5)) diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index 63010315a1b25c..c9d6e71f59761d 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -80,6 +80,7 @@ if (CONFIG_ENABLE_PW_RPC) # Append additional directories for RPC build set(PRIV_INCLUDE_DIRS_LIST "${PRIV_INCLUDE_DIRS_LIST}" "${CMAKE_SOURCE_DIR}/../../platform/esp32/pw_sys_io/public" + "${CMAKE_SOURCE_DIR}/../../common" "${CMAKE_SOURCE_DIR}/../../common/pigweed" "${CMAKE_SOURCE_DIR}/../../common/pigweed/esp32" "${CMAKE_SOURCE_DIR}/../../../src/lib/support" @@ -149,6 +150,17 @@ pw_proto_library(device_service pw_protobuf.common_protos ) +pw_proto_library(lighting_service + SOURCES + ${CHIP_ROOT}/examples/common/pigweed/protos/lighting_service.proto + PREFIX + lighting_service + STRIP_PREFIX + ${CHIP_ROOT}/examples/common/pigweed/protos + DEPS + pw_protobuf.common_protos +) + pw_proto_library(wifi_service SOURCES ${CHIP_ROOT}/examples/ipv6only-app/common/wifi_service/wifi_service.proto @@ -165,6 +177,7 @@ pw_proto_library(wifi_service target_link_libraries(${COMPONENT_LIB} PUBLIC button_service.nanopb_rpc device_service.nanopb_rpc + lighting_service.nanopb_rpc wifi_service.nanopb_rpc pw_checksum pw_hdlc diff --git a/examples/all-clusters-app/esp32/main/Rpc.cpp b/examples/all-clusters-app/esp32/main/Rpc.cpp index 4208c3ca730f98..82e5ae7be7c57d 100644 --- a/examples/all-clusters-app/esp32/main/Rpc.cpp +++ b/examples/all-clusters-app/esp32/main/Rpc.cpp @@ -19,8 +19,6 @@ #if CONFIG_ENABLE_PW_RPC #include "PigweedLoggerMutex.h" #include "RpcService.h" -#include "button_service/button_service.rpc.pb.h" -#include "device_service/device_service.rpc.pb.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/event_groups.h" @@ -29,6 +27,10 @@ #include "pw_log/log.h" #include "pw_rpc/server.h" #include "pw_sys_io/sys_io.h" +#include "rpc_services/Button.h" +#include "rpc_services/Device.h" +#include "rpc_services/Lighting.h" + #include #include "ScreenManager.h" @@ -72,35 +74,10 @@ constexpr size_t kScanRecordsMax = sizeof(chip_rpc_ScanResults().aps) / sizeof(c chip_rpc_ScanResults out_scan_records; wifi_ap_record_t scan_records[kScanRecordsMax]; -class Device final : public generated::Device -{ -public: - pw::Status FactoryReset(ServerContext & ctx, const pw_protobuf_Empty & request, pw_protobuf_Empty & response) - { - chip::DeviceLayer::ConfigurationMgr().InitiateFactoryReset(); - return pw::OkStatus(); - } - pw::Status Reboot(ServerContext & ctx, const pw_protobuf_Empty & request, pw_protobuf_Empty & response) - { - return pw::Status::Unimplemented(); - } - pw::Status TriggerOta(ServerContext & ctx, const pw_protobuf_Empty & request, pw_protobuf_Empty & response) - { - return pw::Status::Unimplemented(); - } - pw::Status GetDeviceInfo(ServerContext &, const pw_protobuf_Empty & request, chip_rpc_DeviceInfo & response) - { - response.vendor_id = 1234; - response.product_id = 5678; - response.software_version = 0; - return pw::OkStatus(); - } -}; - -class Button final : public generated::Button