Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ICD] Add Check-In message check when switching to idle mode #31563

Merged
merged 14 commits into from
Jan 30, 2024
Merged
7 changes: 7 additions & 0 deletions src/app/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ source_set("pre-encoded-value") {
]
}

source_set("subscription-manager") {
sources = [ "SubscriptionManager.h" ]

public_deps = [ "${chip_root}/src/lib/core" ]
}

source_set("message-def") {
sources = [
"MessageDef/ArrayBuilder.cpp",
Expand Down Expand Up @@ -247,6 +253,7 @@ static_library("interaction-model") {
":app_config",
":message-def",
":paths",
":subscription-manager",
"${chip_root}/src/app/icd:icd_config",
"${chip_root}/src/app/icd:observer",
"${chip_root}/src/lib/address_resolve",
Expand Down
8 changes: 7 additions & 1 deletion src/app/InteractionModelEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ void InteractionModelEngine::ShutdownMatchingSubscriptions(const Optional<Fabric
}
#endif // CHIP_CONFIG_ENABLE_READ_CLIENT

bool InteractionModelEngine::SubjectHasActiveSubscription(const FabricIndex aFabricIndex, const NodeId & subjectID)
bool InteractionModelEngine::SubjectHasActiveSubscription(const FabricIndex & aFabricIndex, const NodeId & subjectID)
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved
{
bool isActive = false;
mReadHandlers.ForEachActiveObject([aFabricIndex, subjectID, &isActive](ReadHandler * handler) {
Expand Down Expand Up @@ -367,6 +367,12 @@ bool InteractionModelEngine::SubjectHasActiveSubscription(const FabricIndex aFab
return isActive;
}

bool InteractionModelEngine::SubjectHasPersistedSubscription(const FabricIndex & aFabricIndex, const NodeId & subject)
{
// TODO(#30281) : Implement persisted sub check and verify how persistent subscriptions affects this at ICDManager::Init
return false;
}

void InteractionModelEngine::OnDone(CommandHandler & apCommandObj)
{
mCommandHandlerObjs.ReleaseObject(&apCommandObj);
Expand Down
38 changes: 20 additions & 18 deletions src/app/InteractionModelEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,6 @@

#include <access/AccessControl.h>
#include <app/AppConfig.h>
#include <app/MessageDef/AttributeReportIBs.h>
#include <app/MessageDef/ReportDataMessage.h>
#include <app/SubscriptionResumptionSessionEstablisher.h>
#include <lib/core/CHIPCore.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/DLLUtil.h>
#include <lib/support/Pool.h>
#include <lib/support/logging/CHIPLogging.h>
#include <messaging/ExchangeContext.h>
#include <messaging/ExchangeMgr.h>
#include <messaging/Flags.h>
#include <protocols/Protocols.h>
#include <protocols/interaction_model/Constants.h>
#include <system/SystemPacketBuffer.h>

#include <app/AttributePathParams.h>
#include <app/CommandHandler.h>
#include <app/CommandHandlerInterface.h>
Expand All @@ -51,17 +36,32 @@
#include <app/ConcreteEventPath.h>
#include <app/DataVersionFilter.h>
#include <app/EventPathParams.h>
#include <app/MessageDef/AttributeReportIBs.h>
#include <app/MessageDef/ReportDataMessage.h>
#include <app/ObjectList.h>
#include <app/ReadClient.h>
#include <app/ReadHandler.h>
#include <app/StatusResponse.h>
#include <app/SubscriptionManager.h>
#include <app/SubscriptionResumptionSessionEstablisher.h>
#include <app/TimedHandler.h>
#include <app/WriteClient.h>
#include <app/WriteHandler.h>
#include <app/reporting/Engine.h>
#include <app/reporting/ReportScheduler.h>
#include <app/util/attribute-metadata.h>
#include <app/util/basic-types.h>
#include <lib/core/CHIPCore.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/DLLUtil.h>
#include <lib/support/Pool.h>
#include <lib/support/logging/CHIPLogging.h>
#include <messaging/ExchangeContext.h>
#include <messaging/ExchangeMgr.h>
#include <messaging/Flags.h>
#include <protocols/Protocols.h>
#include <protocols/interaction_model/Constants.h>
#include <system/SystemPacketBuffer.h>

#include <app/CASESessionManager.h>

Expand All @@ -79,7 +79,8 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler,
public Messaging::ExchangeDelegate,
public CommandHandler::Callback,
public ReadHandler::ManagementCallback,
public FabricTable::Delegate
public FabricTable::Delegate,
public SubscriptionManager
{
public:
/**
Expand Down Expand Up @@ -323,8 +324,9 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler,

CHIP_ERROR ResumeSubscriptions();

// Check if a given subject (CAT or NodeId) has at least 1 active subscription
bool SubjectHasActiveSubscription(const FabricIndex aFabricIndex, const NodeId & subject);
bool SubjectHasActiveSubscription(const FabricIndex & aFabricIndex, const NodeId & subject) override;
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved

bool SubjectHasPersistedSubscription(const FabricIndex & aFabricIndex, const NodeId & subject) override;
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved

#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
//
Expand Down
67 changes: 67 additions & 0 deletions src/app/SubscriptionManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
*
* Copyright (c) 2024 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
* This file defines an interface that exposes all the public subscription management APIs.
* The interface is implemented by the InteractionModelEngine to avoid creating unnecessary dependencies
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved
* Since the IMEgine has more dependency than its consummers need.
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved
* By leveraging the SubscriptionManager APIs, a consummer avoids depending on the global data model functions.
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved
*/

#pragma once

#include <lib/core/DataModelTypes.h>
#include <lib/core/NodeId.h>

namespace chip {
namespace app {

class SubscriptionManager
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved
{
public:
virtual ~SubscriptionManager(){};

/**
* @brief Check if a given subject (CAT or operational NodeId) has at least 1 active subscription.
*
* @param[in] aFabricIndex fabric index of the subject
* @param[in] subject NodeId of the subect
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved
*
* @return true subject has at least one active subscription with the device
* false subject doesn't have any acitve subscription with the device
*/
virtual bool SubjectHasActiveSubscription(const FabricIndex & aFabricIndex, const NodeId & subject) = 0;
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved

/**
* @brief Check if a given subject (CAT or operational NodeId) has at least 1 persisted subscription.
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved
* If CHIP_CONFIG_PERSIST_SUBSCRIPTIONS is not enable, function alweays returns false.
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved
* See the CHIP_CONFIG_PERSIST_SUBSCRIPTIONS for more information on persisted subscriptions.
*
* @param[in] aFabricIndex fabric index of the subject
* @param[in] subject NodeId of the subect
*
* @return true subject has at least one persisted subscription with the device
* false subject doesn't have any acitve subscription with the device
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved
* false If CHIP_CONFIG_PERSIST_SUBSCRIPTIONS is not enabled
*/
virtual bool SubjectHasPersistedSubscription(const FabricIndex & aFabricIndex, const NodeId & subject) = 0;
};

} // namespace app
} // namespace chip
3 changes: 2 additions & 1 deletion src/app/icd/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ source_set("manager") {
":notifier",
":observer",
":sender",
"${chip_root}/src/app:interaction-model",
"${chip_root}/src/app:subscription-manager",
"${chip_root}/src/credentials:credentials",
]
}
Expand Down Expand Up @@ -114,5 +114,6 @@ source_set("configuration-data") {
deps = [
":icd_config",
"${chip_root}/src/lib/core",
"${chip_root}/src/lib/support",
]
}
13 changes: 13 additions & 0 deletions src/app/icd/ICDConfigurationData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "ICDConfigurationData.h"
#include <app/icd/ICDConfig.h>
#include <lib/support/CodeUtils.h>

namespace chip {

Expand All @@ -36,4 +37,16 @@ System::Clock::Milliseconds32 ICDConfigurationData::GetSlowPollingInterval()
return mSlowPollingInterval;
}

CHIP_ERROR ICDConfigurationData::SetModeDurations(uint32_t activeModeDuration_ms, uint32_t idleModeInterval_s)
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved
{
VerifyOrReturnError(activeModeDuration_ms <= (idleModeInterval_s * 1000), CHIP_ERROR_INVALID_ARGUMENT);
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved
VerifyOrReturnError(idleModeInterval_s <= kMaxIdleModeDuration_s, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(idleModeInterval_s >= kMinIdleModeDuration_s, CHIP_ERROR_INVALID_ARGUMENT);

mIdleModeDuration_s = idleModeInterval_s;
mActiveModeDuration_ms = activeModeDuration_ms;

return CHIP_NO_ERROR;
}

} // namespace chip
34 changes: 28 additions & 6 deletions src/app/icd/ICDConfigurationData.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ namespace chip {
namespace app {
// Forward declaration of ICDManager to allow it to be friend with ICDConfigurationData
class ICDManager;

// Forward declaration of TestICDManager to allow it to be friend with the ICDConfigurationData
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved
// Used in unit tests
class TestICDManager;
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved

} // namespace app

/**
Expand All @@ -47,9 +52,9 @@ class ICDConfigurationData

static ICDConfigurationData & GetInstance() { return instance; };

uint32_t GetIdleModeDurationSec() { return mIdleInterval_s; }
uint32_t GetIdleModeDurationSec() { return mIdleModeDuration_s; }

uint32_t GetActiveModeDurationMs() { return mActiveInterval_ms; }
uint32_t GetActiveModeDurationMs() { return mActiveModeDuration_ms; }

uint16_t GetActiveModeThresholdMs() { return mActiveThreshold_ms; }

Expand Down Expand Up @@ -89,6 +94,7 @@ class ICDConfigurationData
// the ICDManager, the ICDManager is a friend that can access the private setters. If a consummer needs to be notified when a
// value is changed, they can leverage the Observer events the ICDManager generates. See src/app/icd/ICDStateObserver.h
friend class chip::app::ICDManager;
friend class chip::app::TestICDManager;

void SetICDMode(ICDMode mode) { mICDMode = mode; };
void SetICDCounter(uint32_t count) { mICDCounter = count; }
Expand All @@ -97,15 +103,31 @@ class ICDConfigurationData

static constexpr uint32_t kMinLitActiveModeThreshold_ms = 5000;

static_assert((CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC) <= 64800,
/**
* @brief Change the ActiveModeDuration and IdleModeDuration value
* To only change one value, pass the old value for the other one
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved
*
* @param[in] activeModeDuration_ms new ActiveModeDuration value
* @param[in] idleModeDuration_s new IdleModeDuration value
* @return CHIP_ERROR CHIP_ERROR_INVALID_ARGUMENT is returned if idleModeDuration_s is smaller than activeModeDuration_ms
* is returned if idleModeDuration_s is greater than 64800 seconds
* is returned if idleModeDuration_s is smaller than 1 seconds
* CHIP_NO_ERROR is returned if the new intervals were set
*/
CHIP_ERROR SetModeDurations(uint32_t activeModeDuration_ms, uint32_t idleModeDuration_s);

static constexpr uint32_t kMaxIdleModeDuration_s = 64800;
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved
static constexpr uint32_t kMinIdleModeDuration_s = 1;

static_assert((CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC) <= kMaxIdleModeDuration_s,
"Spec requires the IdleModeDuration to be equal or inferior to 64800s.");
static_assert((CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC) >= 1,
static_assert((CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC) >= kMinIdleModeDuration_s,
"Spec requires the IdleModeDuration to be equal or greater to 1s.");
uint32_t mIdleInterval_s = CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC;
uint32_t mIdleModeDuration_s = CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC;

static_assert((CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS) <= (CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC * kMillisecondsPerSecond),
"Spec requires the IdleModeDuration be equal or greater to the ActiveModeDuration.");
uint32_t mActiveInterval_ms = CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS;
uint32_t mActiveModeDuration_ms = CHIP_CONFIG_ICD_ACTIVE_MODE_DURATION_MS;

uint16_t mActiveThreshold_ms = CHIP_CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS;

Expand Down
Loading
Loading