@@ -183,12 +183,39 @@ static uint32_t curr_fade_time(struct bt_mesh_light_ctrl_srv *srv)
183183}
184184
185185static bool state_is_on (const struct bt_mesh_light_ctrl_srv * srv ,
186- enum bt_mesh_light_ctrl_srv_state state )
186+ enum bt_mesh_light_ctrl_srv_state prev_state )
187187{
188- /* Only the stable Standby state is considered Off: */
189- if (srv -> fade .duration > 0 ) {
190- return (state != LIGHT_CTRL_STATE_STANDBY ||
191- atomic_test_bit (& srv -> flags , FLAG_TRANSITION ));
188+ /* Note: The issue with this function is the prev_state represents previous state, but
189+ * the state of the FSM changes once old state is captured. Thus, we need some
190+ * implied logic here to correct this understanding.
191+ *
192+ * This module will be refactored later.
193+ */
194+
195+ /* If there is a delayed transition, report the value before the change. */
196+ if (atomic_test_bit (& srv -> flags , FLAG_ON_PENDING ) ||
197+ atomic_test_bit (& srv -> flags , FLAG_OFF_PENDING )) {
198+ return prev_state != LIGHT_CTRL_STATE_STANDBY ;
199+ }
200+
201+ /* For ongoing transition (of non-zero duration), we have two cases:
202+ * - Immediately at state change publications (prev_state != srv->state),
203+ * Present should reflect the state 'before' the transition started.
204+ * - For later Status queries (prev_state == srv->state), Present shall remain
205+ * On (1) for the duration of the transition.
206+ */
207+ if (atomic_test_bit (& srv -> flags , FLAG_TRANSITION ) && srv -> fade .duration > 0 ) {
208+ if (prev_state != srv -> state ) {
209+ return prev_state != LIGHT_CTRL_STATE_STANDBY ;
210+ }
211+
212+ /* At this point, we are in an ongoing transition (with non-zero duration),
213+ * prev_state == srv->state, and neither FLAG_ON_PENDING nor FLAG_OFF_PENDING is
214+ * set. Per spec, the Present OnOff is reported as ON for the entire duration of a
215+ * transition to OFF. Here we return true, indicating the light should be reported
216+ * as ON during this transition regardless of the eventual target state.
217+ */
218+ return true;
192219 }
193220
194221 return srv -> state != LIGHT_CTRL_STATE_STANDBY ;
@@ -230,6 +257,13 @@ static int light_onoff_status_send(struct bt_mesh_light_ctrl_srv *srv,
230257 3 );
231258 light_onoff_encode (srv , & buf , prev_state );
232259
260+ if (buf .len > 2 ) {
261+ LOG_DBG ("POnOff: %u TOnOff: %u RT: 0x%02X" , buf .data [2 ], buf .data [3 ],
262+ (uint8_t ) buf .data [4 ]);
263+ } else {
264+ LOG_DBG ("POnOff: %u" , buf .data [2 ]);
265+ }
266+
233267 return bt_mesh_msg_send (srv -> model , ctx , & buf );
234268}
235269
@@ -888,7 +922,7 @@ static int light_onoff_set(struct bt_mesh_light_ctrl_srv *srv, struct bt_mesh_ms
888922 enum bt_mesh_light_ctrl_srv_state prev_state = srv -> state ;
889923
890924 if (!tid_check_and_update (& srv -> tid , tid , ctx )) {
891- LOG_DBG ("Set Light OnOff: %s (%u + %u)" , onoff ? "on" : "off" ,
925+ LOG_DBG ("Set Light OnOff: %s (TT %u + Delay %u)" , onoff ? "on" : "off" ,
892926 has_trans ? transition .time : 0 ,
893927 has_trans ? transition .delay : 0 );
894928
0 commit comments