Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EFR32] Lock-app working schedules with nvm storage, nvm credentials fix, add comments #20044

Merged
merged 6 commits into from
Jun 30, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 99 additions & 19 deletions examples/lock-app/efr32/include/LockManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,73 @@

#include <lib/core/CHIPError.h>

using namespace ::chip;
namespace EFR32DoorLock {
namespace ResourceRanges {
// Used to size arrays
static constexpr uint16_t kMaxUsers = 10;
static constexpr uint8_t kMaxCredentialsPerUser = 10;
static constexpr uint8_t kMaxWeekdaySchedulesPerUser = 10;
static constexpr uint8_t kMaxYeardaySchedulesPerUser = 10;
static constexpr uint8_t kMaxHolidaySchedules = 10;
static constexpr uint8_t kMaxCredentialSize = 8;

// Indices received for user/credential/schedules are 1-indexed
static constexpr uint8_t kStartIndexValue = 1;

// Currently up to 10 users are support on the EFR32 platform
#define DOOR_LOCK_MAX_USERS 10
#define DOOR_LOCK_MAX_CREDENTIAL_SIZE 8
#define MININUM_USER_INDEX 1
#define MINIMUM_CREDENTIAL_INDEX 1
#define MAX_CREDENTIAL_PER_USER 10
#define MAX_CREDENTIALS 50
static constexpr uint8_t kMaxCredentials = kMaxUsers * kMaxCredentialsPerUser;
} // namespace ResourceRanges

static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_DATA_SIZE = 20;
namespace LockInitParams {

struct LockParam
{
// Read from zap attributes
uint16_t numberOfUsers = 0;
uint8_t numberOfCredentialsPerUser = 0;
uint8_t numberOfWeekdaySchedulesPerUser = 0;
uint8_t numberOfYeardaySchedulesPerUser = 0;
uint8_t numberOfHolidaySchedules = 0;
};

class ParamBuilder
{
public:
ParamBuilder & SetNumberOfUsers(uint16_t numberOfUsers)
{
lockParam_.numberOfUsers = numberOfUsers;
return *this;
}
ParamBuilder & SetNumberOfCredentialsPerUser(uint8_t numberOfCredentialsPerUser)
{
lockParam_.numberOfCredentialsPerUser = numberOfCredentialsPerUser;
return *this;
}
ParamBuilder & SetNumberOfWeekdaySchedulesPerUser(uint8_t numberOfWeekdaySchedulesPerUser)
{
lockParam_.numberOfWeekdaySchedulesPerUser = numberOfWeekdaySchedulesPerUser;
return *this;
}
ParamBuilder & SetNumberOfYeardaySchedulesPerUser(uint8_t numberOfYeardaySchedulesPerUser)
{
lockParam_.numberOfYeardaySchedulesPerUser = numberOfYeardaySchedulesPerUser;
return *this;
}
ParamBuilder & SetNumberOfHolidaySchedules(uint8_t numberOfHolidaySchedules)
{
lockParam_.numberOfHolidaySchedules = numberOfHolidaySchedules;
return *this;
}
LockParam GetLockParam() { return lockParam_; }

private:
LockParam lockParam_;
};

} // namespace LockInitParams
} // namespace EFR32DoorLock

using namespace ::chip;
using namespace EFR32DoorLock::ResourceRanges;

class LockManager
{
Expand All @@ -61,7 +117,7 @@ class LockManager
} State;

CHIP_ERROR Init(chip::app::DataModel::Nullable<chip::app::Clusters::DoorLock::DlLockState> state,
uint8_t maxNumberOfCredentialsPerUser, uint16_t numberOfSupportedUsers);
EFR32DoorLock::LockInitParams::LockParam lockParam);
bool NextState();
bool IsActionInProgress();
bool InitiateAction(int32_t aActor, Action_t aAction);
Expand All @@ -73,17 +129,40 @@ class LockManager
bool Lock(chip::EndpointId endpointId, const Optional<chip::ByteSpan> & pin, DlOperationError & err);
bool Unlock(chip::EndpointId endpointId, const Optional<chip::ByteSpan> & pin, DlOperationError & err);

bool GetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) const;
bool GetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user);
bool SetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator, chip::FabricIndex modifier,
const chip::CharSpan & userName, uint32_t uniqueId, DlUserStatus userStatus, DlUserType usertype,
DlCredentialRule credentialRule, const DlCredential * credentials, size_t totalCredentials);

bool GetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, DlCredentialType credentialType,
EmberAfPluginDoorLockCredentialInfo & credential) const;
EmberAfPluginDoorLockCredentialInfo & credential);

bool SetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator, chip::FabricIndex modifier,
DlCredentialStatus credentialStatus, DlCredentialType credentialType, const chip::ByteSpan & credentialData);

DlStatus GetWeekdaySchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex,
EmberAfPluginDoorLockWeekDaySchedule & schedule);

DlStatus SetWeekdaySchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex, DlScheduleStatus status,
DlDaysMaskMap daysMask, uint8_t startHour, uint8_t startMinute, uint8_t endHour, uint8_t endMinute);

DlStatus GetYeardaySchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex,
EmberAfPluginDoorLockYearDaySchedule & schedule);

DlStatus SetYeardaySchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, DlScheduleStatus status,
uint32_t localStartTime, uint32_t localEndTime);

DlStatus GetHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex, EmberAfPluginDoorLockHolidaySchedule & schedule);

DlStatus SetHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex, DlScheduleStatus status, uint32_t localStartTime,
uint32_t localEndTime, DlOperatingMode operatingMode);

bool IsValidUserIndex(uint16_t userIndex);
bool IsValidCredentialIndex(uint16_t credentialIndex, DlCredentialType type);
bool IsValidWeekdayScheduleIndex(uint8_t scheduleIndex);
bool IsValidYeardayScheduleIndex(uint8_t scheduleIndex);
bool IsValidHolidayScheduleIndex(uint8_t scheduleIndex);

bool setLockState(chip::EndpointId endpointId, DlLockState lockState, const Optional<chip::ByteSpan> & pin,
DlOperationError & err);
const char * lockStateToString(DlLockState lockState) const;
Expand All @@ -105,17 +184,18 @@ class LockManager
static void AutoLockTimerEventHandler(AppEvent * aEvent);
static void ActuatorMovementTimerEventHandler(AppEvent * aEvent);

EmberAfPluginDoorLockUserInfo mLockUsers[DOOR_LOCK_MAX_USERS];
EmberAfPluginDoorLockCredentialInfo mLockCredentials[MAX_CREDENTIALS];

uint8_t mMaxCredentialsPerUser;
uint16_t mMaxUsers;
EmberAfPluginDoorLockUserInfo mLockUsers[kMaxUsers];
EmberAfPluginDoorLockCredentialInfo mLockCredentials[kMaxCredentials];
EmberAfPluginDoorLockWeekDaySchedule mWeekdaySchedule[kMaxUsers][kMaxWeekdaySchedulesPerUser];
EmberAfPluginDoorLockYearDaySchedule mYeardaySchedule[kMaxUsers][kMaxYeardaySchedulesPerUser];
EmberAfPluginDoorLockHolidaySchedule mHolidaySchedule[kMaxHolidaySchedules];

char mUserNames[ArraySize(mLockUsers)][DOOR_LOCK_MAX_USER_NAME_SIZE];
uint8_t mCredentialData[MAX_CREDENTIALS][DOOR_LOCK_MAX_CREDENTIAL_SIZE];
chip::Platform::ScopedMemoryBuffer<DlCredential> mCredentials[MAX_CREDENTIAL_PER_USER];
uint8_t mCredentialData[kMaxCredentials][kMaxCredentialSize];
DlCredential mCredentials[kMaxUsers][kMaxCredentialsPerUser];

static LockManager sLock;
EFR32DoorLock::LockInitParams::LockParam LockParams;
};

inline LockManager & LockMgr()
Expand Down
54 changes: 47 additions & 7 deletions examples/lock-app/efr32/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ using chip::app::Clusters::DoorLock::DlOperationSource;
using namespace chip;
using namespace ::chip::DeviceLayer;
using namespace ::chip::DeviceLayer::Internal;
using namespace EFR32DoorLock::LockInitParams;

namespace {
TimerHandle_t sFunctionTimer; // FreeRTOS app sw timer.
Expand Down Expand Up @@ -236,27 +237,66 @@ CHIP_ERROR AppTask::Init()
chip::DeviceLayer::PlatformMgr().LockChipStack();
chip::app::Clusters::DoorLock::Attributes::LockState::Get(endpointId, state);

uint8_t maxCredentialsPerUser = 0;
if (!DoorLockServer::Instance().GetNumberOfCredentialsSupportedPerUser(endpointId, maxCredentialsPerUser))
uint8_t numberOfCredentialsPerUser = 0;
if (!DoorLockServer::Instance().GetNumberOfCredentialsSupportedPerUser(endpointId, numberOfCredentialsPerUser))
{
ChipLogError(Zcl,
"Unable to get number of credentials supported per user when initializing lock endpoint, defaulting to 5 "
"[endpointId=%d]",
endpointId);
maxCredentialsPerUser = 5;
numberOfCredentialsPerUser = 5;
}

uint16_t numberOfSupportedUsers = 0;
if (!DoorLockServer::Instance().GetNumberOfUserSupported(endpointId, numberOfSupportedUsers))
uint16_t numberOfUsers = 0;
if (!DoorLockServer::Instance().GetNumberOfUserSupported(endpointId, numberOfUsers))
{
ChipLogError(Zcl,
"Unable to get number of supported users when initializing lock endpoint, defaulting to 10 [endpointId=%d]",
endpointId);
numberOfSupportedUsers = 10;
numberOfUsers = 10;
}

uint8_t numberOfWeekdaySchedulesPerUser = 0;
if (!DoorLockServer::Instance().GetNumberOfWeekDaySchedulesPerUserSupported(endpointId, numberOfWeekdaySchedulesPerUser))
{
ChipLogError(
Zcl,
"Unable to get number of supported weekday schedules when initializing lock endpoint, defaulting to 10 [endpointId=%d]",
endpointId);
numberOfWeekdaySchedulesPerUser = 10;
}

uint8_t numberOfYeardaySchedulesPerUser = 0;
if (!DoorLockServer::Instance().GetNumberOfYearDaySchedulesPerUserSupported(endpointId, numberOfYeardaySchedulesPerUser))
{
ChipLogError(
Zcl,
"Unable to get number of supported yearday schedules when initializing lock endpoint, defaulting to 10 [endpointId=%d]",
endpointId);
numberOfYeardaySchedulesPerUser = 10;
}

uint8_t numberOfHolidaySchedules = 0;
if (!DoorLockServer::Instance().GetNumberOfHolidaySchedulesSupported(endpointId, numberOfHolidaySchedules))
{
ChipLogError(
Zcl,
"Unable to get number of supported holiday schedules when initializing lock endpoint, defaulting to 10 [endpointId=%d]",
endpointId);
numberOfHolidaySchedules = 10;
}

chip::DeviceLayer::PlatformMgr().UnlockChipStack();

err = LockMgr().Init(state, maxCredentialsPerUser, numberOfSupportedUsers);
err = LockMgr().Init(state,
ParamBuilder()
.SetNumberOfUsers(numberOfUsers)
.SetNumberOfCredentialsPerUser(numberOfCredentialsPerUser)
.SetNumberOfWeekdaySchedulesPerUser(numberOfWeekdaySchedulesPerUser)
.SetNumberOfYeardaySchedulesPerUser(numberOfYeardaySchedulesPerUser)
.SetNumberOfHolidaySchedules(numberOfHolidaySchedules)
.GetLockParam());

if (err != CHIP_NO_ERROR)
{
EFR32_LOG("LockMgr().Init() failed");
Expand Down
Loading