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 172 : 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 172 : if (i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS)
54 : {
55 172 : return reinterpret_cast<WiFiPAFEndPoint *>(sEndPointPool.Pool + (sizeof(WiFiPAFEndPoint) * i));
56 : }
57 :
58 0 : return nullptr;
59 : }
60 :
61 16 : WiFiPAFEndPoint * Find(WIFIPAF_CONNECTION_OBJECT c) const
62 : {
63 16 : if (c == WIFIPAF_CONNECTION_UNINITIALIZED)
64 : {
65 0 : return nullptr;
66 : }
67 :
68 16 : for (size_t i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
69 : {
70 16 : WiFiPAFEndPoint * elem = Get(i);
71 16 : WiFiPAFSession * pInInfo = reinterpret_cast<WiFiPAFSession *>(c);
72 16 : if ((elem->mWiFiPafLayer != nullptr) && (elem->mSessionInfo.id == pInInfo->id) &&
73 16 : (elem->mSessionInfo.peer_id == pInInfo->peer_id) &&
74 16 : !memcmp(elem->mSessionInfo.peer_addr, pInInfo->peer_addr, kMACAddressLength))
75 : {
76 16 : ChipLogProgress(WiFiPAF, "Find: Found WiFiPAFEndPoint[%zu]", i);
77 16 : return elem;
78 : }
79 : #ifdef CHIP_WIFIPAF_LAYER_DEBUG_LOGGING_ENABLED
80 : {
81 : const WiFiPAFSession * pElmInfo = &elem->mSessionInfo;
82 : ChipLogError(WiFiPAF, "EndPoint[%zu]", 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: [%" PRIu64 ", %" PRIu64 "]", 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 8 : WiFiPAFEndPoint * GetFree() const
100 : {
101 8 : for (size_t i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
102 : {
103 8 : WiFiPAFEndPoint * elem = Get(i);
104 8 : if (elem->mWiFiPafLayer == nullptr)
105 : {
106 8 : 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 3 : CHIP_ERROR PAFTransportCapabilitiesRequestMessage::Decode(const PacketBufferHandle & msgBuf,
166 : PAFTransportCapabilitiesRequestMessage & msg)
167 : {
168 3 : 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 3 : 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 286 : WiFiPAFLayer::WiFiPAFLayer()
231 : {
232 286 : InitialPafInfo();
233 286 : }
234 :
235 73 : CHIP_ERROR WiFiPAFLayer::Init(chip::System::Layer * systemLayer)
236 : {
237 73 : mSystemLayer = systemLayer;
238 73 : memset(&sWiFiPAFEndPointPool, 0, sizeof(sWiFiPAFEndPointPool));
239 73 : ChipLogProgress(WiFiPAF, "WiFiPAF: WiFiPAFLayer::Init()");
240 73 : return CHIP_NO_ERROR;
241 : }
242 :
243 74 : void WiFiPAFLayer::Shutdown()
244 : {
245 222 : for (uint8_t i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
246 : {
247 148 : WiFiPAFEndPoint * endPoint = sWiFiPAFEndPointPool.Get(i);
248 148 : if ((endPoint == nullptr) || (endPoint->mWiFiPafLayer != this))
249 : {
250 147 : continue;
251 : }
252 :
253 1 : ChipLogProgress(WiFiPAF, "WiFiPAF: Canceling id: %u", endPoint->mSessionInfo.id);
254 1 : endPoint->DoClose(kWiFiPAFCloseFlag_AbortTransmission, WIFIPAF_ERROR_APP_CLOSED_CONNECTION);
255 : }
256 74 : }
257 :
258 2 : bool WiFiPAFLayer::OnWiFiPAFMessageReceived(WiFiPAFSession & RxInfo, System::PacketBufferHandle && msg)
259 : {
260 2 : WiFiPAFEndPoint * endPoint = sWiFiPAFEndPointPool.Find(reinterpret_cast<WIFIPAF_CONNECTION_OBJECT>(&RxInfo));
261 2 : VerifyOrReturnError(endPoint != nullptr, false, ChipLogDetail(WiFiPAF, "No endpoint for received indication"));
262 2 : RxInfo.role = endPoint->mSessionInfo.role;
263 2 : CHIP_ERROR err = endPoint->Receive(std::move(msg));
264 4 : VerifyOrReturnError(err == CHIP_NO_ERROR, false,
265 : ChipLogError(WiFiPAF, "Receive failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
266 :
267 2 : return true;
268 : }
269 :
270 2 : CHIP_ERROR WiFiPAFLayer::OnWiFiPAFMsgRxComplete(WiFiPAFSession & RxInfo, System::PacketBufferHandle && msg)
271 : {
272 2 : if (mWiFiPAFTransport != nullptr)
273 : {
274 2 : return mWiFiPAFTransport->WiFiPAFMessageReceived(RxInfo, std::move(msg));
275 : }
276 0 : return CHIP_ERROR_INCORRECT_STATE;
277 : }
278 :
279 2 : void WiFiPAFLayer::SetWiFiPAFState(State state)
280 : {
281 2 : mAppState = state;
282 2 : }
283 :
284 5 : CHIP_ERROR WiFiPAFLayer::SendMessage(WiFiPAF::WiFiPAFSession & TxInfo, chip::System::PacketBufferHandle && msg)
285 : {
286 5 : WiFiPAFEndPoint * endPoint = sWiFiPAFEndPointPool.Find(reinterpret_cast<WIFIPAF_CONNECTION_OBJECT>(&TxInfo));
287 5 : VerifyOrReturnError(endPoint != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogDetail(WiFiPAF, "No endpoint to send packets"));
288 5 : CHIP_ERROR err = endPoint->Send(std::move(msg));
289 10 : VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE,
290 : ChipLogError(WiFiPAF, "Send pakets failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
291 :
292 5 : return CHIP_NO_ERROR;
293 : }
294 :
295 9 : CHIP_ERROR WiFiPAFLayer::HandleWriteConfirmed(WiFiPAF::WiFiPAFSession & TxInfo, bool result)
296 : {
297 9 : WiFiPAFEndPoint * endPoint = sWiFiPAFEndPointPool.Find(reinterpret_cast<WIFIPAF_CONNECTION_OBJECT>(&TxInfo));
298 9 : VerifyOrReturnError(endPoint != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogDetail(WiFiPAF, "No endpoint to send packets"));
299 9 : CHIP_ERROR err = endPoint->HandleSendConfirmationReceived(result);
300 18 : VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE,
301 : ChipLogError(WiFiPAF, "Write_Confirm, Send pakets failed, err = %" CHIP_ERROR_FORMAT, err.Format()));
302 :
303 9 : return CHIP_NO_ERROR;
304 : }
305 :
306 : static WiFiPAFLayer sInstance;
307 153 : WiFiPAFLayer & WiFiPAFLayer::GetWiFiPAFLayer()
308 : {
309 153 : return sInstance;
310 : }
311 :
312 8 : CHIP_ERROR WiFiPAFLayer::NewEndPoint(WiFiPAFEndPoint ** retEndPoint, WiFiPAFSession & SessionInfo, WiFiPafRole role)
313 : {
314 8 : *retEndPoint = nullptr;
315 :
316 8 : *retEndPoint = sWiFiPAFEndPointPool.GetFree();
317 8 : if (*retEndPoint == nullptr)
318 : {
319 0 : ChipLogError(WiFiPAF, "endpoint pool FULL");
320 0 : return CHIP_ERROR_ENDPOINT_POOL_FULL;
321 : }
322 8 : return (*retEndPoint)->Init(this, SessionInfo);
323 : }
324 :
325 0 : CHIP_ERROR WiFiPAFLayer::HandleTransportConnectionInitiated(WiFiPAF::WiFiPAFSession & SessionInfo,
326 : OnSubscribeCompleteFunct OnSubscribeDoneFunc, void * appState,
327 : OnSubscribeErrorFunct OnSubscribeErrFunc)
328 : {
329 0 : CHIP_ERROR err = CHIP_NO_ERROR;
330 0 : WiFiPAFEndPoint * newEndPoint = nullptr;
331 :
332 0 : ChipLogProgress(WiFiPAF, "Creating WiFiPAFEndPoint");
333 0 : ReturnErrorOnFailure(NewEndPoint(&newEndPoint, SessionInfo, SessionInfo.role));
334 0 : newEndPoint->mOnPafSubscribeComplete = OnSubscribeDoneFunc;
335 0 : newEndPoint->mOnPafSubscribeError = OnSubscribeErrFunc;
336 0 : newEndPoint->mAppState = appState;
337 0 : if (SessionInfo.role == kWiFiPafRole_Subscriber)
338 : {
339 0 : err = newEndPoint->StartConnect();
340 : }
341 : else
342 : {
343 0 : err = newEndPoint->StartReceiveConnectionTimer();
344 : }
345 :
346 0 : return err;
347 : }
348 :
349 2 : void WiFiPAFLayer::OnEndPointConnectComplete(WiFiPAFEndPoint * endPoint, CHIP_ERROR err)
350 : {
351 2 : VerifyOrDie(endPoint != nullptr);
352 2 : if (endPoint->mOnPafSubscribeComplete != nullptr)
353 : {
354 0 : endPoint->mOnPafSubscribeComplete(endPoint->mAppState);
355 0 : endPoint->mOnPafSubscribeComplete = nullptr;
356 : }
357 2 : }
358 :
359 : WiFiPAFTransportProtocolVersion
360 1 : WiFiPAFLayer::GetHighestSupportedProtocolVersion(const PAFTransportCapabilitiesRequestMessage & reqMsg)
361 : {
362 1 : WiFiPAFTransportProtocolVersion retVersion = kWiFiPAFTransportProtocolVersion_None;
363 :
364 1 : uint8_t shift_width = 4;
365 :
366 2 : for (int i = 0; i < NUM_PAFTP_SUPPORTED_PROTOCOL_VERSIONS; i++)
367 : {
368 2 : shift_width ^= 4;
369 :
370 2 : uint8_t version = reqMsg.mSupportedProtocolVersions[(i / 2)];
371 2 : version = static_cast<uint8_t>((version >> shift_width) & 0x0F); // Grab just the nibble we want.
372 :
373 2 : if ((version >= CHIP_PAF_TRANSPORT_PROTOCOL_MIN_SUPPORTED_VERSION) &&
374 1 : (version <= CHIP_PAF_TRANSPORT_PROTOCOL_MAX_SUPPORTED_VERSION) && (version > retVersion))
375 : {
376 1 : retVersion = static_cast<WiFiPAFTransportProtocolVersion>(version);
377 : }
378 1 : else if (version == kWiFiPAFTransportProtocolVersion_None) // Signifies end of supported versions list
379 : {
380 1 : break;
381 : }
382 : }
383 :
384 1 : return retVersion;
385 : }
386 :
387 : inline constexpr uint8_t kInvalidActiveWiFiPafSessionId = UINT8_MAX;
388 297 : void WiFiPAFLayer::InitialPafInfo()
389 : {
390 891 : for (uint8_t i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
391 : {
392 594 : CleanPafInfo(mPafInfoVect[i]);
393 : }
394 297 : }
395 :
396 600 : void WiFiPAFLayer::CleanPafInfo(WiFiPAFSession & SessionInfo)
397 : {
398 600 : memset(&SessionInfo, 0, sizeof(WiFiPAFSession));
399 600 : SessionInfo.id = kUndefinedWiFiPafSessionId;
400 600 : SessionInfo.peer_id = kUndefinedWiFiPafSessionId;
401 600 : SessionInfo.nodeId = kUndefinedNodeId;
402 600 : SessionInfo.discriminator = UINT16_MAX;
403 600 : }
404 :
405 8 : CHIP_ERROR WiFiPAFLayer::AddPafSession(PafInfoAccess accType, WiFiPAFSession & SessionInfo)
406 : {
407 : uint8_t i;
408 8 : uint8_t eSlotId = kInvalidActiveWiFiPafSessionId;
409 8 : WiFiPAFSession * pPafSession = nullptr;
410 :
411 : // Check if the session has existed
412 24 : for (i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
413 : {
414 16 : pPafSession = &mPafInfoVect[i];
415 16 : switch (accType)
416 : {
417 4 : case PafInfoAccess::kAccNodeInfo:
418 4 : if (pPafSession->nodeId == SessionInfo.nodeId)
419 : {
420 0 : VerifyOrDie(pPafSession->discriminator == SessionInfo.discriminator);
421 : // Already exist
422 0 : return CHIP_NO_ERROR;
423 : }
424 4 : break;
425 12 : case PafInfoAccess::kAccSessionId:
426 12 : if (pPafSession->id == SessionInfo.id)
427 : {
428 : // Already exist
429 0 : return CHIP_NO_ERROR;
430 : }
431 12 : break;
432 0 : default:
433 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
434 : };
435 16 : if ((pPafSession->id == kUndefinedWiFiPafSessionId) && (pPafSession->nodeId == kUndefinedNodeId) &&
436 13 : (pPafSession->discriminator == UINT16_MAX))
437 : {
438 13 : eSlotId = i;
439 : }
440 : }
441 : // Add the session if available
442 8 : if (eSlotId != kInvalidActiveWiFiPafSessionId)
443 : {
444 7 : pPafSession = &mPafInfoVect[eSlotId];
445 7 : pPafSession->role = SessionInfo.role;
446 7 : switch (accType)
447 : {
448 2 : case PafInfoAccess::kAccNodeInfo:
449 2 : pPafSession->nodeId = SessionInfo.nodeId;
450 2 : pPafSession->discriminator = SessionInfo.discriminator;
451 2 : ChipLogProgress(WiFiPAF, "WiFiPAF: Add session with nodeId: %" PRIu64 ", disc: %x, sessions", SessionInfo.nodeId,
452 : SessionInfo.discriminator);
453 2 : return CHIP_NO_ERROR;
454 5 : case PafInfoAccess::kAccSessionId:
455 5 : pPafSession->id = SessionInfo.id;
456 5 : ChipLogProgress(WiFiPAF, "WiFiPAF: Add session with id: %u", SessionInfo.id);
457 5 : return CHIP_NO_ERROR;
458 0 : default:
459 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
460 : };
461 : }
462 1 : ChipLogError(WiFiPAF, "WiFiPAF: No available space for the new sessions");
463 1 : return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED;
464 : }
465 :
466 8 : CHIP_ERROR WiFiPAFLayer::RmPafSession(PafInfoAccess accType, WiFiPAFSession & SessionInfo)
467 : {
468 : uint8_t i;
469 : WiFiPAFSession * pPafSession;
470 :
471 15 : for (i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
472 : {
473 14 : pPafSession = &mPafInfoVect[i];
474 14 : switch (accType)
475 : {
476 13 : case PafInfoAccess::kAccSessionId:
477 13 : if (pPafSession->id == SessionInfo.id)
478 : {
479 6 : ChipLogProgress(WiFiPAF, "Removing session with id: %u", pPafSession->id);
480 : // Clear the slot
481 6 : CleanPafInfo(*pPafSession);
482 6 : return CHIP_NO_ERROR;
483 : }
484 7 : break;
485 1 : default:
486 1 : return CHIP_ERROR_NOT_IMPLEMENTED;
487 : };
488 : }
489 1 : ChipLogError(WiFiPAF, "No PAF session found");
490 1 : return CHIP_ERROR_NOT_FOUND;
491 : }
492 :
493 4 : WiFiPAFSession * WiFiPAFLayer::GetPAFInfo(PafInfoAccess accType, WiFiPAFSession & SessionInfo)
494 : {
495 : uint8_t i;
496 4 : WiFiPAFSession * pPafSession = nullptr;
497 :
498 7 : for (i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
499 : {
500 7 : pPafSession = &mPafInfoVect[i];
501 7 : if (pPafSession->role == kWiFiPafRole_Publisher)
502 : {
503 0 : if (pPafSession->id != kUndefinedWiFiPafSessionId)
504 0 : return pPafSession;
505 0 : continue;
506 : }
507 7 : switch (accType)
508 : {
509 2 : case PafInfoAccess::kAccSessionId:
510 2 : if (pPafSession->id == SessionInfo.id)
511 : {
512 1 : return pPafSession;
513 : }
514 1 : break;
515 2 : case PafInfoAccess::kAccNodeId:
516 2 : if (pPafSession->nodeId == SessionInfo.nodeId)
517 : {
518 1 : return pPafSession;
519 : }
520 1 : break;
521 3 : case PafInfoAccess::kAccDisc:
522 3 : if (pPafSession->discriminator == SessionInfo.discriminator)
523 : {
524 2 : return pPafSession;
525 : }
526 1 : break;
527 0 : default:
528 0 : return nullptr;
529 : };
530 : }
531 :
532 0 : return nullptr;
533 : }
534 : } /* namespace WiFiPAF */
535 : } /* namespace chip */
|