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 196 : WiFiPAFLayer::WiFiPAFLayer()
231 : {
232 196 : InitialPafInfo();
233 196 : }
234 :
235 57 : CHIP_ERROR WiFiPAFLayer::Init(chip::System::Layer * systemLayer)
236 : {
237 57 : mSystemLayer = systemLayer;
238 57 : memset(&sWiFiPAFEndPointPool, 0, sizeof(sWiFiPAFEndPointPool));
239 57 : ChipLogProgress(WiFiPAF, "WiFiPAF: WiFiPAFLayer::Init()");
240 57 : return CHIP_NO_ERROR;
241 : }
242 :
243 57 : void WiFiPAFLayer::Shutdown(OnCancelDeviceHandle OnCancelDevice)
244 : {
245 57 : ChipLogProgress(WiFiPAF, "WiFiPAF: Closing all WiFiPAF sessions to shutdown");
246 : uint8_t i;
247 : WiFiPAFSession * pPafSession;
248 :
249 171 : for (i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
250 : {
251 114 : pPafSession = &mPafInfoVect[i];
252 114 : if (pPafSession->id == UINT32_MAX)
253 : {
254 : // Unused session
255 114 : 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 57 : }
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 4 : 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 10 : 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 9 : CHIP_ERROR WiFiPAFLayer::HandleWriteConfirmed(WiFiPAF::WiFiPAFSession & TxInfo, bool result)
305 : {
306 9 : WiFiPAFEndPoint * endPoint = sWiFiPAFEndPointPool.Find(reinterpret_cast<WIFIPAF_CONNECTION_OBJECT>(&TxInfo));
307 9 : VerifyOrReturnError(endPoint != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogDetail(WiFiPAF, "No endpoint to send packets"));
308 9 : CHIP_ERROR err = endPoint->HandleSendConfirmationReceived(result);
309 18 : 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 9 : return CHIP_NO_ERROR;
313 : }
314 :
315 : static WiFiPAFLayer sInstance;
316 128 : WiFiPAFLayer & WiFiPAFLayer::GetWiFiPAFLayer()
317 : {
318 128 : 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 : return (*retEndPoint)->Init(this, SessionInfo);
332 : }
333 :
334 0 : CHIP_ERROR WiFiPAFLayer::HandleTransportConnectionInitiated(WiFiPAF::WiFiPAFSession & SessionInfo,
335 : OnSubscribeCompleteFunct OnSubscribeDoneFunc, void * appState,
336 : OnSubscribeErrorFunct OnSubscribeErrFunc)
337 : {
338 0 : CHIP_ERROR err = CHIP_NO_ERROR;
339 0 : WiFiPAFEndPoint * newEndPoint = nullptr;
340 :
341 0 : ChipLogProgress(WiFiPAF, "Creating WiFiPAFEndPoint");
342 0 : ReturnErrorOnFailure(NewEndPoint(&newEndPoint, SessionInfo, SessionInfo.role));
343 0 : newEndPoint->mOnPafSubscribeComplete = OnSubscribeDoneFunc;
344 0 : newEndPoint->mOnPafSubscribeError = OnSubscribeErrFunc;
345 0 : newEndPoint->mAppState = appState;
346 0 : if (SessionInfo.role == kWiFiPafRole_Subscriber)
347 : {
348 0 : err = newEndPoint->StartConnect();
349 : }
350 :
351 0 : return err;
352 : }
353 :
354 2 : void WiFiPAFLayer::OnEndPointConnectComplete(WiFiPAFEndPoint * endPoint, CHIP_ERROR err)
355 : {
356 2 : VerifyOrDie(endPoint != nullptr);
357 2 : if (endPoint->mOnPafSubscribeComplete != nullptr)
358 : {
359 0 : endPoint->mOnPafSubscribeComplete(endPoint->mAppState);
360 0 : endPoint->mOnPafSubscribeComplete = nullptr;
361 : }
362 2 : }
363 :
364 : WiFiPAFTransportProtocolVersion
365 1 : WiFiPAFLayer::GetHighestSupportedProtocolVersion(const PAFTransportCapabilitiesRequestMessage & reqMsg)
366 : {
367 1 : WiFiPAFTransportProtocolVersion retVersion = kWiFiPAFTransportProtocolVersion_None;
368 :
369 1 : uint8_t shift_width = 4;
370 :
371 2 : for (int i = 0; i < NUM_PAFTP_SUPPORTED_PROTOCOL_VERSIONS; i++)
372 : {
373 2 : shift_width ^= 4;
374 :
375 2 : uint8_t version = reqMsg.mSupportedProtocolVersions[(i / 2)];
376 2 : version = static_cast<uint8_t>((version >> shift_width) & 0x0F); // Grab just the nibble we want.
377 :
378 2 : if ((version >= CHIP_PAF_TRANSPORT_PROTOCOL_MIN_SUPPORTED_VERSION) &&
379 1 : (version <= CHIP_PAF_TRANSPORT_PROTOCOL_MAX_SUPPORTED_VERSION) && (version > retVersion))
380 : {
381 1 : retVersion = static_cast<WiFiPAFTransportProtocolVersion>(version);
382 : }
383 1 : else if (version == kWiFiPAFTransportProtocolVersion_None) // Signifies end of supported versions list
384 : {
385 1 : break;
386 : }
387 : }
388 :
389 1 : return retVersion;
390 : }
391 :
392 : inline constexpr uint8_t kInvalidActiveWiFiPafSessionId = UINT8_MAX;
393 201 : void WiFiPAFLayer::InitialPafInfo()
394 : {
395 603 : for (uint8_t i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
396 : {
397 402 : CleanPafInfo(mPafInfoVect[i]);
398 : }
399 201 : }
400 :
401 406 : void WiFiPAFLayer::CleanPafInfo(WiFiPAFSession & SessionInfo)
402 : {
403 406 : memset(&SessionInfo, 0, sizeof(WiFiPAFSession));
404 406 : SessionInfo.id = kUndefinedWiFiPafSessionId;
405 406 : SessionInfo.peer_id = kUndefinedWiFiPafSessionId;
406 406 : SessionInfo.nodeId = kUndefinedNodeId;
407 406 : SessionInfo.discriminator = UINT16_MAX;
408 406 : return;
409 : }
410 :
411 5 : CHIP_ERROR WiFiPAFLayer::AddPafSession(PafInfoAccess accType, WiFiPAFSession & SessionInfo)
412 : {
413 : uint8_t i;
414 5 : uint8_t eSlotId = kInvalidActiveWiFiPafSessionId;
415 5 : WiFiPAFSession * pPafSession = nullptr;
416 :
417 : // Check if the session has existed
418 15 : for (i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
419 : {
420 10 : pPafSession = &mPafInfoVect[i];
421 10 : switch (accType)
422 : {
423 4 : case PafInfoAccess::kAccNodeInfo:
424 4 : if (pPafSession->nodeId == SessionInfo.nodeId)
425 : {
426 0 : VerifyOrDie(pPafSession->discriminator == SessionInfo.discriminator);
427 : // Already exist
428 0 : return CHIP_NO_ERROR;
429 : }
430 4 : break;
431 6 : case PafInfoAccess::kAccSessionId:
432 6 : if (pPafSession->id == SessionInfo.id)
433 : {
434 : // Already exist
435 0 : return CHIP_NO_ERROR;
436 : }
437 6 : break;
438 0 : default:
439 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
440 : };
441 10 : if ((pPafSession->id == kUndefinedWiFiPafSessionId) && (pPafSession->nodeId == kUndefinedNodeId) &&
442 7 : (pPafSession->discriminator == UINT16_MAX))
443 : {
444 7 : eSlotId = i;
445 : }
446 : }
447 : // Add the session if available
448 5 : if (eSlotId != kInvalidActiveWiFiPafSessionId)
449 : {
450 4 : pPafSession = &mPafInfoVect[eSlotId];
451 4 : pPafSession->role = SessionInfo.role;
452 4 : switch (accType)
453 : {
454 2 : case PafInfoAccess::kAccNodeInfo:
455 2 : pPafSession->nodeId = SessionInfo.nodeId;
456 2 : pPafSession->discriminator = SessionInfo.discriminator;
457 2 : ChipLogProgress(WiFiPAF, "WiFiPAF: Add session with nodeId: %" PRIu64 ", disc: %x, sessions", SessionInfo.nodeId,
458 : SessionInfo.discriminator);
459 2 : return CHIP_NO_ERROR;
460 2 : case PafInfoAccess::kAccSessionId:
461 2 : pPafSession->id = SessionInfo.id;
462 2 : ChipLogProgress(WiFiPAF, "WiFiPAF: Add session with id: %u", SessionInfo.id);
463 2 : return CHIP_NO_ERROR;
464 0 : default:
465 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
466 : };
467 : }
468 1 : ChipLogError(WiFiPAF, "WiFiPAF: No available space for the new sessions");
469 1 : return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED;
470 : }
471 :
472 6 : CHIP_ERROR WiFiPAFLayer::RmPafSession(PafInfoAccess accType, WiFiPAFSession & SessionInfo)
473 : {
474 : uint8_t i;
475 : WiFiPAFSession * pPafSession;
476 :
477 11 : for (i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
478 : {
479 10 : pPafSession = &mPafInfoVect[i];
480 10 : switch (accType)
481 : {
482 9 : case PafInfoAccess::kAccSessionId:
483 9 : if (pPafSession->id == SessionInfo.id)
484 : {
485 4 : ChipLogProgress(WiFiPAF, "Removing session with id: %u", pPafSession->id);
486 : // Clear the slot
487 4 : CleanPafInfo(*pPafSession);
488 4 : return CHIP_NO_ERROR;
489 : }
490 5 : break;
491 1 : default:
492 1 : return CHIP_ERROR_NOT_IMPLEMENTED;
493 : };
494 : }
495 1 : ChipLogError(WiFiPAF, "No PAF session found");
496 1 : return CHIP_ERROR_NOT_FOUND;
497 : }
498 :
499 4 : WiFiPAFSession * WiFiPAFLayer::GetPAFInfo(PafInfoAccess accType, WiFiPAFSession & SessionInfo)
500 : {
501 : uint8_t i;
502 4 : WiFiPAFSession * pPafSession = nullptr;
503 :
504 7 : for (i = 0; i < WIFIPAF_LAYER_NUM_PAF_ENDPOINTS; i++)
505 : {
506 7 : pPafSession = &mPafInfoVect[i];
507 7 : if (pPafSession->role == kWiFiPafRole_Publisher)
508 : {
509 0 : if (pPafSession->id != kUndefinedWiFiPafSessionId)
510 0 : return pPafSession;
511 : else
512 0 : continue;
513 : }
514 7 : switch (accType)
515 : {
516 2 : case PafInfoAccess::kAccSessionId:
517 2 : if (pPafSession->id == SessionInfo.id)
518 : {
519 1 : return pPafSession;
520 : }
521 1 : break;
522 2 : case PafInfoAccess::kAccNodeId:
523 2 : if (pPafSession->nodeId == SessionInfo.nodeId)
524 : {
525 1 : return pPafSession;
526 : }
527 1 : break;
528 3 : case PafInfoAccess::kAccDisc:
529 3 : if (pPafSession->discriminator == SessionInfo.discriminator)
530 : {
531 2 : return pPafSession;
532 : }
533 1 : break;
534 0 : default:
535 0 : return nullptr;
536 : };
537 : }
538 :
539 0 : return nullptr;
540 : }
541 : } /* namespace WiFiPAF */
542 : } /* namespace chip */
|