         
         // no attributes, impossible to write
         guard database.attributes.isEmpty == false
-            else { errorResponse(opcode, .invalidHandle, pdu.handle); return }
+            else { await errorResponse(opcode, .invalidHandle, pdu.handle); return }
         
         // validate handle
         guard database.contains(handle: pdu.handle)
-            else { errorResponse(opcode, .invalidHandle, pdu.handle); return }
+            else { await errorResponse(opcode, .invalidHandle, pdu.handle); return }
         
         // validate that the prepared writes queue is not full
         guard preparedWrites.count <= maximumPreparedWrites
-            else { errorResponse(opcode, .prepareQueueFull); return }
+            else { await errorResponse(opcode, .prepareQueueFull); return }
         
         // get attribute
         let attribute = database[handle: pdu.handle]
         
         // validate permissions
-        if let error = checkPermissions([.write, .writeAuthentication, .writeEncrypt], attribute) {
-            
-            errorResponse(opcode, error, pdu.handle)
+        if let error = await checkPermissions([.write, .writeAuthentication, .writeEncrypt], attribute) {
+            await errorResponse(opcode, error, pdu.handle)
             return
         }
         

        }
    }
    
    private func handleReadRequest(opcode: ATTOpcode,
                                   handle: UInt16,
                                   offset: UInt16 = 0,
                                   isBlob: Bool = false) -> Data? {
        
        // no attributes
        guard database.attributes.isEmpty == false
            else { errorResponse(opcode, .invalidHandle, handle); return nil }
        
        // validate handle
        guard database.contains(handle: handle)
            else { errorResponse(opcode, .invalidHandle, handle); return nil }
        
        // get attribute
        let attribute = database[handle: handle]
        
        // validate permissions
        if let error = checkPermissions([.read, .readAuthentication, .readEncrypt], attribute) {
            
            errorResponse(opcode, error, handle)
            return nil
        }
        

        }
        
        let response = ATTFindInformationResponse(attributeData: attributeData)
        await respond(response)
    }
    
    private func findByTypeValue(_ pdu: ATTFindByTypeRequest) async {
        
        typealias Handle = ATTFindByTypeResponse.HandlesInformation
        
        log?("Find By Type Value (\(pdu.startHandle) - \(pdu.endHandle)) (\(pdu.attributeType))")
        
        guard pdu.startHandle != 0 && pdu.endHandle != 0
            else { await errorResponse(type(of: pdu).attributeOpcode, .invalidHandle); return }
        
        guard pdu.startHandle <= pdu.endHandle
            else { await errorResponse(type(of: pdu).attributeOpcode, .invalidHandle, pdu.startHandle); return }
        
        let handles = database.findByTypeValue(handle: (pdu.startHandle, pdu.endHandle),
                                               type: pdu.attributeType,
                                               value: pdu.attributeValue)
        
        guard handles.isEmpty == false
            else { await errorResponse(type(of: pdu).attributeOpcode, .attributeNotFound, pdu.startHandle); return }
        
        let response = ATTFindByTypeResponse(handles)
        await respond(response)
    }
    
    private func writeRequest(_ pdu: ATTWriteRequest) async {
        let opcode = type(of: pdu).attributeOpcode
        await handleWriteRequest(opcode: opcode, handle: pdu.handle, value: pdu.value, shouldRespond: true)
    }
    
    private func writeCommand(_ pdu: ATTWriteCommand) async {
        let opcode = type(of: pdu).attributeOpcode
        await handleWriteRequest(opcode: opcode, handle: pdu.handle, value: pdu.value, shouldRespond: false)
    }
    
    private func readRequest(_ pdu: ATTReadRequest) async {
        let opcode = type(of: pdu).attributeOpcode
        log?("Read (\(pdu.handle))")
        if let value = await handleReadRequest(opcode: opcode, handle: pdu.handle) {
            await respond(ATTReadResponse(attributeValue: value))
        }
    }
    
    private func readBlobRequest(_ pdu: ATTReadBlobRequest) async {
        let opcode = type(of: pdu).attributeOpcode
        log?("Read Blob (\(pdu.handle))")
        if let value = await handleReadRequest(opcode: opcode, handle: pdu.handle, offset: pdu.offset, isBlob: true) {
            await respond(ATTReadBlobResponse(partAttributeValue: value))
        }
    }
    
    private func readMultipleRequest(_ pdu: ATTReadMultipleRequest) async {
        let opcode = type(of: pdu).attributeOpcode
        log?("Read Multiple Request \(pdu.handles)")
        
        // no attributes, impossible to read
        guard database.attributes.isEmpty == false
            else { await errorResponse(opcode, .invalidHandle, pdu.handles[0]); return }
        
        var values = Data()
        
