Skip to content

Commit 1992080

Browse files
gjc13pull[bot]
authored andcommitted
[app] add binding cluster support (#12981)
* [app] add binding cluster support The change adds `BindingManager` class for managing the connections to bound devices and forward events on bound clusters to the application. * fix review comments & add docs * decouple client from server attributes * Use interaction engine to send On/Off commands * add group to the callback signature * fix review comments * add docs for binding callback arguments * fix unbind * modify callback signature * make BindingManager instance optional * Modify struct layout to save RAM
1 parent 614b2e8 commit 1992080

File tree

16 files changed

+671
-45
lines changed

16 files changed

+671
-45
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
*
3+
* Copyright (c) 2021 Project CHIP Authors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#pragma once
19+
20+
#include "lib/core/CHIPError.h"
21+
22+
CHIP_ERROR InitBindingHandlers();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
*
3+
* Copyright (c) 2021 Project CHIP Authors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include "binding-handler.h"
19+
20+
#include "app-common/zap-generated/ids/Clusters.h"
21+
#include "app-common/zap-generated/ids/Commands.h"
22+
#include "app/CommandSender.h"
23+
#include "app/clusters/bindings/BindingManager.h"
24+
#include "app/server/Server.h"
25+
#include "controller/InvokeInteraction.h"
26+
#include "lib/core/CHIPError.h"
27+
28+
#if defined(ENABLE_CHIP_SHELL)
29+
#include "lib/shell/Engine.h"
30+
31+
using chip::Shell::Engine;
32+
using chip::Shell::shell_command_t;
33+
using chip::Shell::streamer_get;
34+
using chip::Shell::streamer_printf;
35+
#endif // defined(ENABLE_CHIP_SHELL)
36+
37+
static bool sSwitchOnOffState = false;
38+
#if defined(ENABLE_CHIP_SHELL)
39+
static void ToggleSwitchOnOff(bool newState)
40+
{
41+
sSwitchOnOffState = newState;
42+
chip::BindingManager::GetInstance().NotifyBoundClusterChanged(1, chip::app::Clusters::OnOff::Id, nullptr);
43+
}
44+
45+
static CHIP_ERROR SwitchCommandHandler(int argc, char ** argv)
46+
{
47+
if (argc == 1 && strcmp(argv[0], "on") == 0)
48+
{
49+
ToggleSwitchOnOff(true);
50+
return CHIP_NO_ERROR;
51+
}
52+
if (argc == 1 && strcmp(argv[0], "off") == 0)
53+
{
54+
ToggleSwitchOnOff(false);
55+
return CHIP_NO_ERROR;
56+
}
57+
streamer_printf(streamer_get(), "Usage: switch [on|off]");
58+
return CHIP_NO_ERROR;
59+
}
60+
61+
static void RegisterSwitchCommands()
62+
{
63+
static const shell_command_t sSwitchCommand = { SwitchCommandHandler, "switch", "Switch commands. Usage: switch [on|off]" };
64+
Engine::Root().RegisterCommands(&sSwitchCommand, 1);
65+
return;
66+
}
67+
#endif // defined(ENABLE_CHIP_SHELL)
68+
69+
static void BoundDeviceChangedHandler(const EmberBindingTableEntry * binding, chip::DeviceProxy * peer_device, void * context)
70+
{
71+
using namespace chip;
72+
using namespace chip::app;
73+
74+
if (binding->type == EMBER_MULTICAST_BINDING)
75+
{
76+
ChipLogError(NotSpecified, "Group binding is not supported now");
77+
return;
78+
}
79+
80+
if (binding->type == EMBER_UNICAST_BINDING && binding->local == 1 && binding->clusterId == Clusters::OnOff::Id)
81+
{
82+
auto onSuccess = [](const ConcreteCommandPath & commandPath, const StatusIB & status, const auto & dataResponse) {
83+
ChipLogProgress(NotSpecified, "OnOff command succeeds");
84+
};
85+
auto onFailure = [](const StatusIB & status, CHIP_ERROR error) {
86+
ChipLogError(NotSpecified, "OnOff command failed: %" CHIP_ERROR_FORMAT, error.Format());
87+
};
88+
89+
if (sSwitchOnOffState)
90+
{
91+
Clusters::OnOff::Commands::On::Type onCommand;
92+
Controller::InvokeCommandRequest(peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(),
93+
binding->remote, onCommand, onSuccess, onFailure);
94+
}
95+
else
96+
{
97+
Clusters::OnOff::Commands::Off::Type offCommand;
98+
Controller::InvokeCommandRequest(peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(),
99+
binding->remote, offCommand, onSuccess, onFailure);
100+
}
101+
}
102+
}
103+
104+
CHIP_ERROR InitBindingHandlers()
105+
{
106+
chip::BindingManager::GetInstance().SetAppServer(&chip::Server::GetInstance());
107+
chip::BindingManager::GetInstance().RegisterBoundDeviceChangedHandler(BoundDeviceChangedHandler);
108+
#if defined(ENABLE_CHIP_SHELL)
109+
RegisterSwitchCommands();
110+
#endif
111+
return CHIP_NO_ERROR;
112+
}

examples/all-clusters-app/esp32/main/main.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#include <app/server/Server.h>
6262
#include <app/util/af-types.h>
6363
#include <app/util/af.h>
64+
#include <binding-handler.h>
6465
#include <credentials/DeviceAttestationCredsProvider.h>
6566
#include <credentials/examples/DeviceAttestationCredsExample.h>
6667
#include <lib/shell/Engine.h>
@@ -537,6 +538,7 @@ static void InitServer(intptr_t context)
537538
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
538539
NetWorkCommissioningInstInit();
539540
SetupPretendDevices();
541+
InitBindingHandlers();
540542
}
541543

542544
static void InitOTARequestor(void)

examples/all-clusters-app/linux/BUILD.gn

+7
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@
1515
import("//build_overrides/build.gni")
1616
import("//build_overrides/chip.gni")
1717

18+
import("${chip_root}/src/lib/lib.gni")
19+
1820
executable("chip-all-clusters-app") {
1921
sources = [
22+
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp",
2023
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp",
2124
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp",
2225
"include/tv-callbacks.cpp",
@@ -35,6 +38,10 @@ executable("chip-all-clusters-app") {
3538

3639
cflags = [ "-Wconversion" ]
3740

41+
if (chip_build_libshell) {
42+
defines = [ "ENABLE_CHIP_SHELL" ]
43+
}
44+
3845
output_dir = root_out_dir
3946
}
4047

examples/all-clusters-app/linux/main.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <platform/Linux/NetworkCommissioningDriver.h>
2525

2626
#include "AppMain.h"
27+
#include "binding-handler.h"
2728

2829
using namespace chip;
2930
using namespace chip::app;
@@ -110,6 +111,7 @@ void ApplicationInit()
110111
int main(int argc, char * argv[])
111112
{
112113
VerifyOrDie(ChipLinuxAppInit(argc, argv) == 0);
114+
VerifyOrDie(InitBindingHandlers() == CHIP_NO_ERROR);
113115
ChipLinuxAppMainLoop();
114116
return 0;
115117
}

examples/all-clusters-app/mbed/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ target_sources(${APP_TARGET} PRIVATE
8686

8787
${APP_CLUSTERS}/application-basic-server/application-basic-server.cpp
8888
${APP_CLUSTERS}/basic/basic.cpp
89+
${APP_CLUSTERS}/bindings/BindingManager.cpp
8990
${APP_CLUSTERS}/bindings/bindings.cpp
9091
${APP_CLUSTERS}/on-off-server/on-off-server.cpp
9192
${APP_CLUSTERS}/access-control-server/access-control-server.cpp

examples/lighting-app/mbed/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ target_sources(${APP_TARGET} PRIVATE
7474
${CHIP_ROOT}/src/app/server/CommissioningWindowManager.cpp
7575
${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp
7676
${CHIP_ROOT}/src/app/clusters/basic/basic.cpp
77+
${CHIP_ROOT}/src/app/clusters/bindings/BindingManager.cpp
7778
${CHIP_ROOT}/src/app/clusters/bindings/bindings.cpp
7879
${CHIP_ROOT}/src/app/clusters/descriptor/descriptor.cpp
7980
${CHIP_ROOT}/src/app/clusters/identify-server/identify-server.cpp

examples/lighting-app/telink/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ target_sources(app PRIVATE
7373
${CHIP_ROOT}/src/app/server/CommissioningWindowManager.cpp
7474
${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp
7575
${CHIP_ROOT}/src/app/clusters/basic/basic.cpp
76+
${CHIP_ROOT}/src/app/clusters/bindings/BindingManager.cpp
7677
${CHIP_ROOT}/src/app/clusters/bindings/bindings.cpp
7778
${CHIP_ROOT}/src/app/clusters/descriptor/descriptor.cpp
7879
${CHIP_ROOT}/src/app/clusters/identify-server/identify-server.cpp

examples/lock-app/mbed/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ target_sources(${APP_TARGET} PRIVATE
7272
${CHIP_ROOT}/src/app/server/CommissioningWindowManager.cpp
7373
${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp
7474
${CHIP_ROOT}/src/app/clusters/basic/basic.cpp
75+
${CHIP_ROOT}/src/app/clusters/bindings/BindingManager.cpp
7576
${CHIP_ROOT}/src/app/clusters/bindings/bindings.cpp
7677
${CHIP_ROOT}/src/app/clusters/descriptor/descriptor.cpp
7778
${CHIP_ROOT}/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp

examples/platform/linux/AppMain.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ DeviceCommissioner * GetDeviceCommissioner()
397397
void ChipLinuxAppMainLoop()
398398
{
399399
#if defined(ENABLE_CHIP_SHELL)
400+
Engine::Root().Init();
400401
std::thread shellThread([]() { Engine::Root().RunMainLoop(); });
401402
chip::Shell::RegisterCommissioneeCommands();
402403
#endif

src/app/CASESessionManager.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ CHIP_ERROR CASESessionManager::FindOrEstablishSession(PeerId peerId, Callback::C
5555
CHIP_ERROR err = session->Connect(onConnection, onFailure, mConfig.dnsResolver);
5656
if (err != CHIP_NO_ERROR)
5757
{
58-
ReleaseSession(session);
58+
// Release the peer rather than the pointer in case the failure handler has already released the session.
59+
ReleaseSession(peerId);
5960
}
6061

6162
return err;

src/app/chip_data_model.gni

+6
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@ template("chip_data_model") {
154154
"${_app_root}/clusters/${cluster}/BDXDownloader.h",
155155
"${_app_root}/clusters/${cluster}/OTARequestor.cpp",
156156
]
157+
} else if (cluster == "bindings") {
158+
sources += [
159+
"${_app_root}/clusters/${cluster}/${cluster}.cpp",
160+
"${_app_root}/clusters/${cluster}/BindingManager.cpp",
161+
"${_app_root}/clusters/${cluster}/BindingManager.h",
162+
]
157163
} else {
158164
sources += [ "${_app_root}/clusters/${cluster}/${cluster}.cpp" ]
159165
}

0 commit comments

Comments
 (0)