Skip to content

Commit

Permalink
Merge branch 'master' into write_handler_validation
Browse files Browse the repository at this point in the history
  • Loading branch information
andreilitvin committed Feb 7, 2025
2 parents b0111d9 + 8deebeb commit 17dbfe0
Show file tree
Hide file tree
Showing 45 changed files with 732 additions and 318 deletions.
1 change: 1 addition & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ jobs:
scripts/run_in_python_env.sh out/venv 'python3 src/python_testing/TestIdChecks.py'
scripts/run_in_python_env.sh out/venv 'python3 src/python_testing/TestMatterTestingSupport.py'
scripts/run_in_python_env.sh out/venv 'python3 src/python_testing/TestSpecParsingDeviceType.py'
scripts/run_in_python_env.sh out/venv 'python3 src/python_testing/TestSpecParsingSelection.py'
scripts/run_in_python_env.sh out/venv 'python3 src/python_testing/TestSpecParsingSupport.py'
- name: Run Tests
Expand Down
2 changes: 1 addition & 1 deletion examples/chef/common/chef-concentration-measurement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ void emberAfPm1ConcentrationMeasurementClusterInitCallback(EndpointId endpoint)
void emberAfPm10ConcentrationMeasurementClusterInitCallback(EndpointId endpoint)
{
gPm10ConcentrationMeasurementInstance[EndpointId(endpoint)] = new Instance<true, true, true, true, true, true>(
EndpointId(endpoint), Pm10ConcentrationMeasurement::Id, MeasurementMediumEnum::kAir, MeasurementUnitEnum::kPpm);
EndpointId(endpoint), Pm10ConcentrationMeasurement::Id, MeasurementMediumEnum::kAir, MeasurementUnitEnum::kUgm3);
gPm10ConcentrationMeasurementInstance[EndpointId(endpoint)]->Init();
gPm10ConcentrationMeasurementInstance[EndpointId(endpoint)]->SetMeasuredValue(MakeNullable(50.0f));
gPm10ConcentrationMeasurementInstance[EndpointId(endpoint)]->SetMinMeasuredValue(MakeNullable(1.0f));
Expand Down
55 changes: 55 additions & 0 deletions examples/common/pigweed/rpc_services/AccessInterceptor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
*
* Copyright (c) 2025 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.
*/

#pragma once

#include "pw_status/status.h"
#include <app/AttributeReportBuilder.h>
#include <app/AttributeValueDecoder.h>
#include <app/AttributeValueEncoder.h>

namespace chip {
namespace rpc {

/**
* Callback class that clusters can implement in order to interpose custom
* interception logic.
*/
class PigweedDebugAccessInterceptor
{
public:
PigweedDebugAccessInterceptor() = default;
virtual ~PigweedDebugAccessInterceptor() = default;

/**
* Callback for writing attributes.
*
* The implementation can do one of three things:
*
* Returns:
* - `std::nullopt` if the `path` was not handled by this Interceptor.
* Interceptor MUST NOT have attepted to decode `decoder`.
* - A `::pw::Status` value that is considered the FINAL result of the
* write (i.e. write handled) either with success or failure.
*/
virtual std::optional<::pw::Status> Write(const chip::app::ConcreteDataAttributePath & path,
chip::app::AttributeValueDecoder & decoder) = 0;
};

} // namespace rpc
} // namespace chip
73 changes: 73 additions & 0 deletions examples/common/pigweed/rpc_services/AccessInterceptorRegistry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
*
* Copyright (c) 2025 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.
*/

#pragma once

#include "pw_status/status.h"
#include <pigweed/rpc_services/AccessInterceptor.h>
#include <set>

namespace chip {
namespace rpc {

/** @brief Custom debug request interceptors.
*
* This class is specifically meant for registering custom Accessors that
* allow mini-handlers to process PigweedRPC read/writes separately from the cluster
* code. It is meant to be used by samples using this PigweedRPC services to allow the RPC
* interface to be used in more ways than simply for example, simulating writes from a Matter
* client at the IM level. Handlers registered here by applications should be attempted before any
* standard processing.
*/
class PigweedDebugAccessInterceptorRegistry
{
public:
/**
* Registers an attribute access inteceptor within this registry. Use `Unregister` to
* unregister an interceptor that was previously registered.
* @param attrOverride - the interceptor to be registered.
*/
void Register(PigweedDebugAccessInterceptor * attrOverride) { mAccessors.insert(attrOverride); }

void Unregister(PigweedDebugAccessInterceptor * attrOverride)
{
if (mAccessors.find(attrOverride) == mAccessors.end())
{
ChipLogError(Support, "Attempt to unregister accessor that is not registered.");
return;
}
mAccessors.erase(attrOverride);
}

const std::set<PigweedDebugAccessInterceptor *> & GetAllAccessors() const { return mAccessors; }

/**
* Returns the singleton instance of the attribute accessor registory.
*/
static PigweedDebugAccessInterceptorRegistry & Instance()
{
static PigweedDebugAccessInterceptorRegistry instance;
return instance;
}

private:
std::set<PigweedDebugAccessInterceptor *> mAccessors;
};

} // namespace rpc
} // namespace chip
36 changes: 36 additions & 0 deletions examples/common/pigweed/rpc_services/Attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,42 @@
#include <app/data-model-provider/Provider.h>
#include <app/util/attribute-storage.h>
#include <app/util/attribute-table.h>
#include <data-model-providers/codegen/CodegenDataModelProvider.h>
#include <lib/core/TLV.h>
#include <lib/core/TLVTags.h>
#include <lib/core/TLVTypes.h>
#include <pigweed/rpc_services/AccessInterceptor.h>
#include <pigweed/rpc_services/AccessInterceptorRegistry.h>
#include <platform/PlatformManager.h>
#include <set>

namespace chip {
namespace rpc {

std::optional<::pw::Status> TryWriteViaAccessor(const chip::app::ConcreteDataAttributePath & path,
chip::app::AttributeValueDecoder & decoder)
{
std::set<PigweedDebugAccessInterceptor *> accessors = PigweedDebugAccessInterceptorRegistry::Instance().GetAllAccessors();

for (PigweedDebugAccessInterceptor * accessor : accessors)
{
std::optional<::pw::Status> result = accessor->Write(path, decoder);
if (result.has_value()) // Write was either a success or failure.
{
return result;
}
else if (decoder.TriedDecode())
{
ChipLogError(Support, "Interceptor tried decode but did not return status.");
return ::pw::Status::FailedPrecondition();
}
}

VerifyOrReturnError(!decoder.TriedDecode(), ::pw::Status::FailedPrecondition());

return std::nullopt;
}

// Implementation class for chip.rpc.Attributes.
class Attributes : public pw_rpc::nanopb::Attributes::Service<Attributes>
{
Expand Down Expand Up @@ -207,6 +235,14 @@ class Attributes : public pw_rpc::nanopb::Attributes::Service<Attributes>
}

app::AttributeValueDecoder decoder(tlvReader.value(), subjectDescriptor);

std::optional<::pw::Status> interceptResult = TryWriteViaAccessor(write_request.path, decoder);
if (interceptResult.has_value())
{
return *interceptResult;
}
ChipLogProgress(Support, "No custom PigweedRPC Attribute Accessor registration found, using fake write access.");

app::DataModel::ActionReturnStatus result = provider->WriteAttribute(write_request, decoder);

if (!result.IsSuccess())
Expand Down
27 changes: 27 additions & 0 deletions examples/lighting-app/telink/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,33 @@ To get output from device, connect UART to following pins:

Baud rate: 115200 bits/s

### Using USB COM Port Instead of UART

Alternatively, the USB COM port can be used instead of UART for console output.

1. Build the project with the following parameter:

```bash
$ west build -b <build_target> -- -DTLNK_USB_DONGLE=y
```

2. Connect the USB cable to your device. A new serial device should appear in
your system (e.g., `/dev/ttyACM0` on Linux or a COM port on Windows).
3. Use your preferred terminal application (like `minicom`, `screen`, or
`PuTTY`) to connect to the newly detected serial device.
4. In your source code, ensure the following header is included and the USB
device stack is initialized:

```c
#ifdef CONFIG_USB_DEVICE_STACK
#include <zephyr/usb/usb_device.h>
#endif /* CONFIG_USB_DEVICE_STACK */
#ifdef CONFIG_USB_DEVICE_STACK
usb_enable(NULL);
#endif /* CONFIG_USB_DEVICE_STACK */
```

### Buttons

The following buttons are available on **tlsr9518adk80d** board:
Expand Down
1 change: 1 addition & 0 deletions integrations/docker/images/base/chip-build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ RUN set -x \
unzip \
wget \
zlib1g-dev \
zstd \
&& rm -rf /var/lib/apt/lists/ \
&& git lfs install \
&& : # last line
Expand Down
2 changes: 1 addition & 1 deletion integrations/docker/images/base/chip-build/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
109 : [Tizen] Fix race when storing cert credentials
111 : [Android] Update android sdk and java version
4 changes: 2 additions & 2 deletions integrations/docker/images/stage-2/chip-build-java/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.source https://github.com/project-chip/connectedh
RUN set -x \
&& apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -fy \
openjdk-17-jdk \
openjdk-11-jdk \
&& rm -rf /var/lib/apt/lists/ \
&& : # last line

Expand All @@ -20,4 +20,4 @@ RUN set -x \
&& : # last line

ENV PATH $PATH:/usr/lib/kotlinc/bin
ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
18 changes: 9 additions & 9 deletions integrations/docker/images/stage-3/chip-build-android/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,26 @@ RUN set -x \

# Download and install android SDK
RUN set -x \
&& wget -O /tmp/android-26.zip https://dl.google.com/android/repository/platform-26_r02.zip \
&& wget -O /tmp/android-30.zip https://dl.google.com/android/repository/platform-30_r03.zip \
&& mkdir -p /opt/android/sdk/platforms \
&& cd /opt/android/sdk/platforms \
&& unzip /tmp/android-26.zip \
&& mv android-8.0.0 android-26 \
&& rm -f /tmp/android-26.zip \
&& unzip /tmp/android-30.zip \
&& mv android-11 android-30 \
&& rm -f /tmp/android-30.zip \
&& chmod -R a+rX /opt/android/sdk \
&& test -d /opt/android/sdk/platforms/android-26 \
&& test -d /opt/android/sdk/platforms/android-30 \
&& : # last line

# Download and install android command line tool (for installing `sdkmanager`)
# We need create latest folder inide cmdline-tools, since latest android commandline tool looks for this latest folder
# We need create 10.0 folder inide cmdline-tools, since latest android commandline tool looks for this latest folder
# when running sdkmanager --licenses
RUN set -x \
&& wget -O /tmp/cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip \
&& wget -O /tmp/cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-9862592_latest.zip \
&& cd /opt/android/sdk \
&& mkdir -p temp \
&& unzip /tmp/cmdline-tools.zip -d temp \
&& mkdir -p cmdline-tools/latest \
&& cp -rf temp/cmdline-tools/* cmdline-tools/latest \
&& mkdir -p cmdline-tools/10.0 \
&& cp -rf temp/cmdline-tools/* cmdline-tools/10.0 \
&& rm -rf temp \
&& test -d /opt/android/sdk/cmdline-tools \
&& : # last line
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ import chip.devicecontroller.model.NodeState;
import chip.devicecontroller.model.Status;

import javax.annotation.Nullable;
import java.lang.ref.Cleaner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -170,23 +169,10 @@ public class ChipClusters {

private Optional<Long> timeoutMillis = Optional.empty();

private final Cleaner.Cleanable cleanable;

public BaseChipCluster(long devicePtr, int endpointId, long clusterId) {
this.devicePtr = devicePtr;
this.endpointId = endpointId;
this.clusterId = clusterId;

this.cleanable =
Cleaner.create()
.register(
this,
() -> {
if (chipClusterPtr != 0) {
deleteCluster(chipClusterPtr);
chipClusterPtr = 0;
}
});
}

/**
Expand Down Expand Up @@ -255,6 +241,15 @@ public class ChipClusters {

@Deprecated
public void deleteCluster(long chipClusterPtr) {}
@SuppressWarnings("deprecation")
protected void finalize() throws Throwable {
super.finalize();

if (chipClusterPtr != 0) {
deleteCluster(chipClusterPtr);
chipClusterPtr = 0;
}
}
}

abstract static class ReportCallbackImpl implements ReportCallback, SubscriptionEstablishedCallback, ResubscriptionAttemptCallback {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import chip.devicecontroller.model.Status;

import javax.annotation.Nullable;
import java.lang.ref.Cleaner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -93,23 +92,10 @@ public static abstract class BaseChipCluster {

private Optional<Long> timeoutMillis = Optional.empty();

private final Cleaner.Cleanable cleanable;

public BaseChipCluster(long devicePtr, int endpointId, long clusterId) {
this.devicePtr = devicePtr;
this.endpointId = endpointId;
this.clusterId = clusterId;

this.cleanable =
Cleaner.create()
.register(
this,
() -> {
if (chipClusterPtr != 0) {
deleteCluster(chipClusterPtr);
chipClusterPtr = 0;
}
});
}

/**
Expand Down Expand Up @@ -178,6 +164,15 @@ protected void invoke(

@Deprecated
public void deleteCluster(long chipClusterPtr) {}
@SuppressWarnings("deprecation")
protected void finalize() throws Throwable {
super.finalize();

if (chipClusterPtr != 0) {
deleteCluster(chipClusterPtr);
chipClusterPtr = 0;
}
}
}

abstract static class ReportCallbackImpl implements ReportCallback, SubscriptionEstablishedCallback, ResubscriptionAttemptCallback {
Expand Down
Loading

0 comments on commit 17dbfe0

Please sign in to comment.