diff --git a/examples/lock-app/infineon/cyw30739/include/AppEvent.h b/examples/lock-app/infineon/cyw30739/include/AppEvent.h index 60583eba2c2123..0703bb86878a02 100644 --- a/examples/lock-app/infineon/cyw30739/include/AppEvent.h +++ b/examples/lock-app/infineon/cyw30739/include/AppEvent.h @@ -29,6 +29,7 @@ struct AppEvent kEventType_Timer, kEventType_Lock, kEventType_Install, + kEventType_app, }; uint16_t Type; diff --git a/examples/lock-app/infineon/cyw30739/include/LockManager.h b/examples/lock-app/infineon/cyw30739/include/LockManager.h index 1cf92b5efe5de1..4bf738182d47b9 100644 --- a/examples/lock-app/infineon/cyw30739/include/LockManager.h +++ b/examples/lock-app/infineon/cyw30739/include/LockManager.h @@ -26,6 +26,24 @@ #include #include +struct WeekDaysScheduleInfo +{ + DlScheduleStatus status; + EmberAfPluginDoorLockWeekDaySchedule schedule; +}; + +struct YearDayScheduleInfo +{ + DlScheduleStatus status; + EmberAfPluginDoorLockYearDaySchedule schedule; +}; + +struct HolidayScheduleInfo +{ + DlScheduleStatus status; + EmberAfPluginDoorLockHolidaySchedule schedule; +}; + namespace CYW30739DoorLock { namespace ResourceRanges { // Used to size arrays @@ -113,13 +131,6 @@ class LockManager kState_UnlockCompleted, } State; - enum Actor_t - { - ACTOR_ZCL_CMD = 0, - ACTOR_APP_CMD, - ACTOR_BUTTON, - } Actor; - CHIP_ERROR Init(chip::app::DataModel::Nullable state, CYW30739DoorLock::LockInitParams::LockParam lockParam); bool NextState(); @@ -138,6 +149,10 @@ class LockManager const chip::CharSpan & userName, uint32_t uniqueId, DlUserStatus userStatus, DlUserType usertype, DlCredentialRule credentialRule, const DlCredential * credentials, size_t totalCredentials); + bool SetDoorState(chip::EndpointId endpointId, DlDoorState newState); + + DlDoorState GetDoorState() const; + bool GetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, DlCredentialType credentialType, EmberAfPluginDoorLockCredentialInfo & credential); @@ -169,6 +184,7 @@ class LockManager bool setLockState(chip::EndpointId endpointId, DlLockState lockState, const Optional & pin, DlOperationError & err); + const char * lockStateToString(DlLockState lockState) const; bool ReadConfigValues(); @@ -177,6 +193,7 @@ class LockManager friend LockManager & LockMgr(); chip::EndpointId mEndpointId; State_t mState; + DlDoorState mDoorState; Callback_fn_initiated mActionInitiated_CB; Callback_fn_completed mActionCompleted_CB; @@ -189,10 +206,9 @@ class LockManager EmberAfPluginDoorLockUserInfo mLockUsers[kMaxUsers]; EmberAfPluginDoorLockCredentialInfo mLockCredentials[kMaxCredentials]; - EmberAfPluginDoorLockWeekDaySchedule mWeekdaySchedule[kMaxUsers][kMaxWeekdaySchedulesPerUser]; - EmberAfPluginDoorLockYearDaySchedule mYeardaySchedule[kMaxUsers][kMaxYeardaySchedulesPerUser]; - EmberAfPluginDoorLockHolidaySchedule mHolidaySchedule[kMaxHolidaySchedules]; - + WeekDaysScheduleInfo mWeekdaySchedule[kMaxUsers][kMaxWeekdaySchedulesPerUser]; + YearDayScheduleInfo mYeardaySchedule[kMaxUsers][kMaxYeardaySchedulesPerUser]; + HolidayScheduleInfo mHolidaySchedule[kMaxHolidaySchedules]; char mUserNames[ArraySize(mLockUsers)][DOOR_LOCK_MAX_USER_NAME_SIZE]; uint8_t mCredentialData[kMaxCredentials][kMaxCredentialSize]; DlCredential mCredentials[kMaxUsers][kMaxCredentialsPerUser]; diff --git a/examples/lock-app/infineon/cyw30739/src/AppShellCommands.cpp b/examples/lock-app/infineon/cyw30739/src/AppShellCommands.cpp index beb21c26c4c023..bd5e301259e81d 100644 --- a/examples/lock-app/infineon/cyw30739/src/AppShellCommands.cpp +++ b/examples/lock-app/infineon/cyw30739/src/AppShellCommands.cpp @@ -29,6 +29,8 @@ static CHIP_ERROR AppCommandDispatch(int argc, char * argv[]); static chip::Shell::Engine sAppSubcommands; +chip::EndpointId endpointId = DOOR_LOCK_SERVER_ENDPOINT; + void RegisterAppShellCommands(void) { static const shell_command_t sAppSubCommands[] = { @@ -70,20 +72,30 @@ CHIP_ERROR AppCommandLockHandler(int argc, char * argv[]) else if (strcmp(argv[0], "on") == 0) { streamer_printf(streamer_get(), "Lock ...\n"); - LockMgr().InitiateAction(LockManager::ACTOR_APP_CMD, LockManager::LOCK_ACTION); + LockMgr().InitiateAction(AppEvent::kEventType_app, LockManager::LOCK_ACTION); } else if (strcmp(argv[0], "off") == 0) { streamer_printf(streamer_get(), "Unlock ...\n"); - LockMgr().InitiateAction(LockManager::ACTOR_BUTTON, LockManager::UNLOCK_ACTION); + LockMgr().InitiateAction(AppEvent::kEventType_app, LockManager::UNLOCK_ACTION); } else if (strcmp(argv[0], "toggle") == 0) { streamer_printf(streamer_get(), "Toggling the lock ...\n"); if (LockMgr().NextState()) - LockMgr().InitiateAction(LockManager::ACTOR_APP_CMD, LockManager::LOCK_ACTION); + LockMgr().InitiateAction(AppEvent::kEventType_app, LockManager::LOCK_ACTION); else - LockMgr().InitiateAction(LockManager::ACTOR_BUTTON, LockManager::UNLOCK_ACTION); + LockMgr().InitiateAction(AppEvent::kEventType_app, LockManager::UNLOCK_ACTION); + } + else if (strcmp(argv[0], "open") == 0) + { + streamer_printf(streamer_get(), "open ...\n"); + LockMgr().SetDoorState(endpointId, DlDoorState::kDoorOpen); + } + else if (strcmp(argv[0], "close") == 0) + { + streamer_printf(streamer_get(), "close ...\n"); + LockMgr().SetDoorState(endpointId, DlDoorState::kDoorClosed); } else { diff --git a/examples/lock-app/infineon/cyw30739/src/ButtonHandler.cpp b/examples/lock-app/infineon/cyw30739/src/ButtonHandler.cpp index 94f85a1b6259ab..7730b6ccf64f01 100644 --- a/examples/lock-app/infineon/cyw30739/src/ButtonHandler.cpp +++ b/examples/lock-app/infineon/cyw30739/src/ButtonHandler.cpp @@ -93,10 +93,9 @@ void app_button_event_handler(const button_manager_button_t * button_mgr, button { err = CHIP_ERROR_UNEXPECTED_EVENT; } - if (err == CHIP_NO_ERROR) { - initiated = LockMgr().InitiateAction(LockManager::ACTOR_BUTTON, action); + initiated = LockMgr().InitiateAction(AppEvent::kEventType_Button, action); if (!initiated) { diff --git a/examples/lock-app/infineon/cyw30739/src/LockManager.cpp b/examples/lock-app/infineon/cyw30739/src/LockManager.cpp index 14f19ab58116f1..d434e94924c3a4 100644 --- a/examples/lock-app/infineon/cyw30739/src/LockManager.cpp +++ b/examples/lock-app/infineon/cyw30739/src/LockManager.cpp @@ -33,7 +33,6 @@ using namespace CYW30739DoorLock::LockInitParams; CHIP_ERROR LockManager::Init(chip::app::DataModel::Nullable state, LockParam lockParam) { LockParams = lockParam; - if (LockParams.numberOfUsers > kMaxUsers) { ChipLogError(Zcl, @@ -448,7 +447,6 @@ bool LockManager::SetCredential(chip::EndpointId endpointId, uint16_t credential chip::FabricIndex modifier, DlCredentialStatus credentialStatus, DlCredentialType credentialType, const chip::ByteSpan & credentialData) { - VerifyOrReturnValue(credentialIndex > 0, false); // indices are one-indexed credentialIndex--; @@ -495,7 +493,13 @@ DlStatus LockManager::GetWeekdaySchedule(chip::EndpointId endpointId, uint8_t we VerifyOrReturnValue(IsValidWeekdayScheduleIndex(weekdayIndex), DlStatus::kFailure); VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure); - schedule = mWeekdaySchedule[userIndex][weekdayIndex]; + const auto & scheduleInStorage = mWeekdaySchedule[userIndex][weekdayIndex]; + if (DlScheduleStatus::kAvailable == scheduleInStorage.status) + { + return DlStatus::kNotFound; + } + + schedule = scheduleInStorage.schedule; return DlStatus::kSuccess; } @@ -516,11 +520,12 @@ DlStatus LockManager::SetWeekdaySchedule(chip::EndpointId endpointId, uint8_t we auto & scheduleInStorage = mWeekdaySchedule[userIndex][weekdayIndex]; - scheduleInStorage.daysMask = daysMask; - scheduleInStorage.startHour = startHour; - scheduleInStorage.startMinute = startMinute; - scheduleInStorage.endHour = endHour; - scheduleInStorage.endMinute = endMinute; + scheduleInStorage.schedule.daysMask = daysMask; + scheduleInStorage.schedule.startHour = startHour; + scheduleInStorage.schedule.startMinute = startMinute; + scheduleInStorage.schedule.endHour = endHour; + scheduleInStorage.schedule.endMinute = endMinute; + scheduleInStorage.status = status; // Save schedule information in NVM flash CYW30739Config::WriteConfigValueBin( @@ -542,9 +547,13 @@ DlStatus LockManager::GetYeardaySchedule(chip::EndpointId endpointId, uint8_t ye VerifyOrReturnValue(IsValidYeardayScheduleIndex(yearDayIndex), DlStatus::kFailure); VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure); - auto & scheduleInStorage = mYeardaySchedule[userIndex][yearDayIndex]; + const auto & scheduleInStorage = mYeardaySchedule[userIndex][yearDayIndex]; + if (DlScheduleStatus::kAvailable == scheduleInStorage.status) + { + return DlStatus::kNotFound; + } - schedule = scheduleInStorage; + schedule = scheduleInStorage.schedule; return DlStatus::kSuccess; } @@ -563,8 +572,9 @@ DlStatus LockManager::SetYeardaySchedule(chip::EndpointId endpointId, uint8_t ye auto & scheduleInStorage = mYeardaySchedule[userIndex][yearDayIndex]; - scheduleInStorage.localStartTime = localStartTime; - scheduleInStorage.localEndTime = localEndTime; + scheduleInStorage.schedule.localStartTime = localStartTime; + scheduleInStorage.schedule.localEndTime = localEndTime; + scheduleInStorage.status = status; // Save schedule information in NVM flash CYW30739Config::WriteConfigValueBin( @@ -583,9 +593,13 @@ DlStatus LockManager::GetHolidaySchedule(chip::EndpointId endpointId, uint8_t ho VerifyOrReturnValue(IsValidHolidayScheduleIndex(holidayIndex), DlStatus::kFailure); - auto & scheduleInStorage = mHolidaySchedule[holidayIndex]; + const auto & scheduleInStorage = mHolidaySchedule[holidayIndex]; + if (DlScheduleStatus::kAvailable == scheduleInStorage.status) + { + return DlStatus::kNotFound; + } - schedule = scheduleInStorage; + schedule = scheduleInStorage.schedule; return DlStatus::kSuccess; } @@ -601,9 +615,10 @@ DlStatus LockManager::SetHolidaySchedule(chip::EndpointId endpointId, uint8_t ho auto & scheduleInStorage = mHolidaySchedule[holidayIndex]; - scheduleInStorage.localStartTime = localStartTime; - scheduleInStorage.localEndTime = localEndTime; - scheduleInStorage.operatingMode = operatingMode; + scheduleInStorage.schedule.localStartTime = localStartTime; + scheduleInStorage.schedule.localEndTime = localEndTime; + scheduleInStorage.schedule.operatingMode = operatingMode; + scheduleInStorage.status = status; // Save schedule information in NVM flash CYW30739Config::WriteConfigValueBin(CYW30739Config::kConfigKey_HolidaySchedules, @@ -633,24 +648,6 @@ const char * LockManager::lockStateToString(DlLockState lockState) const bool LockManager::setLockState(chip::EndpointId endpointId, DlLockState lockState, const Optional & pin, DlOperationError & err) { - DlLockState curState = DlLockState::kLocked; - if (mState == kState_UnlockCompleted) - curState = DlLockState::kUnlocked; - - if ((curState == lockState) && (curState == DlLockState::kLocked)) - { - ChipLogDetail(Zcl, "Door Lock App: door is already locked, ignoring command to set lock state to \"%s\" [endpointId=%d]", - lockStateToString(lockState), endpointId); - return true; - } - else if ((curState == lockState) && (curState == DlLockState::kUnlocked)) - { - ChipLogDetail(Zcl, - "Door Lock App: door is already unlocked, ignoring command to set unlock state to \"%s\" [endpointId=%d]", - lockStateToString(lockState), endpointId); - return true; - } - // Assume pin is required until told otherwise bool requirePin = true; chip::app::Clusters::DoorLock::Attributes::RequirePINforRemoteOperation::Get(endpointId, &requirePin); @@ -658,18 +655,21 @@ bool LockManager::setLockState(chip::EndpointId endpointId, DlLockState lockStat // If a pin code is not given if (!pin.HasValue()) { - ChipLogDetail(Zcl, "Door Lock App: PIN code is not specified, but it is required [endpointId=%d]", mEndpointId); - curState = lockState; + ChipLogDetail(Zcl, "Door Lock App: PIN code is not specified [endpointId=%d]", endpointId); // If a pin code is not required if (!requirePin) { ChipLogDetail(Zcl, "Door Lock App: setting door lock state to \"%s\" [endpointId=%d]", lockStateToString(lockState), endpointId); - curState = lockState; + + DoorLockServer::Instance().SetLockState(endpointId, lockState); + return true; } + ChipLogError(Zcl, "Door Lock App: PIN code is not specified, but it is required [endpointId=%d]", endpointId); + return false; } @@ -686,9 +686,9 @@ bool LockManager::setLockState(chip::EndpointId endpointId, DlLockState lockStat { ChipLogDetail(Zcl, "Lock App: specified PIN code was found in the database, setting lock state to \"%s\" [endpointId=%d]", - lockStateToString(lockState), mEndpointId); + lockStateToString(lockState), endpointId); - curState = lockState; + DoorLockServer::Instance().SetLockState(endpointId, lockState); return true; } @@ -697,8 +697,21 @@ bool LockManager::setLockState(chip::EndpointId endpointId, DlLockState lockStat ChipLogDetail(Zcl, "Door Lock App: specified PIN code was not found in the database, ignoring command to set lock state to \"%s\" " "[endpointId=%d]", - lockStateToString(lockState), mEndpointId); + lockStateToString(lockState), endpointId); err = DlOperationError::kInvalidCredential; return false; } + +bool LockManager::SetDoorState(chip::EndpointId endpointId, DlDoorState newState) +{ + if (mDoorState != newState) + { + ChipLogProgress(Zcl, "Changing the door state to: %d [endpointId=%d,previousState=%d]", to_underlying(newState), endpointId, + to_underlying(mDoorState)); + + mDoorState = newState; + return DoorLockServer::Instance().SetDoorState(endpointId, mDoorState); + } + return true; +} diff --git a/examples/lock-app/infineon/cyw30739/src/ZclCallbacks.cpp b/examples/lock-app/infineon/cyw30739/src/ZclCallbacks.cpp index 26c245db77b944..d092def7f63db9 100644 --- a/examples/lock-app/infineon/cyw30739/src/ZclCallbacks.cpp +++ b/examples/lock-app/infineon/cyw30739/src/ZclCallbacks.cpp @@ -41,38 +41,17 @@ void emberAfBasicClusterInitCallback(EndpointId endpoint) Basic::Attributes::ManufacturingDate::Set(endpoint, CharSpan(cString)); } -void MatterPostAttributeChangeCallback(const app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, +void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, uint8_t * value) - { - switch (attributePath.mClusterId) + ClusterId clusterId = attributePath.mClusterId; + AttributeId attributeId = attributePath.mAttributeId; + ChipLogProgress(Zcl, "Cluster callback: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); + + if (clusterId == DoorLock::Id && attributeId == DoorLock::Attributes::LockState::Id) { - case DoorLock::Id: - if (attributePath.mAttributeId == DoorLock::Attributes::LockState::Id) - { - ChipLogProgress(Zcl, "Door lock cluster: " ChipLogFormatMEI, ChipLogValueMEI(attributePath.mClusterId)); - printf("ZCL OnOff -> %u\n", *value); - LockMgr().InitiateAction(LockManager::ACTOR_ZCL_CMD, (*value) ? LockManager::LOCK_ACTION : LockManager::UNLOCK_ACTION); - return; - } - break; - case Identify::Id: - if (attributePath.mAttributeId == Identify::Attributes::IdentifyTime::Id) - { - uint16_t identifyTime; - if (EMBER_ZCL_STATUS_SUCCESS == Identify::Attributes::IdentifyTime::Get(attributePath.mEndpointId, &identifyTime)) - { - ChipLogProgress(Zcl, "IdentifyTime %u", identifyTime); - return; - } - } - break; - default: - printf("Unhandled cluster ID: 0x%04lx\n", attributePath.mClusterId); - return; + ChipLogProgress(Zcl, "Door lock cluster: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); } - - printf("ERROR clusterId: 0x%04lx, unknown attribute ID: 0x%04lx\n", attributePath.mClusterId, attributePath.mAttributeId); } bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const Optional & pinCode, DlOperationError & err) @@ -128,28 +107,40 @@ bool emberAfPluginDoorLockSetUser(chip::EndpointId endpointId, uint16_t userInde credentials, totalCredentials); } -// TODO: These functions will be supported by door-lock-server in the future. These are set to return failure until implemented. DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex, EmberAfPluginDoorLockWeekDaySchedule & schedule) { - return DlStatus::kFailure; + return LockMgr().GetWeekdaySchedule(endpointId, weekdayIndex, userIndex, schedule); } DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, EmberAfPluginDoorLockYearDaySchedule & schedule) { - return DlStatus::kFailure; + return LockMgr().GetYeardaySchedule(endpointId, yearDayIndex, userIndex, schedule); +} + +DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t holidayIndex, + EmberAfPluginDoorLockHolidaySchedule & holidaySchedule) +{ + return LockMgr().GetHolidaySchedule(endpointId, holidayIndex, holidaySchedule); } DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex, DlScheduleStatus status, DlDaysMaskMap daysMask, uint8_t startHour, uint8_t startMinute, uint8_t endHour, uint8_t endMinute) { - return DlStatus::kFailure; + return LockMgr().SetWeekdaySchedule(endpointId, weekdayIndex, userIndex, status, daysMask, startHour, startMinute, endHour, + endMinute); } DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, DlScheduleStatus status, uint32_t localStartTime, uint32_t localEndTime) { - return DlStatus::kFailure; + return LockMgr().SetYeardaySchedule(endpointId, yearDayIndex, userIndex, status, localStartTime, localEndTime); +} + +DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t holidayIndex, DlScheduleStatus status, + uint32_t localStartTime, uint32_t localEndTime, DlOperatingMode operatingMode) +{ + return LockMgr().SetHolidaySchedule(endpointId, holidayIndex, status, localStartTime, localEndTime, operatingMode); } diff --git a/examples/lock-app/infineon/cyw30739/src/main.cpp b/examples/lock-app/infineon/cyw30739/src/main.cpp index 6e184b06f0a67f..d72d154e7c3a10 100644 --- a/examples/lock-app/infineon/cyw30739/src/main.cpp +++ b/examples/lock-app/infineon/cyw30739/src/main.cpp @@ -255,8 +255,6 @@ void InitApp(intptr_t args) LockMgr().SetCallbacks(ActionInitiated, ActionCompleted); - chip::DeviceLayer::PlatformMgr().ScheduleWork(UpdateClusterState, reinterpret_cast(nullptr)); - ConfigurationMgr().LogDeviceConfig(); #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR @@ -277,7 +275,7 @@ void ActionInitiated(LockManager::Action_t aAction, int32_t aActor) ChipLogDetail(Zcl, "Unlock Action has been initiated"); } - if (aActor == LockManager::ACTOR_BUTTON) + if (aActor == AppEvent::kEventType_Button) { syncClusterToButtonAction = true; }