Skip to content

Commit

Permalink
[EFR32] Adding shell commands to light-switch example (#15515)
Browse files Browse the repository at this point in the history
* dynamic commands

* Added shell to light-switch

* clean up namespaces

* restyle
  • Loading branch information
mkardous-silabs authored and pull[bot] committed Sep 7, 2023
1 parent 6e0bc23 commit 1414908
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 15 deletions.
10 changes: 10 additions & 0 deletions examples/light-switch-app/efr32/include/binding-handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,17 @@
*/
#pragma once

#include "app-common/zap-generated/ids/Clusters.h"
#include "app-common/zap-generated/ids/Commands.h"
#include "lib/core/CHIPError.h"

CHIP_ERROR InitBindingHandler();
void SwitchToggleOnOff(intptr_t context);
void SwitchOnOffOn(intptr_t context);
void SwitchOnOffOff(intptr_t context);

struct BindingCommandData
{
chip::CommandId commandId;
chip::ClusterId clusterId;
};
142 changes: 127 additions & 15 deletions examples/light-switch-app/efr32/src/binding-handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,51 +18,163 @@
#include "binding-handler.h"

#include "AppConfig.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"

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

using namespace chip;
using namespace chip::app;

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

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

void ProcessOnOffBindingCommand(CommandId commandId, const EmberBindingTableEntry & binding, DeviceProxy * peer_device)
{
auto onSuccess = [](const ConcreteCommandPath & commandPath, const StatusIB & status, const auto & dataResponse) {
ChipLogProgress(NotSpecified, "OnOff command succeeds");
};

auto onFailure = [](CHIP_ERROR error) {
ChipLogError(NotSpecified, "OnOff command failed: %" CHIP_ERROR_FORMAT, error.Format());
};

switch (commandId)
{
case Clusters::OnOff::Commands::Toggle::Id:
Clusters::OnOff::Commands::Toggle::Type toggleCommand;
Controller::InvokeCommandRequest(peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote,
toggleCommand, onSuccess, onFailure);
break;

case Clusters::OnOff::Commands::On::Id:
Clusters::OnOff::Commands::On::Type onCommand;
Controller::InvokeCommandRequest(peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote,
onCommand, onSuccess, onFailure);
break;

case Clusters::OnOff::Commands::Off::Id:
Clusters::OnOff::Commands::Off::Type offCommand;
Controller::InvokeCommandRequest(peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote,
offCommand, onSuccess, onFailure);
break;

default:
ChipLogError(NotSpecified, "Invalid binding command data - commandId is not supported");
break;
}
}

void LightSwitchChangedHandler(const EmberBindingTableEntry & binding, DeviceProxy * peer_device, void * context)
{
VerifyOrReturn(context != nullptr, ChipLogError(NotSpecified, "Invalid context for Light switch handler"););
BindingCommandData * data = static_cast<BindingCommandData *>(context);

if (binding.type == EMBER_MULTICAST_BINDING)
{
ChipLogError(NotSpecified, "Group binding is not supported now");
return;
}
else if (binding.type == EMBER_UNICAST_BINDING && binding.local == 1 &&
(!binding.clusterId.HasValue() || binding.clusterId.Value() == data->clusterId))
{

switch (data->clusterId)
{
case Clusters::OnOff::Id:
ProcessOnOffBindingCommand(data->commandId, binding, peer_device);
break;
default:
ChipLogError(NotSpecified, "Invalid binding command data - clusterId is not supported");
break;
}
}

if (binding.type == EMBER_UNICAST_BINDING && binding.local == 1 && binding.clusterId.HasValue() &&
binding.clusterId.Value() == Clusters::OnOff::Id)
Platform::Delete(data);
}

#ifdef ENABLE_CHIP_SHELL
CHIP_ERROR SwitchCommandHandler(int argc, char ** argv)
{
if (argc == 1 && strcmp(argv[0], "on") == 0)
{
Clusters::OnOff::Commands::Toggle::Type toggleCommand;
Controller::InvokeCommandRequest(peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote,
toggleCommand, onSuccess, onFailure);
DeviceLayer::PlatformMgr().ScheduleWork(SwitchOnOffOn, 0);
}
else if (argc == 1 && strcmp(argv[0], "off") == 0)
{
DeviceLayer::PlatformMgr().ScheduleWork(SwitchOnOffOff, 0);
}
else if (argc == 1 && strcmp(argv[0], "toggle") == 0)
{
DeviceLayer::PlatformMgr().ScheduleWork(SwitchToggleOnOff, 0);
}
else
{
streamer_printf(streamer_get(), "Usage: switch [on|off|toggle]");
}
return CHIP_NO_ERROR;
}

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

void SwitchToggleOnOff(intptr_t context)
{
chip::BindingManager::GetInstance().NotifyBoundClusterChanged(1, chip::app::Clusters::OnOff::Id, nullptr);
BindingCommandData * data = Platform::New<BindingCommandData>();
VerifyOrReturn(data != nullptr, ChipLogError(NotSpecified, "SwitchToggleOnOff - Out of Memory of work data"));

data->clusterId = Clusters::OnOff::Id;
data->commandId = Clusters::OnOff::Commands::Toggle::Id;

BindingManager::GetInstance().NotifyBoundClusterChanged(1 /* endpointId */, Clusters::OnOff::Id, static_cast<void *>(data));
}

void SwitchOnOffOn(intptr_t context)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
VerifyOrReturn(data != nullptr, ChipLogError(NotSpecified, "SwitchOnOffOn - Out of Memory of work data"));

data->clusterId = Clusters::OnOff::Id;
data->commandId = Clusters::OnOff::Commands::On::Id;

BindingManager::GetInstance().NotifyBoundClusterChanged(1 /* endpointId */, Clusters::OnOff::Id, static_cast<void *>(data));
}

void SwitchOnOffOff(intptr_t context)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
VerifyOrReturn(data != nullptr, ChipLogError(NotSpecified, "SwitchOnOffOff - Out of Memory of work data"));

data->clusterId = Clusters::OnOff::Id;
data->commandId = Clusters::OnOff::Commands::Off::Id;

BindingManager::GetInstance().NotifyBoundClusterChanged(1 /* endpointId */, Clusters::OnOff::Id, static_cast<void *>(data));
}

CHIP_ERROR InitBindingHandler()
{
chip::BindingManager::GetInstance().SetAppServer(&chip::Server::GetInstance());
chip::BindingManager::GetInstance().RegisterBoundDeviceChangedHandler(BoundDeviceChangedHandler);
BindingManager::GetInstance().SetAppServer(&Server::GetInstance());
BindingManager::GetInstance().RegisterBoundDeviceChangedHandler(LightSwitchChangedHandler);

#if defined(ENABLE_CHIP_SHELL)
RegisterSwitchCommands();
#endif

return CHIP_NO_ERROR;
}

0 comments on commit 1414908

Please sign in to comment.