add door lock example and add icd function for thread device(h2+c6)

This commit is contained in:
liyashuai
2024-03-22 19:56:35 +08:00
parent 3ddea0493b
commit 64326977b8
24 changed files with 1928 additions and 0 deletions
+6
View File
@@ -92,3 +92,9 @@ examples/managed_component_light:
- if: IDF_TARGET in [""]
temporary: true
reason: this should be compiled without setting up environment, another CI has been added
examples/door_lock:
enable:
- if: IDF_TARGET in ["esp32", "esp32c3", "esp32c2", "esp32c6", "esp32h2"]
temporary: true
reason: the other targets are not tested yet
+40
View File
@@ -0,0 +1,40 @@
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
if(NOT DEFINED ENV{ESP_MATTER_PATH})
message(FATAL_ERROR "Please set ESP_MATTER_PATH to the path of esp-matter repo")
endif(NOT DEFINED ENV{ESP_MATTER_PATH})
set(PROJECT_VER "1.0")
set(PROJECT_VER_NUMBER 1)
set(ESP_MATTER_PATH $ENV{ESP_MATTER_PATH})
set(MATTER_SDK_PATH ${ESP_MATTER_PATH}/connectedhomeip/connectedhomeip)
# This should be done before using the IDF_TARGET variable.
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(EXTRA_COMPONENT_DIRS
"${ESP_MATTER_PATH}/examples/common"
"${MATTER_SDK_PATH}/config/esp32/components"
"${ESP_MATTER_PATH}/components"
${extra_components_dirs_append})
project(door_lock)
# WARNING: This is just an example for using key for decrypting the encrypted OTA image
# Please do not use it as is.
if(CONFIG_ENABLE_ENCRYPTED_OTA)
target_add_binary_data(light.elf "esp_image_encryption_key.pem" TEXT)
endif()
if(CONFIG_IDF_TARGET_ESP32C2)
include(relinker)
endif()
idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++17;-Os;-DCHIP_HAVE_CONFIG_H;-Wno-overloaded-virtual" APPEND)
idf_build_set_property(C_COMPILE_OPTIONS "-Os" APPEND)
# For RISCV chips, project_include.cmake sets -Wno-format, but does not clear various
# flags that depend on -Wformat
idf_build_set_property(COMPILE_OPTIONS "-Wno-format-nonliteral;-Wno-format-security" APPEND)
+15
View File
@@ -0,0 +1,15 @@
# Doorlock
This example creates a Doorlock device using the ESP Matter data model.
See the [docs](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/developing.html) for more information about building and flashing the firmware.
## 1. Additional Environment Setup
No additional setup is required.
## 2. Post Commissioning Setup
No additional setup is required.
## 3. Device Performance
+6
View File
@@ -0,0 +1,6 @@
idf_component_register(SRC_DIRS "." "./lock"
PRIV_INCLUDE_DIRS
"." "./lock" "${ESP_MATTER_PATH}/examples/common/utils")
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17)
target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H")
+37
View File
@@ -0,0 +1,37 @@
/*
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <esp_log.h>
#include <stdlib.h>
#include <string.h>
#include <esp_matter.h>
#include "bsp/esp-bsp.h"
#include <app_priv.h>
static const char *TAG = "app_driver";
using namespace chip::app::Clusters;
using namespace esp_matter;
esp_err_t app_driver_attribute_update(app_driver_handle_t driver_handle, uint16_t endpoint_id, uint32_t cluster_id,
uint32_t attribute_id, esp_matter_attr_val_t *val)
{
esp_err_t err = ESP_OK;
return err;
}
app_driver_handle_t app_driver_button_init()
{
/* Initialize button */
button_handle_t btns[BSP_BUTTON_NUM];
ESP_ERROR_CHECK(bsp_iot_button_create(btns, NULL, BSP_BUTTON_NUM));
return (app_driver_handle_t)btns[0];
}
+220
View File
@@ -0,0 +1,220 @@
/*
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <esp_err.h>
#include <esp_log.h>
#include <nvs_flash.h>
#if CONFIG_PM_ENABLE
#include <esp_pm.h>
#endif
#include <esp_matter.h>
#include <esp_matter_console.h>
#include <esp_matter_ota.h>
#include <common_macros.h>
#include <app_priv.h>
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
#include <platform/ESP32/OpenthreadLauncher.h>
#endif
#include <app/server/CommissioningWindowManager.h>
#include <app/server/Server.h>
static const char *TAG = "app_main";
uint16_t door_lock_endpoint_id = 0;
using namespace esp_matter;
using namespace esp_matter::attribute;
using namespace esp_matter::endpoint;
using namespace chip::app::Clusters;
using namespace chip;
constexpr auto k_timeout_seconds = 300;
#if CONFIG_ENABLE_ENCRYPTED_OTA
extern const char decryption_key_start[] asm("_binary_esp_image_encryption_key_pem_start");
extern const char decryption_key_end[] asm("_binary_esp_image_encryption_key_pem_end");
static const char *s_decryption_key = decryption_key_start;
static const uint16_t s_decryption_key_len = decryption_key_end - decryption_key_start;
#endif // CONFIG_ENABLE_ENCRYPTED_OTA
static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg)
{
switch (event->Type) {
case chip::DeviceLayer::DeviceEventType::kInterfaceIpAddressChanged:
ESP_LOGI(TAG, "Interface IP Address changed");
break;
case chip::DeviceLayer::DeviceEventType::kCommissioningComplete:
ESP_LOGI(TAG, "Commissioning complete");
break;
case chip::DeviceLayer::DeviceEventType::kFailSafeTimerExpired:
ESP_LOGI(TAG, "Commissioning failed, fail safe timer expired");
break;
case chip::DeviceLayer::DeviceEventType::kCommissioningSessionStarted:
ESP_LOGI(TAG, "Commissioning session started");
break;
case chip::DeviceLayer::DeviceEventType::kCommissioningSessionStopped:
ESP_LOGI(TAG, "Commissioning session stopped");
break;
case chip::DeviceLayer::DeviceEventType::kCommissioningWindowOpened:
ESP_LOGI(TAG, "Commissioning window opened");
break;
case chip::DeviceLayer::DeviceEventType::kCommissioningWindowClosed:
ESP_LOGI(TAG, "Commissioning window closed");
break;
case chip::DeviceLayer::DeviceEventType::kFabricRemoved:
{
ESP_LOGI(TAG, "Fabric removed successfully");
if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0)
{
chip::CommissioningWindowManager & commissionMgr = chip::Server::GetInstance().GetCommissioningWindowManager();
constexpr auto kTimeoutSeconds = chip::System::Clock::Seconds16(k_timeout_seconds);
if (!commissionMgr.IsCommissioningWindowOpen())
{
/* After removing last fabric, this example does not remove the Wi-Fi credentials
* and still has IP connectivity so, only advertising on DNS-SD.
*/
CHIP_ERROR err = commissionMgr.OpenBasicCommissioningWindow(kTimeoutSeconds,
chip::CommissioningWindowAdvertisement::kDnssdOnly);
if (err != CHIP_NO_ERROR)
{
ESP_LOGE(TAG, "Failed to open commissioning window, err:%" CHIP_ERROR_FORMAT, err.Format());
}
}
}
break;
}
case chip::DeviceLayer::DeviceEventType::kFabricWillBeRemoved:
ESP_LOGI(TAG, "Fabric will be removed");
break;
case chip::DeviceLayer::DeviceEventType::kFabricUpdated:
ESP_LOGI(TAG, "Fabric is updated");
break;
case chip::DeviceLayer::DeviceEventType::kFabricCommitted:
ESP_LOGI(TAG, "Fabric is committed");
break;
case chip::DeviceLayer::DeviceEventType::kBLEDeinitialized:
ESP_LOGI(TAG, "BLE deinitialized and memory reclaimed");
break;
default:
break;
}
}
// This callback is invoked when clients interact with the Identify Cluster.
// In the callback implementation, an endpoint can identify itself. (e.g., by flashing an LED or light).
static esp_err_t app_identification_cb(identification::callback_type_t type, uint16_t endpoint_id, uint8_t effect_id,
uint8_t effect_variant, void *priv_data)
{
ESP_LOGI(TAG, "Identification callback: type: %u, effect: %u, variant: %u", type, effect_id, effect_variant);
return ESP_OK;
}
// This callback is called for every attribute update. The callback implementation shall
// handle the desired attributes and return an appropriate error code. If the attribute
// is not of your interest, please do not return an error code and strictly return ESP_OK.
static esp_err_t app_attribute_update_cb(attribute::callback_type_t type, uint16_t endpoint_id, uint32_t cluster_id,
uint32_t attribute_id, esp_matter_attr_val_t *val, void *priv_data)
{
esp_err_t err = ESP_OK;
if (type == PRE_UPDATE) {
/* Driver update */
app_driver_handle_t driver_handle = (app_driver_handle_t)priv_data;
err = app_driver_attribute_update(driver_handle, endpoint_id, cluster_id, attribute_id, val);
}
return err;
}
extern "C" void app_main()
{
esp_err_t err = ESP_OK;
/* Initialize the ESP NVS layer */
nvs_flash_init();
#if CONFIG_PM_ENABLE
esp_pm_config_t pm_config = {
.max_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ,
.min_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ,
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
.light_sleep_enable = true
#endif
};
err = esp_pm_configure(&pm_config);
#endif
/* Create a Matter node and add the mandatory Root Node device type on endpoint 0 */
node::config_t node_config;
// node handle can be used to add/modify other endpoints.
node_t *node = node::create(&node_config, app_attribute_update_cb, app_identification_cb);
ABORT_APP_ON_FAILURE(node != nullptr, ESP_LOGE(TAG, "Failed to create Matter node"));
door_lock::config_t door_lock_config;
cluster::door_lock::feature::credential_over_the_air_access::config_t cota_config;
cluster::door_lock::feature::pin_credential::config_t pin_credential_config;
cluster::door_lock::feature::user::config_t user_config;
// endpoint handles can be used to add/modify clusters.
endpoint_t *endpoint = door_lock::create(node, &door_lock_config, ENDPOINT_FLAG_NONE, NULL);
ABORT_APP_ON_FAILURE(endpoint != nullptr, ESP_LOGE(TAG, "Failed to create door lock endpoint"));
cluster_t *door_lock_cluster = cluster::get(endpoint, DoorLock::Id);
cluster::door_lock::feature::credential_over_the_air_access::add(door_lock_cluster, &cota_config);
cluster::door_lock::feature::pin_credential::add(door_lock_cluster, &pin_credential_config);
cluster::door_lock::feature::user::add(door_lock_cluster, &user_config);
cluster::door_lock::attribute::create_auto_relock_time(door_lock_cluster, 5);
door_lock_endpoint_id = endpoint::get_id(endpoint);
ESP_LOGI(TAG, "Door lock created with endpoint_id %d", door_lock_endpoint_id);
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
/* Set OpenThread platform config */
esp_openthread_platform_config_t config = {
.radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(),
.host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(),
.port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(),
};
set_openthread_platform_config(&config);
#endif
/* Matter start */
err = esp_matter::start(app_event_cb);
ABORT_APP_ON_FAILURE(err == ESP_OK, ESP_LOGE(TAG, "Failed to start Matter, err:%d", err));
/* do nothing now */
door_lock_init();
#if CONFIG_ENABLE_ENCRYPTED_OTA
err = esp_matter_ota_requestor_encrypted_init(s_decryption_key, s_decryption_key_len);
ABORT_APP_ON_FAILURE(err == ESP_OK, ESP_LOGE(TAG, "Failed to initialized the encrypted OTA, err: %d", err));
#endif // CONFIG_ENABLE_ENCRYPTED_OTA
#if CONFIG_ENABLE_CHIP_SHELL
esp_matter::console::diagnostics_register_commands();
esp_matter::console::wifi_register_commands();
#if CONFIG_OPENTHREAD_CLI
esp_matter::console::otcli_register_commands();
#endif
esp_matter::console::init();
#endif
}
+65
View File
@@ -0,0 +1,65 @@
/*
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#pragma once
#include <esp_err.h>
#include <esp_matter.h>
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
#include "esp_openthread_types.h"
#endif
typedef void *app_driver_handle_t;
/** Initialize the button driver
*
* This initializes the button driver associated with the selected board.
*
* @return Handle on success.
* @return NULL in case of failure.
*/
app_driver_handle_t app_driver_button_init();
/** Driver Update
*
* This API should be called to update the driver for the attribute being updated.
* This is usually called from the common `app_attribute_update_cb()`.
*
* @param[in] endpoint_id Endpoint ID of the attribute.
* @param[in] cluster_id Cluster ID of the attribute.
* @param[in] attribute_id Attribute ID of the attribute.
* @param[in] val Pointer to `esp_matter_attr_val_t`. Use appropriate elements as per the value type.
*
* @return ESP_OK on success.
* @return error in case of failure.
*/
esp_err_t app_driver_attribute_update(app_driver_handle_t driver_handle, uint16_t endpoint_id, uint32_t cluster_id,
uint32_t attribute_id, esp_matter_attr_val_t *val);
/** The definition and invocation of this function are intended to resolve the issue:
* unable to link and call the callback functions defined in the door_lock_callbacks.cpp file.
*/
void door_lock_init();
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \
{ \
.radio_mode = RADIO_MODE_NATIVE, \
}
#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \
{ \
.host_connection_mode = HOST_CONNECTION_MODE_NONE, \
}
#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \
{ \
.storage_partition_name = "nvs", .netif_queue_size = 10, .task_queue_size = 10, \
}
#endif
@@ -0,0 +1,8 @@
dependencies:
espressif/cmake_utilities:
version: 0.*
rules: # will add "optional_component" only when all if clauses are True
- if: "idf_version >=5.0"
- if: "target in [esp32c2]"
esp_bsp_generic:
version: "^1.1.0"
@@ -0,0 +1,124 @@
/*
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <esp_log.h>
#include "door_lock_manager.h"
#include <app/clusters/door-lock-server/door-lock-server.h>
#include <platform/CHIPDeviceLayer.h>
#include <app-common/zap-generated/ids/Attributes.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app/ConcreteAttributePath.h>
#include <app/data-model/Nullable.h>
#include <lib/core/DataModelTypes.h>
using namespace chip::app::Clusters;
using chip::app::DataModel::Nullable;
static const char *TAG = "doorlock_callback";
void door_lock_init()
{
ESP_LOGI(TAG, "doorlock example init");
}
void emberAfDoorLockClusterInitCallback(EndpointId endpoint)
{
DoorLockServer::Instance().InitServer(endpoint);
BoltLockMgr().InitLockState();
}
bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const Nullable<chip::FabricIndex> & fabricIdx,
const Nullable<chip::NodeId> & nodeId, const Optional<ByteSpan> & pinCode,
OperationErrorEnum & err)
{
ESP_LOGI(TAG, "Door Lock App: Lock Command endpoint=%d", endpointId);
bool status = BoltLockMgr().Lock(endpointId, pinCode, err);
return status;
}
bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const Nullable<chip::FabricIndex> & fabricIdx,
const Nullable<chip::NodeId> & nodeId, const Optional<ByteSpan> & pinCode,
OperationErrorEnum & err)
{
ESP_LOGI(TAG, "Door Lock App: Unlock Command endpoint=%d", endpointId);
bool status = BoltLockMgr().Unlock(endpointId, pinCode, err);
return status;
}
bool emberAfPluginDoorLockGetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, CredentialTypeEnum 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,
CredentialTypeEnum 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,
UserStatusEnum userStatus, UserTypeEnum usertype, CredentialRuleEnum credentialRule,
const CredentialStruct * 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, DaysMaskMap 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, OperatingModeEnum operatingMode)
{
return BoltLockMgr().SetHolidaySchedule(endpointId, holidayIndex, status, localStartTime, localEndTime, operatingMode);
}
void emberAfPluginDoorLockOnAutoRelock(chip::EndpointId endpointId)
{
ESP_LOGI(TAG, "Door auto relock");
}
@@ -0,0 +1,588 @@
/*
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include "door_lock_manager.h"
#include <platform/ESP32/ESP32Config.h>
#include <app-common/zap-generated/attributes/Accessors.h>
#include <cstring>
#include <esp_log.h>
static const char *TAG = "doorlock_manager";
BoltLockManager BoltLockManager::sLock;
TimerHandle_t sLockTimer;
using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;
using namespace chip::DeviceLayer::Internal;
using namespace ESP32DoorLock::LockInitParams;
using namespace chip::Protocols::InteractionModel;
CHIP_ERROR BoltLockManager::Init(DataModel::Nullable<DoorLock::DlLockState> state,
LockParam lockParam)
{
LockParams = lockParam;
if (LockParams.numberOfUsers > kMaxUsers)
{
ESP_LOGI(TAG,"Max number of users is greater than %d, the maximum amount of users currently supported on this platform", kMaxUsers);
return CHIP_ERROR_NO_MEMORY;
}
if (LockParams.numberOfCredentialsPerUser > kMaxCredentialsPerUser)
{
ESP_LOGI(TAG, "Max number of credentials per user is greater than %d, the maximum amount of users currently supported on "
"this platform", kMaxCredentialsPerUser);
return CHIP_ERROR_NO_MEMORY;
}
if (LockParams.numberOfWeekdaySchedulesPerUser > kMaxWeekdaySchedulesPerUser)
{
ESP_LOGI(TAG, " Max number of schedules is greater than %d, the maximum amount of schedules currently supported on this platform",
kMaxWeekdaySchedulesPerUser);
return CHIP_ERROR_NO_MEMORY;
}
if (LockParams.numberOfYeardaySchedulesPerUser > kMaxYeardaySchedulesPerUser)
{
ESP_LOGI(TAG, "Max number of schedules is greater than %d, the maximum amount of schedules currently supported on this platform",
kMaxYeardaySchedulesPerUser);
return CHIP_ERROR_NO_MEMORY;
}
if (LockParams.numberOfHolidaySchedules > kMaxHolidaySchedules)
{
ESP_LOGI(TAG, "Max number of schedules is greater than %d, the maximum amount of schedules currently supported on this platform",
kMaxHolidaySchedules);
return CHIP_ERROR_NO_MEMORY;
}
return CHIP_NO_ERROR;
}
bool BoltLockManager::IsValidUserIndex(uint16_t userIndex)
{
return (userIndex < kMaxUsers);
}
bool BoltLockManager::IsValidCredentialIndex(uint16_t credentialIndex, CredentialTypeEnum type)
{
if (CredentialTypeEnum::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<uint8_t *>(&mLockUsers),
sizeof(EmberAfPluginDoorLockUserInfo) * ArraySize(mLockUsers), outLen);
ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_Credential, reinterpret_cast<uint8_t *>(&mLockCredentials),
sizeof(EmberAfPluginDoorLockCredentialInfo) * ArraySize(mLockCredentials), outLen);
ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_LockUserName, reinterpret_cast<uint8_t *>(mUserNames),
sizeof(mUserNames), outLen);
ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_CredentialData, reinterpret_cast<uint8_t *>(mCredentialData),
sizeof(mCredentialData), outLen);
ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_UserCredentials, reinterpret_cast<uint8_t *>(mCredentials),
sizeof(CredentialStruct) * LockParams.numberOfUsers * LockParams.numberOfCredentialsPerUser,
outLen);
ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_WeekDaySchedules, reinterpret_cast<uint8_t *>(mWeekdaySchedule),
sizeof(EmberAfPluginDoorLockWeekDaySchedule) * LockParams.numberOfWeekdaySchedulesPerUser *
LockParams.numberOfUsers,
outLen);
ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_YearDaySchedules, reinterpret_cast<uint8_t *>(mYeardaySchedule),
sizeof(EmberAfPluginDoorLockYearDaySchedule) * LockParams.numberOfYeardaySchedulesPerUser *
LockParams.numberOfUsers,
outLen);
ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_HolidaySchedules, reinterpret_cast<uint8_t *>(&(mHolidaySchedule)),
sizeof(EmberAfPluginDoorLockHolidaySchedule) * LockParams.numberOfHolidaySchedules, outLen);
return true;
}
bool BoltLockManager::Lock(EndpointId endpointId, const Optional<ByteSpan> & pin, OperationErrorEnum & err)
{
return setLockState(endpointId, DlLockState::kLocked, pin, err);
}
bool BoltLockManager::Unlock(EndpointId endpointId, const Optional<ByteSpan> & pin, OperationErrorEnum & err)
{
return setLockState(endpointId, DlLockState::kUnlocked, pin, err);
}
bool BoltLockManager::GetUser(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 (UserStatusEnum::kAvailable == user.userStatus)
{
ESP_LOGI(TAG, "Found unoccupied user [endpoint=%d]", endpointId);
return true;
}
user.userName = CharSpan(userInDb.userName.data(), userInDb.userName.size());
user.credentials = Span<const CredentialStruct>(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<int>(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(EndpointId endpointId, uint16_t userIndex, FabricIndex creator,
FabricIndex modifier, const CharSpan & userName, uint32_t uniqueId,
UserStatusEnum userStatus, UserTypeEnum usertype, CredentialRuleEnum credentialRule,
const CredentialStruct * 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;
}
Platform::CopyString(mUserNames[userIndex], userName);
userInStorage.userName = 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];
}
userInStorage.credentials = Span<const CredentialStruct>(mCredentials[userIndex], totalCredentials);
// Save user information in NVM flash
ESP32Config::WriteConfigValueBin(ESP32Config::kConfigKey_LockUser, reinterpret_cast<const uint8_t *>(&mLockUsers),
sizeof(EmberAfPluginDoorLockUserInfo) * LockParams.numberOfUsers);
ESP32Config::WriteConfigValueBin(ESP32Config::kConfigKey_UserCredentials, reinterpret_cast<const uint8_t *>(mCredentials),
sizeof(CredentialStruct) * LockParams.numberOfUsers * LockParams.numberOfCredentialsPerUser);
ESP32Config::WriteConfigValueBin(ESP32Config::kConfigKey_LockUserName, reinterpret_cast<const uint8_t *>(mUserNames),
sizeof(mUserNames));
ESP_LOGI(TAG, "Successfully set the user [mEndpointId=%d,index=%d]", endpointId, userIndex);
return true;
}
bool BoltLockManager::GetCredential(EndpointId endpointId, uint16_t credentialIndex, CredentialTypeEnum credentialType,
EmberAfPluginDoorLockCredentialInfo & credential)
{
if (CredentialTypeEnum::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(EndpointId endpointId, uint16_t credentialIndex, FabricIndex creator,
FabricIndex modifier, DlCredentialStatus credentialStatus,
CredentialTypeEnum credentialType, const ByteSpan & credentialData)
{
if (CredentialTypeEnum::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 = ByteSpan{ mCredentialData[credentialIndex], credentialData.size() };
// Save credential information in NVM flash
ESP32Config::WriteConfigValueBin(ESP32Config::kConfigKey_Credential, reinterpret_cast<const uint8_t *>(&mLockCredentials),
sizeof(EmberAfPluginDoorLockCredentialInfo) * LockParams.numberOfCredentialsPerUser);
ESP32Config::WriteConfigValueBin(ESP32Config::kConfigKey_CredentialData, reinterpret_cast<const uint8_t *>(&mCredentialData),
sizeof(mCredentialData));
ESP_LOGI(TAG, "Successfully set the credential [credentialType=%u]", to_underlying(credentialType));
return true;
}
DlStatus BoltLockManager::GetWeekdaySchedule(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(EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex,
DlScheduleStatus status, DaysMaskMap 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<const uint8_t *>(mWeekdaySchedule),
sizeof(EmberAfPluginDoorLockWeekDaySchedule) * LockParams.numberOfWeekdaySchedulesPerUser *
LockParams.numberOfUsers);
return DlStatus::kSuccess;
}
DlStatus BoltLockManager::GetYeardaySchedule(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(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<const uint8_t *>(mYeardaySchedule),
sizeof(EmberAfPluginDoorLockYearDaySchedule) * LockParams.numberOfYeardaySchedulesPerUser *
LockParams.numberOfUsers);
return DlStatus::kSuccess;
}
DlStatus BoltLockManager::GetHolidaySchedule(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(EndpointId endpointId, uint8_t holidayIndex, DlScheduleStatus status,
uint32_t localStartTime, uint32_t localEndTime, OperatingModeEnum 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<const uint8_t *>(&(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::kUnlatched:
return "Unlatched";
case DlLockState::kUnknownEnumValue:
break;
}
return "Unknown";
}
bool BoltLockManager::setLockState(EndpointId endpointId, DlLockState lockState, const Optional<ByteSpan> & pin,
OperationErrorEnum & err)
{
// Assume pin is required until told otherwise
bool requirePin = true;
if ( Status::Success != DoorLock::Attributes::RequirePINforRemoteOperation::Get(endpointId, &requirePin)) {
requirePin = false;
}
// 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 != CredentialTypeEnum::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 = OperationErrorEnum::kInvalidCredential;
return false;
}
CHIP_ERROR BoltLockManager::InitLockState()
{
// Initial lock state
DataModel::Nullable<DoorLock::DlLockState> state;
EndpointId endpointId{ 1 };
DoorLock::Attributes::LockState::Get(endpointId, state);
uint8_t numberOfCredentialsPerUser = 0;
if (!DoorLockServer::Instance().GetNumberOfCredentialsSupportedPerUser(endpointId, numberOfCredentialsPerUser))
{
ESP_LOGE(TAG, "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))
{
ESP_LOGE(TAG, "Unable to get number of supported users when initializing lock endpoint, defaulting to 10 [endpointId=%d]", endpointId);
numberOfUsers = 10;
}
CHIP_ERROR err = BoltLockMgr().Init(state, ParamBuilder()
.SetNumberOfUsers(numberOfUsers)
.SetNumberOfCredentialsPerUser(numberOfCredentialsPerUser)
.GetLockParam());
ReadConfigValues();
if (err != CHIP_NO_ERROR)
{
ESP_LOGE(TAG, "BoltLockMgr().Init() failed");
return err;
}
return err;
}
@@ -0,0 +1,182 @@
/*
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#pragma once
#include <app/clusters/door-lock-server/door-lock-server.h>
#include <stdbool.h>
#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h" // provides FreeRTOS timer support
#include <lib/core/CHIPError.h>
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;
CHIP_ERROR InitLockState();
CHIP_ERROR Init(chip::app::DataModel::Nullable<chip::app::Clusters::DoorLock::DlLockState> state,
ESP32DoorLock::LockInitParams::LockParam lockParam);
bool Lock(chip::EndpointId endpointId, const Optional<chip::ByteSpan> & pin, OperationErrorEnum & err);
bool Unlock(chip::EndpointId endpointId, const Optional<chip::ByteSpan> & pin, OperationErrorEnum & 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, UserStatusEnum userStatus, UserTypeEnum usertype,
CredentialRuleEnum credentialRule, const CredentialStruct * credentials, size_t totalCredentials);
bool GetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, CredentialTypeEnum credentialType,
EmberAfPluginDoorLockCredentialInfo & credential);
bool SetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator, chip::FabricIndex modifier,
DlCredentialStatus credentialStatus, CredentialTypeEnum 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,
DaysMaskMap 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, OperatingModeEnum operatingMode);
bool IsValidUserIndex(uint16_t userIndex);
bool IsValidCredentialIndex(uint16_t credentialIndex, CredentialTypeEnum 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<chip::ByteSpan> & pin,
OperationErrorEnum & err);
const char * lockStateToString(DlLockState lockState) const;
bool ReadConfigValues();
private:
friend BoltLockManager & BoltLockMgr();
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];
CredentialStruct mCredentials[kMaxUsers][kMaxCredentialsPerUser];
static BoltLockManager sLock;
ESP32DoorLock::LockInitParams::LockParam LockParams;
};
inline BoltLockManager & BoltLockMgr()
{
return BoltLockManager::sLock;
}
+11
View File
@@ -0,0 +1,11 @@
# Name, Type, SubType, Offset, Size, Flags
# Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table
esp_secure_cert, 0x3F, ,0xd000, 0x2000, encrypted
nvs, data, nvs, 0x10000, 0xC000,
nvs_keys, data, nvs_keys,, 0x1000, encrypted
otadata, data, ota, , 0x2000
phy_init, data, phy, , 0x1000,
ota_0, app, ota_0, 0x20000, 0x1E0000,
ota_1, app, ota_1, 0x200000, 0x1E0000,
fctry, data, nvs, 0x3E0000, 0x6000
coredump, data, coredump,, 64K
1 # Name, Type, SubType, Offset, Size, Flags
2 # Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table
3 esp_secure_cert, 0x3F, ,0xd000, 0x2000, encrypted
4 nvs, data, nvs, 0x10000, 0xC000,
5 nvs_keys, data, nvs_keys,, 0x1000, encrypted
6 otadata, data, ota, , 0x2000
7 phy_init, data, phy, , 0x1000,
8 ota_0, app, ota_0, 0x20000, 0x1E0000,
9 ota_1, app, ota_1, 0x200000, 0x1E0000,
10 fctry, data, nvs, 0x3E0000, 0x6000
11 coredump, data, coredump,, 64K
+65
View File
@@ -0,0 +1,65 @@
# Default to 921600 baud when flashing and monitoring device
CONFIG_ESPTOOLPY_BAUD_921600B=y
CONFIG_ESPTOOLPY_BAUD=921600
CONFIG_ESPTOOLPY_COMPRESSED=y
CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y
CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
#enable BT
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=y
#disable BT connection reattempt
CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=n
#enable lwip ipv6 autoconfig
CONFIG_LWIP_IPV6_AUTOCONFIG=y
# Use a custom partition table
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_OFFSET=0xC000
# Enable chip shell
CONFIG_ENABLE_CHIP_SHELL=y
#enable lwIP route hooks
CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y
CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y
# Button
CONFIG_BUTTON_PERIOD_TIME_MS=20
CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
# disable softap by default
CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n
# Disable DS Peripheral
CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n
# Use compact attribute storage mode
CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y
# Enable HKDF in mbedtls
CONFIG_MBEDTLS_HKDF_C=y
# Increase LwIP IPv6 address number to 6 (MAX_FABRIC + 1)
# unique local addresses for fabrics(MAX_FABRIC), a link local address(1)
CONFIG_LWIP_IPV6_NUM_ADDRESSES=6
# ESP32-DevKitC Settings
# Buttons
CONFIG_BSP_BUTTONS_NUM=1
CONFIG_BSP_BUTTON_1_TYPE_GPIO=y
CONFIG_BSP_BUTTON_1_GPIO=0
CONFIG_BSP_BUTTON_1_LEVEL=0
# LEDs
CONFIG_BSP_LEDS_NUM=0
# configurations required for diagnostic logs cluster
# Enable the diagnostic logs transfer over BDX protocol
CONFIG_CHIP_ENABLE_BDX_LOG_TRANSFER=y
CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH=y
CONFIG_ESP32_COREDUMP_DATA_FORMAT_ELF=y
@@ -0,0 +1,51 @@
CONFIG_IDF_TARGET="esp32c6"
# libsodium
CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y
# NIMBLE
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_EXT_ADV=n
CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70
CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=n
# FreeRTOS should use legacy API
CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY=y
# Enable OpenThread
CONFIG_OPENTHREAD_ENABLED=y
CONFIG_OPENTHREAD_SRP_CLIENT=y
CONFIG_OPENTHREAD_DNS_CLIENT=y
CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC=n
CONFIG_OPENTHREAD_LOG_LEVEL_NOTE=y
CONFIG_OPENTHREAD_CLI=n
# Disable lwip ipv6 autoconfig
CONFIG_LWIP_IPV6_AUTOCONFIG=n
# Use a custom partition table
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
# LwIP config for OpenThread
CONFIG_LWIP_IPV6_NUM_ADDRESSES=8
CONFIG_LWIP_MULTICAST_PING=y
# MDNS platform
CONFIG_USE_MINIMAL_MDNS=n
CONFIG_ENABLE_EXTENDED_DISCOVERY=y
# Enable OTA Requestor
CONFIG_ENABLE_OTA_REQUESTOR=y
# Disable STA and AP for ESP32C6
CONFIG_ENABLE_WIFI_STATION=n
CONFIG_ENABLE_WIFI_AP=n
# Button
CONFIG_BUTTON_PERIOD_TIME_MS=20
CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
# Enable chip shell
CONFIG_ENABLE_CHIP_SHELL=y
@@ -0,0 +1,176 @@
# Bluetooth
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=y
## NimBLE Options
CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1
CONFIG_BT_NIMBLE_MAX_BONDS=2
CONFIG_BT_NIMBLE_MAX_CCCDS=2
CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=3072
CONFIG_BT_NIMBLE_ROLE_CENTRAL=n
CONFIG_BT_NIMBLE_ROLE_OBSERVER=n
CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=10
CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE=100
CONFIG_BT_NIMBLE_MSYS_2_BLOCK_COUNT=4
CONFIG_BT_NIMBLE_ACL_BUF_COUNT=5
CONFIG_BT_NIMBLE_HCI_EVT_HI_BUF_COUNT=5
CONFIG_BT_NIMBLE_HCI_EVT_LO_BUF_COUNT=3
CONFIG_BT_NIMBLE_GATT_MAX_PROCS=1
CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=n
CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT=n
CONFIG_BT_NIMBLE_WHITELIST_SIZE=1
## Controller Options
CONFIG_BT_LE_CONTROLLER_TASK_STACK_SIZE=3072
CONFIG_BT_LE_LL_RESOLV_LIST_SIZE=1
CONFIG_BT_LE_LL_DUP_SCAN_LIST_COUNT=1
# Release BT IRAM memory
CONFIG_BT_RELEASE_IRAM=y
# SPI Configuration
CONFIG_SPI_MASTER_ISR_IN_IRAM=n
CONFIG_SPI_SLAVE_ISR_IN_IRAM=n
# Ethernet
CONFIG_ETH_USE_SPI_ETHERNET=n
# Event Loop Library
CONFIG_ESP_EVENT_POST_FROM_ISR=n
# Chip revision
CONFIG_ESP32C2_REV2_DEVELOPMENT=y
# ESP Ringbuf
CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y
CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH=y
# ESP System Settings
CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=16
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2048
CONFIG_ESP_MAIN_TASK_STACK_SIZE=3072
## Memory protection
CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT=n
# High resolution timer (esp_timer)
CONFIG_ESP_TIMER_TASK_STACK_SIZE=2048
# Wi-Fi
CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=n
CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=3
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=6
CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=6
CONFIG_ESP32_WIFI_IRAM_OPT=n
CONFIG_ESP32_WIFI_RX_IRAM_OPT=n
CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=n
CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=n
CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=n
CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n
# FreeRTOS
## Kernel
CONFIG_FREERTOS_HZ=1000
CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y
## Port
CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=n
CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y
# Hardware Abstraction Layer (HAL) and Low Level (LL)
CONFIG_HAL_ASSERTION_DISABLE=y
# LWIP
CONFIG_LWIP_MAX_SOCKETS=5
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=16
CONFIG_LWIP_DHCPS=n
CONFIG_LWIP_IPV6_AUTOCONFIG=y
CONFIG_LWIP_MAX_ACTIVE_TCP=5
CONFIG_LWIP_MAX_LISTENING_TCP=5
CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=n
CONFIG_LWIP_TCP_SYNMAXRTX=12
CONFIG_LWIP_TCP_MSL=40000
CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=16000
CONFIG_LWIP_TCP_SND_BUF_DEFAULT=4096
CONFIG_LWIP_TCP_WND_DEFAULT=2440
CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS=y
CONFIG_LWIP_TCP_RTO_TIME=1500
CONFIG_LWIP_MAX_UDP_PCBS=8
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=2560
CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y
CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y
# mbedTLS
CONFIG_MBEDTLS_DYNAMIC_BUFFER=y
CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y
CONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT=y
CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y
CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=n
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN=y
CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y
CONFIG_MBEDTLS_SSL_PROTO_SSL3=n
CONFIG_MBEDTLS_SSL_PROTO_TLS1=n
CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=n
# ESP-MQTT Configurations
CONFIG_MQTT_PROTOCOL_311=n
# Protocomm
CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=n
CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=n
# SPI Flash driver
CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=n
CONFIG_SPI_FLASH_ROM_IMPL=y
# Websocket
CONFIG_WS_TRANSPORT=n
# Virtual file system
CONFIG_VFS_SUPPORT_DIR=n
CONFIG_VFS_SUPPORT_SELECT=n
CONFIG_VFS_SUPPORT_TERMIOS=n
# Wear Levelling
CONFIG_WL_SECTOR_SIZE_512=y
# CHIP Core
## General Options
CONFIG_MAX_EXCHANGE_CONTEXTS=6
CONFIG_MAX_BINDINGS=6
CONFIG_MAX_PEER_NODES=12
CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS=6
CONFIG_ENABLE_CHIP_SHELL=n
CONFIG_DISABLE_IPV4=y
CONFIG_BUILD_CHIP_TESTS=n
## Networking Options
CONFIG_NUM_TCP_ENDPOINTS=1
CONFIG_NUM_UDP_ENDPOINTS=6
## System Options
CONFIG_NUM_TIMERS=24
CONFIG_ENABLE_OTA_REQUESTOR=y
# CHIP Device Layer
## General Options
CONFIG_CHIP_TASK_STACK_SIZE=6144
CONFIG_MAX_EVENT_QUEUE_SIZE=20
## Event Logging Options
CONFIG_EVENT_LOGGING_CRIT_BUFFER_SIZE=256
CONFIG_EVENT_LOGGING_INFO_BUFFER_SIZE=256
CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE=256
# ESP Matter
CONFIG_ESP_MATTER_MAX_DEVICE_TYPE_COUNT=4
CONFIG_ESP_MATTER_MAX_DYNAMIC_ENDPOINT_COUNT=4
# ESP32-C2-DevKitM-1 Settings
# Buttons
CONFIG_BSP_BUTTONS_NUM=1
CONFIG_BSP_BUTTON_1_TYPE_GPIO=y
CONFIG_BSP_BUTTON_1_GPIO=0
CONFIG_BSP_BUTTON_1_LEVEL=0
# LEDs
CONFIG_BSP_LEDS_NUM=1
CONFIG_BSP_LED_TYPE_RGB_CLASSIC=y
CONFIG_BSP_LED_RGB_RED_GPIO=0
CONFIG_BSP_LED_RGB_GREEN_GPIO=1
CONFIG_BSP_LED_RGB_BLUE_GPIO=8
@@ -0,0 +1,4 @@
# CMake Utilities
CONFIG_CU_RELINKER_ENABLE=y
CONFIG_CU_RELINKER_ENABLE_CUSTOMIZED_CONFIGURATION_FILES=y
CONFIG_CU_RELINKER_CUSTOMIZED_CONFIGURATION_FILES_PATH="../common/relinker/esp32c2_v5.1"
@@ -0,0 +1,4 @@
# CMake Utilities
CONFIG_CU_RELINKER_ENABLE=y
CONFIG_CU_RELINKER_ENABLE_CUSTOMIZED_CONFIGURATION_FILES=y
CONFIG_CU_RELINKER_CUSTOMIZED_CONFIGURATION_FILES_PATH="../common/relinker/esp32c2_v5.2"
@@ -0,0 +1,21 @@
CONFIG_IDF_TARGET="esp32c3"
# Enable OTA Requestor
CONFIG_ENABLE_OTA_REQUESTOR=y
# Disable AP
CONFIG_ENABLE_WIFI_STATION=y
CONFIG_ENABLE_WIFI_AP=n
# ESP32-C3-DevKitC-02 Settings
# Buttons
CONFIG_BSP_BUTTONS_NUM=1
CONFIG_BSP_BUTTON_1_TYPE_GPIO=y
CONFIG_BSP_BUTTON_1_GPIO=9
CONFIG_BSP_BUTTON_1_LEVEL=0
# LEDs
CONFIG_BSP_LEDS_NUM=1
CONFIG_BSP_LED_TYPE_RGB=y
CONFIG_BSP_LED_RGB_GPIO=8
CONFIG_BSP_LED_RGB_BACKEND_RMT=y
@@ -0,0 +1,95 @@
CONFIG_IDF_TARGET="esp32c6"
# libsodium
CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y
# NIMBLE
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_EXT_ADV=n
CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70
CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=y
# FreeRTOS should use legacy API
CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY=y
# Enable OpenThread
CONFIG_OPENTHREAD_ENABLED=y
CONFIG_OPENTHREAD_SRP_CLIENT=y
CONFIG_OPENTHREAD_DNS_CLIENT=y
CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC=n
CONFIG_OPENTHREAD_LOG_LEVEL_NOTE=y
CONFIG_OPENTHREAD_CLI=n
# Disable lwip ipv6 autoconfig
CONFIG_LWIP_IPV6_AUTOCONFIG=n
# Use a custom partition table
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
# LwIP config for OpenThread
CONFIG_LWIP_IPV6_NUM_ADDRESSES=8
CONFIG_LWIP_MULTICAST_PING=y
# MDNS platform
CONFIG_USE_MINIMAL_MDNS=n
CONFIG_ENABLE_EXTENDED_DISCOVERY=y
# Enable OTA Requestor
CONFIG_ENABLE_OTA_REQUESTOR=y
# Disable STA and AP for ESP32H2
CONFIG_ENABLE_WIFI_STATION=n
CONFIG_ENABLE_WIFI_AP=n
# Disable chip shell
CONFIG_ENABLE_CHIP_SHELL=n
# Enable DS Peripheral
CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=y
# BLE Sleep
CONFIG_BT_LE_SLEEP_ENABLE=y
CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL=y
# Disable external 32K crystal
CONFIG_RTC_CLK_SRC_EXT_CRYS=n
# Enable power management
CONFIG_PM_ENABLE=y
CONFIG_PM_DFS_INIT_AUTO=y
CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y
CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=n
CONFIG_ESP_PHY_MAC_BB_PD=y
# FreeRTOS config for light sleep
CONFIG_FREERTOS_HZ=1000
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
# Enable IEEE 802.15.4 sleep
CONFIG_IEEE802154_SLEEP_ENABLE=y
# FreeRTOS config for light sleep
CONFIG_LWIP_ND6=n
CONFIG_LWIP_IPV4=n
CONFIG_DISABLE_IPV4=y
# Disable hardware acceleration
CONFIG_MBEDTLS_HARDWARE_AES=n
CONFIG_MBEDTLS_HARDWARE_MPI=n
CONFIG_MBEDTLS_HARDWARE_SHA=n
CONFIG_MBEDTLS_HARDWARE_ECC=n
CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY=n
CONFIG_MBEDTLS_SSL_PROTO_DTLS=y
# Use OpenThread MTD
CONFIG_OPENTHREAD_MTD=y
# ICD configurations
CONFIG_ENABLE_ICD_SERVER=y
CONFIG_ICD_FAST_POLL_INTERVAL_MS=500
CONFIG_ICD_IDLE_MODE_INTERVAL_SEC=60
CONFIG_ICD_ACTIVE_MODE_INTERVAL_MS=1000
CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS=1000
CONFIG_ENABLE_ICD_LIT=y
@@ -0,0 +1,94 @@
CONFIG_IDF_TARGET="esp32h2"
# libsodium
CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y
# NIMBLE
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_EXT_ADV=n
CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70
CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=y
# FreeRTOS should use legacy API
CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY=y
# Enable OpenThread
CONFIG_OPENTHREAD_ENABLED=y
CONFIG_OPENTHREAD_SRP_CLIENT=y
CONFIG_OPENTHREAD_DNS_CLIENT=y
CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC=n
CONFIG_OPENTHREAD_LOG_LEVEL_NOTE=y
CONFIG_OPENTHREAD_CLI=n
# Disable lwip ipv6 autoconfig
CONFIG_LWIP_IPV6_AUTOCONFIG=n
# Use a custom partition table
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
# LwIP config for OpenThread
CONFIG_LWIP_IPV6_NUM_ADDRESSES=8
CONFIG_LWIP_MULTICAST_PING=y
# MDNS platform
CONFIG_USE_MINIMAL_MDNS=n
CONFIG_ENABLE_EXTENDED_DISCOVERY=y
# Enable OTA Requestor
CONFIG_ENABLE_OTA_REQUESTOR=y
# Disable STA and AP for ESP32H2
CONFIG_ENABLE_WIFI_STATION=n
CONFIG_ENABLE_WIFI_AP=n
# Disable chip shell
CONFIG_ENABLE_CHIP_SHELL=n
# Enable DS Peripheral
CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=y
# BLE Sleep
CONFIG_BT_LE_SLEEP_ENABLE=y
CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL=y
# Disable external 32K crystal
CONFIG_RTC_CLK_SRC_EXT_CRYS=n
# Enable power management
CONFIG_PM_ENABLE=y
CONFIG_PM_DFS_INIT_AUTO=y
CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y
CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y
# FreeRTOS config for light sleep
CONFIG_FREERTOS_HZ=1000
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
# Enable IEEE 802.15.4 sleep
CONFIG_IEEE802154_SLEEP_ENABLE=y
# FreeRTOS config for light sleep
CONFIG_LWIP_ND6=n
CONFIG_LWIP_IPV4=n
CONFIG_DISABLE_IPV4=y
# Disable hardware acceleration
CONFIG_MBEDTLS_HARDWARE_AES=n
CONFIG_MBEDTLS_HARDWARE_MPI=n
CONFIG_MBEDTLS_HARDWARE_SHA=n
CONFIG_MBEDTLS_HARDWARE_ECC=n
CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY=n
CONFIG_MBEDTLS_SSL_PROTO_DTLS=y
# Use OpenThread MTD
CONFIG_OPENTHREAD_MTD=y
# ICD configurations
CONFIG_ENABLE_ICD_SERVER=y
CONFIG_ICD_FAST_POLL_INTERVAL_MS=500
CONFIG_ICD_IDLE_MODE_INTERVAL_SEC=60
CONFIG_ICD_ACTIVE_MODE_INTERVAL_MS=1000
CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS=1000
CONFIG_ENABLE_ICD_LIT=y
@@ -0,0 +1,53 @@
#enable BT
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=y
#disable BT connection reattempt
CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=n
#enable lwip ipv6 autoconfig
CONFIG_LWIP_IPV6_AUTOCONFIG=y
# Use a custom partition table
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_OFFSET=0xC000
# Enable chip shell
CONFIG_ENABLE_CHIP_SHELL=y
#enable lwIP route hooks
CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y
CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y
# Button
CONFIG_BUTTON_PERIOD_TIME_MS=20
CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
# disable softap by default
CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n
# Disable DS Peripheral
CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n
# Use compact attribute storage mode
CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y
# Enable HKDF in mbedtls
CONFIG_MBEDTLS_HKDF_C=y
# Increase LwIP IPv6 address number to 6 (MAX_FABRIC + 1)
# unique local addresses for fabrics(MAX_FABRIC), a link local address(1)
CONFIG_LWIP_IPV6_NUM_ADDRESSES=6
# ESP32-S3-DevKitC-1 Settings
# Buttons
CONFIG_BSP_BUTTONS_NUM=1
CONFIG_BSP_BUTTON_1_TYPE_GPIO=y
CONFIG_BSP_BUTTON_1_GPIO=0
CONFIG_BSP_BUTTON_1_LEVEL=0
# LEDs
CONFIG_BSP_LEDS_NUM=1
CONFIG_BSP_LED_TYPE_RGB=y
CONFIG_BSP_LED_RGB_GPIO=48
CONFIG_BSP_LED_RGB_BACKEND_RMT=y
@@ -0,0 +1,61 @@
# Default to 921600 baud when flashing and monitoring device
CONFIG_ESPTOOLPY_BAUD_921600B=y
CONFIG_ESPTOOLPY_BAUD=921600
CONFIG_ESPTOOLPY_COMPRESSED=y
CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y
CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
#enable BT
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=y
#disable BT connection reattempt
CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=n
#enable lwip ipv6 autoconfig
CONFIG_LWIP_IPV6_AUTOCONFIG=y
# Use a custom partition table
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
# Disable chip shell
CONFIG_ENABLE_CHIP_SHELL=n
# Disable chip tests
CONFIG_BUILD_CHIP_TESTS=n
#enable lwIP route hooks
CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y
CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y
# Button
CONFIG_BUTTON_PERIOD_TIME_MS=20
CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
# External Platform
CONFIG_CHIP_ENABLE_EXTERNAL_PLATFORM=y
CONFIG_CHIP_EXTERNAL_PLATFORM_DIR="../../../../../platform/ESP32_custom"
CONFIG_CHIP_EXTERNAL_PLATFORM_INCLUDE_DIR="../../../../.."
# disable softap by default
CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n
# Disable DS Peripheral
CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n
# Use compact attribute storage mode
CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y
# Enable HKDF in mbedtls
CONFIG_MBEDTLS_HKDF_C=y
# ESP32-DevKit Settings
# Buttons
CONFIG_BSP_BUTTONS_NUM=1
CONFIG_BSP_BUTTON_1_TYPE_GPIO=y
CONFIG_BSP_BUTTON_1_GPIO=0
CONFIG_BSP_BUTTON_1_LEVEL=0
# LEDs
CONFIG_BSP_LEDS_NUM=0