@@ -186,22 +186,24 @@ bool LockManager::InitiateAction(int32_t aActor, Action_t aAction)
186
186
State_t new_state;
187
187
188
188
// Initiate Turn Lock/Unlock Action only when the previous one is complete.
189
- if (mState == kState_LockCompleted && aAction == UNLOCK_ACTION)
189
+ if (( mState == kState_LockCompleted || mState == kState_UnlatchCompleted ) && ( aAction == UNLOCK_ACTION) )
190
190
{
191
191
action_initiated = true ;
192
-
193
- new_state = kState_UnlockInitiated ;
192
+ new_state = kState_UnlockInitiated ;
193
+ }
194
+ else if ((mState == kState_LockCompleted || mState == kState_UnlockCompleted ) && (aAction == UNLATCH_ACTION))
195
+ {
196
+ action_initiated = true ;
197
+ new_state = kState_UnlatchInitiated ;
194
198
}
195
199
else if (mState == kState_UnlockCompleted && aAction == LOCK_ACTION)
196
200
{
197
201
action_initiated = true ;
198
-
199
- new_state = kState_LockInitiated ;
202
+ new_state = kState_LockInitiated ;
200
203
}
201
204
202
205
if (action_initiated)
203
206
{
204
-
205
207
StartTimer (ACTUATOR_MOVEMENT_PERIOS_MS);
206
208
207
209
// Since the timer started successfully, update the state and trigger callback
@@ -249,6 +251,23 @@ void LockManager::TimerEventHandler(void * timerCbArg)
249
251
event.Handler = ActuatorMovementTimerEventHandler;
250
252
AppTask::GetAppTask ().PostEvent (&event);
251
253
}
254
+ void LockManager::UnlockAfterUnlatch ()
255
+ {
256
+ // write the new lock value
257
+ bool succes = false ;
258
+ if (mUnlatchContext .mEndpointId != kInvalidEndpointId )
259
+ {
260
+ succes = setLockState (mUnlatchContext .mEndpointId , mUnlatchContext .mFabricIdx , mUnlatchContext .mNodeId ,
261
+ DlLockState::kUnlocked , mUnlatchContext .mPin , mUnlatchContext .mErr );
262
+ }
263
+
264
+ if (!succes)
265
+ {
266
+ SILABS_LOG (" Failed to update the lock state after Unlatch" );
267
+ }
268
+
269
+ InitiateAction (AppEvent::kEventType_Lock , LockManager::UNLOCK_ACTION);
270
+ }
252
271
253
272
void LockManager::ActuatorMovementTimerEventHandler (AppEvent * aEvent)
254
273
{
@@ -261,6 +280,11 @@ void LockManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent)
261
280
lock->mState = kState_LockCompleted ;
262
281
actionCompleted = LOCK_ACTION;
263
282
}
283
+ else if (lock->mState == kState_UnlatchInitiated )
284
+ {
285
+ lock->mState = kState_UnlatchCompleted ;
286
+ actionCompleted = UNLATCH_ACTION;
287
+ }
264
288
else if (lock->mState == kState_UnlockInitiated )
265
289
{
266
290
lock->mState = kState_UnlockCompleted ;
@@ -285,6 +309,29 @@ bool LockManager::Lock(chip::EndpointId endpointId, const Nullable<chip::FabricI
285
309
bool LockManager::Unlock (chip::EndpointId endpointId, const Nullable<chip::FabricIndex> & fabricIdx,
286
310
const Nullable<chip::NodeId> & nodeId, const Optional<chip::ByteSpan> & pin, OperationErrorEnum & err)
287
311
{
312
+ if (DoorLockServer::Instance ().SupportsUnbolt (endpointId))
313
+ {
314
+ // TODO: Our current implementation does not support multiple endpoint. This needs to be fixed in the future.
315
+ if (endpointId != mUnlatchContext .mEndpointId )
316
+ {
317
+ // If we get a request to unlock on a different endpoint while the current endpoint is in the middle of an action,
318
+ // we return false for now. This needs to be fixed in the future.
319
+ if (mState != kState_UnlockCompleted && mState != kState_LockCompleted )
320
+ {
321
+ ChipLogError (Zcl, " Cannot unlock while unlatch on another endpoint is in progress on anotther endpoint" );
322
+ return false ;
323
+ }
324
+ else
325
+ {
326
+ mUnlatchContext .Update (endpointId, fabricIdx, nodeId, pin, err);
327
+ return setLockState (endpointId, fabricIdx, nodeId, DlLockState::kUnlatched , pin, err);
328
+ }
329
+ }
330
+ else
331
+ {
332
+ return setLockState (endpointId, fabricIdx, nodeId, DlLockState::kUnlatched , pin, err);
333
+ }
334
+ }
288
335
return setLockState (endpointId, fabricIdx, nodeId, DlLockState::kUnlocked , pin, err);
289
336
}
290
337
0 commit comments