iosMain.dev.bluefalcon.BlueFalcon.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of blue-falcon Show documentation
Show all versions of blue-falcon Show documentation
Bluetooth Multiplatform Library
package dev.bluefalcon
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import platform.CoreBluetooth.*
import platform.Foundation.*
import platform.darwin.NSObject
expect class BluetoothPeripheralManager(blueFalcon: BlueFalcon): CBCentralManagerDelegateProtocol, NSObject
expect class PeripheralDelegate(blueFalcon: BlueFalcon)
actual class BlueFalcon actual constructor(
private val context: ApplicationContext,
private val serviceUUID: String?
) {
actual val delegates: MutableSet = mutableSetOf()
private val centralManager: CBCentralManager
private val bluetoothPeripheralManager = BluetoothPeripheralManager(this)
actual var isScanning: Boolean = false
actual val scope = CoroutineScope(Dispatchers.Default)
internal actual val _peripherals = MutableStateFlow>(emptySet())
actual val peripherals: NativeFlow> = _peripherals.toNativeType(scope)
init {
centralManager = CBCentralManager(bluetoothPeripheralManager, null)
}
actual fun connect(bluetoothPeripheral: BluetoothPeripheral, autoConnect: Boolean) {
//auto connect is ignored due to not needing it in iOS
centralManager.connectPeripheral(bluetoothPeripheral.bluetoothDevice, null)
}
actual fun disconnect(bluetoothPeripheral: BluetoothPeripheral) {
centralManager.cancelPeripheralConnection(bluetoothPeripheral.bluetoothDevice)
}
@Throws(
BluetoothUnknownException::class,
BluetoothResettingException::class,
BluetoothUnsupportedException::class,
BluetoothPermissionException::class,
BluetoothNotEnabledException::class
)
actual fun scan() {
isScanning = true
when (centralManager.state) {
CBManagerStateUnknown -> throw BluetoothUnknownException()
CBManagerStateResetting -> throw BluetoothResettingException()
CBManagerStateUnsupported -> throw BluetoothUnsupportedException()
CBManagerStateUnauthorized -> throw BluetoothPermissionException()
CBManagerStatePoweredOff -> throw BluetoothNotEnabledException()
CBManagerStatePoweredOn -> {
if (serviceUUID != null) {
val serviceCBUUID = CBUUID.UUIDWithString(serviceUUID)
centralManager.scanForPeripheralsWithServices(listOf(serviceCBUUID), mapOf(CBCentralManagerScanOptionAllowDuplicatesKey to true) )
} else {
centralManager.scanForPeripheralsWithServices(null, mapOf(CBCentralManagerScanOptionAllowDuplicatesKey to true) )
}
}
}
}
actual fun stopScanning() {
isScanning = false
centralManager.stopScan()
}
actual fun readCharacteristic(
bluetoothPeripheral: BluetoothPeripheral,
bluetoothCharacteristic: BluetoothCharacteristic
) {
bluetoothPeripheral.bluetoothDevice.readValueForCharacteristic(bluetoothCharacteristic.characteristic)
}
actual fun notifyCharacteristic(
bluetoothPeripheral: BluetoothPeripheral,
bluetoothCharacteristic: BluetoothCharacteristic,
notify: Boolean
) {
bluetoothPeripheral.bluetoothDevice.setNotifyValue(notify, bluetoothCharacteristic.characteristic)
}
actual fun indicateCharacteristic(
bluetoothPeripheral: BluetoothPeripheral,
bluetoothCharacteristic: BluetoothCharacteristic,
indicate: Boolean
) {
notifyCharacteristic(bluetoothPeripheral, bluetoothCharacteristic, indicate)
}
actual fun notifyAndIndicateCharacteristic(
bluetoothPeripheral: BluetoothPeripheral,
bluetoothCharacteristic: BluetoothCharacteristic,
enable: Boolean
) {
notifyCharacteristic(bluetoothPeripheral, bluetoothCharacteristic, enable)
}
actual fun writeCharacteristic(
bluetoothPeripheral: BluetoothPeripheral,
bluetoothCharacteristic: BluetoothCharacteristic,
value: String,
writeType: Int?
) {
sharedWriteCharacteristic(
bluetoothPeripheral,
bluetoothCharacteristic,
NSString.create(string = value),
writeType
)
}
actual fun writeCharacteristic(
bluetoothPeripheral: BluetoothPeripheral,
bluetoothCharacteristic: BluetoothCharacteristic,
value: ByteArray,
writeType: Int?
) {
sharedWriteCharacteristic(
bluetoothPeripheral,
bluetoothCharacteristic,
NSString.create(string = value.decodeToString()),
writeType
)
}
actual fun writeCharacteristicWithoutEncoding(
bluetoothPeripheral: BluetoothPeripheral,
bluetoothCharacteristic: BluetoothCharacteristic,
value: ByteArray,
writeType: Int?
) {
sharedWriteCharacteristic(
bluetoothPeripheral,
bluetoothCharacteristic,
value.toData(),
writeType
)
}
private fun sharedWriteCharacteristic(
bluetoothPeripheral: BluetoothPeripheral,
bluetoothCharacteristic: BluetoothCharacteristic,
value: NSString,
writeType: Int?
) {
value.dataUsingEncoding(NSUTF8StringEncoding)?.let {
sharedWriteCharacteristic(
bluetoothPeripheral,
bluetoothCharacteristic,
it,
writeType
)
}
}
private fun sharedWriteCharacteristic(
bluetoothPeripheral: BluetoothPeripheral,
bluetoothCharacteristic: BluetoothCharacteristic,
value: NSData,
writeType: Int?
) {
bluetoothPeripheral.bluetoothDevice.writeValue(
value,
bluetoothCharacteristic.characteristic,
when (writeType) {
1 -> CBCharacteristicWriteWithoutResponse
else -> CBCharacteristicWriteWithResponse
}
)
}
actual fun readDescriptor(
bluetoothPeripheral: BluetoothPeripheral,
bluetoothCharacteristic: BluetoothCharacteristic,
bluetoothCharacteristicDescriptor: BluetoothCharacteristicDescriptor
) {
bluetoothPeripheral.bluetoothDevice.discoverDescriptorsForCharacteristic(bluetoothCharacteristic.characteristic)
}
actual fun changeMTU(bluetoothPeripheral: BluetoothPeripheral, mtuSize: Int) {
println("Change MTU size called but not needed.")
delegates.forEach {
it.didUpdateMTU(bluetoothPeripheral)
}
}
}