diff --git a/examples/lock-app/silabs/src/EventHandlerLibShell.cpp b/examples/lock-app/silabs/src/EventHandlerLibShell.cpp index ef79290bd1..d9b9244fc6 100644 --- a/examples/lock-app/silabs/src/EventHandlerLibShell.cpp +++ b/examples/lock-app/silabs/src/EventHandlerLibShell.cpp @@ -99,7 +99,7 @@ CHIP_ERROR AlarmEventHandler(int argc, char ** argv) if (argc >= 2) { ChipLogError(Zcl, "Too many arguments provided to function %s, line %d", __func__, __LINE__); - return APP_ERROR_TOO_MANY_SHELL_ARGUMENTS; + return CHIP_ERROR_INVALID_ARGUMENT; } AlarmEventData * data = Platform::New(); @@ -131,7 +131,7 @@ CHIP_ERROR DoorStateEventHandler(int argc, char ** argv) if (argc >= 2) { ChipLogError(Zcl, "Too many arguments provided to function %s, line %d", __func__, __LINE__); - return APP_ERROR_TOO_MANY_SHELL_ARGUMENTS; + return CHIP_ERROR_INVALID_ARGUMENT; } DoorStateEventData * data = Platform::New(); diff --git a/examples/refrigerator-app/silabs/BUILD.gn b/examples/refrigerator-app/silabs/BUILD.gn index 9e63c6c10e..27c59f70a8 100644 --- a/examples/refrigerator-app/silabs/BUILD.gn +++ b/examples/refrigerator-app/silabs/BUILD.gn @@ -143,6 +143,10 @@ silabs_executable("refrigerator_app") { "src/refrigerator-and-temperature-controlled-cabinet-mode.cpp", ] + if (chip_build_libshell) { + sources += [ "src/EventHandlerLibShell.cpp" ] + } + if (use_temp_sensor) { sources += [ "${efr32_sdk_root}/hardware/driver/si70xx/src/sl_si70xx.c", diff --git a/examples/refrigerator-app/silabs/include/EventHandlerLibShell.h b/examples/refrigerator-app/silabs/include/EventHandlerLibShell.h new file mode 100644 index 0000000000..5997b24d5b --- /dev/null +++ b/examples/refrigerator-app/silabs/include/EventHandlerLibShell.h @@ -0,0 +1,36 @@ +/* + * + * Copyright (c) 2024 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 +#include +#include + +class EventData +{ +public: + chip::EventId eventId; +}; + +class RefrigeratorAlarmEventData : public EventData +{ +public: + chip::app::Clusters::RefrigeratorAlarm::AlarmBitmap doorState; +}; + +CHIP_ERROR RegisterRefrigeratorEvents(); +void EventWorkerFunction(intptr_t context); diff --git a/examples/refrigerator-app/silabs/src/AppTask.cpp b/examples/refrigerator-app/silabs/src/AppTask.cpp index d2def279be..c9dc451b71 100644 --- a/examples/refrigerator-app/silabs/src/AppTask.cpp +++ b/examples/refrigerator-app/silabs/src/AppTask.cpp @@ -24,7 +24,6 @@ #include "AppTask.h" #include "AppConfig.h" #include "AppEvent.h" - #include "LEDWidget.h" #ifdef DISPLAY_ENABLED @@ -35,6 +34,10 @@ #endif // QR_CODE_ENABLED #endif // DISPLAY_ENABLED +#if defined(ENABLE_CHIP_SHELL) +#include "EventHandlerLibShell.h" +#endif // ENABLE_CHIP_SHELL + #include #include #include @@ -94,6 +97,15 @@ CHIP_ERROR AppTask::Init() appError(err); } +#if defined(ENABLE_CHIP_SHELL) + err = RegisterRefrigeratorEvents(); + if (err != CHIP_NO_ERROR) + { + SILABS_LOG("RegisterRefrigeratorEvents() failed"); + appError(err); + } +#endif // ENABLE_CHIP_SHELL + return err; } diff --git a/examples/refrigerator-app/silabs/src/EventHandlerLibShell.cpp b/examples/refrigerator-app/silabs/src/EventHandlerLibShell.cpp new file mode 100644 index 0000000000..212b2ac8d8 --- /dev/null +++ b/examples/refrigerator-app/silabs/src/EventHandlerLibShell.cpp @@ -0,0 +1,178 @@ +/* + * + * Copyright (c) 2024 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 + +constexpr uint8_t kRefEndpointId = 1; + +using namespace chip; +using namespace chip::app; +using namespace Clusters::RefrigeratorAlarm; +using namespace Clusters::TemperatureControl; +using Shell::Engine; +using Shell::shell_command_t; +using Shell::streamer_get; +using Shell::streamer_printf; + +Engine sShellRefrigeratorSubCommands; +Engine sShellRefrigeratorEventSubCommands; +Engine sShellRefrigeratorEventAlarmDoorSubCommands; + +/******************************************************** + * Refrigerator shell functions + *********************************************************/ + +CHIP_ERROR RefrigeratorHelpHandler(int argc, char ** argv) +{ + sShellRefrigeratorSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR RefrigeratorCommandHandler(int argc, char ** argv) +{ + if (argc == 0) + { + return RefrigeratorHelpHandler(argc, argv); + } + + return sShellRefrigeratorSubCommands.ExecCommand(argc, argv); +} + +/******************************************************** + * Event shell functions + *********************************************************/ + +CHIP_ERROR EventHelpHandler(int argc, char ** argv) +{ + sShellRefrigeratorEventSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR EventRefrigeratorCommandHandler(int argc, char ** argv) +{ + if (argc == 0) + { + return EventHelpHandler(argc, argv); + } + + return sShellRefrigeratorEventSubCommands.ExecCommand(argc, argv); +} + +/******************************************************** + * Alarm shell functions + *********************************************************/ + +CHIP_ERROR AlarmHelpHandler(int argc, char ** argv) +{ + sShellRefrigeratorEventAlarmDoorSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR RefrigeratorDoorEventHandler(int argc, char ** argv) +{ + + if (argc == 0) + { + return AlarmHelpHandler(argc, argv); + } + if (argc >= 2) + { + ChipLogError(Shell, "Too many arguments"); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + // Check if the argument is a valid integer + if (argv[0] == nullptr || !std::all_of(argv[0], argv[0] + strlen(argv[0]), ::isdigit)) + { + ChipLogError(Shell, "Invalid argument: Input must be a valid integer."); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + // Convert the argument to an integer + int value = std::stoi(argv[0]); // Safe to use now, as we validated the input earlier + + RefrigeratorAlarmEventData * data = Platform::New(); + data->eventId = Events::Notify::Id; + data->doorState = static_cast(value); + + DeviceLayer::PlatformMgr().ScheduleWork(EventWorkerFunction, reinterpret_cast(data)); + + return CHIP_NO_ERROR; +} + +/** + * @brief configures Refrigerator matter shell + * + */ + +CHIP_ERROR RegisterRefrigeratorEvents() +{ + static const shell_command_t sRefrigeratorSubCommands[] = { + { &RefrigeratorHelpHandler, "help", "Usage: refrigeratoralarm " }, + { &EventRefrigeratorCommandHandler, "event", " Usage: refrigeratoralarm event " } + }; + + static const shell_command_t sRefrigeratorEventSubCommands[] = { + { &EventHelpHandler, "help", "Usage : refrigeratoralarm event " }, + { &RefrigeratorDoorEventHandler, "door-state-change", "Sends door state change event to Refrigerator app" } + }; + + static const shell_command_t sRefrigeratorEventAlarmDoorSubCommands[] = { + { &AlarmHelpHandler, "help", "Usage : Refrigerator event to change door state" } + }; + + static const shell_command_t sRefrigeratorCommand = { &RefrigeratorCommandHandler, "refrigeratoralarm", + "refrigerator alarm commands. Usage: refrigeratoralarm " }; + + sShellRefrigeratorEventAlarmDoorSubCommands.RegisterCommands(sRefrigeratorEventAlarmDoorSubCommands, + ArraySize(sRefrigeratorEventAlarmDoorSubCommands)); + sShellRefrigeratorEventSubCommands.RegisterCommands(sRefrigeratorEventSubCommands, ArraySize(sRefrigeratorEventSubCommands)); + sShellRefrigeratorSubCommands.RegisterCommands(sRefrigeratorSubCommands, ArraySize(sRefrigeratorSubCommands)); + + Engine::Root().RegisterCommands(&sRefrigeratorCommand, 1); + + return CHIP_NO_ERROR; +} + +void EventWorkerFunction(intptr_t context) +{ + VerifyOrReturn(reinterpret_cast(context) != nullptr, ChipLogError(Shell, "EventWorkerFunction - Invalid work data")); + EventData * data = reinterpret_cast(context); + + switch (data->eventId) + { + case Events::Notify::Id: { + RefrigeratorAlarmEventData * alarmData = reinterpret_cast(context); + RefrigeratorAlarmServer::Instance().SetStateValue(kRefEndpointId, alarmData->doorState); + break; + } + + default: { + ChipLogError(Zcl, "Invalid Event Id %s, line %d", __func__, __LINE__); + break; + } + } + // Free memory + Platform::Delete(data); +}