Skip to content

Commit

Permalink
[#19793] Implement separate feature bits for schedules in the door lo…
Browse files Browse the repository at this point in the history
…ck cluster
  • Loading branch information
Morozov-5F committed Jul 14, 2022
1 parent 5aa5e8e commit 4128817
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"featureLevel": 72,
"featureLevel": 75,
"creator": "zap",
"keyValuePairs": [
{
Expand All @@ -19,14 +19,14 @@
{
"pathRelativity": "relativeToZap",
"path": "../../../src/app/zap-templates/app-templates.json",
"version": "chip-v1",
"type": "gen-templates-json"
"type": "gen-templates-json",
"version": "chip-v1"
},
{
"pathRelativity": "relativeToZap",
"path": "../../../src/app/zap-templates/zcl/zcl-with-test-extensions.json",
"version": "ZCL Test Data",
"type": "zcl-properties"
"type": "zcl-properties",
"version": "ZCL Test Data"
}
],
"endpointTypes": [
Expand Down Expand Up @@ -13331,7 +13331,7 @@
"storageOption": "RAM",
"singleton": 0,
"bounded": 0,
"defaultValue": "0x113",
"defaultValue": "0xD13",
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand Down Expand Up @@ -24662,5 +24662,6 @@
"endpointVersion": 1,
"deviceIdentifier": 61442
}
]
],
"log": []
}
28 changes: 14 additions & 14 deletions examples/lock-app/lock-common/lock-app.zap
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"featureLevel": 71,
"featureLevel": 75,
"creator": "zap",
"keyValuePairs": [
{
Expand All @@ -19,14 +19,14 @@
{
"pathRelativity": "relativeToZap",
"path": "../../../src/app/zap-templates/zcl/zcl.json",
"version": "ZCL Test Data",
"type": "zcl-properties"
"type": "zcl-properties",
"version": "ZCL Test Data"
},
{
"pathRelativity": "relativeToZap",
"path": "../../../src/app/zap-templates/app-templates.json",
"version": "chip-v1",
"type": "gen-templates-json"
"type": "gen-templates-json",
"version": "chip-v1"
}
],
"endpointTypes": [
Expand Down Expand Up @@ -2146,7 +2146,7 @@
"code": 0,
"mfgCode": null,
"side": "server",
"type": "enum8",
"type": "PowerSourceStatus",
"included": 1,
"storageOption": "RAM",
"singleton": 0,
Expand Down Expand Up @@ -7112,7 +7112,7 @@
"code": 0,
"mfgCode": null,
"side": "server",
"type": "enum8",
"type": "PowerSourceStatus",
"included": 1,
"storageOption": "RAM",
"singleton": 0,
Expand Down Expand Up @@ -7172,11 +7172,11 @@
"reportableChange": 0
},
{
"name": "BatteryChargeLevel",
"name": "BatChargeLevel",
"code": 14,
"mfgCode": null,
"side": "server",
"type": "enum8",
"type": "BatChargeLevel",
"included": 1,
"storageOption": "RAM",
"singleton": 0,
Expand All @@ -7188,7 +7188,7 @@
"reportableChange": 0
},
{
"name": "BatteryReplacementNeeded",
"name": "BatReplacementNeeded",
"code": 15,
"mfgCode": null,
"side": "server",
Expand All @@ -7204,11 +7204,11 @@
"reportableChange": 0
},
{
"name": "BatteryReplaceability",
"name": "BatReplaceability",
"code": 16,
"mfgCode": null,
"side": "server",
"type": "enum8",
"type": "BatReplaceability",
"included": 1,
"storageOption": "RAM",
"singleton": 0,
Expand All @@ -7220,7 +7220,7 @@
"reportableChange": 0
},
{
"name": "BatteryReplacementDescription",
"name": "BatReplacementDescription",
"code": 19,
"mfgCode": null,
"side": "server",
Expand Down Expand Up @@ -8133,7 +8133,7 @@
"storageOption": "RAM",
"singleton": 0,
"bounded": 0,
"defaultValue": "0x1B3",
"defaultValue": "0xDB3",
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand Down
2 changes: 1 addition & 1 deletion scripts/tests/chiptest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
def target_for_name(name: str):
if name.startswith("TV_") or name.startswith("Test_TC_MC_") or name.startswith("Test_TC_LOWPOWER_") or name.startswith("Test_TC_KEYPADINPUT_") or name.startswith("Test_TC_APPLAUNCHER_") or name.startswith("Test_TC_MEDIAINPUT_") or name.startswith("Test_TC_WAKEONLAN_") or name.startswith("Test_TC_CHANNEL_") or name.startswith("Test_TC_MEDIAPLAYBACK_") or name.startswith("Test_TC_AUDIOOUTPUT_") or name.startswith("Test_TC_TGTNAV_") or name.startswith("Test_TC_APBSC_") or name.startswith("Test_TC_CONTENTLAUNCHER_") or name.startswith("Test_TC_ALOGIN_"):
return TestTarget.TV
if name.startswith("DL_") or name.startswith("Test_TC_DLRK_"):
if name.startswith("DL_") or name.startswith("Test_TC_DRLK_"):
return TestTarget.LOCK
if name.startswith("OTA_"):
return TestTarget.OTA
Expand Down
37 changes: 19 additions & 18 deletions src/app/clusters/door-lock-server/door-lock-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app-common/zap-generated/callback.h>
#include <app-common/zap-generated/cluster-id.h>
#include <app-common/zap-generated/command-id.h>
#include <app/EventLogging.h>
#include <app/server/Server.h>
#include <app/util/af-event.h>
Expand All @@ -35,7 +34,6 @@
#include <app/CommandHandler.h>
#include <app/ConcreteAttributePath.h>
#include <app/ConcreteCommandPath.h>
#include <app/EventLogging.h>
#include <lib/support/CodeUtils.h>

using namespace chip;
Expand Down Expand Up @@ -385,7 +383,7 @@ void DoorLockServer::getUserCommandHandler(chip::app::CommandHandler * commandOb
SuccessOrExit(err = writer->Put(TLV::ContextTag(to_underlying(ResponseFields::kUserStatus)), user.userStatus));
SuccessOrExit(err = writer->Put(TLV::ContextTag(to_underlying(ResponseFields::kUserType)), user.userType));
SuccessOrExit(err = writer->Put(TLV::ContextTag(to_underlying(ResponseFields::kCredentialRule)), user.credentialRule));
if (user.credentials.size() > 0)
if (!user.credentials.empty())
{
TLV::TLVType credentialsContainer;
SuccessOrExit(err = writer->StartContainer(TLV::ContextTag(to_underlying(ResponseFields::kCredentials)),
Expand Down Expand Up @@ -797,7 +795,7 @@ void DoorLockServer::setWeekDayScheduleCommandHandler(chip::app::CommandHandler
uint8_t startHour, uint8_t startMinute, uint8_t endHour, uint8_t endMinute)
{
auto endpointId = commandPath.mEndpointId;
if (!SupportsSchedules(endpointId))
if (!SupportsWeekDaySchedules(endpointId))
{
emberAfDoorLockClusterPrintln("[SetWeekDaySchedule] Ignore command (not supported) [endpointId=%d]", endpointId);
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_COMMAND);
Expand Down Expand Up @@ -905,7 +903,7 @@ void DoorLockServer::getWeekDayScheduleCommandHandler(chip::app::CommandHandler
uint16_t userIndex)
{
auto endpointId = commandPath.mEndpointId;
if (!SupportsSchedules(endpointId))
if (!SupportsWeekDaySchedules(endpointId))
{
emberAfDoorLockClusterPrintln("[GetWeekDaySchedule] Ignore command (not supported) [endpointId=%d]", endpointId);
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_COMMAND);
Expand Down Expand Up @@ -948,7 +946,7 @@ void DoorLockServer::clearWeekDayScheduleCommandHandler(chip::app::CommandHandle
uint16_t userIndex)
{
auto endpointId = commandPath.mEndpointId;
if (!SupportsSchedules(endpointId))
if (!SupportsWeekDaySchedules(endpointId))
{
emberAfDoorLockClusterPrintln("[ClearWeekDaySchedule] Ignore command (not supported) [endpointId=%d]", endpointId);
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_COMMAND);
Expand Down Expand Up @@ -1025,7 +1023,7 @@ void DoorLockServer::setYearDayScheduleCommandHandler(chip::app::CommandHandler
uint16_t userIndex, uint32_t localStartTime, uint32_t localEndTime)
{
auto endpointId = commandPath.mEndpointId;
if (!SupportsSchedules(endpointId))
if (!SupportsYearDaySchedules(endpointId))
{
emberAfDoorLockClusterPrintln("[SetYearDaySchedule] Ignore command (not supported) [endpointId=%d]", endpointId);
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_COMMAND);
Expand Down Expand Up @@ -1105,7 +1103,7 @@ void DoorLockServer::getYearDayScheduleCommandHandler(chip::app::CommandHandler
uint16_t userIndex)
{
auto endpointId = commandPath.mEndpointId;
if (!SupportsSchedules(endpointId))
if (!SupportsYearDaySchedules(endpointId))
{
emberAfDoorLockClusterPrintln("[GetYearDaySchedule] Ignore command (not supported) [endpointId=%d]", endpointId);
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_COMMAND);
Expand Down Expand Up @@ -1147,7 +1145,7 @@ void DoorLockServer::clearYearDayScheduleCommandHandler(chip::app::CommandHandle
uint16_t userIndex)
{
auto endpointId = commandPath.mEndpointId;
if (!SupportsSchedules(endpointId))
if (!SupportsYearDaySchedules(endpointId))
{
emberAfDoorLockClusterPrintln("[ClearYearDaySchedule] Ignore command (not supported) [endpointId=%d]", endpointId);
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_COMMAND);
Expand Down Expand Up @@ -1218,12 +1216,15 @@ void DoorLockServer::clearYearDayScheduleCommandHandler(chip::app::CommandHandle
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
}

bool DoorLockServer::HasFeature(chip::EndpointId endpointId, DoorLockFeature feature)
chip::BitFlags<DoorLockFeature> DoorLockServer::GetFeatures(chip::EndpointId endpointId)
{
uint32_t featureMap = 0;
bool success = GetAttribute(endpointId, Attributes::FeatureMap::Id, Attributes::FeatureMap::Get, featureMap);

return success && ((featureMap & to_underlying(feature)) != 0);
chip::BitFlags<DoorLockFeature> featureMap;
if (!GetAttribute(endpointId, Attributes::FeatureMap::Id, Attributes::FeatureMap::Get, *featureMap.RawStorage()))
{
ChipLogError(Zcl, "Unable to get the door lock feature map: attribute read error");
featureMap.ClearAll();
}
return featureMap;
}

bool DoorLockServer::OnFabricRemoved(chip::EndpointId endpointId, chip::FabricIndex fabricIndex)
Expand Down Expand Up @@ -2955,7 +2956,7 @@ void DoorLockServer::setHolidayScheduleCommandHandler(chip::app::CommandHandler
VerifyOrDie(nullptr != commandObj);

auto endpointId = commandPath.mEndpointId;
if (!SupportsSchedules(endpointId))
if (!SupportsHolidaySchedules(endpointId))
{
emberAfDoorLockClusterPrintln("[SetHolidaySchedule] Ignore command (not supported) [endpointId=%d]", endpointId);
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_COMMAND);
Expand Down Expand Up @@ -3014,7 +3015,7 @@ void DoorLockServer::getHolidayScheduleCommandHandler(chip::app::CommandHandler
const ConcreteCommandPath & commandPath, uint8_t holidayIndex)
{
auto endpointId = commandPath.mEndpointId;
if (!SupportsSchedules(endpointId))
if (!SupportsHolidaySchedules(endpointId))
{
emberAfDoorLockClusterPrintln("[GetHolidaySchedule] Ignore command (not supported) [endpointId=%d,scheduleIndex=%d]",
endpointId, holidayIndex);
Expand Down Expand Up @@ -3048,7 +3049,7 @@ void DoorLockServer::clearHolidayScheduleCommandHandler(chip::app::CommandHandle
const chip::app::ConcreteCommandPath & commandPath, uint8_t holidayIndex)
{
auto endpointId = commandPath.mEndpointId;
if (!SupportsSchedules(endpointId))
if (!SupportsHolidaySchedules(endpointId))
{
emberAfDoorLockClusterPrintln("[ClearHolidaySchedule] Ignore command (not supported) [endpointId=%d]", endpointId);
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_COMMAND);
Expand Down Expand Up @@ -3138,7 +3139,7 @@ bool DoorLockServer::HandleRemoteLockOperation(chip::app::CommandHandler * comma
// [EM]: I don't think we should prevent door lock/unlocking if we couldn't find credential associated with user. I
// think if the app thinks that PIN is correct the door should be unlocked.
//
// [DV]: let's app decide on PIN correctness, we will fail only if 'opHandler' returns false.
// [DV]: let app decide on PIN correctness, we will fail only if 'opHandler' returns false.
credentialsOk =
true; // findUserIndexByCredential(endpoint, DlCredentialType::kPin, pinCode.Value(), pinUserIdx, pinCredIdx);
}
Expand Down
40 changes: 31 additions & 9 deletions src/app/clusters/door-lock-server/door-lock-server.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,28 +117,50 @@ class DoorLockServer
bool GetNumberOfCredentialsSupportedPerUser(chip::EndpointId endpointId, uint8_t & numberOfCredentialsSupportedPerUser);
bool GetNumberOfHolidaySchedulesSupported(chip::EndpointId endpointId, uint8_t & numberOfHolidaySchedules);

bool HasFeature(chip::EndpointId endpointId, DoorLockFeature feature);
chip::BitFlags<DoorLockFeature> GetFeatures(chip::EndpointId endpointId);

inline bool SupportsPIN(chip::EndpointId endpointId) { return HasFeature(endpointId, DoorLockFeature::kPINCredentials); }
inline bool SupportsPIN(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(DoorLockFeature::kPINCredentials); }

inline bool SupportsRFID(chip::EndpointId endpointId) { return HasFeature(endpointId, DoorLockFeature::kRFIDCredentials); }
inline bool SupportsRFID(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(DoorLockFeature::kRFIDCredentials); }

inline bool SupportsFingers(chip::EndpointId endpointId) { return HasFeature(endpointId, DoorLockFeature::kFingerCredentials); }
inline bool SupportsFingers(chip::EndpointId endpointId)
{
return GetFeatures(endpointId).Has(DoorLockFeature::kFingerCredentials);
}

inline bool SupportsFace(chip::EndpointId endpointId) { return HasFeature(endpointId, DoorLockFeature::kFaceCredentials); }
inline bool SupportsFace(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(DoorLockFeature::kFaceCredentials); }

inline bool SupportsSchedules(chip::EndpointId endpointId) { return HasFeature(endpointId, DoorLockFeature::kAccessSchedules); }
inline bool SupportsWeekDaySchedules(chip::EndpointId endpointId)
{
return GetFeatures(endpointId).Has(DoorLockFeature::kWeekDaySchedules);
}

inline bool SupportsYearDaySchedules(chip::EndpointId endpointId)
{
return GetFeatures(endpointId).Has(DoorLockFeature::kYearDaySchedules);
}

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

inline bool SupportsAnyCredential(chip::EndpointId endpointId)
{
return GetFeatures(endpointId)
.HasAny(DoorLockFeature::kPINCredentials, DoorLockFeature::kRFIDCredentials, DoorLockFeature::kFingerCredentials,
DoorLockFeature::kFaceCredentials);
}

inline bool SupportsCredentialsOTA(chip::EndpointId endpointId)
{
return HasFeature(endpointId, DoorLockFeature::kCredentialsOTA);
return GetFeatures(endpointId).Has(DoorLockFeature::kCredentialsOTA);
}

inline bool SupportsUSR(chip::EndpointId endpointId)
{
// appclusters, 5.2.2: USR feature has conformance [PIN | RID | FGP | FACE]
// TODO: Add missing functions to check if RID, FGP or FACE are supported
return HasFeature(endpointId, DoorLockFeature::kUsersManagement) && SupportsPIN(endpointId);
return GetFeatures(endpointId).Has(DoorLockFeature::kUsersManagement) && SupportsAnyCredential(endpointId);
}

bool OnFabricRemoved(chip::EndpointId endpointId, chip::FabricIndex fabricIndex);
Expand Down
Loading

0 comments on commit 4128817

Please sign in to comment.