27
27
#include < app/CommandHandler.h>
28
28
#include < app/ConcreteAttributePath.h>
29
29
#include < app/ConcreteCommandPath.h>
30
+ #include < app/server/Server.h>
31
+ #include < app/util/endpoint-config-api.h>
30
32
#include < lib/core/CHIPEncoding.h>
31
33
#include < platform/internal/CHIPDeviceLayerInternal.h>
32
34
@@ -116,8 +118,7 @@ void TimerExpiredCallback(System::Layer * systemLayer, void * callbackContext)
116
118
VerifyOrReturn (delegate != nullptr , ChipLogError (Zcl, " Delegate is null. Unable to handle timer expired" ));
117
119
118
120
delegate->ClearPendingPresetList ();
119
- gThermostatAttrAccess .SetAtomicWrite (endpoint, false );
120
- gThermostatAttrAccess .SetAtomicWriteScopedNodeId (endpoint, ScopedNodeId ());
121
+ gThermostatAttrAccess .SetAtomicWrite (endpoint, ScopedNodeId (), kAtomicWriteState_Closed );
121
122
}
122
123
123
124
/* *
@@ -205,8 +206,7 @@ void resetAtomicWrite(Delegate * delegate, EndpointId endpoint)
205
206
delegate->ClearPendingPresetList ();
206
207
}
207
208
ClearTimer (endpoint);
208
- gThermostatAttrAccess .SetAtomicWrite (endpoint, false );
209
- gThermostatAttrAccess .SetAtomicWriteScopedNodeId (endpoint, ScopedNodeId ());
209
+ gThermostatAttrAccess .SetAtomicWrite (endpoint, ScopedNodeId (), kAtomicWriteState_Closed );
210
210
}
211
211
212
212
/* *
@@ -605,14 +605,16 @@ void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate)
605
605
}
606
606
}
607
607
608
- void ThermostatAttrAccess::SetAtomicWrite (EndpointId endpoint, bool inProgress )
608
+ void ThermostatAttrAccess::SetAtomicWrite (EndpointId endpoint, ScopedNodeId originatorNodeId, AtomicWriteState state )
609
609
{
610
610
uint16_t ep =
611
611
emberAfGetClusterServerEndpointIndex (endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT);
612
612
613
- if (ep < ArraySize (mAtomicWriteState ))
613
+ if (ep < ArraySize (mAtomicWriteSessions ))
614
614
{
615
- mAtomicWriteState [ep] = inProgress;
615
+ mAtomicWriteSessions [ep].state = state;
616
+ mAtomicWriteSessions [ep].endpointId = endpoint;
617
+ mAtomicWriteSessions [ep].nodeId = originatorNodeId;
616
618
}
617
619
}
618
620
@@ -622,9 +624,9 @@ bool ThermostatAttrAccess::InAtomicWrite(EndpointId endpoint)
622
624
uint16_t ep =
623
625
emberAfGetClusterServerEndpointIndex (endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT);
624
626
625
- if (ep < ArraySize (mAtomicWriteState ))
627
+ if (ep < ArraySize (mAtomicWriteSessions ))
626
628
{
627
- inAtomicWrite = mAtomicWriteState [ep];
629
+ inAtomicWrite = ( mAtomicWriteSessions [ep]. state == kAtomicWriteState_Open ) ;
628
630
}
629
631
return inAtomicWrite;
630
632
}
@@ -649,26 +651,15 @@ bool ThermostatAttrAccess::InAtomicWrite(CommandHandler * commandObj, EndpointId
649
651
return GetAtomicWriteScopedNodeId (endpoint) == sourceNodeId;
650
652
}
651
653
652
- void ThermostatAttrAccess::SetAtomicWriteScopedNodeId (EndpointId endpoint, ScopedNodeId originatorNodeId)
653
- {
654
- uint16_t ep =
655
- emberAfGetClusterServerEndpointIndex (endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT);
656
-
657
- if (ep < ArraySize (mAtomicWriteNodeIds ))
658
- {
659
- mAtomicWriteNodeIds [ep] = originatorNodeId;
660
- }
661
- }
662
-
663
654
ScopedNodeId ThermostatAttrAccess::GetAtomicWriteScopedNodeId (EndpointId endpoint)
664
655
{
665
656
ScopedNodeId originatorNodeId = ScopedNodeId ();
666
657
uint16_t ep =
667
658
emberAfGetClusterServerEndpointIndex (endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT);
668
659
669
- if (ep < ArraySize (mAtomicWriteNodeIds ))
660
+ if (ep < ArraySize (mAtomicWriteSessions ))
670
661
{
671
- originatorNodeId = mAtomicWriteNodeIds [ep];
662
+ originatorNodeId = mAtomicWriteSessions [ep]. nodeId ;
672
663
}
673
664
return originatorNodeId;
674
665
}
@@ -704,7 +695,7 @@ CHIP_ERROR ThermostatAttrAccess::Read(const ConcreteReadAttributePath & aPath, A
704
695
}
705
696
break ;
706
697
case PresetTypes::Id: {
707
- Delegate * delegate = GetDelegate (aPath.mEndpointId );
698
+ auto delegate = GetDelegate (aPath.mEndpointId );
708
699
VerifyOrReturnError (delegate != nullptr , CHIP_ERROR_INCORRECT_STATE, ChipLogError (Zcl, " Delegate is null" ));
709
700
710
701
return aEncoder.EncodeList ([delegate](const auto & encoder) -> CHIP_ERROR {
@@ -723,14 +714,14 @@ CHIP_ERROR ThermostatAttrAccess::Read(const ConcreteReadAttributePath & aPath, A
723
714
}
724
715
break ;
725
716
case NumberOfPresets::Id: {
726
- Delegate * delegate = GetDelegate (aPath.mEndpointId );
717
+ auto delegate = GetDelegate (aPath.mEndpointId );
727
718
VerifyOrReturnError (delegate != nullptr , CHIP_ERROR_INCORRECT_STATE, ChipLogError (Zcl, " Delegate is null" ));
728
719
729
720
ReturnErrorOnFailure (aEncoder.Encode (delegate->GetNumberOfPresets ()));
730
721
}
731
722
break ;
732
723
case Presets::Id: {
733
- Delegate * delegate = GetDelegate (aPath.mEndpointId );
724
+ auto delegate = GetDelegate (aPath.mEndpointId );
734
725
VerifyOrReturnError (delegate != nullptr , CHIP_ERROR_INCORRECT_STATE, ChipLogError (Zcl, " Delegate is null" ));
735
726
736
727
auto & subjectDescriptor = aEncoder.GetSubjectDescriptor ();
@@ -766,7 +757,7 @@ CHIP_ERROR ThermostatAttrAccess::Read(const ConcreteReadAttributePath & aPath, A
766
757
}
767
758
break ;
768
759
case ActivePresetHandle::Id: {
769
- Delegate * delegate = GetDelegate (aPath.mEndpointId );
760
+ auto delegate = GetDelegate (aPath.mEndpointId );
770
761
VerifyOrReturnError (delegate != nullptr , CHIP_ERROR_INCORRECT_STATE, ChipLogError (Zcl, " Delegate is null" ));
771
762
772
763
uint8_t buffer[kPresetHandleSize ];
@@ -812,7 +803,7 @@ CHIP_ERROR ThermostatAttrAccess::Write(const ConcreteDataAttributePath & aPath,
812
803
{
813
804
case Presets::Id: {
814
805
815
- Delegate * delegate = GetDelegate (endpoint);
806
+ auto delegate = GetDelegate (endpoint);
816
807
VerifyOrReturnError (delegate != nullptr , CHIP_ERROR_INCORRECT_STATE, ChipLogError (Zcl, " Delegate is null" ));
817
808
818
809
// Presets are not editable, return INVALID_IN_STATE.
@@ -897,7 +888,7 @@ CHIP_ERROR ThermostatAttrAccess::Write(const ConcreteDataAttributePath & aPath,
897
888
return CHIP_NO_ERROR;
898
889
}
899
890
900
- CHIP_ERROR ThermostatAttrAccess::AppendPendingPreset (Delegate * delegate, const PresetStruct::Type & preset)
891
+ CHIP_ERROR ThermostatAttrAccess::AppendPendingPreset (Thermostat:: Delegate * delegate, const PresetStruct::Type & preset)
901
892
{
902
893
if (!IsValidPresetEntry (preset))
903
894
{
@@ -951,6 +942,23 @@ CHIP_ERROR ThermostatAttrAccess::AppendPendingPreset(Delegate * delegate, const
951
942
return delegate->AppendToPendingPresetList (preset);
952
943
}
953
944
945
+ void ThermostatAttrAccess::OnFabricRemoved (const FabricTable & fabricTable, FabricIndex fabricIndex)
946
+ {
947
+ for (size_t i = 0 ; i < ArraySize (mAtomicWriteSessions ); ++i)
948
+ {
949
+ auto atomicWriteState = mAtomicWriteSessions [i];
950
+ if (atomicWriteState.state == kAtomicWriteState_Open && atomicWriteState.nodeId .GetFabricIndex () == fabricIndex)
951
+ {
952
+ auto delegate = GetDelegate (atomicWriteState.endpointId );
953
+ if (delegate == nullptr )
954
+ {
955
+ continue ;
956
+ }
957
+ resetAtomicWrite (delegate, atomicWriteState.endpointId );
958
+ }
959
+ }
960
+ }
961
+
954
962
} // namespace Thermostat
955
963
} // namespace Clusters
956
964
} // namespace app
@@ -1394,8 +1402,6 @@ void handleAtomicBegin(CommandHandler * commandObj, const ConcreteCommandPath &
1394
1402
return ;
1395
1403
}
1396
1404
1397
- auto timeout = commandData.timeout .Value ();
1398
-
1399
1405
if (!validAtomicAttributes (commandData, false ))
1400
1406
{
1401
1407
commandObj->AddStatus (commandPath, imcode::InvalidCommand);
@@ -1412,13 +1418,18 @@ void handleAtomicBegin(CommandHandler * commandObj, const ConcreteCommandPath &
1412
1418
// needs to keep track of a pending preset list now.
1413
1419
delegate->InitializePendingPresets ();
1414
1420
1415
- uint16_t maxTimeout = 5000 ;
1416
- timeout = std::min ( timeout, maxTimeout );
1421
+ auto timeout =
1422
+ delegate-> GetAtomicWriteTimeout (commandData. attributeRequests , System::Clock::Milliseconds16 (commandData. timeout . Value ()) );
1417
1423
1418
- ScheduleTimer (endpoint, System::Clock::Milliseconds16 (timeout));
1419
- gThermostatAttrAccess .SetAtomicWrite (endpoint, true );
1420
- gThermostatAttrAccess .SetAtomicWriteScopedNodeId (endpoint, GetSourceScopedNodeId (commandObj));
1421
- sendAtomicResponse (commandObj, commandPath, imcode::Success, imcode::Success, imcode::Success, MakeOptional (timeout));
1424
+ if (!timeout.has_value ())
1425
+ {
1426
+ commandObj->AddStatus (commandPath, imcode::InvalidCommand);
1427
+ return ;
1428
+ }
1429
+ ScheduleTimer (endpoint, timeout.value ());
1430
+ gThermostatAttrAccess .SetAtomicWrite (endpoint, GetSourceScopedNodeId (commandObj), kAtomicWriteState_Open );
1431
+ sendAtomicResponse (commandObj, commandPath, imcode::Success, imcode::Success, imcode::Success,
1432
+ MakeOptional (timeout.value ().count ()));
1422
1433
}
1423
1434
1424
1435
imcode commitPresets (Delegate * delegate, EndpointId endpoint)
@@ -1868,5 +1879,17 @@ bool emberAfThermostatClusterSetpointRaiseLowerCallback(app::CommandHandler * co
1868
1879
1869
1880
void MatterThermostatPluginServerInitCallback ()
1870
1881
{
1882
+ Server::GetInstance ().GetFabricTable ().AddFabricDelegate (&gThermostatAttrAccess );
1871
1883
AttributeAccessInterfaceRegistry::Instance ().Register (&gThermostatAttrAccess );
1872
1884
}
1885
+
1886
+ void MatterThermostatClusterServerShutdownCallback (EndpointId endpoint)
1887
+ {
1888
+ ChipLogProgress (Zcl, " Shutting down thermostat server cluster on endpoint %d" , endpoint);
1889
+ Delegate * delegate = GetDelegate (endpoint);
1890
+
1891
+ if (delegate != nullptr )
1892
+ {
1893
+ resetAtomicWrite (delegate, endpoint);
1894
+ }
1895
+ }
0 commit comments