@@ -962,18 +962,56 @@ static void moveHandler(app::CommandHandler * commandObj, const app::ConcreteCom
962
962
goto send_default_response;
963
963
}
964
964
965
+ // Always validate the rate parameter received. A rate of 0 is invalid.
965
966
if (!rate.IsNull () && (rate.Value () == 0 ))
966
967
{
967
- // Move at a rate of zero is no move at all. Immediately succeed without touching anything.
968
- ChipLogProgress (Zcl, " Immediate success due to move rate of 0 (would move at no rate)." );
969
- status = Status::Success;
968
+ // Providing rate of 0 is not allowed.
969
+ status = Status::InvalidCommand;
970
970
goto send_default_response;
971
971
}
972
972
973
+ uint8_t eventDuration; // use this local var so state->eventDurationMs is only set once the command is validated.
974
+ #ifndef IGNORE_LEVEL_CONTROL_CLUSTER_TRANSITION
975
+ // If the Rate field is null, the device should move at the default move rate, if available,
976
+ // Otherwise, move as fast as possible
977
+ if (rate.IsNull ())
978
+ {
979
+ app::DataModel::Nullable<uint8_t > defaultMoveRate;
980
+ status = Attributes::DefaultMoveRate::Get (endpoint, defaultMoveRate);
981
+ if (status != Status::Success || defaultMoveRate.IsNull ())
982
+ {
983
+ ChipLogProgress (Zcl, " ERR: reading default move rate %x" , to_underlying (status));
984
+ eventDuration = FASTEST_TRANSITION_TIME_MS;
985
+ }
986
+ else
987
+ {
988
+ // The defaultMoveRate cannot be 0
989
+ if (defaultMoveRate.Value () == 0 )
990
+ {
991
+ status = Status::InvalidCommand;
992
+ goto send_default_response;
993
+ }
994
+ // Already checked that defaultMoveRate.Value() != 0.
995
+ eventDuration = static_cast <uint8_t >(MILLISECOND_TICKS_PER_SECOND / defaultMoveRate.Value ());
996
+ }
997
+ }
998
+ else
999
+ {
1000
+ // Already confirmed rate.Value() != 0.
1001
+ eventDuration = static_cast <uint8_t >(MILLISECOND_TICKS_PER_SECOND / rate.Value ());
1002
+ }
1003
+ #else
1004
+ // Transition/rate is not supported so always use fastest transition time and ignore
1005
+ // both the provided transition time as well as OnOffTransitionTime.
1006
+ ChipLogProgress (Zcl, " Device does not support transition, ignoring rate" );
1007
+ eventDuration = FASTEST_TRANSITION_TIME_MS;
1008
+ #endif // IGNORE_LEVEL_CONTROL_CLUSTER_TRANSITION
1009
+
973
1010
// Cancel any currently active command before fiddling with the state.
974
1011
cancelEndpointTimerCallback (endpoint);
975
1012
976
- status = Attributes::CurrentLevel::Get (endpoint, currentLevel);
1013
+ state->eventDurationMs = eventDuration;
1014
+ status = Attributes::CurrentLevel::Get (endpoint, currentLevel);
977
1015
if (status != Status::Success)
978
1016
{
979
1017
ChipLogProgress (Zcl, " ERR: reading current level %x" , to_underlying (status));
@@ -1026,41 +1064,6 @@ static void moveHandler(app::CommandHandler * commandObj, const app::ConcreteCom
1026
1064
}
1027
1065
}
1028
1066
1029
- #ifndef IGNORE_LEVEL_CONTROL_CLUSTER_TRANSITION
1030
- // If the Rate field is null, the device should move at the default move rate, if available,
1031
- // Otherwise, move as fast as possible
1032
- if (rate.IsNull ())
1033
- {
1034
- app::DataModel::Nullable<uint8_t > defaultMoveRate;
1035
- status = Attributes::DefaultMoveRate::Get (endpoint, defaultMoveRate);
1036
- if (status != Status::Success || defaultMoveRate.IsNull ())
1037
- {
1038
- ChipLogProgress (Zcl, " ERR: reading default move rate %x" , to_underlying (status));
1039
- state->eventDurationMs = FASTEST_TRANSITION_TIME_MS;
1040
- }
1041
- else
1042
- {
1043
- // nonsensical case, means "don't move", so we're done
1044
- if (defaultMoveRate.Value () == 0 )
1045
- {
1046
- status = Status::Success;
1047
- goto send_default_response;
1048
- }
1049
- // Already checked that defaultMoveRate.Value() != 0.
1050
- state->eventDurationMs = MILLISECOND_TICKS_PER_SECOND / defaultMoveRate.Value ();
1051
- }
1052
- }
1053
- else
1054
- {
1055
- state->eventDurationMs = MILLISECOND_TICKS_PER_SECOND / std::max (static_cast <uint8_t >(1u ), rate.Value ());
1056
- }
1057
- #else
1058
- // Transition/rate is not supported so always use fastest transition time and ignore
1059
- // both the provided transition time as well as OnOffTransitionTime.
1060
- ChipLogProgress (Zcl, " Device does not support transition, ignoring rate" );
1061
- state->eventDurationMs = FASTEST_TRANSITION_TIME_MS;
1062
- #endif // IGNORE_LEVEL_CONTROL_CLUSTER_TRANSITION
1063
-
1064
1067
state->transitionTimeMs = difference * state->eventDurationMs ;
1065
1068
state->elapsedTimeMs = 0 ;
1066
1069
0 commit comments