[Silabs] Fix window-app sync issue with 917 soc (#33376)
* Pull request #1812: [MATTER-2228] Remove all chip lock from the Lift and Tilt actions update.
Merge in WMN_TOOLS/matter from fix/Window-app-synchronization to RC_2.3.0-1.3
Squashed commit of the following:
commit 05e3e7224c6108e7e08ba4d9d7ff69f2b2c6fdc1
Author: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com>
Date: Tue May 7 16:30:30 2024 -0400
address last comments
commit 2d32b0eca831de91ae1105cf076f07b7fd9d424f
Author: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com>
Date: Tue May 7 15:02:16 2024 -0400
address comments
commit 1db94351b7be41e9ef65cabafe1abf4910446848
Author: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com>
Date: Mon May 6 11:32:49 2024 -0400
Cleanup and add briefs and comments
... and 1 more commit
* Restyled by clang-format
* Apply suggestions and fix default config for the window app
---------
Co-authored-by: Restyled.io <commits@restyled.io>
diff --git a/examples/window-app/silabs/build_for_wifi_args.gni b/examples/window-app/silabs/build_for_wifi_args.gni
index afe39bf..d6a8a54 100644
--- a/examples/window-app/silabs/build_for_wifi_args.gni
+++ b/examples/window-app/silabs/build_for_wifi_args.gni
@@ -19,3 +19,4 @@
chip_enable_ota_requestor = true
app_data_model = "${chip_root}/examples/window-app/common:window-common"
+sl_enable_test_event_trigger = true
diff --git a/examples/window-app/silabs/include/WindowManager.h b/examples/window-app/silabs/include/WindowManager.h
index 9faf669..8ae75e8 100644
--- a/examples/window-app/silabs/include/WindowManager.h
+++ b/examples/window-app/silabs/include/WindowManager.h
@@ -57,23 +57,33 @@
struct Cover
{
+ enum ControlAction : uint8_t
+ {
+ Lift = 0,
+ Tilt = 1
+ };
+
void Init(chip::EndpointId endpoint);
- void LiftUpdate(bool newTarget);
- void LiftGoToTarget() { LiftUpdate(true); }
- void LiftContinueToTarget() { LiftUpdate(false); }
- void LiftStepToward(OperationalState direction);
- void LiftSchedulePositionSet(chip::Percent100ths position) { SchedulePositionSet(position, false); }
- void LiftScheduleOperationalStateSet(OperationalState opState) { ScheduleOperationalStateSet(opState, false); }
+ /**
+ * @brief Schedule a lift or a tilt related attribute transition on the ChipEvent queue
+ * **This function allocates a CoverWorkData which needs to be freed by the Worker callback**
+ *
+ * @param action : ControlAction::Lift will ScheduleWork LiftUpdateWorker, while ControlAction::Tilt will ScheduleWork
+ * TilitUpdateWorker
+ * @param setNewTarget : True will stop any ongoing transition and start a new one. False will continue the active
+ * transition updates
+ */
+ void ScheduleControlAction(ControlAction action, bool setNewTarget);
+ // Helper functions that schedule Lift transitions
+ inline void LiftGoToTarget() { ScheduleControlAction(ControlAction::Lift, true); }
+ inline void LiftContinueToTarget() { ScheduleControlAction(ControlAction::Lift, false); }
+ // Helper functions that schedule Tilt transitions
+ inline void TiltGoToTarget() { ScheduleControlAction(ControlAction::Tilt, true); }
+ inline void TiltContinueToTarget() { ScheduleControlAction(ControlAction::Tilt, false); }
- void TiltUpdate(bool newTarget);
- void TiltGoToTarget() { TiltUpdate(true); }
- void TiltContinueToTarget() { TiltUpdate(false); }
- void TiltStepToward(OperationalState direction);
- void TiltSchedulePositionSet(chip::Percent100ths position) { SchedulePositionSet(position, true); }
- void TiltScheduleOperationalStateSet(OperationalState opState) { ScheduleOperationalStateSet(opState, true); }
-
- void UpdateTargetPosition(OperationalState direction, bool isTilt);
+ void PositionSet(chip::EndpointId endpointId, chip::Percent100ths position, ControlAction action);
+ void UpdateTargetPosition(OperationalState direction, ControlAction action);
Type CycleType();
@@ -88,22 +98,23 @@
OperationalState mLiftOpState = OperationalState::Stall;
OperationalState mTiltOpState = OperationalState::Stall;
- struct CoverWorkData
- {
- chip::EndpointId mEndpointId;
- bool isTilt;
+ /**
+ * @brief Worker callbacks for the ScheduleControlAction.
+ * Those functions compute the operational state, and transititon movement based on the current and target positions
+ * for the cover.
+ * @param arg Context passed to the schedule worker. In this case, a CoverWorkData pointer
+ * The referenced CoverWorkData was allocated by ScheduleControlAction and must be freed by the worker.
+ */
+ static void LiftUpdateWorker(intptr_t arg);
+ static void TiltUpdateWorker(intptr_t arg);
+ };
- union
- {
- chip::Percent100ths percent100ths;
- OperationalState opState;
- };
- };
-
- void SchedulePositionSet(chip::Percent100ths position, bool isTilt);
- static void CallbackPositionSet(intptr_t arg);
- void ScheduleOperationalStateSet(OperationalState opState, bool isTilt);
- static void CallbackOperationalStateSet(intptr_t arg);
+ struct CoverWorkData
+ {
+ Cover * cover = nullptr;
+ bool setNewTarget = false;
+ CoverWorkData(Cover * c, bool t) : cover(c), setNewTarget(t) {}
+ ~CoverWorkData() { cover = nullptr; }
};
static WindowManager & Instance();
diff --git a/examples/window-app/silabs/openthread.gni b/examples/window-app/silabs/openthread.gni
index 9fd09bd..47c5860 100644
--- a/examples/window-app/silabs/openthread.gni
+++ b/examples/window-app/silabs/openthread.gni
@@ -21,13 +21,14 @@
app_data_model = "${chip_root}/examples/window-app/common:window-common"
chip_enable_ota_requestor = true
chip_enable_openthread = true
+sl_enable_test_event_trigger = true
openthread_external_platform =
"${chip_root}/third_party/openthread/platforms/efr32:libopenthread-efr32"
# ICD Default configurations
chip_enable_icd_server = true
-enable_synchronized_sed = true
+enable_synchronized_sed = false
chip_subscription_timeout_resumption = false
sl_use_subscription_syncing = true
diff --git a/examples/window-app/silabs/src/WindowManager.cpp b/examples/window-app/silabs/src/WindowManager.cpp
index af607fd..0b8639d 100644
--- a/examples/window-app/silabs/src/WindowManager.cpp
+++ b/examples/window-app/silabs/src/WindowManager.cpp
@@ -268,135 +268,131 @@
chip::BitFlags<SafetyStatus> safetyStatus(0x00); // 0 is no issues;
}
-void WindowManager::Cover::LiftStepToward(OperationalState direction)
+void WindowManager::Cover::ScheduleControlAction(ControlAction action, bool setNewTarget)
{
- Protocols::InteractionModel::Status status;
- chip::Percent100ths percent100ths;
- NPercent100ths current;
+ VerifyOrReturn(action <= ControlAction::Tilt);
+ // Allocate a CoverWorkData. It will be freed by the Worker callback
+ CoverWorkData * data = new CoverWorkData(this, setNewTarget);
+ VerifyOrDie(data != nullptr);
- chip::DeviceLayer::PlatformMgr().LockChipStack();
- status = Attributes::CurrentPositionLiftPercent100ths::Get(mEndpoint, current);
- chip::DeviceLayer::PlatformMgr().UnlockChipStack();
-
- if ((status == Protocols::InteractionModel::Status::Success) && !current.IsNull())
+ AsyncWorkFunct workFunct = (action == ControlAction::Lift) ? LiftUpdateWorker : TiltUpdateWorker;
+ if (PlatformMgr().ScheduleWork(workFunct, reinterpret_cast<intptr_t>(data)) != CHIP_NO_ERROR)
{
- percent100ths = ComputePercent100thsStep(direction, current.Value(), LIFT_DELTA);
+ ChipLogError(AppServer, "Failed to schedule cover control action");
+ delete data;
}
- else
- {
- percent100ths = WC_PERCENT100THS_MIDDLE; // set at middle by default
- }
-
- LiftSchedulePositionSet(percent100ths);
}
-void WindowManager::Cover::LiftUpdate(bool newTarget)
+void WindowManager::Cover::LiftUpdateWorker(intptr_t arg)
{
+ // Use a unique_prt so it's freed when leaving this context
+ std::unique_ptr<CoverWorkData> data(reinterpret_cast<CoverWorkData *>(arg));
+ Cover * cover = data->cover;
+
NPercent100ths current, target;
- chip::DeviceLayer::PlatformMgr().LockChipStack();
-
- Attributes::TargetPositionLiftPercent100ths::Get(mEndpoint, target);
- Attributes::CurrentPositionLiftPercent100ths::Get(mEndpoint, current);
+ VerifyOrReturn(Attributes::TargetPositionLiftPercent100ths::Get(cover->mEndpoint, target) ==
+ Protocols::InteractionModel::Status::Success);
+ VerifyOrReturn(Attributes::CurrentPositionLiftPercent100ths::Get(cover->mEndpoint, current) ==
+ Protocols::InteractionModel::Status::Success);
OperationalState opState = ComputeOperationalState(target, current);
- chip::DeviceLayer::PlatformMgr().UnlockChipStack();
-
- /* If Triggered by a TARGET update */
- if (newTarget)
+ // If Triggered by a TARGET update
+ if (data->setNewTarget)
{
- mLiftTimer->Stop(); // Cancel previous motion if any
- mLiftOpState = opState;
+ cover->mLiftTimer->Stop(); // Cancel previous motion if any
+ cover->mLiftOpState = opState;
}
- if (mLiftOpState == opState)
+ if (cover->mLiftOpState == opState)
{
- /* Actuator still need to move, not reached/crossed Target yet */
- LiftStepToward(mLiftOpState);
+ // Actuator still needs to move, has not reached/crossed Target yet
+ chip::Percent100ths percent100ths;
+
+ if (!current.IsNull())
+ {
+ percent100ths = ComputePercent100thsStep(cover->mLiftOpState, current.Value(), LIFT_DELTA);
+ }
+ else
+ {
+ percent100ths = WC_PERCENT100THS_MIDDLE; // set at middle by default
+ }
+
+ cover->PositionSet(cover->mEndpoint, percent100ths, ControlAction::Lift);
}
- else /* CURRENT reached TARGET or crossed it */
+ else // CURRENT reached TARGET or crossed it
{
- /* Actuator finalize the movement AND CURRENT Must be equal to TARGET at the end */
+ // Actuator finalize the movement AND CURRENT Must be equal to TARGET at the end
if (!target.IsNull())
- LiftSchedulePositionSet(target.Value());
+ cover->PositionSet(cover->mEndpoint, target.Value(), ControlAction::Lift);
- mLiftOpState = OperationalState::Stall;
+ cover->mLiftOpState = OperationalState::Stall;
}
- LiftScheduleOperationalStateSet(mLiftOpState);
+ OperationalStateSet(cover->mEndpoint, OperationalStatus::kLift, cover->mLiftOpState);
- if ((OperationalState::Stall != mLiftOpState) && mLiftTimer)
+ if ((OperationalState::Stall != cover->mLiftOpState) && cover->mLiftTimer)
{
- mLiftTimer->Start();
+ cover->mLiftTimer->Start();
}
}
-void WindowManager::Cover::TiltStepToward(OperationalState direction)
+void WindowManager::Cover::TiltUpdateWorker(intptr_t arg)
{
- Protocols::InteractionModel::Status status;
- chip::Percent100ths percent100ths;
- NPercent100ths current;
+ // Use a unique_prt so it's freed when leaving this context
+ std::unique_ptr<CoverWorkData> data(reinterpret_cast<CoverWorkData *>(arg));
+ Cover * cover = data->cover;
- chip::DeviceLayer::PlatformMgr().LockChipStack();
- status = Attributes::CurrentPositionTiltPercent100ths::Get(mEndpoint, current);
- chip::DeviceLayer::PlatformMgr().UnlockChipStack();
-
- if ((status == Protocols::InteractionModel::Status::Success) && !current.IsNull())
- {
- percent100ths = ComputePercent100thsStep(direction, current.Value(), TILT_DELTA);
- }
- else
- {
- percent100ths = WC_PERCENT100THS_MIDDLE; // set at middle by default
- }
-
- TiltSchedulePositionSet(percent100ths);
-}
-
-void WindowManager::Cover::TiltUpdate(bool newTarget)
-{
NPercent100ths current, target;
-
- chip::DeviceLayer::PlatformMgr().LockChipStack();
-
- Attributes::TargetPositionTiltPercent100ths::Get(mEndpoint, target);
- Attributes::CurrentPositionTiltPercent100ths::Get(mEndpoint, current);
+ VerifyOrReturn(Attributes::TargetPositionTiltPercent100ths::Get(cover->mEndpoint, target) ==
+ Protocols::InteractionModel::Status::Success);
+ VerifyOrReturn(Attributes::CurrentPositionTiltPercent100ths::Get(cover->mEndpoint, current) ==
+ Protocols::InteractionModel::Status::Success);
OperationalState opState = ComputeOperationalState(target, current);
- chip::DeviceLayer::PlatformMgr().UnlockChipStack();
-
- /* If Triggered by a TARGET update */
- if (newTarget)
+ // If Triggered by a TARGET update
+ if (data->setNewTarget)
{
- mTiltTimer->Stop(); // Cancel previous motion if any
- mTiltOpState = opState;
+ cover->mTiltTimer->Stop(); // Cancel previous motion if any
+ cover->mTiltOpState = opState;
}
- if (mTiltOpState == opState)
+ if (cover->mTiltOpState == opState)
{
- /* Actuator still need to move, not reached/crossed Target yet */
- TiltStepToward(mTiltOpState);
+ // Actuator still needs to move, has not reached/crossed Target yet
+ chip::Percent100ths percent100ths;
+
+ if (!current.IsNull())
+ {
+ percent100ths = ComputePercent100thsStep(cover->mTiltOpState, current.Value(), TILT_DELTA);
+ }
+ else
+ {
+ percent100ths = WC_PERCENT100THS_MIDDLE; // set at middle by default
+ }
+
+ cover->PositionSet(cover->mEndpoint, percent100ths, ControlAction::Tilt);
}
- else /* CURRENT reached TARGET or crossed it */
+ else // CURRENT reached TARGET or crossed it
{
- /* Actuator finalize the movement AND CURRENT Must be equal to TARGET at the end */
+ // Actuator finalize the movement AND CURRENT Must be equal to TARGET at the end
if (!target.IsNull())
- TiltSchedulePositionSet(target.Value());
+ cover->PositionSet(cover->mEndpoint, target.Value(), ControlAction::Tilt);
- mTiltOpState = OperationalState::Stall;
+ cover->mTiltOpState = OperationalState::Stall;
}
- TiltScheduleOperationalStateSet(mTiltOpState);
+ OperationalStateSet(cover->mEndpoint, OperationalStatus::kTilt, cover->mTiltOpState);
- if ((OperationalState::Stall != mTiltOpState) && mTiltTimer)
+ if ((OperationalState::Stall != cover->mTiltOpState) && cover->mTiltTimer)
{
- mTiltTimer->Start();
+ cover->mTiltTimer->Start();
}
}
-void WindowManager::Cover::UpdateTargetPosition(OperationalState direction, bool isTilt)
+void WindowManager::Cover::UpdateTargetPosition(OperationalState direction, ControlAction action)
{
Protocols::InteractionModel::Status status;
NPercent100ths current;
@@ -404,7 +400,7 @@
chip::DeviceLayer::PlatformMgr().LockChipStack();
- if (isTilt)
+ if (action == ControlAction::Tilt)
{
status = Attributes::CurrentPositionTiltPercent100ths::Get(mEndpoint, current);
if ((status == Protocols::InteractionModel::Status::Success) && !current.IsNull())
@@ -473,29 +469,15 @@
}
}
-void WindowManager::Cover::SchedulePositionSet(chip::Percent100ths position, bool isTilt)
+void WindowManager::Cover::PositionSet(chip::EndpointId endpointId, chip::Percent100ths position, ControlAction action)
{
- CoverWorkData * data = chip::Platform::New<CoverWorkData>();
- VerifyOrReturn(data != nullptr, ChipLogProgress(Zcl, "Cover::SchedulePositionSet - Out of Memory for WorkData"));
-
- data->mEndpointId = mEndpoint;
- data->percent100ths = position;
- data->isTilt = isTilt;
-
- chip::DeviceLayer::PlatformMgr().ScheduleWork(CallbackPositionSet, reinterpret_cast<intptr_t>(data));
-}
-
-void WindowManager::Cover::CallbackPositionSet(intptr_t arg)
-{
- NPercent100ths position;
- WindowManager::Cover::CoverWorkData * data = reinterpret_cast<WindowManager::Cover::CoverWorkData *>(arg);
- position.SetNonNull(data->percent100ths);
-
- if (data->isTilt)
+ NPercent100ths nullablePosition;
+ nullablePosition.SetNonNull(position);
+ if (action == ControlAction::Tilt)
{
- TiltPositionSet(data->mEndpointId, position);
+ TiltPositionSet(endpointId, nullablePosition);
#ifdef DIC_ENABLE
- uint16_t value = data->percent100ths;
+ uint16_t value = position;
char buffer[MSG_SIZE];
itoa(value, buffer, DECIMAL);
dic_sendmsg("tilt/position set", (const char *) (buffer));
@@ -503,36 +485,14 @@
}
else
{
- LiftPositionSet(data->mEndpointId, position);
+ LiftPositionSet(endpointId, nullablePosition);
#ifdef DIC_ENABLE
- uint16_t value = data->percent100ths;
+ uint16_t value = position;
char buffer[MSG_SIZE];
itoa(value, buffer, DECIMAL);
dic_sendmsg("lift/position set", (const char *) (buffer));
#endif // DIC_ENABLE
}
- chip::Platform::Delete(data);
-}
-
-void WindowManager::Cover::ScheduleOperationalStateSet(OperationalState opState, bool isTilt)
-{
- CoverWorkData * data = chip::Platform::New<CoverWorkData>();
- VerifyOrReturn(data != nullptr, ChipLogProgress(Zcl, "Cover::OperationalStatusSet - Out of Memory for WorkData"));
-
- data->mEndpointId = mEndpoint;
- data->opState = opState;
- data->isTilt = isTilt;
-
- chip::DeviceLayer::PlatformMgr().ScheduleWork(CallbackOperationalStateSet, reinterpret_cast<intptr_t>(data));
-}
-
-void WindowManager::Cover::CallbackOperationalStateSet(intptr_t arg)
-{
- WindowManager::Cover::CoverWorkData * data = reinterpret_cast<WindowManager::Cover::CoverWorkData *>(arg);
-
- OperationalStateSet(data->mEndpointId, data->isTilt ? OperationalStatus::kTilt : OperationalStatus::kLift, data->opState);
-
- chip::Platform::Delete(data);
}
//------------------------------------------------------------------------------
@@ -756,7 +716,8 @@
}
else
{
- window->GetCover().UpdateTargetPosition(OperationalState::MovingUpOrOpen, window->mTiltMode);
+ window->GetCover().UpdateTargetPosition(
+ OperationalState::MovingUpOrOpen, ((window->mTiltMode) ? Cover::ControlAction::Tilt : Cover::ControlAction::Lift));
}
break;
@@ -792,7 +753,9 @@
}
else
{
- window->GetCover().UpdateTargetPosition(OperationalState::MovingDownOrClose, window->mTiltMode);
+ window->GetCover().UpdateTargetPosition(
+ OperationalState::MovingDownOrClose,
+ ((window->mTiltMode) ? Cover::ControlAction::Tilt : Cover::ControlAction::Lift));
}
break;