     ///
     /// ![Image](https://github.com/PureSwift/Bluetooth/raw/master/Assets/ReadLongCharacteristicValues.png)
     @inline(__always)
-    private func readLongAttributeValue(_ operation: ReadOperation) {
+    private func readLongAttributeValue(_ operation: ReadOperation) async throws {
         
         // The Attribute Protocol Read Blob Request is used to perform this sub-procedure.
         // The Attribute Handle shall be set to the Characteristic Value Handle of the Characteristic Value to be read.

        // The offset for subsequent Read Blob Requests is the next octet that has yet to be read.
        // The Read Blob Request is repeated until the Read Blob Response’s Part Attribute Value parameter is shorter than (ATT_MTU-1).
        
        let pdu = ATTReadBlobRequest(handle: operation.handle,
                                     offset: operation.offset)
        
        send(pdu) { [unowned self] in self.readBlobResponse($0, operation: operation) }
    }
    
    private func writeAttribute(_ handle: UInt16,
                                data: Data,
                                reliableWrites: Bool,
                                completion: ((GATTClientResponse<()>) -> ())?) {
        
        // short value
        if data.count <= Int(maximumTransmissionUnit.rawValue) - 3 { // ATT_MTU - 3
            
            if let completion = completion {
                
                writeAttributeValue(handle,
                                    data: data,
                                    completion: completion)
                
            } else {
                
                writeAttributeCommand(handle,
                                      data: data)
            }
            
        } else {
            
            let completion = completion ?? { _ in }
            
            writeLongAttributeValue(handle,
                                    data: data,
                                    reliableWrites: reliableWrites,
                                    completion: completion)
        }
    }
    
    private func writeAttributeCommand(_ attribute: UInt16, data: Data) {
        
        let data = Data(data.prefix(Int(maximumTransmissionUnit.rawValue) - 3))
        
        let pdu = ATTWriteCommand(handle: attribute, value: data)
        
        send(pdu)
    }
    
    /// Write attribute request.
    private func writeAttributeValue(_ attribute: UInt16,
                                     data: Data,
                                     completion: @escaping (GATTClientResponse<()>) -> ()) {
        
        let data = Data(data.prefix(Int(maximumTransmissionUnit.rawValue) - 3))
        
        let pdu = ATTWriteRequest(handle: attribute, value: data)

        send(pdu) { [unowned self] in self.writeResponse($0, completion: completion) }
    }
    
    private func writeLongAttributeValue(_ attribute: UInt16,
                                         data: Data,
                                         reliableWrites: Bool = false,
                                         completion: @escaping (GATTClientResponse<()>) -> ()) {
        
        // The Attribute Protocol Prepare Write Request and Execute Write Request are used to perform this sub-procedure.
        // The Attribute Handle parameter shall be set to the Characteristic Value Handle of the Characteristic Value to be written.

    private func readResponse(
        _ response: ATTResponse<ATTReadResponse>,
        operation: ReadOperation
    ) async throws {
        
        // The Read Response only contains a Characteristic Value that is less than or equal to (ATT_MTU – 1) octets in length.
        // If the Characteristic Value is greater than (ATT_MTU – 1) octets in length, the Read Long Characteristic Value procedure
