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 implements objects which provide an abstraction layer between
21 : * a platform's WiFiPAF implementation and the CHIP
22 : * stack.
23 : *
24 : */
25 : #include "WiFiPAFLayer.h"
26 : #include "WiFiPAFConfig.h"
27 : #include "WiFiPAFEndPoint.h"
28 : #include "WiFiPAFError.h"
29 : #include <lib/core/CHIPEncoding.h>
30 :
31 : #undef CHIP_WIFIPAF_LAYER_DEBUG_LOGGING_ENABLED
32 : // Magic values expected in first 2 bytes of valid PAF transport capabilities request or response:
33 : // ref: 4.21.3, PAFTP Control Frames
34 : #define CAPABILITIES_MSG_CHECK_BYTE_1 0b01100101
35 : #define CAPABILITIES_MSG_CHECK_BYTE_2 0b01101100
36 :
37 : namespace chip {
38 : namespace WiFiPAF {
39 :
40 : class WiFiPAFEndPointPool
41 : {
42 : public:
43 : int Size() const { return WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; }
44 :
45 16 : WiFiPAFEndPoint * Get(size_t i) const
46 : {
47 : static union
48 : {
49 : uint8_t Pool[sizeof(WiFiPAFEndPoint) * WIFIPAF_LAYER_NUM_PAF_ENDPOINTS];
50 : WiFiPAFEndPoint::AlignT ForceAlignment;
51 : } sEndPointPool;
52 :
53 16 : if (i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS)
54 : {
55 16 : return reinterpret_cast<WiFiPAFEndPoint *>(sEndPointPool.Pool + (sizeof(WiFiPAFEndPoint) * i));
56 : }
57 :
58 0 : return nullptr;
59 : }
60 :
61 14 : WiFiPAFEndPoint * Find(WIFIPAF_CONNECTION_OBJECT c) const
62 : {
63 14 : if (c == WIFIPAF_CONNECTION_UNINITIALIZED)
64 : {
65 0 : return nullptr;
66 : }
67 :
68 14 : for (size_t i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
69 : {
70 14 : WiFiPAFEndPoint * elem = Get(i);
71 14 : WiFiPAFSession * pInInfo = reinterpret_cast<WiFiPAFSession *>(c);
72 14 : if ((elem->mWiFiPafLayer != nullptr) && (elem->mSessionInfo.id == pInInfo->id) &&
73 14 : (elem->mSessionInfo.peer_id == pInInfo->peer_id) &&
74 14 : !memcmp(elem->mSessionInfo.peer_addr, pInInfo->peer_addr, sizeof(uint8_t) * 6))
75 : {
76 14 : ChipLogProgress(WiFiPAF, "Find: Found WiFiPAFEndPoint[%lu]", i);
77 14 : return elem;
78 : }
79 : #ifdef CHIP_WIFIPAF_LAYER_DEBUG_LOGGING_ENABLED
80 : {
81 : const WiFiPAFSession * pElmInfo = &elem->mSessionInfo;
82 : ChipLogError(WiFiPAF, "EndPoint[%lu]", i);
83 : ChipLogError(WiFiPAF, "Role: [%d, %d]", pElmInfo->role, pInInfo->role);
84 : ChipLogError(WiFiPAF, "id: [%u, %u]", pElmInfo->id, pInInfo->id);
85 : ChipLogError(WiFiPAF, "peer_id: [%d, %d]", pElmInfo->peer_id, pInInfo->peer_id);
86 : ChipLogError(WiFiPAF, "ElmMac: [%02x:%02x:%02x:%02x:%02x:%02x]", pElmInfo->peer_addr[0], pElmInfo->peer_addr[1],
87 : pElmInfo->peer_addr[2], pElmInfo->peer_addr[3], pElmInfo->peer_addr[4], pElmInfo->peer_addr[5]);
88 : ChipLogError(WiFiPAF, "InMac: [%02x:%02x:%02x:%02x:%02x:%02x]", pInInfo->peer_addr[0], pInInfo->peer_addr[1],
89 : pInInfo->peer_addr[2], pInInfo->peer_addr[3], pInInfo->peer_addr[4], pInInfo->peer_addr[5]);
90 : ChipLogError(WiFiPAF, "nodeId: [%lu, %lu]", pElmInfo->nodeId, pInInfo->nodeId);
91 : ChipLogError(WiFiPAF, "discriminator: [%d, %d]", pElmInfo->discriminator, pInInfo->discriminator);
92 : }
93 : #endif
94 : }
95 :
96 0 : return nullptr;
97 : }
98 :
99 2 : WiFiPAFEndPoint * GetFree() const
100 : {
101 2 : for (size_t i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
102 : {
103 2 : WiFiPAFEndPoint * elem = Get(i);
104 2 : if (elem->mWiFiPafLayer == nullptr)
105 : {
106 2 : return elem;
107 : }
108 : }
109 0 : return nullptr;
110 : }
111 : };
112 :
113 : // EndPoint Pools
114 : static WiFiPAFEndPointPool sWiFiPAFEndPointPool;
115 :
116 : /*
117 : * PAFTransportCapabilitiesRequestMessage implementation:
118 : * ref: 4.21.3.1, PAFTP Handshake Request
119 : */
120 2 : void PAFTransportCapabilitiesRequestMessage::SetSupportedProtocolVersion(uint8_t index, uint8_t version)
121 : {
122 : uint8_t mask;
123 :
124 : // If even-index, store version in lower 4 bits; else, higher 4 bits.
125 2 : if (index % 2 == 0)
126 : {
127 2 : mask = 0x0F;
128 : }
129 : else
130 : {
131 0 : mask = 0xF0;
132 0 : version = static_cast<uint8_t>(version << 4);
133 : }
134 :
135 2 : version &= mask;
136 :
137 2 : uint8_t & slot = mSupportedProtocolVersions[(index / 2)];
138 2 : slot = static_cast<uint8_t>(slot & ~mask); // Clear version at index; leave other version in same byte alone
139 2 : slot |= version;
140 2 : }
141 :
142 2 : CHIP_ERROR PAFTransportCapabilitiesRequestMessage::Encode(const PacketBufferHandle & msgBuf) const
143 : {
144 2 : uint8_t * p = msgBuf->Start();
145 :
146 : // Verify we can write the fixed-length request without running into the end of the buffer.
147 2 : VerifyOrReturnError(msgBuf->MaxDataLength() >= kCapabilitiesRequestLength, CHIP_ERROR_NO_MEMORY);
148 :
149 2 : chip::Encoding::Write8(p, CAPABILITIES_MSG_CHECK_BYTE_1);
150 2 : chip::Encoding::Write8(p, CAPABILITIES_MSG_CHECK_BYTE_2);
151 :
152 10 : for (uint8_t version : mSupportedProtocolVersions)
153 : {
154 8 : chip::Encoding::Write8(p, version);
155 : }
156 :
157 2 : chip::Encoding::LittleEndian::Write16(p, mMtu);
158 2 : chip::Encoding::Write8(p, mWindowSize);
159 :
160 2 : msgBuf->SetDataLength(kCapabilitiesRequestLength);
161 :
162 2 : return CHIP_NO_ERROR;
163 : }
164 :
165 2 : CHIP_ERROR PAFTransportCapabilitiesRequestMessage::Decode(const PacketBufferHandle & msgBuf,
166 : PAFTransportCapabilitiesRequestMessage & msg)
167 : {
168 2 : const uint8_t * p = msgBuf->Start();
169 :
170 : // Verify we can read the fixed-length request without running into the end of the buffer.
171 2 : VerifyOrReturnError(msgBuf->DataLength() >= kCapabilitiesRequestLength, CHIP_ERROR_MESSAGE_INCOMPLETE);
172 :
173 2 : VerifyOrReturnError(CAPABILITIES_MSG_CHECK_BYTE_1 == chip::Encoding::Read8(p), WIFIPAF_ERROR_INVALID_MESSAGE);
174 2 : VerifyOrReturnError(CAPABILITIES_MSG_CHECK_BYTE_2 == chip::Encoding::Read8(p), WIFIPAF_ERROR_INVALID_MESSAGE);
175 :
176 : static_assert(kCapabilitiesRequestSupportedVersionsLength == sizeof(msg.mSupportedProtocolVersions),
177 : "Expected capability sizes and storage must match");
178 10 : for (unsigned char & version : msg.mSupportedProtocolVersions)
179 : {
180 8 : version = chip::Encoding::Read8(p);
181 : }
182 :
183 2 : msg.mMtu = chip::Encoding::LittleEndian::Read16(p);
184 2 : msg.mWindowSize = chip::Encoding::Read8(p);
185 :
186 2 : return CHIP_NO_ERROR;
187 : }
188 :
189 2 : CHIP_ERROR PAFTransportCapabilitiesResponseMessage::Encode(const PacketBufferHandle & msgBuf) const
190 : {
191 2 : uint8_t * p = msgBuf->Start();
192 :
193 : // Verify we can write the fixed-length request without running into the end of the buffer.
194 2 : VerifyOrReturnError(msgBuf->MaxDataLength() >= kCapabilitiesResponseLength, CHIP_ERROR_NO_MEMORY);
195 :
196 2 : chip::Encoding::Write8(p, CAPABILITIES_MSG_CHECK_BYTE_1);
197 2 : chip::Encoding::Write8(p, CAPABILITIES_MSG_CHECK_BYTE_2);
198 :
199 2 : chip::Encoding::Write8(p, mSelectedProtocolVersion);
200 2 : chip::Encoding::LittleEndian::Write16(p, mFragmentSize);
201 2 : chip::Encoding::Write8(p, mWindowSize);
202 :
203 2 : msgBuf->SetDataLength(kCapabilitiesResponseLength);
204 :
205 2 : return CHIP_NO_ERROR;
206 : }
207 :
208 2 : CHIP_ERROR PAFTransportCapabilitiesResponseMessage::Decode(const PacketBufferHandle & msgBuf,
209 : PAFTransportCapabilitiesResponseMessage & msg)
210 : {
211 2 : const uint8_t * p = msgBuf->Start();
212 :
213 : // Verify we can read the fixed-length response without running into the end of the buffer.
214 2 : VerifyOrReturnError(msgBuf->DataLength() >= kCapabilitiesResponseLength, CHIP_ERROR_MESSAGE_INCOMPLETE);
215 :
216 2 : VerifyOrReturnError(CAPABILITIES_MSG_CHECK_BYTE_1 == chip::Encoding::Read8(p), WIFIPAF_ERROR_INVALID_MESSAGE);
217 2 : VerifyOrReturnError(CAPABILITIES_MSG_CHECK_BYTE_2 == chip::Encoding::Read8(p), WIFIPAF_ERROR_INVALID_MESSAGE);
218 :
219 2 : msg.mSelectedProtocolVersion = chip::Encoding::Read8(p);
220 2 : msg.mFragmentSize = chip::Encoding::LittleEndian::Read16(p);
221 2 : msg.mWindowSize = chip::Encoding::Read8(p);
222 :
223 2 : return CHIP_NO_ERROR;
224 : }
225 :
226 : /*
227 : * WiFiPAFLayer Implementation
228 : */
229 :
230 120 : WiFiPAFLayer::WiFiPAFLayer()
231 : {
232 120 : InitialPafInfo();
233 120 : }
234 :
235 50 : CHIP_ERROR WiFiPAFLayer::Init(chip::System::Layer * systemLayer)
236 : {
237 50 : mSystemLayer = systemLayer;
238 50 : memset(&sWiFiPAFEndPointPool, 0, sizeof(sWiFiPAFEndPointPool));
239 50 : ChipLogProgress(WiFiPAF, "WiFiPAF: WiFiPAFLayer::Init()");
240 50 : return CHIP_NO_ERROR;
241 : }
242 :
243 50 : void WiFiPAFLayer::Shutdown(OnCancelDeviceHandle OnCancelDevice)
244 : {
245 50 : ChipLogProgress(WiFiPAF, "WiFiPAF: Closing all WiFiPAF sessions to shutdown");
246 : uint8_t i;
247 : WiFiPAFSession * pPafSession;
248 :
249 150 : for (i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
250 : {
251 100 : pPafSession = &mPafInfoVect[i];
252 100 : if (pPafSession->id == UINT32_MAX)
253 : {
254 : // Unused session
255 100 : continue;
256 : }
257 0 : ChipLogProgress(WiFiPAF, "WiFiPAF: Canceling id: %u", pPafSession->id);
258 0 : OnCancelDevice(pPafSession->id, pPafSession->role);
259 0 : WiFiPAFEndPoint * endPoint = sWiFiPAFEndPointPool.Find(reinterpret_cast<WIFIPAF_CONNECTION_OBJECT>(pPafSession));
260 0 : if (endPoint != nullptr)
261 : {
262 0 : endPoint->DoClose(kWiFiPAFCloseFlag_AbortTransmission, WIFIPAF_ERROR_APP_CLOSED_CONNECTION);
263 : }
264 : }
265 50 : }
266 :
267 2 : bool WiFiPAFLayer::OnWiFiPAFMessageReceived(WiFiPAFSession & RxInfo, System::PacketBufferHandle && msg)
268 : {
269 2 : WiFiPAFEndPoint * endPoint = sWiFiPAFEndPointPool.Find(reinterpret_cast<WIFIPAF_CONNECTION_OBJECT>(&RxInfo));
270 2 : VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(WiFiPAF, "No endpoint for received indication"));
271 2 : RxInfo.role = endPoint->mSessionInfo.role;
272 2 : CHIP_ERROR err = endPoint->Receive(std::move(msg));
273 2 : VerifyOrReturnError(err == CHIP_NO_ERROR, false,
274 : ChipLogError(WiFiPAF, "Receive failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
275 :
276 2 : return true;
277 : }
278 :
279 2 : CHIP_ERROR WiFiPAFLayer::OnWiFiPAFMsgRxComplete(WiFiPAFSession & RxInfo, System::PacketBufferHandle && msg)
280 : {
281 2 : if (mWiFiPAFTransport != nullptr)
282 : {
283 2 : return mWiFiPAFTransport->WiFiPAFMessageReceived(RxInfo, std::move(msg));
284 : }
285 0 : return CHIP_ERROR_INCORRECT_STATE;
286 : }
287 :
288 2 : void WiFiPAFLayer::SetWiFiPAFState(State state)
289 : {
290 2 : mAppState = state;
291 2 : }
292 :
293 5 : CHIP_ERROR WiFiPAFLayer::SendMessage(WiFiPAF::WiFiPAFSession & TxInfo, chip::System::PacketBufferHandle && msg)
294 : {
295 5 : WiFiPAFEndPoint * endPoint = sWiFiPAFEndPointPool.Find(reinterpret_cast<WIFIPAF_CONNECTION_OBJECT>(&TxInfo));
296 5 : VerifyOrReturnError(endPoint != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogDetail(WiFiPAF, "No endpoint to send packets"));
297 5 : CHIP_ERROR err = endPoint->Send(std::move(msg));
298 5 : VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE,
299 : ChipLogError(WiFiPAF, "Send pakets failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
300 :
301 5 : return CHIP_NO_ERROR;
302 : }
303 :
304 7 : CHIP_ERROR WiFiPAFLayer::HandleWriteConfirmed(WiFiPAF::WiFiPAFSession & TxInfo, bool result)
305 : {
306 7 : WiFiPAFEndPoint * endPoint = sWiFiPAFEndPointPool.Find(reinterpret_cast<WIFIPAF_CONNECTION_OBJECT>(&TxInfo));
307 7 : VerifyOrReturnError(endPoint != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogDetail(WiFiPAF, "No endpoint to send packets"));
308 7 : CHIP_ERROR err = endPoint->HandleSendConfirmationReceived(result);
309 7 : VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE,
310 : ChipLogError(WiFiPAF, "Write_Confirm, Send pakets failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
311 :
312 7 : return CHIP_NO_ERROR;
313 : }
314 :
315 : static WiFiPAFLayer sInstance;
316 111 : WiFiPAFLayer & WiFiPAFLayer::GetWiFiPAFLayer()
317 : {
318 111 : return sInstance;
319 : }
320 :
321 2 : CHIP_ERROR WiFiPAFLayer::NewEndPoint(WiFiPAFEndPoint ** retEndPoint, WiFiPAFSession & SessionInfo, WiFiPafRole role)
322 : {
323 2 : *retEndPoint = nullptr;
324 :
325 2 : *retEndPoint = sWiFiPAFEndPointPool.GetFree();
326 2 : if (*retEndPoint == nullptr)
327 : {
328 0 : ChipLogError(WiFiPAF, "endpoint pool FULL");
329 0 : return CHIP_ERROR_ENDPOINT_POOL_FULL;
330 : }
331 2 : (*retEndPoint)->Init(this, SessionInfo);
332 :
333 2 : return CHIP_NO_ERROR;
334 : }
335 :
336 0 : CHIP_ERROR WiFiPAFLayer::HandleTransportConnectionInitiated(WiFiPAF::WiFiPAFSession & SessionInfo,
337 : OnSubscribeCompleteFunct OnSubscribeDoneFunc, void * appState,
338 : OnSubscribeErrorFunct OnSubscribeErrFunc)
339 : {
340 0 : CHIP_ERROR err = CHIP_NO_ERROR;
341 0 : WiFiPAFEndPoint * newEndPoint = nullptr;
342 :
343 0 : ChipLogProgress(WiFiPAF, "Creating WiFiPAFEndPoint");
344 0 : err = NewEndPoint(&newEndPoint, SessionInfo, SessionInfo.role);
345 0 : newEndPoint->mOnPafSubscribeComplete = OnSubscribeDoneFunc;
346 0 : newEndPoint->mOnPafSubscribeError = OnSubscribeErrFunc;
347 0 : newEndPoint->mAppState = appState;
348 0 : if (SessionInfo.role == kWiFiPafRole_Subscriber)
349 : {
350 0 : err = newEndPoint->StartConnect();
351 : }
352 :
353 0 : return err;
354 : }
355 :
356 2 : void WiFiPAFLayer::OnEndPointConnectComplete(WiFiPAFEndPoint * endPoint, CHIP_ERROR err)
357 : {
358 2 : VerifyOrDie(endPoint != nullptr);
359 2 : if (endPoint->mOnPafSubscribeComplete != nullptr)
360 : {
361 0 : endPoint->mOnPafSubscribeComplete(endPoint->mAppState);
362 0 : endPoint->mOnPafSubscribeComplete = nullptr;
363 : }
364 2 : }
365 :
366 : WiFiPAFTransportProtocolVersion
367 1 : WiFiPAFLayer::GetHighestSupportedProtocolVersion(const PAFTransportCapabilitiesRequestMessage & reqMsg)
368 : {
369 1 : WiFiPAFTransportProtocolVersion retVersion = kWiFiPAFTransportProtocolVersion_None;
370 :
371 1 : uint8_t shift_width = 4;
372 :
373 2 : for (int i = 0; i < NUM_PAFTP_SUPPORTED_PROTOCOL_VERSIONS; i++)
374 : {
375 2 : shift_width ^= 4;
376 :
377 2 : uint8_t version = reqMsg.mSupportedProtocolVersions[(i / 2)];
378 2 : version = static_cast<uint8_t>((version >> shift_width) & 0x0F); // Grab just the nibble we want.
379 :
380 2 : if ((version >= CHIP_PAF_TRANSPORT_PROTOCOL_MIN_SUPPORTED_VERSION) &&
381 1 : (version <= CHIP_PAF_TRANSPORT_PROTOCOL_MAX_SUPPORTED_VERSION) && (version > retVersion))
382 : {
383 1 : retVersion = static_cast<WiFiPAFTransportProtocolVersion>(version);
384 : }
385 1 : else if (version == kWiFiPAFTransportProtocolVersion_None) // Signifies end of supported versions list
386 : {
387 1 : break;
388 : }
389 : }
390 :
391 1 : return retVersion;
392 : }
393 :
394 : inline constexpr uint8_t kInvalidActiveWiFiPafSessionId = UINT8_MAX;
395 125 : void WiFiPAFLayer::InitialPafInfo()
396 : {
397 375 : for (uint8_t i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
398 : {
399 250 : CleanPafInfo(mPafInfoVect[i]);
400 : }
401 125 : }
402 :
403 254 : void WiFiPAFLayer::CleanPafInfo(WiFiPAFSession & SessionInfo)
404 : {
405 254 : memset(&SessionInfo, 0, sizeof(WiFiPAFSession));
406 254 : SessionInfo.id = kUndefinedWiFiPafSessionId;
407 254 : SessionInfo.peer_id = kUndefinedWiFiPafSessionId;
408 254 : SessionInfo.nodeId = kUndefinedNodeId;
409 254 : SessionInfo.discriminator = UINT16_MAX;
410 254 : return;
411 : }
412 :
413 5 : CHIP_ERROR WiFiPAFLayer::AddPafSession(PafInfoAccess accType, WiFiPAFSession & SessionInfo)
414 : {
415 : uint8_t i;
416 5 : uint8_t eSlotId = kInvalidActiveWiFiPafSessionId;
417 5 : WiFiPAFSession * pPafSession = nullptr;
418 :
419 : // Check if the session has existed
420 15 : for (i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
421 : {
422 10 : pPafSession = &mPafInfoVect[i];
423 10 : switch (accType)
424 : {
425 4 : case PafInfoAccess::kAccNodeInfo:
426 4 : if (pPafSession->nodeId == SessionInfo.nodeId)
427 : {
428 0 : VerifyOrDie(pPafSession->discriminator == SessionInfo.discriminator);
429 : // Already exist
430 0 : return CHIP_NO_ERROR;
431 : }
432 4 : break;
433 6 : case PafInfoAccess::kAccSessionId:
434 6 : if (pPafSession->id == SessionInfo.id)
435 : {
436 : // Already exist
437 0 : return CHIP_NO_ERROR;
438 : }
439 6 : break;
440 0 : default:
441 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
442 : };
443 10 : if ((pPafSession->id == kUndefinedWiFiPafSessionId) && (pPafSession->nodeId == kUndefinedNodeId) &&
444 7 : (pPafSession->discriminator == UINT16_MAX))
445 : {
446 7 : eSlotId = i;
447 : }
448 : }
449 : // Add the session if available
450 5 : if (eSlotId != kInvalidActiveWiFiPafSessionId)
451 : {
452 4 : pPafSession = &mPafInfoVect[eSlotId];
453 4 : pPafSession->role = SessionInfo.role;
454 4 : switch (accType)
455 : {
456 2 : case PafInfoAccess::kAccNodeInfo:
457 2 : pPafSession->nodeId = SessionInfo.nodeId;
458 2 : pPafSession->discriminator = SessionInfo.discriminator;
459 2 : ChipLogProgress(WiFiPAF, "WiFiPAF: Add session with nodeId: %lu, disc: %x, sessions", SessionInfo.nodeId,
460 : SessionInfo.discriminator);
461 2 : return CHIP_NO_ERROR;
462 2 : case PafInfoAccess::kAccSessionId:
463 2 : pPafSession->id = SessionInfo.id;
464 2 : ChipLogProgress(WiFiPAF, "WiFiPAF: Add session with id: %u", SessionInfo.id);
465 2 : return CHIP_NO_ERROR;
466 0 : default:
467 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
468 : };
469 : }
470 1 : ChipLogError(WiFiPAF, "WiFiPAF: No available space for the new sessions");
471 1 : return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED;
472 : }
473 :
474 6 : CHIP_ERROR WiFiPAFLayer::RmPafSession(PafInfoAccess accType, WiFiPAFSession & SessionInfo)
475 : {
476 : uint8_t i;
477 : WiFiPAFSession * pPafSession;
478 :
479 11 : for (i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
480 : {
481 10 : pPafSession = &mPafInfoVect[i];
482 10 : switch (accType)
483 : {
484 9 : case PafInfoAccess::kAccSessionId:
485 9 : if (pPafSession->id == SessionInfo.id)
486 : {
487 4 : ChipLogProgress(WiFiPAF, "Removing session with id: %u", pPafSession->id);
488 : // Clear the slot
489 4 : CleanPafInfo(*pPafSession);
490 4 : return CHIP_NO_ERROR;
491 : }
492 5 : break;
493 1 : default:
494 1 : return CHIP_ERROR_NOT_IMPLEMENTED;
495 : };
496 : }
497 1 : ChipLogError(WiFiPAF, "No PAF session found");
498 1 : return CHIP_ERROR_NOT_FOUND;
499 : }
500 :
501 4 : WiFiPAFSession * WiFiPAFLayer::GetPAFInfo(PafInfoAccess accType, WiFiPAFSession & SessionInfo)
502 : {
503 : uint8_t i;
504 4 : WiFiPAFSession * pPafSession = nullptr;
505 :
506 7 : for (i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
507 : {
508 7 : pPafSession = &mPafInfoVect[i];
509 7 : if (pPafSession->role == kWiFiPafRole_Publisher)
510 : {
511 0 : if (pPafSession->id != kUndefinedWiFiPafSessionId)
512 0 : return pPafSession;
513 : else
514 0 : continue;
515 : }
516 7 : switch (accType)
517 : {
518 2 : case PafInfoAccess::kAccSessionId:
519 2 : if (pPafSession->id == SessionInfo.id)
520 : {
521 1 : return pPafSession;
522 : }
523 1 : break;
524 2 : case PafInfoAccess::kAccNodeId:
525 2 : if (pPafSession->nodeId == SessionInfo.nodeId)
526 : {
527 1 : return pPafSession;
528 : }
529 1 : break;
530 3 : case PafInfoAccess::kAccDisc:
531 3 : if (pPafSession->discriminator == SessionInfo.discriminator)
532 : {
533 2 : return pPafSession;
534 : }
535 1 : break;
536 0 : default:
537 0 : return nullptr;
538 : };
539 : }
540 :
541 0 : return nullptr;
542 : }
543 : } /* namespace WiFiPAF */
544 : } /* namespace chip */
|