Skip to content

Commit

Permalink
Bridge app test updates (#18858)
Browse files Browse the repository at this point in the history
* Changes to support the bridge test plan.

Added single character commands to the bridge-app to support the
bridge test plan. The following commands are supported:

2 (TC-BR-2) Light 2 is added
4 (TC-BR-4) Light 1 is removed
5 (TC-BR-5) Light 1 is added back
b (TC-BR-3 step 1b) Present devices are renamed
c (TC-BR-3 step 2c) State  of Light 1 and Light 2 are changed.
Z

* Progress for aggregator changes.

* Changed the example/bridge app have the bridge on a non-zero endpoint ID.

The example/bridge-app was updated to use a non-zero endpoint-ID.
The bridge/aggregator is now on endpoint 1. All endpoint IDs show on both
endpoint ID 0, and the dynamic deivces added to the bridge show on the
bridge endpoint ID 1 as well.

* Removed fixed label from bridge-app example.

The funcion of the fixed label is replaced by the actions cluster,
so the fixed label was removed.

* Update examples/bridge-app/linux/bridged-actions-stub.cpp

Co-authored-by: Boris Zbarsky <[email protected]>

* Added Restyled changes.

* Resolved build failures for bridge-app

  - removed fixed label support from esp32 bridge-app
  - added include for identify-server.h
  - added callbacks for bridged-actions

* Fixed restyled whitespace.

Co-authored-by: Boris Zbarsky <[email protected]>
  • Loading branch information
2 people authored and pull[bot] committed Jan 5, 2024
1 parent 9a0b92b commit 1016444
Show file tree
Hide file tree
Showing 18 changed files with 2,884 additions and 469 deletions.
349 changes: 329 additions & 20 deletions examples/bridge-app/bridge-common/bridge-app.matter

Large diffs are not rendered by default.

2,087 changes: 1,899 additions & 188 deletions examples/bridge-app/bridge-common/bridge-app.zap

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions examples/bridge-app/esp32/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ idf_component_register(PRIV_INCLUDE_DIRS
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/basic"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/bridged-device-basic-information-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/level-control"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/identify-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/diagnostic-logs-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/ethernet-network-diagnostics-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/localization-configuration-server"
Expand Down
84 changes: 84 additions & 0 deletions examples/bridge-app/esp32/main/DeviceCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,23 @@
* limitations under the License.
*/

#include <app-common/zap-generated/af-structs.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app-common/zap-generated/ids/Attributes.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app/AttributeAccessInterface.h>
#include <app/util/attribute-storage.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>

#include "DeviceCallbacks.h"

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

using namespace ::chip;
using namespace ::chip::app;
using namespace ::chip::app::Clusters;
using namespace ::chip::app::Clusters::BridgedActions::Attributes;
using namespace ::chip::Inet;
using namespace ::chip::System;

Expand All @@ -31,3 +43,75 @@ void AppDeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, Clus
endpointId, attributeId);
ESP_LOGI(TAG, "Current free heap: %d\n", heap_caps_get_free_size(MALLOC_CAP_8BIT));
}

namespace {

class BridgedActionsAttrAccess : public AttributeAccessInterface
{
public:
// Register for the Bridged Actions cluster on all endpoints.
BridgedActionsAttrAccess() : AttributeAccessInterface(Optional<EndpointId>::Missing(), BridgedActions::Id) {}

CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override;

private:
static constexpr uint16_t ClusterRevision = 1;

CHIP_ERROR ReadActionListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder);
CHIP_ERROR ReadEndpointListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder);
CHIP_ERROR ReadSetupUrlAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder);
CHIP_ERROR ReadClusterRevision(EndpointId endpoint, AttributeValueEncoder & aEncoder);
};

constexpr uint16_t BridgedActionsAttrAccess::ClusterRevision;

CHIP_ERROR BridgedActionsAttrAccess::ReadActionListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder)
{
// Just return an empty list
return aEncoder.EncodeEmptyList();
}

CHIP_ERROR BridgedActionsAttrAccess::ReadEndpointListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder)
{
// Just return an empty list
return aEncoder.EncodeEmptyList();
}

CHIP_ERROR BridgedActionsAttrAccess::ReadSetupUrlAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder)
{
const char SetupUrl[] = "https://example.com";
return aEncoder.Encode(chip::CharSpan::fromCharString(SetupUrl));
}

CHIP_ERROR BridgedActionsAttrAccess::ReadClusterRevision(EndpointId endpoint, AttributeValueEncoder & aEncoder)
{
return aEncoder.Encode(ClusterRevision);
}

BridgedActionsAttrAccess gAttrAccess;

CHIP_ERROR BridgedActionsAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
{
VerifyOrDie(aPath.mClusterId == BridgedActions::Id);

switch (aPath.mAttributeId)
{
case ActionList::Id:
return ReadActionListAttribute(aPath.mEndpointId, aEncoder);
case EndpointList::Id:
return ReadEndpointListAttribute(aPath.mEndpointId, aEncoder);
case SetupUrl::Id:
return ReadSetupUrlAttribute(aPath.mEndpointId, aEncoder);
case ClusterRevision::Id:
return ReadClusterRevision(aPath.mEndpointId, aEncoder);
default:
break;
}
return CHIP_NO_ERROR;
}
} // anonymous namespace

void MatterBridgedActionsPluginServerInitCallback(void)
{
registerAttributeAccessOverride(&gAttrAccess);
}
59 changes: 3 additions & 56 deletions examples/bridge-app/esp32/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <app-common/zap-generated/af-structs.h>
#include <app-common/zap-generated/attribute-id.h>
#include <app-common/zap-generated/cluster-id.h>
#include <app/clusters/identify-server/identify-server.h>
#include <app/reporting/reporting.h>
#include <app/util/attribute-storage.h>
#include <common/Esp32AppServer.h>
Expand All @@ -42,7 +43,6 @@ static AppDeviceCallbacks AppCallback;
static const int kNodeLabelSize = 32;
// Current ZCL implementation of Struct uses a max-size array of 254 bytes
static const int kDescriptorAttributeArraySize = 254;
static const int kFixedLabelAttributeArraySize = 254;

static EndpointId gCurrentEndpointId;
static EndpointId gFirstDynamicEndpointId;
Expand Down Expand Up @@ -71,7 +71,6 @@ static Device gLight4("Light 4", "Den");
- On/Off
- Descriptor
- Bridged Device Basic
- Fixed Label
*/

// Declare On/Off cluster attributes
Expand All @@ -93,11 +92,6 @@ DECLARE_DYNAMIC_ATTRIBUTE(ZCL_NODE_LABEL_ATTRIBUTE_ID, CHAR_STRING, kNodeLabelSi
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_REACHABLE_ATTRIBUTE_ID, BOOLEAN, 1, 0), /* Reachable */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();

// Declare Fixed Label cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(fixedLabelAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(ZCL_LABEL_LIST_ATTRIBUTE_ID, ARRAY, kFixedLabelAttributeArraySize, 0), /* label list */
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();

// Declare Cluster List for Bridged Light endpoint
// TODO: It's not clear whether it would be better to get the command lists from
// the ZAP config on our last fixed endpoint instead.
Expand All @@ -114,8 +108,8 @@ constexpr CommandId onOffIncomingCommands[] = {
DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(bridgedLightClusters)
DECLARE_DYNAMIC_CLUSTER(ZCL_ON_OFF_CLUSTER_ID, onOffAttrs, onOffIncomingCommands, nullptr),
DECLARE_DYNAMIC_CLUSTER(ZCL_DESCRIPTOR_CLUSTER_ID, descriptorAttrs, nullptr, nullptr),
DECLARE_DYNAMIC_CLUSTER(ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, bridgedDeviceBasicAttrs, nullptr, nullptr),
DECLARE_DYNAMIC_CLUSTER(ZCL_FIXED_LABEL_CLUSTER_ID, fixedLabelAttrs, nullptr, nullptr), DECLARE_DYNAMIC_CLUSTER_LIST_END;
DECLARE_DYNAMIC_CLUSTER(ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID, bridgedDeviceBasicAttrs, nullptr,
nullptr) DECLARE_DYNAMIC_CLUSTER_LIST_END;

// Declare Bridged Light endpoint
DECLARE_DYNAMIC_ENDPOINT(bridgedLightEndpoint, bridgedLightClusters);
Expand Down Expand Up @@ -201,18 +195,6 @@ uint8_t * ToZclCharString(uint8_t * zclString, const char * cString, uint8_t max
return zclString;
}

// Converted into bytes and mapped the (label, value)
void EncodeFixedLabel(const char * label, const char * value, uint8_t * buffer, uint16_t length,
const EmberAfAttributeMetadata * am)
{
_LabelStruct labelStruct;

labelStruct.label = chip::CharSpan::fromCharString(label);
labelStruct.value = chip::CharSpan::fromCharString(value);

// TODO: Need to set up an AttributeAccessInterface to handle the lists here.
}

EmberAfStatus HandleReadBridgedDeviceBasicAttribute(Device * dev, chip::AttributeId attributeId, uint8_t * buffer,
uint16_t maxReadLength)
{
Expand All @@ -238,25 +220,6 @@ EmberAfStatus HandleReadBridgedDeviceBasicAttribute(Device * dev, chip::Attribut
return EMBER_ZCL_STATUS_SUCCESS;
}

EmberAfStatus HandleReadFixedLabelAttribute(Device * dev, const EmberAfAttributeMetadata * am, uint8_t * buffer,
uint16_t maxReadLength)
{
if ((am->attributeId == ZCL_LABEL_LIST_ATTRIBUTE_ID) && (maxReadLength <= kFixedLabelAttributeArraySize))
{
EncodeFixedLabel("room", dev->GetLocation(), buffer, maxReadLength, am);
}
else if ((am->attributeId == ZCL_CLUSTER_REVISION_SERVER_ATTRIBUTE_ID) && (maxReadLength == 2))
{
*buffer = (uint16_t) ZCL_FIXED_LABEL_CLUSTER_REVISION;
}
else
{
return EMBER_ZCL_STATUS_FAILURE;
}

return EMBER_ZCL_STATUS_SUCCESS;
}

EmberAfStatus HandleReadOnOffAttribute(Device * dev, chip::AttributeId attributeId, uint8_t * buffer, uint16_t maxReadLength)
{
ChipLogProgress(DeviceLayer, "HandleReadOnOffAttribute: attrId=%d, maxReadLength=%d", attributeId, maxReadLength);
Expand Down Expand Up @@ -300,10 +263,6 @@ EmberAfStatus emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterI
{
return HandleReadBridgedDeviceBasicAttribute(dev, attributeMetadata->attributeId, buffer, maxReadLength);
}
else if (clusterId == ZCL_FIXED_LABEL_CLUSTER_ID)
{
return HandleReadFixedLabelAttribute(dev, attributeMetadata, buffer, maxReadLength);
}
else if (clusterId == ZCL_ON_OFF_CLUSTER_ID)
{
return HandleReadOnOffAttribute(dev, attributeMetadata->attributeId, buffer, maxReadLength);
Expand Down Expand Up @@ -354,18 +313,6 @@ void HandleDeviceStatusChanged(Device * dev, Device::Changed_t itemChangedMask)
MatterReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_BRIDGED_DEVICE_BASIC_CLUSTER_ID,
ZCL_NODE_LABEL_ATTRIBUTE_ID, ZCL_CHAR_STRING_ATTRIBUTE_TYPE, zclName);
}
if (itemChangedMask & Device::kChanged_Location)
{
uint8_t buffer[kFixedLabelAttributeArraySize];
EmberAfAttributeMetadata am = { .attributeId = ZCL_LABEL_LIST_ATTRIBUTE_ID,
.size = kFixedLabelAttributeArraySize,
.defaultValue = static_cast<uint32_t>(0) };

EncodeFixedLabel("room", dev->GetLocation(), buffer, sizeof(buffer), &am);

MatterReportingAttributeChangeCallback(dev->GetEndpointId(), ZCL_FIXED_LABEL_CLUSTER_ID, ZCL_LABEL_LIST_ATTRIBUTE_ID,
ZCL_ARRAY_ATTRIBUTE_TYPE, buffer);
}
}

const EmberAfDeviceType gBridgedRootDeviceTypes[] = { { DEVICE_TYPE_ROOT_NODE, DEVICE_VERSION_DEFAULT },
Expand Down
1 change: 1 addition & 0 deletions examples/bridge-app/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ assert(chip_build_tools)

executable("chip-bridge-app") {
sources = [
"${chip_root}/examples/bridge-app/linux/bridged-actions-stub.cpp",
"${chip_root}/examples/tv-app/tv-common/include/CHIPProjectAppConfig.h",
"Device.cpp",
"include/Device.h",
Expand Down
6 changes: 6 additions & 0 deletions examples/bridge-app/linux/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ void DeviceOnOff::SetOnOff(bool aOn)
}
}

void DeviceOnOff::Toggle()
{
bool aOn = !IsOn();
SetOnOff(aOn);
}

void DeviceOnOff::SetChangeCallback(DeviceCallback_fn aChanged_CB)
{
mChanged_CB = aChanged_CB;
Expand Down
102 changes: 102 additions & 0 deletions examples/bridge-app/linux/bridged-actions-stub.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
*
* Copyright (c) 2021 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <app-common/zap-generated/af-structs.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app-common/zap-generated/ids/Attributes.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app/AttributeAccessInterface.h>
#include <app/util/attribute-storage.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>

using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;
using namespace chip::app::Clusters::BridgedActions::Attributes;

namespace {

class BridgedActionsAttrAccess : public AttributeAccessInterface
{
public:
// Register for the Bridged Actions cluster on all endpoints.
BridgedActionsAttrAccess() : AttributeAccessInterface(Optional<EndpointId>::Missing(), BridgedActions::Id) {}

CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override;

private:
static constexpr uint16_t ClusterRevision = 1;

CHIP_ERROR ReadActionListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder);
CHIP_ERROR ReadEndpointListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder);
CHIP_ERROR ReadSetupUrlAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder);
CHIP_ERROR ReadClusterRevision(EndpointId endpoint, AttributeValueEncoder & aEncoder);
};

constexpr uint16_t BridgedActionsAttrAccess::ClusterRevision;

CHIP_ERROR BridgedActionsAttrAccess::ReadActionListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder)
{
// Just return an empty list
return aEncoder.EncodeEmptyList();
}

CHIP_ERROR BridgedActionsAttrAccess::ReadEndpointListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder)
{
// Just return an empty list
return aEncoder.EncodeEmptyList();
}

CHIP_ERROR BridgedActionsAttrAccess::ReadSetupUrlAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder)
{
const char SetupUrl[] = "https://example.com";
return aEncoder.Encode(chip::CharSpan::fromCharString(SetupUrl));
}

CHIP_ERROR BridgedActionsAttrAccess::ReadClusterRevision(EndpointId endpoint, AttributeValueEncoder & aEncoder)
{
return aEncoder.Encode(ClusterRevision);
}

BridgedActionsAttrAccess gAttrAccess;

CHIP_ERROR BridgedActionsAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
{
VerifyOrDie(aPath.mClusterId == BridgedActions::Id);

switch (aPath.mAttributeId)
{
case ActionList::Id:
return ReadActionListAttribute(aPath.mEndpointId, aEncoder);
case EndpointList::Id:
return ReadEndpointListAttribute(aPath.mEndpointId, aEncoder);
case SetupUrl::Id:
return ReadSetupUrlAttribute(aPath.mEndpointId, aEncoder);
case ClusterRevision::Id:
return ReadClusterRevision(aPath.mEndpointId, aEncoder);
default:
break;
}
return CHIP_NO_ERROR;
}
} // anonymous namespace

void MatterBridgedActionsPluginServerInitCallback(void)
{
registerAttributeAccessOverride(&gAttrAccess);
}
1 change: 1 addition & 0 deletions examples/bridge-app/linux/include/Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class DeviceOnOff : public Device

bool IsOn();
void SetOnOff(bool aOn);
void Toggle();

using DeviceCallback_fn = std::function<void(DeviceOnOff *, DeviceOnOff::Changed_t)>;
void SetChangeCallback(DeviceCallback_fn aChanged_CB);
Expand Down
Loading

0 comments on commit 1016444

Please sign in to comment.