Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / messaging / ExchangeContext.h
1 /*
2  *
3  *    Copyright (c) 2020-2021 Project CHIP Authors
4  *
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *    Unless required by applicable law or agreed to in writing, software
12  *    distributed under the License is distributed on an "AS IS" BASIS,
13  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *    See the License for the specific language governing permissions and
15  *    limitations under the License.
16  */
17
18 /**
19  *    @file
20  *      This file defines the classes corresponding to CHIP Exchange Context.
21  *
22  */
23
24 #pragma once
25
26 #include <lib/core/ReferenceCounted.h>
27 #include <messaging/ExchangeACL.h>
28 #include <messaging/ExchangeDelegate.h>
29 #include <messaging/Flags.h>
30 #include <messaging/ReliableMessageContext.h>
31 #include <protocols/Protocols.h>
32 #include <support/BitFlags.h>
33 #include <support/DLLUtil.h>
34 #include <system/SystemTimer.h>
35 #include <transport/SecureSessionMgr.h>
36
37 namespace chip {
38
39 constexpr uint16_t kMsgCounterChallengeSize = 8; // The size of the message counter synchronization request message.
40
41 namespace Messaging {
42
43 class ExchangeManager;
44 class ExchangeContext;
45
46 class ExchangeContextDeletor
47 {
48 public:
49     static void Release(ExchangeContext * obj);
50 };
51
52 /**
53  *  @brief
54  *    This class represents an ongoing conversation (ExchangeContext) between two or more nodes.
55  *    It defines methods for encoding and communicating CHIP messages within an ExchangeContext
56  *    over various transport mechanisms, for example, TCP, UDP, or CHIP Reliable Messaging.
57  */
58 class DLL_EXPORT ExchangeContext : public ReferenceCounted<ExchangeContext, ExchangeContextDeletor, 0>
59 {
60     friend class ExchangeManager;
61     friend class ExchangeContextDeletor;
62     friend class MessageCounterSyncMgr;
63
64 public:
65     typedef uint32_t Timeout; // Type used to express the timeout in this ExchangeContext, in milliseconds
66
67     /**
68      *  Determine whether the context is the initiator of the exchange.
69      *
70      *  @return Returns 'true' if it is the initiator, else 'false'.
71      */
72     bool IsInitiator() const;
73
74     /**
75      *  Determine whether a response is expected for messages sent over
76      *  this exchange.
77      *
78      *  @return Returns 'true' if response expected, else 'false'.
79      */
80     bool IsResponseExpected() const;
81
82     /**
83      *  Set whether a response is expected on this exchange.
84      *
85      *  @param[in]  inResponseExpected  A Boolean indicating whether (true) or not
86      *                                  (false) a response is expected on this
87      *                                  exchange.
88      */
89     void SetResponseExpected(bool inResponseExpected);
90
91     /**
92      *  Send a CHIP message on this exchange.
93      *
94      *  @param[in]    protocolId    The protocol identifier of the CHIP message to be sent.
95      *
96      *  @param[in]    msgType       The message type of the corresponding protocol.
97      *
98      *  @param[in]    msgPayload    A handle to the packet buffer holding the CHIP message.
99      *
100      *  @param[in]    sendFlags     Flags set by the application for the CHIP message being sent.
101      *
102      *  @retval  #CHIP_ERROR_INVALID_ARGUMENT               if an invalid argument was passed to this SendMessage API.
103      *  @retval  #CHIP_ERROR_WRONG_MSG_VERSION_FOR_EXCHANGE if there is a mismatch in the specific send operation and the
104      *                                                       CHIP message protocol version that is supported.
105      *  @retval  #CHIP_ERROR_NOT_CONNECTED                  if the context was associated with a connection that is now
106      *                                                       closed.
107      *  @retval  #CHIP_ERROR_INCORRECT_STATE                if the state of the exchange context is incorrect.
108      *  @retval  #CHIP_NO_ERROR                             if the CHIP layer successfully sent the message down to the
109      *                                                       network layer.
110      */
111     CHIP_ERROR SendMessage(Protocols::Id protocolId, uint8_t msgType, System::PacketBufferHandle msgPayload,
112                            const SendFlags & sendFlags);
113
114     /**
115      * A strongly-message-typed version of SendMessage.
116      */
117     template <typename MessageType, typename = std::enable_if_t<std::is_enum<MessageType>::value>>
118     CHIP_ERROR SendMessage(MessageType msgType, System::PacketBufferHandle && msgPayload, const SendFlags & sendFlags)
119     {
120         static_assert(std::is_same<std::underlying_type_t<MessageType>, uint8_t>::value, "Enum is wrong size; cast is not safe");
121         return SendMessage(Protocols::MessageTypeTraits<MessageType>::ProtocolId(), static_cast<uint8_t>(msgType),
122                            std::move(msgPayload), sendFlags);
123     }
124
125     /**
126      *  Handle a received CHIP message on this exchange.
127      *
128      *  @param[in]    packetHeader  A reference to the PacketHeader object.
129      *
130      *  @param[in]    payloadHeader A reference to the PayloadHeader object.
131      *
132      *  @param[in]    msgBuf        A handle to the packet buffer holding the CHIP message.
133      *
134      *  @retval  #CHIP_ERROR_INVALID_ARGUMENT               if an invalid argument was passed to this HandleMessage API.
135      *  @retval  #CHIP_ERROR_INCORRECT_STATE                if the state of the exchange context is incorrect.
136      *  @retval  #CHIP_NO_ERROR                             if the CHIP layer successfully delivered the message up to the
137      *                                                       protocol layer.
138      */
139     CHIP_ERROR HandleMessage(const PacketHeader & packetHeader, const PayloadHeader & payloadHeader,
140                              System::PacketBufferHandle msgBuf);
141
142     ExchangeDelegate * GetDelegate() const { return mDelegate; }
143     void SetDelegate(ExchangeDelegate * delegate) { mDelegate = delegate; }
144     void SetReliableMessageDelegate(ReliableMessageDelegate * delegate) { mReliableMessageContext.SetDelegate(delegate); }
145
146     ExchangeManager * GetExchangeMgr() const { return mExchangeMgr; }
147
148     ReliableMessageContext * GetReliableMessageContext() { return &mReliableMessageContext; };
149
150     ExchangeACL * GetExchangeACL(Transport::AdminPairingTable & table)
151     {
152         if (mExchangeACL == nullptr)
153         {
154             Transport::AdminPairingInfo * admin = table.FindAdmin(mSecureSession.GetAdminId());
155             if (admin != nullptr)
156             {
157                 mExchangeACL = chip::Platform::New<CASEExchangeACL>(admin);
158             }
159         }
160
161         return mExchangeACL;
162     }
163
164     SecureSessionHandle GetSecureSession() { return mSecureSession; }
165
166     uint16_t GetExchangeId() const { return mExchangeId; }
167
168     void SetChallenge(const uint8_t * value) { memcpy(&mChallenge[0], value, kMsgCounterChallengeSize); }
169
170     const uint8_t * GetChallenge() const { return mChallenge; }
171
172     SecureSessionHandle GetSecureSessionHandle() const { return mSecureSession; }
173
174     /*
175      * In order to use reference counting (see refCount below) we use a hold/free paradigm where users of the exchange
176      * can hold onto it while it's out of their direct control to make sure it isn't closed before everyone's ready.
177      * A customized version of reference counting is used since there are some extra stuff to do within Release.
178      */
179     void Close();
180     void Abort();
181
182     ExchangeContext * Alloc(ExchangeManager * em, uint16_t ExchangeId, SecureSessionHandle session, bool Initiator,
183                             ExchangeDelegate * delegate);
184     void Free();
185     void Reset();
186
187     void SetResponseTimeout(Timeout timeout);
188
189 private:
190     enum class ExFlagValues : uint16_t
191     {
192         kFlagInitiator        = 0x0001, // This context is the initiator of the exchange.
193         kFlagResponseExpected = 0x0002, // If a response is expected for a message that is being sent.
194     };
195
196     Timeout mResponseTimeout; // Maximum time to wait for response (in milliseconds); 0 disables response timeout.
197     ReliableMessageContext mReliableMessageContext;
198     ExchangeDelegate * mDelegate   = nullptr;
199     ExchangeManager * mExchangeMgr = nullptr;
200     ExchangeACL * mExchangeACL     = nullptr;
201
202     SecureSessionHandle mSecureSession; // The connection state
203     uint16_t mExchangeId;               // Assigned exchange ID.
204
205     // [TODO: #4711]: this field need to be moved to appState object which implement 'exchange-specific' contextual
206     // actions with a delegate pattern.
207     uint8_t mChallenge[kMsgCounterChallengeSize]; // Challenge number to identify the sychronization request cryptographically.
208
209     BitFlags<ExFlagValues> mFlags; // Internal state flags
210
211     /**
212      *  Search for an existing exchange that the message applies to.
213      *
214      *  @param[in]    session       The secure session of the received message.
215      *
216      *  @param[in]    packetHeader  A reference to the PacketHeader object.
217      *
218      *  @param[in]    payloadHeader A reference to the PayloadHeader object.
219      *
220      *  @retval  true                                       If a match is found.
221      *  @retval  false                                      If a match is not found.
222      */
223     bool MatchExchange(SecureSessionHandle session, const PacketHeader & packetHeader, const PayloadHeader & payloadHeader);
224
225     CHIP_ERROR StartResponseTimer();
226
227     /**
228      * A subset of SendMessage functionality that does not perform message
229      * counter sync for group keys.
230      */
231     CHIP_ERROR SendMessageImpl(Protocols::Id protocolId, uint8_t msgType, System::PacketBufferHandle msgBuf,
232                                const SendFlags & sendFlags, Transport::PeerConnectionState * state = nullptr);
233     void CancelResponseTimer();
234     static void HandleResponseTimeout(System::Layer * aSystemLayer, void * aAppState, System::Error aError);
235
236     void DoClose(bool clearRetransTable);
237 };
238
239 inline void ExchangeContextDeletor::Release(ExchangeContext * obj)
240 {
241     obj->Free();
242 }
243
244 } // namespace Messaging
245 } // namespace chip