Skip to content

Commit 3851275

Browse files
AlvinHsiaoandy31415
authored andcommitted
[Infineon] Add Implementation for Door Lock cluster (#22397)
Co-authored-by: Andrei Litvin <andy314@gmail.com>
1 parent f5025b3 commit 3851275

File tree

7 files changed

+124
-94
lines changed

7 files changed

+124
-94
lines changed

examples/lock-app/infineon/cyw30739/include/AppEvent.h

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ struct AppEvent
2929
kEventType_Timer,
3030
kEventType_Lock,
3131
kEventType_Install,
32+
kEventType_app,
3233
};
3334

3435
uint16_t Type;

examples/lock-app/infineon/cyw30739/include/LockManager.h

+27-11
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,24 @@
2626
#include <stdint.h>
2727
#include <wiced_timer.h>
2828

29+
struct WeekDaysScheduleInfo
30+
{
31+
DlScheduleStatus status;
32+
EmberAfPluginDoorLockWeekDaySchedule schedule;
33+
};
34+
35+
struct YearDayScheduleInfo
36+
{
37+
DlScheduleStatus status;
38+
EmberAfPluginDoorLockYearDaySchedule schedule;
39+
};
40+
41+
struct HolidayScheduleInfo
42+
{
43+
DlScheduleStatus status;
44+
EmberAfPluginDoorLockHolidaySchedule schedule;
45+
};
46+
2947
namespace CYW30739DoorLock {
3048
namespace ResourceRanges {
3149
// Used to size arrays
@@ -113,13 +131,6 @@ class LockManager
113131
kState_UnlockCompleted,
114132
} State;
115133

116-
enum Actor_t
117-
{
118-
ACTOR_ZCL_CMD = 0,
119-
ACTOR_APP_CMD,
120-
ACTOR_BUTTON,
121-
} Actor;
122-
123134
CHIP_ERROR Init(chip::app::DataModel::Nullable<chip::app::Clusters::DoorLock::DlLockState> state,
124135
CYW30739DoorLock::LockInitParams::LockParam lockParam);
125136
bool NextState();
@@ -138,6 +149,10 @@ class LockManager
138149
const chip::CharSpan & userName, uint32_t uniqueId, DlUserStatus userStatus, DlUserType usertype,
139150
DlCredentialRule credentialRule, const DlCredential * credentials, size_t totalCredentials);
140151

152+
bool SetDoorState(chip::EndpointId endpointId, DlDoorState newState);
153+
154+
DlDoorState GetDoorState() const;
155+
141156
bool GetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, DlCredentialType credentialType,
142157
EmberAfPluginDoorLockCredentialInfo & credential);
143158

@@ -169,6 +184,7 @@ class LockManager
169184

170185
bool setLockState(chip::EndpointId endpointId, DlLockState lockState, const Optional<chip::ByteSpan> & pin,
171186
DlOperationError & err);
187+
172188
const char * lockStateToString(DlLockState lockState) const;
173189

174190
bool ReadConfigValues();
@@ -177,6 +193,7 @@ class LockManager
177193
friend LockManager & LockMgr();
178194
chip::EndpointId mEndpointId;
179195
State_t mState;
196+
DlDoorState mDoorState;
180197

181198
Callback_fn_initiated mActionInitiated_CB;
182199
Callback_fn_completed mActionCompleted_CB;
@@ -189,10 +206,9 @@ class LockManager
189206

190207
EmberAfPluginDoorLockUserInfo mLockUsers[kMaxUsers];
191208
EmberAfPluginDoorLockCredentialInfo mLockCredentials[kMaxCredentials];
192-
EmberAfPluginDoorLockWeekDaySchedule mWeekdaySchedule[kMaxUsers][kMaxWeekdaySchedulesPerUser];
193-
EmberAfPluginDoorLockYearDaySchedule mYeardaySchedule[kMaxUsers][kMaxYeardaySchedulesPerUser];
194-
EmberAfPluginDoorLockHolidaySchedule mHolidaySchedule[kMaxHolidaySchedules];
195-
209+
WeekDaysScheduleInfo mWeekdaySchedule[kMaxUsers][kMaxWeekdaySchedulesPerUser];
210+
YearDayScheduleInfo mYeardaySchedule[kMaxUsers][kMaxYeardaySchedulesPerUser];
211+
HolidayScheduleInfo mHolidaySchedule[kMaxHolidaySchedules];
196212
char mUserNames[ArraySize(mLockUsers)][DOOR_LOCK_MAX_USER_NAME_SIZE];
197213
uint8_t mCredentialData[kMaxCredentials][kMaxCredentialSize];
198214
DlCredential mCredentials[kMaxUsers][kMaxCredentialsPerUser];

examples/lock-app/infineon/cyw30739/src/AppShellCommands.cpp

+16-4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ static CHIP_ERROR AppCommandDispatch(int argc, char * argv[]);
2929

3030
static chip::Shell::Engine sAppSubcommands;
3131

32+
chip::EndpointId endpointId = DOOR_LOCK_SERVER_ENDPOINT;
33+
3234
void RegisterAppShellCommands(void)
3335
{
3436
static const shell_command_t sAppSubCommands[] = {
@@ -70,20 +72,30 @@ CHIP_ERROR AppCommandLockHandler(int argc, char * argv[])
7072
else if (strcmp(argv[0], "on") == 0)
7173
{
7274
streamer_printf(streamer_get(), "Lock ...\n");
73-
LockMgr().InitiateAction(LockManager::ACTOR_APP_CMD, LockManager::LOCK_ACTION);
75+
LockMgr().InitiateAction(AppEvent::kEventType_app, LockManager::LOCK_ACTION);
7476
}
7577
else if (strcmp(argv[0], "off") == 0)
7678
{
7779
streamer_printf(streamer_get(), "Unlock ...\n");
78-
LockMgr().InitiateAction(LockManager::ACTOR_BUTTON, LockManager::UNLOCK_ACTION);
80+
LockMgr().InitiateAction(AppEvent::kEventType_app, LockManager::UNLOCK_ACTION);
7981
}
8082
else if (strcmp(argv[0], "toggle") == 0)
8183
{
8284
streamer_printf(streamer_get(), "Toggling the lock ...\n");
8385
if (LockMgr().NextState())
84-
LockMgr().InitiateAction(LockManager::ACTOR_APP_CMD, LockManager::LOCK_ACTION);
86+
LockMgr().InitiateAction(AppEvent::kEventType_app, LockManager::LOCK_ACTION);
8587
else
86-
LockMgr().InitiateAction(LockManager::ACTOR_BUTTON, LockManager::UNLOCK_ACTION);
88+
LockMgr().InitiateAction(AppEvent::kEventType_app, LockManager::UNLOCK_ACTION);
89+
}
90+
else if (strcmp(argv[0], "open") == 0)
91+
{
92+
streamer_printf(streamer_get(), "open ...\n");
93+
LockMgr().SetDoorState(endpointId, DlDoorState::kDoorOpen);
94+
}
95+
else if (strcmp(argv[0], "close") == 0)
96+
{
97+
streamer_printf(streamer_get(), "close ...\n");
98+
LockMgr().SetDoorState(endpointId, DlDoorState::kDoorClosed);
8799
}
88100
else
89101
{

examples/lock-app/infineon/cyw30739/src/ButtonHandler.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,9 @@ void app_button_event_handler(const button_manager_button_t * button_mgr, button
9393
{
9494
err = CHIP_ERROR_UNEXPECTED_EVENT;
9595
}
96-
9796
if (err == CHIP_NO_ERROR)
9897
{
99-
initiated = LockMgr().InitiateAction(LockManager::ACTOR_BUTTON, action);
98+
initiated = LockMgr().InitiateAction(AppEvent::kEventType_Button, action);
10099

101100
if (!initiated)
102101
{

examples/lock-app/infineon/cyw30739/src/LockManager.cpp

+54-41
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ using namespace CYW30739DoorLock::LockInitParams;
3333
CHIP_ERROR LockManager::Init(chip::app::DataModel::Nullable<chip::app::Clusters::DoorLock::DlLockState> state, LockParam lockParam)
3434
{
3535
LockParams = lockParam;
36-
3736
if (LockParams.numberOfUsers > kMaxUsers)
3837
{
3938
ChipLogError(Zcl,
@@ -448,7 +447,6 @@ bool LockManager::SetCredential(chip::EndpointId endpointId, uint16_t credential
448447
chip::FabricIndex modifier, DlCredentialStatus credentialStatus, DlCredentialType credentialType,
449448
const chip::ByteSpan & credentialData)
450449
{
451-
452450
VerifyOrReturnValue(credentialIndex > 0, false); // indices are one-indexed
453451

454452
credentialIndex--;
@@ -495,7 +493,13 @@ DlStatus LockManager::GetWeekdaySchedule(chip::EndpointId endpointId, uint8_t we
495493
VerifyOrReturnValue(IsValidWeekdayScheduleIndex(weekdayIndex), DlStatus::kFailure);
496494
VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure);
497495

498-
schedule = mWeekdaySchedule[userIndex][weekdayIndex];
496+
const auto & scheduleInStorage = mWeekdaySchedule[userIndex][weekdayIndex];
497+
if (DlScheduleStatus::kAvailable == scheduleInStorage.status)
498+
{
499+
return DlStatus::kNotFound;
500+
}
501+
502+
schedule = scheduleInStorage.schedule;
499503

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

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

519-
scheduleInStorage.daysMask = daysMask;
520-
scheduleInStorage.startHour = startHour;
521-
scheduleInStorage.startMinute = startMinute;
522-
scheduleInStorage.endHour = endHour;
523-
scheduleInStorage.endMinute = endMinute;
523+
scheduleInStorage.schedule.daysMask = daysMask;
524+
scheduleInStorage.schedule.startHour = startHour;
525+
scheduleInStorage.schedule.startMinute = startMinute;
526+
scheduleInStorage.schedule.endHour = endHour;
527+
scheduleInStorage.schedule.endMinute = endMinute;
528+
scheduleInStorage.status = status;
524529

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

545-
auto & scheduleInStorage = mYeardaySchedule[userIndex][yearDayIndex];
550+
const auto & scheduleInStorage = mYeardaySchedule[userIndex][yearDayIndex];
551+
if (DlScheduleStatus::kAvailable == scheduleInStorage.status)
552+
{
553+
return DlStatus::kNotFound;
554+
}
546555

547-
schedule = scheduleInStorage;
556+
schedule = scheduleInStorage.schedule;
548557

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

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

566-
scheduleInStorage.localStartTime = localStartTime;
567-
scheduleInStorage.localEndTime = localEndTime;
575+
scheduleInStorage.schedule.localStartTime = localStartTime;
576+
scheduleInStorage.schedule.localEndTime = localEndTime;
577+
scheduleInStorage.status = status;
568578

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

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

586-
auto & scheduleInStorage = mHolidaySchedule[holidayIndex];
596+
const auto & scheduleInStorage = mHolidaySchedule[holidayIndex];
597+
if (DlScheduleStatus::kAvailable == scheduleInStorage.status)
598+
{
599+
return DlStatus::kNotFound;
600+
}
587601

588-
schedule = scheduleInStorage;
602+
schedule = scheduleInStorage.schedule;
589603

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

602616
auto & scheduleInStorage = mHolidaySchedule[holidayIndex];
603617

604-
scheduleInStorage.localStartTime = localStartTime;
605-
scheduleInStorage.localEndTime = localEndTime;
606-
scheduleInStorage.operatingMode = operatingMode;
618+
scheduleInStorage.schedule.localStartTime = localStartTime;
619+
scheduleInStorage.schedule.localEndTime = localEndTime;
620+
scheduleInStorage.schedule.operatingMode = operatingMode;
621+
scheduleInStorage.status = status;
607622

608623
// Save schedule information in NVM flash
609624
CYW30739Config::WriteConfigValueBin(CYW30739Config::kConfigKey_HolidaySchedules,
@@ -633,43 +648,28 @@ const char * LockManager::lockStateToString(DlLockState lockState) const
633648
bool LockManager::setLockState(chip::EndpointId endpointId, DlLockState lockState, const Optional<chip::ByteSpan> & pin,
634649
DlOperationError & err)
635650
{
636-
DlLockState curState = DlLockState::kLocked;
637-
if (mState == kState_UnlockCompleted)
638-
curState = DlLockState::kUnlocked;
639-
640-
if ((curState == lockState) && (curState == DlLockState::kLocked))
641-
{
642-
ChipLogDetail(Zcl, "Door Lock App: door is already locked, ignoring command to set lock state to \"%s\" [endpointId=%d]",
643-
lockStateToString(lockState), endpointId);
644-
return true;
645-
}
646-
else if ((curState == lockState) && (curState == DlLockState::kUnlocked))
647-
{
648-
ChipLogDetail(Zcl,
649-
"Door Lock App: door is already unlocked, ignoring command to set unlock state to \"%s\" [endpointId=%d]",
650-
lockStateToString(lockState), endpointId);
651-
return true;
652-
}
653-
654651
// Assume pin is required until told otherwise
655652
bool requirePin = true;
656653
chip::app::Clusters::DoorLock::Attributes::RequirePINforRemoteOperation::Get(endpointId, &requirePin);
657654

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

664660
// If a pin code is not required
665661
if (!requirePin)
666662
{
667663
ChipLogDetail(Zcl, "Door Lock App: setting door lock state to \"%s\" [endpointId=%d]", lockStateToString(lockState),
668664
endpointId);
669-
curState = lockState;
665+
666+
DoorLockServer::Instance().SetLockState(endpointId, lockState);
667+
670668
return true;
671669
}
672670

671+
ChipLogError(Zcl, "Door Lock App: PIN code is not specified, but it is required [endpointId=%d]", endpointId);
672+
673673
return false;
674674
}
675675

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

691-
curState = lockState;
691+
DoorLockServer::Instance().SetLockState(endpointId, lockState);
692692

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

702702
err = DlOperationError::kInvalidCredential;
703703
return false;
704704
}
705+
706+
bool LockManager::SetDoorState(chip::EndpointId endpointId, DlDoorState newState)
707+
{
708+
if (mDoorState != newState)
709+
{
710+
ChipLogProgress(Zcl, "Changing the door state to: %d [endpointId=%d,previousState=%d]", to_underlying(newState), endpointId,
711+
to_underlying(mDoorState));
712+
713+
mDoorState = newState;
714+
return DoorLockServer::Instance().SetDoorState(endpointId, mDoorState);
715+
}
716+
return true;
717+
}

0 commit comments

Comments
 (0)