Add more Bluetooth debugging and disable scan duty cycling

- Add better state descriptions for both central and peripheral managers
- Add logging when setting up peripheral and adding service
- Temporarily disable scan duty cycling to ensure continuous scanning
- Add service UUID logging during peripheral setup

This should help identify:
1. Why Mac shows 'unsupported' state for Bluetooth
2. Whether services are being added successfully
3. If advertising is actually starting
This commit is contained in:
jack
2025-07-10 12:39:58 +02:00
parent d111a9537f
commit 7e78d0fe87
+65 -7
View File
@@ -80,8 +80,8 @@ class BluetoothMeshService: NSObject {
// Battery and range optimizations // Battery and range optimizations
private var scanDutyCycleTimer: Timer? private var scanDutyCycleTimer: Timer?
private var isActivelyScanning = true private var isActivelyScanning = true
private var activeScanDuration: TimeInterval = 2.0 // Scan actively for 2 seconds - will be adjusted based on battery private var activeScanDuration: TimeInterval = 10.0 // Increased to 10 seconds for debugging - will be adjusted based on battery
private var scanPauseDuration: TimeInterval = 3.0 // Pause for 3 seconds - will be adjusted based on battery private var scanPauseDuration: TimeInterval = 2.0 // Reduced to 2 seconds for debugging - will be adjusted based on battery
private var lastRSSIUpdate: [String: Date] = [:] // Throttle RSSI updates private var lastRSSIUpdate: [String: Date] = [:] // Throttle RSSI updates
private var batteryMonitorTimer: Timer? private var batteryMonitorTimer: Timer?
private var currentBatteryLevel: Float = 1.0 // Default to full battery private var currentBatteryLevel: Float = 1.0 // Default to full battery
@@ -422,7 +422,9 @@ class BluetoothMeshService: NSObject {
} }
func startAdvertising() { func startAdvertising() {
print("[BLUETOOTH DEBUG] startAdvertising called, peripheral state: \(peripheralManager?.state.rawValue ?? -1)")
guard peripheralManager?.state == .poweredOn else { guard peripheralManager?.state == .poweredOn else {
print("[BLUETOOTH DEBUG] Cannot start advertising, peripheral not powered on")
return return
} }
@@ -436,6 +438,7 @@ class BluetoothMeshService: NSObject {
CBAdvertisementDataLocalNameKey: myPeerID CBAdvertisementDataLocalNameKey: myPeerID
] ]
print("[BLUETOOTH DEBUG] Starting advertising with service UUID: \(BluetoothMeshService.serviceUUID), peerID: \(myPeerID)")
isAdvertising = true isAdvertising = true
peripheralManager?.startAdvertising(advertisementData) peripheralManager?.startAdvertising(advertisementData)
} }
@@ -452,16 +455,19 @@ class BluetoothMeshService: NSObject {
CBCentralManagerScanOptionAllowDuplicatesKey: true CBCentralManagerScanOptionAllowDuplicatesKey: true
] ]
print("[BLUETOOTH DEBUG] Starting scan for peripherals with service UUID: \(BluetoothMeshService.serviceUUID)")
centralManager?.scanForPeripherals( centralManager?.scanForPeripherals(
withServices: [BluetoothMeshService.serviceUUID], withServices: [BluetoothMeshService.serviceUUID],
options: scanOptions options: scanOptions
) )
print("[BLUETOOTH DEBUG] Scan started successfully")
// Update scan parameters based on battery before starting // Update scan parameters based on battery before starting
updateScanParametersForBattery() updateScanParametersForBattery()
// Implement scan duty cycling for battery efficiency // Implement scan duty cycling for battery efficiency
scheduleScanDutyCycle() // TEMPORARILY DISABLED FOR DEBUGGING
// scheduleScanDutyCycle()
} }
private func scheduleScanDutyCycle() { private func scheduleScanDutyCycle() {
@@ -475,6 +481,7 @@ class BluetoothMeshService: NSObject {
if self.isActivelyScanning { if self.isActivelyScanning {
// Pause scanning to save battery // Pause scanning to save battery
print("[BLUETOOTH DEBUG] Pausing scan after \(self.activeScanDuration) seconds")
self.centralManager?.stopScan() self.centralManager?.stopScan()
self.isActivelyScanning = false self.isActivelyScanning = false
@@ -482,6 +489,7 @@ class BluetoothMeshService: NSObject {
DispatchQueue.main.asyncAfter(deadline: .now() + self.scanPauseDuration) { [weak self] in DispatchQueue.main.asyncAfter(deadline: .now() + self.scanPauseDuration) { [weak self] in
guard let self = self else { return } guard let self = self else { return }
if self.centralManager?.state == .poweredOn { if self.centralManager?.state == .poweredOn {
print("[BLUETOOTH DEBUG] Resuming scan after \(self.scanPauseDuration) seconds pause")
self.centralManager?.scanForPeripherals( self.centralManager?.scanForPeripherals(
withServices: [BluetoothMeshService.serviceUUID], withServices: [BluetoothMeshService.serviceUUID],
options: [CBCentralManagerScanOptionAllowDuplicatesKey: true] options: [CBCentralManagerScanOptionAllowDuplicatesKey: true]
@@ -494,6 +502,7 @@ class BluetoothMeshService: NSObject {
} }
private func setupPeripheral() { private func setupPeripheral() {
print("[BLUETOOTH DEBUG] Setting up peripheral with service UUID: \(BluetoothMeshService.serviceUUID)")
let characteristic = CBMutableCharacteristic( let characteristic = CBMutableCharacteristic(
type: BluetoothMeshService.characteristicUUID, type: BluetoothMeshService.characteristicUUID,
properties: [.read, .write, .writeWithoutResponse, .notify], properties: [.read, .write, .writeWithoutResponse, .notify],
@@ -504,6 +513,7 @@ class BluetoothMeshService: NSObject {
let service = CBMutableService(type: BluetoothMeshService.serviceUUID, primary: true) let service = CBMutableService(type: BluetoothMeshService.serviceUUID, primary: true)
service.characteristics = [characteristic] service.characteristics = [characteristic]
print("[BLUETOOTH DEBUG] Adding service to peripheral manager")
peripheralManager?.add(service) peripheralManager?.add(service)
self.characteristic = characteristic self.characteristic = characteristic
} }
@@ -2256,8 +2266,26 @@ class BluetoothMeshService: NSObject {
extension BluetoothMeshService: CBCentralManagerDelegate { extension BluetoothMeshService: CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) { func centralManagerDidUpdateState(_ central: CBCentralManager) {
// Central manager state updated // Central manager state updated
print("[BLUETOOTH DEBUG] Central manager state changed to: \(central.state.rawValue) (poweredOn = 5)") let stateString: String
if central.state == .poweredOn { switch central.state {
case .unknown: stateString = "unknown(0)"
case .resetting: stateString = "resetting(1)"
case .unsupported: stateString = "unsupported(2)"
case .unauthorized: stateString = "unauthorized(3)"
case .poweredOff: stateString = "poweredOff(4)"
case .poweredOn: stateString = "poweredOn(5)"
@unknown default: stateString = "unknown state(\(central.state.rawValue))"
}
print("[BLUETOOTH DEBUG] Central manager state changed to: \(stateString)")
if central.state == .unsupported {
print("[BLUETOOTH DEBUG] Bluetooth is not supported on this device")
} else if central.state == .unauthorized {
print("[BLUETOOTH DEBUG] Bluetooth is unauthorized. Check app permissions in Settings")
} else if central.state == .poweredOff {
print("[BLUETOOTH DEBUG] Bluetooth is powered off. Please turn on Bluetooth")
} else if central.state == .poweredOn {
print("[BLUETOOTH DEBUG] Central powered on, starting scan") print("[BLUETOOTH DEBUG] Central powered on, starting scan")
startScanning() startScanning()
@@ -2602,8 +2630,26 @@ extension BluetoothMeshService: CBPeripheralDelegate {
extension BluetoothMeshService: CBPeripheralManagerDelegate { extension BluetoothMeshService: CBPeripheralManagerDelegate {
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) { func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
// Peripheral manager state updated // Peripheral manager state updated
print("[BLUETOOTH DEBUG] Peripheral manager state changed to: \(peripheral.state.rawValue) (poweredOn = 5)") let stateString: String
switch peripheral.state { switch peripheral.state {
case .unknown: stateString = "unknown(0)"
case .resetting: stateString = "resetting(1)"
case .unsupported: stateString = "unsupported(2)"
case .unauthorized: stateString = "unauthorized(3)"
case .poweredOff: stateString = "poweredOff(4)"
case .poweredOn: stateString = "poweredOn(5)"
@unknown default: stateString = "unknown state(\(peripheral.state.rawValue))"
}
print("[BLUETOOTH DEBUG] Peripheral manager state changed to: \(stateString)")
switch peripheral.state {
case .unsupported:
print("[BLUETOOTH DEBUG] Bluetooth is not supported on this device")
case .unauthorized:
print("[BLUETOOTH DEBUG] Bluetooth is unauthorized. Check app permissions in Settings")
case .poweredOff:
print("[BLUETOOTH DEBUG] Bluetooth is powered off. Please turn on Bluetooth")
case .poweredOn: case .poweredOn:
print("[BLUETOOTH DEBUG] Peripheral powered on, setting up and advertising") print("[BLUETOOTH DEBUG] Peripheral powered on, setting up and advertising")
setupPeripheral() setupPeripheral()
@@ -2619,7 +2665,19 @@ extension BluetoothMeshService: CBPeripheralManagerDelegate {
} }
func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) { func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) {
// Handle service addition if needed if let error = error {
print("[BLUETOOTH DEBUG] Failed to add service: \(error.localizedDescription)")
} else {
print("[BLUETOOTH DEBUG] Service added successfully: \(service.uuid)")
}
}
func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) {
if let error = error {
print("[BLUETOOTH DEBUG] Failed to start advertising: \(error.localizedDescription)")
} else {
print("[BLUETOOTH DEBUG] Advertising started successfully")
}
} }
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) { func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) {