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

[Infineon] Add Implementation for Door Lock cluster #22397

Merged
merged 2 commits into from
Sep 13, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
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