Skip to content

Commit

Permalink
Fix incorrect return codes in door lock cluster (#19813) (#20433)
Browse files Browse the repository at this point in the history
* [#19622] Return generic failure instead of not found for schedule operations in the door lock

* [#19563] Check enum ranges for Door Lock commands
- Refactor the cluster, so it is consistent in way of handling commands

* Refactoring of the door lock cluster: move credential error checking into a single function, fix typos

* Fix tests for Door Lock cluster and run them against the lock app

* Update auto-generated files

Co-authored-by: Evgeniy Morozov <[email protected]>
  • Loading branch information
woody-apple and Morozov-5F authored Jul 7, 2022
1 parent e882f2b commit 0f0ddcf
Show file tree
Hide file tree
Showing 8 changed files with 350 additions and 281 deletions.
28 changes: 17 additions & 11 deletions scripts/tests/chiptest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,34 @@


def target_for_name(name: str):
if name.startswith('TV_') or name.startswith('Test_TC_MC_'):
if name.startswith("TV_") or name.startswith("Test_TC_MC_"):
return TestTarget.TV
if name.startswith('DL_') or name.startswith('Test_TC_DL_'):
if name.startswith("DL_") or name.startswith("Test_TC_DLRK_"):
return TestTarget.LOCK
if name.startswith('OTA_'):
if name.startswith("OTA_"):
return TestTarget.OTA
return TestTarget.ALL_CLUSTERS


def tests_with_command(chip_tool: str, is_manual: bool):
"""Executes `chip_tool` binary to see what tests are available, using cmd
to get the list.
to get the list.
"""
cmd = 'list'
cmd = "list"
if is_manual:
cmd += '-manual'
cmd += "-manual"

result = subprocess.run([chip_tool, 'tests', cmd], capture_output=True)
result = subprocess.run([chip_tool, "tests", cmd], capture_output=True)

for name in result.stdout.decode('utf8').split('\n'):
for name in result.stdout.decode("utf8").split("\n"):
if not name:
continue

target = target_for_name(name)

yield TestDefinition(run_name=name, name=name, target=target, is_manual=is_manual)
yield TestDefinition(
run_name=name, name=name, target=target, is_manual=is_manual
)


def AllTests(chip_tool: str):
Expand All @@ -58,6 +60,10 @@ def AllTests(chip_tool: str):


__all__ = [
'TestTarget', 'TestDefinition', 'AllTests', 'ApplicationPaths',
'linux', 'runner',
"TestTarget",
"TestDefinition",
"AllTests",
"ApplicationPaths",
"linux",
"runner",
]
337 changes: 172 additions & 165 deletions src/app/clusters/door-lock-server/door-lock-server.cpp

Large diffs are not rendered by default.

159 changes: 108 additions & 51 deletions src/app/clusters/door-lock-server/door-lock-server.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,45 +117,6 @@ class DoorLockServer
bool GetNumberOfCredentialsSupportedPerUser(chip::EndpointId endpointId, uint8_t & numberOfCredentialsSupportedPerUser);
bool GetNumberOfHolidaySchedulesSupported(chip::EndpointId endpointId, uint8_t & numberOfHolidaySchedules);

void SetUserCommandHandler(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::SetUser::DecodableType & commandData);

void GetUserCommandHandler(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::GetUser::DecodableType & commandData);

void ClearUserCommandHandler(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::ClearUser::DecodableType & commandData);

void SetCredentialCommandHandler(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::SetCredential::DecodableType & commandData);

void GetCredentialStatusCommandHandler(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::GetCredentialStatus::DecodableType & commandData);

void ClearCredentialCommandHandler(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::ClearCredential::DecodableType & commandData);

void SetWeekDayScheduleCommandHandler(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::SetWeekDaySchedule::DecodableType & commandData);
void GetWeekDayScheduleCommandHandler(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::GetWeekDaySchedule::DecodableType & commandData);
void ClearWeekDayScheduleCommandHandler(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::ClearWeekDaySchedule::DecodableType & commandData);

void SetYearDayScheduleCommandHandler(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::SetYearDaySchedule::DecodableType & commandData);
void GetYearDayScheduleCommandHandler(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::GetYearDaySchedule::DecodableType & commandData);
void ClearYearDayScheduleCommandHandler(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::ClearYearDaySchedule::DecodableType & commandData);

bool HasFeature(chip::EndpointId endpointId, DoorLockFeature feature);

inline bool SupportsPIN(chip::EndpointId endpointId) { return HasFeature(endpointId, DoorLockFeature::kPINCredentials); }
Expand Down Expand Up @@ -193,7 +154,7 @@ class DoorLockServer
bool credentialIndexValid(chip::EndpointId endpointId, DlCredentialType type, uint16_t credentialIndex);
bool credentialIndexValid(chip::EndpointId endpointId, DlCredentialType type, uint16_t credentialIndex,
uint16_t & maxNumberOfCredentials);
bool getCredentialRange(chip::EndpointId endpointId, DlCredentialType type, size_t & minSize, size_t & maxSize);
DlStatus credentialLengthWithinRange(chip::EndpointId endpointId, DlCredentialType type, const chip::ByteSpan & credentialData);
bool getMaxNumberOfCredentials(chip::EndpointId endpointId, DlCredentialType credentialType, uint16_t & maxNumberOfCredentials);

bool findOccupiedUserSlot(chip::EndpointId endpointId, uint16_t startIndex, uint16_t & userIndex);
Expand Down Expand Up @@ -263,10 +224,12 @@ class DoorLockServer
bool clearFabricFromCredentials(chip::EndpointId endpointId, DlCredentialType credentialType, chip::FabricIndex fabricToRemove);
bool clearFabricFromCredentials(chip::EndpointId endpointId, chip::FabricIndex fabricToRemove);

CHIP_ERROR sendSetCredentialResponse(chip::app::CommandHandler * commandObj, DlStatus status, uint16_t userIndex,
uint16_t nextCredentialIndex);
void sendSetCredentialResponse(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
DlStatus status, uint16_t userIndex, uint16_t nextCredentialIndex);

// TODO: Maybe use CHIP_APPLICATION_ERROR instead of boolean in class methods?
// OPTIMIZE: there are a lot of methods such as this that could be made static which could help reduce the stack footprint
// in case of multiple lock endpoints
bool credentialTypeSupported(chip::EndpointId endpointId, DlCredentialType type);

bool weekDayIndexValid(chip::EndpointId endpointId, uint8_t weekDayIndex);
Expand Down Expand Up @@ -304,14 +267,57 @@ class DoorLockServer

DlLockDataType credentialTypeToLockDataType(DlCredentialType credentialType);

void setHolidaySchedule(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
uint8_t holidayIndex, uint32_t localStartTime, uint32_t localEndTime, DlOperatingMode operatingMode);
void setUserCommandHandler(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::SetUser::DecodableType & commandData);

void getUserCommandHandler(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
uint16_t userIndex);

void clearUserCommandHandler(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
uint16_t userIndex);

void setCredentialCommandHandler(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::SetCredential::DecodableType & commandData);

void getCredentialStatusCommandHandler(chip::app::CommandHandler * commandObj,
const chip::app::ConcreteCommandPath & commandPath, DlCredentialType credentialType,
uint16_t credentialIndex);

void clearCredentialCommandHandler(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::ClearCredential::DecodableType & commandData);

void setWeekDayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
const chip::app::ConcreteCommandPath & commandPath, uint8_t weekDayIndex,
uint16_t userIndex, const chip::BitMask<DlDaysMaskMap> & daysMask, uint8_t startHour,
uint8_t startMinute, uint8_t endHour, uint8_t endMinute);

void getWeekDayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
const chip::app::ConcreteCommandPath & commandPath, uint8_t weekDayIndex,
uint16_t userIndex);

void clearWeekDayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
const chip::app::ConcreteCommandPath & commandPath, uint8_t weekDayIndex,
uint16_t userIndex);

void setYearDayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
const chip::app::ConcreteCommandPath & commandPath, uint8_t yearDayIndex,
uint16_t userIndex, uint32_t localStartTime, uint32_t localEndTime);
void getYearDayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
const chip::app::ConcreteCommandPath & commandPath, uint8_t yearDayIndex,
uint16_t userIndex);
void clearYearDayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
const chip::app::ConcreteCommandPath & commandPath, uint8_t yearDayIndex,
uint16_t userIndex);

void setHolidayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
const chip::app::ConcreteCommandPath & commandPath, uint8_t holidayIndex,
uint32_t localStartTime, uint32_t localEndTime, DlOperatingMode operatingMode);

void getHolidaySchedule(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
uint8_t holidayIndex);
void getHolidayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
const chip::app::ConcreteCommandPath & commandPath, uint8_t holidayIndex);

void clearHolidaySchedule(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
uint8_t holidayIndex);
void clearHolidayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
const chip::app::ConcreteCommandPath & commandPath, uint8_t holidayIndex);

bool RemoteOperationEnabled(chip::EndpointId endpointId) const;

Expand All @@ -323,8 +329,8 @@ class DoorLockServer
* @param opType remote operation type (lock, unlock)
* @param opHandler plugin handler for specified command
* @param pinCode pin code passed by client
* @return true if locking/unlocking was successfull
* @return false if error happenned during lock/unlock
* @return true if locking/unlocking was successful
* @return false if error happened during lock/unlock
*/
bool HandleRemoteLockOperation(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
DlLockOperationType opType, RemoteLockOpHandler opHandler,
Expand All @@ -342,7 +348,7 @@ class DoorLockServer
* @param nodeId node id
* @param credList list of credentials used in lock operation (can be NULL if no credentials were used)
* @param credListSize size of credentials list (if 0, then no credentials were used)
* @param opSuccess flags if operation was successfull or not
* @param opSuccess flags if operation was successful or not
*/
void SendLockOperationEvent(chip::EndpointId endpointId, DlLockOperationType opType, DlOperationSource opSource,
DlOperationError opErr, const Nullable<uint16_t> & userId,
Expand Down Expand Up @@ -424,6 +430,57 @@ class DoorLockServer
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::ClearHolidaySchedule::DecodableType & commandData);

friend bool
emberAfDoorLockClusterSetUserCallback(chip::app::CommandHandler * commandObj,
const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::SetUser::DecodableType & commandData);

friend bool
emberAfDoorLockClusterGetUserCallback(chip::app::CommandHandler * commandObj,
const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::GetUser::DecodableType & commandData);

friend bool
emberAfDoorLockClusterClearUserCallback(chip::app::CommandHandler * commandObj,
const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::ClearUser::DecodableType & commandData);

friend bool emberAfDoorLockClusterSetCredentialCallback(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::SetCredential::DecodableType & commandData);

friend bool emberAfDoorLockClusterGetCredentialStatusCallback(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::GetCredentialStatus::DecodableType & commandData);

friend bool emberAfDoorLockClusterClearCredentialCallback(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::ClearCredential::DecodableType & commandData);

friend bool emberAfDoorLockClusterSetWeekDayScheduleCallback(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::SetWeekDaySchedule::DecodableType & commandData);

friend bool emberAfDoorLockClusterGetWeekDayScheduleCallback(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::GetWeekDaySchedule::DecodableType & commandData);

friend bool emberAfDoorLockClusterClearWeekDayScheduleCallback(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::ClearWeekDaySchedule::DecodableType & commandData);

friend bool emberAfDoorLockClusterSetYearDayScheduleCallback(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::SetYearDaySchedule::DecodableType & commandData);

friend bool emberAfDoorLockClusterGetYearDayScheduleCallback(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::GetYearDaySchedule::DecodableType & commandData);

friend bool emberAfDoorLockClusterClearYearDayScheduleCallback(
chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
const chip::app::Clusters::DoorLock::Commands::ClearYearDaySchedule::DecodableType & commandData);

EmberEventControl AutolockEvent; /**< for automatic relock scheduling */

static DoorLockServer instance;
Expand Down
2 changes: 1 addition & 1 deletion src/app/tests/suites/DL_LockUnlock.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ tests:
response:
value: 2

- label: "Try to unlock the door without a PIN"
- label: "Try to lock the door without a PIN"
command: "LockDoor"
timedInteractionTimeoutMs: 10000

Expand Down
Loading

0 comments on commit 0f0ddcf

Please sign in to comment.