Kotlin Multiplatform BLE library for iOS, Android, macos, windows and javascript
This document provides detailed information about the Windows 10 Bluetooth LE implementation for Blue Falcon.
The Windows implementation provides full Bluetooth Low Energy support for Windows 10 desktop applications through JNI (Java Native Interface) and Windows Runtime (WinRT) APIs. This implementation does NOT rely on any third-party libraries and uses only the built-in Windows Bluetooth APIs.
The Windows implementation consists of three layers:
windowsMain/kotlin)windowsMain/cpp/jni_bridge.cpp)windowsMain/cpp/BluetoothLEManager.cpp/h)Windows.Devices.BluetoothWindows.Devices.Bluetooth.AdvertisementWindows.Devices.Bluetooth.GenericAttributeProfilecd library\src\windowsMain\cpp
mkdir build
cd build
cmake .. -G "Visual Studio 16 2019" -A x64
cmake --build . --config Release
The output bluefalcon-windows.dll will be in the Release directory.
Copy the DLL to one of the following locations:
library/src/windowsMain/resources/import dev.bluefalcon.*
// Create BlueFalcon instance
val blueFalcon = BlueFalcon(
log = PrintLnLogger, // or your custom logger
context = ApplicationContext(), // Empty context for Windows
autoDiscoverAllServicesAndCharacteristics = true
)
// Implement delegate to receive callbacks
blueFalcon.delegates.add(object : BlueFalconDelegate {
override fun didDiscoverDevice(
bluetoothPeripheral: BluetoothPeripheral,
advertisementData: Map<AdvertisementDataRetrievalKeys, Any>
) {
println("Found device: ${bluetoothPeripheral.name} - ${bluetoothPeripheral.uuid}")
}
override fun didConnect(bluetoothPeripheral: BluetoothPeripheral) {
println("Connected to ${bluetoothPeripheral.name}")
}
override fun didDiscoverServices(bluetoothPeripheral: BluetoothPeripheral) {
println("Discovered ${bluetoothPeripheral.services.size} services")
}
override fun didCharacteristcValueChanged(
bluetoothPeripheral: BluetoothPeripheral,
bluetoothCharacteristic: BluetoothCharacteristic
) {
println("Characteristic changed: ${bluetoothCharacteristic.uuid}")
println("Value: ${bluetoothCharacteristic.value?.contentToString()}")
}
// Implement other delegate methods...
})
// Start scanning
blueFalcon.scan()
// Stop scanning
blueFalcon.stopScanning()
// Connect to a device
blueFalcon.connect(device, autoConnect = false)
// Read a characteristic
blueFalcon.readCharacteristic(device, characteristic)
// Write to a characteristic
blueFalcon.writeCharacteristic(device, characteristic, data)
// Enable notifications
blueFalcon.notifyCharacteristic(device, characteristic, true)
The legacy dev.bluefalcon.BlueFalcon API does not support pairing. Use the core facade with
WindowsEngine and a peripheral discovered by that engine:
import dev.bluefalcon.core.BlueFalcon
import dev.bluefalcon.engine.windows.WindowsEngine
import dev.bluefalcon.plugins.bonding.BondingPlugin
import kotlinx.coroutines.flow.first
suspend fun pairWithDiscoveredDevice() {
val engine = WindowsEngine()
val blueFalcon = BlueFalcon(engine)
val bonding = BondingPlugin.create()
blueFalcon.plugins.install(bonding)
bonding.bind(blueFalcon)
blueFalcon.scan()
val device = engine.peripherals.first { it.isNotEmpty() }.first()
blueFalcon.connect(device)
val result = bonding.requestBond(device)
println("Pairing result: $result")
}
Windows pairing uses custom pairing with encryption protection. Confirmation-only, displayed-PIN, and PIN-match requests show a Windows consent prompt; PIN-entry requests are not currently supported.
// Scan for devices with specific service UUID
val heartRateServiceUuid = kotlin.uuid.Uuid.parse("0000180d-0000-1000-8000-00805f9b34fb")
val filters = listOf(
ServiceFilter(serviceUuids = listOf(heartRateServiceUuid))
)
blueFalcon.scan(filters)
The Windows implementation supports all standard Blue Falcon APIs:
scan(filters: List<ServiceFilter> = emptyList())stopScanning()clearPeripherals()connect(bluetoothPeripheral: BluetoothPeripheral, autoConnect: Boolean = false)disconnect(bluetoothPeripheral: BluetoothPeripheral)connectionState(bluetoothPeripheral: BluetoothPeripheral): BluetoothPeripheralStateretrievePeripheral(identifier: String): BluetoothPeripheral?discoverServices(bluetoothPeripheral: BluetoothPeripheral, serviceUUIDs: List<Uuid> = emptyList())discoverCharacteristics(bluetoothPeripheral: BluetoothPeripheral, bluetoothService: BluetoothService, characteristicUUIDs: List<Uuid> = emptyList())readCharacteristic(bluetoothPeripheral: BluetoothPeripheral, bluetoothCharacteristic: BluetoothCharacteristic)writeCharacteristic(bluetoothPeripheral: BluetoothPeripheral, bluetoothCharacteristic: BluetoothCharacteristic, value: ByteArray, writeType: Int?)notifyCharacteristic(bluetoothPeripheral: BluetoothPeripheral, bluetoothCharacteristic: BluetoothCharacteristic, notify: Boolean)indicateCharacteristic(bluetoothPeripheral: BluetoothPeripheral, bluetoothCharacteristic: BluetoothCharacteristic, indicate: Boolean)readDescriptor(bluetoothPeripheral: BluetoothPeripheral, bluetoothCharacteristic: BluetoothCharacteristic, bluetoothCharacteristicDescriptor: BluetoothCharacteristicDescriptor)writeDescriptor(bluetoothPeripheral: BluetoothPeripheral, bluetoothCharacteristicDescriptor: BluetoothCharacteristicDescriptor, value: ByteArray)changeMTU(bluetoothPeripheral: BluetoothPeripheral, mtuSize: Int)supportsAdapterSelection returns true on Windowsadapters() enumerates host Bluetooth radios and exposes identifier, name, address, default status, and BLE supportselectAdapter(identifier) switches the radio Blue Falcon monitors and uses for subsequent adapter-scoped operationsXX:XX:XX:XX:XX:XXretrievePeripheral() accepts MAC address stringschangeMTU() is provided for API compatibility but Windows handles this automaticallyrequestConnectionPriority() is not directly supported on WindowsWindows 10 version 1803+ requires the following capabilities in your application manifest:
adapters() and selectAdapter() on Windows.All Bluetooth operations are asynchronous, using Kotlin coroutines on the Kotlin side and WinRT async patterns on the native side. Callbacks are marshaled back to Java/Kotlin through JNI.
didDisconnect callbacksWhen contributing to the Windows implementation: