Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2025 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 a WiFiPAF connection endpoint abstraction.
21 : *
22 : */
23 :
24 : #pragma once
25 :
26 : #include <cstdint>
27 :
28 : #include <lib/core/CHIPError.h>
29 : #include <lib/support/BitFlags.h>
30 : #include <lib/support/BufferReader.h>
31 : #include <lib/support/DLLUtil.h>
32 : #include <system/SystemLayer.h>
33 : #include <system/SystemPacketBuffer.h>
34 :
35 : #include "WiFiPAFConfig.h"
36 : #include "WiFiPAFRole.h"
37 : #include "WiFiPAFTP.h"
38 :
39 : namespace chip {
40 : namespace WiFiPAF {
41 :
42 : using ::chip::System::PacketBufferHandle;
43 :
44 : enum
45 : {
46 : kWiFiPAFCloseFlag_SuppressCallback = 0x01,
47 : kWiFiPAFCloseFlag_AbortTransmission = 0x02
48 : };
49 :
50 : // Forward declarations
51 : class WiFiPAFLayer;
52 : class WiFiPAFEndPointPool;
53 :
54 : class DLL_EXPORT WiFiPAFEndPoint
55 : {
56 : friend class WiFiPAFLayer;
57 : friend class WiFiPAFEndPointPool;
58 : friend class TestWiFiPAFLayer;
59 :
60 : public:
61 : typedef uint64_t AlignT;
62 :
63 : enum
64 : {
65 : kState_Ready = 0,
66 : kState_Connecting = 1,
67 : kState_Aborting = 2,
68 : kState_Connected = 3,
69 : kState_Closing = 4,
70 : kState_Closed = 5
71 : } mState; // [READ-ONLY] End point connection state. Refers to state of CHIP over
72 : // PAF transport protocol connection.
73 :
74 : typedef void (*OnSubscribeCompleteFunct)(void * appState);
75 : typedef void (*OnSubscribeErrorFunct)(void * appState, CHIP_ERROR err);
76 : OnSubscribeCompleteFunct mOnPafSubscribeComplete;
77 : OnSubscribeErrorFunct mOnPafSubscribeError;
78 : void * mAppState;
79 :
80 : typedef void (*OnMessageReceivedFunct)(WiFiPAFEndPoint * endPoint, PacketBufferHandle && msg);
81 : OnMessageReceivedFunct OnMessageReceived;
82 :
83 : typedef void (*OnConnectionClosedFunct)(WiFiPAFEndPoint * endPoint, CHIP_ERROR err);
84 : OnConnectionClosedFunct OnConnectionClosed;
85 :
86 : CHIP_ERROR Send(PacketBufferHandle && data);
87 : CHIP_ERROR Receive(PacketBufferHandle && data);
88 : CHIP_ERROR StartConnect();
89 58 : WiFiPAFEndPoint() = default;
90 406 : ~WiFiPAFEndPoint() = default;
91 :
92 : private:
93 : CHIP_ERROR RxPacketProcess(PacketBufferHandle && data);
94 : enum class PktDirect_t : uint8_t
95 : {
96 : kTx,
97 : kRx
98 : };
99 : CHIP_ERROR DebugPktAckSn(const PktDirect_t PktDirect, Encoding::LittleEndian::Reader & reader, uint8_t * pHead);
100 : CHIP_ERROR GetPktSn(Encoding::LittleEndian::Reader & reader, uint8_t * pHead, SequenceNumber_t & seqNum);
101 :
102 : WiFiPAFLayer * mWiFiPafLayer; ///< [READ-ONLY] Pointer to the WiFiPAFLayer object that owns this object.
103 : WiFiPAFSession mSessionInfo;
104 : SequenceNumber_t mRxAck;
105 : #define PAFTP_REORDER_QUEUE_SIZE PAF_MAX_RECEIVE_WINDOW_SIZE
106 : PacketBufferHandle ReorderQueue[PAFTP_REORDER_QUEUE_SIZE] = {};
107 : uint8_t ItemsInReorderQueue;
108 :
109 : enum class ConnectionStateFlag : uint8_t
110 : {
111 : kCapabilitiesConfReceived = 0x02, // Ready for sent capabilities req/resp.
112 : kCapabilitiesMsgReceived = 0x04, // Capabilities request or response message received.
113 : kStandAloneAckInFlight = 0x10, // Stand-alone ack in flight.
114 : kOperationInFlight = 0x20 // Operation in flight,
115 : };
116 :
117 : // clang-format off
118 : /*
119 : * +--------------------------------------------------------------------------------+
120 : * | PHASE 1: CONNECTION SETUP SUPERVISION |
121 :
122 : * +--------------------------------------------------------------------------------+
123 : * [Subscriber Role] [Publisher Role]
124 : * HandleTransportConnect() HandleTransportConnectionInitiated()
125 : * --> StartConnect() |
126 : * | |
127 : * v v
128 : * +----------------------+ +-------------------------+
129 : * | kConnectTimerRunning | | kReceiveConnectionTimer-|
130 : * | (15000ms) | | Running (15000ms) |
131 : * +----------------------+ +-------------------------+
132 :
133 : * | | | |
134 : * (Handshake (Timeout) (Handshake (Timeout)
135 : * Complete) | Complete) |
136 : * | v | v
137 : * | [DoClose w/ | [DoClose w/
138 : * | CONNECT_TIMED_OUT] | RECEIVE_TIMED_OUT]
139 : * | |
140 : * +-----------------------+------------------------+
141 : * |
142 : * v
143 : * +--------------------------+
144 : * | kState_Connected |
145 : * +--------------------------+
146 : *
147 : * +--------------------------------------------------------------------------------+
148 : * | PHASE 2: DATA & ACK TRANSMISSION |
149 : * +--------------------------------------------------------------------------------+
150 : *
151 : * [Transmit Payload] [Receive Fragment w/ Ack Req]
152 : * | |
153 : * v v
154 : * +--------------------------+ +--------------------------+
155 : * | kAckReceivedTimerRunning | | kSendAckTimerRunning |
156 : * | (15000ms) | | (200ms) |
157 : * +--------------------------+ +--------------------------+
158 : * | | | |
159 : * (Ack Arrives) (Timeout) (Timeout) (Piggybacked
160 : * | | | on Tx)
161 : * v v v |
162 : * [StopAckTimer] [Resend/Close] [DriveStandAloneAck] v
163 : * [StopSendAckTimer]
164 : */
165 : // clang-format on
166 : enum class TimerStateFlag : uint8_t
167 : {
168 :
169 : kConnectTimerRunning = 0x01, // PAFTP connect completion timer running.
170 : kWaitResTimerRunning = 0x02, // Wait for resource to be available
171 : kAckReceivedTimerRunning = 0x04, // Ack received timer running due to unacked sent fragment.
172 : kSendAckTimerRunning = 0x08, // Send ack timer running; indicates pending ack to send.
173 : kReceiveConnectionTimerRunning = 0x10, // Receive connection timer running.
174 : };
175 :
176 : // Queue of outgoing messages to send when current PAFTPEngine transmission completes.
177 : // Re-used during connection setup to cache capabilities request and response payloads; payloads are freed when
178 : // connection is established.
179 : PacketBufferHandle mSendQueue;
180 :
181 : // Pending stand-alone PAFTP acknowledgement. Pre-empts regular send queue or fragmented message transmission in
182 : // progress.
183 : PacketBufferHandle mAckToSend;
184 :
185 : WiFiPAFTP mPafTP;
186 : WiFiPafRole mRole;
187 : // How many continuing times the resource is unavailable. Will close the session if it's occupied too long
188 : uint8_t mResourceWaitCount = 0;
189 :
190 : BitFlags<ConnectionStateFlag> mConnStateFlags;
191 : BitFlags<TimerStateFlag> mTimerStateFlags;
192 : SequenceNumber_t mLocalReceiveWindowSize;
193 : SequenceNumber_t mRemoteReceiveWindowSize;
194 : SequenceNumber_t mReceiveWindowMaxSize;
195 :
196 : CHIP_ERROR Init(WiFiPAFLayer * WiFiPafLayer, WiFiPAFSession & SessionInfo);
197 : void DoClose(uint8_t flags, CHIP_ERROR err);
198 : bool IsConnected(uint8_t state) const;
199 :
200 : // Transmit path:
201 : CHIP_ERROR DriveSending();
202 : CHIP_ERROR DriveStandAloneAck();
203 : bool PrepareNextFragment(PacketBufferHandle && data, bool & sentAck);
204 : CHIP_ERROR SendNextMessage();
205 : CHIP_ERROR ContinueMessageSend();
206 : CHIP_ERROR DoSendStandAloneAck();
207 : CHIP_ERROR SendCharacteristic(PacketBufferHandle && buf);
208 : CHIP_ERROR SendWrite(PacketBufferHandle && buf);
209 :
210 : // Receive path:
211 : CHIP_ERROR HandleConnectComplete();
212 : CHIP_ERROR HandleSendConfirmationReceived(bool result);
213 : CHIP_ERROR HandleHandshakeConfirmationReceived();
214 : CHIP_ERROR HandleFragmentConfirmationReceived(bool result);
215 : CHIP_ERROR HandleCapabilitiesRequestReceived(PacketBufferHandle && data);
216 : CHIP_ERROR HandleCapabilitiesResponseReceived(PacketBufferHandle && data);
217 : SequenceNumber_t AdjustRemoteReceiveWindow(SequenceNumber_t lastReceivedAck, SequenceNumber_t maxRemoteWindowSize,
218 : SequenceNumber_t newestUnackedSentSeqNum);
219 :
220 : // Timer control functions:
221 : CHIP_ERROR StartConnectTimer(); // Start connect timer.
222 : CHIP_ERROR StartAckReceivedTimer(); // Start ack-received timer if it's not already running.
223 : CHIP_ERROR RestartAckReceivedTimer(); // Restart ack-received timer.
224 : CHIP_ERROR StartSendAckTimer(); // Start send-ack timer if it's not already running.
225 : CHIP_ERROR StartWaitResourceTimer(); // Start wait-resource timer if it's not already running.
226 : CHIP_ERROR StartReceiveConnectionTimer(); // Start receive connection timer.
227 : void StopConnectTimer(); // Stop connect timer.
228 : void StopReceiveConnectionTimer(); // Stop receive connection timer.
229 : void StopAckReceivedTimer(); // Stop ack-received timer.
230 : void StopSendAckTimer(); // Stop send-ack timer.
231 :
232 : void StopWaitResourceTimer(); // Stop wait-resource timer
233 :
234 : // Timer expired callbacks:
235 : static void HandleConnectTimeout(chip::System::Layer * systemLayer, void * appState);
236 : static void HandleReceiveConnectionTimeout(chip::System::Layer * systemLayer, void * appState);
237 : static void HandleAckReceivedTimeout(chip::System::Layer * systemLayer, void * appState);
238 : static void HandleSendAckTimeout(chip::System::Layer * systemLayer, void * appState);
239 :
240 : static void HandleWaitResourceTimeout(chip::System::Layer * systemLayer, void * appState);
241 :
242 : // Close functions:
243 : void DoCloseCallback(uint8_t state, uint8_t flags, CHIP_ERROR err);
244 : void FinalizeClose(uint8_t state, uint8_t flags, CHIP_ERROR err);
245 : void Free();
246 : void FreePAFtpEngine();
247 :
248 : void QueueTx(PacketBufferHandle && data, PacketType_t type);
249 : void ClearAll();
250 : };
251 :
252 : } /* namespace WiFiPAF */
253 : } /* namespace chip */
|