From 653c2068e70b802810e2810a5327af67b0a35329 Mon Sep 17 00:00:00 2001 From: "severin.memmishofer" Date: Fri, 14 Jul 2023 16:08:05 +0200 Subject: [PATCH] Bluetooth now correctly transmits the WANT-Vector and it gets displayed on the other device --- RippleChat/BTPeripheral.swift | 41 ++++++++++++++++++--- RippleChat/BluetoothController.swift | 54 +++++++++++++++++++++++++--- RippleChat/Views/PeeringView.swift | 9 +++-- 3 files changed, 92 insertions(+), 12 deletions(-) diff --git a/RippleChat/BTPeripheral.swift b/RippleChat/BTPeripheral.swift index ba0d0ec..5babc0e 100644 --- a/RippleChat/BTPeripheral.swift +++ b/RippleChat/BTPeripheral.swift @@ -44,28 +44,61 @@ extension BluetoothPeripheral: CBPeripheralManagerDelegate { } func addBTService() { - let myCharacteristic = CBMutableCharacteristic(type: BLE_CHARACTERISTIC_UUID_RX, properties: [.read, .write, .notify], value: nil, permissions: [.readable, .writeable]) + let myCharacteristic = CBMutableCharacteristic(type: BLE_CHARACTERISTIC_UUID_RX, properties: [.read, .write, .notify, .writeWithoutResponse], value: nil, permissions: [.readable, .writeable]) let myService = CBMutableService(type: BLE_SERVICE_UUID, primary: true) myService.characteristics = [myCharacteristic] peripheralManager!.add(myService) + } + + func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) { peripheralManager!.startAdvertising([CBAdvertisementDataLocalNameKey : "RippleChat", CBAdvertisementDataServiceUUIDsKey: [BLE_SERVICE_UUID]]) print("Started Advertising") - + if(peripheralManager?.delegate == nil) { + print("peripheral is nil") + } else { + print("peripheral is not nil") + } } + func discoverServices(_ serviceUUIDs: [CBUUID]?) { + print("test Peripheral") + print("Discovering services... \(String(describing: serviceUUIDs))") + } + + func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { + print("Discovering Services Peripheral") +// print("*******************************************************") +// +// if ((error) != nil) { +// print("Error discovering services: \(error!.localizedDescription)") +// return +// } +// guard let services = peripheral.services else { +// return +// } +// //We need to discover the all characteristic +// for service in services { +// peripheral.discoverCharacteristics(nil, for: service) +// } +// print("Discovered Services: \(services)") + } + func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) { for request in requests { if let value = request.value { // Handle the received data let receivedData = Data(value) + print(receivedData) + // Decode the received JSON string into your data structure let decoder = JSONDecoder() do { - let receivedObject = try decoder.decode(String.self, from: receivedData) + let receivedObject = try decoder.decode(WantMessage.self, from: receivedData) // Use the received object to update your app state as needed print("Received Write") - self.incomingMsg = receivedObject + self.incomingMsg = receivedObject.printMsg() + print(receivedObject.printMsg()) } catch { print("Failed to decode JSON: \(error)") } diff --git a/RippleChat/BluetoothController.swift b/RippleChat/BluetoothController.swift index bab3561..ba5a0d1 100644 --- a/RippleChat/BluetoothController.swift +++ b/RippleChat/BluetoothController.swift @@ -22,23 +22,60 @@ class BluetoothController: NSObject, ObservableObject { super.init() self.centralManager = CBCentralManager(delegate: self, queue: .main) } + +// func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { +// } } -extension BluetoothController: CBCentralManagerDelegate { +extension BluetoothController: CBCentralManagerDelegate, CBPeripheralDelegate { + func centralManagerDidUpdateState(_ central: CBCentralManager) { if central.state == .poweredOn { + print("Device is powered on...") self.centralManager?.scanForPeripherals(withServices: [BLE_SERVICE_UUID]) } } func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { if !peripherals.contains(peripheral) { - centralManager?.connect(peripheral) + peripheral.delegate = self + centralManager!.connect(peripheral) self.peripherals.append(peripheral) self.peripheralNames.append(peripheral.name ?? "unnamed device") } } + func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { + peripheral.discoverServices([BLE_SERVICE_UUID]) + print("Connected to device \(String(describing: peripheral.name))") + if(centralManager?.delegate == nil) { + print("central is nil") + } else { + print("central is not nil") + } + } + +// func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { +// print("Discovering services...") +// peripheral.discoverCharacteristics(BLE_CHARACTERISTIC_UUID_RX) +// } + + func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { + print("*******************************************************") + + if ((error) != nil) { + print("Error discovering services: \(error!.localizedDescription)") + return + } + guard let services = peripheral.services else { + return + } + //We need to discover the all characteristic + for service in services { + peripheral.discoverCharacteristics(nil, for: service) + } + print("Discovered Services: \(services)") + } func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { guard let characteristics = service.characteristics else { @@ -47,12 +84,19 @@ extension BluetoothController: CBCentralManagerDelegate { } for characteristic in characteristics { - if characteristic.properties.contains(.write) || characteristic.properties.contains(.writeWithoutResponse) { - // This characteristic supports writing - writeCharacteristics.append(characteristic) + if characteristic.uuid.isEqual(BLE_CHARACTERISTIC_UUID_RX) { + self.writeCharacteristics.append(characteristic) + peripheral.setNotifyValue(true, for: characteristic) + peripheral.readValue(for: characteristic) + print("Characteristic: \(characteristic.uuid)") } } } + + func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { + print("updating characteristic value...") + print(characteristic.value ?? "Characteristic is nil") + } func writeToCharacteristics(message: String) { guard let messageData = message.data(using: .utf8) else { diff --git a/RippleChat/Views/PeeringView.swift b/RippleChat/Views/PeeringView.swift index f332470..421d70c 100644 --- a/RippleChat/Views/PeeringView.swift +++ b/RippleChat/Views/PeeringView.swift @@ -24,8 +24,8 @@ struct PeeringView: View { do { let WANT_msg = WantMessage(friends: dataStore.friends) let encoded_msg = try JSONEncoder().encode(WANT_msg) - //btController.writeToCharacteristics(message: String(data: encoded_msg, encoding: .utf8)!) - btController.writeToCharacteristics(message: "Test") + btController.writeToCharacteristics(message: String(data: encoded_msg, encoding: .utf8)!) + //btController.writeToCharacteristics(message: "Test") print("Pressed Button") } catch { fatalError(error.localizedDescription) @@ -47,7 +47,10 @@ struct PeeringView_Previews: PreviewProvider { } struct WantMessage: Codable { - var commmand = "WANT" + var command = "WANT" var friends = [String:Int]() + func printMsg() -> String { + return ("\(command) : \(friends.description)") + } }