         
         self.peripheral = peripheral
         self.callback = callback
-        self.client = GATTClient(socket: socket,
-                                 maximumTransmissionUnit: maximumTransmissionUnit,
-                                 log: { callback.log?("[\(peripheral)]: " + $0) },
-                                 writePending: nil)
-        
-        // wakeup ATT writer
-        //self.client.writePending = { [weak self] in self?.writePending = true }
-        
-        // run read thread
-        //self.connectionThread.start()
-        
-        self.client.writePending = { [unowned self] in
-            Task {
-                do { try self.client.write() }
-                catch {
-                    tasks.forEach { $0(error) }
+        self.client = GATTClient(
+            socket: socket,
+            maximumTransmissionUnit: maximumTransmissionUnit,
+            log: { callback.log?("[\(peripheral)]: " + $0) },
+            writePending: nil
+        )
+        
+        self.client.writePending = { [weak self] in
+            guard let self = self else { return }
+            Task(priority: .userInitiated) {
+                do {
+                    var didWrite = true
+                    repeat {
+                        didWrite = try self.client.write()
+                    } while didWrite
                 }
-            }
-            
+                catch {  }
+            }
         }
     }
     
     // MARK: - Methods
     
-    private var tasks = [(Error) -> ()]()
-    
-    private func readSocket() {
-        
-    }
-    
-    public func discoverServices(_ services: [BluetoothUUID],
-                                 for peripheral: Peripheral,
-                                 timeout: TimeInterval) async throws -> [Service<Peripheral, UInt16>] {
-        
-        let foundServices = try await withCheckedThrowingContinuation { continuation in
-            // resume with completion handler
-            client.discoverAllPrimaryServices {
-                continuation.resume(with: $0)
-            }
-            tasks.append({
-                
-            })
-            // run socket
-            self.client
-        }
-        
-        // store in cache
+    public func discoverServices(
+        _ services: Set<BluetoothUUID>,
+        for peripheral: Peripheral
+    ) async throws -> [Service<Peripheral, UInt16>] {
+        let foundServices = try await withCheckedThrowingContinuation { [weak self] (continuation: CheckedContinuation<[GATTClient.Service], Error>) in
+            guard let self = self else { return }
+            self.client.discoverAllPrimaryServices { clientResponse in
+                continuation.resume(with: clientResponse)
+            }
+        }
         cache.insert(foundServices)
-        
         return cache.services.map {
             Service(
                 id: $0.key,

        }
    }
    
    public func discoverCharacteristics(_ characteristics: [BluetoothUUID],
                                        for service: Service<Peripheral, UInt16>,
                                        timeout: TimeInterval) throws -> [Characteristic<Peripheral, UInt16>] {
        
        assert(service.peripheral == peripheral)
        

            else { throw CentralError.invalidAttribute(characteristic.uuid) }
        
        // GATT request
        return try await withCheckedThrowingContinuation { [weak self] (continuation: CheckedContinuation<Data, Error>) in
            guard let self = self else { return }
            self.client.readCharacteristic(gattCharacteristic.attribute) { clientResponse in
                continuation.resume(with: clientResponse)
            }
        }
    }
    
    public func writeValue(
        _ data: Data,
        for characteristic: Characteristic<Peripheral, UInt16>,
        withResponse: Bool
    ) async throws {
        
        assert(characteristic.peripheral == peripheral)
        
