blob: ef79290bd1961f50588ccc0b5efcc5faf5cac3de [file] [log] [blame]
/*
*
* 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<AlarmCodeEnum>(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<DoorStateEnum>(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;
}
}
}