85 class Peripheral :
public std::enable_shared_from_this<Peripheral>
87 using BluetoothLEDevice = winrt::Windows::Devices::Bluetooth::BluetoothLEDevice;
88 using GattSession = winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::GattSession;
97 BluetoothLEDevice _device{
nullptr };
98 GattSession _session{
nullptr };
99 winrt::event_token _connectionStatusChangedToken{};
102 std::unordered_map<winrt::guid, std::shared_ptr<Service>> _services{};
105 volatile bool _isReady{};
108 mutable std::recursive_mutex _connectOpMtx{};
109 volatile size_t _connectCounter{};
110 volatile bool _connecting{};
113 std::vector<std::tuple<ConnectionEvent, ConnectionEventReason>> _connectionEventsQueue{};
116 : _address{ bluetoothAddress }, _onConnectionEvent{ onConnectionEvent }
118 assert(bluetoothAddress);
119 assert(onConnectionEvent);
120 _connectionEventsQueue.reserve(16);
135 static std::shared_ptr<Peripheral>
create(
139 return std::shared_ptr<Peripheral>{
new Peripheral(bluetoothAddress, onConnectionEvent) };
166 std::vector<winrt::guid> requiredServices = std::vector<winrt::guid>{},
167 bool maintainConnection =
false);
177 notifyQueuedConnectionEvents();
204 using namespace winrt::Windows::Devices::Bluetooth;
206 auto dev = safeGetDevice();
207 return dev ? (dev.ConnectionStatus() == BluetoothConnectionStatus::Connected) :
false;
235 auto dev = safeGetDevice();
236 return dev ? dev.DeviceId() : winrt::hstring{};
244 const winrt::hstring
name()
const
246 auto dev = safeGetDevice();
247 return dev ? dev.Name() : winrt::hstring{};
258 std::lock_guard lock{ _connectOpMtx };
259 return _session ? _session.MaxPduSize() : 0;
275 std::lock_guard lock{ _connectOpMtx };
276 auto it = _services.find(uuid);
277 return it != _services.end() ? it->second :
nullptr;
287 std::lock_guard lock{ _connectOpMtx };
288 outServices.reserve(outServices.size() + _services.size());
289 for (
auto& [_, s] : _services)
291 outServices.emplace_back(s);
299 BluetoothLEDevice safeGetDevice()
const
302 std::lock_guard lock{ _connectOpMtx };
310 void notifyQueuedConnectionEvents()
313 decltype(_connectionEventsQueue) queue{};
315 std::lock_guard lock{ _connectOpMtx };
316 queue = _connectionEventsQueue;
317 _connectionEventsQueue.clear();
319 if (_onConnectionEvent)
321 for (
auto& [ev, reason] : queue)
323 _onConnectionEvent(ev, reason);
329 void onDeviceConnectionStatusChanged(BluetoothLEDevice device, winrt::Windows::Foundation::IInspectable _)
331 using namespace winrt::Windows::Devices::Bluetooth;
333 if (device.ConnectionStatus() == BluetoothConnectionStatus::Disconnected)
335 bool linkLoss = (_session !=
nullptr) && _session.MaintainConnection();
337 notifyQueuedConnectionEvents();
Common types used across the Systemic::BluetoothLE namespace.
Represents a Bluetooth Low Energy (BLE) peripheral.
Definition: Peripheral.h:86
const winrt::hstring name() const
Gets the name of the peripheral.
Definition: Peripheral.h:244
bluetooth_address_t address() const
Gets the Bluetooth address of the peripheral.
Definition: Peripheral.h:190
const winrt::hstring deviceId() const
Gets the device id assigned by the system for the peripheral.
Definition: Peripheral.h:233
std::shared_ptr< Service > getDiscoveredService(const winrt::guid &uuid) const
Gets the Service instance with the given UUID.
Definition: Peripheral.h:273
void copyDiscoveredServices(std::vector< std::shared_ptr< Service > > &outServices) const
Copy the discovered services to the given std::vector.
Definition: Peripheral.h:285
bool isConnected() const
Indicates whether the peripheral is connected.
Definition: Peripheral.h:202
static std::shared_ptr< Peripheral > create(bluetooth_address_t bluetoothAddress, const std::function< void(ConnectionEvent, ConnectionEventReason)> &onConnectionEvent)
Initializes a new instance of Peripheral with the given Bluetooth address and a callback for notifyin...
Definition: Peripheral.h:135
std::future< BleRequestStatus > connectAsync(std::vector< winrt::guid > requiredServices=std::vector< winrt::guid >{}, bool maintainConnection=false)
Connects to the BLE peripheral.
uint16_t mtu() const
Gets the Maximum Transmission Unit (MTU).
Definition: Peripheral.h:255
void disconnect()
Immediately disconnects the peripheral.
Definition: Peripheral.h:174
bool isReady() const
Indicates whether the peripheral is ready.
Definition: Peripheral.h:218
~Peripheral()
Disconnects and destroys the Peripheral instance.
Definition: Peripheral.h:145
A collection of C++ classes that provides a simplified access to Bluetooth Low Energy peripherals.
Definition: BleTypes.h:38
std::uint64_t bluetooth_address_t
Type for a Bluetooth address.
Definition: BleTypes.h:40
@ Canceled
The request was canceled.
@ Success
The request completed successfully.
@ NotSupported
The request failed because of the operation is not supported by the peripheral.
@ Timeout
The request did not succeed after the timeout period.
@ Disconnected
The request was aborted because the peripheral got disconnected.
ConnectionEvent
Peripheral connection events.
Definition: Peripheral.h:16
@ Disconnecting
Raised at the beginning of a user initiated disconnect.
@ Connected
Raised once the peripheral is connected, just before services are being discovered.
@ Connecting
Raised at the beginning of the connect sequence and is followed either by Connected or FailedToConnec...
@ Ready
Raised after a Connected event, once the required services have been discovered.
@ FailedToConnect
Raised when the peripheral fails to connect, the reason of failure is also given.
ConnectionEventReason
Peripheral connection event reasons.
Definition: Peripheral.h:38
@ LinkLoss
Peripheral was disconnected while in "auto connect" mode.
@ Success
The disconnect was initiated by user.
@ Unknown
The disconnect happened for an unknown reason.
@ Timeout
Peripheral didn't responded in time.
@ AdpaterOff
The local device Bluetooth adapter is off.