@@ -488,19 +488,20 @@ bool LockEndpoint::setLockState(const Nullable<chip::FabricIndex> & fabricIdx, c
488
488
auto userIndex = static_cast <uint8_t >(user - mLockUsers .begin ());
489
489
490
490
// Check if schedules affect the user
491
- if ((user->userType == UserTypeEnum::kScheduleRestrictedUser || user->userType == UserTypeEnum::kWeekDayScheduleUser ) &&
492
- !weekDayScheduleInAction (userIndex))
491
+ bool haveWeekDaySchedules = false ;
492
+ bool haveYearDaySchedules = false ;
493
+ if (weekDayScheduleForbidsAccess (userIndex, &haveWeekDaySchedules) ||
494
+ yearDayScheduleForbidsAccess (userIndex, &haveYearDaySchedules) ||
495
+ // Also disallow access for a user that's supposed to have _some_
496
+ // schedule but doesn't have any
497
+ (user->userType == UserTypeEnum::kScheduleRestrictedUser && !haveWeekDaySchedules && !haveYearDaySchedules))
493
498
{
494
- if ((user->userType == UserTypeEnum::kScheduleRestrictedUser || user->userType == UserTypeEnum::kYearDayScheduleUser ) &&
495
- !yearDayScheduleInAction (userIndex))
496
- {
497
- ChipLogDetail (Zcl,
498
- " Lock App: associated user is not allowed to operate the lock due to schedules"
499
- " [endpointId=%d,userIndex=%u]" ,
500
- mEndpointId , userIndex);
501
- err = OperationErrorEnum::kRestricted ;
502
- return false ;
503
- }
499
+ ChipLogDetail (Zcl,
500
+ " Lock App: associated user is not allowed to operate the lock due to schedules"
501
+ " [endpointId=%d,userIndex=%u]" ,
502
+ mEndpointId , userIndex);
503
+ err = OperationErrorEnum::kRestricted ;
504
+ return false ;
504
505
}
505
506
ChipLogProgress (
506
507
Zcl,
@@ -561,12 +562,23 @@ void LockEndpoint::OnLockActionCompleteCallback(chip::System::Layer *, void * ca
561
562
}
562
563
}
563
564
564
- bool LockEndpoint::weekDayScheduleInAction (uint16_t userIndex) const
565
+ bool LockEndpoint::weekDayScheduleForbidsAccess (uint16_t userIndex, bool * haveSchedule ) const
565
566
{
567
+ *haveSchedule = std::any_of (mWeekDaySchedules [userIndex].begin (), mWeekDaySchedules [userIndex].end (),
568
+ [](const WeekDaysScheduleInfo & s) { return s.status == DlScheduleStatus::kOccupied ; });
569
+
566
570
const auto & user = mLockUsers [userIndex];
567
571
if (user.userType != UserTypeEnum::kScheduleRestrictedUser && user.userType != UserTypeEnum::kWeekDayScheduleUser )
568
572
{
569
- return true ;
573
+ // Weekday schedules don't apply to this user.
574
+ return false ;
575
+ }
576
+
577
+ if (user.userType == UserTypeEnum::kScheduleRestrictedUser && !*haveSchedule)
578
+ {
579
+ // It's valid to not have any schedules of a given type; on its own this
580
+ // does not prevent access.
581
+ return false ;
570
582
}
571
583
572
584
chip::System::Clock::Milliseconds64 cTMs;
@@ -575,7 +587,7 @@ bool LockEndpoint::weekDayScheduleInAction(uint16_t userIndex) const
575
587
{
576
588
ChipLogError (Zcl, " Lock App: unable to get current time to check user schedules [endpointId=%d,error=%d (%s)]" , mEndpointId ,
577
589
chipError.AsInteger (), chipError.AsString ());
578
- return false ;
590
+ return true ;
579
591
}
580
592
time_t unixEpoch = std::chrono::duration_cast<chip::System::Clock::Seconds32>(cTMs).count ();
581
593
@@ -585,8 +597,9 @@ bool LockEndpoint::weekDayScheduleInAction(uint16_t userIndex) const
585
597
auto currentTime =
586
598
calendarTime.tm_hour * chip::kSecondsPerHour + calendarTime.tm_min * chip::kSecondsPerMinute + calendarTime.tm_sec ;
587
599
588
- // Second, check the week day schedules.
589
- return std::any_of (
600
+ // Now check whether any schedule allows the current time. If it does,
601
+ // access is not forbidden.
602
+ return !std::any_of (
590
603
mWeekDaySchedules [userIndex].begin (), mWeekDaySchedules [userIndex].end (),
591
604
[currentTime, calendarTime](const WeekDaysScheduleInfo & s) {
592
605
auto startTime = s.schedule .startHour * chip::kSecondsPerHour + s.schedule .startMinute * chip::kSecondsPerMinute ;
@@ -596,12 +609,22 @@ bool LockEndpoint::weekDayScheduleInAction(uint16_t userIndex) const
596
609
});
597
610
}
598
611
599
- bool LockEndpoint::yearDayScheduleInAction (uint16_t userIndex) const
612
+ bool LockEndpoint::yearDayScheduleForbidsAccess (uint16_t userIndex, bool * haveSchedule ) const
600
613
{
614
+ *haveSchedule = std::any_of (mYearDaySchedules [userIndex].begin (), mYearDaySchedules [userIndex].end (),
615
+ [](const YearDayScheduleInfo & sch) { return sch.status == DlScheduleStatus::kOccupied ; });
616
+
601
617
const auto & user = mLockUsers [userIndex];
602
618
if (user.userType != UserTypeEnum::kScheduleRestrictedUser && user.userType != UserTypeEnum::kYearDayScheduleUser )
603
619
{
604
- return true ;
620
+ return false ;
621
+ }
622
+
623
+ if (user.userType == UserTypeEnum::kScheduleRestrictedUser && !*haveSchedule)
624
+ {
625
+ // It's valid to not have any schedules of a given type; on its own this
626
+ // does not prevent access.
627
+ return false ;
605
628
}
606
629
607
630
chip::System::Clock::Milliseconds64 cTMs;
@@ -610,7 +633,7 @@ bool LockEndpoint::yearDayScheduleInAction(uint16_t userIndex) const
610
633
{
611
634
ChipLogError (Zcl, " Lock App: unable to get current time to check user schedules [endpointId=%d,error=%d (%s)]" , mEndpointId ,
612
635
chipError.AsInteger (), chipError.AsString ());
613
- return false ;
636
+ return true ;
614
637
}
615
638
auto unixEpoch = std::chrono::duration_cast<chip::System::Clock::Seconds32>(cTMs).count ();
616
639
uint32_t chipEpoch = 0 ;
@@ -623,11 +646,11 @@ bool LockEndpoint::yearDayScheduleInAction(uint16_t userIndex) const
623
646
return false ;
624
647
}
625
648
626
- return std::any_of (mYearDaySchedules [userIndex].begin (), mYearDaySchedules [userIndex].end (),
627
- [chipEpoch](const YearDayScheduleInfo & sch) {
628
- return sch.status == DlScheduleStatus::kOccupied && sch.schedule .localStartTime <= chipEpoch &&
629
- chipEpoch <= sch.schedule .localEndTime ;
630
- });
649
+ return ! std::any_of (mYearDaySchedules [userIndex].begin (), mYearDaySchedules [userIndex].end (),
650
+ [chipEpoch](const YearDayScheduleInfo & sch) {
651
+ return sch.status == DlScheduleStatus::kOccupied && sch.schedule .localStartTime <= chipEpoch &&
652
+ chipEpoch <= sch.schedule .localEndTime ;
653
+ });
631
654
}
632
655
633
656
const char * LockEndpoint::lockStateToString (DlLockState lockState) const
0 commit comments