Apply Upstream code (2021-03-15)
[platform/upstream/connectedhomeip.git] / src / app / Command.h
1 /*
2  *
3  *    Copyright (c) 2020-2021 Project CHIP Authors
4  *    All rights reserved.
5  *
6  *    Licensed under the Apache License, Version 2.0 (the "License");
7  *    you may not use this file except in compliance with the License.
8  *    You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *    Unless required by applicable law or agreed to in writing, software
13  *    distributed under the License is distributed on an "AS IS" BASIS,
14  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *    See the License for the specific language governing permissions and
16  *    limitations under the License.
17  */
18
19 /**
20  *    @file
21  *      This file defines Base class for a CHIP IM Command
22  *
23  */
24
25 #pragma once
26
27 #include <core/CHIPCore.h>
28 #include <messaging/ExchangeContext.h>
29 #include <messaging/ExchangeMgr.h>
30 #include <messaging/Flags.h>
31 #include <protocols/Protocols.h>
32 #include <support/BitFlags.h>
33 #include <support/CodeUtils.h>
34 #include <support/DLLUtil.h>
35 #include <support/logging/CHIPLogging.h>
36 #include <system/SystemPacketBuffer.h>
37 #include <system/TLVPacketBufferBackingStore.h>
38
39 #include <app/MessageDef/CommandDataElement.h>
40 #include <app/MessageDef/CommandList.h>
41 #include <app/MessageDef/InvokeCommand.h>
42
43 namespace chip {
44 namespace app {
45
46 class Command
47 {
48 public:
49     enum class CommandRoleId
50     {
51         SenderId  = 0,
52         HandlerId = 1,
53     };
54
55     enum class CommandState
56     {
57         Uninitialized = 0, //< The invoke command message has not been initialized
58         Initialized,       //< The invoke command message has been initialized and is ready
59         AddCommand,        //< The invoke command message has added Command
60         Sending,           //< The invoke command message  has sent out the invoke command
61     };
62
63     enum class CommandPathFlags : uint8_t
64     {
65         kEndpointIdValid = 0x01, /**< Set when the EndpointId field is valid */
66         kGroupIdValid    = 0x02, /**< Set when the GroupId field is valid */
67     };
68
69     /**
70      * Encapsulates arguments to be passed into SendCommand().
71      *
72      */
73     struct CommandParams
74     {
75         CommandParams(chip::EndpointId endpointId, chip::GroupId groupId, chip::ClusterId clusterId, chip::CommandId commandId,
76                       const BitFlags<CommandPathFlags> & flags) :
77             EndpointId(endpointId),
78             GroupId(groupId), ClusterId(clusterId), CommandId(commandId), Flags(flags)
79         {}
80
81         chip::EndpointId EndpointId;
82         chip::GroupId GroupId;
83         chip::ClusterId ClusterId;
84         chip::CommandId CommandId;
85         BitFlags<CommandPathFlags> Flags;
86     };
87
88     /**
89      *  Initialize the Command object. Within the lifetime
90      *  of this instance, this method is invoked once after object
91      *  construction until a call to Shutdown is made to terminate the
92      *  instance.
93      *
94      *  @param[in]    apExchangeMgr    A pointer to the ExchangeManager object.
95      *
96      *  @retval #CHIP_ERROR_INCORRECT_STATE If the state is not equal to
97      *          CommandState::NotInitialized.
98      *  @retval #CHIP_NO_ERROR On success.
99      *
100      */
101     CHIP_ERROR Init(Messaging::ExchangeManager * apExchangeMgr);
102
103     /**
104      *  Shutdown the CommandSender. This terminates this instance
105      *  of the object and releases all held resources.
106      *
107      */
108     void Shutdown();
109
110     /**
111      * Finalize Command Message TLV Builder and finalize command message
112      *
113      * @return CHIP_ERROR
114      *
115      */
116     CHIP_ERROR FinalizeCommandsMessage();
117
118     chip::TLV::TLVWriter & CreateCommandDataElementTLVWriter();
119     CHIP_ERROR AddCommand(chip::EndpointId aEndpintId, chip::GroupId aGroupId, chip::ClusterId aClusterId,
120                           chip::CommandId aCommandId, BitFlags<CommandPathFlags> Flags);
121     CHIP_ERROR AddCommand(CommandParams & aCommandParams);
122     CHIP_ERROR AddStatusCode(const uint16_t aGeneralCode, const uint32_t aProtocolId, const uint16_t aProtocolCode,
123                              const chip::ClusterId aClusterId);
124
125     /**
126      * Gets the inner exchange context object, without ownership.
127      *
128      * @return The inner exchange context, might be nullptr if no
129      *         exchange context has been assigned or the context
130      *         has been released.
131      */
132     const Messaging::ExchangeContext * GetExchangeContext() const { return mpExchangeCtx; }
133
134     CHIP_ERROR Reset();
135
136     virtual ~Command() = default;
137
138     bool IsFree() const { return (nullptr == mpExchangeCtx); };
139     virtual CHIP_ERROR ProcessCommandDataElement(CommandDataElement::Parser & aCommandElement) = 0;
140
141 protected:
142     CHIP_ERROR ClearExistingExchangeContext();
143     void MoveToState(const CommandState aTargetState);
144     CHIP_ERROR ProcessCommandMessage(System::PacketBufferHandle && payload, CommandRoleId aCommandRoleId);
145     void ClearState();
146     const char * GetStateStr() const;
147
148     Messaging::ExchangeManager * mpExchangeMgr = nullptr;
149     Messaging::ExchangeContext * mpExchangeCtx = nullptr;
150     chip::System::PacketBufferHandle mCommandMessageBuf;
151
152 private:
153     chip::System::PacketBufferHandle mpBufHandle;
154     InvokeCommand::Builder mInvokeCommandBuilder;
155     CommandState mState;
156
157     chip::System::PacketBufferHandle mCommandDataBuf;
158     chip::System::PacketBufferTLVWriter mCommandMessageWriter;
159     chip::System::PacketBufferTLVWriter mCommandDataWriter;
160 };
161 } // namespace app
162 } // namespace chip