diff --git a/examples/all-clusters-app/esp32/main/AppTask.cpp b/examples/all-clusters-app/esp32/main/AppTask.cpp index 2111d7cb32df47..51ee806898cd10 100644 --- a/examples/all-clusters-app/esp32/main/AppTask.cpp +++ b/examples/all-clusters-app/esp32/main/AppTask.cpp @@ -27,9 +27,7 @@ #include "esp_spi_flash.h" #include "freertos/FreeRTOS.h" #include -#include -#define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000 #define APP_TASK_NAME "APP" #define APP_EVENT_QUEUE_SIZE 10 #define APP_TASK_STACK_SIZE (3072) @@ -37,7 +35,6 @@ static const char * TAG = "app-task"; namespace { -TimerHandle_t sFunctionTimer; // FreeRTOS app sw timer QueueHandle_t sAppEventQueue; TaskHandle_t sAppTaskHandle; @@ -61,106 +58,6 @@ CHIP_ERROR AppTask::StartAppTask() return (xReturned == pdPASS) ? CHIP_NO_ERROR : APP_ERROR_CREATE_TASK_FAILED; } -void AppTask::TimerEventHandler(TimerHandle_t xTimer) -{ - AppEvent event; - event.mType = AppEvent::kEventType_Timer; - event.mTimerEvent.mContext = (void *) xTimer; - event.mHandler = FunctionTimerEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FunctionTimerEventHandler(AppEvent * aEvent) -{ - if (aEvent->mType != AppEvent::kEventType_Timer) - { - return; - } - // If we reached here, the button was held past FACTORY_RESET_TRIGGER_TIMEOUT, - // initiate factory reset - if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_StartBleAdv) - { - // ESP_LOGI(TAG, "Factory Reset Triggered. Release button within %ums to cancel.", FACTORY_RESET_CANCEL_WINDOW_TIMEOUT); - // Start timer for FACTORY_RESET_CANCEL_WINDOW_TIMEOUT to allow user to - // cancel, if required. - sAppTask.StartTimer(FACTORY_RESET_CANCEL_WINDOW_TIMEOUT); - sAppTask.mFunction = kFunction_FactoryReset; - // Turn off all LEDs before starting blink to make sure blink is - // co-ordinated. - // sStatusLED.Set(false); - // sLockLED.Set(false); - // sStatusLED.Blink(500); - // sLockLED.Blink(500); - } - else if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_FactoryReset) - { - // Actually trigger Factory Reset - sAppTask.mFunction = kFunction_NoneSelected; - chip::Server::GetInstance().ScheduleFactoryReset(); - } -} - -void AppTask::CancelTimer() -{ - if (xTimerStop(sFunctionTimer, 0) == pdFAIL) - { - ESP_LOGI(TAG, "app timer stop() failed"); - return; - } - mFunctionTimerActive = false; -} -void AppTask::StartTimer(uint32_t aTimeoutInMs) -{ - if (xTimerIsTimerActive(sFunctionTimer)) - { - ESP_LOGI(TAG, "app timer already started!"); - CancelTimer(); - } - // timer is not active, change its period to required value (== restart). - // FreeRTOS- Block for a maximum of 100 ticks if the change period command - // cannot immediately be sent to the timer command queue. - if (xTimerChangePeriod(sFunctionTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS) - { - ESP_LOGI(TAG, "app timer start() failed"); - return; - } - mFunctionTimerActive = true; -} -void AppTask::ActionInitiated(BoltLockManager::Action_t aAction, int32_t aActor) -{ - // If the action has been initiated by the lock, update the bolt lock trait - // and start flashing the LEDs rapidly to indicate action initiation. - if (aAction == BoltLockManager::LOCK_ACTION) - { - ESP_LOGI(TAG, "Lock Action has been initiated"); - } - else if (aAction == BoltLockManager::UNLOCK_ACTION) - { - ESP_LOGI(TAG, "Unlock Action has been initiated"); - } - if (aActor == AppEvent::kEventType_Button) - { - sAppTask.mSyncClusterToButtonAction = true; - } - // sLockLED.Blink(50, 50); -} -void AppTask::ActionCompleted(BoltLockManager::Action_t aAction) -{ - // if the action has been completed by the lock, update the bolt lock trait. - // Turn on the lock LED if in a LOCKED state OR - // Turn off the lock LED if in an UNLOCKED state. - if (aAction == BoltLockManager::LOCK_ACTION) - { - ESP_LOGI(TAG, "Lock Action has been completed"); - // sLockLED.Set(true); - } - else if (aAction == BoltLockManager::UNLOCK_ACTION) - { - ESP_LOGI(TAG, "Unlock Action has been completed"); - // sLockLED.Set(false); - } -} - CHIP_ERROR AppTask::Init() { /* Print chip information */ @@ -172,18 +69,7 @@ CHIP_ERROR AppTask::Init() ESP_LOGI(TAG, "%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024), (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); - // Create FreeRTOS sw timer for Function Selection - sFunctionTimer = xTimerCreate("FnTmr", // Just a text name, not used by the RTOS kernel - 1, // == default timer period (mS) - false, // no timer reload (==one-shot) - (void *) this, // init timer id = app task obj context - TimerEventHandler // timer callback handler - ); - - CHIP_ERROR err = BoltLockMgr().InitLockState(); - - BoltLockMgr().SetCallbacks(ActionInitiated, ActionCompleted); - + CHIP_ERROR err = CHIP_NO_ERROR; statusLED1.Init(STATUS_LED_GPIO_NUM); // Our second LED doesn't map to any physical LEDs so far, just to virtual // "LED"s on devices with screens. diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index cb096a8c1e3262..a4003980dedde0 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -20,6 +20,7 @@ set(PRIV_INCLUDE_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/all-clusters-app" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/include" "${CMAKE_CURRENT_LIST_DIR}/include" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/lock-app/linux/include" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/third_party/nlfaultinjection/repo/include" @@ -29,11 +30,11 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/all-clusters-app/zap-generated" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated/attributes" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/lock-app/linux/src" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/ota" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/common" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/shell_extension" - "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/lock" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" @@ -93,6 +94,10 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/src" ) +set(EXCLUDE_SRCS_LIST + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/lock-app/linux/src/LockAppCommandDelegate.cpp" +) + if (CONFIG_ENABLE_PW_RPC) # Append additional directories for RPC build set(PRIV_INCLUDE_DIRS_LIST "${PRIV_INCLUDE_DIRS_LIST}" diff --git a/examples/platform/esp32/lock/AppEvent.h b/examples/all-clusters-app/esp32/main/include/AppEvent.h similarity index 90% rename from examples/platform/esp32/lock/AppEvent.h rename to examples/all-clusters-app/esp32/main/include/AppEvent.h index 114b228b078f01..26b97ab86d5018 100644 --- a/examples/platform/esp32/lock/AppEvent.h +++ b/examples/all-clusters-app/esp32/main/include/AppEvent.h @@ -29,7 +29,6 @@ struct AppEvent kEventType_Button = 0, kEventType_Timer, kEventType_Light, - kEventType_Lock, kEventType_Install, }; @@ -46,11 +45,6 @@ struct AppEvent { void * mContext; } mTimerEvent; - struct - { - uint8_t mAction; - int32_t mActor; - } mLockEvent; }; EventHandler mHandler; diff --git a/examples/all-clusters-app/esp32/main/include/AppTask.h b/examples/all-clusters-app/esp32/main/include/AppTask.h index 8a72b2d47e5777..3dd8b0bf121a5c 100644 --- a/examples/all-clusters-app/esp32/main/include/AppTask.h +++ b/examples/all-clusters-app/esp32/main/include/AppTask.h @@ -18,8 +18,7 @@ */ #pragma once -#include -#include +#include "AppEvent.h" #include // Application-defined error codes in the CHIP_ERROR space. @@ -29,7 +28,6 @@ #define APP_ERROR_CREATE_TIMER_FAILED CHIP_APPLICATION_ERROR(0x04) #define APP_ERROR_START_TIMER_FAILED CHIP_APPLICATION_ERROR(0x05) #define APP_ERROR_STOP_TIMER_FAILED CHIP_APPLICATION_ERROR(0x06) -#define APP_ERROR_ALLOCATION_FAILED CHIP_APPLICATION_ERROR(0x07) class AppTask { @@ -42,30 +40,7 @@ class AppTask private: CHIP_ERROR Init(); - - static void ActionInitiated(BoltLockManager::Action_t aAction, int32_t aActor); - static void ActionCompleted(BoltLockManager::Action_t aAction); - - void StartTimer(uint32_t aTimeoutMs); - void CancelTimer(void); - - static void FunctionTimerEventHandler(AppEvent * aEvent); - static void TimerEventHandler(TimerHandle_t xTimer); - void DispatchEvent(AppEvent * event); - - enum Function_t - { - kFunction_NoneSelected = 0, - kFunction_SoftwareUpdate = 0, - kFunction_StartBleAdv = 1, - kFunction_FactoryReset = 2, - kFunction_Invalid - } Function; - Function_t mFunction; - bool mFunctionTimerActive; - bool mSyncClusterToButtonAction; - static AppTask sAppTask; friend AppTask & GetAppTask(void); }; diff --git a/examples/lock-app/esp32/main/AppTask.cpp b/examples/lock-app/esp32/main/AppTask.cpp index 9014982eba5975..c7ebacf0f334f5 100644 --- a/examples/lock-app/esp32/main/AppTask.cpp +++ b/examples/lock-app/esp32/main/AppTask.cpp @@ -16,14 +16,13 @@ */ #include "AppTask.h" +#include "AppConfig.h" +#include "AppEvent.h" #include "Button.h" #include "LEDWidget.h" #include "esp_log.h" #include #include -#include -#include -//#include #include #include #include @@ -61,7 +60,6 @@ StackType_t appStack[APP_TASK_STACK_SIZE / sizeof(StackType_t)]; using namespace ::chip::DeviceLayer; using namespace ::chip::System; -// using namespace ESP32DoorLock::LockInitParams; AppTask AppTask::sAppTask; @@ -81,14 +79,19 @@ CHIP_ERROR AppTask::StartAppTask() CHIP_ERROR AppTask::Init() { - // Create FreeRTOS sw timer for Function Selection + // Create FreeRTOS sw timer for Function Selection. sFunctionTimer = xTimerCreate("FnTmr", // Just a text name, not used by the RTOS kernel 1, // == default timer period (mS) false, // no timer reload (==one-shot) (void *) this, // init timer id = app task obj context TimerEventHandler // timer callback handler ); - CHIP_ERROR err = BoltLockMgr().InitLockState(); + CHIP_ERROR err = BoltLockMgr().Init(); + if (err != CHIP_NO_ERROR) + { + ESP_LOGI(TAG, "BoltLockMgr().Init() failed"); + return err; + } BoltLockMgr().SetCallbacks(ActionInitiated, ActionCompleted); @@ -198,12 +201,12 @@ void AppTask::LockActionEventHandler(AppEvent * aEvent) int32_t actor; CHIP_ERROR err = CHIP_NO_ERROR; - if (aEvent->mType == AppEvent::kEventType_Lock) + if (aEvent->Type == AppEvent::kEventType_Lock) { - action = static_cast(aEvent->mLockEvent.mAction); - actor = aEvent->mLockEvent.mActor; + action = static_cast(aEvent->LockEvent.Action); + actor = aEvent->LockEvent.Actor; } - else if (aEvent->mType == AppEvent::kEventType_Button) + else if (aEvent->Type == AppEvent::kEventType_Button) { if (BoltLockMgr().IsUnlocked()) { @@ -238,19 +241,19 @@ void AppTask::ButtonEventHandler(uint8_t btnIdx, uint8_t btnAction) return; } - AppEvent button_event = {}; - button_event.mType = AppEvent::kEventType_Button; - button_event.mButtonEvent.mPinNo = btnIdx; - button_event.mButtonEvent.mAction = btnAction; + AppEvent button_event = {}; + button_event.Type = AppEvent::kEventType_Button; + button_event.ButtonEvent.PinNo = btnIdx; + button_event.ButtonEvent.Action = btnAction; if (btnIdx == APP_LOCK_BUTTON && btnAction == APP_BUTTON_PRESSED) { - button_event.mHandler = LockActionEventHandler; + button_event.Handler = LockActionEventHandler; sAppTask.PostEvent(&button_event); } else if (btnIdx == APP_FUNCTION_BUTTON) { - button_event.mHandler = FunctionHandler; + button_event.Handler = FunctionHandler; sAppTask.PostEvent(&button_event); } } @@ -258,15 +261,15 @@ void AppTask::ButtonEventHandler(uint8_t btnIdx, uint8_t btnAction) void AppTask::TimerEventHandler(TimerHandle_t xTimer) { AppEvent event; - event.mType = AppEvent::kEventType_Timer; - event.mTimerEvent.mContext = (void *) xTimer; - event.mHandler = FunctionTimerEventHandler; + event.Type = AppEvent::kEventType_Timer; + event.TimerEvent.Context = (void *) xTimer; + event.Handler = FunctionTimerEventHandler; sAppTask.PostEvent(&event); } void AppTask::FunctionTimerEventHandler(AppEvent * aEvent) { - if (aEvent->mType != AppEvent::kEventType_Timer) + if (aEvent->Type != AppEvent::kEventType_Timer) { return; } @@ -301,7 +304,7 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent) void AppTask::FunctionHandler(AppEvent * aEvent) { - if (aEvent->mButtonEvent.mPinNo != APP_FUNCTION_BUTTON) + if (aEvent->ButtonEvent.PinNo != APP_FUNCTION_BUTTON) { return; } @@ -313,7 +316,7 @@ void AppTask::FunctionHandler(AppEvent * aEvent) // FACTORY_RESET_TRIGGER_TIMEOUT to signal factory reset has been initiated. // To cancel factory reset: release the APP_FUNCTION_BUTTON once all LEDs // start blinking within the FACTORY_RESET_CANCEL_WINDOW_TIMEOUT - if (aEvent->mButtonEvent.mAction == APP_BUTTON_PRESSED) + if (aEvent->ButtonEvent.Action == APP_BUTTON_PRESSED) { if (!sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_NoneSelected) { @@ -428,10 +431,10 @@ void AppTask::ActionCompleted(BoltLockManager::Action_t aAction) void AppTask::PostLockActionRequest(int32_t aActor, BoltLockManager::Action_t aAction) { AppEvent event; - event.mType = AppEvent::kEventType_Lock; - event.mLockEvent.mActor = aActor; - event.mLockEvent.mAction = aAction; - event.mHandler = LockActionEventHandler; + event.Type = AppEvent::kEventType_Lock; + event.LockEvent.Actor = aActor; + event.LockEvent.Action = aAction; + event.Handler = LockActionEventHandler; PostEvent(&event); } @@ -448,9 +451,9 @@ void AppTask::PostEvent(const AppEvent * aEvent) void AppTask::DispatchEvent(AppEvent * aEvent) { - if (aEvent->mHandler) + if (aEvent->Handler) { - aEvent->mHandler(aEvent); + aEvent->Handler(aEvent); } else { diff --git a/examples/lock-app/esp32/main/BoltLockManager.cpp b/examples/lock-app/esp32/main/BoltLockManager.cpp new file mode 100644 index 00000000000000..d6cb59aaf54a3e --- /dev/null +++ b/examples/lock-app/esp32/main/BoltLockManager.cpp @@ -0,0 +1,217 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BoltLockManager.h" + +#include "AppConfig.h" +#include "AppTask.h" +#include "esp_log.h" +#include +static const char * TAG = "BoltLockManager"; +BoltLockManager BoltLockManager::sLock; + +TimerHandle_t sLockTimer; + +CHIP_ERROR BoltLockManager::Init() +{ + // Create FreeRTOS sw timer for lock timer. + sLockTimer = xTimerCreate("lockTmr", // Just a text name, not used by the RTOS kernel + 1, // == default timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = lock obj context + TimerEventHandler // timer callback handler + ); + + if (sLockTimer == NULL) + { + ESP_LOGE(TAG, "sLockTimer timer create failed"); + return APP_ERROR_CREATE_TIMER_FAILED; + } + + mState = kState_LockingCompleted; + mAutoLockTimerArmed = false; + mAutoRelock = false; + mAutoLockDuration = 0; + + return CHIP_NO_ERROR; +} + +void BoltLockManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB) +{ + mActionInitiated_CB = aActionInitiated_CB; + mActionCompleted_CB = aActionCompleted_CB; +} + +bool BoltLockManager::IsActionInProgress() +{ + return (mState == kState_LockingInitiated || mState == kState_UnlockingInitiated); +} + +bool BoltLockManager::IsUnlocked() +{ + return (mState == kState_UnlockingCompleted); +} + +void BoltLockManager::SetAutoLockDuration(uint32_t aDurationInSecs) +{ + mAutoLockDuration = aDurationInSecs; +} + +bool BoltLockManager::InitiateAction(int32_t aActor, Action_t aAction) +{ + bool action_initiated = false; + State_t new_state; + // Initiate Lock/Unlock Action only when the previous one is complete. + if (mState == kState_LockingCompleted && aAction == UNLOCK_ACTION) + { + action_initiated = true; + + new_state = kState_UnlockingInitiated; + } + else if (mState == kState_UnlockingCompleted && aAction == LOCK_ACTION) + { + action_initiated = true; + + new_state = kState_LockingInitiated; + } + + if (action_initiated) + { + if (mAutoLockTimerArmed && new_state == kState_LockingInitiated) + { + // If auto lock timer has been armed and someone initiates locking, + // cancel the timer and continue as normal. + mAutoLockTimerArmed = false; + + CancelTimer(); + } + + StartTimer(ACTUATOR_MOVEMENT_PERIOS_MS); + + // Since the timer started successfully, update the state and trigger callback + mState = new_state; + + if (mActionInitiated_CB) + { + mActionInitiated_CB(aAction, aActor); + } + } + + return action_initiated; +} + +void BoltLockManager::StartTimer(uint32_t aTimeoutMs) +{ + if (xTimerIsTimerActive(sLockTimer)) + { + ESP_LOGI(TAG, "app timer already started!"); + CancelTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sLockTimer, (aTimeoutMs / portTICK_PERIOD_MS), 100) != pdPASS) + { + ESP_LOGI(TAG, "sLockTimer timer start() failed"); + return; + } +} + +void BoltLockManager::CancelTimer(void) +{ + if (xTimerStop(sLockTimer, 0) == pdFAIL) + { + ESP_LOGI(TAG, "Lock timer timer stop() failed"); + return; + } +} +void BoltLockManager::TimerEventHandler(TimerHandle_t xTimer) +{ + // Get lock obj context from timer id. + BoltLockManager * lock = static_cast(pvTimerGetTimerID(xTimer)); + + // The timer event handler will be called in the context of the timer task + // once sLockTimer expires. Post an event to apptask queue with the actual handler + // so that the event can be handled in the context of the apptask. + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.TimerEvent.Context = lock; + if (lock->mAutoLockTimerArmed) + { + event.Handler = AutoReLockTimerEventHandler; + } + else + { + event.Handler = ActuatorMovementTimerEventHandler; + } + GetAppTask().PostEvent(&event); +} + +void BoltLockManager::AutoReLockTimerEventHandler(AppEvent * aEvent) +{ + BoltLockManager * lock = static_cast(aEvent->TimerEvent.Context); + int32_t actor = 0; + + // Make sure auto lock timer is still armed. + if (!lock->mAutoLockTimerArmed) + { + return; + } + + lock->mAutoLockTimerArmed = false; + + ESP_LOGI(TAG, "Auto Re-Lock has been triggered!"); + + lock->InitiateAction(actor, LOCK_ACTION); +} + +void BoltLockManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent) +{ + Action_t actionCompleted = INVALID_ACTION; + + BoltLockManager * lock = static_cast(aEvent->TimerEvent.Context); + + if (lock->mState == kState_LockingInitiated) + { + lock->mState = kState_LockingCompleted; + actionCompleted = LOCK_ACTION; + } + else if (lock->mState == kState_UnlockingInitiated) + { + lock->mState = kState_UnlockingCompleted; + actionCompleted = UNLOCK_ACTION; + } + + if (actionCompleted != INVALID_ACTION) + { + if (lock->mActionCompleted_CB) + { + lock->mActionCompleted_CB(actionCompleted); + } + + if (lock->mAutoRelock && actionCompleted == UNLOCK_ACTION) + { + // Start the timer for auto relock + lock->StartTimer(lock->mAutoLockDuration * 1000); + + lock->mAutoLockTimerArmed = true; + + ESP_LOGI(TAG, "Auto Re-lock enabled. Will be triggered in %u seconds", lock->mAutoLockDuration); + } + } +} diff --git a/examples/lock-app/esp32/main/Button.cpp b/examples/lock-app/esp32/main/Button.cpp index 301e62f92d7e08..698888440ecb65 100644 --- a/examples/lock-app/esp32/main/Button.cpp +++ b/examples/lock-app/esp32/main/Button.cpp @@ -18,7 +18,7 @@ #include "Button.h" #include "AppTask.h" -//#include +#include "AppConfig.h" esp_err_t Button::Init(gpio_num_t gpioNum, uint16_t debouncePeriod) { diff --git a/examples/lock-app/esp32/main/CMakeLists.txt b/examples/lock-app/esp32/main/CMakeLists.txt index 8947b92a95c617..8dd4bc1dc0a774 100644 --- a/examples/lock-app/esp32/main/CMakeLists.txt +++ b/examples/lock-app/esp32/main/CMakeLists.txt @@ -23,7 +23,6 @@ idf_component_register(INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/pw_sys_io/public" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32" - "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/lock" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/common" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/common/pigweed" @@ -186,7 +185,6 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/door-lock-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/identify-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/groups-server" - "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/lock" PRIV_REQUIRES chip QRCode bt) add_dependencies(${COMPONENT_LIB} app-codegen) diff --git a/examples/lock-app/esp32/main/DeviceCallbacks.cpp b/examples/lock-app/esp32/main/DeviceCallbacks.cpp index 576bbb7b8edf4f..7a073be32e1e53 100644 --- a/examples/lock-app/esp32/main/DeviceCallbacks.cpp +++ b/examples/lock-app/esp32/main/DeviceCallbacks.cpp @@ -24,8 +24,8 @@ **/ #include "DeviceCallbacks.h" -#include -#include +#include "AppConfig.h" +#include "BoltLockManager.h" #include #include @@ -59,8 +59,7 @@ void AppDeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, Clus void AppDeviceCallbacks::OnOnOffPostAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value) { - VerifyOrExit(attributeId == app::Clusters::OnOff::Attributes::OnOff::Id, - ESP_LOGI(TAG, "Unhandled Attribute ID: '0x%04x", attributeId)); + VerifyOrExit(attributeId == ZCL_ON_OFF_ATTRIBUTE_ID, ESP_LOGI(TAG, "Unhandled Attribute ID: '0x%04x", attributeId)); VerifyOrExit(endpointId == 1 || endpointId == 2, ESP_LOGE(TAG, "Unexpected EndPoint ID: `0x%02x'", endpointId)); if (*value) { diff --git a/examples/platform/esp32/lock/AppConfig.h b/examples/lock-app/esp32/main/include/AppConfig.h similarity index 98% rename from examples/platform/esp32/lock/AppConfig.h rename to examples/lock-app/esp32/main/include/AppConfig.h index e90d9a16336725..ec883599d56627 100644 --- a/examples/platform/esp32/lock/AppConfig.h +++ b/examples/lock-app/esp32/main/include/AppConfig.h @@ -17,6 +17,8 @@ #pragma once +#include "driver/gpio.h" + // ---- Lock Example App Config ---- #define APP_TASK_NAME "LOCK-APP" diff --git a/examples/lock-app/esp32/main/include/AppEvent.h b/examples/lock-app/esp32/main/include/AppEvent.h new file mode 100644 index 00000000000000..783d29ca6feb5d --- /dev/null +++ b/examples/lock-app/esp32/main/include/AppEvent.h @@ -0,0 +1,54 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +struct AppEvent; +typedef void (*EventHandler)(AppEvent *); + +struct AppEvent +{ + enum AppEventTypes + { + kEventType_Button = 0, + kEventType_Timer, + kEventType_Lock, + kEventType_Install, + }; + + uint16_t Type; + + union + { + struct + { + uint8_t PinNo; + uint8_t Action; + } ButtonEvent; + struct + { + void * Context; + } TimerEvent; + struct + { + uint8_t Action; + int32_t Actor; + } LockEvent; + }; + + EventHandler Handler; +}; diff --git a/examples/lock-app/esp32/main/include/AppTask.h b/examples/lock-app/esp32/main/include/AppTask.h index 7a1aad3e221800..ba7121b1554495 100644 --- a/examples/lock-app/esp32/main/include/AppTask.h +++ b/examples/lock-app/esp32/main/include/AppTask.h @@ -20,8 +20,8 @@ #include #include -#include -#include +#include "AppEvent.h" +#include "BoltLockManager.h" #include "freertos/FreeRTOS.h" #include @@ -35,7 +35,6 @@ #define APP_ERROR_CREATE_TIMER_FAILED CHIP_APPLICATION_ERROR(0x04) #define APP_ERROR_START_TIMER_FAILED CHIP_APPLICATION_ERROR(0x05) #define APP_ERROR_STOP_TIMER_FAILED CHIP_APPLICATION_ERROR(0x06) -#define APP_ERROR_ALLOCATION_FAILED CHIP_APPLICATION_ERROR(0x07) class AppTask { diff --git a/examples/lock-app/esp32/main/include/BoltLockManager.h b/examples/lock-app/esp32/main/include/BoltLockManager.h new file mode 100644 index 00000000000000..654da89ece435b --- /dev/null +++ b/examples/lock-app/esp32/main/include/BoltLockManager.h @@ -0,0 +1,87 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LOCK_MANAGER_H +#define LOCK_MANAGER_H + +#include +#include + +#include "AppEvent.h" + +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/timers.h" // provides FreeRTOS timer support + +class BoltLockManager +{ +public: + enum Action_t + { + LOCK_ACTION = 0, + UNLOCK_ACTION, + + INVALID_ACTION + } Action; + + enum State_t + { + kState_LockingInitiated = 0, + kState_LockingCompleted, + kState_UnlockingInitiated, + kState_UnlockingCompleted, + } State; + + CHIP_ERROR Init(); + bool IsUnlocked(); + void EnableAutoRelock(bool aOn); + void SetAutoLockDuration(uint32_t aDurationInSecs); + bool IsActionInProgress(); + bool InitiateAction(int32_t aActor, Action_t aAction); + + typedef void (*Callback_fn_initiated)(Action_t, int32_t aActor); + typedef void (*Callback_fn_completed)(Action_t); + void SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB); + +private: + friend BoltLockManager & BoltLockMgr(void); + State_t mState; + + Callback_fn_initiated mActionInitiated_CB; + Callback_fn_completed mActionCompleted_CB; + + bool mAutoRelock; + uint32_t mAutoLockDuration; + bool mAutoLockTimerArmed; + + void CancelTimer(void); + void StartTimer(uint32_t aTimeoutMs); + + static void TimerEventHandler(TimerHandle_t xTimer); + static void AutoReLockTimerEventHandler(AppEvent * aEvent); + static void ActuatorMovementTimerEventHandler(AppEvent * aEvent); + + static BoltLockManager sLock; +}; + +inline BoltLockManager & BoltLockMgr(void) +{ + return BoltLockManager::sLock; +} + +#endif // LOCK_MANAGER_H diff --git a/examples/lock-app/esp32/main/include/Button.h b/examples/lock-app/esp32/main/include/Button.h index fc838f806a1061..53ae87884b2865 100644 --- a/examples/lock-app/esp32/main/include/Button.h +++ b/examples/lock-app/esp32/main/include/Button.h @@ -17,10 +17,11 @@ #pragma once +#include + +#include "AppConfig.h" #include "AppTask.h" -#include "driver/gpio.h" #include "freertos/FreeRTOS.h" -#include class Button { diff --git a/examples/platform/esp32/lock/BoltLockManager.cpp b/examples/platform/esp32/lock/BoltLockManager.cpp deleted file mode 100644 index 8506bcf12278e5..00000000000000 --- a/examples/platform/esp32/lock/BoltLockManager.cpp +++ /dev/null @@ -1,836 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "BoltLockManager.h" - -#include "AppConfig.h" -#include "AppTask.h" -#include -#include -#include - -BoltLockManager BoltLockManager::sLock; - -TimerHandle_t sLockTimer; - -using namespace ::chip::DeviceLayer::Internal; -using namespace ESP32DoorLock::LockInitParams; - -CHIP_ERROR BoltLockManager::Init(chip::app::DataModel::Nullable state, - LockParam lockParam) -{ - - LockParams = lockParam; - - if (LockParams.numberOfUsers > kMaxUsers) - { - ChipLogDetail(Zcl, - "Max number of users is greater than %d, the maximum amount of users currently supported on this platform", - kMaxUsers); - return APP_ERROR_ALLOCATION_FAILED; - } - - if (LockParams.numberOfCredentialsPerUser > kMaxCredentialsPerUser) - { - ChipLogDetail(Zcl, - "Max number of credentials per user is greater than %d, the maximum amount of users currently supported on " - "this platform", - kMaxCredentialsPerUser); - return APP_ERROR_ALLOCATION_FAILED; - } - - if (LockParams.numberOfWeekdaySchedulesPerUser > kMaxWeekdaySchedulesPerUser) - { - ChipLogDetail( - Zcl, - " Max number of schedules is greater than %d, the maximum amount of schedules currently supported on this platform", - kMaxWeekdaySchedulesPerUser); - return APP_ERROR_ALLOCATION_FAILED; - } - - if (LockParams.numberOfYeardaySchedulesPerUser > kMaxYeardaySchedulesPerUser) - { - ChipLogDetail( - Zcl, "Max number of schedules is greater than %d, the maximum amount of schedules currently supported on this platform", - kMaxYeardaySchedulesPerUser); - return APP_ERROR_ALLOCATION_FAILED; - } - - if (LockParams.numberOfHolidaySchedules > kMaxHolidaySchedules) - { - ChipLogDetail( - Zcl, "Max number of schedules is greater than %d, the maximum amount of schedules currently supported on this platform", - kMaxHolidaySchedules); - return APP_ERROR_ALLOCATION_FAILED; - } - - // Create FreeRTOS sw timer for lock timer. - sLockTimer = xTimerCreate("lockTmr", // Just a text name, not used by the RTOS kernel - 1, // == default timer period (mS) - false, // no timer reload (==one-shot) - (void *) this, // init timer id = lock obj context - TimerEventHandler // timer callback handler - ); - - if (sLockTimer == NULL) - { - ChipLogDetail(Zcl, "sLockTimer timer create failed"); - return APP_ERROR_CREATE_TIMER_FAILED; - } - - if (state.Value() == DlLockState::kUnlocked) - mState = kState_UnlockCompleted; - else - mState = kState_LockCompleted; - - return CHIP_NO_ERROR; -} - -bool BoltLockManager::IsValidUserIndex(uint16_t userIndex) -{ - return (userIndex < kMaxUsers); -} - -bool BoltLockManager::IsValidCredentialIndex(uint16_t credentialIndex, DlCredentialType type) -{ - if (DlCredentialType::kProgrammingPIN == type) - { - return (0 == credentialIndex); // 0 is required index for Programming PIN - } - return (credentialIndex < kMaxCredentialsPerUser); -} - -bool BoltLockManager::IsValidWeekdayScheduleIndex(uint8_t scheduleIndex) -{ - return (scheduleIndex < kMaxWeekdaySchedulesPerUser); -} - -bool BoltLockManager::IsValidYeardayScheduleIndex(uint8_t scheduleIndex) -{ - return (scheduleIndex < kMaxYeardaySchedulesPerUser); -} - -bool BoltLockManager::IsValidHolidayScheduleIndex(uint8_t scheduleIndex) -{ - return (scheduleIndex < kMaxHolidaySchedules); -} - -bool BoltLockManager::ReadConfigValues() -{ - size_t outLen; - ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_LockUser, reinterpret_cast(&mLockUsers), - sizeof(EmberAfPluginDoorLockUserInfo) * ArraySize(mLockUsers), outLen); - - ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_Credential, reinterpret_cast(&mLockCredentials), - sizeof(EmberAfPluginDoorLockCredentialInfo) * ArraySize(mLockCredentials), outLen); - - ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_LockUserName, reinterpret_cast(mUserNames), - sizeof(mUserNames), outLen); - - ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_CredentialData, reinterpret_cast(mCredentialData), - sizeof(mCredentialData), outLen); - - ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_UserCredentials, reinterpret_cast(mCredentials), - sizeof(DlCredential) * LockParams.numberOfUsers * LockParams.numberOfCredentialsPerUser, - outLen); - - ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_WeekDaySchedules, reinterpret_cast(mWeekdaySchedule), - sizeof(EmberAfPluginDoorLockWeekDaySchedule) * LockParams.numberOfWeekdaySchedulesPerUser * - LockParams.numberOfUsers, - outLen); - - ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_YearDaySchedules, reinterpret_cast(mYeardaySchedule), - sizeof(EmberAfPluginDoorLockYearDaySchedule) * LockParams.numberOfYeardaySchedulesPerUser * - LockParams.numberOfUsers, - outLen); - - ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_HolidaySchedules, reinterpret_cast(&(mHolidaySchedule)), - sizeof(EmberAfPluginDoorLockHolidaySchedule) * LockParams.numberOfHolidaySchedules, outLen); - - return true; -} - -void BoltLockManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB) -{ - mActionInitiated_CB = aActionInitiated_CB; - mActionCompleted_CB = aActionCompleted_CB; -} - -bool BoltLockManager::IsActionInProgress() -{ - return (mState == kState_LockInitiated || mState == kState_UnlockInitiated); -} - -bool BoltLockManager::IsUnlocked() -{ - return (mState == kState_UnlockCompleted); -} - -void BoltLockManager::SetAutoLockDuration(uint32_t aDurationInSecs) -{ - mAutoLockDuration = aDurationInSecs; -} - -bool BoltLockManager::NextState() -{ - return (mState == kState_UnlockCompleted); -} - -bool BoltLockManager::InitiateAction(int32_t aActor, Action_t aAction) -{ - bool action_initiated = false; - State_t new_state; - - // Initiate Turn Lock/Unlock Action only when the previous one is complete. - if (mState == kState_LockCompleted && aAction == UNLOCK_ACTION) - { - action_initiated = true; - - new_state = kState_UnlockInitiated; - } - else if (mState == kState_UnlockCompleted && aAction == LOCK_ACTION) - { - action_initiated = true; - - new_state = kState_LockInitiated; - } - - if (action_initiated) - { - if (mAutoLockTimerArmed && new_state == kState_LockInitiated) - { - // If auto lock timer has been armed and someone initiates locking, - // cancel the timer and continue as normal. - mAutoLockTimerArmed = false; - - CancelTimer(); - } - - StartTimer(ACTUATOR_MOVEMENT_PERIOS_MS); - - // Since the timer started successfully, update the state and trigger callback - mState = new_state; - - if (mActionInitiated_CB) - { - mActionInitiated_CB(aAction, aActor); - } - } - - return action_initiated; -} - -void BoltLockManager::StartTimer(uint32_t aTimeoutMs) -{ - if (xTimerIsTimerActive(sLockTimer)) - { - ESP_LOGI(TAG, "app timer already started!"); - CancelTimer(); - } - - // timer is not active, change its period to required value (== restart). - // FreeRTOS- Block for a maximum of 100 ticks if the change period command - // cannot immediately be sent to the timer command queue. - if (xTimerChangePeriod(sLockTimer, (aTimeoutMs / portTICK_PERIOD_MS), 100) != pdPASS) - { - ESP_LOGI(TAG, "sLockTimer timer start() failed : %s", ErrorStr(APP_ERROR_START_TIMER_FAILED)); - } -} - -void BoltLockManager::CancelTimer(void) -{ - if (xTimerStop(sLockTimer, 0) == pdFAIL) - { - ESP_LOGI(TAG, "sLockTimer stop() failed : %s", ErrorStr(APP_ERROR_STOP_TIMER_FAILED)); - } -} - -void BoltLockManager::TimerEventHandler(TimerHandle_t xTimer) -{ - // Get lock obj context from timer id. - BoltLockManager * lock = static_cast(pvTimerGetTimerID(xTimer)); - - // The timer event handler will be called in the context of the timer task - // once sLockTimer expires. Post an event to apptask queue with the actual handler - // so that the event can be handled in the context of the apptask. - AppEvent event; - event.mType = AppEvent::kEventType_Timer; - event.mTimerEvent.mContext = lock; - if (lock->mAutoLockTimerArmed) - { - event.mHandler = AutoReLockTimerEventHandler; - } - else - { - event.mHandler = ActuatorMovementTimerEventHandler; - } - GetAppTask().PostEvent(&event); -} - -void BoltLockManager::AutoReLockTimerEventHandler(AppEvent * aEvent) -{ - BoltLockManager * lock = static_cast(aEvent->mTimerEvent.mContext); - int32_t actor = 0; - - // Make sure auto lock timer is still armed. - if (!lock->mAutoLockTimerArmed) - { - return; - } - - lock->mAutoLockTimerArmed = false; - - ESP_LOGI(TAG, "Auto Re-Lock has been triggered!"); - - lock->InitiateAction(actor, LOCK_ACTION); -} - -void BoltLockManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent) -{ - Action_t actionCompleted = INVALID_ACTION; - - BoltLockManager * lock = static_cast(aEvent->mTimerEvent.mContext); - - if (lock->mState == kState_LockInitiated) - { - lock->mState = kState_LockCompleted; - actionCompleted = LOCK_ACTION; - } - else if (lock->mState == kState_UnlockInitiated) - { - lock->mState = kState_UnlockCompleted; - actionCompleted = UNLOCK_ACTION; - } - - if (actionCompleted != INVALID_ACTION) - { - if (lock->mActionCompleted_CB) - { - lock->mActionCompleted_CB(actionCompleted); - } - - if (lock->mAutoRelock && actionCompleted == UNLOCK_ACTION) - { - // Start the timer for auto relock - lock->StartTimer(lock->mAutoLockDuration * 1000); - - lock->mAutoLockTimerArmed = true; - - ESP_LOGI(TAG, "Auto Re-lock enabled. Will be triggered in %u seconds", lock->mAutoLockDuration); - } - } -} - -bool BoltLockManager::Lock(chip::EndpointId endpointId, const Optional & pin, DlOperationError & err) -{ - return setLockState(endpointId, DlLockState::kLocked, pin, err); -} - -bool BoltLockManager::Unlock(chip::EndpointId endpointId, const Optional & pin, DlOperationError & err) -{ - return setLockState(endpointId, DlLockState::kUnlocked, pin, err); -} - -bool BoltLockManager::GetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) -{ - VerifyOrReturnValue(userIndex > 0, false); // indices are one-indexed - - userIndex--; - - VerifyOrReturnValue(IsValidUserIndex(userIndex), false); - - ESP_LOGI(TAG, "Door Lock App: BoltLockManager::GetUser [endpoint=%d,userIndex=%hu]", endpointId, userIndex); - - const auto & userInDb = mLockUsers[userIndex]; - - user.userStatus = userInDb.userStatus; - if (DlUserStatus::kAvailable == user.userStatus) - { - ESP_LOGI(TAG, "Found unoccupied user [endpoint=%d]", endpointId); - return true; - } - - user.userName = chip::CharSpan(userInDb.userName.data(), userInDb.userName.size()); - user.credentials = chip::Span(mCredentials[userIndex], userInDb.credentials.size()); - user.userUniqueId = userInDb.userUniqueId; - user.userType = userInDb.userType; - user.credentialRule = userInDb.credentialRule; - // So far there's no way to actually create the credential outside Matter, so here we always set the creation/modification - // source to Matter - user.creationSource = DlAssetSource::kMatterIM; - user.createdBy = userInDb.createdBy; - user.modificationSource = DlAssetSource::kMatterIM; - user.lastModifiedBy = userInDb.lastModifiedBy; - - ESP_LOGI(TAG, - "Found occupied user [endpoint=%d,name=\"%.*s\",credentialsCount=%u,uniqueId=%" PRIu32 - ",type=%u,credentialRule=%u,createdBy=%d,lastModifiedBy=%d]", - endpointId, static_cast(user.userName.size()), user.userName.data(), user.credentials.size(), user.userUniqueId, - to_underlying(user.userType), to_underlying(user.credentialRule), user.createdBy, user.lastModifiedBy); - - return true; -} - -bool BoltLockManager::SetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator, - chip::FabricIndex modifier, const chip::CharSpan & userName, uint32_t uniqueId, - DlUserStatus userStatus, DlUserType usertype, DlCredentialRule credentialRule, - const DlCredential * credentials, size_t totalCredentials) -{ - ESP_LOGI(TAG, - "Door Lock App: BoltLockManager::SetUser " - "[endpoint=%d,userIndex=%d,creator=%d,modifier=%d,userName=%s,uniqueId=%" PRIu32 "" - "userStatus=%u,userType=%u,credentialRule=%u,credentials=%p,totalCredentials=%u]", - endpointId, userIndex, creator, modifier, userName.data(), uniqueId, to_underlying(userStatus), - to_underlying(usertype), to_underlying(credentialRule), credentials, totalCredentials); - - VerifyOrReturnValue(userIndex > 0, false); // indices are one-indexed - - userIndex--; - - VerifyOrReturnValue(IsValidUserIndex(userIndex), false); - - auto & userInStorage = mLockUsers[userIndex]; - - if (userName.size() > DOOR_LOCK_MAX_USER_NAME_SIZE) - { - ESP_LOGE(TAG, "Cannot set user - user name is too long [endpoint=%d,index=%d]", endpointId, userIndex); - return false; - } - - if (totalCredentials > LockParams.numberOfCredentialsPerUser) - { - ESP_LOGE(TAG, "Cannot set user - total number of credentials is too big [endpoint=%d,index=%d,totalCredentials=%u]", - endpointId, userIndex, totalCredentials); - return false; - } - - chip::Platform::CopyString(mUserNames[userIndex], userName); - userInStorage.userName = chip::CharSpan(mUserNames[userIndex], userName.size()); - userInStorage.userUniqueId = uniqueId; - userInStorage.userStatus = userStatus; - userInStorage.userType = usertype; - userInStorage.credentialRule = credentialRule; - userInStorage.lastModifiedBy = modifier; - userInStorage.createdBy = creator; - - for (size_t i = 0; i < totalCredentials; ++i) - { - mCredentials[userIndex][i] = credentials[i]; - mCredentials[userIndex][i].CredentialType = 1; - mCredentials[userIndex][i].CredentialIndex = i + 1; - } - - userInStorage.credentials = chip::Span(mCredentials[userIndex], totalCredentials); - - // Save user information in NVM flash - ESP32Config::WriteConfigValueBin(ESP32Config::kConfigKey_LockUser, reinterpret_cast(&mLockUsers), - sizeof(EmberAfPluginDoorLockUserInfo) * LockParams.numberOfUsers); - - ESP32Config::WriteConfigValueBin(ESP32Config::kConfigKey_UserCredentials, reinterpret_cast(mCredentials), - sizeof(DlCredential) * LockParams.numberOfUsers * LockParams.numberOfCredentialsPerUser); - - ESP32Config::WriteConfigValueBin(ESP32Config::kConfigKey_LockUserName, reinterpret_cast(mUserNames), - sizeof(mUserNames)); - - ESP_LOGI(TAG, "Successfully set the user [mEndpointId=%d,index=%d]", endpointId, userIndex); - - return true; -} - -bool BoltLockManager::GetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, DlCredentialType credentialType, - EmberAfPluginDoorLockCredentialInfo & credential) -{ - - if (DlCredentialType::kProgrammingPIN == credentialType) - { - VerifyOrReturnValue(IsValidCredentialIndex(credentialIndex, credentialType), - false); // programming pin index is only index allowed to contain 0 - } - else - { - VerifyOrReturnValue(IsValidCredentialIndex(--credentialIndex, credentialType), false); // otherwise, indices are one-indexed - } - - ESP_LOGI(TAG, "Lock App: BoltLockManager::GetCredential [credentialType=%u], credentialIndex=%d", to_underlying(credentialType), - credentialIndex); - - const auto & credentialInStorage = mLockCredentials[credentialIndex]; - - credential.status = credentialInStorage.status; - ESP_LOGI(TAG, "CredentialStatus: %d, CredentialIndex: %d ", (int) credential.status, credentialIndex); - - if (DlCredentialStatus::kAvailable == credential.status) - { - ESP_LOGI(TAG, "Found unoccupied credential "); - return true; - } - credential.credentialType = credentialInStorage.credentialType; - credential.credentialData = credentialInStorage.credentialData; - credential.createdBy = credentialInStorage.createdBy; - credential.lastModifiedBy = credentialInStorage.lastModifiedBy; - // So far there's no way to actually create the credential outside Matter, so here we always set the creation/modification - // source to Matter - credential.creationSource = DlAssetSource::kMatterIM; - credential.modificationSource = DlAssetSource::kMatterIM; - - ESP_LOGI(TAG, "Found occupied credential [type=%u,dataSize=%u]", to_underlying(credential.credentialType), - credential.credentialData.size()); - - return true; -} - -bool BoltLockManager::SetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator, - chip::FabricIndex modifier, DlCredentialStatus credentialStatus, - DlCredentialType credentialType, const chip::ByteSpan & credentialData) -{ - - if (DlCredentialType::kProgrammingPIN == credentialType) - { - VerifyOrReturnValue(IsValidCredentialIndex(credentialIndex, credentialType), - false); // programming pin index is only index allowed to contain 0 - } - else - { - VerifyOrReturnValue(IsValidCredentialIndex(--credentialIndex, credentialType), false); // otherwise, indices are one-indexed - } - - ESP_LOGI(TAG, - "Door Lock App: BoltLockManager::SetCredential " - "[credentialStatus=%u,credentialType=%u,credentialDataSize=%u,creator=%d,modifier=%d]", - to_underlying(credentialStatus), to_underlying(credentialType), credentialData.size(), creator, modifier); - - auto & credentialInStorage = mLockCredentials[credentialIndex]; - - credentialInStorage.status = credentialStatus; - credentialInStorage.credentialType = credentialType; - credentialInStorage.createdBy = creator; - credentialInStorage.lastModifiedBy = modifier; - - memcpy(mCredentialData[credentialIndex], credentialData.data(), credentialData.size()); - credentialInStorage.credentialData = chip::ByteSpan{ mCredentialData[credentialIndex], credentialData.size() }; - - // Save credential information in NVM flash - ESP32Config::WriteConfigValueBin(ESP32Config::kConfigKey_Credential, reinterpret_cast(&mLockCredentials), - sizeof(EmberAfPluginDoorLockCredentialInfo) * LockParams.numberOfCredentialsPerUser); - - ESP32Config::WriteConfigValueBin(ESP32Config::kConfigKey_CredentialData, reinterpret_cast(&mCredentialData), - sizeof(mCredentialData)); - - ESP_LOGI(TAG, "Successfully set the credential [credentialType=%u]", to_underlying(credentialType)); - - return true; -} - -DlStatus BoltLockManager::GetWeekdaySchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex, - EmberAfPluginDoorLockWeekDaySchedule & schedule) -{ - - VerifyOrReturnValue(weekdayIndex > 0, DlStatus::kFailure); // indices are one-indexed - VerifyOrReturnValue(userIndex > 0, DlStatus::kFailure); // indices are one-indexed - - weekdayIndex--; - userIndex--; - - VerifyOrReturnValue(IsValidWeekdayScheduleIndex(weekdayIndex), DlStatus::kFailure); - VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure); - - const auto & scheduleInStorage = mWeekdaySchedule[userIndex][weekdayIndex]; - if (DlScheduleStatus::kAvailable == scheduleInStorage.status) - { - return DlStatus::kNotFound; - } - - schedule = scheduleInStorage.schedule; - - return DlStatus::kSuccess; -} - -DlStatus BoltLockManager::SetWeekdaySchedule(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) -{ - - VerifyOrReturnValue(weekdayIndex > 0, DlStatus::kFailure); // indices are one-indexed - VerifyOrReturnValue(userIndex > 0, DlStatus::kFailure); // indices are one-indexed - - weekdayIndex--; - userIndex--; - - VerifyOrReturnValue(IsValidWeekdayScheduleIndex(weekdayIndex), DlStatus::kFailure); - VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure); - - auto & scheduleInStorage = mWeekdaySchedule[userIndex][weekdayIndex]; - - 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 - ESP32Config::WriteConfigValueBin(ESP32Config::kConfigKey_WeekDaySchedules, reinterpret_cast(mWeekdaySchedule), - sizeof(EmberAfPluginDoorLockWeekDaySchedule) * LockParams.numberOfWeekdaySchedulesPerUser * - LockParams.numberOfUsers); - - return DlStatus::kSuccess; -} - -DlStatus BoltLockManager::GetYeardaySchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, - EmberAfPluginDoorLockYearDaySchedule & schedule) -{ - VerifyOrReturnValue(yearDayIndex > 0, DlStatus::kFailure); // indices are one-indexed - VerifyOrReturnValue(userIndex > 0, DlStatus::kFailure); // indices are one-indexed - - yearDayIndex--; - userIndex--; - - VerifyOrReturnValue(IsValidYeardayScheduleIndex(yearDayIndex), DlStatus::kFailure); - VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure); - - const auto & scheduleInStorage = mYeardaySchedule[userIndex][yearDayIndex]; - if (DlScheduleStatus::kAvailable == scheduleInStorage.status) - { - return DlStatus::kNotFound; - } - - schedule = scheduleInStorage.schedule; - - return DlStatus::kSuccess; -} - -DlStatus BoltLockManager::SetYeardaySchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, - DlScheduleStatus status, uint32_t localStartTime, uint32_t localEndTime) -{ - VerifyOrReturnValue(yearDayIndex > 0, DlStatus::kFailure); // indices are one-indexed - VerifyOrReturnValue(userIndex > 0, DlStatus::kFailure); // indices are one-indexed - - yearDayIndex--; - userIndex--; - - VerifyOrReturnValue(IsValidYeardayScheduleIndex(yearDayIndex), DlStatus::kFailure); - VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure); - - auto & scheduleInStorage = mYeardaySchedule[userIndex][yearDayIndex]; - - scheduleInStorage.schedule.localStartTime = localStartTime; - scheduleInStorage.schedule.localEndTime = localEndTime; - scheduleInStorage.status = status; - - // Save schedule information in NVM flash - ESP32Config::WriteConfigValueBin(ESP32Config::kConfigKey_YearDaySchedules, reinterpret_cast(mYeardaySchedule), - sizeof(EmberAfPluginDoorLockYearDaySchedule) * LockParams.numberOfYeardaySchedulesPerUser * - LockParams.numberOfUsers); - - return DlStatus::kSuccess; -} - -DlStatus BoltLockManager::GetHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex, - EmberAfPluginDoorLockHolidaySchedule & schedule) -{ - VerifyOrReturnValue(holidayIndex > 0, DlStatus::kFailure); // indices are one-indexed - - holidayIndex--; - - VerifyOrReturnValue(IsValidHolidayScheduleIndex(holidayIndex), DlStatus::kFailure); - - const auto & scheduleInStorage = mHolidaySchedule[holidayIndex]; - if (DlScheduleStatus::kAvailable == scheduleInStorage.status) - { - return DlStatus::kNotFound; - } - - schedule = scheduleInStorage.schedule; - - return DlStatus::kSuccess; -} - -DlStatus BoltLockManager::SetHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex, DlScheduleStatus status, - uint32_t localStartTime, uint32_t localEndTime, DlOperatingMode operatingMode) -{ - VerifyOrReturnValue(holidayIndex > 0, DlStatus::kFailure); // indices are one-indexed - - holidayIndex--; - - VerifyOrReturnValue(IsValidHolidayScheduleIndex(holidayIndex), DlStatus::kFailure); - - auto & scheduleInStorage = mHolidaySchedule[holidayIndex]; - - scheduleInStorage.schedule.localStartTime = localStartTime; - scheduleInStorage.schedule.localEndTime = localEndTime; - scheduleInStorage.schedule.operatingMode = operatingMode; - scheduleInStorage.status = status; - - // Save schedule information in NVM flash - ESP32Config::WriteConfigValueBin(ESP32Config::kConfigKey_HolidaySchedules, - reinterpret_cast(&(mHolidaySchedule)), - sizeof(EmberAfPluginDoorLockHolidaySchedule) * LockParams.numberOfHolidaySchedules); - - return DlStatus::kSuccess; -} - -const char * BoltLockManager::lockStateToString(DlLockState lockState) const -{ - switch (lockState) - { - case DlLockState::kNotFullyLocked: - return "Not Fully Locked"; - case DlLockState::kLocked: - return "Locked"; - case DlLockState::kUnlocked: - return "Unlocked"; - case DlLockState::kUnknownEnumValue: - break; - } - - return "Unknown"; -} - -bool BoltLockManager::setLockState(chip::EndpointId endpointId, DlLockState lockState, const Optional & pin, - DlOperationError & err) -{ - - // Assume pin is required until told otherwise - bool requirePin = true; - chip::app::Clusters::DoorLock::Attributes::RequirePINforRemoteOperation::Get(endpointId, &requirePin); - - // If a pin code is not given - if (!pin.HasValue()) - { - ESP_LOGI(TAG, "Door Lock App: PIN code is not specified [endpointId=%d]", endpointId); - - // If a pin code is not required - if (!requirePin) - { - ESP_LOGI(TAG, "Door Lock App: setting door lock state to \"%s\" [endpointId=%d]", lockStateToString(lockState), - endpointId); - - DoorLockServer::Instance().SetLockState(endpointId, lockState); - - return true; - } - - ESP_LOGI(TAG, "Door Lock App: PIN code is not specified, but it is required [endpointId=%d]", endpointId); - - return false; - } - - // Check the PIN code - for (uint8_t i = 0; i < kMaxCredentials; i++) - { - if (mLockCredentials[i].credentialType != DlCredentialType::kPin || - mLockCredentials[i].status == DlCredentialStatus::kAvailable) - { - continue; - } - - if (mLockCredentials[i].credentialData.data_equal(pin.Value())) - { - ESP_LOGI(TAG, "Lock App: specified PIN code was found in the database, setting lock state to \"%s\" [endpointId=%d]", - lockStateToString(lockState), endpointId); - - DoorLockServer::Instance().SetLockState(endpointId, lockState); - - return true; - } - } - - ESP_LOGI(TAG, - "Door Lock App: specified PIN code was not found in the database, ignoring command to set lock state to \"%s\" " - "[endpointId=%d]", - lockStateToString(lockState), endpointId); - - err = DlOperationError::kInvalidCredential; - return false; -} - -CHIP_ERROR BoltLockManager::InitLockState() -{ - - // Initial lock state - chip::app::DataModel::Nullable state; - chip::EndpointId endpointId{ 1 }; - chip::DeviceLayer::PlatformMgr().LockChipStack(); - chip::app::Clusters::DoorLock::Attributes::LockState::Get(endpointId, state); - - uint8_t numberOfCredentialsPerUser = 0; - if (!DoorLockServer::Instance().GetNumberOfCredentialsSupportedPerUser(endpointId, numberOfCredentialsPerUser)) - { - ChipLogError(Zcl, - "Unable to get number of credentials supported per user when initializing lock endpoint, defaulting to 5 " - "[endpointId=%d]", - endpointId); - numberOfCredentialsPerUser = 5; - } - - uint16_t numberOfUsers = 0; - if (!DoorLockServer::Instance().GetNumberOfUserSupported(endpointId, numberOfUsers)) - { - ChipLogError(Zcl, - "Unable to get number of supported users when initializing lock endpoint, defaulting to 10 [endpointId=%d]", - endpointId); - numberOfUsers = 10; - } - - uint8_t numberOfWeekdaySchedulesPerUser = 0; - if (!DoorLockServer::Instance().GetNumberOfWeekDaySchedulesPerUserSupported(endpointId, numberOfWeekdaySchedulesPerUser)) - { - ChipLogError( - Zcl, - "Unable to get number of supported weekday schedules when initializing lock endpoint, defaulting to 10 [endpointId=%d]", - endpointId); - numberOfWeekdaySchedulesPerUser = 10; - } - - uint8_t numberOfYeardaySchedulesPerUser = 0; - if (!DoorLockServer::Instance().GetNumberOfYearDaySchedulesPerUserSupported(endpointId, numberOfYeardaySchedulesPerUser)) - { - ChipLogError( - Zcl, - "Unable to get number of supported yearday schedules when initializing lock endpoint, defaulting to 10 [endpointId=%d]", - endpointId); - numberOfYeardaySchedulesPerUser = 10; - } - - uint8_t numberOfHolidaySchedules = 0; - if (!DoorLockServer::Instance().GetNumberOfHolidaySchedulesSupported(endpointId, numberOfHolidaySchedules)) - { - ChipLogError( - Zcl, - "Unable to get number of supported holiday schedules when initializing lock endpoint, defaulting to 10 [endpointId=%d]", - endpointId); - numberOfHolidaySchedules = 10; - } - - chip::DeviceLayer::PlatformMgr().UnlockChipStack(); - - CHIP_ERROR err = BoltLockMgr().Init(state, - ParamBuilder() - .SetNumberOfUsers(numberOfUsers) - .SetNumberOfCredentialsPerUser(numberOfCredentialsPerUser) - .SetNumberOfWeekdaySchedulesPerUser(numberOfWeekdaySchedulesPerUser) - .SetNumberOfYeardaySchedulesPerUser(numberOfYeardaySchedulesPerUser) - .SetNumberOfHolidaySchedules(numberOfHolidaySchedules) - .GetLockParam()); - if (err != CHIP_NO_ERROR) - { - ESP_LOGI(TAG, "BoltLockMgr().Init() failed"); - return err; - } - - return err; -} diff --git a/examples/platform/esp32/lock/BoltLockManager.h b/examples/platform/esp32/lock/BoltLockManager.h deleted file mode 100644 index ff01d75e15f2f2..00000000000000 --- a/examples/platform/esp32/lock/BoltLockManager.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once -#include - -#include -#include - -#include "AppEvent.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/timers.h" // provides FreeRTOS timer support - -#include - -struct WeekDaysScheduleInfo -{ - DlScheduleStatus status; - EmberAfPluginDoorLockWeekDaySchedule schedule; -}; - -struct YearDayScheduleInfo -{ - DlScheduleStatus status; - EmberAfPluginDoorLockYearDaySchedule schedule; -}; - -struct HolidayScheduleInfo -{ - DlScheduleStatus status; - EmberAfPluginDoorLockHolidaySchedule schedule; -}; - -namespace ESP32DoorLock { -namespace ResourceRanges { -// Used to size arrays -static constexpr uint16_t kMaxUsers = 10; -static constexpr uint8_t kMaxCredentialsPerUser = 10; -static constexpr uint8_t kMaxWeekdaySchedulesPerUser = 10; -static constexpr uint8_t kMaxYeardaySchedulesPerUser = 10; -static constexpr uint8_t kMaxHolidaySchedules = 10; -static constexpr uint8_t kMaxCredentialSize = 8; - -static constexpr uint8_t kMaxCredentials = kMaxUsers * kMaxCredentialsPerUser; -} // namespace ResourceRanges - -namespace LockInitParams { - -struct LockParam -{ - // Read from zap attributes - uint16_t numberOfUsers = 0; - uint8_t numberOfCredentialsPerUser = 0; - uint8_t numberOfWeekdaySchedulesPerUser = 0; - uint8_t numberOfYeardaySchedulesPerUser = 0; - uint8_t numberOfHolidaySchedules = 0; -}; - -class ParamBuilder -{ -public: - ParamBuilder & SetNumberOfUsers(uint16_t numberOfUsers) - { - lockParam_.numberOfUsers = numberOfUsers; - return *this; - } - ParamBuilder & SetNumberOfCredentialsPerUser(uint8_t numberOfCredentialsPerUser) - { - lockParam_.numberOfCredentialsPerUser = numberOfCredentialsPerUser; - return *this; - } - ParamBuilder & SetNumberOfWeekdaySchedulesPerUser(uint8_t numberOfWeekdaySchedulesPerUser) - { - lockParam_.numberOfWeekdaySchedulesPerUser = numberOfWeekdaySchedulesPerUser; - return *this; - } - ParamBuilder & SetNumberOfYeardaySchedulesPerUser(uint8_t numberOfYeardaySchedulesPerUser) - { - lockParam_.numberOfYeardaySchedulesPerUser = numberOfYeardaySchedulesPerUser; - return *this; - } - ParamBuilder & SetNumberOfHolidaySchedules(uint8_t numberOfHolidaySchedules) - { - lockParam_.numberOfHolidaySchedules = numberOfHolidaySchedules; - return *this; - } - LockParam GetLockParam() { return lockParam_; } - -private: - LockParam lockParam_; -}; - -} // namespace LockInitParams -} // namespace ESP32DoorLock - -using namespace ::chip; -using namespace ESP32DoorLock::ResourceRanges; - -class BoltLockManager -{ -public: - enum Action_t - { - LOCK_ACTION = 0, - UNLOCK_ACTION, - - INVALID_ACTION - } Action; - - enum State_t - { - kState_LockInitiated = 0, - kState_LockCompleted, - kState_UnlockInitiated, - kState_UnlockCompleted, - } State; - - CHIP_ERROR InitLockState(); - CHIP_ERROR Init(chip::app::DataModel::Nullable state, - ESP32DoorLock::LockInitParams::LockParam lockParam); - bool IsUnlocked(); - void EnableAutoRelock(bool aOn); - void SetAutoLockDuration(uint32_t aDurationInSecs); - bool NextState(); - bool IsActionInProgress(); - bool InitiateAction(int32_t aActor, Action_t aAction); - - typedef void (*Callback_fn_initiated)(Action_t, int32_t aActor); - typedef void (*Callback_fn_completed)(Action_t); - void SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB); - - bool Lock(chip::EndpointId endpointId, const Optional & pin, DlOperationError & err); - bool Unlock(chip::EndpointId endpointId, const Optional & pin, DlOperationError & err); - - bool GetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user); - bool SetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator, chip::FabricIndex modifier, - const chip::CharSpan & userName, uint32_t uniqueId, DlUserStatus userStatus, DlUserType usertype, - DlCredentialRule credentialRule, const DlCredential * credentials, size_t totalCredentials); - - bool GetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, DlCredentialType credentialType, - EmberAfPluginDoorLockCredentialInfo & credential); - - bool SetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator, chip::FabricIndex modifier, - DlCredentialStatus credentialStatus, DlCredentialType credentialType, const chip::ByteSpan & credentialData); - - DlStatus GetWeekdaySchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex, - EmberAfPluginDoorLockWeekDaySchedule & schedule); - - DlStatus SetWeekdaySchedule(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); - - DlStatus GetYeardaySchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, - EmberAfPluginDoorLockYearDaySchedule & schedule); - - DlStatus SetYeardaySchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, DlScheduleStatus status, - uint32_t localStartTime, uint32_t localEndTime); - - DlStatus GetHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex, EmberAfPluginDoorLockHolidaySchedule & schedule); - - DlStatus SetHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex, DlScheduleStatus status, uint32_t localStartTime, - uint32_t localEndTime, DlOperatingMode operatingMode); - - bool IsValidUserIndex(uint16_t userIndex); - bool IsValidCredentialIndex(uint16_t credentialIndex, DlCredentialType type); - bool IsValidWeekdayScheduleIndex(uint8_t scheduleIndex); - bool IsValidYeardayScheduleIndex(uint8_t scheduleIndex); - bool IsValidHolidayScheduleIndex(uint8_t scheduleIndex); - - bool setLockState(chip::EndpointId endpointId, DlLockState lockState, const Optional & pin, - DlOperationError & err); - const char * lockStateToString(DlLockState lockState) const; - - bool ReadConfigValues(); - -private: - friend BoltLockManager & BoltLockMgr(); - State_t mState; - - Callback_fn_initiated mActionInitiated_CB; - Callback_fn_completed mActionCompleted_CB; - - bool mAutoRelock; - uint32_t mAutoLockDuration; - bool mAutoLockTimerArmed; - - void CancelTimer(void); - void StartTimer(uint32_t aTimeoutMs); - - static void TimerEventHandler(TimerHandle_t xTimer); - static void AutoReLockTimerEventHandler(AppEvent * aEvent); - static void ActuatorMovementTimerEventHandler(AppEvent * aEvent); - - EmberAfPluginDoorLockUserInfo mLockUsers[kMaxUsers]; - EmberAfPluginDoorLockCredentialInfo mLockCredentials[kMaxCredentials]; - 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]; - - static BoltLockManager sLock; - ESP32DoorLock::LockInitParams::LockParam LockParams; -}; - -inline BoltLockManager & BoltLockMgr() -{ - return BoltLockManager::sLock; -} diff --git a/examples/platform/esp32/lock/ZclCallbacks.cpp b/examples/platform/esp32/lock/ZclCallbacks.cpp deleted file mode 100644 index b77a66e615f143..00000000000000 --- a/examples/platform/esp32/lock/ZclCallbacks.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * This file implements the handler for data model messages. - */ - -//#include "AppConfig.h" -#include "BoltLockManager.h" -#include - -#include -#include -#include -#include - -using namespace ::chip::app::Clusters; -using namespace ::chip::DeviceLayer::Internal; - -/** @brief DoorLock Cluster Init - * - * This function is called when a specific cluster is initialized. It gives the - * application an opportunity to take care of cluster initialization procedures. - * It is called exactly once for each endpoint where cluster is present. - * - * @param endpoint Ver.: always - * - */ -void emberAfDoorLockClusterInitCallback(EndpointId endpoint) {} - -bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const Optional & pinCode, DlOperationError & err) -{ - ChipLogProgress(Zcl, "Door Lock App: Lock Command endpoint=%d", endpointId); - bool status = BoltLockMgr().Lock(endpointId, pinCode, err); - if (status == true) - { - BoltLockMgr().InitiateAction(AppEvent::kEventType_Lock, BoltLockManager::LOCK_ACTION); - } - return status; -} - -bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const Optional & pinCode, - DlOperationError & err) -{ - ChipLogProgress(Zcl, "Door Lock App: Unlock Command endpoint=%d", endpointId); - bool status = BoltLockMgr().Unlock(endpointId, pinCode, err); - if (status == true) - { - BoltLockMgr().InitiateAction(AppEvent::kEventType_Lock, BoltLockManager::UNLOCK_ACTION); - } - - return status; -} - -bool emberAfPluginDoorLockGetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, DlCredentialType credentialType, - EmberAfPluginDoorLockCredentialInfo & credential) -{ - return BoltLockMgr().GetCredential(endpointId, credentialIndex, credentialType, credential); -} - -bool emberAfPluginDoorLockSetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator, - chip::FabricIndex modifier, DlCredentialStatus credentialStatus, - DlCredentialType credentialType, const chip::ByteSpan & credentialData) -{ - return BoltLockMgr().SetCredential(endpointId, credentialIndex, creator, modifier, credentialStatus, credentialType, - credentialData); -} - -bool emberAfPluginDoorLockGetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) -{ - return BoltLockMgr().GetUser(endpointId, userIndex, user); -} - -bool emberAfPluginDoorLockSetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator, - chip::FabricIndex modifier, const chip::CharSpan & userName, uint32_t uniqueId, - DlUserStatus userStatus, DlUserType usertype, DlCredentialRule credentialRule, - const DlCredential * credentials, size_t totalCredentials) -{ - - return BoltLockMgr().SetUser(endpointId, userIndex, creator, modifier, userName, uniqueId, userStatus, usertype, credentialRule, - credentials, totalCredentials); -} - -DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex, - EmberAfPluginDoorLockWeekDaySchedule & schedule) -{ - return BoltLockMgr().GetWeekdaySchedule(endpointId, weekdayIndex, userIndex, schedule); -} - -DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, - EmberAfPluginDoorLockYearDaySchedule & schedule) -{ - return BoltLockMgr().GetYeardaySchedule(endpointId, yearDayIndex, userIndex, schedule); -} - -DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t holidayIndex, - EmberAfPluginDoorLockHolidaySchedule & holidaySchedule) -{ - return BoltLockMgr().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 BoltLockMgr().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 BoltLockMgr().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 BoltLockMgr().SetHolidaySchedule(endpointId, holidayIndex, status, localStartTime, localEndTime, operatingMode); -} - -void emberAfPluginDoorLockOnAutoRelock(chip::EndpointId endpointId) -{ - // Apply the relock state in the application control - BoltLockMgr().InitiateAction(AppEvent::kEventType_Lock, BoltLockManager::LOCK_ACTION); -} diff --git a/src/platform/ESP32/ESP32Config.cpp b/src/platform/ESP32/ESP32Config.cpp index d47af60778e155..6d91c0d2566ed0 100644 --- a/src/platform/ESP32/ESP32Config.cpp +++ b/src/platform/ESP32/ESP32Config.cpp @@ -89,14 +89,6 @@ const ESP32Config::Key ESP32Config::kConfigKey_WiFiStationSecType = { kConfigNam const ESP32Config::Key ESP32Config::kConfigKey_RegulatoryLocation = { kConfigNamespace_ChipConfig, "reg-location" }; const ESP32Config::Key ESP32Config::kConfigKey_CountryCode = { kConfigNamespace_ChipConfig, "country-code" }; const ESP32Config::Key ESP32Config::kConfigKey_UniqueId = { kConfigNamespace_ChipConfig, "unique-id" }; -const ESP32Config::Key ESP32Config::kConfigKey_LockUser = { kConfigNamespace_ChipConfig, "lock-user" }; -const ESP32Config::Key ESP32Config::kConfigKey_Credential = { kConfigNamespace_ChipConfig, "credential" }; -const ESP32Config::Key ESP32Config::kConfigKey_LockUserName = { kConfigNamespace_ChipConfig, "lock-user-name" }; -const ESP32Config::Key ESP32Config::kConfigKey_CredentialData = { kConfigNamespace_ChipConfig, "credential-data" }; -const ESP32Config::Key ESP32Config::kConfigKey_UserCredentials = { kConfigNamespace_ChipConfig, "user-credential" }; -const ESP32Config::Key ESP32Config::kConfigKey_WeekDaySchedules = { kConfigNamespace_ChipConfig, "week-day-sched" }; -const ESP32Config::Key ESP32Config::kConfigKey_YearDaySchedules = { kConfigNamespace_ChipConfig, "year-day-sched" }; -const ESP32Config::Key ESP32Config::kConfigKey_HolidaySchedules = { kConfigNamespace_ChipConfig, "holiday-sched" }; // Keys stored in the Chip-counters namespace const ESP32Config::Key ESP32Config::kCounterKey_RebootCount = { kConfigNamespace_ChipCounters, "reboot-count" }; diff --git a/src/platform/ESP32/ESP32Config.h b/src/platform/ESP32/ESP32Config.h index c85303c2197555..6a008dbb795cf7 100644 --- a/src/platform/ESP32/ESP32Config.h +++ b/src/platform/ESP32/ESP32Config.h @@ -91,14 +91,6 @@ class ESP32Config static const Key kConfigKey_RegulatoryLocation; static const Key kConfigKey_CountryCode; static const Key kConfigKey_UniqueId; - static const Key kConfigKey_LockUser; - static const Key kConfigKey_Credential; - static const Key kConfigKey_LockUserName; - static const Key kConfigKey_CredentialData; - static const Key kConfigKey_UserCredentials; - static const Key kConfigKey_WeekDaySchedules; - static const Key kConfigKey_YearDaySchedules; - static const Key kConfigKey_HolidaySchedules; // CHIP Counter keys static const Key kCounterKey_RebootCount;