feat: Writes to characteristic
This commit is contained in:
@@ -1,8 +1,14 @@
|
||||
import SwiftUI
|
||||
import CoreBluetooth
|
||||
|
||||
struct Constants {
|
||||
static let scbtSvcUuid = "00010F2C-DEAD-BEEF-A455-DEAD69BEEF69";
|
||||
static let scbtPetUuid: String = "00010F2D-DEAD-BEEF-A455-DEAD69BEEF69";
|
||||
}
|
||||
|
||||
final class BluetoothManager: NSObject, ObservableObject {
|
||||
private var periphManager: CBPeripheralManager!
|
||||
private var centralManager: CBCentralManager!
|
||||
private var myPeripheral: CBPeripheral?
|
||||
@Published var status = "Starting..."
|
||||
|
||||
override init() {
|
||||
@@ -11,22 +17,135 @@ final class BluetoothManager: NSObject, ObservableObject {
|
||||
}
|
||||
}
|
||||
|
||||
extension BluetoothManager: CBPeripheralManagerDelegate {
|
||||
func peripheralManagerDidUpdateState(_ central: CBPeripheralManager) {
|
||||
switch central.state {
|
||||
case .poweredOn:
|
||||
status = "Broadcasting"
|
||||
let uuid = CBUUID(string: "12345678-1234-1234-1234-123456789ABC")
|
||||
periphManager.startAdvertising(
|
||||
[
|
||||
CBAdvertisementDataServiceUUIDsKey: [uuid],
|
||||
CBAdvertisementDataLocalNameKey: "scbt-Test"
|
||||
])
|
||||
case .poweredOff:
|
||||
status = "Bluetooth off"
|
||||
extension BluetoothManager: CBCentralManagerDelegate, CBPeripheralDelegate {
|
||||
func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
||||
guard central.state == .poweredOn else {
|
||||
status = "Bluetooth OFF"
|
||||
return
|
||||
}
|
||||
|
||||
default:
|
||||
status = "Bluetooth unavailable"
|
||||
let uuid = CBUUID(string: Constants.scbtSvcUuid)
|
||||
centralManager.scanForPeripherals(
|
||||
withServices: [uuid],
|
||||
options: [
|
||||
CBCentralManagerScanOptionAllowDuplicatesKey: false
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
// Discovery callback
|
||||
func centralManager(
|
||||
_ central: CBCentralManager,
|
||||
didDiscover peripheral: CBPeripheral,
|
||||
advertisementData: [String: Any],
|
||||
rssi RSSI: NSNumber
|
||||
) {
|
||||
if (peripheral.name != nil) {
|
||||
status = "Found: \(peripheral.name!)"
|
||||
} else {
|
||||
status = "Found: \(peripheral.identifier)"
|
||||
}
|
||||
|
||||
myPeripheral = peripheral
|
||||
central.stopScan()
|
||||
central.connect(peripheral)
|
||||
}
|
||||
|
||||
// Connection callback
|
||||
func centralManager(
|
||||
_ central: CBCentralManager,
|
||||
didConnect peripheral: CBPeripheral
|
||||
) {
|
||||
status = "Connected"
|
||||
let uuid = CBUUID(string: Constants.scbtSvcUuid)
|
||||
peripheral.discoverServices([uuid])
|
||||
peripheral.delegate = self
|
||||
}
|
||||
|
||||
// Connection failure callback
|
||||
func centralManager(
|
||||
_ central: CBCentralManager,
|
||||
didFailToConnect peripheral: CBPeripheral,
|
||||
error: Error?
|
||||
) {
|
||||
let error2: String
|
||||
if (error == nil) { error2 = "unknown" }
|
||||
else { error2 = "\(error!)" }
|
||||
status = "Failed: \(error2)"
|
||||
}
|
||||
|
||||
// Disconnection callback
|
||||
func centralManager(
|
||||
_ central: CBCentralManager,
|
||||
didDisconnectPeripheral peripheral: CBPeripheral,
|
||||
error: Error?
|
||||
) {
|
||||
let error2: String
|
||||
if (error == nil) { error2 = "unknown" }
|
||||
else { error2 = "\(error!)" }
|
||||
status = "Disconnected: \(error2)"
|
||||
}
|
||||
|
||||
// Service callback
|
||||
func peripheral(
|
||||
_ peripheral: CBPeripheral,
|
||||
didDiscoverServices error: Error?
|
||||
) {
|
||||
guard let services = peripheral.services else { return }
|
||||
|
||||
status = "Service found"
|
||||
|
||||
let scbtSvc = CBUUID(string: Constants.scbtSvcUuid)
|
||||
let scbtPet = CBUUID(string: Constants.scbtPetUuid)
|
||||
|
||||
for service in services {
|
||||
// Ignore non scbtSvc
|
||||
if (service.uuid != scbtSvc) { continue }
|
||||
|
||||
peripheral.discoverCharacteristics([scbtPet], for: service)
|
||||
}
|
||||
}
|
||||
|
||||
// Characteristic callback
|
||||
func peripheral(
|
||||
_ perihperal: CBPeripheral,
|
||||
didDiscoverCharacteristicsFor service: CBService,
|
||||
error: Error?
|
||||
) {
|
||||
if (error != nil) {
|
||||
status = "\(error!)"
|
||||
return
|
||||
}
|
||||
|
||||
guard let characteristics = service.characteristics else { return }
|
||||
|
||||
status = "Characteristics found (\(characteristics.count))"
|
||||
|
||||
let scbtPet = CBUUID(string: Constants.scbtPetUuid)
|
||||
|
||||
for characteristic in characteristics {
|
||||
// Ignore non pet
|
||||
if (characteristic.uuid != scbtPet) { continue }
|
||||
|
||||
var value: UInt32 = 0
|
||||
let data = Data(bytes: &value, count: MemoryLayout<UInt32>.size)
|
||||
|
||||
perihperal.writeValue(data, for: characteristic, type: .withResponse)
|
||||
status = "Written \(data)"
|
||||
}
|
||||
}
|
||||
|
||||
// Characteristic write callback
|
||||
func peripheral(
|
||||
_ perihperal: CBPeripheral,
|
||||
didWriteValueFor characteristic: CBCharacteristic,
|
||||
error: (any Error)?
|
||||
) {
|
||||
if (error == nil) {
|
||||
status = "Write success"
|
||||
}
|
||||
else {
|
||||
status = "Write failed: \(error!)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user