From e022273c71997d15520c4346f461b035c4fdc5ea Mon Sep 17 00:00:00 2001 From: jvillasenor Date: Thu, 16 Feb 2023 08:39:49 -0800 Subject: [PATCH] Resolve event notifications from lock when setting the lock state. --- .../lock-app/linux/include/LockEndpoint.h | 7 +++-- examples/lock-app/linux/include/LockManager.h | 6 ++-- examples/lock-app/linux/src/LockEndpoint.cpp | 18 ++++++----- examples/lock-app/linux/src/LockManager.cpp | 10 ++++--- .../linux/src/ZCLDoorLockCallbacks.cpp | 4 +-- .../door-lock-server/door-lock-server.cpp | 30 +++++-------------- .../door-lock-server/door-lock-server.h | 7 +++-- 7 files changed, 40 insertions(+), 42 deletions(-) diff --git a/examples/lock-app/linux/include/LockEndpoint.h b/examples/lock-app/linux/include/LockEndpoint.h index 7ba34d10d6c3cd..f652ec2df6f0a8 100644 --- a/examples/lock-app/linux/include/LockEndpoint.h +++ b/examples/lock-app/linux/include/LockEndpoint.h @@ -64,8 +64,8 @@ class LockEndpoint inline chip::EndpointId GetEndpointId() const { return mEndpointId; } - bool Lock(const Optional & pin, OperationErrorEnum & err); - bool Unlock(const Optional & pin, OperationErrorEnum & err); + bool Lock(const Optional & pin, OperationErrorEnum & err, OperationSourceEnum opSource); + bool Unlock(const Optional & pin, OperationErrorEnum & err, OperationSourceEnum opSource); bool GetUser(uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) const; bool SetUser(uint16_t userIndex, chip::FabricIndex creator, chip::FabricIndex modifier, const chip::CharSpan & userName, @@ -97,7 +97,8 @@ class LockEndpoint OperatingModeEnum operatingMode); private: - bool setLockState(DlLockState lockState, const Optional & pin, OperationErrorEnum & err); + bool setLockState(DlLockState lockState, const Optional & pin, OperationErrorEnum & err, + OperationSourceEnum opSource = OperationSourceEnum::kUnspecified); const char * lockStateToString(DlLockState lockState) const; bool weekDayScheduleInAction(uint16_t userIndex) const; diff --git a/examples/lock-app/linux/include/LockManager.h b/examples/lock-app/linux/include/LockManager.h index 07123df607bf46..9f274abe487598 100644 --- a/examples/lock-app/linux/include/LockManager.h +++ b/examples/lock-app/linux/include/LockManager.h @@ -35,8 +35,10 @@ class LockManager bool SendLockAlarm(chip::EndpointId endpointId, AlarmCodeEnum alarmCode); - bool Lock(chip::EndpointId endpointId, const Optional & pin, OperationErrorEnum & err); - bool Unlock(chip::EndpointId endpointId, const Optional & pin, OperationErrorEnum & err); + bool Lock(chip::EndpointId endpointId, const Optional & pin, OperationErrorEnum & err, + OperationSourceEnum opSource); + bool Unlock(chip::EndpointId endpointId, const Optional & pin, OperationErrorEnum & err, + OperationSourceEnum opSource); bool GetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user); bool SetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator, chip::FabricIndex modifier, diff --git a/examples/lock-app/linux/src/LockEndpoint.cpp b/examples/lock-app/linux/src/LockEndpoint.cpp index bb18cbe2263747..7f5cf7a22873ad 100644 --- a/examples/lock-app/linux/src/LockEndpoint.cpp +++ b/examples/lock-app/linux/src/LockEndpoint.cpp @@ -20,15 +20,16 @@ #include using chip::to_underlying; +using chip::app::DataModel::MakeNullable; -bool LockEndpoint::Lock(const Optional & pin, OperationErrorEnum & err) +bool LockEndpoint::Lock(const Optional & pin, OperationErrorEnum & err, OperationSourceEnum opSource) { - return setLockState(DlLockState::kLocked, pin, err); + return setLockState(DlLockState::kLocked, pin, err, opSource); } -bool LockEndpoint::Unlock(const Optional & pin, OperationErrorEnum & err) +bool LockEndpoint::Unlock(const Optional & pin, OperationErrorEnum & err, OperationSourceEnum opSource) { - return setLockState(DlLockState::kUnlocked, pin, err); + return setLockState(DlLockState::kUnlocked, pin, err, opSource); } bool LockEndpoint::GetUser(uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) const @@ -376,7 +377,8 @@ DlStatus LockEndpoint::SetSchedule(uint8_t holidayIndex, DlScheduleStatus status return DlStatus::kSuccess; } -bool LockEndpoint::setLockState(DlLockState lockState, const Optional & pin, OperationErrorEnum & err) +bool LockEndpoint::setLockState(DlLockState lockState, const Optional & pin, OperationErrorEnum & err, + OperationSourceEnum opSource) { // Assume pin is required until told otherwise bool requirePin = true; @@ -457,8 +459,10 @@ bool LockEndpoint::setLockState(DlLockState lockState, const Optional>(userCredential); + DoorLockServer::Instance().SetLockState(mEndpointId, mLockState, opSource, Nullable(userIndex + 1), userCredentials); return true; } diff --git a/examples/lock-app/linux/src/LockManager.cpp b/examples/lock-app/linux/src/LockManager.cpp index e4bb4cc9406344..69e12533857b3b 100644 --- a/examples/lock-app/linux/src/LockManager.cpp +++ b/examples/lock-app/linux/src/LockManager.cpp @@ -134,7 +134,8 @@ bool LockManager::SendLockAlarm(chip::EndpointId endpointId, AlarmCodeEnum alarm return lockEndpoint->SendLockAlarm(alarmCode); } -bool LockManager::Lock(chip::EndpointId endpointId, const Optional & pin, OperationErrorEnum & err) +bool LockManager::Lock(chip::EndpointId endpointId, const Optional & pin, OperationErrorEnum & err, + OperationSourceEnum opSource) { auto lockEndpoint = getEndpoint(endpointId); if (nullptr == lockEndpoint) @@ -142,10 +143,11 @@ bool LockManager::Lock(chip::EndpointId endpointId, const OptionalLock(pin, err); + return lockEndpoint->Lock(pin, err, opSource); } -bool LockManager::Unlock(chip::EndpointId endpointId, const Optional & pin, OperationErrorEnum & err) +bool LockManager::Unlock(chip::EndpointId endpointId, const Optional & pin, OperationErrorEnum & err, + OperationSourceEnum opSource) { auto lockEndpoint = getEndpoint(endpointId); if (nullptr == lockEndpoint) @@ -153,7 +155,7 @@ bool LockManager::Unlock(chip::EndpointId endpointId, const OptionalUnlock(pin, err); + return lockEndpoint->Unlock(pin, err, opSource); } bool LockManager::GetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) diff --git a/examples/lock-app/linux/src/ZCLDoorLockCallbacks.cpp b/examples/lock-app/linux/src/ZCLDoorLockCallbacks.cpp index a0670f2abf7f0c..6bc674f699b531 100644 --- a/examples/lock-app/linux/src/ZCLDoorLockCallbacks.cpp +++ b/examples/lock-app/linux/src/ZCLDoorLockCallbacks.cpp @@ -13,13 +13,13 @@ using namespace chip::app::Clusters::DoorLock; bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const Optional & pinCode, OperationErrorEnum & err) { - return LockManager::Instance().Lock(endpointId, pinCode, err); + return LockManager::Instance().Lock(endpointId, pinCode, err, OperationSourceEnum::kRemote); } bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const Optional & pinCode, OperationErrorEnum & err) { - return LockManager::Instance().Unlock(endpointId, pinCode, err); + return LockManager::Instance().Unlock(endpointId, pinCode, err, OperationSourceEnum::kRemote); } bool emberAfPluginDoorLockGetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) diff --git a/src/app/clusters/door-lock-server/door-lock-server.cpp b/src/app/clusters/door-lock-server/door-lock-server.cpp index 2a475b6a02f485..d25f61d6eefc6f 100644 --- a/src/app/clusters/door-lock-server/door-lock-server.cpp +++ b/src/app/clusters/door-lock-server/door-lock-server.cpp @@ -107,7 +107,8 @@ bool DoorLockServer::SetLockState(chip::EndpointId endpointId, DlLockState newLo return SetAttribute(endpointId, Attributes::LockState::Id, Attributes::LockState::Set, newLockState); } -bool DoorLockServer::SetLockState(chip::EndpointId endpointId, DlLockState newLockState, OperationSourceEnum opSource) +bool DoorLockServer::SetLockState(chip::EndpointId endpointId, DlLockState newLockState, OperationSourceEnum opSource, + const Nullable & userIndex, const Nullable> & credentials) { bool success = SetLockState(endpointId, newLockState); @@ -122,8 +123,8 @@ bool DoorLockServer::SetLockState(chip::EndpointId endpointId, DlLockState newLo // Send LockOperation event auto opType = (DlLockState::kLocked == newLockState) ? LockOperationTypeEnum::kLock : LockOperationTypeEnum::kUnlock; - SendLockOperationEvent(endpointId, opType, opSource, OperationErrorEnum::kUnspecified, Nullable(), - Nullable(), Nullable(), nullptr, 0, success); + SendLockOperationEvent(endpointId, opType, opSource, OperationErrorEnum::kUnspecified, userIndex, Nullable(), + Nullable(), credentials, success); // Schedule auto-relocking if (success && LockOperationTypeEnum::kUnlock == opType) @@ -3380,46 +3381,31 @@ bool DoorLockServer::HandleRemoteLockOperation(chip::app::CommandHandler * comma // Send LockOperation/LockOperationError event. The credential index in // foundCred will be filled in if we actually have a value to fill in. + Nullable> credentials{}; LockOpCredentials foundCred[] = { { CredentialTypeEnum::kPin, UINT16_MAX } }; - LockOpCredentials * credList = nullptr; - size_t credListSize = 0; // appclusters.pdf 5.3.5.3, 5.3.5.4: // The list of credentials used in performing the lock operation. This SHALL be null if no credentials were involved. if (pinCode.HasValue() && pinCredIdx.HasValue()) { foundCred[0].credentialIndex = pinCredIdx.Value(); - credList = foundCred; - credListSize = 1; + credentials.SetNonNull(foundCred); } SendLockOperationEvent(endpoint, opType, OperationSourceEnum::kRemote, reason, pinUserIdx, Nullable(getFabricIndex(commandObj)), Nullable(getNodeId(commandObj)), - credList, credListSize, success); + credentials, success); return success; } void DoorLockServer::SendLockOperationEvent(chip::EndpointId endpointId, LockOperationTypeEnum opType, OperationSourceEnum opSource, OperationErrorEnum opErr, const Nullable & userId, const Nullable & fabricIdx, const Nullable & nodeId, - LockOpCredentials * credList, size_t credListSize, bool opSuccess) + const Nullable> & credentials, bool opSuccess) { - Nullable> credentials{}; - - // appclusters.pdf 5.3.5.3, 5.3.5.4: - // The list of credentials used in performing the lock operation. This SHALL be null if no credentials were involved. - if (nullptr == credList || 0 == credListSize) - { - credentials.SetNull(); - } - else - { - credentials.SetNonNull(List(credList, credListSize)); - } // TODO: if [USR] feature is not supported then credentials should be omitted (Optional.HasValue()==false)? // Spec just says that it should be NULL if no PIN were provided. - if (opSuccess) { Events::LockOperation::Type event{ opType, opSource, userId, fabricIdx, nodeId, MakeOptional(credentials) }; diff --git a/src/app/clusters/door-lock-server/door-lock-server.h b/src/app/clusters/door-lock-server/door-lock-server.h index 3eeb79eba043e5..a925d16725f00a 100644 --- a/src/app/clusters/door-lock-server/door-lock-server.h +++ b/src/app/clusters/door-lock-server/door-lock-server.h @@ -54,6 +54,7 @@ using chip::app::Clusters::DoorLock::UserStatusEnum; using chip::app::Clusters::DoorLock::UserTypeEnum; using chip::app::DataModel::List; using chip::app::DataModel::Nullable; +using chip::app::DataModel::NullNullable; using CredentialStruct = chip::app::Clusters::DoorLock::Structs::CredentialStruct::Type; using LockOpCredentials = CredentialStruct; @@ -95,7 +96,9 @@ class DoorLockServer * * @return true on success, false on failure. */ - bool SetLockState(chip::EndpointId endpointId, DlLockState newLockState, OperationSourceEnum opSource); + bool SetLockState(chip::EndpointId endpointId, DlLockState newLockState, OperationSourceEnum opSource, + const Nullable & userIndex = NullNullable, + const Nullable> & credentials = NullNullable); /** * Updates the LockState attribute with new value. @@ -408,7 +411,7 @@ class DoorLockServer void SendLockOperationEvent(chip::EndpointId endpointId, LockOperationTypeEnum opType, OperationSourceEnum opSource, OperationErrorEnum opErr, const Nullable & userId, const Nullable & fabricIdx, const Nullable & nodeId, - LockOpCredentials * credList, size_t credListSize, bool opSuccess = true); + const Nullable> & credentials = NullNullable, bool opSuccess = true); /** * @brief Schedule auto relocking with a given timeout