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

EFR32 lock event generation using matter shell #23248

Merged
merged 4 commits into from
Oct 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/lock-app/efr32/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ efr32_executable("lock_app") {
sources += [ "${examples_plat_dir}/uart.cpp" ]
}

if (chip_build_libshell) {
sources += [ "src/EventHandlerLibShell.cpp" ]
}

deps = [
":sdk",
"${chip_root}/examples/lock-app/lock-common",
Expand Down
3 changes: 3 additions & 0 deletions examples/lock-app/efr32/include/AppTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
#define APP_ERROR_START_TIMER_FAILED CHIP_APPLICATION_ERROR(0x05)
#define APP_ERROR_STOP_TIMER_FAILED CHIP_APPLICATION_ERROR(0x06)
#define APP_ERROR_ALLOCATION_FAILED CHIP_APPLICATION_ERROR(0x07)
#if defined(ENABLE_CHIP_SHELL)
#define APP_ERROR_TOO_MANY_SHELL_ARGUMENTS CHIP_APPLICATION_ERROR(0x08)
#endif // ENABLE_CHIP_SHELL

/**********************************************************
* AppTask Declaration
Expand Down
40 changes: 40 additions & 0 deletions examples/lock-app/efr32/include/EventHandlerLibShell.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
*
* Copyright (c) 2020 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 <app/clusters/door-lock-server/door-lock-server.h>

class EventData
{
public:
chip::EventId eventId;
};

class AlarmEventData : public EventData
{
public:
DlAlarmCode alarmCode;
};

class DoorStateEventData : public EventData
{
public:
DlDoorState doorState;
};

CHIP_ERROR RegisterLockEvents();
void EventWorkerFunction(intptr_t context);
12 changes: 12 additions & 0 deletions examples/lock-app/efr32/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include "AppTask.h"
#include "AppConfig.h"
#include "AppEvent.h"
#if defined(ENABLE_CHIP_SHELL)
#include "EventHandlerLibShell.h"
#endif // ENABLE_CHIP_SHELL

#ifdef ENABLE_WSTK_LEDS
#include "LEDWidget.h"
Expand Down Expand Up @@ -161,6 +164,15 @@ CHIP_ERROR AppTask::Init()
appError(err);
}

#if defined(ENABLE_CHIP_SHELL)
err = RegisterLockEvents();
if (err != CHIP_NO_ERROR)
{
EFR32_LOG("RegisterLockEvents() failed");
appError(err);
}
#endif // ENABLE_CHIP_SHELL

// Initial lock state
chip::app::DataModel::Nullable<chip::app::Clusters::DoorLock::DlLockState> state;
chip::EndpointId endpointId{ 1 };
Expand Down
211 changes: 211 additions & 0 deletions examples/lock-app/efr32/src/EventHandlerLibShell.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/*
*
* Copyright (c) 2020 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 "EventHandlerLibShell.h"
#include "AppTask.h"
#include "lib/shell/Engine.h"
#include "lib/shell/commands/Help.h"

#include "app/server/Server.h"
#include "platform/CHIPDeviceLayer.h"
#include <lib/support/CodeUtils.h>

constexpr uint8_t lockEndpoint = 1;

using namespace chip;
using namespace chip::app;
using namespace Clusters::DoorLock;
using Shell::Engine;
using Shell::shell_command_t;
using Shell::streamer_get;
using Shell::streamer_printf;

Engine sShellDoorlockSubCommands;
Engine sShellDoorlockEventSubCommands;
Engine sShellDoorlockEventAlarmSubCommands;
Engine sShellDoorlockEventDoorStateSubCommands;

/********************************************************
* Doorlock shell functions
*********************************************************/

CHIP_ERROR DoorlockHelpHandler(int argc, char ** argv)
{
sShellDoorlockSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
return CHIP_NO_ERROR;
}

CHIP_ERROR DoorlockCommandHandler(int argc, char ** argv)
{
if (argc == 0)
{
return DoorlockHelpHandler(argc, argv);
}

return sShellDoorlockSubCommands.ExecCommand(argc, argv);
}

/********************************************************
* Event shell functions
*********************************************************/

CHIP_ERROR EventHelpHandler(int argc, char ** argv)
{
sShellDoorlockEventSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
return CHIP_NO_ERROR;
}

CHIP_ERROR EventDoorlockCommandHandler(int argc, char ** argv)
{
if (argc == 0)
{
return EventHelpHandler(argc, argv);
}

return sShellDoorlockEventSubCommands.ExecCommand(argc, argv);
}

/********************************************************
* Alarm shell functions
*********************************************************/

CHIP_ERROR AlarmHelpHandler(int argc, char ** argv)
{
sShellDoorlockEventAlarmSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
return CHIP_NO_ERROR;
}

CHIP_ERROR AlarmEventHandler(int argc, char ** argv)
{

if (argc == 0)
{
return AlarmHelpHandler(argc, argv);
}
if (argc >= 2)
{
ChipLogError(Zcl, "Too many arguments provided to function %s, line %d", __func__, __LINE__);
return APP_ERROR_TOO_MANY_SHELL_ARGUMENTS;
}

AlarmEventData * data = Platform::New<AlarmEventData>();
data->eventId = Events::DoorLockAlarm::Id;
data->alarmCode = static_cast<DlAlarmCode>(atoi(argv[0]));

DeviceLayer::PlatformMgr().ScheduleWork(EventWorkerFunction, reinterpret_cast<intptr_t>(data));

return CHIP_NO_ERROR;
}

/********************************************************
* Door state shell functions
*********************************************************/

CHIP_ERROR DoorStateHelpHandler(int argc, char ** argv)
{
sShellDoorlockEventDoorStateSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
return CHIP_NO_ERROR;
}

CHIP_ERROR DoorStateEventHandler(int argc, char ** argv)
{

if (argc == 0)
{
return DoorStateHelpHandler(argc, argv);
}
if (argc >= 2)
{
ChipLogError(Zcl, "Too many arguments provided to function %s, line %d", __func__, __LINE__);
return APP_ERROR_TOO_MANY_SHELL_ARGUMENTS;
}

DoorStateEventData * data = Platform::New<DoorStateEventData>();
data->eventId = Events::DoorStateChange::Id;
data->doorState = static_cast<DlDoorState>(atoi(argv[0]));

DeviceLayer::PlatformMgr().ScheduleWork(EventWorkerFunction, reinterpret_cast<intptr_t>(data));

return CHIP_NO_ERROR;
}

/**
* @brief configures lock matter shell
*
*/

CHIP_ERROR RegisterLockEvents()
{
static const shell_command_t sDoorlockSubCommands[] = { { &DoorlockHelpHandler, "help", "Usage: doorlock <subcommand>" },
{ &EventDoorlockCommandHandler, "event",
" Usage: doorlock event <subcommand>" } };

static const shell_command_t sDoorlockEventSubCommands[] = {
{ &EventHelpHandler, "help", "Usage : doorlock event <subcommand>" },
{ &AlarmEventHandler, "lock-alarm", "Sends lock alarm event to lock app" },
{ &DoorStateEventHandler, "door-state-change", "Sends door state change event to lock app" }
};

static const shell_command_t sDoorlockEventAlarmSubCommands[] = { { &AlarmHelpHandler, "help",
"Usage : doorlock event lock-alarm AlarmCode" } };

static const shell_command_t sDoorlockEventDoorStateSubCommands[] = {
{ &DoorStateHelpHandler, "help", "Usage : doorlock event door-state-change DoorState" }
};

static const shell_command_t sDoorLockCommand = { &DoorlockCommandHandler, "doorlock",
"doorlock commands. Usage: doorlock <subcommand>" };

sShellDoorlockEventAlarmSubCommands.RegisterCommands(sDoorlockEventAlarmSubCommands, ArraySize(sDoorlockEventAlarmSubCommands));

sShellDoorlockEventDoorStateSubCommands.RegisterCommands(sDoorlockEventDoorStateSubCommands,
ArraySize(sDoorlockEventDoorStateSubCommands));

sShellDoorlockEventSubCommands.RegisterCommands(sDoorlockEventSubCommands, ArraySize(sDoorlockEventSubCommands));
sShellDoorlockSubCommands.RegisterCommands(sDoorlockSubCommands, ArraySize(sDoorlockSubCommands));

Engine::Root().RegisterCommands(&sDoorLockCommand, 1);

return CHIP_NO_ERROR;
}

void EventWorkerFunction(intptr_t context)
{
VerifyOrReturn(context != 0, ChipLogError(NotSpecified, "EventWorkerFunction - Invalid work data"));

EventData * data = reinterpret_cast<EventData *>(context);

switch (data->eventId)
{
case Events::DoorLockAlarm::Id: {
AlarmEventData * alarmData = reinterpret_cast<AlarmEventData *>(context);
DoorLockServer::Instance().SendLockAlarmEvent(lockEndpoint, alarmData->alarmCode);
break;
}

case Events::DoorStateChange::Id: {
DoorStateEventData * doorStateData = reinterpret_cast<DoorStateEventData *>(context);
DoorLockServer::Instance().SetDoorState(lockEndpoint, doorStateData->doorState);
break;
}

default: {
ChipLogError(Zcl, "Invalid Event Id %s, line %d", __func__, __LINE__);
break;
}
}
}