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