Skip to content

Commit 2f9a711

Browse files
committed
Allow Thermostat delegate to provide timeout for atomic requests
1 parent bdc747e commit 2f9a711

File tree

4 files changed

+60
-6
lines changed

4 files changed

+60
-6
lines changed

examples/thermostat/linux/include/thermostat-delegate-impl.h

+3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ class ThermostatDelegate : public Delegate
4444
public:
4545
static inline ThermostatDelegate & GetInstance() { return sInstance; }
4646

47+
System::Clock::Milliseconds16 GetAtomicWriteTimeout(DataModel::DecodableList<chip::AttributeId> attributeRequests,
48+
System::Clock::Milliseconds16 timeoutRequest) override;
49+
4750
CHIP_ERROR GetPresetTypeAtIndex(size_t index, Structs::PresetTypeStruct::Type & presetType) override;
4851

4952
uint8_t GetNumberOfPresets() override;

examples/thermostat/linux/thermostat-delegate-impl.cpp

+38
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,44 @@ CHIP_ERROR ThermostatDelegate::SetActivePresetHandle(const DataModel::Nullable<B
148148
return CHIP_NO_ERROR;
149149
}
150150

151+
System::Clock::Milliseconds16
152+
ThermostatDelegate::GetAtomicWriteTimeout(DataModel::DecodableList<chip::AttributeId> attributeRequests,
153+
System::Clock::Milliseconds16 timeoutRequest)
154+
{
155+
auto attributeIdsIter = attributeRequests.begin();
156+
bool requestedPresets = false, requestedSchedules = false;
157+
while (attributeIdsIter.Next())
158+
{
159+
auto & attributeId = attributeIdsIter.GetValue();
160+
161+
switch (attributeId)
162+
{
163+
case Attributes::Presets::Id:
164+
requestedPresets = true;
165+
break;
166+
case Attributes::Schedules::Id:
167+
requestedSchedules = true;
168+
break;
169+
default:
170+
return System::Clock::Milliseconds16(0);
171+
}
172+
}
173+
if (attributeIdsIter.GetStatus() != CHIP_NO_ERROR)
174+
{
175+
return System::Clock::Milliseconds16(0);
176+
}
177+
auto timeout = System::Clock::Milliseconds16(0);
178+
if (requestedPresets)
179+
{
180+
timeout += std::chrono::milliseconds(1000);
181+
}
182+
if (requestedSchedules)
183+
{
184+
timeout += std::chrono::milliseconds(3000);
185+
}
186+
return std::min(timeoutRequest, timeout);
187+
}
188+
151189
void ThermostatDelegate::InitializePendingPresets()
152190
{
153191
mNextFreeIndexInPendingPresetsList = 0;

src/app/clusters/thermostat-server/thermostat-delegate.h

+10
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ class Delegate
3838

3939
virtual ~Delegate() = default;
4040

41+
/**
42+
* @brief Get the maximum timeout for atomically writing to a set of attributes
43+
*
44+
* @param[in] attributeRequests The list of attributes to write to.
45+
* @param[out] timeoutRequest The timeout proposed by the client.
46+
* @return The maximum allowed timeout; zero if the request is invalid.
47+
*/
48+
virtual System::Clock::Milliseconds16 GetAtomicWriteTimeout(DataModel::DecodableList<chip::AttributeId> attributeRequests,
49+
System::Clock::Milliseconds16 timeoutRequest) = 0;
50+
4151
/**
4252
* @brief Get the preset type at a given index in the PresetTypes attribute
4353
*

src/app/clusters/thermostat-server/thermostat-server.cpp

+9-6
Original file line numberDiff line numberDiff line change
@@ -1402,8 +1402,6 @@ void handleAtomicBegin(CommandHandler * commandObj, const ConcreteCommandPath &
14021402
return;
14031403
}
14041404

1405-
auto timeout = commandData.timeout.Value();
1406-
14071405
if (!validAtomicAttributes(commandData, false))
14081406
{
14091407
commandObj->AddStatus(commandPath, imcode::InvalidCommand);
@@ -1420,12 +1418,17 @@ void handleAtomicBegin(CommandHandler * commandObj, const ConcreteCommandPath &
14201418
// needs to keep track of a pending preset list now.
14211419
delegate->InitializePendingPresets();
14221420

1423-
uint16_t maxTimeout = 5000;
1424-
timeout = std::min(timeout, maxTimeout);
1421+
System::Clock::Milliseconds16 timeout =
1422+
delegate->GetAtomicWriteTimeout(commandData.attributeRequests, System::Clock::Milliseconds16(commandData.timeout.Value()));
14251423

1426-
ScheduleTimer(endpoint, System::Clock::Milliseconds16(timeout));
1424+
if (timeout == System::Clock::Milliseconds16(0))
1425+
{
1426+
commandObj->AddStatus(commandPath, imcode::InvalidCommand);
1427+
return;
1428+
}
1429+
ScheduleTimer(endpoint, timeout);
14271430
gThermostatAttrAccess.SetAtomicWrite(endpoint, GetSourceScopedNodeId(commandObj), true);
1428-
sendAtomicResponse(commandObj, commandPath, imcode::Success, imcode::Success, imcode::Success, MakeOptional(timeout));
1431+
sendAtomicResponse(commandObj, commandPath, imcode::Success, imcode::Success, imcode::Success, MakeOptional(timeout.count()));
14291432
}
14301433

14311434
imcode commitPresets(Delegate * delegate, EndpointId endpoint)

0 commit comments

Comments
 (0)