Skip to content

Commit 3f949ef

Browse files
authored
Merge branch 'master' into feature/app-install-flow-public
2 parents 3cdd1d5 + 7611b99 commit 3f949ef

File tree

14 files changed

+334
-32
lines changed

14 files changed

+334
-32
lines changed

examples/lock-app/lock-common/include/LockEndpoint.h

+30-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818

1919
#pragma once
2020

21+
#include <app/clusters/door-lock-server/door-lock-delegate.h>
2122
#include <app/clusters/door-lock-server/door-lock-server.h>
23+
#include <crypto/CHIPCryptoPAL.h>
2224
#include <vector>
2325

2426
struct LockUserInfo
@@ -38,10 +40,10 @@ struct WeekDaysScheduleInfo;
3840
struct YearDayScheduleInfo;
3941
struct HolidayScheduleInfo;
4042

41-
static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_DATA_SIZE = 20;
42-
static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_TYPES = 6;
43+
static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_DATA_SIZE = 65;
44+
static constexpr size_t DOOR_LOCK_CREDENTIAL_INFO_MAX_TYPES = 9;
4345

44-
class LockEndpoint
46+
class LockEndpoint : public chip::app::Clusters::DoorLock::Delegate
4547
{
4648
public:
4749
LockEndpoint(chip::EndpointId endpointId, uint16_t numberOfLockUsersSupported, uint16_t numberOfCredentialsSupported,
@@ -60,6 +62,7 @@ class LockEndpoint
6062
}
6163
DoorLockServer::Instance().SetDoorState(endpointId, mDoorState);
6264
DoorLockServer::Instance().SetLockState(endpointId, mLockState);
65+
chip::Crypto::DRBG_get_bytes(mAliroReaderGroupSubIdentifier, sizeof(mAliroReaderGroupSubIdentifier));
6366
}
6467

6568
inline chip::EndpointId GetEndpointId() const { return mEndpointId; }
@@ -100,6 +103,22 @@ class LockEndpoint
100103
DlStatus SetSchedule(uint8_t holidayIndex, DlScheduleStatus status, uint32_t localStartTime, uint32_t localEndTime,
101104
OperatingModeEnum operatingMode);
102105

106+
// DoorLock::Delegate API.
107+
CHIP_ERROR GetAliroReaderVerificationKey(chip::MutableByteSpan & verificationKey) override;
108+
CHIP_ERROR GetAliroReaderGroupIdentifier(chip::MutableByteSpan & groupIdentifier) override;
109+
CHIP_ERROR GetAliroReaderGroupSubIdentifier(chip::MutableByteSpan & groupSubIdentifier) override;
110+
CHIP_ERROR GetAliroExpeditedTransactionSupportedProtocolVersionAtIndex(size_t index,
111+
chip::MutableByteSpan & protocolVersion) override;
112+
CHIP_ERROR GetAliroGroupResolvingKey(chip::MutableByteSpan & groupResolvingKey) override;
113+
CHIP_ERROR GetAliroSupportedBLEUWBProtocolVersionAtIndex(size_t index, chip::MutableByteSpan & protocolVersion) override;
114+
uint8_t GetAliroBLEAdvertisingVersion() override;
115+
uint16_t GetNumberOfAliroCredentialIssuerKeysSupported() override;
116+
uint16_t GetNumberOfAliroEndpointKeysSupported() override;
117+
CHIP_ERROR SetAliroReaderConfig(const chip::ByteSpan & signingKey, const chip::ByteSpan & verificationKey,
118+
const chip::ByteSpan & groupIdentifier,
119+
const chip::Optional<chip::ByteSpan> & groupResolvingKey) override;
120+
CHIP_ERROR ClearAliroReaderConfig() override;
121+
103122
private:
104123
bool setLockState(const Nullable<chip::FabricIndex> & fabricIdx, const Nullable<chip::NodeId> & nodeId, DlLockState lockState,
105124
const Optional<chip::ByteSpan> & pin, OperationErrorEnum & err,
@@ -130,6 +149,14 @@ class LockEndpoint
130149
std::vector<std::vector<WeekDaysScheduleInfo>> mWeekDaySchedules;
131150
std::vector<std::vector<YearDayScheduleInfo>> mYearDaySchedules;
132151
std::vector<HolidayScheduleInfo> mHolidaySchedules;
152+
153+
// Actual Aliro state would presumably be stored somewhere else, and persistently; this
154+
// example just stores it in memory for illustration purposes.
155+
uint8_t mAliroReaderVerificationKey[chip::app::Clusters::DoorLock::kAliroReaderVerificationKeySize];
156+
uint8_t mAliroReaderGroupIdentifier[chip::app::Clusters::DoorLock::kAliroReaderGroupIdentifierSize];
157+
uint8_t mAliroReaderGroupSubIdentifier[chip::app::Clusters::DoorLock::kAliroReaderGroupSubIdentifierSize];
158+
uint8_t mAliroGroupResolvingKey[chip::app::Clusters::DoorLock::kAliroGroupResolvingKeySize];
159+
bool mAliroStateInitialized = false;
133160
};
134161

135162
struct LockCredentialInfo

examples/lock-app/lock-common/include/LockManager.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,12 @@ class LockManager
7070
private:
7171
LockEndpoint * getEndpoint(chip::EndpointId endpointId);
7272

73-
std::vector<LockEndpoint> mEndpoints;
73+
/**
74+
* We store the LockEndpoint instances by pointer, not value, so
75+
* LockEndpoint can have a stable location in memory, which lets it
76+
* implement DoorLock::Delegate.
77+
*/
78+
std::vector<std::unique_ptr<LockEndpoint>> mEndpoints;
7479

7580
static LockManager instance;
7681
};

examples/lock-app/lock-common/src/LockEndpoint.cpp

+150-1
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,15 @@
1717
*/
1818
#include "LockEndpoint.h"
1919
#include <app-common/zap-generated/attributes/Accessors.h>
20+
#include <app-common/zap-generated/cluster-enums.h>
2021
#include <cstring>
22+
#include <lib/core/CHIPEncoding.h>
2123
#include <platform/CHIPDeviceLayer.h>
2224
#include <platform/internal/CHIPDeviceLayerInternal.h>
2325

26+
using chip::ByteSpan;
27+
using chip::MutableByteSpan;
28+
using chip::Optional;
2429
using chip::to_underlying;
2530
using chip::app::DataModel::MakeNullable;
2631

@@ -204,7 +209,8 @@ bool LockEndpoint::GetCredential(uint16_t credentialIndex, CredentialTypeEnum cr
204209
if (credentialIndex >= mLockCredentials.at(to_underlying(credentialType)).size() ||
205210
(0 == credentialIndex && CredentialTypeEnum::kProgrammingPIN != credentialType))
206211
{
207-
ChipLogError(Zcl, "Cannot get the credential - index out of range [endpoint=%d,index=%d]", mEndpointId, credentialIndex);
212+
ChipLogError(Zcl, "Cannot get the credential - index out of range [endpoint=%d,index=%d]: %d", mEndpointId, credentialIndex,
213+
static_cast<int>(mLockCredentials.at(to_underlying(credentialType)).size()));
208214
return false;
209215
}
210216

@@ -407,6 +413,149 @@ DlStatus LockEndpoint::SetSchedule(uint8_t holidayIndex, DlScheduleStatus status
407413
return DlStatus::kSuccess;
408414
}
409415

416+
CHIP_ERROR LockEndpoint::GetAliroReaderVerificationKey(MutableByteSpan & verificationKey)
417+
{
418+
if (!mAliroStateInitialized)
419+
{
420+
verificationKey.reduce_size(0);
421+
return CHIP_NO_ERROR;
422+
}
423+
424+
return chip::CopySpanToMutableSpan(ByteSpan(mAliroReaderVerificationKey), verificationKey);
425+
}
426+
427+
CHIP_ERROR LockEndpoint::GetAliroReaderGroupIdentifier(MutableByteSpan & groupIdentifier)
428+
{
429+
if (!mAliroStateInitialized)
430+
{
431+
groupIdentifier.reduce_size(0);
432+
return CHIP_NO_ERROR;
433+
}
434+
435+
return CopySpanToMutableSpan(ByteSpan(mAliroReaderGroupIdentifier), groupIdentifier);
436+
}
437+
438+
CHIP_ERROR LockEndpoint::GetAliroReaderGroupSubIdentifier(MutableByteSpan & groupSubIdentifier)
439+
{
440+
return CopySpanToMutableSpan(ByteSpan(mAliroReaderGroupSubIdentifier), groupSubIdentifier);
441+
}
442+
443+
namespace {
444+
445+
CHIP_ERROR CopyProtocolVersionIntoSpan(uint16_t protocolVersionValue, MutableByteSpan & protocolVersion)
446+
{
447+
using namespace chip::app::Clusters::DoorLock;
448+
449+
static_assert(sizeof(protocolVersionValue) == kAliroProtocolVersionSize);
450+
451+
if (protocolVersion.size() < kAliroProtocolVersionSize)
452+
{
453+
return CHIP_ERROR_INVALID_ARGUMENT;
454+
}
455+
456+
// Per Aliro spec, protocol version encoding is big-endian
457+
chip::Encoding::BigEndian::Put16(protocolVersion.data(), protocolVersionValue);
458+
protocolVersion.reduce_size(kAliroProtocolVersionSize);
459+
return CHIP_NO_ERROR;
460+
}
461+
462+
} // anonymous namespace
463+
464+
CHIP_ERROR LockEndpoint::GetAliroExpeditedTransactionSupportedProtocolVersionAtIndex(size_t index,
465+
MutableByteSpan & protocolVersion)
466+
{
467+
// Only claim support for the one known protocol version for now: 0x0100.
468+
constexpr uint16_t knownProtocolVersion = 0x0100;
469+
470+
if (index > 0)
471+
{
472+
return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED;
473+
}
474+
475+
return CopyProtocolVersionIntoSpan(knownProtocolVersion, protocolVersion);
476+
}
477+
478+
CHIP_ERROR LockEndpoint::GetAliroGroupResolvingKey(MutableByteSpan & groupResolvingKey)
479+
{
480+
if (!mAliroStateInitialized)
481+
{
482+
groupResolvingKey.reduce_size(0);
483+
return CHIP_NO_ERROR;
484+
}
485+
486+
return CopySpanToMutableSpan(ByteSpan(mAliroGroupResolvingKey), groupResolvingKey);
487+
}
488+
489+
CHIP_ERROR LockEndpoint::GetAliroSupportedBLEUWBProtocolVersionAtIndex(size_t index, MutableByteSpan & protocolVersion)
490+
{
491+
// Only claim support for the one known protocol version for now: 0x0100.
492+
constexpr uint16_t knownProtocolVersion = 0x0100;
493+
494+
if (index > 0)
495+
{
496+
return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED;
497+
}
498+
499+
return CopyProtocolVersionIntoSpan(knownProtocolVersion, protocolVersion);
500+
}
501+
502+
uint8_t LockEndpoint::GetAliroBLEAdvertisingVersion()
503+
{
504+
// For now the only define value of the BLE advertising version for Aliro is 0.
505+
return 0;
506+
}
507+
508+
uint16_t LockEndpoint::GetNumberOfAliroCredentialIssuerKeysSupported()
509+
{
510+
using namespace chip::app::Clusters::DoorLock;
511+
512+
// Our vector has an extra entry at index 0 that is not a valid entry, so
513+
// the actual number of credentials supported is one length than the length.
514+
return static_cast<uint16_t>(mLockCredentials.at(to_underlying(CredentialTypeEnum::kAliroCredentialIssuerKey)).size() - 1);
515+
}
516+
517+
uint16_t LockEndpoint::GetNumberOfAliroEndpointKeysSupported()
518+
{
519+
using namespace chip::app::Clusters::DoorLock;
520+
521+
// Our vector has an extra entry at index 0 that is not a valid entry, so
522+
// the actual number of credentials supported is one length than the length.
523+
//
524+
// Also, our arrays are the same size, so we just return the size of one of
525+
// the arrays: that is the cap on the total number of endpoint keys
526+
// supported, which can be of either type.
527+
return static_cast<uint16_t>(mLockCredentials.at(to_underlying(CredentialTypeEnum::kAliroEvictableEndpointKey)).size() - 1);
528+
}
529+
530+
CHIP_ERROR LockEndpoint::SetAliroReaderConfig(const ByteSpan & signingKey, const ByteSpan & verificationKey,
531+
const ByteSpan & groupIdentifier, const Optional<ByteSpan> & groupResolvingKey)
532+
{
533+
// We ignore the signing key, since we never do anything with it.
534+
535+
VerifyOrReturnError(verificationKey.size() == sizeof(mAliroReaderVerificationKey), CHIP_ERROR_INVALID_ARGUMENT);
536+
memcpy(mAliroReaderVerificationKey, verificationKey.data(), sizeof(mAliroReaderVerificationKey));
537+
538+
VerifyOrReturnError(groupIdentifier.size() == sizeof(mAliroReaderGroupIdentifier), CHIP_ERROR_INVALID_ARGUMENT);
539+
memcpy(mAliroReaderGroupIdentifier, groupIdentifier.data(), sizeof(mAliroReaderGroupIdentifier));
540+
541+
if (groupResolvingKey.HasValue())
542+
{
543+
VerifyOrReturnError(groupResolvingKey.Value().size() == sizeof(mAliroGroupResolvingKey), CHIP_ERROR_INVALID_ARGUMENT);
544+
memcpy(mAliroGroupResolvingKey, groupResolvingKey.Value().data(), sizeof(mAliroGroupResolvingKey));
545+
}
546+
547+
mAliroStateInitialized = true;
548+
return CHIP_NO_ERROR;
549+
}
550+
551+
CHIP_ERROR LockEndpoint::ClearAliroReaderConfig()
552+
{
553+
// A real implementation would clear out key data from the other parts of
554+
// the application that might use it.
555+
mAliroStateInitialized = false;
556+
return CHIP_NO_ERROR;
557+
}
558+
410559
bool LockEndpoint::setLockState(const Nullable<chip::FabricIndex> & fabricIdx, const Nullable<chip::NodeId> & nodeId,
411560
DlLockState lockState, const Optional<chip::ByteSpan> & pin, OperationErrorEnum & err,
412561
OperationSourceEnum opSource)

examples/lock-app/lock-common/src/LockManager.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include <iostream>
2222
#include <lib/support/logging/CHIPLogging.h>
23+
#include <memory>
2324

2425
using chip::to_underlying;
2526

@@ -98,15 +99,17 @@ bool LockManager::InitEndpoint(chip::EndpointId endpointId)
9899
numberOfHolidaySchedules = 10;
99100
}
100101

101-
mEndpoints.emplace_back(endpointId, numberOfSupportedUsers, numberOfSupportedCredentials, numberOfWeekDaySchedulesPerUser,
102-
numberOfYearDaySchedulesPerUser, numberOfCredentialsSupportedPerUser, numberOfHolidaySchedules);
102+
mEndpoints.emplace_back(std::make_unique<LockEndpoint>(endpointId, numberOfSupportedUsers, numberOfSupportedCredentials,
103+
numberOfWeekDaySchedulesPerUser, numberOfYearDaySchedulesPerUser,
104+
numberOfCredentialsSupportedPerUser, numberOfHolidaySchedules));
103105

104106
ChipLogProgress(Zcl,
105107
"Initialized new lock door endpoint "
106108
"[id=%d,users=%d,credentials=%d,weekDaySchedulesPerUser=%d,yearDaySchedulesPerUser=%d,"
107109
"numberOfCredentialsSupportedPerUser=%d,holidaySchedules=%d]",
108110
endpointId, numberOfSupportedUsers, numberOfSupportedCredentials, numberOfWeekDaySchedulesPerUser,
109111
numberOfYearDaySchedulesPerUser, numberOfCredentialsSupportedPerUser, numberOfHolidaySchedules);
112+
DoorLockServer::Instance().SetDelegate(endpointId, mEndpoints.back().get());
110113

111114
return true;
112115
}
@@ -303,11 +306,11 @@ DlStatus LockManager::SetSchedule(chip::EndpointId endpointId, uint8_t holidayIn
303306

304307
LockEndpoint * LockManager::getEndpoint(chip::EndpointId endpointId)
305308
{
306-
for (auto & mEndpoint : mEndpoints)
309+
for (auto & endpoint : mEndpoints)
307310
{
308-
if (mEndpoint.GetEndpointId() == endpointId)
311+
if (endpoint->GetEndpointId() == endpointId)
309312
{
310-
return &mEndpoint;
313+
return endpoint.get();
311314
}
312315
}
313316
return nullptr;

0 commit comments

Comments
 (0)