| /* |
| * |
| * Copyright (c) 2021 Project CHIP Authors |
| * |
| * 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 <platform/CHIPDeviceConfig.h> |
| |
| #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE |
| |
| #include <glib.h> |
| #include <memory> |
| |
| #include <ble/CHIPBleServiceData.h> |
| #include <lib/core/CHIPError.h> |
| #include <platform/Linux/dbus/bluez/DbusBluez.h> |
| #include <system/SystemLayer.h> |
| |
| namespace chip { |
| namespace DeviceLayer { |
| namespace Internal { |
| |
| /// Receives callbacks when chip devices are being scanned |
| class ChipDeviceScannerDelegate |
| { |
| public: |
| virtual ~ChipDeviceScannerDelegate() {} |
| |
| // Called when a CHIP device was found |
| virtual void OnDeviceScanned(BluezDevice1 * device, const chip::Ble::ChipBLEDeviceIdentificationInfo & info) = 0; |
| |
| // Called when a scan was completed (stopped or timed out) |
| virtual void OnScanComplete() = 0; |
| |
| // Call on scan error |
| virtual void OnScanError(CHIP_ERROR) = 0; |
| }; |
| |
| /// Allows scanning for CHIP devices |
| /// |
| /// Will perform scan operations and call back whenever a device is discovered. |
| class ChipDeviceScanner |
| { |
| public: |
| /// NOTE: prefer to use the ::Create method instead direct constructor calling. |
| ChipDeviceScanner(GDBusObjectManager * manager, BluezAdapter1 * adapter, GCancellable * cancellable, |
| ChipDeviceScannerDelegate * delegate); |
| |
| ChipDeviceScanner(ChipDeviceScanner &&) = default; |
| ChipDeviceScanner(const ChipDeviceScanner &) = delete; |
| ChipDeviceScanner & operator=(const ChipDeviceScanner &) = delete; |
| |
| ~ChipDeviceScanner(); |
| |
| /// Initiate a scan for devices, with the given timeout |
| /// |
| /// This method must be called while in the Matter context (from the Matter event |
| /// loop, or while holding the Matter stack lock). |
| CHIP_ERROR StartScan(System::Clock::Timeout timeout); |
| |
| /// Stop any currently running scan |
| CHIP_ERROR StopScan(); |
| |
| /// Should only be called by TimerExpiredCallback. |
| void MarkTimerExpired() { mTimerExpired = true; } |
| |
| /// Create a new device scanner |
| /// |
| /// Convenience method to allocate any required variables. |
| /// On success, maintains a reference to the provided adapter. |
| static std::unique_ptr<ChipDeviceScanner> Create(BluezAdapter1 * adapter, ChipDeviceScannerDelegate * delegate); |
| |
| private: |
| static void TimerExpiredCallback(chip::System::Layer * layer, void * appState); |
| static CHIP_ERROR MainLoopStartScan(ChipDeviceScanner * self); |
| static CHIP_ERROR MainLoopStopScan(ChipDeviceScanner * self); |
| static void SignalObjectAdded(GDBusObjectManager * manager, GDBusObject * object, ChipDeviceScanner * self); |
| static void SignalInterfaceChanged(GDBusObjectManagerClient * manager, GDBusObjectProxy * object, GDBusProxy * aInterface, |
| GVariant * aChangedProperties, const gchar * const * aInvalidatedProps, |
| ChipDeviceScanner * self); |
| |
| /// Check if a given device is a CHIP device and if yes, report it as discovered |
| void ReportDevice(BluezDevice1 * device); |
| |
| /// Check if a given device is a CHIP device and if yes, remove it from the adapter |
| /// so that it can be re-discovered if it's still advertising. |
| void RemoveDevice(BluezDevice1 * device); |
| |
| GDBusObjectManager * mManager = nullptr; |
| BluezAdapter1 * mAdapter = nullptr; |
| GCancellable * mCancellable = nullptr; |
| ChipDeviceScannerDelegate * mDelegate = nullptr; |
| gulong mObjectAddedSignal = 0; |
| gulong mInterfaceChangedSignal = 0; |
| bool mIsScanning = false; |
| bool mIsStopping = false; |
| /// Used to track if timer has alread expired and doesn't need to be canceled. |
| bool mTimerExpired = false; |
| }; |
| |
| } // namespace Internal |
| } // namespace DeviceLayer |
| } // namespace chip |
| |
| #endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE |