/* * * Copyright (c) 2022 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 #include #include #include #include #include #include #include #include #include #include #if CONFIG_DEVICE_LAYER #include #endif namespace chip { namespace Shell { class OnOffCommands { public: // delete the copy constructor OnOffCommands(const OnOffCommands &) = delete; // delete the move constructor OnOffCommands(OnOffCommands &&) = delete; // delete the assignment operator OnOffCommands & operator=(const OnOffCommands &) = delete; static OnOffCommands & GetInstance() { static OnOffCommands instance; return instance; } // Register the OnOff commands void Register(); private: OnOffCommands() {} static CHIP_ERROR OnOffHandler(int argc, char ** argv) { if (argc == 0) { sSubShell.ForEachCommand(PrintCommandHelp, nullptr); return CHIP_NO_ERROR; } CHIP_ERROR error = sSubShell.ExecCommand(argc, argv); if (error != CHIP_NO_ERROR) { streamer_printf(streamer_get(), "Error: %" CHIP_ERROR_FORMAT "\r\n", error.Format()); } return error; } static CHIP_ERROR OnLightHandler(int argc, char ** argv) { if (argc != 1) return CHIP_ERROR_INVALID_ARGUMENT; chip::app::Clusters::OnOff::Attributes::OnOff::Set(atoi(argv[0]), 1); return CHIP_NO_ERROR; } static CHIP_ERROR OffLightHandler(int argc, char ** argv) { if (argc != 1) return CHIP_ERROR_INVALID_ARGUMENT; chip::app::Clusters::OnOff::Attributes::OnOff::Set(atoi(argv[0]), 0); return CHIP_NO_ERROR; } static CHIP_ERROR ToggleLightHandler(int argc, char ** argv) { if (argc != 1) return CHIP_ERROR_INVALID_ARGUMENT; bool value; chip::app::Clusters::OnOff::Attributes::OnOff::Get(atoi(argv[0]), &value); chip::app::Clusters::OnOff::Attributes::OnOff::Set(atoi(argv[0]), !value); return CHIP_NO_ERROR; } static Shell::Engine sSubShell; }; class CASECommands { public: // delete the copy constructor CASECommands(const CASECommands &) = delete; // delete the move constructor CASECommands(CASECommands &&) = delete; // delete the assignment operator CASECommands & operator=(const CASECommands &) = delete; static CASECommands & GetInstance() { static CASECommands instance; return instance; } // Register the CASESession commands void Register(); void SetFabricInfo(const FabricInfo * fabricInfo) { mFabricInfo = fabricInfo; } void SetNodeId(NodeId nodeId) { mNodeId = nodeId; } void SetOnConnecting(bool onConnecting) { mOnConnecting = onConnecting; } const FabricInfo * GetFabricInfo(void) { return mFabricInfo; } NodeId GetNodeId(void) { return mNodeId; } bool GetOnConnecting(void) { return mOnConnecting; } private: CASECommands() {} static void OnConnected(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) { streamer_printf(streamer_get(), "Establish CASESession Success!\r\n"); GetInstance().SetOnConnecting(false); } static void OnConnectionFailure(void * context, const ScopedNodeId & peerId, CHIP_ERROR error) { streamer_printf(streamer_get(), "Establish CASESession Failure!\r\n"); GetInstance().SetOnConnecting(false); } static void ConnectToNode(intptr_t arg) { CASECommands * caseCommand = reinterpret_cast(arg); Server * server = &(chip::Server::GetInstance()); CASESessionManager * caseSessionManager = server->GetCASESessionManager(); if (caseSessionManager == nullptr) { ChipLogError(SecureChannel, "Can't get the CASESessionManager"); return; } caseSessionManager->FindOrEstablishSession( ScopedNodeId(caseCommand->GetNodeId(), caseCommand->GetFabricInfo()->GetFabricIndex()), &sOnConnectedCallback, &sOnConnectionFailureCallback); } static CHIP_ERROR ConnectToNodeHandler(int argc, char ** argv) { if (GetInstance().GetOnConnecting()) { return CHIP_ERROR_INCORRECT_STATE; } const FabricIndex fabricIndex = static_cast(strtoul(argv[0], nullptr, 10)); const FabricInfo * fabricInfo = Server::GetInstance().GetFabricTable().FindFabricWithIndex(fabricIndex); if (fabricInfo == nullptr) { streamer_printf(streamer_get(), "Can't get fabric information from FabricIndex\r\n"); return CHIP_ERROR_NOT_FOUND; } GetInstance().SetFabricInfo(fabricInfo); GetInstance().SetNodeId(static_cast(strtoul(argv[1], nullptr, 10))); streamer_printf(streamer_get(), "Try to establish CaseSession to NodeId:0x" ChipLogFormatX64 " on fabric index %d\r\n", ChipLogValueX64(GetInstance().GetNodeId()), fabricIndex); GetInstance().SetOnConnecting(true); chip::DeviceLayer::PlatformMgr().ScheduleWork(ConnectToNode, reinterpret_cast(&GetInstance())); return CHIP_NO_ERROR; } static CHIP_ERROR CASEHandler(int argc, char ** argv) { if (argc == 0) { sSubShell.ForEachCommand(PrintCommandHelp, nullptr); return CHIP_NO_ERROR; } CHIP_ERROR err = sSubShell.ExecCommand(argc, argv); if (err != CHIP_NO_ERROR) { streamer_printf(streamer_get(), "Error: %" CHIP_ERROR_FORMAT "\r\n", err.Format()); } return err; } static Callback::Callback sOnConnectedCallback; static Callback::Callback sOnConnectionFailureCallback; static Shell::Engine sSubShell; const FabricInfo * mFabricInfo = nullptr; NodeId mNodeId = 0; bool mOnConnecting = false; }; } // namespace Shell } // namespace chip