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