Skip to content

Commit

Permalink
[ESP32] Added door lock support for esp32. (#24547)
Browse files Browse the repository at this point in the history
* [ESP32/Linux] Added support of door-lock for esp32 and moved linux
door-lock code to common

* Restored linux implementation, implemented door lock support for esp32

* Restyled by clang-format

* esp32/all-clusters-app's uses linux door-lock replace it with esp32 door-lock support

* Restyled by whitespace

* Restyled by clang-format

* Removed redundent handling of lock/unlock

* Rebased and fixed zap generated changes

* Restyled by clang-format

Co-authored-by: Restyled.io <[email protected]>
  • Loading branch information
2 people authored and pull[bot] committed Dec 18, 2023
1 parent f70154f commit 1293240
Show file tree
Hide file tree
Showing 19 changed files with 1,408 additions and 408 deletions.
116 changes: 115 additions & 1 deletion examples/all-clusters-app/esp32/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,17 @@
#include "esp_spi_flash.h"
#include "freertos/FreeRTOS.h"
#include <app/server/OnboardingCodesUtil.h>
#include <lock/BoltLockManager.h>

#define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000
#define APP_TASK_NAME "APP"
#define APP_EVENT_QUEUE_SIZE 10
#define APP_TASK_STACK_SIZE (3072)

static const char * TAG = "app-task";

namespace {
TimerHandle_t sFunctionTimer; // FreeRTOS app sw timer

QueueHandle_t sAppEventQueue;
TaskHandle_t sAppTaskHandle;
Expand All @@ -58,6 +61,106 @@ 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 */
Expand All @@ -69,7 +172,18 @@ 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");

CHIP_ERROR err = CHIP_NO_ERROR;
// 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);

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.
Expand Down
7 changes: 1 addition & 6 deletions examples/all-clusters-app/esp32/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ 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"
Expand All @@ -30,11 +29,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"
Expand Down Expand Up @@ -94,10 +93,6 @@ 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}"
Expand Down
27 changes: 26 additions & 1 deletion examples/all-clusters-app/esp32/main/include/AppTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
*/

#pragma once
#include "AppEvent.h"
#include <lock/AppEvent.h>
#include <lock/BoltLockManager.h>
#include <platform/CHIPDeviceLayer.h>

// Application-defined error codes in the CHIP_ERROR space.
Expand All @@ -28,6 +29,7 @@
#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
{
Expand All @@ -40,7 +42,30 @@ 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);
};
Expand Down
59 changes: 28 additions & 31 deletions examples/lock-app/esp32/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@
*/

#include "AppTask.h"
#include "AppConfig.h"
#include "AppEvent.h"
#include "Button.h"
#include "LEDWidget.h"
#include "esp_log.h"
#include <app-common/zap-generated/attribute-id.h>
#include <app-common/zap-generated/attribute-type.h>
#include <lock/AppConfig.h>
#include <lock/AppEvent.h>
//#include <app-common/zap-generated/attributes/Accessors.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app/server/OnboardingCodesUtil.h>
#include <app/server/Server.h>
Expand Down Expand Up @@ -60,6 +61,7 @@ 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;

Expand All @@ -79,19 +81,14 @@ 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().Init();
if (err != CHIP_NO_ERROR)
{
ESP_LOGI(TAG, "BoltLockMgr().Init() failed");
return err;
}
CHIP_ERROR err = BoltLockMgr().InitLockState();

BoltLockMgr().SetCallbacks(ActionInitiated, ActionCompleted);

Expand Down Expand Up @@ -201,12 +198,12 @@ void AppTask::LockActionEventHandler(AppEvent * aEvent)
int32_t actor;
CHIP_ERROR err = CHIP_NO_ERROR;

if (aEvent->Type == AppEvent::kEventType_Lock)
if (aEvent->mType == AppEvent::kEventType_Lock)
{
action = static_cast<BoltLockManager::Action_t>(aEvent->LockEvent.Action);
actor = aEvent->LockEvent.Actor;
action = static_cast<BoltLockManager::Action_t>(aEvent->mLockEvent.mAction);
actor = aEvent->mLockEvent.mActor;
}
else if (aEvent->Type == AppEvent::kEventType_Button)
else if (aEvent->mType == AppEvent::kEventType_Button)
{
if (BoltLockMgr().IsUnlocked())
{
Expand Down Expand Up @@ -241,35 +238,35 @@ void AppTask::ButtonEventHandler(uint8_t btnIdx, uint8_t btnAction)
return;
}

AppEvent button_event = {};
button_event.Type = AppEvent::kEventType_Button;
button_event.ButtonEvent.PinNo = btnIdx;
button_event.ButtonEvent.Action = btnAction;
AppEvent button_event = {};
button_event.mType = AppEvent::kEventType_Button;
button_event.mButtonEvent.mPinNo = btnIdx;
button_event.mButtonEvent.mAction = btnAction;

if (btnIdx == APP_LOCK_BUTTON && btnAction == APP_BUTTON_PRESSED)
{
button_event.Handler = LockActionEventHandler;
button_event.mHandler = LockActionEventHandler;
sAppTask.PostEvent(&button_event);
}
else if (btnIdx == APP_FUNCTION_BUTTON)
{
button_event.Handler = FunctionHandler;
button_event.mHandler = FunctionHandler;
sAppTask.PostEvent(&button_event);
}
}

void AppTask::TimerEventHandler(TimerHandle_t xTimer)
{
AppEvent event;
event.Type = AppEvent::kEventType_Timer;
event.TimerEvent.Context = (void *) xTimer;
event.Handler = FunctionTimerEventHandler;
event.mType = AppEvent::kEventType_Timer;
event.mTimerEvent.mContext = (void *) xTimer;
event.mHandler = FunctionTimerEventHandler;
sAppTask.PostEvent(&event);
}

void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
{
if (aEvent->Type != AppEvent::kEventType_Timer)
if (aEvent->mType != AppEvent::kEventType_Timer)
{
return;
}
Expand Down Expand Up @@ -304,7 +301,7 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)

void AppTask::FunctionHandler(AppEvent * aEvent)
{
if (aEvent->ButtonEvent.PinNo != APP_FUNCTION_BUTTON)
if (aEvent->mButtonEvent.mPinNo != APP_FUNCTION_BUTTON)
{
return;
}
Expand All @@ -316,7 +313,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->ButtonEvent.Action == APP_BUTTON_PRESSED)
if (aEvent->mButtonEvent.mAction == APP_BUTTON_PRESSED)
{
if (!sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_NoneSelected)
{
Expand Down Expand Up @@ -431,10 +428,10 @@ void AppTask::ActionCompleted(BoltLockManager::Action_t aAction)
void AppTask::PostLockActionRequest(int32_t aActor, BoltLockManager::Action_t aAction)
{
AppEvent event;
event.Type = AppEvent::kEventType_Lock;
event.LockEvent.Actor = aActor;
event.LockEvent.Action = aAction;
event.Handler = LockActionEventHandler;
event.mType = AppEvent::kEventType_Lock;
event.mLockEvent.mActor = aActor;
event.mLockEvent.mAction = aAction;
event.mHandler = LockActionEventHandler;
PostEvent(&event);
}

Expand All @@ -451,9 +448,9 @@ void AppTask::PostEvent(const AppEvent * aEvent)

void AppTask::DispatchEvent(AppEvent * aEvent)
{
if (aEvent->Handler)
if (aEvent->mHandler)
{
aEvent->Handler(aEvent);
aEvent->mHandler(aEvent);
}
else
{
Expand Down
Loading

0 comments on commit 1293240

Please sign in to comment.