Skip to content

Commit

Permalink
ESP32: Add bridge app example to ESP32
Browse files Browse the repository at this point in the history
  • Loading branch information
sweetymhaiske committed Jul 14, 2021
1 parent 0e19e0d commit 6b33427
Show file tree
Hide file tree
Showing 12 changed files with 1,080 additions and 0 deletions.
14 changes: 14 additions & 0 deletions examples/bridge-app/esp32/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)

set(EXTRA_COMPONENT_DIRS
"${CMAKE_CURRENT_LIST_DIR}/third_party/connectedhomeip/config/esp32/components"
"${CMAKE_CURRENT_LIST_DIR}/../../common/m5stack-tft/repo/components/tft"
"${CMAKE_CURRENT_LIST_DIR}/../../common/m5stack-tft/repo/components/spidriver"
"${CMAKE_CURRENT_LIST_DIR}/../../common/QRCode"
"${CMAKE_CURRENT_LIST_DIR}/../../common/screen-framework"
)

project(chip-bridge-app)
idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++17;-Os;-DLWIP_IPV6_SCOPES=0;-DCHIP_HAVE_CONFIG_H;-DDYNAMIC_ENDPOINT_COUNT=16" APPEND)
idf_build_set_property(C_COMPILE_OPTIONS "-Os;-DLWIP_IPV6_SCOPES=0" APPEND)
104 changes: 104 additions & 0 deletions examples/bridge-app/esp32/main/CHIPDeviceManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
*
* Copyright (c) 2020 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @file
* This file implements the CHIP Device Interface that is used by
* applications to interact with the CHIP stack
*
*/

#include <stdlib.h>

#include "CHIPDeviceManager.h"
#include <app/util/basic-types.h>
#include <setup_payload/SetupPayload.h>
#include <support/CHIPMem.h>
#include <support/CodeUtils.h>
#include <support/ErrorStr.h>

using namespace ::chip;

namespace chip {

namespace DeviceManager {

using namespace ::chip::DeviceLayer;

void CHIPDeviceManager::CommonDeviceEventHandler(const ChipDeviceEvent * event, intptr_t arg)
{
CHIPDeviceManagerCallbacks * cb = reinterpret_cast<CHIPDeviceManagerCallbacks *>(arg);
if (cb != nullptr)
{
cb->DeviceEventCallback(event, reinterpret_cast<intptr_t>(cb));
}
}

CHIP_ERROR CHIPDeviceManager::Init(CHIPDeviceManagerCallbacks * cb)
{
CHIP_ERROR err;
mCB = cb;
RendezvousInformationFlags flags = RendezvousInformationFlags(CONFIG_RENDEZVOUS_MODE);

// Initialize the CHIP stack.
err = PlatformMgr().InitChipStack();
SuccessOrExit(err);

if (flags.Has(RendezvousInformationFlag::kBLE))
{
ConnectivityMgr().SetBLEAdvertisingEnabled(true);
}
else if (flags.Has(RendezvousInformationFlag::kSoftAP))
{
// TODO(cecille): Fix for the case where BLE and SoftAP are both enabled.`
ConnectivityMgr().SetBLEAdvertisingEnabled(false);
ConnectivityMgr().SetWiFiAPMode(ConnectivityManager::kWiFiAPMode_Enabled);
}
else
{
// If rendezvous is bypassed, enable SoftAP so that the device can still
// be communicated with via its SoftAP as needed.
ConnectivityMgr().SetWiFiAPMode(ConnectivityManager::kWiFiAPMode_Enabled);
}

err = Platform::MemoryInit();
SuccessOrExit(err);

// Register a function to receive events from the CHIP device layer. Note that calls to
// this function will happen on the CHIP event loop thread, not the app_main thread.
PlatformMgr().AddEventHandler(CHIPDeviceManager::CommonDeviceEventHandler, reinterpret_cast<intptr_t>(cb));

// Start a task to run the CHIP Device event loop.
err = PlatformMgr().StartEventLoopTask();
SuccessOrExit(err);

exit:
return err;
}
} // namespace DeviceManager
} // namespace chip

void emberAfPostAttributeChangeCallback(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId, uint8_t mask,
uint16_t manufacturerCode, uint8_t type, uint16_t size, uint8_t * value)
{
chip::DeviceManager::CHIPDeviceManagerCallbacks * cb =
chip::DeviceManager::CHIPDeviceManager::GetInstance().GetCHIPDeviceManagerCallbacks();
if (cb != nullptr)
{
cb->PostAttributeChangeCallback(endpointId, clusterId, attributeId, mask, manufacturerCode, type, size, value);
}
}
24 changes: 24 additions & 0 deletions examples/bridge-app/esp32/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
idf_component_register(PRIV_INCLUDE_DIRS
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/bridge-app/bridge-common"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32"
"${CMAKE_CURRENT_LIST_DIR}/include"
SRC_DIRS
"${CMAKE_CURRENT_LIST_DIR}"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/bridge-app/bridge-common/gen"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/basic"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/level-control"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/diagnostic-logs-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/descriptor"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/network-commissioning"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/on-off-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/operational-credentials-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/general-commissioning-server"
PRIV_REQUIRES chip QRCode tft spidriver bt screen-framework)

set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17)
target_compile_options(${COMPONENT_LIB} PRIVATE "-DLWIP_IPV6_SCOPES=0" "-DCHIP_HAVE_CONFIG_H")

102 changes: 102 additions & 0 deletions examples/bridge-app/esp32/main/Device.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include "Device.h"

#include <cstdio>
#include <platform/CHIPDeviceLayer.h>

Device::Device(const char * szDeviceName, const char * szLocation)
{
strncpy(mName, szDeviceName, sizeof(mName));
strncpy(mLocation, szLocation, sizeof(mLocation));
mState = kState_Off;
mReachable = false;
mEndpointId = 0;
mChanged_CB = nullptr;
}

bool Device::IsOn()
{
return mState == kState_On;
}

bool Device::IsReachable()
{
return mReachable;
}

void Device::SetOnOff(bool aOn)
{
bool changed;

if (aOn)
{
changed = (mState != kState_On);
mState = kState_On;
ChipLogProgress(DeviceLayer, "Device[%s]: ON", mName);
}
else
{
changed = (mState != kState_Off);
mState = kState_Off;
ChipLogProgress(DeviceLayer, "Device[%s]: OFF", mName);
}

if ((changed) && (mChanged_CB))
{
mChanged_CB(this, kChanged_State);
}
}

void Device::SetReachable(bool aReachable)
{
bool changed = (mReachable != aReachable);

mReachable = aReachable;

if (aReachable)
{
ChipLogProgress(DeviceLayer, "Device[%s]: ONLINE", mName);
}
else
{
ChipLogProgress(DeviceLayer, "Device[%s]: OFFLINE", mName);
}

if ((changed) && (mChanged_CB))
{
mChanged_CB(this, kChanged_Reachable);
}
}

void Device::SetName(const char * szName)
{
bool changed = (strncmp(mName, szName, sizeof(mName)) != 0);

ChipLogProgress(DeviceLayer, "Device[%s]: New Name=\"%s\"", mName, szName);

strncpy(mName, szName, sizeof(mName));

if ((changed) && (mChanged_CB))
{
mChanged_CB(this, kChanged_Name);
}
}

void Device::SetLocation(const char * szLocation)
{
bool changed = (strncmp(mLocation, szLocation, sizeof(mLocation)) != 0);

strncpy(mLocation, szLocation, sizeof(mLocation));

ChipLogProgress(DeviceLayer, "Device[%s]: Location=\"%s\"", mName, mLocation);

if ((changed) && (mChanged_CB))
{
mChanged_CB(this, kChanged_Location);
}
}

void Device::SetChangeCallback(DeviceCallback_fn aChanged_CB)
{
mChanged_CB = aChanged_CB;
}

133 changes: 133 additions & 0 deletions examples/bridge-app/esp32/main/DeviceCallbacks.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
*
* Copyright (c) 2020 Project CHIP Authors
* 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 DeviceCallbacks.cpp
*
* Implements all the callbacks to the application from the CHIP Stack
*
**/

#include "DeviceCallbacks.h"
#include "freertos/FreeRTOS.h"
#include "esp_heap_caps.h"
#include "esp_log.h"
#include <app/common/gen/attribute-id.h>
#include <app/common/gen/cluster-id.h>
#include <app/server/Mdns.h>
#include <support/CodeUtils.h>

static const char * TAG = "lock-devicecallbacks";

using namespace ::chip;
using namespace ::chip::Inet;
using namespace ::chip::System;
using namespace ::chip::DeviceLayer;

void DeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg)
{
switch (event->Type)
{
case DeviceEventType::kInternetConnectivityChange:
OnInternetConnectivityChange(event);
break;

case DeviceEventType::kSessionEstablished:
OnSessionEstablished(event);
break;

case DeviceEventType::kInterfaceIpAddressChanged:
if ((event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV4_Assigned) ||
(event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV6_Assigned))
{
// MDNS server restart on any ip assignment: if link local ipv6 is configured, that
// will not trigger a 'internet connectivity change' as there is no internet
// connectivity. MDNS still wants to refresh its listening interfaces to include the
// newly selected address.
chip::app::Mdns::StartServer();
}
break;
}

ESP_LOGI(TAG, "Current free heap: %d\n", heap_caps_get_free_size(MALLOC_CAP_8BIT));
}
void DeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId, uint8_t mask,
uint16_t manufacturerCode, uint8_t type, uint16_t size, uint8_t * value)
{
ESP_LOGI(TAG, "PostAttributeChangeCallback - Cluster ID: '0x%04x', EndPoint ID: '0x%02x', Attribute ID: '0x%04x'", clusterId,
endpointId, attributeId);

switch (clusterId)
{
case ZCL_ON_OFF_CLUSTER_ID:
OnOnOffPostAttributeChangeCallback(endpointId, attributeId, value);
break;

default:
ESP_LOGI(TAG, "Unhandled cluster ID: %d", clusterId);
break;
}

ESP_LOGI(TAG, "Current free heap: %d\n", heap_caps_get_free_size(MALLOC_CAP_8BIT));
}

void DeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event)
{
if (event->InternetConnectivityChange.IPv4 == kConnectivity_Established)
{
ESP_LOGI(TAG, "Server ready at: %s:%d", event->InternetConnectivityChange.address, CHIP_PORT);
chip::app::Mdns::StartServer();
}
else if (event->InternetConnectivityChange.IPv4 == kConnectivity_Lost)
{
ESP_LOGE(TAG, "Lost IPv4 connectivity...");
}
if (event->InternetConnectivityChange.IPv6 == kConnectivity_Established)
{
ESP_LOGI(TAG, "IPv6 Server ready...");
chip::app::Mdns::StartServer();
}
else if (event->InternetConnectivityChange.IPv6 == kConnectivity_Lost)
{
ESP_LOGE(TAG, "Lost IPv6 connectivity...");
}
}

void DeviceCallbacks::OnSessionEstablished(const ChipDeviceEvent * event)
{
if (event->SessionEstablished.IsCommissioner)
{
ESP_LOGI(TAG, "Commissioner detected!");
}
}

void DeviceCallbacks::OnOnOffPostAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value)
{
/* VerifyOrExit(attributeId == ZCL_ON_OFF_ATTRIBUTE_ID, ESP_LOGI(TAG, "Unhandled Attribute ID: '0x%04x", attributeId));
VerifyOrExit(endpointId == 1 || endpointId == 2, ESP_LOGE(TAG, "Unexpected EndPoint ID: `0x%02x'", endpointId));
if (*value)
{
BoltLockMgr().InitiateAction(AppEvent::kEventType_Lock, BoltLockManager::LOCK_ACTION);
}
else
{
BoltLockMgr().InitiateAction(AppEvent::kEventType_Lock, BoltLockManager::UNLOCK_ACTION);
}
exit:*/
return;
}
Loading

0 comments on commit 6b33427

Please sign in to comment.