Blue-Falcon

Kotlin Multiplatform BLE library for iOS, Android, macos, windows and javascript

View the Project on GitHub Reedyuk/blue-falcon

Blue Falcon 3.0 API Reference

Table of Contents

  1. Core API
  2. Plugin API
  3. Data Types
  4. Engine Implementations
  5. Configuration DSL
  6. Error Handling
  7. Flow and State Management

Core API

BlueFalcon

The main client class for interacting with Bluetooth Low Energy devices.

Constructor

class BlueFalcon(
    val engine: BlueFalconEngine
)

DSL Constructor

fun BlueFalcon(block: BlueFalconConfig.() -> Unit): BlueFalcon

Example:

val blueFalcon = BlueFalcon {
    engine = AndroidBlueFalconEngine(context)
    install(LoggingPlugin) { /* config */ }
}

Properties

Property Type Description
engine BlueFalconEngine Underlying platform engine
plugins PluginRegistry Installed plugins
peripherals StateFlow<Set<BluetoothPeripheral>> Discovered devices
managerState StateFlow<BluetoothManagerState> Bluetooth adapter state
isScanning Boolean Whether currently scanning

Methods

Scanning
suspend fun scan(filters: List<ServiceFilter> = emptyList())

Start scanning for BLE devices.

Parameters:

Example:

// Scan for all devices
blueFalcon.scan()

// Scan for devices with specific service
blueFalcon.scan(filters = listOf(
    ServiceFilter(Uuid("0000180D-0000-1000-8000-00805F9B34FB"))
))

suspend fun stopScanning()

Stop scanning for devices.


fun clearPeripherals()

Clear all discovered peripherals from cache.

Connection Management
suspend fun connect(
    peripheral: BluetoothPeripheral, 
    autoConnect: Boolean = false
)

Connect to a BLE peripheral.

Parameters:

Throws:

Example:

try {
    blueFalcon.connect(peripheral, autoConnect = true)
    println("Connected!")
} catch (e: BluetoothException) {
    println("Failed: ${e.message}")
}

suspend fun disconnect(peripheral: BluetoothPeripheral)

Disconnect from a peripheral.


fun connectionState(peripheral: BluetoothPeripheral): BluetoothPeripheralState

Get current connection state.

Returns: Connected, Connecting, Disconnected, Disconnecting


fun retrievePeripheral(identifier: String): BluetoothPeripheral?

Retrieve a peripheral by platform-specific identifier.

Parameters:

Returns: Peripheral if found, null otherwise


fun requestConnectionPriority(
    peripheral: BluetoothPeripheral,
    priority: ConnectionPriority
)

Request connection priority change (Android only, no-op on other platforms).

Priority levels: Balanced, High, LowPower

Service Discovery
suspend fun discoverServices(
    peripheral: BluetoothPeripheral,
    serviceUUIDs: List<Uuid> = emptyList()
)

Discover GATT services on a connected peripheral.

Parameters:

Example:

blueFalcon.connect(peripheral)
blueFalcon.discoverServices(peripheral)

peripheral.services.forEach { service ->
    println("Service: ${service.uuid}")
}

suspend fun discoverCharacteristics(
    peripheral: BluetoothPeripheral,
    service: BluetoothService,
    characteristicUUIDs: List<Uuid> = emptyList()
)

Discover characteristics for a service.

GATT Operations
suspend fun readCharacteristic(
    peripheral: BluetoothPeripheral,
    characteristic: BluetoothCharacteristic
)

Read a characteristic value. Result is stored in characteristic.value.

Example:

blueFalcon.readCharacteristic(peripheral, characteristic)
val value = characteristic.value
println("Read: ${value?.decodeToString()}")

suspend fun writeCharacteristic(
    peripheral: BluetoothPeripheral,
    characteristic: BluetoothCharacteristic,
    value: String,
    writeType: Int? = null
)

suspend fun writeCharacteristic(
    peripheral: BluetoothPeripheral,
    characteristic: BluetoothCharacteristic,
    value: ByteArray,
    writeType: Int? = null
)

Write to a characteristic.

Parameters:

Example:

// Write string
blueFalcon.writeCharacteristic(peripheral, characteristic, "Hello BLE")

// Write bytes
blueFalcon.writeCharacteristic(peripheral, characteristic, byteArrayOf(0x01, 0x02))

suspend fun notifyCharacteristic(
    peripheral: BluetoothPeripheral,
    characteristic: BluetoothCharacteristic,
    notify: Boolean
)

Enable/disable notifications for a characteristic.

Example:

// Enable notifications
blueFalcon.notifyCharacteristic(peripheral, characteristic, notify = true)

// Disable notifications
blueFalcon.notifyCharacteristic(peripheral, characteristic, notify = false)

suspend fun indicateCharacteristic(
    peripheral: BluetoothPeripheral,
    characteristic: BluetoothCharacteristic,
    indicate: Boolean
)

Enable/disable indications for a characteristic.

Descriptor Operations
suspend fun readDescriptor(
    peripheral: BluetoothPeripheral,
    characteristic: BluetoothCharacteristic,
    descriptor: BluetoothCharacteristicDescriptor
)

Read a characteristic descriptor.


suspend fun writeDescriptor(
    peripheral: BluetoothPeripheral,
    descriptor: BluetoothCharacteristicDescriptor,
    value: ByteArray
)

Write to a characteristic descriptor.

Advanced Operations
suspend fun changeMTU(peripheral: BluetoothPeripheral, mtuSize: Int)

Request MTU (Maximum Transmission Unit) size change.


fun refreshGattCache(peripheral: BluetoothPeripheral): Boolean

Refresh GATT cache (Android only).


suspend fun openL2capChannel(peripheral: BluetoothPeripheral, psm: Int)

Open L2CAP channel (platform-dependent).


suspend fun createBond(peripheral: BluetoothPeripheral)

Create a bond (pair) with the peripheral.


suspend fun removeBond(peripheral: BluetoothPeripheral)

Remove bond (unpair) with the peripheral.


Plugin API

BlueFalconPlugin

Base interface for creating plugins.

interface BlueFalconPlugin {
    fun install(client: BlueFalconClient, config: PluginConfig)
    
    suspend fun onBeforeScan(call: ScanCall): ScanCall = call
    suspend fun onAfterScan(call: ScanCall) {}
    
    suspend fun onBeforeConnect(call: ConnectCall): ConnectCall = call
    suspend fun onAfterConnect(call: ConnectCall, result: Result<Unit>) {}
    
    suspend fun onBeforeRead(call: ReadCall): ReadCall = call
    suspend fun onAfterRead(call: ReadCall, result: Result<ByteArray?>) {}
    
    suspend fun onBeforeWrite(call: WriteCall): WriteCall = call
    suspend fun onAfterWrite(call: WriteCall, result: Result<Unit>) {}
}

Hook Methods:

Method Description When Called
install() Plugin initialization Once on installation
onBeforeScan() Intercept scan Before scan starts
onAfterScan() Post-scan hook After scan completes
onBeforeConnect() Intercept connect Before connection attempt
onAfterConnect() Post-connect hook After connection result
onBeforeRead() Intercept read Before reading characteristic
onAfterRead() Post-read hook After read completes
onBeforeWrite() Intercept write Before writing characteristic
onAfterWrite() Post-write hook After write completes

Example:

class MyPlugin : BlueFalconPlugin {
    override fun install(client: BlueFalconClient, config: PluginConfig) {
        println("Plugin installed")
    }
    
    override suspend fun onBeforeRead(call: ReadCall): ReadCall {
        println("About to read ${call.characteristic.uuid}")
        return call
    }
    
    override suspend fun onAfterRead(call: ReadCall, result: Result<ByteArray?>) {
        result.onSuccess { data ->
            println("Read ${data?.size ?: 0} bytes")
        }
    }
}

PluginRegistry

Manages installed plugins.

class PluginRegistry {
    fun install(plugin: BlueFalconPlugin, configure: PluginConfig.() -> Unit = {})
    fun uninstall(plugin: BlueFalconPlugin)
}

Example:

val plugins = blueFalcon.plugins

// Install a plugin
plugins.install(LoggingPlugin(LoggingPlugin.Config()))

// Uninstall a plugin
plugins.uninstall(loggingPlugin)

PluginConfig

Base class for plugin configurations.

open class PluginConfig

Example:

class MyPluginConfig : PluginConfig() {
    var enabled: Boolean = true
    var timeout: Duration = 5.seconds
}

Operation Call Types

ScanCall

data class ScanCall(val filters: List<ServiceFilter>)

ConnectCall

data class ConnectCall(
    val peripheral: BluetoothPeripheral,
    val autoConnect: Boolean
)

ReadCall

data class ReadCall(
    val peripheral: BluetoothPeripheral,
    val characteristic: BluetoothCharacteristic
)

WriteCall

data class WriteCall(
    val peripheral: BluetoothPeripheral,
    val characteristic: BluetoothCharacteristic,
    val value: ByteArray,
    val writeType: Int?
)

Data Types

BluetoothPeripheral

Represents a BLE device.

interface BluetoothPeripheral {
    val name: String?                          // Device name
    val uuid: String                           // Platform-specific ID
    val rssi: Float?                           // Signal strength (dBm)
    val mtuSize: Int?                          // MTU size
    val services: List<BluetoothService>       // GATT services
    val characteristics: List<BluetoothCharacteristic>
}

Example:

blueFalcon.peripherals.collect { devices ->
    devices.forEach { device ->
        println("${device.name} (${device.uuid})")
        println("RSSI: ${device.rssi} dBm")
    }
}

BluetoothService

Represents a GATT service.

interface BluetoothService {
    val uuid: Uuid                              // Service UUID
    val name: String?                           // Human-readable name
    val characteristics: List<BluetoothCharacteristic>
}

Example:

peripheral.services.forEach { service ->
    println("Service: ${service.uuid}")
    service.characteristics.forEach { char ->
        println("  Characteristic: ${char.uuid}")
    }
}

BluetoothCharacteristic

Represents a GATT characteristic.

interface BluetoothCharacteristic {
    val uuid: Uuid                              // Characteristic UUID
    val name: String?                           // Human-readable name
    val value: ByteArray?                       // Current value
    val descriptors: List<BluetoothCharacteristicDescriptor>
    val isNotifying: Boolean                    // Notifications enabled?
    val service: BluetoothService?              // Parent service
}

Example:

blueFalcon.readCharacteristic(peripheral, characteristic)
val text = characteristic.value?.decodeToString()
println("Value: $text")

BluetoothCharacteristicDescriptor

Represents a GATT descriptor.

interface BluetoothCharacteristicDescriptor {
    val uuid: Uuid                              // Descriptor UUID
    val name: String?                           // Human-readable name
    val value: ByteArray?                       // Current value
    val characteristic: BluetoothCharacteristic? // Parent characteristic
}

Uuid

UUID wrapper for BLE UUIDs.

class Uuid(val value: String) {
    override fun toString(): String = value
}

Common UUIDs:

// Standard service UUIDs
val HEART_RATE_SERVICE = Uuid("0000180D-0000-1000-8000-00805F9B34FB")
val BATTERY_SERVICE = Uuid("0000180F-0000-1000-8000-00805F9B34FB")
val DEVICE_INFO = Uuid("0000180A-0000-1000-8000-00805F9B34FB")

// Standard characteristic UUIDs
val HEART_RATE_MEASUREMENT = Uuid("00002A37-0000-1000-8000-00805F9B34FB")
val BATTERY_LEVEL = Uuid("00002A19-0000-1000-8000-00805F9B34FB")

ServiceFilter

Filter for scanning operations.

class ServiceFilter(val uuid: Uuid)

Example:

val heartRateFilter = ServiceFilter(
    Uuid("0000180D-0000-1000-8000-00805F9B34FB")
)

blueFalcon.scan(filters = listOf(heartRateFilter))

BluetoothPeripheralState

Connection state enum.

enum class BluetoothPeripheralState {
    Connected,
    Connecting,
    Disconnected,
    Disconnecting
}

BluetoothManagerState

Bluetooth adapter state.

enum class BluetoothManagerState {
    Unknown,
    Resetting,
    Unsupported,
    Unauthorized,
    PoweredOff,
    PoweredOn
}

ConnectionPriority

Connection priority levels (Android).

enum class ConnectionPriority {
    Balanced,
    High,
    LowPower
}

Engine Implementations

BlueFalconEngine

Core interface that all platform engines implement.

interface BlueFalconEngine {
    val scope: CoroutineScope
    val peripherals: StateFlow<Set<BluetoothPeripheral>>
    val managerState: StateFlow<BluetoothManagerState>
    val isScanning: Boolean
    
    suspend fun scan(filters: List<ServiceFilter> = emptyList())
    suspend fun stopScanning()
    // ... all BlueFalcon methods
}

Platform Engines

Android

class AndroidBlueFalconEngine(
    context: Context,
    autoDiscoverServices: Boolean = true
) : BlueFalconEngine

Dependencies:

androidMain.dependencies {
    implementation("dev.bluefalcon:blue-falcon-engine-android:3.0.0")
}

Example:

val engine = AndroidBlueFalconEngine(
    context = applicationContext,
    autoDiscoverServices = true
)

iOS

class IosBlueFalconEngine : BlueFalconEngine

Dependencies:

iosMain.dependencies {
    implementation("dev.bluefalcon:blue-falcon-engine-ios:3.0.0")
}

Example:

val engine = IosBlueFalconEngine()

macOS

class MacOSBlueFalconEngine : BlueFalconEngine

Dependencies:

macosMain.dependencies {
    implementation("dev.bluefalcon:blue-falcon-engine-macos:3.0.0")
}

JavaScript (Web Bluetooth)

class JsBlueFalconEngine : BlueFalconEngine

Dependencies:

jsMain.dependencies {
    implementation("dev.bluefalcon:blue-falcon-engine-js:3.0.0")
}

Browser support: Chrome, Edge, Opera

Windows

class WindowsBlueFalconEngine : BlueFalconEngine

Dependencies:

windowsMain.dependencies {
    implementation("dev.bluefalcon:blue-falcon-engine-windows:3.0.0")
}

Requirements: Windows 10 version 1803+

Raspberry Pi

class RpiBlueFalconEngine : BlueFalconEngine

Dependencies:

rpiMain.dependencies {
    implementation("dev.bluefalcon:blue-falcon-engine-rpi:3.0.0")
}

Configuration DSL

BlueFalconConfig

Configuration builder for DSL-based initialization.

class BlueFalconConfig {
    lateinit var engine: BlueFalconEngine
    
    fun <T : BlueFalconPlugin> install(
        plugin: T, 
        configure: PluginConfig.() -> Unit = {}
    )
}

Example:

val blueFalcon = BlueFalcon {
    engine = AndroidBlueFalconEngine(context)
    
    install(LoggingPlugin) {
        level = LogLevel.DEBUG
        logger = PrintLnLogger
    }
    
    install(RetryPlugin) {
        maxRetries = 3
        initialDelay = 500.milliseconds
    }
}

Error Handling

Exception Hierarchy

sealed class BluetoothException : Exception()

class BluetoothUnknownException : BluetoothException()
class BluetoothResettingException : BluetoothException()
class BluetoothUnsupportedException : BluetoothException()
class BluetoothPermissionException : BluetoothException()
class BluetoothNotEnabledException : BluetoothException()

Handling Errors

try {
    blueFalcon.connect(peripheral)
} catch (e: BluetoothPermissionException) {
    // Request permissions
} catch (e: BluetoothNotEnabledException) {
    // Prompt user to enable Bluetooth
} catch (e: BluetoothException) {
    // Handle other BLE errors
}

Result Type

Plugin hooks receive Result<T> for operations:

override suspend fun onAfterConnect(call: ConnectCall, result: Result<Unit>) {
    result.fold(
        onSuccess = { println("Connected!") },
        onFailure = { error -> println("Failed: $error") }
    )
}

Flow and State Management

StateFlow for Peripherals

val peripherals: StateFlow<Set<BluetoothPeripheral>>

Example:

lifecycleScope.launch {
    blueFalcon.peripherals.collect { devices ->
        println("Found ${devices.size} devices")
        updateUI(devices)
    }
}

StateFlow for Bluetooth State

val managerState: StateFlow<BluetoothManagerState>

Example:

lifecycleScope.launch {
    blueFalcon.managerState.collect { state ->
        when (state) {
            BluetoothManagerState.PoweredOn -> startScanning()
            BluetoothManagerState.PoweredOff -> showBluetoothDisabledMessage()
            BluetoothManagerState.Unauthorized -> requestPermissions()
            else -> {}
        }
    }
}

Combining Flows

lifecycleScope.launch {
    combine(
        blueFalcon.peripherals,
        blueFalcon.managerState
    ) { devices, state ->
        Pair(devices, state)
    }.collect { (devices, state) ->
        if (state == BluetoothManagerState.PoweredOn) {
            updateDeviceList(devices)
        }
    }
}

Quick Reference

Common Operations

// Initialize
val blueFalcon = BlueFalcon {
    engine = AndroidBlueFalconEngine(context)
}

// Scan
blueFalcon.scan()

// Monitor discovered devices
blueFalcon.peripherals.collect { devices -> }

// Connect
blueFalcon.connect(peripheral)

// Discover services
blueFalcon.discoverServices(peripheral)

// Read characteristic
blueFalcon.readCharacteristic(peripheral, characteristic)
val value = characteristic.value

// Write characteristic
blueFalcon.writeCharacteristic(peripheral, characteristic, "data")

// Enable notifications
blueFalcon.notifyCharacteristic(peripheral, characteristic, true)

// Disconnect
blueFalcon.disconnect(peripheral)

Platform-Specific Setup

Platform Engine Context Required
Android AndroidBlueFalconEngine ✅ Android Context
iOS IosBlueFalconEngine ❌ None
macOS MacOSBlueFalconEngine ❌ None
JavaScript JsBlueFalconEngine ❌ None
Windows WindowsBlueFalconEngine ❌ None
Raspberry Pi RpiBlueFalconEngine ❌ None

Further Reading


Need help? Open an issue on GitHub or check the examples in the examples/ directory.