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

Allow the linux lock app to store credentials by type. #24532

Merged
merged 2 commits into from
Jan 24, 2023
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
5 changes: 3 additions & 2 deletions examples/lock-app/linux/include/LockEndpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct YearDayScheduleInfo;
struct HolidayScheduleInfo;

static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_DATA_SIZE = 20;
static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_TYPES = 6;

class LockEndpoint
{
Expand All @@ -48,7 +49,7 @@ class LockEndpoint
uint8_t numberOfHolidaySchedules) :
mEndpointId{ endpointId },
mLockState{ DlLockState::kLocked }, mDoorState{ DoorStateEnum::kDoorClosed }, mLockUsers(numberOfLockUsersSupported),
mLockCredentials(numberOfCredentialsSupported + 1),
mLockCredentials(DOOR_LOCK_CREDENTIAL_INFO_MAX_TYPES, std::vector<LockCredentialInfo>(numberOfCredentialsSupported + 1)),
mWeekDaySchedules(numberOfLockUsersSupported, std::vector<WeekDaysScheduleInfo>(weekDaySchedulesPerUser)),
mYearDaySchedules(numberOfLockUsersSupported, std::vector<YearDayScheduleInfo>(yearDaySchedulesPerUser)),
mHolidaySchedules(numberOfHolidaySchedules)
Expand Down Expand Up @@ -109,7 +110,7 @@ class LockEndpoint
// This is very naive implementation of users/credentials/schedules database and by no means the best practice. Proper storage
// of those items is out of scope of this example.
std::vector<LockUserInfo> mLockUsers;
std::vector<LockCredentialInfo> mLockCredentials;
std::vector<std::vector<LockCredentialInfo>> mLockCredentials;
std::vector<std::vector<WeekDaysScheduleInfo>> mWeekDaySchedules;
std::vector<std::vector<YearDayScheduleInfo>> mYearDaySchedules;
std::vector<HolidayScheduleInfo> mHolidaySchedules;
Expand Down
30 changes: 22 additions & 8 deletions examples/lock-app/linux/src/LockEndpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,14 +164,20 @@ bool LockEndpoint::GetCredential(uint16_t credentialIndex, CredentialTypeEnum cr
ChipLogProgress(Zcl, "Lock App: LockEndpoint::GetCredential [endpoint=%d,credentialIndex=%u,credentialType=%u]", mEndpointId,
credentialIndex, to_underlying(credentialType));

if (credentialIndex >= mLockCredentials.size() ||
if (to_underlying(credentialType) >= mLockCredentials.size())
{
ChipLogError(Zcl, "Cannot get the credential - index out of range [endpoint=%d,index=%d]", mEndpointId, credentialIndex);
return false;
}

if (credentialIndex >= mLockCredentials.at(to_underlying(credentialType)).size() ||
(0 == credentialIndex && CredentialTypeEnum::kProgrammingPIN != credentialType))
{
ChipLogError(Zcl, "Cannot get the credential - index out of range [endpoint=%d,index=%d]", mEndpointId, credentialIndex);
return false;
}

const auto & credentialInStorage = mLockCredentials[credentialIndex];
const auto & credentialInStorage = mLockCredentials[to_underlying(credentialType)][credentialIndex];

credential.status = credentialInStorage.status;
if (DlCredentialStatus::kAvailable == credential.status)
Expand Down Expand Up @@ -206,14 +212,21 @@ bool LockEndpoint::SetCredential(uint16_t credentialIndex, chip::FabricIndex cre
mEndpointId, credentialIndex, to_underlying(credentialStatus), to_underlying(credentialType),
static_cast<unsigned int>(credentialData.size()), creator, modifier);

if (credentialIndex >= mLockCredentials.size() ||
if (to_underlying(credentialType) >= mLockCredentials.capacity())
{
ChipLogError(Zcl, "Cannot set the credential - type out of range [endpoint=%d,type=%d]", mEndpointId,
to_underlying(credentialType));
return false;
}

if (credentialIndex >= mLockCredentials.at(to_underlying(credentialType)).size() ||
(0 == credentialIndex && CredentialTypeEnum::kProgrammingPIN != credentialType))
{
ChipLogError(Zcl, "Cannot set the credential - index out of range [endpoint=%d,index=%d]", mEndpointId, credentialIndex);
return false;
}

auto & credentialInStorage = mLockCredentials[credentialIndex];
auto & credentialInStorage = mLockCredentials[to_underlying(credentialType)][credentialIndex];
if (credentialData.size() > DOOR_LOCK_CREDENTIAL_INFO_MAX_DATA_SIZE)
{
ChipLogError(Zcl,
Expand Down Expand Up @@ -391,11 +404,12 @@ bool LockEndpoint::setLockState(DlLockState lockState, const Optional<chip::Byte
}

// Find the credential so we can make sure it is not absent right away
auto credential = std::find_if(mLockCredentials.begin(), mLockCredentials.end(), [&pin](const LockCredentialInfo & c) {
return (c.credentialType == CredentialTypeEnum::kPin && c.status != DlCredentialStatus::kAvailable) &&
auto & pinCredentials = mLockCredentials[to_underlying(CredentialTypeEnum::kPin)];
auto credential = std::find_if(pinCredentials.begin(), pinCredentials.end(), [&pin](const LockCredentialInfo & c) {
return (c.status != DlCredentialStatus::kAvailable) &&
chip::ByteSpan{ c.credentialData, c.credentialDataSize }.data_equal(pin.Value());
});
if (credential == mLockCredentials.end())
if (credential == pinCredentials.end())
{
ChipLogDetail(Zcl,
"Lock App: specified PIN code was not found in the database, ignoring command to set lock state to \"%s\" "
Expand All @@ -407,7 +421,7 @@ bool LockEndpoint::setLockState(DlLockState lockState, const Optional<chip::Byte
}

// Find a user that correspond to this credential
auto credentialIndex = static_cast<unsigned>(credential - mLockCredentials.begin());
auto credentialIndex = static_cast<unsigned>(credential - pinCredentials.begin());
auto user = std::find_if(mLockUsers.begin(), mLockUsers.end(), [credential, credentialIndex](const LockUserInfo & u) {
return std::any_of(u.credentials.begin(), u.credentials.end(), [&credential, credentialIndex](const CredentialStruct & c) {
return c.CredentialIndex == credentialIndex && c.CredentialType == to_underlying(credential->credentialType);
Expand Down
Loading