Skip to content

Commit

Permalink
Refer to the latest lock-app codes
Browse files Browse the repository at this point in the history
  • Loading branch information
erwinpan1 committed Mar 7, 2024
1 parent d39a7e5 commit 69cb8cb
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 100 deletions.
112 changes: 40 additions & 72 deletions examples/chef/common/clusters/door-lock/chef-doorlock-stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,66 +50,18 @@ bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const
return LockManager::Instance().Unlock(endpointId, fabricIdx, nodeId, pinCode, err, OperationSourceEnum::kRemote);
}

//UnlockWithTimeout

// =============================================================================
// Users and credentials access callbacks
// =============================================================================

// SetWeekDaySchedule
DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex,
DlScheduleStatus status, DaysMaskMap daysMask, uint8_t startHour, uint8_t startMinute,
uint8_t endHour, uint8_t endMinute)
{
return LockManager::Instance().SetSchedule(endpointId, weekdayIndex, userIndex, status, daysMask, startHour, startMinute,
endHour, endMinute);
}

// GetWeekDaySchedule
DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex,
EmberAfPluginDoorLockWeekDaySchedule & schedule)
{
return LockManager::Instance().GetSchedule(endpointId, weekdayIndex, userIndex, schedule);
}

// emberAfDoorLockClusterClearWeekDayScheduleCallback was handled in src/app/clusters/door-lock-server/door-lock-server.cpp
// And finally call into emberAfPluginDoorLockSetSchedule

// SetYearDaySchedule
DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex,
DlScheduleStatus status, uint32_t localStartTime, uint32_t localEndTime)
{
return LockManager::Instance().SetSchedule(endpointId, yearDayIndex, userIndex, status, localStartTime, localEndTime);
}

// GetYearDaySchedule
DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex,
EmberAfPluginDoorLockYearDaySchedule & schedule)
{
return LockManager::Instance().GetSchedule(endpointId, yearDayIndex, userIndex, schedule);
}

// emberAfDoorLockClusterClearYearDayScheduleCallback was handled in src/app/clusters/door-lock-server/door-lock-server.cpp
// And finally call into emberAfPluginDoorLockSetSchedule

// SetHolidaySchedule
DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t holidayIndex, DlScheduleStatus status,
uint32_t localStartTime, uint32_t localEndTime, OperatingModeEnum operatingMode)
bool emberAfPluginDoorLockOnDoorUnboltCommand(chip::EndpointId endpointId, const Nullable<chip::FabricIndex> & fabricIdx,
const Nullable<chip::NodeId> & nodeId, const Optional<ByteSpan> & pinCode,
OperationErrorEnum & err)
{
return LockManager::Instance().SetSchedule(endpointId, holidayIndex, status, localStartTime, localEndTime, operatingMode);
return LockManager::Instance().Unbolt(endpointId, fabricIdx, nodeId, pinCode, err, OperationSourceEnum::kRemote);
}

// GetHolidaySchedule
DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t holidayIndex,
EmberAfPluginDoorLockHolidaySchedule & schedule)
bool emberAfPluginDoorLockGetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user)
{
return LockManager::Instance().GetSchedule(endpointId, holidayIndex, schedule);
return LockManager::Instance().GetUser(endpointId, userIndex, user);
}

// emberAfDoorLockClusterClearHolidayScheduleCallback was handled in src/app/clusters/door-lock-server/door-lock-server.cpp
// And finally call into emberAfPluginDoorLockSetSchedule

// SetUser
bool emberAfPluginDoorLockSetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator,
chip::FabricIndex modifier, const chip::CharSpan & userName, uint32_t uniqueId,
UserStatusEnum userStatus, UserTypeEnum usertype, CredentialRuleEnum credentialRule,
Expand All @@ -120,16 +72,12 @@ bool emberAfPluginDoorLockSetUser(chip::EndpointId endpointId, uint16_t userInde
credentialRule, credentials, totalCredentials);
}

// GetUser
bool emberAfPluginDoorLockGetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user)
bool emberAfPluginDoorLockGetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, CredentialTypeEnum credentialType,
EmberAfPluginDoorLockCredentialInfo & credential)
{
return LockManager::Instance().GetUser(endpointId, userIndex, user);
return LockManager::Instance().GetCredential(endpointId, credentialIndex, credentialType, credential);
}

// emberAfDoorLockClusterClearUserCallback was handled in src/app/clusters/door-lock-server/door-lock-server.cpp
// And finally call into emberAfPluginDoorLockSetCredential and emberAfPluginDoorLockSetUser

// SetCredential
bool emberAfPluginDoorLockSetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator,
chip::FabricIndex modifier, DlCredentialStatus credentialStatus,
CredentialTypeEnum credentialType, const chip::ByteSpan & credentialData)
Expand All @@ -138,22 +86,42 @@ bool emberAfPluginDoorLockSetCredential(chip::EndpointId endpointId, uint16_t cr
credentialData);
}

// GetCredential
bool emberAfPluginDoorLockGetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, CredentialTypeEnum credentialType,
EmberAfPluginDoorLockCredentialInfo & credential)
DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex,
EmberAfPluginDoorLockWeekDaySchedule & schedule)
{
return LockManager::Instance().GetCredential(endpointId, credentialIndex, credentialType, credential);
return LockManager::Instance().GetSchedule(endpointId, weekdayIndex, userIndex, schedule);
}

// emberAfDoorLockClusterClearCredentialCallback was handled in src/app/clusters/door-lock-server/door-lock-server.cpp
// And finally call into emberAfPluginDoorLockSetCredential and emberAfPluginDoorLockSetUser
DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t holidayIndex,
EmberAfPluginDoorLockHolidaySchedule & schedule)
{
return LockManager::Instance().GetSchedule(endpointId, holidayIndex, schedule);
}

// UnboltDoor
bool emberAfPluginDoorLockOnDoorUnboltCommand(chip::EndpointId endpointId, const Nullable<chip::FabricIndex> & fabricIdx,
const Nullable<chip::NodeId> & nodeId, const Optional<ByteSpan> & pinCode,
OperationErrorEnum & err)
DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex,
DlScheduleStatus status, DaysMaskMap daysMask, uint8_t startHour, uint8_t startMinute,
uint8_t endHour, uint8_t endMinute)
{
return LockManager::Instance().Unbolt(endpointId, fabricIdx, nodeId, pinCode, err, OperationSourceEnum::kRemote);
return LockManager::Instance().SetSchedule(endpointId, weekdayIndex, userIndex, status, daysMask, startHour, startMinute,
endHour, endMinute);
}

DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex,
DlScheduleStatus status, uint32_t localStartTime, uint32_t localEndTime)
{
return LockManager::Instance().SetSchedule(endpointId, yearDayIndex, userIndex, status, localStartTime, localEndTime);
}

DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex,
EmberAfPluginDoorLockYearDaySchedule & schedule)
{
return LockManager::Instance().GetSchedule(endpointId, yearDayIndex, userIndex, schedule);
}

DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t holidayIndex, DlScheduleStatus status,
uint32_t localStartTime, uint32_t localEndTime, OperatingModeEnum operatingMode)
{
return LockManager::Instance().SetSchedule(endpointId, holidayIndex, status, localStartTime, localEndTime, operatingMode);
}

void emberAfDoorLockClusterInitCallback(EndpointId endpoint)
Expand Down
75 changes: 49 additions & 26 deletions examples/chef/common/clusters/door-lock/chef-lock-endpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,19 +509,20 @@ printf("\n \033[41m %s, %d \033[0m \n", __func__, __LINE__);
auto userIndex = static_cast<uint8_t>(user - mLockUsers.begin());

// Check if schedules affect the user
bool ret = weekDayScheduleInAction(userIndex);
printf("\033[44m %s, %d, ret=%d \033[0m \n", __func__, __LINE__, static_cast<int>(ret));
if ( ((user->userType == UserTypeEnum::kScheduleRestrictedUser || user->userType == UserTypeEnum::kWeekDayScheduleUser) &&
!weekDayScheduleInAction(userIndex)) ||
((user->userType == UserTypeEnum::kScheduleRestrictedUser || user->userType == UserTypeEnum::kYearDayScheduleUser) &&
!yearDayScheduleInAction(userIndex)) )
{
ChipLogDetail(Zcl,
"Lock App: associated user is not allowed to operate the lock due to schedules"
"[endpointId=%d,userIndex=%u]",
mEndpointId, userIndex);
err = OperationErrorEnum::kRestricted;
return false;
bool haveWeekDaySchedules = false;
bool haveYearDaySchedules = false;
if (weekDayScheduleForbidsAccess(userIndex, &haveWeekDaySchedules) ||
yearDayScheduleForbidsAccess(userIndex, &haveYearDaySchedules) ||
// Also disallow access for a user that's supposed to have _some_
// schedule but doesn't have any
(user->userType == UserTypeEnum::kScheduleRestrictedUser && !haveWeekDaySchedules && !haveYearDaySchedules))
{
ChipLogDetail(Zcl,
"Lock App: associated user is not allowed to operate the lock due to schedules"
"[endpointId=%d,userIndex=%u]",
mEndpointId, userIndex);
err = OperationErrorEnum::kRestricted;
return false;
}
ChipLogProgress(
Zcl,
Expand Down Expand Up @@ -582,12 +583,23 @@ void LockEndpoint::OnLockActionCompleteCallback(chip::System::Layer *, void * ca
}
}

bool LockEndpoint::weekDayScheduleInAction(uint16_t userIndex) const
bool LockEndpoint::weekDayScheduleForbidsAccess(uint16_t userIndex, bool * haveSchedule) const
{
*haveSchedule = std::any_of(mWeekDaySchedules[userIndex].begin(), mWeekDaySchedules[userIndex].end(),
[](const WeekDaysScheduleInfo & s) { return s.status == DlScheduleStatus::kOccupied; });

const auto & user = mLockUsers[userIndex];
if (user.userType != UserTypeEnum::kScheduleRestrictedUser && user.userType != UserTypeEnum::kWeekDayScheduleUser)
{
return true;
// Weekday schedules don't apply to this user.
return false;
}

if (user.userType == UserTypeEnum::kScheduleRestrictedUser && !*haveSchedule)
{
// It's valid to not have any schedules of a given type; on its own this
// does not prevent access.
return false;
}

chip::System::Clock::Milliseconds64 cTMs;
Expand All @@ -596,7 +608,7 @@ bool LockEndpoint::weekDayScheduleInAction(uint16_t userIndex) const
{
ChipLogError(Zcl, "Lock App: unable to get current time to check user schedules [endpointId=%d,error=%d (%s)]", mEndpointId,
chipError.AsInteger(), chipError.AsString());
return false;
return true;
}
time_t unixEpoch = std::chrono::duration_cast<chip::System::Clock::Seconds32>(cTMs).count();

Expand All @@ -606,8 +618,9 @@ bool LockEndpoint::weekDayScheduleInAction(uint16_t userIndex) const
auto currentTime =
calendarTime.tm_hour * chip::kSecondsPerHour + calendarTime.tm_min * chip::kSecondsPerMinute + calendarTime.tm_sec;

// Second, check the week day schedules.
return std::any_of(
// Now check whether any schedule allows the current time. If it does,
// access is not forbidden.
return !std::any_of(
mWeekDaySchedules[userIndex].begin(), mWeekDaySchedules[userIndex].end(),
[currentTime, calendarTime](const WeekDaysScheduleInfo & s) {
auto startTime = s.schedule.startHour * chip::kSecondsPerHour + s.schedule.startMinute * chip::kSecondsPerMinute;
Expand All @@ -620,12 +633,22 @@ bool LockEndpoint::weekDayScheduleInAction(uint16_t userIndex) const
});
}

bool LockEndpoint::yearDayScheduleInAction(uint16_t userIndex) const
bool LockEndpoint::yearDayScheduleForbidsAccess(uint16_t userIndex, bool * haveSchedule) const
{
*haveSchedule = std::any_of(mYearDaySchedules[userIndex].begin(), mYearDaySchedules[userIndex].end(),
[](const YearDayScheduleInfo & sch) { return sch.status == DlScheduleStatus::kOccupied; });

const auto & user = mLockUsers[userIndex];
if (user.userType != UserTypeEnum::kScheduleRestrictedUser && user.userType != UserTypeEnum::kYearDayScheduleUser)
{
return true;
return false;
}

if (user.userType == UserTypeEnum::kScheduleRestrictedUser && !*haveSchedule)
{
// It's valid to not have any schedules of a given type; on its own this
// does not prevent access.
return false;
}

chip::System::Clock::Milliseconds64 cTMs;
Expand All @@ -634,7 +657,7 @@ bool LockEndpoint::yearDayScheduleInAction(uint16_t userIndex) const
{
ChipLogError(Zcl, "Lock App: unable to get current time to check user schedules [endpointId=%d,error=%d (%s)]", mEndpointId,
chipError.AsInteger(), chipError.AsString());
return false;
return true;
}
auto unixEpoch = std::chrono::duration_cast<chip::System::Clock::Seconds32>(cTMs).count();
uint32_t chipEpoch = 0;
Expand All @@ -647,11 +670,11 @@ bool LockEndpoint::yearDayScheduleInAction(uint16_t userIndex) const
return false;
}

return std::any_of(mYearDaySchedules[userIndex].begin(), mYearDaySchedules[userIndex].end(),
[chipEpoch](const YearDayScheduleInfo & sch) {
return sch.status == DlScheduleStatus::kOccupied && sch.schedule.localStartTime <= chipEpoch &&
chipEpoch <= sch.schedule.localEndTime;
});
return !std::any_of(mYearDaySchedules[userIndex].begin(), mYearDaySchedules[userIndex].end(),
[chipEpoch](const YearDayScheduleInfo & sch) {
return sch.status == DlScheduleStatus::kOccupied && sch.schedule.localStartTime <= chipEpoch &&
chipEpoch <= sch.schedule.localEndTime;
});
}

const char * LockEndpoint::lockStateToString(DlLockState lockState) const
Expand Down
12 changes: 10 additions & 2 deletions examples/chef/common/clusters/door-lock/chef-lock-endpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,16 @@ class LockEndpoint
OperationSourceEnum opSource = OperationSourceEnum::kUnspecified);
const char * lockStateToString(DlLockState lockState) const;

bool weekDayScheduleInAction(uint16_t userIndex) const;
bool yearDayScheduleInAction(uint16_t userIndex) const;
// Returns true if week day schedules should apply to the user, there are
// schedules defined for the user, and access is not currently allowed by
// those schedules. The outparam indicates whether there were in fact any
// year day schedules defined for the user.
bool weekDayScheduleForbidsAccess(uint16_t userIndex, bool * haveSchedule) const;
// Returns true if year day schedules should apply to the user, there are
// schedules defined for the user, and access is not currently allowed by
// those schedules. The outparam indicates whether there were in fact any
// year day schedules defined for the user.
bool yearDayScheduleForbidsAccess(uint16_t userIndex, bool * haveSchedule) const;

static void OnLockActionCompleteCallback(chip::System::Layer *, void * callbackContext);

Expand Down

0 comments on commit 69cb8cb

Please sign in to comment.