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 : #pragma once
19 :
20 : #include <app/InteractionModelDelegatePointers.h>
21 : #include <messaging/ExchangeContext.h>
22 : #include <messaging/ExchangeDelegate.h>
23 : #include <system/SystemClock.h>
24 : #include <system/SystemLayer.h>
25 : #include <system/SystemPacketBuffer.h>
26 : #include <transport/raw/MessageHeader.h>
27 :
28 : namespace chip {
29 : namespace app {
30 :
31 : class TimedHandler;
32 :
33 : /**
34 : * A TimedHandler handles a Timed Request action and then waits for a
35 : * subsequent Invoke or Write action and hands those on to
36 : * InteractionModelEngine if they arrive soon enough.
37 : *
38 : * Lifetime handling:
39 : *
40 : * A TimedHandler is initially allocated when the Timed Request is received and
41 : * becomes the delegate for that exchange. After that it remains alive until
42 : * either the exchange is closed or the interaction is handed on to the
43 : * InteractionModelEngine.
44 : */
45 : class TimedHandlerDelegate
46 : {
47 : public:
48 60 : virtual ~TimedHandlerDelegate() = default;
49 :
50 : /**
51 : * Called when a timed invoke is received. This function takes over all
52 : * handling of the exchange, status reporting, and so forth.
53 : */
54 : virtual void OnTimedInvoke(TimedHandler * apTimedHandler, Messaging::ExchangeContext * apExchangeContext,
55 : const PayloadHeader & aPayloadHeader, System::PacketBufferHandle && aPayload) = 0;
56 :
57 : /**
58 : * Called when a timed write is received. This function takes over all
59 : * handling of the exchange, status reporting, and so forth.
60 : */
61 : virtual void OnTimedWrite(TimedHandler * apTimedHandler, Messaging::ExchangeContext * apExchangeContext,
62 : const PayloadHeader & aPayloadHeader, System::PacketBufferHandle && aPayload) = 0;
63 :
64 : /**
65 : * Called when a timed interaction has failed (i.e. the exchange it was
66 : * happening on has closed while the exchange delegate was the timed
67 : * handler).
68 : */
69 : virtual void OnTimedInteractionFailed(TimedHandler * apTimedHandler) = 0;
70 : };
71 :
72 : class TimedHandler : public Messaging::ExchangeDelegate
73 : {
74 : public:
75 5 : TimedHandler(TimedHandlerDelegate * delegate) : mDelegate(delegate) {}
76 5 : ~TimedHandler() override {}
77 :
78 : // ExchangeDelegate implementation.
79 : CHIP_ERROR OnMessageReceived(Messaging::ExchangeContext * aExchangeContext, const PayloadHeader & aPayloadHeader,
80 : System::PacketBufferHandle && aPayload) override;
81 :
82 : private:
83 : // ExchangeDelegate implementation.
84 0 : void OnResponseTimeout(Messaging::ExchangeContext *) override
85 : { /* We just want to allow the exchange to close */
86 0 : }
87 : void OnExchangeClosing(Messaging::ExchangeContext * aExchangeContext) override;
88 :
89 : void CancelTimer();
90 :
91 : /**
92 : * Handler for the Timed Request action. This returns success if the Timed
93 : * Request action is parsed successfully and the success Status Response
94 : * action is sent, failure otherwise.
95 : */
96 : CHIP_ERROR HandleTimedRequestAction(Messaging::ExchangeContext * aExchangeContext, const PayloadHeader & aPayloadHeader,
97 : System::PacketBufferHandle && aPayload);
98 :
99 : enum class State : uint8_t
100 : {
101 : kExpectingTimedAction, // Initial state: expecting a timed action.
102 : kReceivedTimedAction, // Have received the timed action. This can
103 : // be a terminal state if the action ends up
104 : // malformed.
105 : kExpectingFollowingAction, // Expecting write or invoke.
106 : };
107 :
108 : State mState = State::kExpectingTimedAction;
109 :
110 : /// This may be "fake" pointer or a real delegate pointer, depending
111 : /// on CHIP_CONFIG_STATIC_GLOBAL_INTERACTION_MODEL_ENGINE setting.
112 : ///
113 : /// When this is not a real pointer, it checks that the value is always
114 : /// set to the global InteractionModelEngine and the size of this
115 : /// member is 1 byte.
116 : InteractionModelDelegatePointer<TimedHandlerDelegate> mDelegate;
117 :
118 : // We keep track of the time limit for message reception, in case our
119 : // exchange's "response expected" timer gets delayed and does not fire when
120 : // the time runs out.
121 : //
122 : // NOTE: mTimeLimit needs to be 8-byte aligned on ARM so we place this last,
123 : // to allow previous values to potentially use remaining packing space.
124 : // Rationale:
125 : // - vtable is 4-byte aligned on 32-bit arm
126 : // - mTimeLimit requires 8-byte aligment
127 : // => As a result we may gain 4 bytes if we place mTimeLimit last.
128 : // Expectation of memory layout:
129 : // - vtable pointer (4 bytes & 4 byte alignment)
130 : // - other members (2 bytes on embedded "global pointer" arm)
131 : // (2 bytes padding for 8-byte alignment)
132 : // - mTimeLimit (8 bytes & 8 byte alignment)
133 : System::Clock::Timestamp mTimeLimit;
134 : };
135 :
136 : } // namespace app
137 : } // namespace chip
|