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

Stop using weak functions for Aliro command callbacks. #33931

Merged
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
18 changes: 18 additions & 0 deletions src/app/clusters/door-lock-server/door-lock-delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,24 @@ class Delegate
* @return The max number of Aliro endpoint keys supported.
*/
virtual uint16_t GetNumberOfAliroEndpointKeysSupported() = 0;

/**
* Set the Aliro reader configuration for the lock. The various arguments
* have already been checked for constraints and consistency with the
* FeatureMap.
*
* @param[in] signingKey Signing key component of the Reader's key pair.
* @param[in] verificationKey Verification key component of the Reader's key pair.
* @param[in] groupIdentifier Reader group identifier for the lock.
* @param[in] groupResolvingKey Group resolving key for the lock if Aliro BLE UWB feature is supported
*/
virtual CHIP_ERROR SetAliroReaderConfig(const ByteSpan & signingKey, const ByteSpan & verificationKey,
const ByteSpan & groupIdentifier, const Optional<ByteSpan> & groupResolvingKey) = 0;

/**
* Clear the Aliro reader configuration for the lock.
*/
virtual CHIP_ERROR ClearAliroReaderConfig() = 0;
};

} // namespace DoorLock
Expand Down
12 changes: 0 additions & 12 deletions src/app/clusters/door-lock-server/door-lock-server-callback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,15 +242,3 @@ emberAfPluginDoorLockGetFaceCredentialLengthConstraints(chip::EndpointId endpoin
{
return false;
}

bool __attribute__((weak))
emberAfPluginDoorLockSetAliroReaderConfig(EndpointId endpointId, const ByteSpan & signingKey, const ByteSpan & verificationKey,
const ByteSpan & groupIdentifier, const Optional<ByteSpan> groupResolvingKey)
{
return false;
}

bool __attribute__((weak)) emberAfPluginDoorLockClearAliroReaderConfig(chip::EndpointId endpointId)
{
return false;
}
84 changes: 67 additions & 17 deletions src/app/clusters/door-lock-server/door-lock-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class DoorLockClusterFabricDelegate : public chip::FabricTable::Delegate
{
void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) override
{
for (auto endpointId : EnabledEndpointsWithServerCluster(chip::app::Clusters::DoorLock::Id))
for (auto endpointId : EnabledEndpointsWithServerCluster(Clusters::DoorLock::Id))
{
if (!DoorLockServer::Instance().OnFabricRemoved(endpointId, fabricIndex))
{
Expand Down Expand Up @@ -3641,7 +3641,7 @@ void DoorLockServer::SendEvent(chip::EndpointId endpointId, T & event)

template <typename T>
bool DoorLockServer::GetAttribute(chip::EndpointId endpointId, chip::AttributeId attributeId,
Status (*getFn)(chip::EndpointId endpointId, T * value), T & value) const
Status (*getFn)(chip::EndpointId endpointId, T * value), T & value)
{
Status status = getFn(endpointId, &value);
bool success = (Status::Success == status);
Expand Down Expand Up @@ -3927,12 +3927,26 @@ void DoorLockServer::setAliroReaderConfigCommandHandler(CommandHandler * command
}

Delegate * delegate = GetDelegate(endpointID);
VerifyOrReturn(delegate != nullptr, ChipLogError(Zcl, "Delegate is null"));
if (!delegate)
{
ChipLogError(Zcl, "Door Lock delegate is null");
commandObj->AddStatus(commandPath, Status::Failure);
return;
}

// If Aliro BLE UWB feature is supported and groupResolvingKey is not provided in the command, return INVALID_COMMAND.
if (SupportsAliroBLEUWB(endpointID) && !groupResolvingKey.HasValue())
// The GroupResolvingKey must be provided if and only if the Aliro BLE UWB
// feature is supported. Otherwise, return INVALID_COMMAND
const bool supportsAliroBLEUWB = SupportsAliroBLEUWB(endpointID);
if (supportsAliroBLEUWB != groupResolvingKey.HasValue())
{
ChipLogProgress(Zcl, "[SetAliroReaderConfig] Aliro BLE UWB supported but Group Resolving Key is not provided");
if (supportsAliroBLEUWB)
{
ChipLogError(Zcl, "[SetAliroReaderConfig] Aliro BLE UWB supported but Group Resolving Key is not provided");
}
else
{
ChipLogError(Zcl, "[SetAliroReaderConfig] Aliro BLE UWB not supported but Group Resolving Key is provided");
}
commandObj->AddStatus(commandPath, Status::InvalidCommand);
return;
}
Expand All @@ -3959,19 +3973,27 @@ void DoorLockServer::setAliroReaderConfigCommandHandler(CommandHandler * command
// INVALID_IN_STATE.
if (err != CHIP_NO_ERROR || !readerVerificationKey.empty())
{
ChipLogProgress(
Zcl, "[SetAliroReaderConfig] Aliro reader verification key was not read or is not null. Return INVALID_IN_STATE");
ChipLogError(Zcl, "[SetAliroReaderConfig] Aliro reader verification key was not read or is not null.");
commandObj->AddStatus(commandPath, Status::InvalidInState);
return;
}

Status status = Status::Success;
if (!emberAfPluginDoorLockSetAliroReaderConfig(endpointID, signingKey, verificationKey, groupIdentifier, groupResolvingKey))
err = delegate->SetAliroReaderConfig(signingKey, verificationKey, groupIdentifier, groupResolvingKey);
if (err != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "[SetAliroReaderConfig] Unable to set aliro reader config [endpointId=%d]", endpointID);
status = Status::Failure;
}
sendClusterResponse(commandObj, commandPath, ClusterStatusCode(status));
else
{
// Various attributes changed; mark them dirty.
MatterReportingAttributeChangeCallback(endpointID, Clusters::DoorLock::Id, AliroReaderVerificationKey::Id);
MatterReportingAttributeChangeCallback(endpointID, Clusters::DoorLock::Id, AliroReaderGroupIdentifier::Id);
if (supportsAliroBLEUWB)
{
MatterReportingAttributeChangeCallback(endpointID, Clusters::DoorLock::Id, AliroGroupResolvingKey::Id);
}
}
sendClusterResponse(commandObj, commandPath, ClusterStatusCode(StatusIB(err).mStatus));
}

void DoorLockServer::clearAliroReaderConfigCommandHandler(CommandHandler * commandObj, const ConcreteCommandPath & commandPath)
Expand All @@ -3987,13 +4009,41 @@ void DoorLockServer::clearAliroReaderConfigCommandHandler(CommandHandler * comma
return;
}

Status status = Status::Success;
if (!emberAfPluginDoorLockClearAliroReaderConfig(endpointID))
Delegate * delegate = GetDelegate(endpointID);
if (!delegate)
{
ChipLogProgress(Zcl, "[SetAliroReaderConfig] Unable to set aliro reader config [endpointId=%d]", endpointID);
status = Status::Failure;
ChipLogError(Zcl, "Door Lock delegate is null");
commandObj->AddStatus(commandPath, Status::Failure);
return;
}

uint8_t buffer[kAliroReaderVerificationKeySize];
MutableByteSpan readerVerificationKey(buffer);
CHIP_ERROR err = delegate->GetAliroReaderVerificationKey(readerVerificationKey);
if (err != CHIP_NO_ERROR && readerVerificationKey.empty())
{
// No reader config to start with. Just return without marking any
// attributes as dirty.
commandObj->AddStatus(commandPath, Status::Success);
return;
}

err = delegate->ClearAliroReaderConfig();
if (err != CHIP_NO_ERROR)
{
ChipLogError(Zcl, "[SetAliroReaderConfig] Unable to set aliro reader config [endpointId=%d]", endpointID);
}
else
{
// Various attributes changed; mark them dirty.
MatterReportingAttributeChangeCallback(endpointID, Clusters::DoorLock::Id, AliroReaderVerificationKey::Id);
MatterReportingAttributeChangeCallback(endpointID, Clusters::DoorLock::Id, AliroReaderGroupIdentifier::Id);
if (SupportsAliroBLEUWB(endpointID))
{
MatterReportingAttributeChangeCallback(endpointID, Clusters::DoorLock::Id, AliroGroupResolvingKey::Id);
}
}
sendClusterResponse(commandObj, commandPath, ClusterStatusCode(status));
sendClusterResponse(commandObj, commandPath, ClusterStatusCode(StatusIB(err).mStatus));
}

// =============================================================================
Expand Down
69 changes: 23 additions & 46 deletions src/app/clusters/door-lock-server/door-lock-server.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <app/AttributeAccessInterface.h>
#include <app/CommandHandler.h>
#include <app/ConcreteCommandPath.h>
#include <app/reporting/reporting.h>
#include <app/util/attribute-storage.h>
#include <app/util/config.h>
#include <platform/CHIPDeviceConfig.h>
Expand Down Expand Up @@ -174,57 +175,60 @@ class DoorLockServer : public chip::app::AttributeAccessInterface

bool SendLockAlarmEvent(chip::EndpointId endpointId, AlarmCodeEnum alarmCode);

chip::BitFlags<Feature> GetFeatures(chip::EndpointId endpointId);
static chip::BitFlags<Feature> GetFeatures(chip::EndpointId endpointId);

inline bool SupportsPIN(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(Feature::kPinCredential); }
static inline bool SupportsPIN(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(Feature::kPinCredential); }

inline bool SupportsRFID(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(Feature::kRfidCredential); }
static inline bool SupportsRFID(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(Feature::kRfidCredential); }

inline bool SupportsFingers(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(Feature::kFingerCredentials); }
static inline bool SupportsFingers(chip::EndpointId endpointId)
{
return GetFeatures(endpointId).Has(Feature::kFingerCredentials);
}

inline bool SupportsFace(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(Feature::kFaceCredentials); }
static inline bool SupportsFace(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(Feature::kFaceCredentials); }

inline bool SupportsWeekDaySchedules(chip::EndpointId endpointId)
static inline bool SupportsWeekDaySchedules(chip::EndpointId endpointId)
{
return GetFeatures(endpointId).Has(Feature::kWeekDayAccessSchedules);
}

inline bool SupportsYearDaySchedules(chip::EndpointId endpointId)
static inline bool SupportsYearDaySchedules(chip::EndpointId endpointId)
{
return GetFeatures(endpointId).Has(Feature::kYearDayAccessSchedules);
}

inline bool SupportsHolidaySchedules(chip::EndpointId endpointId)
static inline bool SupportsHolidaySchedules(chip::EndpointId endpointId)
{
return GetFeatures(endpointId).Has(Feature::kHolidaySchedules);
}

inline bool SupportsAnyCredential(chip::EndpointId endpointId)
static inline bool SupportsAnyCredential(chip::EndpointId endpointId)
{
return GetFeatures(endpointId)
.HasAny(Feature::kPinCredential, Feature::kRfidCredential, Feature::kFingerCredentials, Feature::kFaceCredentials,
Feature::kAliroProvisioning);
}

inline bool SupportsCredentialsOTA(chip::EndpointId endpointId)
static inline bool SupportsCredentialsOTA(chip::EndpointId endpointId)
{
return GetFeatures(endpointId).Has(Feature::kCredentialsOverTheAirAccess);
}

inline bool SupportsUSR(chip::EndpointId endpointId)
static inline bool SupportsUSR(chip::EndpointId endpointId)
{
// appclusters, 5.2.2: USR feature has conformance [PIN | RID | FGP | FACE]
return GetFeatures(endpointId).Has(Feature::kUser) && SupportsAnyCredential(endpointId);
}

inline bool SupportsUnbolt(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(Feature::kUnbolt); }
static bool SupportsUnbolt(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(Feature::kUnbolt); }

/**
* @brief Checks if Aliro Provisioning feature is supported on the given endpoint
*
* @param endpointId endpointId ID of the endpoint which contains the lock.
*/
inline bool SupportsAliroProvisioning(chip::EndpointId endpointId)
static inline bool SupportsAliroProvisioning(chip::EndpointId endpointId)
{
return GetFeatures(endpointId).Has(Feature::kAliroProvisioning);
}
Expand All @@ -234,7 +238,10 @@ class DoorLockServer : public chip::app::AttributeAccessInterface
*
* @param endpointId endpointId ID of the endpoint which contains the lock.
*/
inline bool SupportsAliroBLEUWB(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(Feature::kAliroBLEUWB); }
static inline bool SupportsAliroBLEUWB(chip::EndpointId endpointId)
{
return GetFeatures(endpointId).Has(Feature::kAliroBLEUWB);
}

/**
* @brief Allows the application to register a custom callback which will be called after the default DoorLock
Expand Down Expand Up @@ -545,8 +552,8 @@ class DoorLockServer : public chip::app::AttributeAccessInterface
* @return false if attribute reading failed (value is kept unchanged)
*/
template <typename T>
bool GetAttribute(chip::EndpointId endpointId, chip::AttributeId attributeId,
chip::Protocols::InteractionModel::Status (*getFn)(chip::EndpointId endpointId, T * value), T & value) const;
static bool GetAttribute(chip::EndpointId endpointId, chip::AttributeId attributeId,
chip::Protocols::InteractionModel::Status (*getFn)(chip::EndpointId endpointId, T * value), T & value);

/**
* @brief Set generic attribute value
Expand Down Expand Up @@ -1273,33 +1280,3 @@ bool emberAfPluginDoorLockGetFingerVeinCredentialLengthConstraints(chip::Endpoin
* @return false on failure, true on success.
*/
bool emberAfPluginDoorLockGetFaceCredentialLengthConstraints(chip::EndpointId endpointId, uint8_t & minLen, uint8_t & maxLen);

/**
* @brief This callback is called when Door Lock cluster needs to communicate the Aliro reader configuration to the door lock.
*
* @note This function is used for communicating the Aliro signing key, verification key, group identifier and group resolving key
* to the lock.
*
* @param endpointId ID of the endpoint which contains the lock.
* @param[in] signingKey Signing key component of the Reader's key pair.
* @param[in] verificationKey Verification key component of the Reader's key pair.
* @param[in] groupIdentifier Reader group identifier for the lock.
* @param[in] groupResolvingKey Group resolving key for the lock if Aliro BLE UWB feature is supported
*
* @retval true, if the Aliro reader config was successfully communicated to the door lock.
* @retval false, if error occurred while communicating the Aliro reader config.
*/
bool emberAfPluginDoorLockSetAliroReaderConfig(chip::EndpointId endpointId, const chip::ByteSpan & signingKey,
const chip::ByteSpan & verificationKey, const chip::ByteSpan & groupIdentifier,
const Optional<chip::ByteSpan> & groupResolvingKey);

/**
* @brief This callback is called when Door Lock cluster needs to clear an existing Aliro reader configuration from the door lock.
*
*
* @param endpointId ID of the endpoint which contains the lock.
*
* @retval true, if the Aliro reader config was successfully cleared from the door lock.
* @retval false, if error occurred while clearing the Aliro reader config.
*/
bool emberAfPluginDoorLockClearAliroReaderConfig(chip::EndpointId endpointId);
Loading