Line data Source code
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 unsolicited
22 : * initiator (client).
23 : *
24 : */
25 :
26 : #include "Echo.h"
27 :
28 : namespace chip {
29 : namespace Protocols {
30 : namespace Echo {
31 :
32 : // The Echo message timeout value in milliseconds.
33 : constexpr System::Clock::Timeout kEchoMessageTimeout = System::Clock::Milliseconds32(800);
34 :
35 0 : CHIP_ERROR EchoClient::Init(Messaging::ExchangeManager * exchangeMgr, const SessionHandle & session)
36 : {
37 : // Error if already initialized.
38 0 : if (mExchangeMgr != nullptr)
39 0 : return CHIP_ERROR_INCORRECT_STATE;
40 :
41 0 : mExchangeMgr = exchangeMgr;
42 0 : mSecureSession.Grab(session);
43 0 : OnEchoResponseReceived = nullptr;
44 0 : mExchangeCtx = nullptr;
45 :
46 0 : return CHIP_NO_ERROR;
47 : }
48 :
49 0 : void EchoClient::Shutdown()
50 : {
51 0 : if (mExchangeCtx != nullptr)
52 : {
53 0 : mExchangeCtx->Abort();
54 0 : mExchangeCtx = nullptr;
55 : }
56 :
57 0 : OnEchoResponseReceived = nullptr;
58 0 : mExchangeMgr = nullptr;
59 0 : }
60 :
61 0 : CHIP_ERROR EchoClient::SendEchoRequest(System::PacketBufferHandle && payload, Messaging::SendFlags sendFlags)
62 : {
63 0 : CHIP_ERROR err = CHIP_NO_ERROR;
64 :
65 : // Discard any existing exchange context. Effectively we can only have one Echo exchange with
66 : // a single node at any one time.
67 0 : if (mExchangeCtx != nullptr)
68 : {
69 0 : mExchangeCtx->Abort();
70 0 : mExchangeCtx = nullptr;
71 : }
72 :
73 0 : VerifyOrReturnError(mSecureSession, CHIP_ERROR_INVALID_MESSAGE_TYPE);
74 :
75 : // Create a new exchange context.
76 0 : mExchangeCtx = mExchangeMgr->NewContext(mSecureSession.Get().Value(), this);
77 0 : if (mExchangeCtx == nullptr)
78 : {
79 0 : return CHIP_ERROR_NO_MEMORY;
80 : }
81 :
82 0 : mExchangeCtx->SetResponseTimeout(kEchoMessageTimeout);
83 :
84 : // Send an Echo Request message. Discard the exchange context if the send fails.
85 0 : err = mExchangeCtx->SendMessage(MsgType::EchoRequest, std::move(payload),
86 0 : sendFlags.Set(Messaging::SendMessageFlags::kExpectResponse));
87 :
88 0 : if (err != CHIP_NO_ERROR)
89 : {
90 0 : mExchangeCtx->Abort();
91 0 : mExchangeCtx = nullptr;
92 : }
93 :
94 0 : return err;
95 : }
96 :
97 0 : CHIP_ERROR EchoClient::OnMessageReceived(Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader,
98 : System::PacketBufferHandle && payload)
99 : {
100 : // Assert that the exchange context matches the client's current context.
101 : // This should never fail because even if SendEchoRequest is called
102 : // back-to-back, the second call will call Close() on the first exchange,
103 : // which clears the OnMessageReceived callback.
104 0 : VerifyOrDie(ec == mExchangeCtx);
105 :
106 0 : mExchangeCtx = nullptr;
107 :
108 : // Verify that the message is an Echo Response.
109 0 : if (!payloadHeader.HasMessageType(MsgType::EchoResponse))
110 : {
111 0 : return CHIP_ERROR_INVALID_ARGUMENT;
112 : }
113 :
114 : // Call the registered OnEchoResponseReceived handler, if any.
115 0 : if (OnEchoResponseReceived != nullptr)
116 : {
117 0 : OnEchoResponseReceived(ec, std::move(payload));
118 : }
119 0 : return CHIP_NO_ERROR;
120 : }
121 :
122 0 : void EchoClient::OnResponseTimeout(Messaging::ExchangeContext * ec)
123 : {
124 0 : mExchangeCtx = nullptr;
125 0 : ChipLogProgress(Echo, "Time out! failed to receive echo response from Exchange: %p", ec);
126 0 : }
127 :
128 : } // namespace Echo
129 : } // namespace Protocols
130 : } // namespace chip
|