Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[app] add binding cluster support #12981

Merged
merged 11 commits into from
Jan 20, 2022
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
*
* 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.
*/

#pragma once

#include "lib/core/CHIPError.h"

CHIP_ERROR InitBindingHandlers();
112 changes: 112 additions & 0 deletions examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
*
* 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 "binding-handler.h"

#include "app-common/zap-generated/ids/Clusters.h"
#include "app-common/zap-generated/ids/Commands.h"
#include "app/CommandSender.h"
#include "app/clusters/bindings/BindingManager.h"
#include "app/server/Server.h"
#include "controller/InvokeInteraction.h"
#include "lib/core/CHIPError.h"

#if defined(ENABLE_CHIP_SHELL)
#include "lib/shell/Engine.h"

using chip::Shell::Engine;
using chip::Shell::shell_command_t;
using chip::Shell::streamer_get;
using chip::Shell::streamer_printf;
#endif // defined(ENABLE_CHIP_SHELL)

static bool sSwitchOnOffState = false;
#if defined(ENABLE_CHIP_SHELL)
static void ToggleSwitchOnOff(bool newState)
{
sSwitchOnOffState = newState;
chip::BindingManager::GetInstance().NotifyBoundClusterChanged(1, chip::app::Clusters::OnOff::Id, nullptr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if the switch is toggled quickly 'N' times in succession, and before BoundDeviceChangedHandler can be called? Does it result in N calls being made to BoundDeviceChangedHandler from the Binding manager?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we need to connect to the unicast binding first, we'll check for duplication when pushing to the pending nofication queue. Only one call will be made under such circumstance.
If the binding is ready, we'll directly call the handler. It will be up to the application to do anti-jittering.

}

static CHIP_ERROR SwitchCommandHandler(int argc, char ** argv)
{
if (argc == 1 && strcmp(argv[0], "on") == 0)
{
ToggleSwitchOnOff(true);
return CHIP_NO_ERROR;
}
if (argc == 1 && strcmp(argv[0], "off") == 0)
{
ToggleSwitchOnOff(false);
return CHIP_NO_ERROR;
}
streamer_printf(streamer_get(), "Usage: switch [on|off]");
return CHIP_NO_ERROR;
}

static void RegisterSwitchCommands()
{
static const shell_command_t sSwitchCommand = { SwitchCommandHandler, "switch", "Switch commands. Usage: switch [on|off]" };
Engine::Root().RegisterCommands(&sSwitchCommand, 1);
return;
}
#endif // defined(ENABLE_CHIP_SHELL)

static void BoundDeviceChangedHandler(const EmberBindingTableEntry * binding, chip::DeviceProxy * peer_device, void * context)
{
using namespace chip;
using namespace chip::app;

if (binding->type == EMBER_MULTICAST_BINDING)
{
ChipLogError(NotSpecified, "Group binding is not supported now");
return;
}

if (binding->type == EMBER_UNICAST_BINDING && binding->local == 1 && binding->clusterId == Clusters::OnOff::Id)
{
auto onSuccess = [](const ConcreteCommandPath & commandPath, const StatusIB & status, const auto & dataResponse) {
ChipLogProgress(NotSpecified, "OnOff command succeeds");
};
auto onFailure = [](const StatusIB & status, CHIP_ERROR error) {
ChipLogError(NotSpecified, "OnOff command failed: %" CHIP_ERROR_FORMAT, error.Format());
};

if (sSwitchOnOffState)
{
Clusters::OnOff::Commands::On::Type onCommand;
Controller::InvokeCommandRequest(peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(),
binding->remote, onCommand, onSuccess, onFailure);
}
else
{
Clusters::OnOff::Commands::Off::Type offCommand;
Controller::InvokeCommandRequest(peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(),
binding->remote, offCommand, onSuccess, onFailure);
}
}
}

CHIP_ERROR InitBindingHandlers()
{
chip::BindingManager::GetInstance().SetAppServer(&chip::Server::GetInstance());
chip::BindingManager::GetInstance().RegisterBoundDeviceChangedHandler(BoundDeviceChangedHandler);
#if defined(ENABLE_CHIP_SHELL)
RegisterSwitchCommands();
#endif
return CHIP_NO_ERROR;
}
2 changes: 2 additions & 0 deletions examples/all-clusters-app/esp32/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
#include <app/server/Server.h>
#include <app/util/af-types.h>
#include <app/util/af.h>
#include <binding-handler.h>
#include <credentials/DeviceAttestationCredsProvider.h>
#include <credentials/examples/DeviceAttestationCredsExample.h>
#include <lib/shell/Engine.h>
Expand Down Expand Up @@ -537,6 +538,7 @@ static void InitServer(intptr_t context)
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
NetWorkCommissioningInstInit();
SetupPretendDevices();
InitBindingHandlers();
}

static void InitOTARequestor(void)
Expand Down
7 changes: 7 additions & 0 deletions examples/all-clusters-app/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@
import("//build_overrides/build.gni")
import("//build_overrides/chip.gni")

import("${chip_root}/src/lib/lib.gni")

executable("chip-all-clusters-app") {
sources = [
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp",
"${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp",
"include/tv-callbacks.cpp",
Expand All @@ -35,6 +38,10 @@ executable("chip-all-clusters-app") {

cflags = [ "-Wconversion" ]

if (chip_build_libshell) {
defines = [ "ENABLE_CHIP_SHELL" ]
}

output_dir = root_out_dir
}

Expand Down
2 changes: 2 additions & 0 deletions examples/all-clusters-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <platform/Linux/NetworkCommissioningDriver.h>

#include "AppMain.h"
#include "binding-handler.h"

using namespace chip;
using namespace chip::app;
Expand Down Expand Up @@ -110,6 +111,7 @@ void ApplicationInit()
int main(int argc, char * argv[])
{
VerifyOrDie(ChipLinuxAppInit(argc, argv) == 0);
VerifyOrDie(InitBindingHandlers() == CHIP_NO_ERROR);
ChipLinuxAppMainLoop();
return 0;
}
Expand Down
1 change: 1 addition & 0 deletions examples/all-clusters-app/mbed/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ target_sources(${APP_TARGET} PRIVATE

${APP_CLUSTERS}/application-basic-server/application-basic-server.cpp
${APP_CLUSTERS}/basic/basic.cpp
${APP_CLUSTERS}/bindings/BindingManager.cpp
${APP_CLUSTERS}/bindings/bindings.cpp
${APP_CLUSTERS}/on-off-server/on-off-server.cpp
${APP_CLUSTERS}/access-control-server/access-control-server.cpp
Expand Down
1 change: 1 addition & 0 deletions examples/lighting-app/mbed/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ target_sources(${APP_TARGET} PRIVATE
${CHIP_ROOT}/src/app/server/CommissioningWindowManager.cpp
${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp
${CHIP_ROOT}/src/app/clusters/basic/basic.cpp
${CHIP_ROOT}/src/app/clusters/bindings/BindingManager.cpp
${CHIP_ROOT}/src/app/clusters/bindings/bindings.cpp
${CHIP_ROOT}/src/app/clusters/descriptor/descriptor.cpp
${CHIP_ROOT}/src/app/clusters/identify-server/identify-server.cpp
Expand Down
1 change: 1 addition & 0 deletions examples/lighting-app/telink/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ target_sources(app PRIVATE
${CHIP_ROOT}/src/app/server/CommissioningWindowManager.cpp
${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp
${CHIP_ROOT}/src/app/clusters/basic/basic.cpp
${CHIP_ROOT}/src/app/clusters/bindings/BindingManager.cpp
${CHIP_ROOT}/src/app/clusters/bindings/bindings.cpp
${CHIP_ROOT}/src/app/clusters/descriptor/descriptor.cpp
${CHIP_ROOT}/src/app/clusters/identify-server/identify-server.cpp
Expand Down
1 change: 1 addition & 0 deletions examples/lock-app/mbed/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ target_sources(${APP_TARGET} PRIVATE
${CHIP_ROOT}/src/app/server/CommissioningWindowManager.cpp
${CHIP_ROOT}/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp
${CHIP_ROOT}/src/app/clusters/basic/basic.cpp
${CHIP_ROOT}/src/app/clusters/bindings/BindingManager.cpp
${CHIP_ROOT}/src/app/clusters/bindings/bindings.cpp
${CHIP_ROOT}/src/app/clusters/descriptor/descriptor.cpp
${CHIP_ROOT}/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp
Expand Down
1 change: 1 addition & 0 deletions examples/platform/linux/AppMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ DeviceCommissioner * GetDeviceCommissioner()
void ChipLinuxAppMainLoop()
{
#if defined(ENABLE_CHIP_SHELL)
Engine::Root().Init();
std::thread shellThread([]() { Engine::Root().RunMainLoop(); });
chip::Shell::RegisterCommissioneeCommands();
#endif
Expand Down
3 changes: 2 additions & 1 deletion src/app/CASESessionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ CHIP_ERROR CASESessionManager::FindOrEstablishSession(PeerId peerId, Callback::C
CHIP_ERROR err = session->Connect(onConnection, onFailure, mConfig.dnsResolver);
if (err != CHIP_NO_ERROR)
{
ReleaseSession(session);
// Release the peer rather than the pointer in case the failure handler has already released the session.
ReleaseSession(peerId);
}

return err;
Expand Down
6 changes: 6 additions & 0 deletions src/app/chip_data_model.gni
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,12 @@ template("chip_data_model") {
"${_app_root}/clusters/${cluster}/BDXDownloader.h",
"${_app_root}/clusters/${cluster}/OTARequestor.cpp",
]
} else if (cluster == "bindings") {
sources += [
"${_app_root}/clusters/${cluster}/${cluster}.cpp",
"${_app_root}/clusters/${cluster}/BindingManager.cpp",
"${_app_root}/clusters/${cluster}/BindingManager.h",
]
} else {
sources += [ "${_app_root}/clusters/${cluster}/${cluster}.cpp" ]
}
Expand Down
Loading