Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / protocols / echo / EchoClient.cpp
1 /*
2  *
3  *    Copyright (c) 2020 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 implements an object for a CHIP Echo unsolicitied
22  *      initiator (client).
23  *
24  */
25
26 #include "Echo.h"
27
28 namespace chip {
29 namespace Protocols {
30 namespace Echo {
31
32 CHIP_ERROR EchoClient::Init(Messaging::ExchangeManager * exchangeMgr, SecureSessionHandle session)
33 {
34     // Error if already initialized.
35     if (mExchangeMgr != nullptr)
36         return CHIP_ERROR_INCORRECT_STATE;
37
38     mExchangeMgr           = exchangeMgr;
39     mSecureSession         = session;
40     OnEchoResponseReceived = nullptr;
41     mExchangeCtx           = nullptr;
42
43     return CHIP_NO_ERROR;
44 }
45
46 void EchoClient::Shutdown()
47 {
48     if (mExchangeCtx != nullptr)
49     {
50         mExchangeCtx->Abort();
51         mExchangeCtx = nullptr;
52     }
53
54     OnEchoResponseReceived = nullptr;
55     mExchangeMgr           = nullptr;
56 }
57
58 CHIP_ERROR EchoClient::SendEchoRequest(System::PacketBufferHandle && payload, const Messaging::SendFlags & sendFlags)
59 {
60     CHIP_ERROR err = CHIP_NO_ERROR;
61
62     // Discard any existing exchange context. Effectively we can only have one Echo exchange with
63     // a single node at any one time.
64     if (mExchangeCtx != nullptr)
65     {
66         mExchangeCtx->Abort();
67         mExchangeCtx = nullptr;
68     }
69
70     // Create a new exchange context.
71     mExchangeCtx = mExchangeMgr->NewContext(mSecureSession, this);
72     if (mExchangeCtx == nullptr)
73     {
74         return CHIP_ERROR_NO_MEMORY;
75     }
76
77     // Send an Echo Request message.  Discard the exchange context if the send fails.
78     err = mExchangeCtx->SendMessage(MsgType::EchoRequest, std::move(payload), sendFlags);
79
80     if (err != CHIP_NO_ERROR)
81     {
82         mExchangeCtx->Abort();
83         mExchangeCtx = nullptr;
84     }
85
86     return err;
87 }
88
89 void EchoClient::OnMessageReceived(Messaging::ExchangeContext * ec, const PacketHeader & packetHeader,
90                                    const PayloadHeader & payloadHeader, System::PacketBufferHandle payload)
91 {
92     // Assert that the exchange context matches the client's current context.
93     // This should never fail because even if SendEchoRequest is called
94     // back-to-back, the second call will call Close() on the first exchange,
95     // which clears the OnMessageReceived callback.
96     VerifyOrDie(ec == mExchangeCtx);
97
98     // Verify that the message is an Echo Response.
99     // If not, close the exchange and free the payload.
100     if (!payloadHeader.HasMessageType(MsgType::EchoResponse))
101     {
102         ec->Close();
103         mExchangeCtx = nullptr;
104         return;
105     }
106
107     // Remove the EC from the app state now. OnEchoResponseReceived can call
108     // SendEchoRequest and install a new one. We abort rather than close
109     // because we no longer care whether the echo request message has been
110     // acknowledged at the transport layer.
111     mExchangeCtx->Abort();
112     mExchangeCtx = nullptr;
113
114     // Call the registered OnEchoResponseReceived handler, if any.
115     if (OnEchoResponseReceived != nullptr)
116     {
117         OnEchoResponseReceived(ec, std::move(payload));
118     }
119 }
120
121 void EchoClient::OnResponseTimeout(Messaging::ExchangeContext * ec)
122 {
123     ChipLogProgress(Echo, "Time out! failed to receive echo response from Exchange: %p", ec);
124 }
125
126 } // namespace Echo
127 } // namespace Protocols
128 } // namespace chip