| /* | |
| * | |
| * Copyright (c) 2026 Project CHIP Authors | |
| * All rights reserved. | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| #pragma once | |
| #include <lib/core/CHIPError.h> | |
| #include <lib/support/Span.h> | |
| #include <system/SystemClock.h> | |
| #include <cstdint> | |
| namespace chip { | |
| namespace app { | |
| namespace Clusters { | |
| namespace CommissioningProxy { | |
| /** | |
| * @brief The Wi-Fi PAF operations a commissioning proxy needs that have no portable form. | |
| * | |
| * Opening, sending over and closing a PAF session is already portable: it goes through | |
| * chip::WiFiPAF::WiFiPAFLayer and the generic ConnectivityManager facade | |
| * (WiFiPAFSubscribe / WiFiPAFCancelSubscribe / WiFiPAFCancelIncompleteSubscribe). | |
| * Discovery is not — scanning for commissionable devices, and recovering the subscribe | |
| * id the platform assigned, both need the platform implementation. Those live here so | |
| * CommissioningProxyPafTransport stays free of any platform header, and so a test can | |
| * drive it against a fake. | |
| * | |
| * One implementation per platform. The application owns the instance and passes it to | |
| * the transport, which keeps a reference and never takes ownership. | |
| */ | |
| class CommissioningProxyPafAdapter | |
| { | |
| public: | |
| /** | |
| * Fired once per discovered commissionable device, on the Matter event loop, with | |
| * @p context passed back unchanged. Used by both the foreground and the background | |
| * scan, so a device looks the same whichever scan found it. | |
| * | |
| * Reported as scalars rather than as a platform type: a NAN peer descriptor is | |
| * platform-specific and typically owns heap storage for its extended data, neither | |
| * of which belongs in the cluster. | |
| * | |
| * @param address peer NAN MAC. | |
| * @param extendedData empty when the advertisement carried none. | |
| * @param wiFiBand WiFiBandBitmap value the peer was found on; 0 when unknown. | |
| * | |
| * Both spans are only valid for the duration of the call. | |
| */ | |
| using DiscoveryCallback = void (*)(void * context, ByteSpan address, uint16_t discriminator, uint16_t vendorId, | |
| uint16_t productId, ByteSpan extendedData, uint16_t wiFiBand); | |
| /// Fired once when a foreground scan started by StartForegroundScan has finished | |
| /// reporting devices, so the transport knows the result set is complete. | |
| using ScanCompleteCallback = void (*)(void * context); | |
| virtual ~CommissioningProxyPafAdapter() = default; | |
| /** | |
| * Run a one-shot discovery scan lasting @p window, reporting each peer through | |
| * @p onDevice and then calling @p onDone exactly once. | |
| * | |
| * Unlike BLE, the platform owns the scan window here, so the transport arms no timer | |
| * of its own and relies on @p onDone to close the scan out. | |
| * | |
| * A NAN radio has a single subscribe slot shared with the background scan and with | |
| * connect. This reports CHIP_ERROR_BUSY only when a background scan holds the slot, | |
| * and even that is a backstop: the transport pauses a running background scan before | |
| * calling. A connect holding the slot is not reported here. | |
| */ | |
| virtual CHIP_ERROR StartForegroundScan(System::Clock::Seconds16 window, DiscoveryCallback onDevice, ScanCompleteCallback onDone, | |
| void * context) = 0; | |
| /** | |
| * Guarantee no further callbacks from a scan started by StartForegroundScan. | |
| * | |
| * The platform owns the scan window and may have no way to abort it early, so this is | |
| * not required to stop the radio — it is required to detach the callbacks, so a scan | |
| * that completes after the caller has gone cannot reach it. Called from the | |
| * transport's Shutdown(). A no-op when no foreground scan is outstanding. | |
| */ | |
| virtual void StopForegroundScan() = 0; | |
| /** | |
| * Start a continuous discovery scan, reporting each peer as it is seen — including | |
| * re-discoveries, so the cluster's cache can refresh a TTL rather than treat the | |
| * peer as new. | |
| * | |
| * Reports CHIP_ERROR_BUSY when a foreground scan holds the single subscribe slot. | |
| * A connect holding it is caught before this is reached, by the transport hook the | |
| * registry calls to start the hardware scan. Either way the registry treats | |
| * CHIP_ERROR_BUSY as "defer and retry later". | |
| */ | |
| virtual CHIP_ERROR StartBackgroundScan(DiscoveryCallback cb, void * context) = 0; | |
| /** | |
| * Stop a scan started by StartBackgroundScan. A no-op when none is running, so | |
| * teardown paths can call it unconditionally. | |
| */ | |
| virtual void StopBackgroundScan() = 0; | |
| /** | |
| * The subscribe id the platform assigned to the most recent subscribe request, which | |
| * the portable WiFiPAFSubscribe() call does not return. The transport needs it to | |
| * cancel that specific subscribe if the connect fails or is abandoned. | |
| * | |
| * Valid only immediately after a successful subscribe; 0 when there is none. | |
| */ | |
| virtual uint32_t PendingConnectSubscribeId() const = 0; | |
| }; | |
| } // namespace CommissioningProxy | |
| } // namespace Clusters | |
| } // namespace app | |
| } // namespace chip |