Line data Source code
1 : /* 2 : * 3 : * Copyright (c) 2020 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 Delegate. 21 : * 22 : */ 23 : 24 : #pragma once 25 : 26 : #include <lib/support/CHIPMem.h> 27 : #include <messaging/ApplicationExchangeDispatch.h> 28 : #include <messaging/ExchangeMessageDispatch.h> 29 : #include <system/SystemPacketBuffer.h> 30 : #include <transport/SessionManager.h> 31 : #include <transport/raw/MessageHeader.h> 32 : 33 : namespace chip { 34 : namespace Messaging { 35 : 36 : class ExchangeContext; 37 : 38 : /** 39 : * @brief 40 : * This class provides a skeleton for the callback functions. The functions will be 41 : * called by ExchangeContext object on specific events. If the user of ExchangeContext 42 : * is interested in receiving these callbacks, they can specialize this class and handle 43 : * each trigger in their implementation of this class. 44 : * 45 : * For consumers who use an ExchangeContext to send/receive protocol messages, there are specific 46 : * expectations around who manages the exchange w.r.t clean-up and destruction: 47 : * 1. When you allocate an exchange, you own the exchange. Until you send a message successfully, it's on you 48 : * to release that ownership by calling Close or Abort on the exchange. 49 : * 50 : * 2. If you send a message successfully that doesn't require a response, the ownership transfers to 51 : * the ExchangeMgr, and it will close the exchange for you automatically. 52 : * 53 : * 3. If you send a message successfully that does require a response and desire to close it before 54 : * you get any notifications on that exchange from the ExchangeMgr, you should call Close or Abort on that exchange. 55 : * 56 : * 4. On reception of a message on an exchange, the ownership transfers to the OnMessageReceived callee. 57 : * If you return from OnMessageReceived and no messages were sent on that exchange, the exchange will transfer back 58 : * to the ExchangeMgr and it will automatically close it. 59 : * 60 : * 5. If you call WillSendMessage on the exchange in OnMessageReceived indicating a desire to send a message later 61 : * on the exchange, then the exchange remains with you, and it's your responsibility to either send a message on it, 62 : * or Close/Abort if you no longer wish to have the exchange around. 63 : * 64 : * 6. If you get a call to OnExchangeClosing, you should null out your reference to the exchange UNLESS you still 65 : * hold ownership of the exchange (i.e due to a prior call to WillSendMessage). In that case, you should call Abort/Close 66 : * whenever you're done with using the exchange. Those calls can be made synchronously within the OnExchangeClosing 67 : * callback. 68 : * 69 : * 7. If you get a call to OnResponseTimeout, you should null out your reference to the exchange since the exchange layer 70 : * owns the exchange and will handle releasing the ref later. A call to OnExchangeClosing will follow after. 71 : * 72 : */ 73 : class DLL_EXPORT ExchangeDelegate 74 : { 75 : public: 76 9 : virtual ~ExchangeDelegate() {} 77 : 78 : /** 79 : * @brief 80 : * This function is the protocol callback for handling a received CHIP 81 : * message. 82 : * 83 : * After calling this method an exchange will close itself unless one of 84 : * two things happens: 85 : * 86 : * 1) A call to SendMessage on the exchange with the kExpectResponse flag 87 : * set. 88 : * 2) A call to WillSendMessage on the exchange. 89 : * 90 : * Consumers that don't do one of those things MUST NOT retain a pointer 91 : * to the exchange. 92 : * 93 : * @param[in] ec A pointer to the ExchangeContext object. 94 : * @param[in] payloadHeader A reference to the PayloadHeader object. 95 : * @param[in] payload A handle to the PacketBuffer object holding the message payload. 96 : */ 97 : virtual CHIP_ERROR OnMessageReceived(ExchangeContext * ec, const PayloadHeader & payloadHeader, 98 : System::PacketBufferHandle && payload) = 0; 99 : 100 : /** 101 : * @brief 102 : * This function is the protocol callback to invoke when the timeout for the receipt 103 : * of a response message has expired. 104 : * 105 : * After calling this method an exchange will close itself unless one of 106 : * two things happens: 107 : * 108 : * 1) A call to SendMessage on the exchange with the kExpectResponse flag 109 : * set. 110 : * 2) A call to WillSendMessage on the exchange. 111 : * 112 : * Consumers that don't do one of those things MUST NOT retain a pointer 113 : * to the exchange. 114 : * 115 : * @param[in] ec A pointer to the ExchangeContext object. 116 : */ 117 : virtual void OnResponseTimeout(ExchangeContext * ec) = 0; 118 : 119 : /** 120 : * @brief 121 : * This function is the protocol callback to invoke when the associated 122 : * exchange context is being closed. 123 : * 124 : * If the exchange was in a state where it was expecting a message to be 125 : * sent due to an earlier WillSendMessage call or because the exchange has 126 : * just been created as an initiator, the consumer is holding a reference 127 : * to the exchange and it's the consumer's responsibility to call 128 : * Release() on the exchange at some point. The usual way this happens is 129 : * that the consumer tries to send its message, that fails, and the 130 : * consumer calls Close() on the exchange. Calling Close() after an 131 : * OnExchangeClosing() notification is allowed in this situation. 132 : * 133 : * @param[in] ec A pointer to the ExchangeContext object. 134 : */ 135 0 : virtual void OnExchangeClosing(ExchangeContext * ec) {} 136 : 137 0 : virtual ExchangeMessageDispatch & GetMessageDispatch() { return ApplicationExchangeDispatch::Instance(); } 138 : }; 139 : 140 : /** 141 : * @brief 142 : * This class handles unsolicited messages. The implementation can select an exchange delegate to use based on the payload header 143 : * of the incoming message. 144 : */ 145 : class DLL_EXPORT UnsolicitedMessageHandler 146 : { 147 : public: 148 1 : virtual ~UnsolicitedMessageHandler() {} 149 : 150 : /** 151 : * @brief 152 : * This function handles an unsolicited CHIP message. 153 : * 154 : * If the implementation returns CHIP_NO_ERROR, it is expected to set newDelegate to the delegate to use for the exchange 155 : * handling the message. The message layer will handle creating the exchange with this delegate. 156 : * 157 : * If the implementation returns an error, message processing will be aborted for this message. 158 : * 159 : * @param[in] payloadHeader A reference to the PayloadHeader object for the unsolicited message. The protocol and message 160 : * type of this header match the UnsolicitedMessageHandler. 161 : * @param[out] newDelegate A new exchange delegate to be used by the new exchange created to handle the message. 162 : */ 163 : virtual CHIP_ERROR OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, ExchangeDelegate *& newDelegate) = 0; 164 : 165 : /** 166 : * @brief 167 : * This function is called when OnUnsolicitedMessageReceived successfully returns a new delegate, but the session manager 168 : * fails to assign the delegate to a new exchange. It can be used to free the delegate as needed. 169 : * 170 : * Once an exchange is created with the delegate, the OnExchangeClosing notification can be used to free the delegate as 171 : * needed. 172 : * 173 : * @param[in] delegate The exchange delegate to be released. 174 : */ 175 0 : virtual void OnExchangeCreationFailed(ExchangeDelegate * delegate) {} 176 : }; 177 : 178 : } // namespace Messaging 179 : } // namespace chip