             CBCentralManagerScanOptionAllowDuplicatesKey: NSNumber(value: filterDuplicates == false)
         ]
         
-        let subject: PassthroughSubject<ScanData<Peripheral, Advertisement>, Error> = self.queue.sync { [unowned self] in
+        return self.centralManager.tryMap { [unowned self] (central) in
             self.combine = .init()
             self.peripheralQueue.removeAll(keepingCapacity: true)
             self.peripherals.removeAll(keepingCapacity: true)
-            return self.combine.scan
-        }
-        
-        centralManager { [unowned self] (central) in
             precondition(central.isScanning == false)
-            do {
-                let state = self.state
-                guard state == .poweredOn
-                    else { throw DarwinCentralError.invalidState(state) }
-                self.log.send("Scanning...")
-                // start scanning
-                self.internalManager.scanForPeripherals(withServices: serviceUUIDs, options: options)
-                assert(self.internalManager.isScanning)
-            } catch {
-                self.combine.scan.send(completion: .failure(error))
-            }
-        }
-        
-        return subject.eraseToAnyPublisher()
+            guard self.state == .poweredOn
+                else { throw DarwinCentralError.invalidState(self.state) }
+            self.log.send("Scanning...")
+            central.scanForPeripherals(withServices: serviceUUIDs, options: options)
+            assert(central.isScanning)
+        }
+        .flatMap { self.combine.scan }
+        .eraseToAnyPublisher()
     }
     
     /// Stops scanning for peripherals.
     public func stopScan() {
-        self.queue.async { [unowned self] in
-            assert(self.internalManager.isScanning)
-            defer { assert(self.internalManager.isScanning == false) }
-            self.internalManager.stopScan()
+        let _ = self.centralManager.sink {
+            assert($0.isScanning)
+            $0.stopScan()
+            assert($0.isScanning == false)
             self.combine.scan.send(completion: .finished)
             self.log.send("Discovered \(self.cache.peripherals.count) peripherals")
         }

    typealias State = DarwinBluetoothState
    
    typealias AttributeID = ObjectIdentifier
    
    /// Central Peer
    ///

    }
    
    /// Discover the specified services.
    public func discoverServices(_ services: [BluetoothUUID],
                          for peripheral: Peripheral) -> AnyPublisher<[Service<Peripheral, AttributeID>], Error> {
        
        let subject = PassthroughSubject<[Service<Peripheral, AttributeID>], Error>()
        let coreServices = services.isEmpty ? nil : services.map { CBUUID($0) }
        
        return self.centralManager.tryMap { [unowned self] (central) -> CBCentralManager in
            guard self.state == .poweredOn else { throw DarwinCentralError.invalidState(self.state) }
            self.combine.services[peripheral] = subject
            return central
        }
        .combineLatest(self.peripheral(for: peripheral))
        .tryMap { (central, peripheral) in
            guard peripheral.state == .connected
                else { throw CentralError.disconnected }
            
            // attempt to connect (does not timeout)
            central.connect(peripheral, options: options)
        }.eraseToAnyPublisher()
        
        self.centralManager.
        centralManager { [unowned self] (central) in
            do {
                // store subject for completion
