diff --git a/app/src/main/java/de/ccc/events/badge/card10/filetransfer/BatchTransferFragment.kt b/app/src/main/java/de/ccc/events/badge/card10/filetransfer/BatchTransferFragment.kt
index 30aa7510815db8101b325c07374a7aec0d541147..801b7ca4dfc367b99738025acb9ee37b11d265b7 100644
--- a/app/src/main/java/de/ccc/events/badge/card10/filetransfer/BatchTransferFragment.kt
+++ b/app/src/main/java/de/ccc/events/badge/card10/filetransfer/BatchTransferFragment.kt
@@ -57,7 +57,6 @@ class BatchTransferFragment : Fragment(), FileTransferListener, GattListener {
         inflater.inflate(R.layout.batch_transfer_fragment, container, false)
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-        label_status.text = getString(R.string.batch_transfer_label_initializing)
         progress.max = queue.size
 
         button_cancel.setOnClickListener {
@@ -72,13 +71,7 @@ class BatchTransferFragment : Fragment(), FileTransferListener, GattListener {
                 .commit()
         }
 
-        initConnection()
-    }
-
-    private fun initConnection() {
-        val ctx = context ?: throw IllegalStateException()
-        ConnectionService.addGattListener("batchfiletransfer", this)
-        ConnectionService.connect(ctx)
+        startTransfer()
     }
 
     private fun startTransfer() {
@@ -123,10 +116,6 @@ class BatchTransferFragment : Fragment(), FileTransferListener, GattListener {
         }
     }
 
-    override fun onConnectionReady() {
-        startTransfer()
-    }
-
     override fun onError() {
         activity?.runOnUiThread {
             label_status.text = getString(R.string.batch_transfer_label_error)
diff --git a/app/src/main/java/de/ccc/events/badge/card10/filetransfer/FileTransferFragment.kt b/app/src/main/java/de/ccc/events/badge/card10/filetransfer/FileTransferFragment.kt
index 0730711d4eeae9413d1b3e3290e6844803863ffd..8a196274886c175729358b8084fb343f52ebe561 100644
--- a/app/src/main/java/de/ccc/events/badge/card10/filetransfer/FileTransferFragment.kt
+++ b/app/src/main/java/de/ccc/events/badge/card10/filetransfer/FileTransferFragment.kt
@@ -80,19 +80,12 @@ class FileTransferFragment : Fragment(), GattListener, FileTransferListener{
         buttonStartStop = view.findViewById(R.id.button_start_stop_transfer)
 
         try {
-            initConnection()
             toggleControls()
         } catch (e: ConnectionException) {
             showError(e.message)
         } catch (e: Exception) {
             showError(getString(R.string.connection_error_generic))
         }
-
-    }
-
-    private fun initConnection() {
-        val ctx = context ?: throw IllegalStateException()
-        ConnectionService.connect(ctx)
     }
 
     override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
diff --git a/app/src/main/java/de/ccc/events/badge/card10/mood/MoodFragment.kt b/app/src/main/java/de/ccc/events/badge/card10/mood/MoodFragment.kt
index 7ff715c898e558a1d379f756095effbe6d36013c..f9224c5e68a627da2225ad00f5a02aaa5accf3ba 100644
--- a/app/src/main/java/de/ccc/events/badge/card10/mood/MoodFragment.kt
+++ b/app/src/main/java/de/ccc/events/badge/card10/mood/MoodFragment.kt
@@ -22,60 +22,23 @@
 
 package de.ccc.events.badge.card10.mood
 
-import android.bluetooth.BluetoothAdapter
-import android.bluetooth.BluetoothGatt
-import android.bluetooth.BluetoothGattCallback
-import android.bluetooth.BluetoothGattCharacteristic
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import androidx.fragment.app.Fragment
-import de.ccc.events.badge.card10.CARD10_BLUETOOTH_MAC_PREFIX
-import de.ccc.events.badge.card10.CARD10_SERVICE_UUID
 import de.ccc.events.badge.card10.R
-import de.ccc.events.badge.card10.ROCKETS_CHARACTERISTIC_UUID
+import de.ccc.events.badge.card10.common.ConnectionService
+import de.ccc.events.badge.card10.time.Card10Service
 import kotlinx.android.synthetic.main.mood_fragment.*
-import java.util.concurrent.CountDownLatch
 
 class MoodFragment : Fragment() {
-
-    private val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
-    private lateinit var gatt: BluetoothGatt
-    private var rocketsCharacteristic: BluetoothGattCharacteristic? = null
-    private var writeLatch: CountDownLatch? = null
+    private var card10Service: Card10Service? = null
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
 
-        val callback = object : BluetoothGattCallback() {
-            override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
-                System.out.println("===== onConnectionStateChange " + gatt + " / " + status + " / " + newState)
-                if (newState == BluetoothGatt.STATE_CONNECTED)
-                    gatt.discoverServices()
-            }
-
-            override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
-                System.out.println("===== onServicesDiscovered " + gatt + " / " + status)
-                val card10Service = gatt.getService(CARD10_SERVICE_UUID)
-                rocketsCharacteristic = card10Service.getCharacteristic(ROCKETS_CHARACTERISTIC_UUID)
-            }
-
-            override fun onCharacteristicWrite(
-                gatt: BluetoothGatt,
-                characteristic: BluetoothGattCharacteristic,
-                status: Int
-            ) {
-                System.out.println("===== onCharacteristicWrite " + characteristic.uuid.toString() + " / " + characteristic.value + " / " + status)
-                writeLatch?.countDown();
-            }
-        }
-
-        val remoteDevices =
-            bluetoothAdapter.bondedDevices.filter { it.address.startsWith(CARD10_BLUETOOTH_MAC_PREFIX, true) }
-        if (remoteDevices.isEmpty())
-            activity!!.finish()
-        gatt = remoteDevices.get(0).connectGatt(activity, false, callback)
+        card10Service = ConnectionService.card10Service
     }
 
     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@@ -83,28 +46,14 @@ class MoodFragment : Fragment() {
     }
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-        mood_good.setOnClickListener({
-            writeGatt(rocketsCharacteristic!!, ubyteArrayOf(0xffu, 0x00u, 0x00u).toByteArray())
-        })
-        mood_neutral.setOnClickListener({
-            writeGatt(rocketsCharacteristic!!, ubyteArrayOf(0x00u, 0xffu, 0x00u).toByteArray())
-        })
-        mood_bad.setOnClickListener({
-            writeGatt(rocketsCharacteristic!!, ubyteArrayOf(0x00u, 0x00u, 0xffu).toByteArray())
-        })
-    }
-
-    fun writeGatt(characteristic: BluetoothGattCharacteristic, values: ByteArray) {
-        characteristic.value = values
-        val init = gatt.writeCharacteristic(rocketsCharacteristic)
-        if (!init)
-            System.out.println("Failed to initiate writing GATT attribute")
-        writeLatch = CountDownLatch(1)
-        writeLatch!!.await();
-    }
-
-    override fun onDestroy() {
-        gatt.close();
-        super.onDestroy()
+        mood_good.setOnClickListener{
+            card10Service?.setRocketValue(ubyteArrayOf(0xffu, 0x00u, 0x00u).toByteArray())
+        }
+        mood_neutral.setOnClickListener{
+            card10Service?.setRocketValue(ubyteArrayOf(0x00u, 0xffu, 0x00u).toByteArray())
+        }
+        mood_bad.setOnClickListener{
+            card10Service?.setRocketValue(ubyteArrayOf(0x00u, 0x00u, 0xffu).toByteArray())
+        }
     }
 }
diff --git a/app/src/main/java/de/ccc/events/badge/card10/sparkle/BeautifulFragment.kt b/app/src/main/java/de/ccc/events/badge/card10/sparkle/BeautifulFragment.kt
index fbf7fc4dff93c26fe85bc14a22ec93bd70304d8c..240f65db6a448ef025334442c0de7bfebe2aea94 100644
--- a/app/src/main/java/de/ccc/events/badge/card10/sparkle/BeautifulFragment.kt
+++ b/app/src/main/java/de/ccc/events/badge/card10/sparkle/BeautifulFragment.kt
@@ -22,65 +22,27 @@
 
 package de.ccc.events.badge.card10.sparkle
 
-import android.bluetooth.*
 import android.os.Bundle
 import android.os.Handler
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import androidx.fragment.app.Fragment
-import de.ccc.events.badge.card10.CARD10_BLUETOOTH_MAC_PREFIX
-import de.ccc.events.badge.card10.CARD10_SERVICE_UUID
-import de.ccc.events.badge.card10.LEDS_ABOVE_CHARACTERISTIC_UUID
 import de.ccc.events.badge.card10.R
-import java.util.concurrent.CountDownLatch
+import de.ccc.events.badge.card10.common.ConnectionService
+import de.ccc.events.badge.card10.time.Card10Service
 import kotlin.random.Random
 
 class BeautifulFragment : Fragment(), Runnable {
-
-    private val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
-    private lateinit var gatt: BluetoothGatt
-    private var ledsAboveCharacteristic: BluetoothGattCharacteristic? = null
-    private @Volatile var writeLatch: CountDownLatch? = null
     private val handler = Handler()
 
+    private var card10Service: Card10Service? = null
+
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
 
-        val callback = object : BluetoothGattCallback() {
-            override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
-                println("===== onConnectionStateChange ${gatt} ${if (status == BluetoothGatt.GATT_SUCCESS) "SUCCESS" else status} ${if (newState == BluetoothProfile.STATE_CONNECTED) "CONNECTED" else if (newState == BluetoothProfile.STATE_DISCONNECTED) "DISCONNECTED" else newState}")
-                if (newState == BluetoothGatt.STATE_CONNECTED)
-                    gatt.requestMtu(64)
-            }
-
-            override fun onMtuChanged(gatt: BluetoothGatt, mtu: Int, status: Int) {
-                println("===== onMtuChanged ${gatt} ${if (status == BluetoothGatt.GATT_SUCCESS) "SUCCESS" else status} ${mtu}")
-                gatt.discoverServices()
-            }
-
-            override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
-                println("===== onServicesDiscovered ${gatt} ${if (status == BluetoothGatt.GATT_SUCCESS) "SUCCESS" else status}")
-                val card10Service = gatt.getService(CARD10_SERVICE_UUID)
-                ledsAboveCharacteristic = card10Service.getCharacteristic(LEDS_ABOVE_CHARACTERISTIC_UUID)
-                handler.post(this@BeautifulFragment)
-            }
-
-            override fun onCharacteristicWrite(
-                gatt: BluetoothGatt,
-                characteristic: BluetoothGattCharacteristic,
-                status: Int
-            ) {
-                println("=== onCharacteristicWrite ${gatt} ${if (status == BluetoothGatt.GATT_SUCCESS) "SUCCESS" else status} ${characteristic.uuid} ${characteristic.value}")
-                writeLatch?.countDown();
-            }
-        }
-
-        val remoteDevices =
-            bluetoothAdapter.bondedDevices.filter { it.address.startsWith(CARD10_BLUETOOTH_MAC_PREFIX, true) }
-        if (remoteDevices.isEmpty())
-            activity!!.finish()
-        gatt = remoteDevices.get(0).connectGatt(activity, false, callback)
+        card10Service = ConnectionService.card10Service
+        handler.post(this@BeautifulFragment)
     }
 
     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@@ -88,18 +50,12 @@ class BeautifulFragment : Fragment(), Runnable {
     }
 
     override fun run() {
-        ledsAboveCharacteristic!!.value = Random.nextBytes(33);
-        writeLatch = CountDownLatch(1)
-        val init = gatt.writeCharacteristic(ledsAboveCharacteristic)
-        if (!init)
-            println("=== Failed to initiate writing GATT attribute")
-        writeLatch!!.await();
+        card10Service?.setLeds(Random.nextBytes(33))
         handler.postDelayed(this, 100)
     }
 
     override fun onDestroy() {
         handler.removeCallbacksAndMessages(null)
-        gatt.close();
         super.onDestroy()
     }
 }
diff --git a/app/src/main/java/de/ccc/events/badge/card10/time/Card10Service.kt b/app/src/main/java/de/ccc/events/badge/card10/time/Card10Service.kt
index ea5aec8d45b6adc5358660285f355be5f8428a93..db1501c62425951bcb5f367a34fd02aea30469b6 100644
--- a/app/src/main/java/de/ccc/events/badge/card10/time/Card10Service.kt
+++ b/app/src/main/java/de/ccc/events/badge/card10/time/Card10Service.kt
@@ -24,6 +24,8 @@ package de.ccc.events.badge.card10.time
 
 import android.bluetooth.BluetoothGattCharacteristic
 import android.bluetooth.BluetoothGattService
+import de.ccc.events.badge.card10.LEDS_ABOVE_CHARACTERISTIC_UUID
+import de.ccc.events.badge.card10.ROCKETS_CHARACTERISTIC_UUID
 import de.ccc.events.badge.card10.TIME_CHARACTERISTIC_UUID
 import de.ccc.events.badge.card10.common.ConnectionService
 import java.nio.ByteBuffer
@@ -31,11 +33,14 @@ import java.nio.ByteBuffer
 class Card10Service(
     service: BluetoothGattService
 ) {
-    private val timeCharacteristic: BluetoothGattCharacteristic
+    private val timeCharacteristic = service.getCharacteristic(TIME_CHARACTERISTIC_UUID)
+    private val rocketsCharacteristic = service.getCharacteristic(ROCKETS_CHARACTERISTIC_UUID)
+    private var ledsAboveCharacteristic = service.getCharacteristic(LEDS_ABOVE_CHARACTERISTIC_UUID)
 
     init {
-        timeCharacteristic = service.getCharacteristic(TIME_CHARACTERISTIC_UUID)
         timeCharacteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
+        rocketsCharacteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
+        ledsAboveCharacteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
     }
 
     fun setTime() {
@@ -44,4 +49,14 @@ class Card10Service(
         timeCharacteristic.value = buffer.array()
         ConnectionService.writeCharacteristic(timeCharacteristic)
     }
+
+    fun setRocketValue(value: ByteArray) {
+        rocketsCharacteristic.value = value
+        ConnectionService.writeCharacteristic(rocketsCharacteristic)
+    }
+
+    fun setLeds(value: ByteArray) {
+        ledsAboveCharacteristic.value = value
+        ConnectionService.writeCharacteristic(ledsAboveCharacteristic)
+    }
 }
\ No newline at end of file