     }
     
     /**
-     Write Without Response
-     
-     This sub-procedure is used to write a Characteristic Value to a server when the client knows the Characteristic Value Handle and the client does not need an acknowledgement that the write was successfully performed. This sub-procedure only writes the first `(ATT_MTU – 3)` octets of a Characteristic Value. This sub-procedure cannot be used to write a long characteristic; instead the Write Long Characteristic Values sub-procedure should be used.
-     
-     If the Characteristic Value write request is the wrong size, or has an invalid value as defined by the profile, then the write shall not succeed and no error shall be generated by the server.
-     */
-    public func writeCharacteristic(_ characteristic: Characteristic, data: Data) {
-        
-        // The Attribute Protocol Write Command is used for this sub-procedure.
-        // The Attribute Handle parameter shall be set to the Characteristic Value Handle.
-        // The Attribute Value parameter shall be set to the new Characteristic Value.
-        
-        let data = [UInt8](data.prefix(connection.maximumTransmissionUnit - 3))
-        
-        let pdu = ATTWriteCommand(handle: characteristic.handle.value, value: data)
-        
-        send(pdu)
-    }
-    
-    /**
-     Signed Write Without Response
-     
-     This sub-procedure is used to write a Characteristic Value to a server when the client knows the Characteristic Value Handle and the ATT Bearer is not encrypted. This sub-procedure shall only be used if the Characteristic Properties authenticated bit is enabled and the client and server device share a bond.
-     
-     If the authenticated Characteristic Value that is written is the wrong size, has an invalid value as defined by the profile, or the signed value does not authenticate the client, then the write shall not succeed and no error shall be gener- ated by the server.
-     
-     - Note: On BR/EDR, the ATT Bearer is always encrypted, due to the use of Security Mode 4, therefore this sub-procedure shall not be used.
-     */
-    public func writeSignedCharacteristic(_ characteristic: Characteristic, data: Data) {
-        
-        // This sub-procedure only writes the first (ATT_MTU – 15) octets of an Attribute Value.
-        // This sub-procedure cannot be used to write a long Attribute.
-        
-        // The Attribute Protocol Write Command is used for this sub-procedure.
-        // The Attribute Handle parameter shall be set to the Characteristic Value Handle.
-        // The Attribute Value parameter shall be set to the new Characteristic Value authenticated by signing the value.
-        
-        // If a connection is already encrypted with LE security mode 1, level 2 or level 3 as defined in [Vol 3] Part C,
-        // Section 10.2 then, a Write Without Response as defined in Section 4.9.1 shall be used instead of
-        // a Signed Write Without Response.
-        
-        let data = [UInt8](data.prefix(connection.maximumTransmissionUnit - 15))
-        
-        // TODO: Sign Data
-        
-        let pdu = ATTWriteCommand(handle: characteristic.handle.value, value: data)
-        
-        send(pdu)
-    }
-    
-    /**
-     Write Characteristic Value
-     
-     This sub-procedure is used to write a Characteristic Value to a server when the client knows the Characteristic Value Handle. This sub-procedure only writes the first (ATT_MTU – 3) octets of a Characteristic Value. This sub-procedure cannot be used to write a long Attribute; instead the Write Long Characteristic Values sub-procedure should be used.
-     
-     ![Image](https://github.com/PureSwift/BluetoothLinux/raw/master/Assets/WriteCharacteristicValue.png)
+     Write Characteristic
+     
+     Uses the appropriate procecedure to write the characteristic value.
      */
     public func writeCharacteristic(_ characteristic: Characteristic,
                                     data: Data,
-                                    completion: @escaping (GATTClientResponse<()>) -> ()) {
-        
-        // The Attribute Protocol Write Request is used to for this sub-procedure.
-        // The Attribute Handle parameter shall be set to the Characteristic Value Handle.
-        // The Attribute Value parameter shall be set to the new characteristic.
-        
-        let data = [UInt8](data.prefix(connection.maximumTransmissionUnit - 3))
-        
-        let pdu = ATTWriteRequest(handle: characteristic.handle.value, value: data)
-        
-        // A Write Response shall be sent by the server if the write of the Characteristic Value succeeded.
-        
-        send(pdu) { [unowned self] in self.writeResponse($0, completion: completion) }
+                                    reliableWrites: Bool = true,
+                                    completion: ((GATTClientResponse<()>) -> ())?) {
+        
+        // short value
+        if data.count <= connection.maximumTransmissionUnit - 3 {
+            
+            if let completion = completion {
+                
+                writeCharacteristicValue(characteristic, data: data, completion: completion)
+                
+            } else {
+                
+                writeCharacteristicCommand(characteristic, data: data)
+            }
+            
+        } else {
+            
+            let completion = completion ?? { _ in }
+            
+            writeLongCharacteristicValue(data: data, reliableWrites: reliableWrites, completion: completion)
+        }
     }
     
     // MARK: - Private Methods

     
     An Error Response shall be sent by the server in response to the Write Request if insufficient authentication, insufficient authorization, insufficient encryption key size is used by the client, or if a write operation is not permitted on the Characteristic Value. The Error Code parameter is set as specified in the Attribute Protocol. If the Characteristic Value that is written is the wrong size, or has an invalid value as defined by the profile, then the value shall not be written and an Error Response shall be sent with the Error Code set to Application Error by the server.
     */
    private func writeResponse(_ response: ATTResponse<ATTWriteResponse>, completion: (GATTClientResponse<()>) -> ()) {
        
        switch response {
            

            
            completion(.value(()))
        }
    }
    
    /**
     Prepare Write Response
     
     
     An Error Response shall be sent by the server in response to the Prepare Write Request if insufficient authentication, insufficient authorization, insufficient encryption key size is used by the client, or if a write operation is not permitted on the Characteristic Value. The Error Code parameter is set as specified in the Attribute Protocol. If the Attribute Value that is written is the wrong size, or has an invalid value as defined by the profile, then the write shall not succeed and an Error Response shall be sent with the Error Code set to Application Error by the server.
     */
    private func prepareWrite(_ response: ATTResponse<ATTPrepareWriteResponse>, operation: WriteOperation) {
        
        
    }
}

