Skip to content

Commit bde473a

Browse files
vicoczJ0EK3RVit Nemecky
authored
Support BLE advertising devices on Windows (imurvai#116)
* Support BLE advertising devices on Windows * JK: process CaDA scan-result * JK: MouldKing is working --------- Co-authored-by: J0EK3R <J0EK3R3.3@WIN11> Co-authored-by: Vit Nemecky <[email protected]>
1 parent f320809 commit bde473a

File tree

3 files changed

+84
-11
lines changed

3 files changed

+84
-11
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using BrickController2.PlatformServices.BluetoothLE;
2+
using Microsoft.Extensions.Logging;
3+
using System.Runtime.InteropServices.WindowsRuntime;
4+
using System.Threading.Tasks;
5+
using Windows.Devices.Bluetooth.Advertisement;
6+
7+
namespace BrickController2.Windows.PlatformServices.BluetoothLE;
8+
9+
internal class BleAdvertiserDevice : IBluetoothLEAdvertiserDevice
10+
{
11+
private readonly ILogger _logger;
12+
13+
private BluetoothLEAdvertisementPublisher? _publisher;
14+
15+
public BleAdvertiserDevice(ILogger logger)
16+
{
17+
_logger = logger;
18+
}
19+
20+
public Task StartAdvertiseAsync(AdvertisingInterval advertisingInterval,
21+
TxPowerLevel txPowerLevel,
22+
ushort manufacturerId,
23+
byte[] rawData)
24+
25+
=> SetNewAdvertisedDataAsync(manufacturerId, rawData);
26+
27+
public Task StopAdvertiseAsync()
28+
{
29+
_publisher?.Stop();
30+
_publisher = null;
31+
32+
return Task.CompletedTask;
33+
}
34+
35+
public Task UpdateAdvertisedDataAsync(ushort manufacturerId, byte[] rawData)
36+
=> SetNewAdvertisedDataAsync(manufacturerId, rawData);
37+
38+
public void Dispose()
39+
{
40+
_publisher?.Stop();
41+
_publisher = null;
42+
}
43+
44+
private Task SetNewAdvertisedDataAsync(ushort manufacturerId, byte[] rawData)
45+
{
46+
_publisher?.Stop();
47+
48+
// compose data
49+
var advertisement = new BluetoothLEAdvertisement()
50+
{
51+
ManufacturerData = { new BluetoothLEManufacturerData(manufacturerId, rawData.AsBuffer()) }
52+
};
53+
54+
_publisher = new BluetoothLEAdvertisementPublisher(advertisement);
55+
_publisher.Start();
56+
57+
_logger.LogDebug("Started BLE advertisement with Manufacturer ID: {0}, Data Length: {1}", [manufacturerId, rawData.Length]);
58+
59+
return Task.CompletedTask;
60+
}
61+
62+
}

BrickController2/BrickController2.WinUI/PlatformServices/BluetoothLE/BleScanner.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,20 @@ private void _passiveWatcher_Received(BluetoothLEAdvertisementWatcher sender, Bl
5656
{
5757
_deviceNameCache.AddOrUpdate(args.BluetoothAddress, deviceName, (key, oldValue) => deviceName);
5858
}
59+
else if (args.Advertisement.DataSections?.Count > 0)
60+
{
61+
// allow processing of advertised data from a device
62+
var advertismentData = args.Advertisement.DataSections
63+
.Where(s => AdvertismentDataTypes.Contains(s.DataType))
64+
.ToDictionary(s => s.DataType, s => s.Data.ToByteArray());
65+
66+
var bluetoothAddress = args.BluetoothAddress.ToBluetoothAddressString();
67+
68+
// if no local name is set, try to get it from the cache
69+
_deviceNameCache.TryGetValue(args.BluetoothAddress, out deviceName);
70+
71+
_scanCallback(new ScanResult(deviceName, bluetoothAddress, advertismentData));
72+
}
5973
}
6074

6175
private void _passiveWatcher_Stopped(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementWatcherStoppedEventArgs args)

BrickController2/BrickController2.WinUI/PlatformServices/BluetoothLE/BleService.cs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using BrickController2.PlatformServices.BluetoothLE;
2+
using Microsoft.Extensions.Logging;
23
using System;
34
using System.Threading;
45
using System.Threading.Tasks;
@@ -9,10 +10,13 @@ namespace BrickController2.Windows.PlatformServices.BluetoothLE;
910

1011
public class BleService : IBluetoothLEService
1112
{
13+
private readonly ILogger _logger;
14+
1215
private bool _isScanning;
1316

14-
public BleService()
17+
public BleService(ILogger<BleService> logger)
1518
{
19+
_logger = logger;
1620
}
1721

1822
public async Task<bool> IsBluetoothLESupportedAsync()
@@ -22,12 +26,7 @@ public async Task<bool> IsBluetoothLESupportedAsync()
2226
}
2327

2428
public Task<bool> IsBluetoothLEAdvertisingSupportedAsync()
25-
#if DEBUG
26-
// JK: to allow development on windows this is enabled
2729
=> Task.FromResult(true);
28-
#else
29-
=> Task.FromResult(false); // Not supported yet - has to be implemented
30-
#endif
3130

3231
public async Task<bool> IsBluetoothOnAsync()
3332
{
@@ -72,6 +71,9 @@ public async Task<bool> ScanDevicesAsync(Action<ScanResult> scanCallback, Cancel
7271
return new BleDevice(address);
7372
}
7473

74+
public IBluetoothLEAdvertiserDevice? CreateBluetoothLEAdvertiserDevice()
75+
=> new BleAdvertiserDevice(_logger);
76+
7577
private async Task<bool> ScanAsync(Action<ScanResult> scanCallback, CancellationToken token)
7678
{
7779
try
@@ -94,9 +96,4 @@ private async Task<bool> ScanAsync(Action<ScanResult> scanCallback, Cancellation
9496
return false;
9597
}
9698
}
97-
98-
public IBluetoothLEAdvertiserDevice? CreateBluetoothLEAdvertiserDevice()
99-
{
100-
return null; // Not supported yet - has to be implemented
101-
}
10299
}

0 commit comments

Comments
 (0)