Skip to content

Commit

Permalink
[Infineon] Add Implementation for Door Lock cluster (#22397)
Browse files Browse the repository at this point in the history
Co-authored-by: Andrei Litvin <[email protected]>
  • Loading branch information
2 people authored and pull[bot] committed Nov 21, 2022
1 parent bd0044e commit 4027363
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 94 deletions.
1 change: 1 addition & 0 deletions examples/lock-app/infineon/cyw30739/include/AppEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct AppEvent
kEventType_Timer,
kEventType_Lock,
kEventType_Install,
kEventType_app,
};

uint16_t Type;
Expand Down
38 changes: 27 additions & 11 deletions examples/lock-app/infineon/cyw30739/include/LockManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,24 @@
#include <stdint.h>
#include <wiced_timer.h>

struct WeekDaysScheduleInfo
{
DlScheduleStatus status;
EmberAfPluginDoorLockWeekDaySchedule schedule;
};

struct YearDayScheduleInfo
{
DlScheduleStatus status;
EmberAfPluginDoorLockYearDaySchedule schedule;
};

struct HolidayScheduleInfo
{
DlScheduleStatus status;
EmberAfPluginDoorLockHolidaySchedule schedule;
};

namespace CYW30739DoorLock {
namespace ResourceRanges {
// Used to size arrays
Expand Down Expand Up @@ -113,13 +131,6 @@ class LockManager
kState_UnlockCompleted,
} State;

enum Actor_t
{
ACTOR_ZCL_CMD = 0,
ACTOR_APP_CMD,
ACTOR_BUTTON,
} Actor;

CHIP_ERROR Init(chip::app::DataModel::Nullable<chip::app::Clusters::DoorLock::DlLockState> state,
CYW30739DoorLock::LockInitParams::LockParam lockParam);
bool NextState();
Expand All @@ -138,6 +149,10 @@ class LockManager
const chip::CharSpan & userName, uint32_t uniqueId, DlUserStatus userStatus, DlUserType usertype,
DlCredentialRule credentialRule, const DlCredential * credentials, size_t totalCredentials);

bool SetDoorState(chip::EndpointId endpointId, DlDoorState newState);

DlDoorState GetDoorState() const;

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

Expand Down Expand Up @@ -169,6 +184,7 @@ class LockManager

bool setLockState(chip::EndpointId endpointId, DlLockState lockState, const Optional<chip::ByteSpan> & pin,
DlOperationError & err);

const char * lockStateToString(DlLockState lockState) const;

bool ReadConfigValues();
Expand All @@ -177,6 +193,7 @@ class LockManager
friend LockManager & LockMgr();
chip::EndpointId mEndpointId;
State_t mState;
DlDoorState mDoorState;

Callback_fn_initiated mActionInitiated_CB;
Callback_fn_completed mActionCompleted_CB;
Expand All @@ -189,10 +206,9 @@ class LockManager

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

WeekDaysScheduleInfo mWeekdaySchedule[kMaxUsers][kMaxWeekdaySchedulesPerUser];
YearDayScheduleInfo mYeardaySchedule[kMaxUsers][kMaxYeardaySchedulesPerUser];
HolidayScheduleInfo mHolidaySchedule[kMaxHolidaySchedules];
char mUserNames[ArraySize(mLockUsers)][DOOR_LOCK_MAX_USER_NAME_SIZE];
uint8_t mCredentialData[kMaxCredentials][kMaxCredentialSize];
DlCredential mCredentials[kMaxUsers][kMaxCredentialsPerUser];
Expand Down
20 changes: 16 additions & 4 deletions examples/lock-app/infineon/cyw30739/src/AppShellCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ static CHIP_ERROR AppCommandDispatch(int argc, char * argv[]);

static chip::Shell::Engine sAppSubcommands;

chip::EndpointId endpointId = DOOR_LOCK_SERVER_ENDPOINT;

void RegisterAppShellCommands(void)
{
static const shell_command_t sAppSubCommands[] = {
Expand Down Expand Up @@ -70,20 +72,30 @@ CHIP_ERROR AppCommandLockHandler(int argc, char * argv[])
else if (strcmp(argv[0], "on") == 0)
{
streamer_printf(streamer_get(), "Lock ...\n");
LockMgr().InitiateAction(LockManager::ACTOR_APP_CMD, LockManager::LOCK_ACTION);
LockMgr().InitiateAction(AppEvent::kEventType_app, LockManager::LOCK_ACTION);
}
else if (strcmp(argv[0], "off") == 0)
{
streamer_printf(streamer_get(), "Unlock ...\n");
LockMgr().InitiateAction(LockManager::ACTOR_BUTTON, LockManager::UNLOCK_ACTION);
LockMgr().InitiateAction(AppEvent::kEventType_app, LockManager::UNLOCK_ACTION);
}
else if (strcmp(argv[0], "toggle") == 0)
{
streamer_printf(streamer_get(), "Toggling the lock ...\n");
if (LockMgr().NextState())
LockMgr().InitiateAction(LockManager::ACTOR_APP_CMD, LockManager::LOCK_ACTION);
LockMgr().InitiateAction(AppEvent::kEventType_app, LockManager::LOCK_ACTION);
else
LockMgr().InitiateAction(LockManager::ACTOR_BUTTON, LockManager::UNLOCK_ACTION);
LockMgr().InitiateAction(AppEvent::kEventType_app, LockManager::UNLOCK_ACTION);
}
else if (strcmp(argv[0], "open") == 0)
{
streamer_printf(streamer_get(), "open ...\n");
LockMgr().SetDoorState(endpointId, DlDoorState::kDoorOpen);
}
else if (strcmp(argv[0], "close") == 0)
{
streamer_printf(streamer_get(), "close ...\n");
LockMgr().SetDoorState(endpointId, DlDoorState::kDoorClosed);
}
else
{
Expand Down
3 changes: 1 addition & 2 deletions examples/lock-app/infineon/cyw30739/src/ButtonHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,9 @@ void app_button_event_handler(const button_manager_button_t * button_mgr, button
{
err = CHIP_ERROR_UNEXPECTED_EVENT;
}

if (err == CHIP_NO_ERROR)
{
initiated = LockMgr().InitiateAction(LockManager::ACTOR_BUTTON, action);
initiated = LockMgr().InitiateAction(AppEvent::kEventType_Button, action);

if (!initiated)
{
Expand Down
95 changes: 54 additions & 41 deletions examples/lock-app/infineon/cyw30739/src/LockManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ using namespace CYW30739DoorLock::LockInitParams;
CHIP_ERROR LockManager::Init(chip::app::DataModel::Nullable<chip::app::Clusters::DoorLock::DlLockState> state, LockParam lockParam)
{
LockParams = lockParam;

if (LockParams.numberOfUsers > kMaxUsers)
{
ChipLogError(Zcl,
Expand Down Expand Up @@ -448,7 +447,6 @@ bool LockManager::SetCredential(chip::EndpointId endpointId, uint16_t credential
chip::FabricIndex modifier, DlCredentialStatus credentialStatus, DlCredentialType credentialType,
const chip::ByteSpan & credentialData)
{

VerifyOrReturnValue(credentialIndex > 0, false); // indices are one-indexed

credentialIndex--;
Expand Down Expand Up @@ -495,7 +493,13 @@ DlStatus LockManager::GetWeekdaySchedule(chip::EndpointId endpointId, uint8_t we
VerifyOrReturnValue(IsValidWeekdayScheduleIndex(weekdayIndex), DlStatus::kFailure);
VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure);

schedule = mWeekdaySchedule[userIndex][weekdayIndex];
const auto & scheduleInStorage = mWeekdaySchedule[userIndex][weekdayIndex];
if (DlScheduleStatus::kAvailable == scheduleInStorage.status)
{
return DlStatus::kNotFound;
}

schedule = scheduleInStorage.schedule;

return DlStatus::kSuccess;
}
Expand All @@ -516,11 +520,12 @@ DlStatus LockManager::SetWeekdaySchedule(chip::EndpointId endpointId, uint8_t we

auto & scheduleInStorage = mWeekdaySchedule[userIndex][weekdayIndex];

scheduleInStorage.daysMask = daysMask;
scheduleInStorage.startHour = startHour;
scheduleInStorage.startMinute = startMinute;
scheduleInStorage.endHour = endHour;
scheduleInStorage.endMinute = endMinute;
scheduleInStorage.schedule.daysMask = daysMask;
scheduleInStorage.schedule.startHour = startHour;
scheduleInStorage.schedule.startMinute = startMinute;
scheduleInStorage.schedule.endHour = endHour;
scheduleInStorage.schedule.endMinute = endMinute;
scheduleInStorage.status = status;

// Save schedule information in NVM flash
CYW30739Config::WriteConfigValueBin(
Expand All @@ -542,9 +547,13 @@ DlStatus LockManager::GetYeardaySchedule(chip::EndpointId endpointId, uint8_t ye
VerifyOrReturnValue(IsValidYeardayScheduleIndex(yearDayIndex), DlStatus::kFailure);
VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure);

auto & scheduleInStorage = mYeardaySchedule[userIndex][yearDayIndex];
const auto & scheduleInStorage = mYeardaySchedule[userIndex][yearDayIndex];
if (DlScheduleStatus::kAvailable == scheduleInStorage.status)
{
return DlStatus::kNotFound;
}

schedule = scheduleInStorage;
schedule = scheduleInStorage.schedule;

return DlStatus::kSuccess;
}
Expand All @@ -563,8 +572,9 @@ DlStatus LockManager::SetYeardaySchedule(chip::EndpointId endpointId, uint8_t ye

auto & scheduleInStorage = mYeardaySchedule[userIndex][yearDayIndex];

scheduleInStorage.localStartTime = localStartTime;
scheduleInStorage.localEndTime = localEndTime;
scheduleInStorage.schedule.localStartTime = localStartTime;
scheduleInStorage.schedule.localEndTime = localEndTime;
scheduleInStorage.status = status;

// Save schedule information in NVM flash
CYW30739Config::WriteConfigValueBin(
Expand All @@ -583,9 +593,13 @@ DlStatus LockManager::GetHolidaySchedule(chip::EndpointId endpointId, uint8_t ho

VerifyOrReturnValue(IsValidHolidayScheduleIndex(holidayIndex), DlStatus::kFailure);

auto & scheduleInStorage = mHolidaySchedule[holidayIndex];
const auto & scheduleInStorage = mHolidaySchedule[holidayIndex];
if (DlScheduleStatus::kAvailable == scheduleInStorage.status)
{
return DlStatus::kNotFound;
}

schedule = scheduleInStorage;
schedule = scheduleInStorage.schedule;

return DlStatus::kSuccess;
}
Expand All @@ -601,9 +615,10 @@ DlStatus LockManager::SetHolidaySchedule(chip::EndpointId endpointId, uint8_t ho

auto & scheduleInStorage = mHolidaySchedule[holidayIndex];

scheduleInStorage.localStartTime = localStartTime;
scheduleInStorage.localEndTime = localEndTime;
scheduleInStorage.operatingMode = operatingMode;
scheduleInStorage.schedule.localStartTime = localStartTime;
scheduleInStorage.schedule.localEndTime = localEndTime;
scheduleInStorage.schedule.operatingMode = operatingMode;
scheduleInStorage.status = status;

// Save schedule information in NVM flash
CYW30739Config::WriteConfigValueBin(CYW30739Config::kConfigKey_HolidaySchedules,
Expand Down Expand Up @@ -633,43 +648,28 @@ const char * LockManager::lockStateToString(DlLockState lockState) const
bool LockManager::setLockState(chip::EndpointId endpointId, DlLockState lockState, const Optional<chip::ByteSpan> & pin,
DlOperationError & err)
{
DlLockState curState = DlLockState::kLocked;
if (mState == kState_UnlockCompleted)
curState = DlLockState::kUnlocked;

if ((curState == lockState) && (curState == DlLockState::kLocked))
{
ChipLogDetail(Zcl, "Door Lock App: door is already locked, ignoring command to set lock state to \"%s\" [endpointId=%d]",
lockStateToString(lockState), endpointId);
return true;
}
else if ((curState == lockState) && (curState == DlLockState::kUnlocked))
{
ChipLogDetail(Zcl,
"Door Lock App: door is already unlocked, ignoring command to set unlock state to \"%s\" [endpointId=%d]",
lockStateToString(lockState), endpointId);
return true;
}

// Assume pin is required until told otherwise
bool requirePin = true;
chip::app::Clusters::DoorLock::Attributes::RequirePINforRemoteOperation::Get(endpointId, &requirePin);

// If a pin code is not given
if (!pin.HasValue())
{
ChipLogDetail(Zcl, "Door Lock App: PIN code is not specified, but it is required [endpointId=%d]", mEndpointId);
curState = lockState;
ChipLogDetail(Zcl, "Door Lock App: PIN code is not specified [endpointId=%d]", endpointId);

// If a pin code is not required
if (!requirePin)
{
ChipLogDetail(Zcl, "Door Lock App: setting door lock state to \"%s\" [endpointId=%d]", lockStateToString(lockState),
endpointId);
curState = lockState;

DoorLockServer::Instance().SetLockState(endpointId, lockState);

return true;
}

ChipLogError(Zcl, "Door Lock App: PIN code is not specified, but it is required [endpointId=%d]", endpointId);

return false;
}

Expand All @@ -686,9 +686,9 @@ bool LockManager::setLockState(chip::EndpointId endpointId, DlLockState lockStat
{
ChipLogDetail(Zcl,
"Lock App: specified PIN code was found in the database, setting lock state to \"%s\" [endpointId=%d]",
lockStateToString(lockState), mEndpointId);
lockStateToString(lockState), endpointId);

curState = lockState;
DoorLockServer::Instance().SetLockState(endpointId, lockState);

return true;
}
Expand All @@ -697,8 +697,21 @@ bool LockManager::setLockState(chip::EndpointId endpointId, DlLockState lockStat
ChipLogDetail(Zcl,
"Door Lock App: specified PIN code was not found in the database, ignoring command to set lock state to \"%s\" "
"[endpointId=%d]",
lockStateToString(lockState), mEndpointId);
lockStateToString(lockState), endpointId);

err = DlOperationError::kInvalidCredential;
return false;
}

bool LockManager::SetDoorState(chip::EndpointId endpointId, DlDoorState newState)
{
if (mDoorState != newState)
{
ChipLogProgress(Zcl, "Changing the door state to: %d [endpointId=%d,previousState=%d]", to_underlying(newState), endpointId,
to_underlying(mDoorState));

mDoorState = newState;
return DoorLockServer::Instance().SetDoorState(endpointId, mDoorState);
}
return true;
}
Loading

0 comments on commit 4027363

Please sign in to comment.