blob: 28176c9efee3b6ac8bbaf47c76d0d4f2a5c7862a [file] [log] [blame]
/*
*
* Copyright (c) 2023 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <app/clusters/door-lock-server/door-lock-server.h>
#include <lib/core/ClusterEnums.h>
#include <lib/support/ScopedBuffer.h>
#include <zephyr/kernel.h>
#include <cstdint>
#include <vector>
// Maximum number of credentials per user supported by lock
#define CONFIG_LOCK_NUM_CREDENTIALS_PER_USER (2)
// Maximum number of users supported by lock
#define CONFIG_LOCK_NUM_USERS (5)
// Maximum number of credentials supported by lock
#define CONFIG_LOCK_NUM_CREDENTIALS (10)
struct LockCredentialInfo;
#define CONFIG_LOCK_CREDENTIAL_INFO_MAX_DATA_SIZE (20)
#define CONFIG_LOCK_CREDENTIAL_INFO_MAX_TYPES (6)
class AppEvent;
class BoltLockManager
{
public:
BoltLockManager() :
mCredentials(CONFIG_LOCK_CREDENTIAL_INFO_MAX_TYPES, std::vector<LockCredentialInfo>(CONFIG_LOCK_NUM_CREDENTIALS + 1))
{}
static constexpr size_t kMaxCredentialLength = 128;
enum class State : uint8_t
{
kLockingInitiated = 0,
kLockingCompleted,
kUnlockingInitiated,
kUnlockingCompleted,
};
struct UserData
{
char mName[DOOR_LOCK_USER_NAME_BUFFER_SIZE];
CredentialStruct mCredentials[CONFIG_LOCK_NUM_CREDENTIALS_PER_USER];
};
struct CredentialData
{
chip::Platform::ScopedMemoryBuffer<uint8_t> mSecret;
};
using OperationSource = chip::app::Clusters::DoorLock::OperationSourceEnum;
using StateChangeCallback = void (*)(State, OperationSource);
static constexpr uint32_t kActuatorMovementTimeMs = 2000;
void Init(StateChangeCallback callback);
State GetState() const { return mState; }
bool IsLocked() const { return mState == State::kLockingCompleted; }
bool GetUser(uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) const;
bool SetUser(uint16_t userIndex, chip::FabricIndex creator, chip::FabricIndex modifier, const chip::CharSpan & userName,
uint32_t uniqueId, UserStatusEnum userStatus, UserTypeEnum userType, CredentialRuleEnum credentialRule,
const CredentialStruct * credentials, size_t totalCredentials);
bool GetCredential(uint16_t credentialIndex, CredentialTypeEnum credentialType,
EmberAfPluginDoorLockCredentialInfo & credential) const;
bool SetCredential(uint16_t credentialIndex, chip::FabricIndex creator, chip::FabricIndex modifier,
DlCredentialStatus credentialStatus, CredentialTypeEnum credentialType,
const chip::ByteSpan & credentialData);
bool ValidatePIN(const Optional<chip::ByteSpan> & pinCode, OperationErrorEnum & err) const;
void Lock(OperationSource source);
void Unlock(OperationSource source);
private:
void SetState(State state, OperationSource source);
static void ActuatorTimerEventHandler(k_timer * timer);
static void ActuatorAppEventHandler(const AppEvent & aEvent);
friend BoltLockManager & BoltLockMgr();
State mState = State::kLockingCompleted;
StateChangeCallback mStateChangeCallback = nullptr;
OperationSource mActuatorOperationSource = OperationSource::kButton;
k_timer mActuatorTimer = {};
UserData mUserData[CONFIG_LOCK_NUM_USERS];
EmberAfPluginDoorLockUserInfo mUsers[CONFIG_LOCK_NUM_USERS] = {};
struct LockCredentialInfo
{
DlCredentialStatus status;
CredentialTypeEnum credentialType;
chip::FabricIndex createdBy;
chip::FabricIndex modifiedBy;
uint8_t credentialData[CONFIG_LOCK_CREDENTIAL_INFO_MAX_TYPES];
size_t credentialDataSize;
};
std::vector<std::vector<LockCredentialInfo>> mCredentials;
static BoltLockManager sLock;
};
inline BoltLockManager & BoltLockMgr()
{
return BoltLockManager::sLock;
}