diff --git a/examples/lock-app/lock-common/include/LockEndpoint.h b/examples/lock-app/lock-common/include/LockEndpoint.h index 6e1fb0311f29b4..01b22a12033ab3 100644 --- a/examples/lock-app/lock-common/include/LockEndpoint.h +++ b/examples/lock-app/lock-common/include/LockEndpoint.h @@ -64,9 +64,12 @@ class LockEndpoint inline chip::EndpointId GetEndpointId() const { return mEndpointId; } - bool Lock(const Optional & pin, OperationErrorEnum & err, OperationSourceEnum opSource); - bool Unlock(const Optional & pin, OperationErrorEnum & err, OperationSourceEnum opSource); - bool Unbolt(const Optional & pin, OperationErrorEnum & err, OperationSourceEnum opSource); + bool Lock(const chip::app::CommandHandler * commandObj, const Optional & pin, OperationErrorEnum & err, + OperationSourceEnum opSource); + bool Unlock(const chip::app::CommandHandler * commandObj, const Optional & pin, OperationErrorEnum & err, + OperationSourceEnum opSource); + bool Unbolt(const chip::app::CommandHandler * commandObj, 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, @@ -98,8 +101,8 @@ class LockEndpoint OperatingModeEnum operatingMode); private: - bool setLockState(DlLockState lockState, const Optional & pin, OperationErrorEnum & err, - OperationSourceEnum opSource = OperationSourceEnum::kUnspecified); + bool setLockState(const chip::app::CommandHandler * commandObj, 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/lock-common/include/LockManager.h b/examples/lock-app/lock-common/include/LockManager.h index eb6d6e99d51e66..728424092bde1e 100644 --- a/examples/lock-app/lock-common/include/LockManager.h +++ b/examples/lock-app/lock-common/include/LockManager.h @@ -35,12 +35,12 @@ class LockManager bool SendLockAlarm(chip::EndpointId endpointId, AlarmCodeEnum alarmCode); - 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 Unbolt(chip::EndpointId endpointId, const Optional & pin, OperationErrorEnum & err, - OperationSourceEnum opSource); + bool Lock(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, const Optional & pin, + OperationErrorEnum & err, OperationSourceEnum opSource); + bool Unlock(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, const Optional & pin, + OperationErrorEnum & err, OperationSourceEnum opSource); + bool Unbolt(const chip::app::CommandHandler * commandObj, 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/lock-common/src/LockEndpoint.cpp b/examples/lock-app/lock-common/src/LockEndpoint.cpp index ec090b03f44e3c..5db2212586d4bc 100644 --- a/examples/lock-app/lock-common/src/LockEndpoint.cpp +++ b/examples/lock-app/lock-common/src/LockEndpoint.cpp @@ -22,25 +22,28 @@ using chip::to_underlying; using chip::app::DataModel::MakeNullable; -bool LockEndpoint::Lock(const Optional & pin, OperationErrorEnum & err, OperationSourceEnum opSource) +bool LockEndpoint::Lock(const chip::app::CommandHandler * commandObj, const Optional & pin, + OperationErrorEnum & err, OperationSourceEnum opSource) { - return setLockState(DlLockState::kLocked, pin, err, opSource); + return setLockState(commandObj, DlLockState::kLocked, pin, err, opSource); } -bool LockEndpoint::Unlock(const Optional & pin, OperationErrorEnum & err, OperationSourceEnum opSource) +bool LockEndpoint::Unlock(const chip::app::CommandHandler * commandObj, const Optional & pin, + OperationErrorEnum & err, OperationSourceEnum opSource) { if (DoorLockServer::Instance().SupportsUnbolt(mEndpointId)) { // If Unbolt is supported Unlock is supposed to pull the latch - setLockState(DlLockState::kUnlatched, pin, err, opSource); + setLockState(commandObj, DlLockState::kUnlatched, pin, err, opSource); } - return setLockState(DlLockState::kUnlocked, pin, err, opSource); + return setLockState(commandObj, DlLockState::kUnlocked, pin, err, opSource); } -bool LockEndpoint::Unbolt(const Optional & pin, OperationErrorEnum & err, OperationSourceEnum opSource) +bool LockEndpoint::Unbolt(const chip::app::CommandHandler * commandObj, const Optional & pin, + OperationErrorEnum & err, OperationSourceEnum opSource) { - return setLockState(DlLockState::kUnlocked, pin, err, opSource); + return setLockState(commandObj, DlLockState::kUnlocked, pin, err, opSource); } bool LockEndpoint::GetUser(uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) const @@ -388,8 +391,8 @@ DlStatus LockEndpoint::SetSchedule(uint8_t holidayIndex, DlScheduleStatus status return DlStatus::kSuccess; } -bool LockEndpoint::setLockState(DlLockState lockState, const Optional & pin, OperationErrorEnum & err, - OperationSourceEnum opSource) +bool LockEndpoint::setLockState(const chip::app::CommandHandler * commandObj, DlLockState lockState, + const Optional & pin, OperationErrorEnum & err, OperationSourceEnum opSource) { // Assume pin is required until told otherwise bool requirePin = true; @@ -406,13 +409,14 @@ bool LockEndpoint::setLockState(DlLockState lockState, const Optional>(userCredential); - DoorLockServer::Instance().SetLockState(mEndpointId, mLockState, opSource, MakeNullable(static_cast(userIndex + 1)), - userCredentials); + DoorLockServer::Instance().SetLockState(nullptr, mEndpointId, mLockState, opSource, + MakeNullable(static_cast(userIndex + 1)), userCredentials); return true; } diff --git a/examples/lock-app/lock-common/src/LockManager.cpp b/examples/lock-app/lock-common/src/LockManager.cpp index f904005340a1fc..9353a00c411e35 100644 --- a/examples/lock-app/lock-common/src/LockManager.cpp +++ b/examples/lock-app/lock-common/src/LockManager.cpp @@ -134,8 +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, - OperationSourceEnum opSource) +bool LockManager::Lock(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, + const Optional & pin, OperationErrorEnum & err, OperationSourceEnum opSource) { auto lockEndpoint = getEndpoint(endpointId); if (nullptr == lockEndpoint) @@ -143,11 +143,11 @@ bool LockManager::Lock(chip::EndpointId endpointId, const OptionalLock(pin, err, opSource); + return lockEndpoint->Lock(commandObj, pin, err, opSource); } -bool LockManager::Unlock(chip::EndpointId endpointId, const Optional & pin, OperationErrorEnum & err, - OperationSourceEnum opSource) +bool LockManager::Unlock(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, + const Optional & pin, OperationErrorEnum & err, OperationSourceEnum opSource) { auto lockEndpoint = getEndpoint(endpointId); if (nullptr == lockEndpoint) @@ -155,11 +155,11 @@ bool LockManager::Unlock(chip::EndpointId endpointId, const OptionalUnlock(pin, err, opSource); + return lockEndpoint->Unlock(commandObj, pin, err, opSource); } -bool LockManager::Unbolt(chip::EndpointId endpointId, const Optional & pin, OperationErrorEnum & err, - OperationSourceEnum opSource) +bool LockManager::Unbolt(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, + const Optional & pin, OperationErrorEnum & err, OperationSourceEnum opSource) { auto lockEndpoint = getEndpoint(endpointId); if (nullptr == lockEndpoint) @@ -167,7 +167,7 @@ bool LockManager::Unbolt(chip::EndpointId endpointId, const OptionalUnbolt(pin, err, opSource); + return lockEndpoint->Unbolt(commandObj, pin, err, opSource); } bool LockManager::GetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) diff --git a/examples/lock-app/lock-common/src/ZCLDoorLockCallbacks.cpp b/examples/lock-app/lock-common/src/ZCLDoorLockCallbacks.cpp index bbecc8ef6ce178..2ac632613ab53a 100644 --- a/examples/lock-app/lock-common/src/ZCLDoorLockCallbacks.cpp +++ b/examples/lock-app/lock-common/src/ZCLDoorLockCallbacks.cpp @@ -28,22 +28,22 @@ using namespace chip::app::Clusters::DoorLock; // should wait for door to be locked on lock command and return success) but // door lock server should check pin before even calling the lock-door // callback. -bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const Optional & pinCode, - OperationErrorEnum & err) +bool emberAfPluginDoorLockOnDoorLockCommand(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, + const Optional & pinCode, OperationErrorEnum & err) { - return LockManager::Instance().Lock(endpointId, pinCode, err, OperationSourceEnum::kRemote); + return LockManager::Instance().Lock(commandObj, endpointId, pinCode, err, OperationSourceEnum::kRemote); } -bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const Optional & pinCode, - OperationErrorEnum & err) +bool emberAfPluginDoorLockOnDoorUnlockCommand(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, + const Optional & pinCode, OperationErrorEnum & err) { - return LockManager::Instance().Unlock(endpointId, pinCode, err, OperationSourceEnum::kRemote); + return LockManager::Instance().Unlock(commandObj, endpointId, pinCode, err, OperationSourceEnum::kRemote); } -bool emberAfPluginDoorLockOnDoorUnboltCommand(chip::EndpointId endpointId, const Optional & pinCode, - OperationErrorEnum & err) +bool emberAfPluginDoorLockOnDoorUnboltCommand(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, + const Optional & pinCode, OperationErrorEnum & err) { - return LockManager::Instance().Unbolt(endpointId, pinCode, err, OperationSourceEnum::kRemote); + return LockManager::Instance().Unbolt(commandObj, 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-callback.cpp b/src/app/clusters/door-lock-server/door-lock-server-callback.cpp index 9db680168dd637..a28bc8c05f6f27 100644 --- a/src/app/clusters/door-lock-server/door-lock-server-callback.cpp +++ b/src/app/clusters/door-lock-server/door-lock-server-callback.cpp @@ -45,21 +45,24 @@ using namespace chip::app::Clusters::DoorLock; // ============================================================================= bool __attribute__((weak)) -emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const Optional & pinCode, OperationErrorEnum & err) +emberAfPluginDoorLockOnDoorLockCommand(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, + const Optional & pinCode, OperationErrorEnum & err) { err = OperationErrorEnum::kUnspecified; return false; } bool __attribute__((weak)) -emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const Optional & pinCode, OperationErrorEnum & err) +emberAfPluginDoorLockOnDoorUnlockCommand(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, + const Optional & pinCode, OperationErrorEnum & err) { err = OperationErrorEnum::kUnspecified; return false; } bool __attribute__((weak)) -emberAfPluginDoorLockOnDoorUnboltCommand(chip::EndpointId endpointId, const Optional & pinCode, OperationErrorEnum & err) +emberAfPluginDoorLockOnDoorUnboltCommand(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, + const Optional & pinCode, OperationErrorEnum & err) { err = OperationErrorEnum::kUnspecified; return false; 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 dbfd723ad8cfff..7231c1c3606891 100644 --- a/src/app/clusters/door-lock-server/door-lock-server.cpp +++ b/src/app/clusters/door-lock-server/door-lock-server.cpp @@ -103,14 +103,12 @@ 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, - const Nullable & userIndex, const Nullable> & credentials) +bool DoorLockServer::SetLockState(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, + DlLockState newLockState, OperationSourceEnum opSource, const Nullable & userIndex, + const Nullable> & credentials) { bool success = SetLockState(endpointId, newLockState); - // Remote operations are handled separately as they use more data unavailable here - VerifyOrReturnError(OperationSourceEnum::kRemote != opSource, success); - // DlLockState::kNotFullyLocked has no appropriate event to send. Also it is unclear whether // it should schedule auto-relocking. So skip it here. Check for supported states explicitly // to handle possible enum extending in future. @@ -130,8 +128,17 @@ bool DoorLockServer::SetLockState(chip::EndpointId endpointId, DlLockState newLo opType = LockOperationTypeEnum::kUnlatch; } - SendLockOperationEvent(endpointId, opType, opSource, OperationErrorEnum::kUnspecified, userIndex, Nullable(), - Nullable(), credentials, success); + if (commandObj == nullptr) + { + SendLockOperationEvent(endpointId, opType, opSource, OperationErrorEnum::kUnspecified, userIndex, + Nullable(), Nullable(), credentials, success); + } + else + { + SendLockOperationEvent(endpointId, opType, opSource, OperationErrorEnum::kUnspecified, userIndex, + Nullable(getFabricIndex(commandObj)), + Nullable(getNodeId(commandObj)), credentials, success); + } // Reset wrong entry attempts (in case there were any incorrect credentials presented before) if lock/unlock was a success // and a valid credential was presented. @@ -3428,7 +3435,7 @@ bool DoorLockServer::HandleRemoteLockOperation(chip::app::CommandHandler * comma } // credentials check succeeded, try to lock/unlock door - success = opHandler(endpoint, pinCode, reason); + success = opHandler(commandObj, endpoint, pinCode, reason); // The app should trigger the lock state change as it may take a while before the lock actually locks/unlocks exit: if (!success && reason == OperationErrorEnum::kInvalidCredential) @@ -3464,23 +3471,15 @@ bool DoorLockServer::HandleRemoteLockOperation(chip::app::CommandHandler * comma credentials.SetNonNull(foundCred); } - // Failed Unlatch requests SHALL generate only a LockOperationError event with LockOperationType set to Unlock - if (LockOperationTypeEnum::kUnlatch == opType && !success) + if (!success) { - opType = LockOperationTypeEnum::kUnlock; - } - - SendLockOperationEvent(endpoint, opType, OperationSourceEnum::kRemote, reason, pinUserIdx, - Nullable(getFabricIndex(commandObj)), Nullable(getNodeId(commandObj)), - credentials, success); + // Failed Unlatch requests SHALL generate only a LockOperationError event with LockOperationType set to Unlock + if (LockOperationTypeEnum::kUnlatch == opType) + { + opType = LockOperationTypeEnum::kUnlock; + } - // SHALL generate a LockOperation event with LockOperationType set to Unlatch when the unlatched state is reached and a - // LockOperation event with LockOperationType set to Unlock when the lock successfully completes the unlock. But as the current - // implementation here is sending LockOperation events immediately we're sending both events immediately. - // https://github.com/project-chip/connectedhomeip/issues/26925 - if (LockOperationTypeEnum::kUnlatch == opType && success) - { - SendLockOperationEvent(endpoint, LockOperationTypeEnum::kUnlock, OperationSourceEnum::kRemote, reason, pinUserIdx, + SendLockOperationEvent(endpoint, opType, OperationSourceEnum::kRemote, reason, pinUserIdx, Nullable(getFabricIndex(commandObj)), Nullable(getNodeId(commandObj)), credentials, success); } @@ -3937,7 +3936,7 @@ void DoorLockServer::DoorLockOnAutoRelockCallback(System::Layer *, void * callba { ChipLogProgress(Zcl, "Door Auto relock timer expired. %s", "Locking..."); - DoorLockServer::Instance().SetLockState(endpointId, DlLockState::kLocked, OperationSourceEnum::kAuto); + DoorLockServer::Instance().SetLockState(nullptr, endpointId, DlLockState::kLocked, OperationSourceEnum::kAuto); emberAfPluginDoorLockOnAutoRelock(endpointId); } else 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 bb2ce23571ba8b..199a0f3dd34062 100644 --- a/src/app/clusters/door-lock-server/door-lock-server.h +++ b/src/app/clusters/door-lock-server/door-lock-server.h @@ -59,8 +59,8 @@ using chip::app::DataModel::NullNullable; using CredentialStruct = chip::app::Clusters::DoorLock::Structs::CredentialStruct::Type; using LockOpCredentials = CredentialStruct; -typedef bool (*RemoteLockOpHandler)(chip::EndpointId endpointId, const Optional & pinCode, - OperationErrorEnum & err); +typedef bool (*RemoteLockOpHandler)(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, + const Optional & pinCode, OperationErrorEnum & err); static constexpr size_t DOOR_LOCK_MAX_USER_NAME_SIZE = 10; /**< Maximum size of the user name (in characters). */ static constexpr size_t DOOR_LOCK_USER_NAME_BUFFER_SIZE = @@ -92,14 +92,15 @@ class DoorLockServer * * @note Does not send an event of opSource is kRemote. * + * @param commandObj command context * @param endpointId ID of the endpoint to the lock state * @param newLockState new lock state * @param opSource source of the operation (will be used in the event). * * @return true on success, false on failure. */ - bool SetLockState(chip::EndpointId endpointId, DlLockState newLockState, OperationSourceEnum opSource, - const Nullable & userIndex = NullNullable, + bool SetLockState(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, DlLockState newLockState, + OperationSourceEnum opSource, const Nullable & userIndex = NullNullable, const Nullable> & credentials = NullNullable); /** @@ -898,6 +899,7 @@ emberAfPluginDoorLockOnUnhandledAttributeChange(chip::EndpointId EndpointId, con /** * @brief User handler for LockDoor command (server) * + * @param commandObj command context * @param endpointId endpoint for which LockDoor command is called * @param pinCode PIN code (optional) * @param err error code if door locking failed (set only if retval==false) @@ -905,12 +907,13 @@ emberAfPluginDoorLockOnUnhandledAttributeChange(chip::EndpointId EndpointId, con * @retval true on success * @retval false if error happenned (err should be set to appropriate error code) */ -bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const Optional & pinCode, - OperationErrorEnum & err); +bool emberAfPluginDoorLockOnDoorLockCommand(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, + const Optional & pinCode, OperationErrorEnum & err); /** * @brief User handler for UnlockDoor command (server) * + * @param commandObj command context * @param endpointId endpoint for which UnlockDoor command is called * @param pinCode PIN code (optional) * @param err error code if door unlocking failed (set only if retval==false) @@ -918,12 +921,13 @@ bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const O * @retval true on success * @retval false if error happenned (err should be set to appropriate error code) */ -bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const Optional & pinCode, - OperationErrorEnum & err); +bool emberAfPluginDoorLockOnDoorUnlockCommand(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, + const Optional & pinCode, OperationErrorEnum & err); /** * @brief User handler for UnboltDoor command (server) * + * @param commandObj command context * @param endpointId endpoint for which UnboltDoor command is called * @param pinCode PIN code (optional) * @param err error code if door unbolting failed (set only if retval==false) @@ -931,8 +935,8 @@ bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const * @retval true on success * @retval false if error happenned (err should be set to appropriate error code) */ -bool emberAfPluginDoorLockOnDoorUnboltCommand(chip::EndpointId endpointId, const Optional & pinCode, - OperationErrorEnum & err); +bool emberAfPluginDoorLockOnDoorUnboltCommand(const chip::app::CommandHandler * commandObj, chip::EndpointId endpointId, + const Optional & pinCode, OperationErrorEnum & err); /** * @brief This callback is called when the AutoRelock timer is expired.