example: Remove external platform for light_wifi_prov example

This commit is contained in:
WanqQixiang
2025-04-14 19:48:09 +08:00
parent f1f3fb79d1
commit 9eec16e3e1
73 changed files with 106 additions and 4438 deletions
-7
View File
@@ -408,13 +408,6 @@ build_esp_matter_examples:
- cp sdkconfig.defaults sdkconfig.defaults.backup
- cp sdkconfig.defaults.ext_plat_ci sdkconfig.defaults
# steps for external platform build for light_wifi_prov app
- cd ${ESP_MATTER_PATH}/examples/light_wifi_prov
- cp sdkconfig.defaults.esp32s3 sdkconfig.defaults.esp32s3.backup
- cp sdkconfig.defaults.esp32s3.ext_plat_ci sdkconfig.defaults.esp32s3
- cp sdkconfig.defaults.esp32c3 sdkconfig.defaults.esp32c3.backup
- cp sdkconfig.defaults.esp32c3.ext_plat_ci sdkconfig.defaults.esp32c3
- cd ${ESP_MATTER_PATH}
- pip install -r tools/ci/requirements-build.txt
- python tools/ci/build_apps.py ./examples --no_pytest
@@ -1,506 +0,0 @@
// SPDX-FileCopyrightText: 2020-2021 Project CHIP Authors
//
// SPDX-License-Identifier: Apache-2.0
//
// SPDX-FileContributor: 2024 Espressif Systems (Shanghai) PTE LTD
//
// Modified the original code to add a secondary BLE advertisement.
//
// For original code and license information, please refer to
// https://github.com/project-chip/connectedhomeip
/*
*
* Copyright (c) 2020-2021 Project CHIP Authors
* Copyright (c) 2018 Nest Labs, Inc.
* All rights reserved.
*
* 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
* Provides an implementation of the BLEManager singleton object
* for the ESP32 platform.
*/
#pragma once
#include <string>
#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
#include "sdkconfig.h"
#include <lib/core/Optional.h>
#ifdef CONFIG_BT_BLUEDROID_ENABLED
#include "esp_bt.h"
#include "esp_gap_ble_api.h"
#ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER
#include "esp_gattc_api.h"
#endif
#include "esp_gatts_api.h"
#include <lib/core/CHIPCallback.h>
#elif defined(CONFIG_BT_NIMBLE_ENABLED)
/* min max macros in NimBLE can cause build issues with generic min max
* functions defined in CHIP.*/
#define min
#define max
#include "host/ble_hs.h"
#undef min
#undef max
/* GATT context */
struct ble_gatt_char_context
{
uint16_t conn_handle;
uint16_t attr_handle;
struct ble_gatt_access_ctxt * ctxt;
void * arg;
};
#define MAX_ADV_DATA_LEN 31
#define MAX_DEVICE_NAME_LEN 29
#endif // CONFIG_BT_BLUEDROID_ENABLED
#include <ble/Ble.h>
#ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER
#include <platform/ESP32/ChipDeviceScanner.h>
#ifdef CONFIG_BT_NIMBLE_ENABLED
#include "nimble/blecent.h"
#endif // CONFIG_BT_NIMBLE_ENABLED
#endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER
#define MAX_SCAN_RSP_DATA_LEN 31
namespace chip {
namespace DeviceLayer {
namespace Internal {
#ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER
enum class BleScanState : uint8_t
{
kNotScanning,
kScanForDiscriminator,
kScanForAddress,
kConnecting,
};
struct BLEAdvConfig
{
char * mpBleName;
uint32_t mAdapterId;
uint8_t mMajor;
uint8_t mMinor;
uint16_t mVendorId;
uint16_t mProductId;
uint64_t mDeviceId;
uint8_t mPairingStatus;
uint8_t mType;
uint16_t mDuration;
const char * mpAdvertisingUUID;
};
struct BLEScanConfig
{
// If an active scan for connection is being performed
BleScanState mBleScanState = BleScanState::kNotScanning;
// If scanning by discriminator, what are we scanning for
SetupDiscriminator mDiscriminator;
// If scanning by address, what address are we searching for
std::string mAddress;
// Optional argument to be passed to callback functions provided by the BLE scan/connect requestor
void * mAppState = nullptr;
};
#endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER
/**
* Concrete implementation of the BLEManager singleton object for the ESP32 platform.
*/
class BLEManagerImpl final : public BLEManager,
private Ble::BleLayer,
private Ble::BlePlatformDelegate,
#ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER
private Ble::BleApplicationDelegate,
private Ble::BleConnectionDelegate,
private ChipDeviceScannerDelegate
#else
private Ble::BleApplicationDelegate
#endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER
{
public:
BLEManagerImpl() {}
#ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER
CHIP_ERROR ConfigureBle(uint32_t aAdapterId, bool aIsCentral);
#ifdef CONFIG_BT_BLUEDROID_ENABLED
static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t * param);
#endif // CONFIG_BT_BLUEDROID_ENABLED
#endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER
CHIP_ERROR ConfigureScanResponseData(ByteSpan data);
void ClearScanResponseData(void);
CHIP_ERROR SetSecondaryGATTService(struct ble_gatt_svc_def *gatt_svc, size_t gattSvcIndex)
{
if (!gatt_svc || gattSvcIndex > 1)
{
return CHIP_ERROR_INVALID_ARGUMENT;
}
mSecondGATTServiceIndex = gattSvcIndex;
memcpy(&mGATTServices[gattSvcIndex], gatt_svc, sizeof(struct ble_gatt_svc_def));
return CHIP_NO_ERROR;
}
using BleGapEventHandler = int(*)(struct ble_gap_event * event, void * arg);
void SetSecondaryAdvGapEventHandler(BleGapEventHandler handler) { mSecondaryBleGapEventHandler = handler; }
CHIP_ERROR SetSecondaryAdvDeviceName(const char *deviceName)
{
strncpy(mSecondaryAdvDeviceName, deviceName, MAX_DEVICE_NAME_LEN);
mSecondaryAdvDeviceName[MAX_DEVICE_NAME_LEN] = 0;
return CHIP_NO_ERROR;
}
CHIP_ERROR SetSecondaryAdvUuid(const ByteSpan &uuid)
{
if (uuid.size() != 16)
{
return CHIP_ERROR_INVALID_ARGUMENT;
}
mSecondaryAdvUuid.u.type = BLE_UUID_TYPE_128;
memcpy(mSecondaryAdvUuid.value, uuid.data(), uuid.size());
return CHIP_NO_ERROR;
}
void SetSecondaryBleSmConfig(bool bleBonding, bool bleSmSc)
{
mSecondaryBleBonding = bleBonding;
mSecondaryBleSmSc = bleSmSc;
}
void RefreshAdv(void);
private:
chip::Optional<chip::ByteSpan> mScanResponse;
uint8_t scanResponseBuffer[MAX_SCAN_RSP_DATA_LEN];
// Allow the BLEManager interface class to delegate method calls to
// the implementation methods provided by this class.
friend BLEManager;
// ===== Members that implement the BLEManager internal interface.
CHIP_ERROR _Init(void);
void _Shutdown();
bool _IsAdvertisingEnabled(void);
CHIP_ERROR _SetAdvertisingEnabled(bool val);
bool _IsAdvertising(void);
CHIP_ERROR _SetAdvertisingMode(BLEAdvertisingMode mode);
CHIP_ERROR _GetDeviceName(char * buf, size_t bufSize);
CHIP_ERROR _SetDeviceName(const char * deviceName);
uint16_t _NumConnections(void);
void _OnPlatformEvent(const ChipDeviceEvent * event);
#ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER
void HandlePlatformSpecificBLEEvent(const ChipDeviceEvent * event);
CHIP_ERROR _SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val);
#endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER
::chip::Ble::BleLayer * _GetBleLayer(void);
// ===== Members that implement virtual methods on BlePlatformDelegate.
CHIP_ERROR SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId,
const Ble::ChipBleUUID * charId) override;
CHIP_ERROR UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId,
const Ble::ChipBleUUID * charId) override;
CHIP_ERROR CloseConnection(BLE_CONNECTION_OBJECT conId) override;
uint16_t GetMTU(BLE_CONNECTION_OBJECT conId) const override;
CHIP_ERROR SendIndication(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId,
System::PacketBufferHandle pBuf) override;
CHIP_ERROR SendWriteRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId,
System::PacketBufferHandle pBuf) override;
// ===== Members that implement virtual methods on BleApplicationDelegate.
void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) override;
// ===== Members that implement virtual methods on BleConnectionDelegate.
#ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER
void NewConnection(chip::Ble::BleLayer * bleLayer, void * appState, const SetupDiscriminator & connDiscriminator) override;
void NewConnection(chip::Ble::BleLayer * bleLayer, void * appState, BLE_CONNECTION_OBJECT connObj) override{};
CHIP_ERROR CancelConnection() override;
// ===== Members that implement virtual methods on ChipDeviceScannerDelegate
#ifdef CONFIG_BT_NIMBLE_ENABLED
virtual void OnDeviceScanned(const struct ble_hs_adv_fields & fields, const ble_addr_t & addr,
const chip::Ble::ChipBLEDeviceIdentificationInfo & info) override;
#elif defined(CONFIG_BT_BLUEDROID_ENABLED)
virtual void OnDeviceScanned(esp_ble_addr_type_t & addr_type, esp_bd_addr_t & addr,
const chip::Ble::ChipBLEDeviceIdentificationInfo & info) override;
#endif // CONFIG_BT_NIMBLE_ENABLED
void OnScanComplete() override;
#endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER
// ===== Members for internal use by the following friends.
friend BLEManager & BLEMgr(void);
friend BLEManagerImpl & BLEMgrImpl(void);
static BLEManagerImpl sInstance;
// ===== Private members reserved for use by this class only.
enum class Flags : uint16_t
{
kAsyncInitCompleted = 0x0001, /**< One-time asynchronous initialization actions have been performed. */
kESPBLELayerInitialized = 0x0002, /**< The ESP BLE layer has been initialized. */
kAppRegistered = 0x0004, /**< The CHIPoBLE application has been registered with the ESP BLE layer. */
kAttrsRegistered = 0x0008, /**< The CHIPoBLE GATT attributes have been registered with the ESP BLE layer. */
kGATTServiceStarted = 0x0010, /**< The CHIPoBLE GATT service has been started. */
kAdvertisingConfigured = 0x0020, /**< CHIPoBLE advertising has been configured in the ESP BLE layer. */
kAdvertising = 0x0040, /**< The system is currently CHIPoBLE advertising. */
kControlOpInProgress = 0x0080, /**< An async control operation has been issued to the ESP BLE layer. */
kAdvertisingEnabled = 0x0100, /**< The application has enabled CHIPoBLE advertising. */
kFastAdvertisingEnabled = 0x0200, /**< The application has enabled fast advertising. */
kUseCustomDeviceName = 0x0400, /**< The application has configured a custom BLE device name. */
kAdvertisingRefreshNeeded = 0x0800, /**< The advertising configuration/state in ESP BLE layer needs to be updated. */
kExtAdvertisingEnabled = 0x1000, /**< The application has enabled Extended BLE announcement. */
};
enum
{
kMaxConnections = BLE_LAYER_NUM_BLE_ENDPOINTS,
kMaxDeviceNameLength = 16
};
#ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER
BLEAdvConfig mBLEAdvConfig;
#endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER
#ifdef CONFIG_BT_NIMBLE_ENABLED
uint16_t mSubscribedConIds[kMaxConnections];
#endif // CONFIG_BT_NIMBLE_ENABLED
struct CHIPoBLEConState
{
System::PacketBufferHandle PendingIndBuf;
uint16_t ConId;
uint16_t MTU : 10;
uint16_t Allocated : 1;
uint16_t Subscribed : 1;
uint16_t Unused : 4;
void Set(uint16_t conId)
{
PendingIndBuf = nullptr;
ConId = conId;
MTU = 0;
Allocated = 1;
Subscribed = 0;
Unused = 0;
}
void Reset()
{
PendingIndBuf = nullptr;
ConId = BLE_CONNECTION_UNINITIALIZED;
MTU = 0;
Allocated = 0;
Subscribed = 0;
Unused = 0;
}
};
CHIPoBLEConState mCons[kMaxConnections];
CHIPoBLEServiceMode mServiceMode;
#ifdef CONFIG_BT_BLUEDROID_ENABLED
esp_gatt_if_t mAppIf;
#elif defined(CONFIG_BT_NIMBLE_ENABLED)
uint16_t mNumGAPCons;
#endif // CONFIG_BT_BLUEDROID_ENABLED
uint16_t mServiceAttrHandle;
uint16_t mRXCharAttrHandle;
uint16_t mTXCharAttrHandle;
#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
uint16_t mC3CharAttrHandle;
#endif
uint16_t mTXCharCCCDAttrHandle;
BitFlags<Flags> mFlags;
char mDeviceName[kMaxDeviceNameLength + 1];
CHIP_ERROR MapBLEError(int bleErr);
void DriveBLEState(void);
CHIP_ERROR InitESPBleLayer(void);
void DeinitESPBleLayer(void);
CHIP_ERROR ConfigureAdvertisingData(void);
CHIP_ERROR StartAdvertising(void);
void StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs);
void CancelBleAdvTimeoutTimer(void);
static void BleAdvTimeoutHandler(System::Layer *, void *);
#ifdef CONFIG_BT_BLUEDROID_ENABLED
void HandleGATTControlEvent(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t * param);
void HandleGATTCommEvent(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t * param);
void HandleRXCharWrite(esp_ble_gatts_cb_param_t * param);
void HandleTXCharRead(esp_ble_gatts_cb_param_t * param);
void HandleTXCharCCCDRead(esp_ble_gatts_cb_param_t * param);
void HandleTXCharCCCDWrite(esp_ble_gatts_cb_param_t * param);
void HandleTXCharConfirm(CHIPoBLEConState * conState, esp_ble_gatts_cb_param_t * param);
void HandleDisconnect(esp_ble_gatts_cb_param_t * param);
CHIPoBLEConState * GetConnectionState(uint16_t conId, bool allocate = false);
bool ReleaseConnectionState(uint16_t conId);
#ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER
CHIP_ERROR HandleGAPConnect(esp_ble_gattc_cb_param_t p_data);
CHIP_ERROR HandleGAPCentralConnect(esp_ble_gattc_cb_param_t p_data);
static void HandleConnectFailed(CHIP_ERROR error);
static void ConnectDevice(esp_bd_addr_t & addr, esp_ble_addr_type_t addr_type, uint16_t timeout);
void HandleGAPConnectionFailed();
CHIP_ERROR HandleRXNotify(esp_ble_gattc_cb_param_t p_data);
#endif
static void HandleGATTEvent(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t * param);
static void HandleGAPEvent(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t * param);
#elif defined(CONFIG_BT_NIMBLE_ENABLED)
CHIP_ERROR DeinitBLE();
static void ClaimBLEMemory(System::Layer *, void *);
void HandleRXCharRead(struct ble_gatt_char_context * param);
void HandleRXCharWrite(struct ble_gatt_char_context * param);
void HandleTXCharWrite(struct ble_gatt_char_context * param);
void HandleTXCharRead(struct ble_gatt_char_context * param);
void HandleTXCharCCCDRead(void * param);
void HandleTXCharCCCDWrite(struct ble_gap_event * gapEvent);
CHIP_ERROR HandleTXComplete(struct ble_gap_event * gapEvent);
CHIP_ERROR HandleGAPConnect(struct ble_gap_event * gapEvent);
CHIP_ERROR HandleGAPPeripheralConnect(struct ble_gap_event * gapEvent);
CHIP_ERROR HandleGAPDisconnect(struct ble_gap_event * gapEvent);
CHIP_ERROR SetSubscribed(uint16_t conId);
bool UnsetSubscribed(uint16_t conId);
bool IsSubscribed(uint16_t conId);
static void ConnectDevice(const ble_addr_t & addr, uint16_t timeout);
CHIP_ERROR HandleGAPCentralConnect(struct ble_gap_event * gapEvent);
void HandleGAPConnectionFailed(struct ble_gap_event * gapEvent, CHIP_ERROR error);
static CHIP_ERROR bleprph_set_random_addr(void);
static void bleprph_host_task(void * param);
static void bleprph_on_sync(void);
static void bleprph_on_reset(int);
static const struct ble_gatt_svc_def CHIPoBLEGATTService;
static int ble_svr_gap_event(struct ble_gap_event * event, void * arg);
static int gatt_svr_chr_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt * ctxt, void * arg);
#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
static int gatt_svr_chr_access_additional_data(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt * ctxt,
void * arg);
void HandleC3CharRead(struct ble_gatt_char_context * param);
#endif /* CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING */
#ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER
static int btshell_on_mtu(uint16_t conn_handle, const struct ble_gatt_error * error, uint16_t mtu, void * arg);
bool SubOrUnsubChar(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId,
bool subscribe);
static void OnGattDiscComplete(const struct peer * peer, int status, void * arg);
static void HandleConnectFailed(CHIP_ERROR error);
CHIP_ERROR HandleRXNotify(struct ble_gap_event * event);
#endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER
#endif // CONFIG_BT_NIMBLE_ENABLED
#ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER
static void CancelConnect(void);
static void HandleConnectTimeout(chip::System::Layer *, void * context);
void InitiateScan(BleScanState scanType);
static void InitiateScan(intptr_t arg);
void HandleAdvertisementTimer(System::Layer * systemLayer, void * context);
void HandleAdvertisementTimer();
void CleanScanConfig();
BLEScanConfig mBLEScanConfig;
bool mIsCentral;
#endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER
static void DriveBLEState(intptr_t arg);
uint8_t mAdvData[MAX_ADV_DATA_LEN];
uint16_t mAdvDataLen;
static constexpr uint8_t kChipAdvInstance = 0;
// Three GATT service
// mGATTServices[0] is for Matter-over-BLE
// mGATTServices[1] is for wifi_provisioning over BLE
// mGATTServices[2] is NULL
struct ble_gatt_svc_def mGATTServices[3];
// Secondary Advertisement
static int secondary_ble_svr_gap_event(struct ble_gap_event * event, void * arg);
CHIP_ERROR ConfigureSecondaryAdvertisingData(void);
CHIP_ERROR StartSecondaryAdvertising(void);
char mSecondaryAdvDeviceName[MAX_DEVICE_NAME_LEN + 1];
size_t mSecondGATTServiceIndex = 1;
ble_uuid128_t mSecondaryAdvUuid;
bool mSecondaryBleBonding;
bool mSecondaryBleSmSc;
ble_hs_adv_fields mSecondaryAdvFields;
ble_hs_adv_fields mSecondaryRespFields;
uint8_t *mSecondaryMfgData;
size_t mSecondaryMfgDataLen;
BleGapEventHandler mSecondaryBleGapEventHandler = nullptr;
static constexpr uint8_t kSecondaryAdvInstance = 1;
};
/**
* Returns a reference to the public interface of the BLEManager singleton object.
*
* Internal components should use this to access features of the BLEManager object
* that are common to all platforms.
*/
inline BLEManager & BLEMgr(void)
{
return BLEManagerImpl::sInstance;
}
/**
* Returns the platform-specific implementation of the BLEManager singleton object.
*
* Internal components can use this to gain access to features of the BLEManager
* that are specific to the ESP32 platform.
*/
inline BLEManagerImpl & BLEMgrImpl(void)
{
return BLEManagerImpl::sInstance;
}
inline ::chip::Ble::BleLayer * BLEManagerImpl::_GetBleLayer()
{
return this;
}
inline bool BLEManagerImpl::_IsAdvertisingEnabled(void)
{
return mFlags.Has(Flags::kAdvertisingEnabled);
}
inline bool BLEManagerImpl::_IsAdvertising(void)
{
return mFlags.Has(Flags::kAdvertising);
}
} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
@@ -1,268 +0,0 @@
# SPDX-FileCopyrightText: 2023 Project CHIP Authors
#
# SPDX-License-Identifier: Apache-2.0
#
# SPDX-FileContributor: 2024 Espressif Systems (Shanghai) PTE LTD
#
# Modified the original code to add a secondary BLE advertisement.
#
# For original code and license information, please refer to
# https://github.com/project-chip/connectedhomeip
# Copyright (c) 2023 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.
import("//build_overrides/chip.gni")
import("${chip_root}/build/chip/buildconfig_header.gni")
import("${chip_root}/src/lib/core/core.gni")
import("${chip_root}/src/platform/device.gni")
declare_args() {
# By default use default/example implementation of CommissionableDataProvider,
# DeviceAttestationCredentialsProvider and DeviceInstanceInfoProvider
chip_use_transitional_commissionable_data_provider = true
chip_use_transitional_device_instance_info_provider = true
chip_use_factory_data_provider = false
chip_use_device_info_provider = false
chip_config_software_version_number = 0
chip_enable_chipoble = false
chip_bt_nimble_enabled = false
chip_bt_bluedroid_enabled = false
chip_enable_ble_controller = false
chip_use_secure_cert_dac_provider = false
chip_use_esp32_ecdsa_peripheral = false
chip_enable_ethernet = false
chip_max_discovered_ip_addresses = 5
chip_enable_route_hook = false
chip_memory_alloc_mode = "default"
}
buildconfig_header("custom_buildconfig") {
header = "CHIPDeviceBuildConfig.h"
header_dir = "platform"
defines = [
"CHIP_DEVICE_CONFIG_ENABLE_WPA=false",
"CHIP_ENABLE_OPENTHREAD=${chip_enable_openthread}",
"CHIP_DEVICE_CONFIG_THREAD_FTD=${chip_openthread_ftd}",
"OPENTHREAD_CONFIG_ENABLE_TOBLE=false",
"CHIP_BYPASS_RENDEZVOUS=false",
"CHIP_STACK_LOCK_TRACKING_ENABLED=true",
"CHIP_STACK_LOCK_TRACKING_ERROR_FATAL=false",
"CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING=false",
"CHIP_DEVICE_CONFIG_RUN_AS_ROOT=false",
"CHIP_DEVICE_LAYER_TARGET_ESP32=1",
"CHIP_DEVICE_LAYER_TARGET=ESP32_custom",
"CHIP_USE_TRANSITIONAL_COMMISSIONABLE_DATA_PROVIDER=${chip_use_transitional_commissionable_data_provider}",
"CHIP_USE_TRANSITIONAL_DEVICE_INSTANCE_INFO_PROVIDER=${chip_use_transitional_device_instance_info_provider}",
"CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE=${chip_enable_chipoble}",
"BLE_PLATFORM_CONFIG_INCLUDE=<platform/ESP32_custom/BlePlatformConfig.h>",
"CHIP_DEVICE_PLATFORM_CONFIG_INCLUDE=<platform/ESP32_custom/CHIPDevicePlatformConfig.h>",
"CHIP_PLATFORM_CONFIG_INCLUDE=<platform/ESP32_custom/CHIPPlatformConfig.h>",
"INET_CONFIG_INCLUDE=<platform/ESP32_custom/InetPlatformConfig.h>",
"SYSTEM_PLATFORM_CONFIG_INCLUDE=<platform/ESP32_custom/SystemPlatformConfig.h>",
"EXTERNAL_CONFIGURATIONMANAGERIMPL_HEADER=<platform/ESP32_custom/ConfigurationManagerImpl.h>",
"EXTERNAL_CHIPDEVICEPLATFORMEVENT_HEADER=<platform/ESP32_custom/CHIPDevicePlatformEvent.h>",
"EXTERNAL_CONNECTIVITYMANAGERIMPL_HEADER=<platform/ESP32_custom/ConnectivityManagerImpl.h>",
"EXTERNAL_BLEMANAGERIMPL_HEADER=<platform/ESP32_custom/BLEManagerImpl.h>",
"EXTERNAL_KEYVALUESTOREMANAGERIMPL_HEADER=<platform/ESP32_custom/KeyValueStoreManagerImpl.h>",
"EXTERNAL_PLATFORMMANAGERIMPL_HEADER=<platform/ESP32_custom/PlatformManagerImpl.h>",
"EXTERNAL_ESP32UTILS_HEADER=<platform/ESP32_custom/ESP32Utils.h>",
"EXTERNAL_ESP32OTAIMAGEPROCESSORIMPL_HEADER=<platform/ESP32_custom/OTAImageProcessorImpl.h>",
"EXTERNAL_ESP32DEVICEINFOPROVIDER_HEADER=<platform/ESP32_custom/ESP32DeviceInfoProvider.h>",
"EXTERNAL_ESP32FACTORYDATAPROVIDER_HEADER=<platform/ESP32_custom/ESP32FactoryDataProvider.h>",
"EXTERNAL_ESP32SECURECERTDACPROVIDER_HEADER=<platform/ESP32_custom/ESP32SecureCertDACProvider.h>",
"CHIP_CONFIG_SOFTWARE_VERSION_NUMBER=${chip_config_software_version_number}",
"CHIP_DEVICE_CONFIG_MAX_DISCOVERED_IP_ADDRESSES=${chip_max_discovered_ip_addresses}",
]
if (chip_enable_ota_requestor) {
defines += [ "CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR=1" ]
}
}
group("platform_buildconfig") {
public_deps = [ ":custom_buildconfig" ]
}
static_library("ESP32_custom") {
sources = [
"${chip_root}/src/platform/SingletonConfigurationManager.cpp",
"CHIPDevicePlatformConfig.h",
"CHIPDevicePlatformEvent.h",
"ConfigurationManagerImpl.cpp",
"ConfigurationManagerImpl.h",
"ConnectivityManagerImpl.cpp",
"ConnectivityManagerImpl.h",
"DiagnosticDataProviderImpl.cpp",
"DiagnosticDataProviderImpl.h",
"ESP32Config.cpp",
"ESP32Config.h",
"ESP32Utils.cpp",
"ESP32Utils.h",
"KeyValueStoreManagerImpl.cpp",
"KeyValueStoreManagerImpl.h",
"Logging.cpp",
"LwIPCoreLock.cpp",
"PlatformManagerImpl.cpp",
"PlatformManagerImpl.h",
"SystemTimeSupport.cpp",
"SystemTimeSupport.h",
]
deps = [
"${chip_root}/src/lib/dnssd:platform_header",
"${chip_root}/src/platform/logging:headers",
"${chip_root}/src/setup_payload",
]
public = [
"${chip_root}/src/credentials/CHIPCert.h",
"${chip_root}/src/credentials/DeviceAttestationCredsProvider.h",
]
public_deps = [
":platform_buildconfig",
"${chip_root}/src/crypto",
"${chip_root}/src/platform:platform_base",
]
if (chip_config_memory_management == "platform") {
if (chip_memory_alloc_mode == "internal") {
sources += [ "CHIPMem-PlatformInternal.cpp" ]
} else if (chip_memory_alloc_mode == "external") {
sources += [ "CHIPMem-PlatformExternal.cpp" ]
} else {
sources += [ "CHIPMem-PlatformDefault.cpp" ]
}
}
if (chip_enable_ota_requestor) {
sources += [
"OTAImageProcessorImpl.cpp",
"OTAImageProcessorImpl.h",
]
}
if (chip_enable_ble) {
sources += ["BLEManagerImpl.h"]
if (chip_enable_ble_controller) {
sources += [ "ChipDeviceScanner.h" ]
}
if (chip_bt_nimble_enabled) {
sources += [ "nimble/BLEManagerImpl.cpp" ]
if (chip_enable_ble_controller) {
sources += [
"nimble/ChipDeviceScanner.cpp",
"nimble/blecent.h",
"nimble/misc.c",
"nimble/peer.c",
]
}
}
if (chip_bt_bluedroid_enabled) {
sources += [ "bluedroid/BLEManagerImpl.cpp" ]
if (chip_enable_ble_controller) {
sources += [ "bluedroid/ChipDeviceScanner.cpp" ]
}
}
}
if (chip_enable_wifi) {
sources += [
"ConnectivityManagerImpl_WiFi.cpp",
"NetworkCommissioningDriver.cpp",
"NetworkCommissioningDriver.h",
]
}
if (chip_mdns == "platform") {
sources += [ "DnssdImpl.cpp" ]
}
if (chip_enable_ethernet) {
sources += [
"ConnectivityManagerImpl_Ethernet.cpp",
"NetworkCommissioningDriver_Ethernet.cpp",
]
}
if (chip_enable_ethernet || chip_enable_wifi) {
if (chip_mdns == "platform") {
sources += [
"ESP32DnssdImpl.cpp",
"ESP32DnssdImpl.h",
]
}
if (chip_mdns == "minimal") {
sources += [ "ESP32EndpointQueueFilter.h" ]
}
if (chip_enable_route_hook) {
sources += [
"route_hook/ESP32RouteHook.c",
"route_hook/ESP32RouteHook.h",
"route_hook/ESP32RouteTable.c",
"route_hook/ESP32RouteTable.h",
]
}
}
if (chip_enable_openthread) {
sources += [
"../OpenThread/GenericNetworkCommissioningThreadDriver.cpp",
"../OpenThread/GenericNetworkCommissioningThreadDriver.h",
"../OpenThread/OpenThreadUtils.cpp",
"OpenthreadLauncher.cpp",
"OpenthreadLauncher.h",
"ThreadStackManagerImpl.cpp",
"ThreadStackManagerImpl.h",
]
if (chip_mdns == "platform") {
sources += [
"../OpenThread/OpenThreadDnssdImpl.cpp",
"../OpenThread/OpenThreadDnssdImpl.h",
]
}
configs -= [ "${chip_root}/build/config/compiler:warnings_default" ]
}
if (chip_use_factory_data_provider) {
sources += [
"ESP32FactoryDataProvider.cpp",
"ESP32FactoryDataProvider.h",
"StaticESP32DeviceInfoProvider.cpp",
"StaticESP32DeviceInfoProvider.h",
]
}
if (chip_use_secure_cert_dac_provider) {
sources += [
"ESP32SecureCertDACProvider.cpp",
"ESP32SecureCertDACProvider.h",
]
}
if (chip_use_device_info_provider) {
sources += [
"ESP32DeviceInfoProvider.cpp",
"ESP32DeviceInfoProvider.h",
]
}
cflags = [ "-Wconversion" ]
}
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/BlePlatformConfig.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/CHIPDevicePlatformConfig.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/CHIPDevicePlatformEvent.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/CHIPMem-PlatformDefault.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/CHIPMem-PlatformExternal.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/CHIPMem-PlatformInternal.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/CHIPPlatformConfig.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ChipDeviceScanner.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ConfigurationManagerImpl.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ConfigurationManagerImpl.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ConnectivityManagerImpl.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ConnectivityManagerImpl.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ConnectivityManagerImpl_Ethernet.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ConnectivityManagerImpl_WiFi.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/DiagnosticDataProviderImpl.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/DiagnosticDataProviderImpl.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/DnssdImpl.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ESP32CHIPCryptoPAL.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ESP32CHIPCryptoPAL.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ESP32Config.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ESP32Config.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ESP32DeviceInfoProvider.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ESP32DeviceInfoProvider.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ESP32DnssdImpl.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ESP32DnssdImpl.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ESP32EndpointQueueFilter.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ESP32FactoryDataProvider.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ESP32FactoryDataProvider.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ESP32SecureCertDACProvider.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ESP32SecureCertDACProvider.h
@@ -1,406 +0,0 @@
// SPDX-FileCopyrightText: 2020 Project CHIP Authors
//
// SPDX-License-Identifier: Apache-2.0
//
// SPDX-FileContributor: 2024 Espressif Systems (Shanghai) PTE LTD
//
// Modified the original code to add a secondary BLE advertisement.
//
// For original code and license information, please refer to
// https://github.com/project-chip/connectedhomeip
/*
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2018 Nest Labs, Inc.
* All rights reserved.
*
* 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
* General utility methods for the ESP32 platform.
*/
/* this file behaves like a config.h, comes first */
#include <platform/internal/CHIPDeviceLayerInternal.h>
#include <lib/core/ErrorStr.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/ESP32/ESP32Utils.h>
#include "esp_event.h"
#include "esp_netif.h"
#include "esp_netif_net_stack.h"
#include "esp_wifi.h"
#include "nvs.h"
using namespace ::chip::DeviceLayer::Internal;
using chip::DeviceLayer::Internal::DeviceNetworkInfo;
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
CHIP_ERROR ESP32Utils::IsAPEnabled(bool & apEnabled)
{
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP
wifi_mode_t curWiFiMode;
esp_err_t err = esp_wifi_get_mode(&curWiFiMode);
if (err != ESP_OK)
{
ChipLogError(DeviceLayer, "esp_wifi_get_mode() failed: %s", esp_err_to_name(err));
return ESP32Utils::MapError(err);
}
apEnabled = (curWiFiMode == WIFI_MODE_AP || curWiFiMode == WIFI_MODE_APSTA);
return CHIP_NO_ERROR;
#else
return CHIP_ERROR_NOT_IMPLEMENTED;
#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP
}
CHIP_ERROR ESP32Utils::IsStationEnabled(bool & staEnabled)
{
wifi_mode_t curWiFiMode;
esp_err_t err = esp_wifi_get_mode(&curWiFiMode);
if (err != ESP_OK)
{
ChipLogError(DeviceLayer, "esp_wifi_get_mode() failed: %s", esp_err_to_name(err));
return ESP32Utils::MapError(err);
}
staEnabled = (curWiFiMode == WIFI_MODE_STA || curWiFiMode == WIFI_MODE_APSTA);
return CHIP_NO_ERROR;
}
bool ESP32Utils::IsStationProvisioned(void)
{
wifi_config_t stationConfig;
return (esp_wifi_get_config(WIFI_IF_STA, &stationConfig) == ERR_OK && stationConfig.sta.ssid[0] != 0);
}
CHIP_ERROR ESP32Utils::IsStationConnected(bool & connected)
{
wifi_ap_record_t apInfo;
connected = (esp_wifi_sta_get_ap_info(&apInfo) == ESP_OK && apInfo.ssid[0] != 0);
return CHIP_NO_ERROR;
}
CHIP_ERROR ESP32Utils::StartWiFiLayer(void)
{
int8_t ignored;
bool wifiStarted;
// There appears to be no direct way to ask the ESP WiFi layer if esp_wifi_start()
// has been called. So use the ESP_ERR_WIFI_NOT_STARTED error returned by
// esp_wifi_get_max_tx_power() to detect this.
esp_err_t err = esp_wifi_get_max_tx_power(&ignored);
switch (err)
{
case ESP_OK:
wifiStarted = true;
break;
case ESP_ERR_WIFI_NOT_STARTED:
wifiStarted = false;
break;
default:
return ESP32Utils::MapError(err);
}
if (!wifiStarted)
{
ChipLogProgress(DeviceLayer, "Starting ESP WiFi layer");
err = esp_wifi_start();
if (err != ESP_OK)
{
ChipLogError(DeviceLayer, "esp_wifi_start() failed: %s", esp_err_to_name(err));
return ESP32Utils::MapError(err);
}
}
return CHIP_NO_ERROR;
}
CHIP_ERROR ESP32Utils::EnableStationMode(void)
{
wifi_mode_t curWiFiMode;
// Get the current ESP WiFI mode.
esp_err_t err = esp_wifi_get_mode(&curWiFiMode);
if (err != ESP_OK)
{
ChipLogError(DeviceLayer, "esp_wifi_get_mode() failed: %s", esp_err_to_name(err));
return ESP32Utils::MapError(err);
}
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP
// If station mode is not already enabled (implying the current mode is WIFI_MODE_AP), change
// the mode to WIFI_MODE_APSTA.
if (curWiFiMode == WIFI_MODE_AP)
{
ChipLogProgress(DeviceLayer, "Changing ESP WiFi mode: %s -> %s", WiFiModeToStr(WIFI_MODE_AP),
WiFiModeToStr(WIFI_MODE_APSTA));
err = esp_wifi_set_mode(WIFI_MODE_APSTA);
if (err != ESP_OK)
{
ChipLogError(DeviceLayer, "esp_wifi_set_mode() failed: %s", esp_err_to_name(err));
return ESP32Utils::MapError(err);
}
}
#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP
return CHIP_NO_ERROR;
}
CHIP_ERROR ESP32Utils::SetAPMode(bool enabled)
{
wifi_mode_t curWiFiMode;
wifi_mode_t targetWiFiMode = WIFI_MODE_STA;
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP
targetWiFiMode = (enabled) ? WIFI_MODE_APSTA : WIFI_MODE_STA;
#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP
// Get the current ESP WiFI mode.
esp_err_t err = esp_wifi_get_mode(&curWiFiMode);
if (err != ESP_OK)
{
ChipLogError(DeviceLayer, "esp_wifi_get_mode() failed: %s", esp_err_to_name(err));
return ESP32Utils::MapError(err);
}
// If station mode is not already enabled (implying the current mode is WIFI_MODE_AP), change
// the mode to WIFI_MODE_APSTA.
if (curWiFiMode != targetWiFiMode)
{
ChipLogProgress(DeviceLayer, "Changing ESP WiFi mode: %s -> %s", WiFiModeToStr(curWiFiMode), WiFiModeToStr(targetWiFiMode));
err = esp_wifi_set_mode(targetWiFiMode);
if (err != ESP_OK)
{
ChipLogError(DeviceLayer, "esp_wifi_set_mode() failed: %s", esp_err_to_name(err));
return ESP32Utils::MapError(err);
}
}
return CHIP_NO_ERROR;
}
int ESP32Utils::OrderScanResultsByRSSI(const void * _res1, const void * _res2)
{
const wifi_ap_record_t * res1 = (const wifi_ap_record_t *) _res1;
const wifi_ap_record_t * res2 = (const wifi_ap_record_t *) _res2;
if (res1->rssi > res2->rssi)
{
return -1;
}
if (res1->rssi < res2->rssi)
{
return 1;
}
return 0;
}
const char * ESP32Utils::WiFiModeToStr(wifi_mode_t wifiMode)
{
switch (wifiMode)
{
case WIFI_MODE_NULL:
return "NULL";
case WIFI_MODE_STA:
return "STA";
case WIFI_MODE_AP:
return "AP";
case WIFI_MODE_APSTA:
return "STA+AP";
default:
return "(unknown)";
}
}
struct netif * ESP32Utils::GetStationNetif(void)
{
return GetNetif(kDefaultWiFiStationNetifKey);
}
CHIP_ERROR ESP32Utils::GetWiFiStationProvision(Internal::DeviceNetworkInfo & netInfo, bool includeCredentials)
{
wifi_config_t stationConfig;
esp_err_t err = esp_wifi_get_config(WIFI_IF_STA, &stationConfig);
if (err != ESP_OK)
{
return ESP32Utils::MapError(err);
}
VerifyOrReturnError(stationConfig.sta.ssid[0] != 0, CHIP_ERROR_INCORRECT_STATE);
netInfo.NetworkId = kWiFiStationNetworkId;
netInfo.FieldPresent.NetworkId = true;
memcpy(netInfo.WiFiSSID, stationConfig.sta.ssid,
std::min(strlen(reinterpret_cast<char *>(stationConfig.sta.ssid)) + 1, sizeof(netInfo.WiFiSSID)));
// Enforce that netInfo wifiSSID is null terminated
netInfo.WiFiSSID[kMaxWiFiSSIDLength] = '\0';
if (includeCredentials)
{
static_assert(sizeof(netInfo.WiFiKey) < 255, "Our min might not fit in netInfo.WiFiKeyLen");
netInfo.WiFiKeyLen = static_cast<uint8_t>(std::min(strlen((char *) stationConfig.sta.password), sizeof(netInfo.WiFiKey)));
memcpy(netInfo.WiFiKey, stationConfig.sta.password, netInfo.WiFiKeyLen);
}
return CHIP_NO_ERROR;
}
CHIP_ERROR ESP32Utils::SetWiFiStationProvision(const Internal::DeviceNetworkInfo & netInfo)
{
wifi_config_t wifiConfig;
char wifiSSID[kMaxWiFiSSIDLength + 1];
size_t netInfoSSIDLen = strlen(netInfo.WiFiSSID);
// Ensure that ESP station mode is enabled. This is required before esp_wifi_set_config(ESP_IF_WIFI_STA,...)
// can be called.
ReturnErrorOnFailure(ESP32Utils::EnableStationMode());
// Enforce that wifiSSID is null terminated before copying it
memcpy(wifiSSID, netInfo.WiFiSSID, std::min(netInfoSSIDLen + 1, sizeof(wifiSSID)));
if (netInfoSSIDLen + 1 < sizeof(wifiSSID))
{
wifiSSID[netInfoSSIDLen] = '\0';
}
else
{
wifiSSID[kMaxWiFiSSIDLength] = '\0';
}
// Initialize an ESP wifi_config_t structure based on the new provision information.
memset(&wifiConfig, 0, sizeof(wifiConfig));
memcpy(wifiConfig.sta.ssid, wifiSSID, std::min(strlen(wifiSSID) + 1, sizeof(wifiConfig.sta.ssid)));
memcpy(wifiConfig.sta.password, netInfo.WiFiKey, std::min((size_t) netInfo.WiFiKeyLen, sizeof(wifiConfig.sta.password)));
wifiConfig.sta.scan_method = WIFI_ALL_CHANNEL_SCAN;
wifiConfig.sta.sort_method = WIFI_CONNECT_AP_BY_SIGNAL;
// Configure the ESP WiFi interface.
esp_err_t err = esp_wifi_set_config(WIFI_IF_STA, &wifiConfig);
if (err != ESP_OK)
{
ChipLogError(DeviceLayer, "esp_wifi_set_config() failed: %s", esp_err_to_name(err));
return ESP32Utils::MapError(err);
}
ChipLogProgress(DeviceLayer, "WiFi station provision set (SSID: %s)", netInfo.WiFiSSID);
return CHIP_NO_ERROR;
}
CHIP_ERROR ESP32Utils::ClearWiFiStationProvision(void)
{
wifi_config_t stationConfig;
// Clear the ESP WiFi station configuration.
memset(&stationConfig, 0, sizeof(stationConfig));
esp_wifi_set_config(WIFI_IF_STA, &stationConfig);
return CHIP_NO_ERROR;
}
CHIP_ERROR ESP32Utils::InitWiFiStack(void)
{
// Intentionally make this function empty so that we can setup wifi stack in the example
return CHIP_NO_ERROR;
}
#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI
struct netif * ESP32Utils::GetNetif(const char * ifKey)
{
struct netif * netif = NULL;
esp_netif_t * netif_handle = NULL;
netif_handle = esp_netif_get_handle_from_ifkey(ifKey);
netif = (struct netif *) esp_netif_get_netif_impl(netif_handle);
return netif;
}
bool ESP32Utils::IsInterfaceUp(const char * ifKey)
{
struct netif * netif = GetNetif(ifKey);
return netif != NULL && netif_is_up(netif);
}
bool ESP32Utils::HasIPv6LinkLocalAddress(const char * ifKey)
{
struct esp_ip6_addr if_ip6_unused;
return esp_netif_get_ip6_linklocal(esp_netif_get_handle_from_ifkey(ifKey), &if_ip6_unused) == ESP_OK;
}
CHIP_ERROR ESP32Utils::MapError(esp_err_t error)
{
if (error == ESP_OK)
{
return CHIP_NO_ERROR;
}
if (error == ESP_ERR_NVS_NOT_FOUND)
{
return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
}
if (error == ESP_ERR_NVS_INVALID_LENGTH)
{
return CHIP_ERROR_BUFFER_TOO_SMALL;
}
return CHIP_ERROR(ChipError::Range::kPlatform, error);
}
/**
* Given a CHIP error value that represents an ESP32 error, returns a
* human-readable NULL-terminated C string describing the error.
*
* @param[in] buf Buffer into which the error string will be placed.
* @param[in] bufSize Size of the supplied buffer in bytes.
* @param[in] err The error to be described.
*
* @return true If a description string was written into the supplied buffer.
* @return false If the supplied error was not an ESP32 error.
*
*/
bool ESP32Utils::FormatError(char * buf, uint16_t bufSize, CHIP_ERROR err)
{
if (!err.IsRange(ChipError::Range::kPlatform))
{
return false;
}
#if CHIP_CONFIG_SHORT_ERROR_STR
const char * desc = NULL;
#else // CHIP_CONFIG_SHORT_ERROR_STR
const char * desc = esp_err_to_name((esp_err_t) err.GetValue());
#endif // CHIP_CONFIG_SHORT_ERROR_STR
chip::FormatError(buf, bufSize, "ESP32", err, desc);
return true;
}
/**
* Register a text error formatter for ESP32 errors.
*/
void ESP32Utils::RegisterESP32ErrorFormatter()
{
static ErrorFormatter sErrorFormatter = { ESP32Utils::FormatError, NULL };
RegisterErrorFormatter(&sErrorFormatter);
}
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ESP32Utils.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/InetPlatformConfig.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/KeyValueStoreManagerImpl.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/KeyValueStoreManagerImpl.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/Logging.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/LwIPCoreLock.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/NetworkCommissioningDriver.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/NetworkCommissioningDriver.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/NetworkCommissioningDriver_Ethernet.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/OTAImageProcessorImpl.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/OTAImageProcessorImpl.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/OpenthreadLauncher.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/OpenthreadLauncher.h
@@ -1,227 +0,0 @@
// SPDX-FileCopyrightText: 2020 Project CHIP Authors
//
// SPDX-License-Identifier: Apache-2.0
//
// SPDX-FileContributor: 2024 Espressif Systems (Shanghai) PTE LTD
//
// Modified the original code to add a secondary BLE advertisement.
//
// For original code and license information, please refer to
// https://github.com/project-chip/connectedhomeip
/*
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2018 Nest Labs, Inc.
* All rights reserved.
*
* 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
* Provides an implementation of the PlatformManager object
* for the ESP32 platform.
*/
/* this file behaves like a config.h, comes first */
#include <platform/internal/CHIPDeviceLayerInternal.h>
#include <crypto/CHIPCryptoPAL.h>
#include <platform/ESP32/DiagnosticDataProviderImpl.h>
#include <platform/ESP32/ESP32Utils.h>
#include <platform/ESP32/SystemTimeSupport.h>
#include <platform/PlatformManager.h>
#include <platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp>
#include "esp_event.h"
#include "esp_heap_caps_init.h"
#include "esp_log.h"
#include "esp_netif.h"
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
#include "spi_flash_mmap.h"
#else
#include "esp_spi_flash.h"
#endif
#include "esp_system.h"
#include "esp_wifi.h"
namespace chip {
namespace DeviceLayer {
namespace Internal {
extern CHIP_ERROR InitLwIPCoreLock();
}
PlatformManagerImpl PlatformManagerImpl::sInstance;
static int app_entropy_source(void * data, unsigned char * output, size_t len, size_t * olen)
{
esp_fill_random(output, len);
*olen = len;
return 0;
}
CHIP_ERROR PlatformManagerImpl::DisableESPEventDispatch()
{
esp_err_t err = esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, PlatformManagerImpl::HandleESPSystemEvent);
if (err != ESP_OK)
{
return Internal::ESP32Utils::MapError(err);
}
err = esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, PlatformManagerImpl::HandleESPSystemEvent);
return Internal::ESP32Utils::MapError(err);
}
CHIP_ERROR PlatformManagerImpl::_InitChipStack()
{
// Arrange for CHIP-encapsulated ESP32 errors to be translated to text
Internal::ESP32Utils::RegisterESP32ErrorFormatter();
// Make sure the LwIP core lock has been initialized
ReturnErrorOnFailure(Internal::InitLwIPCoreLock());
// Initialize TCP/IP network interface, which internally initializes LwIP stack. We have to
// call this before the usage of PacketBufferHandle::New() because in case of LwIP-based pool
// allocator, the LwIP pool allocator uses the LwIP stack.
esp_err_t err = esp_netif_init();
VerifyOrReturnError(err == ESP_OK, Internal::ESP32Utils::MapError(err));
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, PlatformManagerImpl::HandleESPSystemEvent, nullptr);
VerifyOrReturnError(err == ESP_OK, Internal::ESP32Utils::MapError(err));
#endif
// Arrange for the ESP event loop to deliver events into the CHIP Device layer.
err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, PlatformManagerImpl::HandleESPSystemEvent, nullptr);
VerifyOrReturnError(err == ESP_OK, Internal::ESP32Utils::MapError(err));
mStartTime = System::SystemClock().GetMonotonicTimestamp();
ReturnErrorOnFailure(chip::Crypto::add_entropy_source(app_entropy_source, nullptr, 16));
// Call _InitChipStack() on the generic implementation base class
// to finish the initialization process.
ReturnErrorOnFailure(Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>::_InitChipStack());
ReturnErrorOnFailure(System::Clock::InitClock_RealTime());
return CHIP_NO_ERROR;
}
void PlatformManagerImpl::_Shutdown()
{
uint64_t upTime = 0;
if (GetDiagnosticDataProvider().GetUpTime(upTime) == CHIP_NO_ERROR)
{
uint32_t totalOperationalHours = 0;
if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR)
{
ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + static_cast<uint32_t>(upTime / 3600));
}
else
{
ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node");
}
}
else
{
ChipLogError(DeviceLayer, "Failed to get current uptime since the Nodes last reboot");
}
Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>::_Shutdown();
esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, PlatformManagerImpl::HandleESPSystemEvent);
esp_netif_deinit();
}
void PlatformManagerImpl::HandleESPSystemEvent(void * arg, esp_event_base_t eventBase, int32_t eventId, void * eventData)
{
ChipDeviceEvent event;
memset(&event, 0, sizeof(event));
event.Type = DeviceEventType::kESPSystemEvent;
event.Platform.ESPSystemEvent.Base = eventBase;
event.Platform.ESPSystemEvent.Id = eventId;
if (eventBase == IP_EVENT)
{
ChipLogProgress(DeviceLayer, "Posting ESPSystemEvent: IP Event with eventId : %ld", eventId);
switch (eventId)
{
case IP_EVENT_STA_GOT_IP:
memcpy(&event.Platform.ESPSystemEvent.Data.IpGotIp, eventData, sizeof(event.Platform.ESPSystemEvent.Data.IpGotIp));
break;
case IP_EVENT_GOT_IP6:
memcpy(&event.Platform.ESPSystemEvent.Data.IpGotIp6, eventData, sizeof(event.Platform.ESPSystemEvent.Data.IpGotIp6));
break;
case IP_EVENT_AP_STAIPASSIGNED:
memcpy(&event.Platform.ESPSystemEvent.Data.IpApStaIpAssigned, eventData,
sizeof(event.Platform.ESPSystemEvent.Data.IpApStaIpAssigned));
break;
default:
break;
}
}
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
else if (eventBase == WIFI_EVENT)
{
ChipLogProgress(DeviceLayer, "Posting ESPSystemEvent: Wifi Event with eventId : %ld", eventId);
switch (eventId)
{
case WIFI_EVENT_SCAN_DONE:
memcpy(&event.Platform.ESPSystemEvent.Data.WiFiStaScanDone, eventData,
sizeof(event.Platform.ESPSystemEvent.Data.WiFiStaScanDone));
break;
case WIFI_EVENT_STA_CONNECTED:
memcpy(&event.Platform.ESPSystemEvent.Data.WiFiStaConnected, eventData,
sizeof(event.Platform.ESPSystemEvent.Data.WiFiStaConnected));
break;
case WIFI_EVENT_STA_DISCONNECTED:
memcpy(&event.Platform.ESPSystemEvent.Data.WiFiStaDisconnected, eventData,
sizeof(event.Platform.ESPSystemEvent.Data.WiFiStaDisconnected));
break;
case WIFI_EVENT_STA_AUTHMODE_CHANGE:
memcpy(&event.Platform.ESPSystemEvent.Data.WiFiStaAuthModeChange, eventData,
sizeof(event.Platform.ESPSystemEvent.Data.WiFiStaAuthModeChange));
break;
case WIFI_EVENT_STA_WPS_ER_PIN:
memcpy(&event.Platform.ESPSystemEvent.Data.WiFiStaWpsErPin, eventData,
sizeof(event.Platform.ESPSystemEvent.Data.WiFiStaWpsErPin));
break;
case WIFI_EVENT_STA_WPS_ER_FAILED:
memcpy(&event.Platform.ESPSystemEvent.Data.WiFiStaWpsErFailed, eventData,
sizeof(event.Platform.ESPSystemEvent.Data.WiFiStaWpsErFailed));
break;
case WIFI_EVENT_AP_STACONNECTED:
memcpy(&event.Platform.ESPSystemEvent.Data.WiFiApStaConnected, eventData,
sizeof(event.Platform.ESPSystemEvent.Data.WiFiApStaConnected));
break;
case WIFI_EVENT_AP_STADISCONNECTED:
memcpy(&event.Platform.ESPSystemEvent.Data.WiFiApStaDisconnected, eventData,
sizeof(event.Platform.ESPSystemEvent.Data.WiFiApStaDisconnected));
break;
case WIFI_EVENT_AP_PROBEREQRECVED:
memcpy(&event.Platform.ESPSystemEvent.Data.WiFiApProbeReqRecved, eventData,
sizeof(event.Platform.ESPSystemEvent.Data.WiFiApProbeReqRecved));
break;
default:
break;
}
}
#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI
else
{
ChipLogProgress(DeviceLayer, "Posting ESPSystemEvent with eventId : %ld", eventId);
}
sInstance.PostEventOrDie(&event);
}
} // namespace DeviceLayer
} // namespace chip
@@ -1,107 +0,0 @@
// SPDX-FileCopyrightText: 2020 Project CHIP Authors
//
// SPDX-License-Identifier: Apache-2.0
//
// SPDX-FileContributor: 2024 Espressif Systems (Shanghai) PTE LTD
//
// Modified the original code to add a secondary BLE advertisement.
//
// For original code and license information, please refer to
// https://github.com/project-chip/connectedhomeip
/*
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2018 Nest Labs, Inc.
* All rights reserved.
*
* 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
* Provides an implementation of the PlatformManager object
* for the ESP32 platform.
*/
#pragma once
#include <platform/internal/GenericPlatformManagerImpl_FreeRTOS.h>
#include <system/SystemClock.h>
namespace chip {
namespace DeviceLayer {
/**
* Concrete implementation of the PlatformManager singleton object for the ESP32 platform.
*/
class PlatformManagerImpl final : public PlatformManager, public Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>
{
// Allow the PlatformManager interface class to delegate method calls to
// the implementation methods provided by this class.
friend PlatformManager;
// Allow the generic implementation base class to call helper methods on
// this class.
#ifndef DOXYGEN_SHOULD_SKIP_THIS
friend Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>;
#endif
public:
// ===== Platform-specific members that may be accessed directly by the application.
CHIP_ERROR InitLwIPCoreLock(void);
static void HandleESPSystemEvent(void * arg, esp_event_base_t eventBase, int32_t eventId, void * eventData);
System::Clock::Timestamp GetStartTime() { return mStartTime; }
static CHIP_ERROR DisableESPEventDispatch();
private:
// ===== Methods that implement the PlatformManager abstract interface.
CHIP_ERROR _InitChipStack(void);
void _Shutdown();
// ===== Members for internal use by the following friends.
friend PlatformManager & PlatformMgr(void);
friend PlatformManagerImpl & PlatformMgrImpl(void);
System::Clock::Timestamp mStartTime = System::Clock::kZero;
static PlatformManagerImpl sInstance;
};
/**
* Returns the public interface of the PlatformManager singleton object.
*
* Chip applications should use this to access features of the PlatformManager object
* that are common to all platforms.
*/
inline PlatformManager & PlatformMgr(void)
{
return PlatformManagerImpl::sInstance;
}
/**
* Returns the platform-specific implementation of the PlatformManager singleton object.
*
* Chip applications can use this to gain access to features of the PlatformManager
* that are specific to the ESP32 platform.
*/
inline PlatformManagerImpl & PlatformMgrImpl(void)
{
return PlatformManagerImpl::sInstance;
}
} // namespace DeviceLayer
} // namespace chip
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ScopedNvsHandle.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/StaticESP32DeviceInfoProvider.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/StaticESP32DeviceInfoProvider.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/SystemPlatformConfig.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/SystemTimeSupport.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/SystemTimeSupport.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ThreadStackManagerImpl.cpp
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/ThreadStackManagerImpl.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/WarmPlatformConfig.h
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/bluedroid
@@ -1 +0,0 @@
../../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/nimble/ChipDeviceScanner.cpp
@@ -1 +0,0 @@
../../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/nimble/blecent.h
@@ -1 +0,0 @@
../../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/nimble/misc.c
@@ -1 +0,0 @@
../../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/nimble/peer.c
@@ -1,645 +0,0 @@
diff --git a/src/platform/ESP32/BLEManagerImpl.h b/src/platform/ESP32/BLEManagerImpl.h
index 2a489420a0..ae315e0b90 100644
--- a/src/platform/ESP32/BLEManagerImpl.h
+++ b/src/platform/ESP32/BLEManagerImpl.h
@@ -61,6 +61,9 @@ struct ble_gatt_char_context
void * arg;
};
+#define MAX_ADV_DATA_LEN 31
+#define MAX_DEVICE_NAME_LEN 29
+
#endif // CONFIG_BT_BLUEDROID_ENABLED
#include <ble/Ble.h>
@@ -143,6 +146,47 @@ public:
CHIP_ERROR ConfigureScanResponseData(ByteSpan data);
void ClearScanResponseData(void);
+ CHIP_ERROR SetSecondaryGATTService(struct ble_gatt_svc_def *gatt_svc, size_t gattSvcIndex)
+ {
+ if (!gatt_svc || gattSvcIndex > 1)
+ {
+ return CHIP_ERROR_INVALID_ARGUMENT;
+ }
+ mSecondGATTServiceIndex = gattSvcIndex;
+ memcpy(&mGATTServices[gattSvcIndex], gatt_svc, sizeof(struct ble_gatt_svc_def));
+ return CHIP_NO_ERROR;
+ }
+
+ using BleGapEventHandler = int(*)(struct ble_gap_event * event, void * arg);
+
+ void SetSecondaryAdvGapEventHandler(BleGapEventHandler handler) { mSecondaryBleGapEventHandler = handler; }
+
+ CHIP_ERROR SetSecondaryAdvDeviceName(const char *deviceName)
+ {
+ strncpy(mSecondaryAdvDeviceName, deviceName, MAX_DEVICE_NAME_LEN);
+ mSecondaryAdvDeviceName[MAX_DEVICE_NAME_LEN] = 0;
+ return CHIP_NO_ERROR;
+ }
+
+ CHIP_ERROR SetSecondaryAdvUuid(const ByteSpan &uuid)
+ {
+ if (uuid.size() != 16)
+ {
+ return CHIP_ERROR_INVALID_ARGUMENT;
+ }
+ mSecondaryAdvUuid.u.type = BLE_UUID_TYPE_128;
+ memcpy(mSecondaryAdvUuid.value, uuid.data(), uuid.size());
+ return CHIP_NO_ERROR;
+ }
+
+ void SetSecondaryBleSmConfig(bool bleBonding, bool bleSmSc)
+ {
+ mSecondaryBleBonding = bleBonding;
+ mSecondaryBleSmSc = bleSmSc;
+ }
+
+ void RefreshAdv(void);
+
private:
chip::Optional<chip::ByteSpan> mScanResponse;
uint8_t scanResponseBuffer[MAX_SCAN_RSP_DATA_LEN];
@@ -346,7 +390,7 @@ private:
static void bleprph_host_task(void * param);
static void bleprph_on_sync(void);
static void bleprph_on_reset(int);
- static const struct ble_gatt_svc_def CHIPoBLEGATTAttrs[];
+ static const struct ble_gatt_svc_def CHIPoBLEGATTService;
static int ble_svr_gap_event(struct ble_gap_event * event, void * arg);
static int gatt_svr_chr_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt * ctxt, void * arg);
@@ -380,6 +424,31 @@ private:
#endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER
static void DriveBLEState(intptr_t arg);
+
+ uint8_t mAdvData[MAX_ADV_DATA_LEN];
+ uint16_t mAdvDataLen;
+ static constexpr uint8_t kChipAdvInstance = 0;
+ // Three GATT service
+ // mGATTServices[0] is for Matter-over-BLE
+ // mGATTServices[1] is for wifi_provisioning over BLE
+ // mGATTServices[2] is NULL
+ struct ble_gatt_svc_def mGATTServices[3];
+
+ // Secondary Advertisement
+ static int secondary_ble_svr_gap_event(struct ble_gap_event * event, void * arg);
+ CHIP_ERROR ConfigureSecondaryAdvertisingData(void);
+ CHIP_ERROR StartSecondaryAdvertising(void);
+ char mSecondaryAdvDeviceName[MAX_DEVICE_NAME_LEN + 1];
+ size_t mSecondGATTServiceIndex = 1;
+ ble_uuid128_t mSecondaryAdvUuid;
+ bool mSecondaryBleBonding;
+ bool mSecondaryBleSmSc;
+ ble_hs_adv_fields mSecondaryAdvFields;
+ ble_hs_adv_fields mSecondaryRespFields;
+ uint8_t *mSecondaryMfgData;
+ size_t mSecondaryMfgDataLen;
+ BleGapEventHandler mSecondaryBleGapEventHandler = nullptr;
+ static constexpr uint8_t kSecondaryAdvInstance = 1;
};
/**
diff --git a/src/platform/ESP32/ESP32Utils.cpp b/src/platform/ESP32/ESP32Utils.cpp
index e66007a0a8..5052535376 100644
--- a/src/platform/ESP32/ESP32Utils.cpp
+++ b/src/platform/ESP32/ESP32Utils.cpp
@@ -311,62 +311,7 @@ CHIP_ERROR ESP32Utils::ClearWiFiStationProvision(void)
CHIP_ERROR ESP32Utils::InitWiFiStack(void)
{
- wifi_init_config_t cfg;
- uint8_t ap_mac[6];
- wifi_mode_t mode;
- esp_err_t err = esp_netif_init();
- if (err != ESP_OK)
- {
- return ESP32Utils::MapError(err);
- }
-
-#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP
- // Lets not create a default AP interface if already present
- if (!esp_netif_get_handle_from_ifkey(kDefaultWiFiAPNetifKey))
- {
- if (!esp_netif_create_default_wifi_ap())
- {
- ChipLogError(DeviceLayer, "Failed to create the WiFi AP netif");
- return CHIP_ERROR_INTERNAL;
- }
- }
-#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP
-
- // Lets not create a default station interface if already present
- if (!esp_netif_get_handle_from_ifkey(kDefaultWiFiStationNetifKey))
- {
- if (!esp_netif_create_default_wifi_sta())
- {
- ChipLogError(DeviceLayer, "Failed to create the WiFi STA netif");
- return CHIP_ERROR_INTERNAL;
- }
- }
-
- // Initialize the ESP WiFi layer.
- cfg = WIFI_INIT_CONFIG_DEFAULT();
- err = esp_wifi_init(&cfg);
- if (err != ESP_OK)
- {
- return ESP32Utils::MapError(err);
- }
-
- esp_wifi_get_mode(&mode);
- if ((mode == WIFI_MODE_AP) || (mode == WIFI_MODE_APSTA))
- {
- esp_fill_random(ap_mac, sizeof(ap_mac));
- /* Bit 0 of the first octet of MAC Address should always be 0 */
- ap_mac[0] &= (uint8_t) ~0x01;
- err = esp_wifi_set_mac(WIFI_IF_AP, ap_mac);
- if (err != ESP_OK)
- {
- return ESP32Utils::MapError(err);
- }
- }
- err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, PlatformManagerImpl::HandleESPSystemEvent, NULL);
- if (err != ESP_OK)
- {
- return ESP32Utils::MapError(err);
- }
+ // Intentionally make this function empty so that we can setup wifi stack in the example
return CHIP_NO_ERROR;
}
#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI
diff --git a/src/platform/ESP32/PlatformManagerImpl.cpp b/src/platform/ESP32/PlatformManagerImpl.cpp
index 2c73019933..7c11f63165 100644
--- a/src/platform/ESP32/PlatformManagerImpl.cpp
+++ b/src/platform/ESP32/PlatformManagerImpl.cpp
@@ -60,6 +60,17 @@ static int app_entropy_source(void * data, unsigned char * output, size_t len, s
return 0;
}
+CHIP_ERROR PlatformManagerImpl::DisableESPEventDispatch()
+{
+ esp_err_t err = esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, PlatformManagerImpl::HandleESPSystemEvent);
+ if (err != ESP_OK)
+ {
+ return Internal::ESP32Utils::MapError(err);
+ }
+ err = esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, PlatformManagerImpl::HandleESPSystemEvent);
+ return Internal::ESP32Utils::MapError(err);
+}
+
CHIP_ERROR PlatformManagerImpl::_InitChipStack()
{
// Arrange for CHIP-encapsulated ESP32 errors to be translated to text
@@ -73,6 +84,11 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack()
esp_err_t err = esp_netif_init();
VerifyOrReturnError(err == ESP_OK, Internal::ESP32Utils::MapError(err));
+#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
+ err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, PlatformManagerImpl::HandleESPSystemEvent, nullptr);
+ VerifyOrReturnError(err == ESP_OK, Internal::ESP32Utils::MapError(err));
+#endif
+
// Arrange for the ESP event loop to deliver events into the CHIP Device layer.
err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, PlatformManagerImpl::HandleESPSystemEvent, nullptr);
VerifyOrReturnError(err == ESP_OK, Internal::ESP32Utils::MapError(err));
diff --git a/src/platform/ESP32/PlatformManagerImpl.h b/src/platform/ESP32/PlatformManagerImpl.h
index cc2b0eefe9..0d99857ef8 100644
--- a/src/platform/ESP32/PlatformManagerImpl.h
+++ b/src/platform/ESP32/PlatformManagerImpl.h
@@ -52,6 +52,7 @@ public:
CHIP_ERROR InitLwIPCoreLock(void);
static void HandleESPSystemEvent(void * arg, esp_event_base_t eventBase, int32_t eventId, void * eventData);
System::Clock::Timestamp GetStartTime() { return mStartTime; }
+ static CHIP_ERROR DisableESPEventDispatch();
private:
// ===== Methods that implement the PlatformManager abstract interface.
diff --git a/src/platform/ESP32/nimble/BLEManagerImpl.cpp b/src/platform/ESP32/nimble/BLEManagerImpl.cpp
index 0a2ddb1763..c9c81b4db1 100644
--- a/src/platform/ESP32/nimble/BLEManagerImpl.cpp
+++ b/src/platform/ESP32/nimble/BLEManagerImpl.cpp
@@ -127,39 +127,36 @@ uint8_t own_addr_type = BLE_OWN_ADDR_RANDOM;
ChipDeviceScanner & mDeviceScanner = Internal::ChipDeviceScanner::GetInstance();
#endif
BLEManagerImpl BLEManagerImpl::sInstance;
-const struct ble_gatt_svc_def BLEManagerImpl::CHIPoBLEGATTAttrs[] = {
- { .type = BLE_GATT_SVC_TYPE_PRIMARY,
- .uuid = (ble_uuid_t *) (&ShortUUID_CHIPoBLEService),
- .characteristics =
- (struct ble_gatt_chr_def[]){
- {
- .uuid = (ble_uuid_t *) (&UUID128_CHIPoBLEChar_RX),
- .access_cb = gatt_svr_chr_access,
- .flags = BLE_GATT_CHR_F_WRITE,
- .val_handle = &sInstance.mRXCharAttrHandle,
- },
- {
- .uuid = (ble_uuid_t *) (&UUID_CHIPoBLEChar_TX),
- .access_cb = gatt_svr_chr_access,
- .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_INDICATE,
- .val_handle = &sInstance.mTXCharCCCDAttrHandle,
- },
+
+const struct ble_gatt_svc_def BLEManagerImpl::CHIPoBLEGATTService = {
+ .type = BLE_GATT_SVC_TYPE_PRIMARY,
+ .uuid = (ble_uuid_t *) (&ShortUUID_CHIPoBLEService),
+ .characteristics = (struct ble_gatt_chr_def[]){
+ {
+ .uuid = (ble_uuid_t *) (&UUID128_CHIPoBLEChar_RX),
+ .access_cb = gatt_svr_chr_access,
+ .flags = BLE_GATT_CHR_F_WRITE,
+ .val_handle = &sInstance.mRXCharAttrHandle,
+ },
+ {
+ .uuid = (ble_uuid_t *) (&UUID_CHIPoBLEChar_TX),
+ .access_cb = gatt_svr_chr_access,
+ .flags =
+ BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_INDICATE,
+ .val_handle = &sInstance.mTXCharCCCDAttrHandle,
+ },
#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
- {
- .uuid = (ble_uuid_t *) (&UUID_CHIPoBLEChar_C3),
- .access_cb = gatt_svr_chr_access_additional_data,
- .flags = BLE_GATT_CHR_F_READ,
- .val_handle = &sInstance.mC3CharAttrHandle,
- },
+ {
+ .uuid = (ble_uuid_t *) (&UUID_CHIPoBLEChar_C3),
+ .access_cb = gatt_svr_chr_access_additional_data,
+ .flags = BLE_GATT_CHR_F_READ,
+ .val_handle = &sInstance.mC3CharAttrHandle,
+ },
#endif
- {
- 0, /* No more characteristics in this service */
- },
- } },
-
- {
- 0, /* No more services. */
- },
+ {
+ 0, /* No more characteristics in this service */
+ },
+ }
};
#ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER
@@ -775,6 +772,12 @@ void BLEManagerImpl::DriveBLEState(void)
ChipLogError(DeviceLayer, "Configure Adv Data failed: %s", ErrorStr(err));
ExitNow();
}
+ err = ConfigureSecondaryAdvertisingData();
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "Configure secondary Adv Data failed: %s", ErrorStr(err));
+ ExitNow();
+ }
}
// Start advertising. This is also an asynchronous step.
@@ -785,6 +788,12 @@ void BLEManagerImpl::DriveBLEState(void)
ChipLogError(DeviceLayer, "Start advertising failed: %s", ErrorStr(err));
ExitNow();
}
+ err = StartSecondaryAdvertising();
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "Start secondary advertising failed: %s", ErrorStr(err));
+ ExitNow();
+ }
mFlags.Clear(Flags::kAdvertisingRefreshNeeded);
// Transition to the Advertising state...
@@ -810,12 +819,12 @@ void BLEManagerImpl::DriveBLEState(void)
{
if (mFlags.Has(Flags::kAdvertising))
{
- if (ble_gap_adv_active())
+ if (ble_gap_ext_adv_active(kChipAdvInstance))
{
- err = MapBLEError(ble_gap_adv_stop());
+ err = MapBLEError(ble_gap_ext_adv_stop(kChipAdvInstance));
if (err != CHIP_NO_ERROR)
{
- ChipLogError(DeviceLayer, "ble_gap_adv_stop() failed: %s", ErrorStr(err));
+ ChipLogError(DeviceLayer, "ble_gap_ext_adv_stop() failed: %s", ErrorStr(err));
ExitNow();
}
}
@@ -941,14 +950,15 @@ CHIP_ERROR BLEManagerImpl::InitESPBleLayer(void)
ble_svc_gap_init();
ble_svc_gatt_init();
- err = MapBLEError(ble_gatts_count_cfg(CHIPoBLEGATTAttrs));
+ mGATTServices[1 - mSecondGATTServiceIndex] = CHIPoBLEGATTService;
+ err = MapBLEError(ble_gatts_count_cfg(mGATTServices));
if (err != CHIP_NO_ERROR)
{
ChipLogError(DeviceLayer, "ble_gatts_count_cfg failed: %s", ErrorStr(err));
ExitNow();
}
- err = MapBLEError(ble_gatts_add_svcs(CHIPoBLEGATTAttrs));
+ err = MapBLEError(ble_gatts_add_svcs(mGATTServices));
if (err != CHIP_NO_ERROR)
{
ChipLogError(DeviceLayer, "ble_gatts_add_svcs failed: %s", ErrorStr(err));
@@ -1031,7 +1041,6 @@ extern "C" void ble_transport_ll_deinit(void) {}
CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void)
{
CHIP_ERROR err;
- uint8_t advData[MAX_ADV_DATA_LEN];
uint8_t index = 0;
constexpr uint8_t kServiceDataTypeSize = 1;
@@ -1057,14 +1066,14 @@ CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void)
ExitNow();
}
- memset(advData, 0, sizeof(advData));
- advData[index++] = 0x02; // length
- advData[index++] = CHIP_ADV_DATA_TYPE_FLAGS; // AD type : flags
- advData[index++] = CHIP_ADV_DATA_FLAGS; // AD value
- advData[index++] = kServiceDataTypeSize + sizeof(ESP32ChipServiceData); // length
- advData[index++] = CHIP_ADV_DATA_TYPE_SERVICE_DATA; // AD type: (Service Data - 16-bit UUID)
- advData[index++] = static_cast<uint8_t>(ShortUUID_CHIPoBLEService.value & 0xFF); // AD value
- advData[index++] = static_cast<uint8_t>((ShortUUID_CHIPoBLEService.value >> 8) & 0xFF); // AD value
+ memset(mAdvData, 0, sizeof(mAdvData));
+ mAdvData[index++] = 0x02; // length
+ mAdvData[index++] = CHIP_ADV_DATA_TYPE_FLAGS; // AD type : flags
+ mAdvData[index++] = CHIP_ADV_DATA_FLAGS; // AD value
+ mAdvData[index++] = kServiceDataTypeSize + sizeof(ESP32ChipServiceData); // length
+ mAdvData[index++] = CHIP_ADV_DATA_TYPE_SERVICE_DATA; // AD type: (Service Data - 16-bit UUID)
+ mAdvData[index++] = static_cast<uint8_t>(ShortUUID_CHIPoBLEService.value & 0xFF); // AD value
+ mAdvData[index++] = static_cast<uint8_t>((ShortUUID_CHIPoBLEService.value >> 8) & 0xFF); // AD value
err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(deviceIdInfo);
if (err != CHIP_NO_ERROR)
@@ -1094,17 +1103,11 @@ CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void)
}
#endif
- VerifyOrExit(index + sizeof(deviceIdInfo) <= sizeof(advData), err = CHIP_ERROR_OUTBOUND_MESSAGE_TOO_BIG);
- memcpy(&advData[index], &deviceIdInfo, sizeof(deviceIdInfo));
+ VerifyOrExit(index + sizeof(deviceIdInfo) <= sizeof(mAdvData), err = CHIP_ERROR_OUTBOUND_MESSAGE_TOO_BIG);
+ memcpy(&mAdvData[index], &deviceIdInfo, sizeof(deviceIdInfo));
index = static_cast<uint8_t>(index + sizeof(deviceIdInfo));
- // Construct the Chip BLE Service Data to be sent in the scan response packet.
- err = MapBLEError(ble_gap_adv_set_data(advData, sizeof(advData)));
- if (err != CHIP_NO_ERROR)
- {
- ChipLogError(DeviceLayer, "ble_gap_adv_set_data failed: %s %d", ErrorStr(err), discriminator);
- ExitNow();
- }
+ mAdvDataLen = index;
exit:
return err;
@@ -1371,6 +1374,14 @@ CHIP_ERROR BLEManagerImpl::HandleGAPConnect(struct ble_gap_event * gapEvent)
#endif
}
+void BLEManagerImpl::RefreshAdv(void)
+{
+ mFlags.Set(Flags::kAdvertisingRefreshNeeded);
+ mFlags.Clear(Flags::kAdvertisingConfigured);
+
+ PlatformMgr().ScheduleWork(DriveBLEState, 0);
+}
+
CHIP_ERROR BLEManagerImpl::HandleGAPDisconnect(struct ble_gap_event * gapEvent)
{
ChipLogProgress(DeviceLayer, "BLE GAP connection terminated (con %u reason 0x%02x)", gapEvent->disconnect.conn.conn_handle,
@@ -1658,16 +1669,18 @@ int BLEManagerImpl::gatt_svr_chr_access(uint16_t conn_handle, uint16_t attr_hand
CHIP_ERROR BLEManagerImpl::StartAdvertising(void)
{
CHIP_ERROR err;
- ble_gap_adv_params adv_params;
+ ble_gap_ext_adv_params adv_params;
memset(&adv_params, 0, sizeof(adv_params));
- adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
+ adv_params.scannable = 1;
+ adv_params.own_addr_type = own_addr_type;
+ adv_params.legacy_pdu = 1;
mFlags.Clear(Flags::kAdvertisingRefreshNeeded);
// Advertise connectable if we haven't reached the maximum number of connections.
- size_t numCons = _NumConnections();
- bool connectable = (numCons < kMaxConnections);
- adv_params.conn_mode = connectable ? BLE_GAP_CONN_MODE_UND : BLE_GAP_CONN_MODE_NON;
+ size_t numCons = _NumConnections();
+ bool connectable = (numCons < kMaxConnections);
+ adv_params.connectable = connectable;
// Advertise in fast mode if it is connectable advertisement and
// the application has expressly requested fast advertising.
@@ -1701,48 +1714,186 @@ CHIP_ERROR BLEManagerImpl::StartAdvertising(void)
(((uint32_t) adv_params.itvl_min) * 10) / 16, (connectable) ? "" : "non-");
{
- if (ble_gap_adv_active())
+ if (ble_gap_ext_adv_active(kChipAdvInstance))
{
/* Advertising is already active. Stop and restart with the new parameters */
ChipLogProgress(DeviceLayer, "Device already advertising, stop active advertisement and restart");
- err = MapBLEError(ble_gap_adv_stop());
+ err = MapBLEError(ble_gap_ext_adv_stop(kChipAdvInstance));
if (err != CHIP_NO_ERROR)
{
- ChipLogError(DeviceLayer, "ble_gap_adv_stop() failed: %s, cannot restart", ErrorStr(err));
+ ChipLogError(DeviceLayer, "ble_gap_ext_adv_stop() failed: %s, cannot restart", ErrorStr(err));
return err;
}
}
-#ifdef CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY
- else
+ err = MapBLEError(ble_gap_ext_adv_configure(kChipAdvInstance, &adv_params, NULL, ble_svr_gap_event, NULL));
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "ble_gap_ext_adv_configure failed: %s", ErrorStr(err));
+ return err;
+ }
+
+ ble_addr_t addr;
+
+ /* generate new non-resolvable private address */
+ err = MapBLEError(ble_hs_id_gen_rnd(1, &addr));
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "ble_hs_id_gen_rnd failed: %s", ErrorStr(err));
+ return err;
+ }
+
+ /* Set generated address */
+ err = MapBLEError(ble_gap_ext_adv_set_addr(kChipAdvInstance, &addr));
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "ble_gap_ext_adv_set_addr failed: %s", ErrorStr(err));
+ return err;
+ }
+
+ struct os_mbuf * data = os_msys_get_pkthdr(mAdvDataLen, 0);
+ assert(data);
+ err = MapBLEError(os_mbuf_append(data, mAdvData, mAdvDataLen));
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "os_mbuf_append failed: %s", ErrorStr(err));
+ return err;
+ }
+
+ err = MapBLEError(ble_gap_ext_adv_set_data(kChipAdvInstance, data));
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "os_mbuf_append failed: %s", ErrorStr(err));
+ return err;
+ }
+
+ if (mScanResponse.HasValue())
{
- err = MapBLEError(ble_hs_pvcy_rpa_config(NIMBLE_HOST_ENABLE_RPA));
+ uint16_t resp_size = static_cast<uint16_t>(mScanResponse.Value().size());
+ struct os_mbuf * resp_data = os_msys_get_pkthdr(resp_size, 0);
+ assert(resp_data);
+ err = MapBLEError(os_mbuf_append(resp_data, mScanResponse.Value().data(), resp_size));
if (err != CHIP_NO_ERROR)
{
- ChipLogError(DeviceLayer, "RPA not set: %s", ErrorStr(err));
+ ChipLogError(DeviceLayer, "os_mbuf_append failed: %s", ErrorStr(err));
return err;
}
- }
-#endif
- if (mScanResponse.HasValue())
- {
- err = MapBLEError(ble_gap_adv_rsp_set_data(mScanResponse.Value().data(), mScanResponse.Value().size()));
+ err = MapBLEError(ble_gap_ext_adv_rsp_set_data(kChipAdvInstance, resp_data));
if (err != CHIP_NO_ERROR)
{
- ChipLogError(DeviceLayer, "ble_gap_adv_rsp_set_data failed: %s", ErrorStr(err));
+ ChipLogError(DeviceLayer, "ble_gap_ext_adv_rsp_set_data failed: %s", ErrorStr(err));
return err;
}
}
- err = MapBLEError(ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER, &adv_params, ble_svr_gap_event, NULL));
- if (err == CHIP_NO_ERROR)
+ err = MapBLEError(ble_gap_ext_adv_start(kChipAdvInstance, 0, 0));
+ if (err != CHIP_NO_ERROR)
{
- return CHIP_NO_ERROR;
+ ChipLogError(DeviceLayer, "ble_gap_ext_adv_start() failed: %s", ErrorStr(err));
}
- else
+ }
+ return err;
+}
+
+int BLEManagerImpl::secondary_ble_svr_gap_event(struct ble_gap_event * event, void * arg)
+{
+ if (chip::DeviceLayer::Internal::BLEMgrImpl().mSecondaryBleGapEventHandler) {
+ return chip::DeviceLayer::Internal::BLEMgrImpl().mSecondaryBleGapEventHandler(event, arg);
+ }
+ return 0;
+}
+
+CHIP_ERROR BLEManagerImpl::ConfigureSecondaryAdvertisingData(void)
+{
+ memset(&mSecondaryAdvFields, 0, sizeof(mSecondaryAdvFields));
+ mSecondaryAdvFields.flags = (BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP);
+ mSecondaryAdvFields.num_uuids128 = 1;
+ mSecondaryAdvFields.uuids128_is_complete = 1;
+ mSecondaryAdvFields.uuids128 = &mSecondaryAdvUuid;
+
+ memset(&mSecondaryRespFields, 0, sizeof(mSecondaryRespFields));
+ mSecondaryRespFields.name = (const uint8_t *)mSecondaryAdvDeviceName;
+ mSecondaryRespFields.name_len = (uint8_t)strlen(mSecondaryAdvDeviceName);
+ mSecondaryRespFields.name_is_complete = 1;
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BLEManagerImpl::StartSecondaryAdvertising(void)
+{
+ CHIP_ERROR err;
+ uint8_t secondary_own_addr_type;
+ err = MapBLEError(ble_hs_util_ensure_addr(0));
+ if (err != CHIP_NO_ERROR) {
+ ESP_LOGE(TAG, "Error loading address");
+ return err;
+ }
+
+ /* Figure out address to use while advertising (no privacy for now) */
+ err = MapBLEError(ble_hs_id_infer_auto(0, &secondary_own_addr_type));
+ if (err != CHIP_NO_ERROR) {
+ ChipLogError(DeviceLayer, "ble_hs_id_infer_auto() failed: %s, cannot restart", ErrorStr(err));
+ return err;
+ }
+ ble_gap_ext_adv_params adv_params;
+ memset(&adv_params, 0, sizeof(adv_params));
+ adv_params.scannable = 1;
+ adv_params.own_addr_type = secondary_own_addr_type;
+ adv_params.legacy_pdu = 1;
+ adv_params.connectable = 1;
+ adv_params.itvl_min = 0x100;
+ adv_params.itvl_max = 0x100;
+
+ if (ble_gap_ext_adv_active(kSecondaryAdvInstance))
+ {
+ /* Advertising is already active. Stop and restart with the new parameters */
+ ChipLogProgress(DeviceLayer, "Device already advertising, stop active advertisement and restart");
+ err = MapBLEError(ble_gap_ext_adv_stop(kSecondaryAdvInstance));
+ if (err != CHIP_NO_ERROR)
{
- ChipLogError(DeviceLayer, "ble_gap_adv_start() failed: %s", ErrorStr(err));
+ ChipLogError(DeviceLayer, "ble_gap_ext_adv_stop() failed: %s, cannot restart", ErrorStr(err));
return err;
}
}
+ err = MapBLEError(ble_gap_ext_adv_configure(kSecondaryAdvInstance, &adv_params, NULL, secondary_ble_svr_gap_event, NULL));
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "ble_gap_ext_adv_configure failed: %s", ErrorStr(err));
+ return err;
+ }
+
+ struct os_mbuf * data = os_msys_get_pkthdr(BLE_HCI_MAX_ADV_DATA_LEN, 0);
+ assert(data);
+ err = MapBLEError(ble_hs_adv_set_fields_mbuf(&mSecondaryAdvFields, data));
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "ble_hs_adv_set_fields_mbuf failed: %s", ErrorStr(err));
+ return err;
+ }
+ err = MapBLEError(ble_gap_ext_adv_set_data(kSecondaryAdvInstance, data));
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "ble_gap_ext_adv_set_data failed: %s", ErrorStr(err));
+ return err;
+ }
+
+ struct os_mbuf * resp_data = os_msys_get_pkthdr(BLE_HCI_MAX_ADV_DATA_LEN, 0);
+ assert(resp_data);
+ err = MapBLEError(ble_hs_adv_set_fields_mbuf(&mSecondaryRespFields, resp_data));
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "ble_hs_adv_set_fields_mbuf failed: %s", ErrorStr(err));
+ return err;
+ }
+ err = MapBLEError(ble_gap_ext_adv_rsp_set_data(kSecondaryAdvInstance, resp_data));
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "ble_gap_ext_adv_set_data failed: %s", ErrorStr(err));
+ return err;
+ }
+ err = MapBLEError(ble_gap_ext_adv_start(kSecondaryAdvInstance, 0, 0));
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "ble_gap_ext_adv_start() failed: %s", ErrorStr(err));
+ }
+ return err;
}
void BLEManagerImpl::DriveBLEState(intptr_t arg)
@@ -1 +0,0 @@
../../../../../connectedhomeip/connectedhomeip/src/platform/ESP32/route_hook
+13 -2
View File
@@ -29,6 +29,8 @@
#include <common_macros.h>
#include "app-common/zap-generated/ids/Attributes.h"
#include "app-common/zap-generated/ids/Clusters.h"
#include "platform/CHIPDeviceEvent.h"
#include "platform/PlatformManager.h"
#include "wifi_provisioning/manager.h"
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
#include <platform/ESP32/OpenthreadLauncher.h>
@@ -39,6 +41,7 @@
#include <app/server/CommissioningWindowManager.h>
#include <app/server/Server.h>
#include <wifi_prov_scheme/protocomm_matter_ble.h>
static const char *TAG = "app_main";
uint16_t light_endpoint_id = 0;
@@ -62,6 +65,9 @@ static esp_rmaker_device_t *light_device;
static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg)
{
if (!event) {
return;
}
switch (event->Type) {
case chip::DeviceLayer::DeviceEventType::kInterfaceIpAddressChanged:
ESP_LOGI(TAG, "Interface IP Address changed");
@@ -127,6 +133,11 @@ static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg)
ESP_LOGI(TAG, "BLE deinitialized and memory reclaimed");
break;
case chip::DeviceLayer::DeviceEventType::kCHIPoBLEAdvertisingChange:
if (event->CHIPoBLEAdvertisingChange.Result == chip::DeviceLayer::kActivity_Started) {
start_secondary_ble_adv();
}
default:
break;
}
@@ -294,7 +305,7 @@ extern "C" void app_main()
abort();
}
/* Matter start */
/* 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));
@@ -309,7 +320,7 @@ extern "C" void app_main()
bool is_wifi_provisioned = false;
wifi_prov_mgr_is_provisioned(&is_wifi_provisioned);
if (is_wifi_provisioned && esp_rmaker_user_node_mapping_get_state() == ESP_RMAKER_USER_MAPPING_DONE) {
chip::DeviceLayer::Internal::BLEMgr().Shutdown();
chip::DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t){ chip::DeviceLayer::Internal::BLEMgr().Shutdown(); });
}
#if CONFIG_ENABLE_CHIP_SHELL
@@ -25,7 +25,6 @@
#include <nvs.h>
#include <nvs_flash.h>
#include <platform/CHIPDeviceLayer.h>
#include <platform/ESP32_custom/PlatformManagerImpl.h>
#include <platform/PlatformManager.h>
#include <qrcode.h>
@@ -14,6 +14,7 @@
#include <host/ble_gap.h>
#include <host/ble_gatt.h>
#include <host/ble_uuid.h>
#include <host/util/util.h>
#include <protocomm.h>
#include <stdint.h>
#include <string.h>
@@ -35,7 +36,9 @@ typedef struct {
} _protocomm_matter_ble_internal_t;
static _protocomm_matter_ble_internal_t *protoble_internal = nullptr;
struct ble_gatt_svc_def *s_gatt_db = nullptr;
static struct ble_gatt_svc_def *s_gatt_db = nullptr;
static ble_hs_adv_fields s_secondary_adv_fields;
static ble_hs_adv_fields s_secondary_resp_fields;
#define BLE_GATT_UUID_CHAR_DSC 0x2901
#define TAG "protocomm_matter_ble"
@@ -402,7 +405,6 @@ static int protocomm_matter_ble_gap_event(struct ble_gap_event *event, void *arg
break;
case BLE_GAP_EVENT_DISCONNECT:
transport_matter_ble_disconnect(event, arg);
chip::DeviceLayer::Internal::BLEMgrImpl().RefreshAdv();
break;
case BLE_GAP_EVENT_MTU:
transport_matter_ble_set_mtu(event, arg);
@@ -413,6 +415,78 @@ static int protocomm_matter_ble_gap_event(struct ble_gap_event *event, void *arg
return 0;
}
int start_secondary_ble_adv()
{
if (!ble_hs_is_enabled()) {
return 0;
}
int ret = 0;
uint8_t secondary_own_addr_type;
ret = ble_hs_util_ensure_addr(0);
if (ret != 0) {
ESP_LOGE(TAG, "ble_hs_util_ensure_addr() failed");
return ret;
}
ret = ble_hs_id_infer_auto(0, &secondary_own_addr_type);
if (ret != 0) {
ESP_LOGE(TAG, "ble_hs_id_infer_auto() failed");
return ret;
}
ble_gap_ext_adv_params adv_params;
memset(&adv_params, 0, sizeof(adv_params));
adv_params.scannable = 1;
adv_params.own_addr_type = secondary_own_addr_type;
adv_params.legacy_pdu = 1;
adv_params.connectable = 1;
adv_params.itvl_min = 0x100;
adv_params.itvl_max = 0x100;
if (ble_gap_ext_adv_active(1)) {
ESP_LOGI(TAG, "Device already advertising, stop active advertisement and restart");
ret = ble_gap_ext_adv_stop(1);
if (ret != 0) {
ESP_LOGE(TAG, "ble_gap_ext_adv_stop() failed, cannot restart");
return ret;
}
}
ret = ble_gap_ext_adv_configure(1, &adv_params, NULL, protocomm_matter_ble_gap_event, NULL);
if (ret != 0) {
ESP_LOGE(TAG, "ble_gap_ext_adv_configure() failed");
return ret;
}
struct os_mbuf * data = os_msys_get_pkthdr(BLE_HCI_MAX_ADV_DATA_LEN, 0);
assert(data);
ret = ble_hs_adv_set_fields_mbuf(&s_secondary_adv_fields, data);
if (ret != 0) {
ESP_LOGE(TAG, "ble_hs_adv_set_fields_mbuf() failed");
return ret;
}
ret = ble_gap_ext_adv_set_data(1, data);
if (ret != 0) {
ESP_LOGE(TAG, "ble_gap_ext_adv_set_data()");
return ret;
}
struct os_mbuf * resp_data = os_msys_get_pkthdr(BLE_HCI_MAX_ADV_DATA_LEN, 0);
assert(resp_data);
ret = ble_hs_adv_set_fields_mbuf(&s_secondary_resp_fields, resp_data);
if (ret != 0) {
ESP_LOGE(TAG, "ble_hs_adv_set_fields_mbuf() failed");
return ret;
}
ret = ble_gap_ext_adv_rsp_set_data(1, resp_data);
if (ret != 0) {
ESP_LOGE(TAG, "ble_gap_ext_adv_rsp_set_data() failed");
return ret;
}
ret = ble_gap_ext_adv_start(1, 0, 0);
if (ret != 0) {
ESP_LOGE(TAG, "ble_gap_ext_adv_start() failed");
return ret;
}
return 0;
}
esp_err_t protocomm_matter_ble_start(protocomm_t *pc, const protocomm_matter_ble_config_t *config)
{
if (!pc || !config || !config->name_uuid_array_len || !config->name_uuid_array) {
@@ -451,11 +525,22 @@ esp_err_t protocomm_matter_ble_start(protocomm_t *pc, const protocomm_matter_ble
free_gatt_ble_misc_memory(s_gatt_db);
}
chip::DeviceLayer::Internal::BLEMgrImpl().SetSecondaryAdvDeviceName(config->device_name);
chip::DeviceLayer::Internal::BLEMgrImpl().SetSecondaryAdvUuid(chip::ByteSpan(config->service_uuid));
chip::DeviceLayer::Internal::BLEMgrImpl().SetSecondaryGATTService(s_gatt_db, 0);
chip::DeviceLayer::Internal::BLEMgrImpl().SetSecondaryBleSmConfig(config->ble_bonding, config->ble_sm_sc);
chip::DeviceLayer::Internal::BLEMgrImpl().SetSecondaryAdvGapEventHandler(protocomm_matter_ble_gap_event);
std::vector<struct ble_gatt_svc_def> extGattSvcs;
extGattSvcs.push_back(*s_gatt_db);
chip::DeviceLayer::Internal::BLEMgrImpl().ConfigureExtraServices(extGattSvcs, false);
memset(&s_secondary_adv_fields, 0, sizeof(s_secondary_adv_fields));
s_secondary_adv_fields.flags = (BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP);
s_secondary_adv_fields.num_uuids128 = 1;
s_secondary_adv_fields.uuids128_is_complete = 1;
static ble_uuid128_t s_secondary_adv_uuid;
s_secondary_adv_uuid.u.type = BLE_UUID_TYPE_128;
memcpy(s_secondary_adv_uuid.value, config->service_uuid, sizeof(config->service_uuid));
s_secondary_adv_fields.uuids128 = &s_secondary_adv_uuid;
memset(&s_secondary_resp_fields, 0, sizeof(s_secondary_resp_fields));
s_secondary_resp_fields.name = (const uint8_t *)config->device_name;
s_secondary_resp_fields.name_len = (uint8_t)strlen(config->device_name);
s_secondary_resp_fields.name_is_complete = 1;
return ESP_OK;
}
@@ -54,3 +54,4 @@ esp_err_t protocomm_matter_ble_start(protocomm_t *pc, const protocomm_matter_ble
esp_err_t protocomm_matter_ble_stop(protocomm_t *pc);
int start_secondary_ble_adv();
@@ -60,11 +60,6 @@ CONFIG_MBEDTLS_ERROR_STRINGS=n
# Fix for Timer Overflows
CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=3120
# External Platform
CONFIG_CHIP_ENABLE_EXTERNAL_PLATFORM=y
CONFIG_CHIP_EXTERNAL_PLATFORM_DIR="../../../../examples/common/secondary_ble_adv/platform/ESP32_custom"
CONFIG_CHIP_EXTERNAL_PLATFORM_INCLUDE_DIR="../../../../examples/common/secondary_ble_adv"
# Additional configurations
CONFIG_ESP_RMAKER_USER_ID_CHECK=y
CONFIG_ESP_RMAKER_NO_CLAIM=y
@@ -1,70 +0,0 @@
#enable BT
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=y
# Enable Extended advertisement of NIMBLE
CONFIG_BT_NIMBLE_EXT_ADV=y
CONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES=2
#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
# Enable HKDF in mbedtls
CONFIG_MBEDTLS_HKDF_C=y
# 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
# mbedtls
CONFIG_MBEDTLS_DYNAMIC_BUFFER=y
CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y
CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN=y
# For additional security on reset to factory
CONFIG_ESP_RMAKER_USER_ID_CHECK=y
# Fix for Timer Overflows
CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=3120
# External Platform
CONFIG_CHIP_ENABLE_EXTERNAL_PLATFORM=y
CONFIG_CHIP_EXTERNAL_PLATFORM_DIR="../../../../../builds/app-frameworks/esp-matter/examples/common/secondary_ble_adv/platform/ESP32_custom"
CONFIG_CHIP_EXTERNAL_PLATFORM_INCLUDE_DIR="../../../../../builds/app-frameworks/esp-matter/examples/common/secondary_ble_adv"
# Memory Optimization
CONFIG_ESP_WIFI_IRAM_OPT=n
CONFIG_ESP_WIFI_RX_IRAM_OPT=n
CONFIG_ESP_MATTER_MAX_DEVICE_TYPE_COUNT=2
CONFIG_ESP_MATTER_BINDING_TABLE_SIZE=1
CONFIG_EVENT_LOGGING_CRIT_BUFFER_SIZE=512
CONFIG_EVENT_LOGGING_INFO_BUFFER_SIZE=256
CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE=256
CONFIG_MAX_EXCHANGE_CONTEXTS=5
CONFIG_MAX_BINDINGS=2
CONFIG_MAX_PEER_NODES=8
CONFIG_NUM_TCP_ENDPOINTS=1
CONFIG_NUM_UDP_ENDPOINTS=6
@@ -1,56 +0,0 @@
#enable BT
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=y
# Enable Extended advertisement of NIMBLE
CONFIG_BT_NIMBLE_EXT_ADV=y
CONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES=2
#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
# Enable HKDF in mbedtls
CONFIG_MBEDTLS_HKDF_C=y
# 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
# mbedtls
CONFIG_MBEDTLS_DYNAMIC_BUFFER=y
CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y
CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN=y
# For additional security on reset to factory
CONFIG_ESP_RMAKER_USER_ID_CHECK=y
# Fix for Timer Overflows
CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=3120
# External Platform
CONFIG_CHIP_ENABLE_EXTERNAL_PLATFORM=y
CONFIG_CHIP_EXTERNAL_PLATFORM_DIR="../../../../../builds/app-frameworks/esp-matter/examples/common/secondary_ble_adv/platform/ESP32_custom"
CONFIG_CHIP_EXTERNAL_PLATFORM_INCLUDE_DIR="../../../../../builds/app-frameworks/esp-matter/examples/common/secondary_ble_adv"