|
26 | 26 |
|
27 | 27 | #include "DeviceWaterValve.h" |
28 | 28 |
|
| 29 | +// The Matter spec requires OpenDuration/DefaultOpenDuration/RemainingDuration to be at least 1s when |
| 30 | +// set, so "no duration configured" (internal 0) must be reported/accepted as null on the wire, using |
| 31 | +// the ZCL convention of an all-ones value to represent null for unsigned integer attributes. |
| 32 | +static constexpr uint32_t kNullDurationValue = 0xFFFFFFFFu; |
| 33 | + |
29 | 34 | DeviceWaterValve::DeviceWaterValve(const char* device_name) : |
30 | 35 | Device(device_name), |
31 | 36 | current_state(VALVE_STATE_CLOSED), |
@@ -206,13 +211,16 @@ CHIP_ERROR DeviceWaterValve::HandleReadEmberAfAttribute(ClusterId clusterId, |
206 | 211 | using namespace ::chip::app::Clusters::ValveConfigurationAndControl::Attributes; |
207 | 212 | if ((attributeId == OpenDuration::Id) && (maxReadLength == 4)) { |
208 | 213 | uint32_t openDuration = this->GetOpenDuration(); |
209 | | - memcpy(buffer, &openDuration, sizeof(openDuration)); |
| 214 | + uint32_t wireOpenDuration = (openDuration == 0) ? kNullDurationValue : openDuration; |
| 215 | + memcpy(buffer, &wireOpenDuration, sizeof(wireOpenDuration)); |
210 | 216 | } else if ((attributeId == DefaultOpenDuration::Id) && (maxReadLength == 4)) { |
211 | 217 | uint32_t defaultOpenDuration = this->GetDefaultOpenDuration(); |
212 | | - memcpy(buffer, &defaultOpenDuration, sizeof(defaultOpenDuration)); |
| 218 | + uint32_t wireDefaultOpenDuration = (defaultOpenDuration == 0) ? kNullDurationValue : defaultOpenDuration; |
| 219 | + memcpy(buffer, &wireDefaultOpenDuration, sizeof(wireDefaultOpenDuration)); |
213 | 220 | } else if ((attributeId == RemainingDuration::Id) && (maxReadLength == 4)) { |
214 | 221 | uint32_t remainingDuration = this->GetRemainingDuration(); |
215 | | - memcpy(buffer, &remainingDuration, sizeof(remainingDuration)); |
| 222 | + uint32_t wireRemainingDuration = (remainingDuration == 0) ? kNullDurationValue : remainingDuration; |
| 223 | + memcpy(buffer, &wireRemainingDuration, sizeof(wireRemainingDuration)); |
216 | 224 | } else if ((attributeId == CurrentState::Id) && (maxReadLength == 1)) { |
217 | 225 | uint8_t currentState = this->GetCurrentState(); |
218 | 226 | memcpy(buffer, ¤tState, sizeof(currentState)); |
@@ -254,7 +262,8 @@ CHIP_ERROR DeviceWaterValve::HandleWriteEmberAfAttribute(ClusterId clusterId, |
254 | 262 |
|
255 | 263 | using namespace ::chip::app::Clusters::ValveConfigurationAndControl::Attributes; |
256 | 264 | if (attributeId == DefaultOpenDuration::Id) { |
257 | | - this->SetDefaultOpenDuration(*((uint32_t*)buffer)); |
| 265 | + uint32_t wireDefaultOpenDuration = *((uint32_t*)buffer); |
| 266 | + this->SetDefaultOpenDuration((wireDefaultOpenDuration == kNullDurationValue) ? 0 : wireDefaultOpenDuration); |
258 | 267 | } else { |
259 | 268 | return CHIP_ERROR_INVALID_ARGUMENT; |
260 | 269 | } |
|
0 commit comments