diff --git a/ring-android/app/src/main/AndroidManifest.xml b/ring-android/app/src/main/AndroidManifest.xml
index 1741a9c26da724e8548a4a863dfecddf7ed4c3b5..fa0667cf00f37f69ebd5eb0998b04dd6f7707d62 100644
--- a/ring-android/app/src/main/AndroidManifest.xml
+++ b/ring-android/app/src/main/AndroidManifest.xml
@@ -169,10 +169,10 @@ as that of the covered work.
             </intent-filter>
         </service>
         <service
-            android:name=".service.SipService"
+            android:name=".service.DRingService"
             android:exported="false" >
             <intent-filter>
-                <action android:name=".service.SipService" />
+                <action android:name=".service.DRingService" />
             </intent-filter>
         </service>
     </application>
diff --git a/ring-android/app/src/main/java/cx/ring/client/AccountEditionActivity.java b/ring-android/app/src/main/java/cx/ring/client/AccountEditionActivity.java
index 8e5822b59ba81bcb7abbb215c10c1b2f045cbce4..d53f4cbca0d935eaa51a3b5481be905d2c9aa3a1 100644
--- a/ring-android/app/src/main/java/cx/ring/client/AccountEditionActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/AccountEditionActivity.java
@@ -53,7 +53,7 @@ import cx.ring.fragments.AudioManagementFragment;
 import cx.ring.fragments.NestedSettingsFragment;
 import cx.ring.fragments.SecurityAccountFragment;
 import cx.ring.model.account.Account;
-import cx.ring.service.ISipService;
+import cx.ring.service.IDRingService;
 import cx.ring.service.LocalService;
 import com.astuetz.PagerSlidingTabStrip;
 import java.util.ArrayList;
@@ -254,7 +254,7 @@ public class AccountEditionActivity extends Activity implements LocalService.Cal
     }
 
     @Override
-    public ISipService getRemoteService() {
+    public IDRingService getRemoteService() {
         return service.getRemoteService();
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/client/AccountWizard.java b/ring-android/app/src/main/java/cx/ring/client/AccountWizard.java
index 931f47b05c7d654951768be22bd4b81e84b62fe2..3ce8865e7b8627ac83b0a115c582d9a23cbfa9f7 100644
--- a/ring-android/app/src/main/java/cx/ring/client/AccountWizard.java
+++ b/ring-android/app/src/main/java/cx/ring/client/AccountWizard.java
@@ -36,7 +36,7 @@ import android.util.Log;
 import android.view.MenuItem;
 import cx.ring.R;
 import cx.ring.fragments.AccountCreationFragment;
-import cx.ring.service.ISipService;
+import cx.ring.service.IDRingService;
 import cx.ring.service.LocalService;
 
 import java.util.ArrayList;
@@ -158,7 +158,7 @@ public class AccountWizard extends AppCompatActivity implements LocalService.Cal
     }
 
     @Override
-    public ISipService getRemoteService() {
+    public IDRingService getRemoteService() {
         return service.getRemoteService();
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/client/CallActivity.java b/ring-android/app/src/main/java/cx/ring/client/CallActivity.java
index 9c9a25c614b288c5cef768706ad28110ba68c5e5..8a2314b9a4249991eacd6305082e171bbb13cc83 100644
--- a/ring-android/app/src/main/java/cx/ring/client/CallActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/CallActivity.java
@@ -45,7 +45,7 @@ import cx.ring.model.CallContact;
 import cx.ring.model.Conference;
 import cx.ring.model.SipCall;
 import cx.ring.model.account.AccountDetailBasic;
-import cx.ring.service.ISipService;
+import cx.ring.service.IDRingService;
 import cx.ring.service.LocalService;
 import cx.ring.utils.CallProximityManager;
 
@@ -167,15 +167,9 @@ public class CallActivity extends AppCompatActivity implements Callbacks, CallFr
 
             if (mDisplayedConference.getState().contentEquals("NONE")) {
                 SipCall call = mDisplayedConference.getParticipants().get(0);
-                try {
-                    String callId = service.getRemoteService().placeCall(call);
-                    if (callId == null || callId.isEmpty()) {
-                        CallActivity.this.terminateCall();
-                    }
-                    mDisplayedConference = service.getRemoteService().getConference(callId);
-                } catch (RemoteException e) {
-                    e.printStackTrace();
-                }
+                mDisplayedConference = service.placeCall(call);
+                if (mDisplayedConference == null)
+                    CallActivity.this.terminateCall();
             }
 
             setContentView(R.layout.activity_call_layout);
@@ -224,7 +218,7 @@ public class CallActivity extends AppCompatActivity implements Callbacks, CallFr
     }
 
     @Override
-    public ISipService getRemoteService() {
+    public IDRingService getRemoteService() {
         return service.getRemoteService();
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/client/DetailHistoryActivity.java b/ring-android/app/src/main/java/cx/ring/client/DetailHistoryActivity.java
index 89625f4896eb6de20d959d7327118e04e76064b9..d61628a52cd9f7760a38a69af568a7bd27a80219 100644
--- a/ring-android/app/src/main/java/cx/ring/client/DetailHistoryActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/DetailHistoryActivity.java
@@ -36,8 +36,8 @@ import cx.ring.fragments.DetailsHistoryEntryFragment;
 import cx.ring.fragments.HistoryFragment;
 import cx.ring.model.Conference;
 import cx.ring.model.SipCall;
-import cx.ring.service.ISipService;
-import cx.ring.service.SipService;
+import cx.ring.service.DRingService;
+import cx.ring.service.IDRingService;
 
 import android.app.Activity;
 import android.app.Fragment;
@@ -54,7 +54,7 @@ import android.view.MenuItem;
 public class DetailHistoryActivity extends Activity implements DetailsHistoryEntryFragment.Callbacks {
 
     private boolean mBound = false;
-    private ISipService service;
+    private IDRingService service;
     private String TAG = DetailHistoryActivity.class.getSimpleName();
 
     @Override
@@ -62,7 +62,7 @@ public class DetailHistoryActivity extends Activity implements DetailsHistoryEnt
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_holder);
 
-        Intent intent = new Intent(this, SipService.class);
+        Intent intent = new Intent(this, DRingService.class);
         bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
         getActionBar().setDisplayHomeAsUpEnabled(true);
     }
@@ -79,7 +79,7 @@ public class DetailHistoryActivity extends Activity implements DetailsHistoryEnt
     }
 
     @Override
-    public ISipService getService() {
+    public IDRingService getService() {
         return service;
     }
 
@@ -97,7 +97,7 @@ public class DetailHistoryActivity extends Activity implements DetailsHistoryEnt
 
         @Override
         public void onServiceConnected(ComponentName className, IBinder binder) {
-            service = ISipService.Stub.asInterface(binder);
+            service = IDRingService.Stub.asInterface(binder);
 
             FragmentTransaction ft = getFragmentManager().beginTransaction();
 
diff --git a/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java b/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
index de2090da95e09ee3f35d14153f0a8ac79993074f..88cf9b5baa9db6e5c3d6ea99634a66d418c2dfb4 100644
--- a/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
@@ -52,7 +52,7 @@ import cx.ring.model.CallContact;
 import cx.ring.model.account.Account;
 import cx.ring.model.Conference;
 import cx.ring.model.SipCall;
-import cx.ring.service.ISipService;
+import cx.ring.service.IDRingService;
 import cx.ring.service.LocalService;
 
 import android.app.Fragment;
@@ -176,9 +176,6 @@ public class HomeActivity extends AppCompatActivity implements LocalService.Call
             ActivityCompat.requestPermissions(this, toRequest, LocalService.PERMISSIONS_REQUEST);
         } else if (!mBound) {
             Log.i(TAG, "onCreate: Binding service...");
-            /*Intent intent = new Intent(this, SipService.class);
-            startService(intent);
-            bindService(intent, mConnection, Context.BIND_AUTO_CREATE);*/
             Intent intent = new Intent(this, LocalService.class);
             startService(intent);
             bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
@@ -385,9 +382,6 @@ public class HomeActivity extends AppCompatActivity implements LocalService.Call
             unbindService(mConnection);
             mBound = false;
         }
-        //Log.i(TAG, "onDestroy: destroying service...");
-        //Intent sipServiceIntent = new Intent(this, SipService.class);
-        //stopService(sipServiceIntent);
     }
 
     public void launchCallActivity(SipCall infos) {
@@ -471,7 +465,7 @@ public class HomeActivity extends AppCompatActivity implements LocalService.Call
     }
 
     @Override
-    public ISipService getRemoteService() {
+    public IDRingService getRemoteService() {
         return service.getRemoteService();
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/client/NewConversationActivity.java b/ring-android/app/src/main/java/cx/ring/client/NewConversationActivity.java
index 3f6ef596dedf2b7a9890c207fe0164e46ac07b78..440da2893f385aaefc547a253736a59ef2a364d4 100644
--- a/ring-android/app/src/main/java/cx/ring/client/NewConversationActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/NewConversationActivity.java
@@ -19,7 +19,7 @@ import android.widget.SearchView;
 import cx.ring.R;
 import cx.ring.fragments.ContactListFragment;
 import cx.ring.model.CallContact;
-import cx.ring.service.ISipService;
+import cx.ring.service.IDRingService;
 import cx.ring.service.LocalService;
 
 public class NewConversationActivity extends Activity implements ContactListFragment.Callbacks {
@@ -132,7 +132,7 @@ public class NewConversationActivity extends Activity implements ContactListFrag
     }
 
     @Override
-    public ISipService getRemoteService() {
+    public IDRingService getRemoteService() {
         return service.getRemoteService();
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/AccountCreationFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/AccountCreationFragment.java
index 24196665f2e56e9a8ad0b15bdb2cd52e8acc6322..07e0d5353b4a0036979a1a2199ab04d5eaa07ee0 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/AccountCreationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/AccountCreationFragment.java
@@ -25,7 +25,6 @@ import java.util.HashMap;
 import cx.ring.R;
 import cx.ring.model.account.AccountDetailBasic;
 import cx.ring.client.HomeActivity;
-import cx.ring.service.ISipService;
 
 import android.app.Activity;
 import android.app.Fragment;
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/AudioManagementFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/AudioManagementFragment.java
index 4f90c0055f1978453ca8f7f9d05544d85ae5359d..d41cfe46ceac107964cff73683772838adeb6b19 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/AudioManagementFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/AudioManagementFragment.java
@@ -41,7 +41,7 @@ import cx.ring.model.account.AccountDetail;
 import cx.ring.model.account.AccountDetailAdvanced;
 import cx.ring.model.account.Account;
 import cx.ring.model.Codec;
-import cx.ring.service.ISipService;
+import cx.ring.service.IDRingService;
 import cx.ring.service.LocalService;
 import cx.ring.views.dragsortlv.DragSortListView;
 
@@ -76,7 +76,7 @@ public class AudioManagementFragment extends PreferenceFragment {
     CodecAdapter listAdapter;
     private static final Callbacks sDummyCallbacks = new Callbacks() {
         @Override
-        public ISipService getRemoteService() {
+        public IDRingService getRemoteService() {
             return null;
         }
         @Override
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java
index 6b29850d8452f3e6532bf0b9eb856a829325d334..252de35979002bea5f24aa2bc3146f18f85a3a8f 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java
@@ -32,9 +32,7 @@
 package cx.ring.fragments;
 
 import android.app.Activity;
-import android.app.FragmentManager;
 import android.net.Uri;
-import android.support.design.widget.FloatingActionButton;
 import android.support.v4.app.NotificationCompat;
 import android.support.v4.app.NotificationManagerCompat;
 import android.app.PendingIntent;
@@ -54,7 +52,6 @@ import android.support.v7.app.ActionBar;
 import android.util.Log;
 import android.view.*;
 import android.view.View.OnClickListener;
-import android.view.inputmethod.InputMethodManager;
 import android.widget.*;
 import android.widget.CompoundButton.OnCheckedChangeListener;
 import cx.ring.R;
@@ -64,18 +61,16 @@ import cx.ring.client.ConversationActivity;
 import cx.ring.client.HomeActivity;
 import cx.ring.interfaces.CallInterface;
 
-import java.util.ArrayList;
 import java.util.Locale;
 import java.util.Random;
 
-import cx.ring.model.BubbleContact;
 import cx.ring.model.CallContact;
 import cx.ring.model.Conference;
 import cx.ring.model.SecureSipCall;
 import cx.ring.model.SipCall;
 import cx.ring.model.account.Account;
+import cx.ring.service.DRingService;
 import cx.ring.service.LocalService;
-import cx.ring.service.SipService;
 
 public class CallFragment extends CallableWrapperFragment implements CallInterface {
 
@@ -564,8 +559,8 @@ public class CallFragment extends CallableWrapperFragment implements CallInterfa
                         new Intent(getActivity(), CallActivity.class).putExtra("conference", getConference()), PendingIntent.FLAG_ONE_SHOT))
                 .addAction(R.drawable.ic_call_end_white_24dp, "Hangup",
                         PendingIntent.getService(getActivity(), new Random().nextInt(),
-                                new Intent(getActivity(), SipService.class)
-                                        .setAction(SipService.ACTION_CALL_END)
+                                new Intent(getActivity(), DRingService.class)
+                                        .setAction(DRingService.ACTION_CALL_END)
                                         .putExtra("conf", call.getCallId()),
                                 PendingIntent.FLAG_ONE_SHOT));
         Log.w("CallNotification ", "Updating " + getConference().notificationId + " for " + contact.getDisplayName());
@@ -720,14 +715,14 @@ public class CallFragment extends CallableWrapperFragment implements CallInterfa
                             new Intent(getActivity(), CallActivity.class).putExtra("conference", getConference()), PendingIntent.FLAG_ONE_SHOT))
                     .addAction(R.drawable.ic_action_accept, "Accept",
                             PendingIntent.getService(getActivity(), new Random().nextInt(),
-                                    new Intent(getActivity(), SipService.class)
-                                            .setAction(SipService.ACTION_CALL_ACCEPT)
+                                    new Intent(getActivity(), DRingService.class)
+                                            .setAction(DRingService.ACTION_CALL_ACCEPT)
                                             .putExtra("conf", call.getCallId()),
                                     PendingIntent.FLAG_ONE_SHOT))
                     .addAction(R.drawable.ic_call_end_white_24dp, "Refuse",
                             PendingIntent.getService(getActivity(), new Random().nextInt(),
-                                    new Intent(getActivity(), SipService.class)
-                                            .setAction(SipService.ACTION_CALL_REFUSE)
+                                    new Intent(getActivity(), DRingService.class)
+                                            .setAction(DRingService.ACTION_CALL_REFUSE)
                                             .putExtra("conf", call.getCallId()),
                                     PendingIntent.FLAG_ONE_SHOT));
             Log.w("CallNotification ", "Updating for incoming " + getConference().notificationId);
@@ -807,8 +802,8 @@ public class CallFragment extends CallableWrapperFragment implements CallInterfa
                         new Intent(getActivity(), CallActivity.class).putExtra("conference", getConference()), PendingIntent.FLAG_ONE_SHOT))
                 .addAction(R.drawable.ic_call_end_white_24dp, "Cancel",
                         PendingIntent.getService(getActivity(), new Random().nextInt(),
-                                new Intent(getActivity(), SipService.class)
-                                        .setAction(SipService.ACTION_CALL_END)
+                                new Intent(getActivity(), DRingService.class)
+                                        .setAction(DRingService.ACTION_CALL_END)
                                         .putExtra("conf", call.getCallId()),
                                 PendingIntent.FLAG_ONE_SHOT));
 
@@ -909,7 +904,7 @@ public class CallFragment extends CallableWrapperFragment implements CallInterfa
             initNormalStateDisplay();
         }
     }
-*/
+
     public void makeTransfer(BubbleContact contact) {
         FragmentManager fm = getFragmentManager();
         editName = TransferDFragment.newInstance();
@@ -925,7 +920,7 @@ public class CallFragment extends CallableWrapperFragment implements CallInterfa
         }
 
     }
-/*
+
     @Override
     public void surfaceCreated(SurfaceHolder holder) {
 
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/CallableWrapperFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/CallableWrapperFragment.java
index 3ea8dcab1bfe2eb5a39fd78b91f62dc5a553b44f..eba28d1144590966f96a64ec14c272d1a9f78162 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/CallableWrapperFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/CallableWrapperFragment.java
@@ -142,27 +142,27 @@ public abstract class CallableWrapperFragment extends Fragment implements CallIn
         @Override
         public void onReceive(Context context, Intent intent) {
             if (intent.getAction().contentEquals(CallManagerCallBack.INCOMING_TEXT)) {
-                incomingText((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("CallID"), intent.getStringExtra("From"), intent.getStringExtra("Msg"));
+                incomingText((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("call"), intent.getStringExtra("from"), intent.getStringExtra("txt"));
             } else if (intent.getAction().contentEquals(CallManagerCallBack.CALL_STATE_CHANGED)) {
-                callStateChanged((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("CallID"), intent.getStringExtra("State"));
+                callStateChanged((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("call"), intent.getStringExtra("state"));
             } else if (intent.getAction().contentEquals(CallManagerCallBack.CONF_CREATED)) {
-                confCreated((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("confID"));
+                confCreated((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("conference"));
             } else if (intent.getAction().contentEquals(CallManagerCallBack.CONF_REMOVED)) {
-                confRemoved((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("confID"));
+                confRemoved((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("conference"));
             } else if (intent.getAction().contentEquals(CallManagerCallBack.CONF_CHANGED)) {
-                confChanged((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("confID"), intent.getStringExtra("state"));
+                confChanged((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("conference"), intent.getStringExtra("state"));
             } else if (intent.getAction().contentEquals(CallManagerCallBack.RECORD_STATE_CHANGED)) {
-                recordingChanged((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("callID"), intent.getStringExtra("file"));
+                recordingChanged((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("call"), intent.getStringExtra("file"));
             } else if (intent.getAction().contentEquals(CallManagerCallBack.ZRTP_OFF)) {
-                secureZrtpOff((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("callID"));
+                secureZrtpOff((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("call"));
             } else if (intent.getAction().contentEquals(CallManagerCallBack.ZRTP_ON)) {
-                secureZrtpOn((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("callID"));
+                secureZrtpOn((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("call"));
             } else if (intent.getAction().contentEquals(CallManagerCallBack.DISPLAY_SAS)) {
-                displaySAS((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("callID"));
+                displaySAS((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("call"));
             } else if (intent.getAction().contentEquals(CallManagerCallBack.ZRTP_NEGOTIATION_FAILED)) {
-                zrtpNegotiationFailed((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("callID"));
+                zrtpNegotiationFailed((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("call"));
             } else if (intent.getAction().contentEquals(CallManagerCallBack.ZRTP_NOT_SUPPORTED)) {
-                zrtpNotSupported((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("callID"));
+                zrtpNotSupported((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("call"));
             } else if (intent.getAction().contentEquals(CallManagerCallBack.RTCP_REPORT_RECEIVED)) {
                 rtcpReportReceived(null, null); // FIXME
             } else {
@@ -172,4 +172,4 @@ public abstract class CallableWrapperFragment extends Fragment implements CallIn
         }
 
     }
-}
\ No newline at end of file
+}
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/DetailsHistoryEntryFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/DetailsHistoryEntryFragment.java
index 5af66ebefc00fc39f5aa0f7717fb2f42190c3121..038b91a0c24eb845e754acf3307a140991fd4a69 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/DetailsHistoryEntryFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/DetailsHistoryEntryFragment.java
@@ -48,7 +48,7 @@ import cx.ring.history.HistoryCall;
 import cx.ring.history.HistoryEntry;
 import cx.ring.model.account.Account;
 import cx.ring.model.SipCall;
-import cx.ring.service.ISipService;
+import cx.ring.service.IDRingService;
 
 import java.util.ArrayList;
 import java.util.Map;
@@ -72,7 +72,7 @@ public class DetailsHistoryEntryFragment extends Fragment {
     private static Callbacks sDummyCallbacks = new Callbacks() {
 
         @Override
-        public ISipService getService() {
+        public IDRingService getService() {
             return null;
         }
 
@@ -84,9 +84,9 @@ public class DetailsHistoryEntryFragment extends Fragment {
 
     public interface Callbacks {
 
-        public ISipService getService();
+        IDRingService getService();
 
-        public void onCall(SipCall call);
+        void onCall(SipCall call);
 
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/NestedSettingsFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/NestedSettingsFragment.java
index 6d192f12be077da2488f022b22ae8f003678f028..0108955409672a83e5c62c9f8e713950b99d2e56 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/NestedSettingsFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/NestedSettingsFragment.java
@@ -46,7 +46,7 @@ import cx.ring.model.account.CredentialsManager;
 import cx.ring.model.account.SRTPManager;
 import cx.ring.model.account.TLSManager;
 import cx.ring.model.account.Account;
-import cx.ring.service.ISipService;
+import cx.ring.service.IDRingService;
 import cx.ring.service.LocalService;
 
 import java.util.ArrayList;
@@ -64,7 +64,7 @@ public class NestedSettingsFragment extends PreferenceFragment {
 
     private static Callbacks sDummyCallbacks = new Callbacks() {
         @Override
-        public ISipService getRemoteService() {
+        public IDRingService getRemoteService() {
             return null;
         }
         @Override
diff --git a/ring-android/app/src/main/java/cx/ring/loaders/AccountsLoader.java b/ring-android/app/src/main/java/cx/ring/loaders/AccountsLoader.java
index b96b6662c38bcf2fa4dc6a34caa772af9b9a6ab6..3c94e0898fd8796c054d8a3bba63bd8413e2b1dc 100644
--- a/ring-android/app/src/main/java/cx/ring/loaders/AccountsLoader.java
+++ b/ring-android/app/src/main/java/cx/ring/loaders/AccountsLoader.java
@@ -42,17 +42,17 @@ import java.util.HashMap;
 import java.util.Map;
 
 import cx.ring.model.account.Account;
-import cx.ring.service.ISipService;
+import cx.ring.service.IDRingService;
 
 public class AccountsLoader extends AsyncTaskLoader<Bundle> {
 
     private static final String TAG = AccountsLoader.class.getSimpleName();
     public static final String ACCOUNTS = "accounts";
     public static final String ACCOUNT_IP2IP = "IP2IP";
-    ISipService service;
+    IDRingService service;
     Bundle mData;
 
-    public AccountsLoader(Context context, ISipService ref) {
+    public AccountsLoader(Context context, IDRingService ref) {
         super(context);
         service = ref;
     }
diff --git a/ring-android/app/src/main/java/cx/ring/loaders/AccountsStateLoader.java b/ring-android/app/src/main/java/cx/ring/loaders/AccountsStateLoader.java
index 9f1908b0d6dcf65fe24ed367d9dcd2384108f336..14a40fb3a05c8e4e9a642bdb126605cc5cc13581 100644
--- a/ring-android/app/src/main/java/cx/ring/loaders/AccountsStateLoader.java
+++ b/ring-android/app/src/main/java/cx/ring/loaders/AccountsStateLoader.java
@@ -33,7 +33,7 @@ package cx.ring.loaders;
 
 import java.util.Map;
 
-import cx.ring.service.ISipService;
+import cx.ring.service.IDRingService;
 
 import android.content.AsyncTaskLoader;
 import android.content.Context;
@@ -45,10 +45,10 @@ public class AccountsStateLoader extends AsyncTaskLoader<Map<String, String>> {
     private static final String TAG = AccountsStateLoader.class.getSimpleName();
     public static final String ACCOUNTS = "accounts";
     public static final String ACCOUNT_IP2IP = "IP2IP";
-    final ISipService service;
+    final IDRingService service;
     final String accountId;
 
-    public AccountsStateLoader(Context context, ISipService ref, String accId) {
+    public AccountsStateLoader(Context context, IDRingService ref, String accId) {
         super(context);
         service = ref;
         accountId = accId;
diff --git a/ring-android/app/src/main/java/cx/ring/model/Conversation.java b/ring-android/app/src/main/java/cx/ring/model/Conversation.java
index 715dc3e8e519580f163d3d210bb58e7c95bbd12c..6401f27800a5f11b436e4be5b4d48ab3e9fd68da 100644
--- a/ring-android/app/src/main/java/cx/ring/model/Conversation.java
+++ b/ring-android/app/src/main/java/cx/ring/model/Conversation.java
@@ -46,6 +46,14 @@ public class Conversation extends ContentObservable implements Parcelable
         return null;
     }
 
+    public void addConference(Conference c) {
+        current_calls.add(c);
+    }
+
+    public void removeConference(Conference c) {
+        current_calls.remove(c);
+    }
+
     public Pair<HistoryEntry, HistoryCall> findHistoryByCallId(String id) {
         for (HistoryEntry e : history.values()) {
             for (HistoryCall c : e.getCalls().values()) {
@@ -197,9 +205,6 @@ public class Conversation extends ContentObservable implements Parcelable
             return null;
         return current_calls.get(0);
     }
-    public void setCurrentCall(Conference c) {
-        current_calls.add(c);
-    }
 
     @Override
     public int describeContents() {
diff --git a/ring-android/app/src/main/java/cx/ring/model/SipCall.java b/ring-android/app/src/main/java/cx/ring/model/SipCall.java
index e178269110321b459f3d7363f543ee78223a3563..05693b88863e13f4858cfe3865c0748a202ae67a 100644
--- a/ring-android/app/src/main/java/cx/ring/model/SipCall.java
+++ b/ring-android/app/src/main/java/cx/ring/model/SipCall.java
@@ -36,6 +36,8 @@ import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
 
+import java.util.Map;
+
 public class SipCall implements Parcelable {
 
     public static String ID = "id";
@@ -51,6 +53,8 @@ public class SipCall implements Parcelable {
     private String mAccount = "";
     private CallContact mContact = null;
     private String mNumber = "";
+    private boolean isPeerHolding = false;
+    private boolean isAudioMuted = false;
     private boolean isRecording = false;
     private long timestampStart_ = 0;
     private long timestampEnd_ = 0;
@@ -104,6 +108,16 @@ public class SipCall implements Parcelable {
         mNumber = args.getString(NUMBER);
     }
 
+    public SipCall(String callId, Map<String, String> call_details) {
+        mCallID = callId;
+        mAccount = call_details.get("ACCOUNTID");
+        mCallType = Integer.parseInt(call_details.get("CALL_TYPE"));
+        mCallState = stateFromString(call_details.get("CALL_STATE"));
+        mNumber = call_details.get("PEER_NUMBER");
+        isPeerHolding = call_details.get("PEER_HOLDING").contentEquals("true");
+        isAudioMuted = call_details.get("AUDIO_MUTED").contentEquals("true");
+    }
+
     public String getRecordPath() {
         return "";
     }
@@ -128,20 +142,22 @@ public class SipCall implements Parcelable {
     }
 
     public interface Direction {
-        int INCOMING = 1;
-        int OUTGOING = 2;
+        int INCOMING = 0;
+        int OUTGOING = 1;
     }
 
     public interface State {
         int NONE = 0;
-        int CONNECTING = 1;
-        int RINGING = 2;
-        int CURRENT = 3;
-        int HUNGUP = 4;
-        int BUSY = 5;
-        int FAILURE = 6;
-        int HOLD = 7;
-        int UNHOLD = 8;
+        int INCOMING = 1;
+        int CONNECTING = 2;
+        int RINGING = 3;
+        int CURRENT = 4;
+        int HUNGUP = 5;
+        int BUSY = 6;
+        int FAILURE = 7;
+        int HOLD = 8;
+        int UNHOLD = 9;
+        int INACTIVE = 10;
     }
 
     @Override
@@ -236,39 +252,61 @@ public class SipCall implements Parcelable {
     }
 
     public String getCallStateString() {
+        return getCallStateString(mCallState);
+    }
 
-        String text_state;
-
-        switch (mCallState) {
-            case State.NONE:
-                text_state = "NONE";
-                break;
+    public static String getCallStateString(int state) {
+        switch (state) {
+            case State.INCOMING:
+                return "INCOMING";
+            case State.CONNECTING:
+                return "CONNECTING";
             case State.RINGING:
-                text_state = "RINGING";
-                break;
+                return "RINGING";
             case State.CURRENT:
-                text_state = "CURRENT";
-                break;
+                return "CURRENT";
             case State.HUNGUP:
-                text_state = "HUNGUP";
-                break;
+                return "HUNGUP";
             case State.BUSY:
-                text_state = "BUSY";
-                break;
+                return "BUSY";
             case State.FAILURE:
-                text_state = "FAILURE";
-                break;
+                return "FAILURE";
             case State.HOLD:
-                text_state = "HOLD";
-                break;
+                return "HOLD";
             case State.UNHOLD:
-                text_state = "UNHOLD";
-                break;
+                return "UNHOLD";
+            case State.NONE:
             default:
-                text_state = "NULL";
+                return "NONE";
         }
+    }
 
-        return text_state;
+    public static int stateFromString(String state) {
+        switch (state) {
+            case "INCOMING":
+                return State.INCOMING;
+            case "CONNECTING":
+                return State.CONNECTING;
+            case "RINGING":
+                return State.RINGING;
+            case "CURRENT":
+                return State.CURRENT;
+            case "HUNGUP":
+                return State.HUNGUP;
+            case "BUSY":
+                return State.BUSY;
+            case "FAILURE":
+                return State.FAILURE;
+            case "HOLD":
+                return State.HOLD;
+            case "UNHOLD":
+                return State.UNHOLD;
+            case "INACTIVE":
+                return State.INACTIVE;
+            case "NONE":
+            default:
+                return State.NONE;
+        }
     }
 
     public boolean isRecording() {
@@ -282,7 +320,7 @@ public class SipCall implements Parcelable {
     public void printCallInfo() {
         Log.i(TAG, "CallInfo: CallID: " + mCallID);
         Log.i(TAG, "          AccountID: " + mAccount);
-        Log.i(TAG, "          CallState: " + mCallState);
+        Log.i(TAG, "          CallState: " + getCallStateString());
         Log.i(TAG, "          CallType: " + mCallType);
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/service/CallManagerCallBack.java b/ring-android/app/src/main/java/cx/ring/service/CallManagerCallBack.java
index c0b1615d952077c7ccab84e233ab90f444eac274..297f4fb4ea69275afb11e400f0803c3542694bd3 100644
--- a/ring-android/app/src/main/java/cx/ring/service/CallManagerCallBack.java
+++ b/ring-android/app/src/main/java/cx/ring/service/CallManagerCallBack.java
@@ -1,31 +1,15 @@
 package cx.ring.service;
 
-import android.support.v4.app.NotificationCompat;
-import android.app.PendingIntent;
 import android.content.Intent;
-import android.os.Bundle;
 import android.util.Log;
 
-import cx.ring.R;
-import cx.ring.client.CallActivity;
 import cx.ring.history.HistoryText;
-import cx.ring.model.CallContact;
 import cx.ring.model.TextMessage;
-import cx.ring.model.account.Account;
-import cx.ring.model.account.AccountDetailSrtp;
-import cx.ring.utils.SwigNativeConverter;
-
-import java.util.ArrayList;
-import java.util.Map;
-
-import cx.ring.model.Conference;
-import cx.ring.model.SecureSipCall;
-import cx.ring.model.SipCall;
 
 public class CallManagerCallBack extends Callback {
 
     private static final String TAG = "CallManagerCallBack";
-    private SipService mService;
+    private DRingService mService;
 
     static public final String CALL_STATE_CHANGED = "call-State-changed";
     static public final String INCOMING_CALL = "incoming-call";
@@ -44,7 +28,7 @@ public class CallManagerCallBack extends Callback {
     static public final String RTCP_REPORT_RECEIVED = "on_rtcp_report_received";
 
 
-    public CallManagerCallBack(SipService context) {
+    public CallManagerCallBack(DRingService context) {
         super();
         mService = context;
     }
@@ -52,67 +36,10 @@ public class CallManagerCallBack extends Callback {
     @Override
     public void callStateChanged(String callID, String newState, int detail_code) {
         Log.w(TAG, "on_call_state_changed : (" + callID + ", " + newState + ")");
-
-        Conference toUpdate = mService.findConference(callID);
-
-        if (toUpdate == null) {
-            Log.w(TAG, "callStateChanged: can't find call " + callID);
-            return;
-        }
-
         Intent intent = new Intent(CALL_STATE_CHANGED);
-        intent.putExtra("CallID", callID);
-        intent.putExtra("State", newState);
-        intent.putExtra("DetailCode", detail_code);
-
-        if (toUpdate.isRinging() && !newState.equals("RINGING")) {
-            Log.w(TAG, "Setting call start date " + callID);
-            toUpdate.getCallById(callID).setTimestampStart(System.currentTimeMillis());
-        }
-
-        switch (newState) {
-            case "CONNECTING":
-                toUpdate.setCallState(callID, SipCall.State.CONNECTING); break;
-            case "RINGING":
-                toUpdate.setCallState(callID, SipCall.State.RINGING); break;
-            case "CURRENT":
-                toUpdate.setCallState(callID, SipCall.State.CURRENT); break;
-            case "HOLD":
-                toUpdate.setCallState(callID, SipCall.State.HOLD); break;
-            case "UNHOLD":
-                toUpdate.setCallState(callID, SipCall.State.CURRENT); break;
-            case "HUNGUP":
-            case "INACTIVE":
-                Log.d(TAG, "Hanging up " + callID);
-                Log.w("CallNotification ", "Canceling " + toUpdate.notificationId);
-                mService.mNotificationManager.notificationManager.cancel(toUpdate.notificationId);
-                SipCall call = toUpdate.getCallById(callID);
-                if (!toUpdate.hasMultipleParticipants()) {
-                    if (toUpdate.isRinging() && toUpdate.isIncoming()) {
-                        mService.mNotificationManager.publishMissedCallNotification(mService.getConferences().get(callID));
-                    }
-                    toUpdate.setCallState(callID, SipCall.State.HUNGUP);
-                    mService.mHistoryManager.insertNewEntry(toUpdate);
-                    mService.getConferences().remove(toUpdate.getId());
-                } else {
-                    toUpdate.setCallState(callID, SipCall.State.HUNGUP);
-                    mService.mHistoryManager.insertNewEntry(call);
-                }
-                break;
-            case "BUSY":
-                mService.mNotificationManager.notificationManager.cancel(toUpdate.notificationId);
-                toUpdate.setCallState(callID, SipCall.State.BUSY);
-                mService.getConferences().remove(toUpdate.getId());
-                break;
-            case "FAILURE":
-                Log.w("CallNotification ", "Canceling " + toUpdate.notificationId);
-                mService.mNotificationManager.notificationManager.cancel(toUpdate.notificationId);
-                toUpdate.setCallState(callID, SipCall.State.FAILURE);
-                mService.getConferences().remove(toUpdate.getId());
-                Ringservice.hangUp(callID);
-                break;
-        }
-        intent.putExtra("conference", toUpdate);
+        intent.putExtra("call", callID);
+        intent.putExtra("state", newState);
+        intent.putExtra("detail_code", detail_code);
         mService.sendBroadcast(intent);
     }
 
@@ -122,53 +49,13 @@ public class CallManagerCallBack extends Callback {
         Log.w(TAG, "on_incoming_call(" + accountID + ", " + callID + ", " + from + ")");
 
         try {
-            StringMap details = Ringservice.getAccountDetails(accountID);
-            //VectMap credentials = Ringservice.getCredentials(accountID);
-            //StringMap state = Ringservice.getVolatileAccountDetails(accountID);
-            Account acc = new Account(accountID, details.toNative(), null, null);
-
             Intent toSend = new Intent(CallManagerCallBack.INCOMING_CALL);
-            toSend.setClass(mService, CallActivity.class);
-            toSend.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-            CallContact unknown = CallContact.buildUnknown(from);
-
-            SipCall newCall = new SipCall(callID, accountID, from, SipCall.Direction.INCOMING);
-            newCall.setContact(unknown);
-            newCall.setCallState(SipCall.State.RINGING);
-            newCall.setTimestampStart(System.currentTimeMillis());
-
-            Conference toAdd;
-            if (acc.useSecureLayer()) {
-               SecureSipCall secureCall = new SecureSipCall(newCall, acc.getSrtpDetails().getDetailString(AccountDetailSrtp.CONFIG_SRTP_KEY_EXCHANGE));
-                toAdd = new Conference(secureCall);
-            } else {
-                toAdd = new Conference(newCall);
-            }
-
-            mService.getConferences().put(toAdd.getId(), toAdd);
-
-            NotificationCompat.Builder noti = new NotificationCompat.Builder(mService)
-                    .setContentTitle("Incoming call with " + from)
-                    .setContentText("incoming call")
-                    .setOngoing(true)
-                    .setSmallIcon(R.drawable.ic_launcher)
-                    .addAction(R.drawable.ic_call_end_white_24dp, "End call",
-                            PendingIntent.getService(mService, 4278,
-                                new Intent(mService, SipService.class)
-                                        .setAction(SipService.ACTION_CALL_END)
-                                        .putExtra("conf", toAdd.getId()),
-                                    PendingIntent.FLAG_ONE_SHOT));
-
-            //mService.startForeground(toAdd.notificationId, noti);
-            Log.w("CallNotification ", "Adding for incoming " + toAdd.notificationId);
-            mService.mNotificationManager.notificationManager.notify(toAdd.notificationId, noti.build());
-
-            Bundle bundle = new Bundle();
-            bundle.putParcelable("conference", toAdd);
+            toSend.putExtra("call", callID);
+            toSend.putExtra("account", accountID);
+            toSend.putExtra("from", from);
             toSend.putExtra("resuming", false);
-            toSend.putExtras(bundle);
-            mService.startActivity(toSend);
+            mService.sendBroadcast(toSend);
+
             mService.mMediaManager.startRing("");
             mService.mMediaManager.obtainAudioFocus(true);
         } catch (Exception e) {
@@ -180,29 +67,7 @@ public class CallManagerCallBack extends Callback {
     public void conferenceCreated(final String confID) {
         Log.w(TAG, "CONFERENCE CREATED:" + confID);
         Intent intent = new Intent(CONF_CREATED);
-        Conference created = new Conference(confID);
-
-        StringVect all_participants = Ringservice.getParticipantList(confID);
-        Log.w(TAG, "all_participants:" + all_participants.size());
-        for (int i = 0; i < all_participants.size(); ++i) {
-            if (mService.getConferences().get(all_participants.get(i)) != null) {
-                created.addParticipant(mService.getConferences().get(all_participants.get(i)).getCallById(all_participants.get(i)));
-                mService.getConferences().remove(all_participants.get(i));
-            } else {
-                for (Map.Entry<String, Conference> stringConferenceEntry : mService.getConferences().entrySet()) {
-                    Conference tmp = stringConferenceEntry.getValue();
-                    for (SipCall c : tmp.getParticipants()) {
-                        if (c.getCallId().contentEquals(all_participants.get(i))) {
-                            created.addParticipant(c);
-                            mService.getConferences().get(tmp.getId()).removeParticipant(c);
-                        }
-                    }
-                }
-            }
-        }
-        intent.putExtra("conference", created);
-        intent.putExtra("confID", created.getId());
-        mService.getConferences().put(created.getId(), created);
+        intent.putExtra("conference", confID);
         mService.sendBroadcast(intent);
     }
 
@@ -214,30 +79,15 @@ public class CallManagerCallBack extends Callback {
         if (msg == null)
             return;
 
-        Conference conf = mService.getConferences().get(id);
-        if (conf == null) {
-            for (Conference tmp : mService.getConferences().values())
-                if (tmp.getCallById(id) != null) {
-                    conf = tmp;
-                    break;
-                }
-            if (conf == null) {
-                Log.w(TAG, "Discarding message for unknown call " + id);
-                return;
-            }
-        }
-
-        TextMessage message = new TextMessage(true, msg, from, id, conf.hasMultipleParticipants() ? null : conf.getParticipants().get(0).getAccount());
-        if (!conf.hasMultipleParticipants())
-            message.setContact(conf.getParticipants().get(0).getContact());
-
-        conf.addSipMessage(message);
+        TextMessage message = new TextMessage(true, msg, from, id, null/*, conf.hasMultipleParticipants() ? null : conf.getParticipants().get(0).getAccount()*/);
 
         mService.mHistoryManager.insertNewTextMessage(new HistoryText(message));
 
         Intent intent = new Intent(INCOMING_TEXT);
+        intent.putExtra("call", id);
+        intent.putExtra("from", from);
         intent.putExtra("txt", message);
-        intent.putExtra("conference", conf);
+        //intent.putExtra("conference", conf);
         mService.sendBroadcast(intent);
     }
 
@@ -245,69 +95,25 @@ public class CallManagerCallBack extends Callback {
     public void conferenceRemoved(String confID) {
         Log.i(TAG, "on_conference_removed:");
         Intent intent = new Intent(CONF_REMOVED);
-        intent.putExtra("confID", confID);
-
-        Conference toReInsert = mService.getConferences().get(confID);
-        for (SipCall call : toReInsert.getParticipants()) {
-            mService.getConferences().put(call.getCallId(), new Conference(call));
-        }
-
-        Conference conf = mService.getConferences().get(confID);
-
-        Log.w("CallNotification ", "Canceling " + conf.notificationId);
-        //NotificationManager mNotifyMgr = (NotificationManager) mService.getSystemService(Context.NOTIFICATION_SERVICE);
-        mService.mNotificationManager.notificationManager.cancel(conf.notificationId);
-
-        intent.putExtra("conference", conf);
-        mService.getConferences().remove(confID);
+        intent.putExtra("conference", confID);
         mService.sendBroadcast(intent);
-
-        if (mService.getConferences().size() == 0) {
-            mService.stopForeground(true);
-        }
-
     }
 
     @Override
     public void conferenceChanged(String confID, String state) {
         Log.i(TAG, "on_conference_state_changed:");
-        Intent intent = new Intent(CONF_CHANGED);
-        intent.putExtra("confID", confID);
-        intent.putExtra("State", state);
-
-
-        Log.i(TAG, "Received:" + intent.getAction());
         Log.i(TAG, "State:" + state);
 
-        Conference toModify = mService.getConferences().get(confID);
-        toModify.setCallState(confID, state);
-
-        ArrayList<String> newParticipants = SwigNativeConverter.convertSwigToNative(Ringservice.getParticipantList(intent.getStringExtra("confID")));
-
-        if (toModify.getParticipants().size() < newParticipants.size()) {
-            // We need to add the new participant to the conf
-            for (String newParticipant : newParticipants) {
-                if (toModify.getCallById(newParticipant) == null) {
-                    mService.addCallToConference(toModify.getId(), newParticipant);
-                }
-            }
-        } else if (toModify.getParticipants().size() > newParticipants.size()) {
-            Log.i(TAG, "toModify.getParticipants().size() > newParticipants.size()");
-            for (SipCall participant : toModify.getParticipants()) {
-                if (!newParticipants.contains(participant.getCallId())) {
-                    mService.detachCallFromConference(toModify.getId(), participant);
-                    break;
-                }
-            }
-        }
-
+        Intent intent = new Intent(CONF_CHANGED);
+        intent.putExtra("conference", confID);
+        intent.putExtra("state", state);
         mService.sendBroadcast(intent);
     }
 
     @Override
     public void recordPlaybackFilepath(String id, String filename) {
         Intent intent = new Intent();
-        intent.putExtra("callID", id);
+        intent.putExtra("call", id);
         intent.putExtra("file", filename);
         mService.sendBroadcast(intent);
     }
@@ -315,28 +121,25 @@ public class CallManagerCallBack extends Callback {
     @Override
     public void secureSdesOn(String callID) {
         Log.i(TAG, "on_secure_sdes_on");
-        SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
+        /*SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
         call.setInitialized();
-        call.useSecureSDES(true);
+        call.useSecureSDES(true);*/
     }
 
     @Override
     public void secureSdesOff(String callID) {
         Log.i(TAG, "on_secure_sdes_off");
-        SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
+        /*SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
         call.setInitialized();
-        call.useSecureSDES(false);
+        call.useSecureSDES(false);*/
     }
 
     @Override
     public void secureZrtpOn(String callID, String cipher) {
         Log.i(TAG, "on_secure_zrtp_on");
         Intent intent = new Intent(ZRTP_ON);
-        SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
-        call.setInitialized();
-        call.setZrtpSupport(true);
-        intent.putExtra("callID", callID);
-        intent.putExtra("conference", mService.findConference(callID));
+        intent.putExtra("call", callID);
+        intent.putExtra("cipher", cipher);
         mService.sendBroadcast(intent);
     }
 
@@ -344,15 +147,7 @@ public class CallManagerCallBack extends Callback {
     public void secureZrtpOff(String callID) {
         Log.i(TAG, "on_secure_zrtp_off");
         Intent intent = new Intent(ZRTP_OFF);
-        intent.putExtra("callID", callID);
-        SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
-        // Security can be off because call was hung up
-        if (call == null)
-            return;
-
-        call.setInitialized();
-        call.setZrtpSupport(false);
-        intent.putExtra("conference", mService.findConference(callID));
+        intent.putExtra("call", callID);
         mService.sendBroadcast(intent);
     }
 
@@ -360,14 +155,9 @@ public class CallManagerCallBack extends Callback {
     public void showSAS(String callID, String sas, int verified) {
         Log.i(TAG, "on_show_sas:" + sas);
         Intent intent = new Intent(DISPLAY_SAS);
-        SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
-        call.setSAS(sas);
-        call.sasConfirmedByZrtpLayer(verified);
-
-        intent.putExtra("callID", callID);
-        intent.putExtra("SAS", sas);
+        intent.putExtra("call", callID);
+        intent.putExtra("sas", sas);
         intent.putExtra("verified", verified);
-        intent.putExtra("conference", mService.findConference(callID));
         mService.sendBroadcast(intent);
     }
 
@@ -375,11 +165,7 @@ public class CallManagerCallBack extends Callback {
     public void zrtpNotSuppOther(String callID) {
         Log.i(TAG, "on_zrtp_not_supported");
         Intent intent = new Intent(ZRTP_NOT_SUPPORTED);
-        SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
-        call.setInitialized();
-        call.setZrtpSupport(false);
-        intent.putExtra("callID", callID);
-        intent.putExtra("conference", mService.findConference(callID));
+        intent.putExtra("call", callID);
         mService.sendBroadcast(intent);
     }
 
@@ -387,11 +173,7 @@ public class CallManagerCallBack extends Callback {
     public void zrtpNegotiationFailed(String callID, String reason, String severity) {
         Log.i(TAG, "on_zrtp_negociation_failed");
         Intent intent = new Intent(ZRTP_NEGOTIATION_FAILED);
-        SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
-        call.setInitialized();
-        call.setZrtpSupport(false);
-        intent.putExtra("callID", callID);
-        intent.putExtra("conference", mService.findConference(callID));
+        intent.putExtra("call", callID);
         mService.sendBroadcast(intent);
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/service/ConfigurationManagerCallback.java b/ring-android/app/src/main/java/cx/ring/service/ConfigurationManagerCallback.java
index e852a0d94173a86c8b6dbd5d584b8f3097e024bb..dba874d50430c80f0f7b082af1ea1248b38355c0 100644
--- a/ring-android/app/src/main/java/cx/ring/service/ConfigurationManagerCallback.java
+++ b/ring-android/app/src/main/java/cx/ring/service/ConfigurationManagerCallback.java
@@ -31,14 +31,14 @@ import cx.ring.model.TextMessage;
 
 public class ConfigurationManagerCallback extends ConfigurationCallback {
 
-    private  SipService mService;
+    private DRingService mService;
     private static final String TAG = "ConfigurationManagerCb";
 
     static public final String ACCOUNTS_CHANGED = "accounts-changed";
     static public final String ACCOUNT_STATE_CHANGED = "account-State-changed";
     static public final String INCOMING_TEXT = "incoming--txt-msg";
 
-    public ConfigurationManagerCallback(SipService context) {
+    public ConfigurationManagerCallback(DRingService context) {
         super();
         mService = context;
     }
@@ -84,8 +84,8 @@ public class ConfigurationManagerCallback extends ConfigurationCallback {
 
     private void sendAccountStateChangedMessage(String accoundID, String state, int code) {
         Intent intent = new Intent(ACCOUNT_STATE_CHANGED);
-        intent.putExtra("Account", accoundID);
-        intent.putExtra("State", state);
+        intent.putExtra("account", accoundID);
+        intent.putExtra("state", state);
         intent.putExtra("code", code);
         mService.sendBroadcast(intent);
     }
diff --git a/ring-android/app/src/main/java/cx/ring/service/SipService.java b/ring-android/app/src/main/java/cx/ring/service/DRingService.java
similarity index 72%
rename from ring-android/app/src/main/java/cx/ring/service/SipService.java
rename to ring-android/app/src/main/java/cx/ring/service/DRingService.java
index 81ed8862cd0af6b44a41401098999df78f425082..0842227d11a593f2aee354c4047e1301f703a11a 100644
--- a/ring-android/app/src/main/java/cx/ring/service/SipService.java
+++ b/ring-android/app/src/main/java/cx/ring/service/DRingService.java
@@ -58,18 +58,19 @@ import cx.ring.utils.SwigNativeConverter;
 import cx.ring.model.SipCall;
 
 
-public class SipService extends Service {
+public class DRingService extends Service {
 
-    static final String TAG = "SipService";
+    static final String TAG = "DRingService";
     private SipServiceExecutor mExecutor;
     private static HandlerThread executorThread;
 
     static public final String ACTION_CALL_ACCEPT = BuildConfig.APPLICATION_ID + ".action.CALL_ACCEPT";
     static public final String ACTION_CALL_REFUSE = BuildConfig.APPLICATION_ID + ".action.CALL_REFUSE";
-    //static public final String ACTION_CALL_REFUSE = BuildConfig.APPLICATION_ID + ".action.CALL_REFUSE";
 
     static public final String ACTION_CALL_END = BuildConfig.APPLICATION_ID + ".action.CALL_END";
 
+    static public final String DRING_CONNECTION_CHANGED = BuildConfig.APPLICATION_ID + ".event.DRING_CONNECTION_CHANGE";
+
     private Handler handler = new Handler();
     private static int POLLING_TIMEOUT = 50;
     private Runnable pollEvents = new Runnable() {
@@ -86,45 +87,12 @@ public class SipService extends Service {
     };
     private boolean isPjSipStackStarted = false;
 
-    protected SipNotifications mNotificationManager;
     protected HistoryManager mHistoryManager;
     protected MediaManager mMediaManager;
 
-    private final HashMap<String, Conference> mConferences = new HashMap<>();
     private ConfigurationManagerCallback configurationCallback;
     private CallManagerCallBack callManagerCallBack;
 
-    public HashMap<String, Conference> getConferences() {
-        return mConferences;
-    }
-
-    public void addCallToConference(String confId, String callId) {
-        if(mConferences.get(callId) != null){
-            // We add a simple call to a conference
-            Log.i(TAG, "// We add a simple call to a conference");
-            mConferences.get(confId).addParticipant(mConferences.get(callId).getParticipants().get(0));
-            mConferences.remove(callId);
-        } else {
-            Log.i(TAG, "addCallToConference");
-            for (Entry<String, Conference> stringConferenceEntry : mConferences.entrySet()) {
-                Conference tmp = stringConferenceEntry.getValue();
-                for (SipCall c : tmp.getParticipants()) {
-                    if (c.getCallId().contentEquals(callId)) {
-                        mConferences.get(confId).addParticipant(c);
-                        mConferences.get(tmp.getId()).removeParticipant(c);
-                    }
-                }
-            }
-        }
-    }
-
-    public void detachCallFromConference(String confId, SipCall call) {
-        Log.i(TAG, "detachCallFromConference");
-        Conference separate = new Conference(call);
-        mConferences.put(separate.getId(), separate);
-        mConferences.get(confId).removeParticipant(call);
-    }
-
     @Override
     public boolean onUnbind(Intent i) {
         super.onUnbind(i);
@@ -145,13 +113,9 @@ public class SipService extends Service {
 
         getExecutor().execute(new StartRunnable());
 
-        mNotificationManager = new SipNotifications(this);
         mMediaManager = new MediaManager(this);
         mHistoryManager = new HistoryManager(this);
-
-        mNotificationManager.onServiceCreate();
         mMediaManager.startService();
-
     }
 
     /* called for each startService() */
@@ -161,26 +125,17 @@ public class SipService extends Service {
         String action = intent == null ? null : intent.getAction();
         try {
             if (action != null) {
-                if (action.equals(ACTION_CALL_END)) {
-                    Conference c = findConference(intent.getStringExtra("conf"));
-                    if (c != null) {
-                        for (SipCall call : c.getParticipants()) {
-                            mBinder.hangUp(call.getCallId());
-                        }
-                        mBinder.hangUpConference(c.getId());
-                        Log.w("CallNotification ", "Canceling " + c.notificationId);
-                        mNotificationManager.notificationManager.cancel(c.notificationId);
-                    }
-                } else if (action.equals(ACTION_CALL_ACCEPT)) {
-                    Conference c = findConference(intent.getStringExtra("conf"));
-                    if (c != null) {
-                        mBinder.accept(c.getParticipants().get(0).getCallId());
-                    }
-                } else if (action.equals(ACTION_CALL_REFUSE)) {
-                    Conference c = findConference(intent.getStringExtra("conf"));
-                    if (c != null) {
-                        mBinder.refuse(c.getParticipants().get(0).getCallId());
-                    }
+                String callId = intent.getStringExtra("conf");
+                switch (action) {
+                    case ACTION_CALL_END:
+                        mBinder.hangUpConference(callId);
+                        break;
+                    case ACTION_CALL_ACCEPT:
+                        mBinder.accept(callId);
+                        break;
+                    case ACTION_CALL_REFUSE:
+                        mBinder.refuse(callId);
+                        break;
                 }
             }
         } catch (Exception e) {
@@ -193,8 +148,6 @@ public class SipService extends Service {
     @Override
     public void onDestroy() {
         Log.i(TAG, "onDestroy");
-        /* called once by stopService() */
-        mNotificationManager.onServiceDestroy();
         mMediaManager.stopService();
         getExecutor().execute(new FinalizeRunnable());
         super.onDestroy();
@@ -211,7 +164,7 @@ public class SipService extends Service {
         if (executorThread == null) {
             Log.d(TAG, "Creating new handler thread");
             // ADT gives a fake warning due to bad parse rule.
-            executorThread = new HandlerThread("SipService.Executor");
+            executorThread = new HandlerThread("DRingService.Executor");
             executorThread.start();
         }
         return executorThread.getLooper();
@@ -225,21 +178,6 @@ public class SipService extends Service {
         return mExecutor;
     }
 
-    public SipCall getCallById(String callID) {
-        if (getConferences().get(callID) != null) {
-            return getConferences().get(callID).getCallById(callID);
-        } else {
-            // Check if call is in a conference
-            for (Entry<String, Conference> stringConferenceEntry : getConferences().entrySet()) {
-                Conference tmp = stringConferenceEntry.getValue();
-                SipCall c = tmp.getCallById(callID);
-                if (c != null)
-                    return c;
-            }
-        }
-        return null;
-    }
-
     // Executes immediate tasks in a single executorThread.
     public static class SipServiceExecutor extends Handler {
 
@@ -357,6 +295,9 @@ public class SipService extends Service {
             Ringservice.fini();
             isPjSipStackStarted = false;
             Log.i(TAG, "PjSIPStack stopped");
+            Intent intent = new Intent(DRING_CONNECTION_CHANGED);
+            intent.putExtra("connected", isPjSipStackStarted);
+            sendBroadcast(intent);
         }
     }
 
@@ -382,6 +323,9 @@ public class SipService extends Service {
         Ringservice.init(configurationCallback, callManagerCallBack);
         handler.postDelayed(pollEvents, POLLING_TIMEOUT);
         Log.i(TAG, "PjSIPStack started");
+        Intent intent = new Intent(DRING_CONNECTION_CHANGED);
+        intent.putExtra("connected", isPjSipStackStarted);
+        sendBroadcast(intent);
     }
 
     // Enforce same thread contract to ensure we do not call from somewhere else
@@ -410,7 +354,6 @@ public class SipService extends Service {
 
     public abstract class SipRunnableWithReturn<T> implements Runnable {
         private T obj = null;
-        //boolean done = false;
 
         protected abstract T doRun() throws SameThreadException, RemoteException;
 
@@ -455,7 +398,7 @@ public class SipService extends Service {
      * *********************************
      */
 
-    private final ISipService.Stub mBinder = new ISipService.Stub() {
+    private final IDRingService.Stub mBinder = new IDRingService.Stub() {
 
         @Override
         public String placeCall(final SipCall call) {
@@ -463,9 +406,7 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<String>() {
                 @Override
                 protected String doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.placeCall() thread running...");
-                    Conference toAdd;
-                    //mConferences.put(toAdd.getId(), toAdd);
+                    Log.i(TAG, "DRingService.placeCall() thread running...");
                     mMediaManager.obtainAudioFocus(false);
 
                     String number = call.getNumber();
@@ -473,37 +414,8 @@ public class SipService extends Service {
                         number = call.getContact().getPhones().get(0).getNumber();
                     }
 
-                    Log.i(TAG, "SipService.placeCall() calling... " + number);
-                    String call_id = Ringservice.placeCall(call.getAccount(), number);
-                    call.setCallID(call_id);
-                    if (!call_id.isEmpty()) {
-                        final Map<String, String> details = getAccountDetails(call.getAccount());
-                        if(details.get(AccountDetailBasic.CONFIG_ACCOUNT_TYPE).contentEquals(AccountDetailBasic.ACCOUNT_TYPE_RING)
-                                || details.get(AccountDetailSrtp.CONFIG_SRTP_ENABLE).contentEquals(AccountDetail.TRUE_STR)
-                                || details.get(AccountDetailTls.CONFIG_TLS_ENABLE).contentEquals(AccountDetail.TRUE_STR)) {
-                            Log.i(TAG, "SipService.placeCall() call is secure");
-                            SecureSipCall secureCall = new SecureSipCall(call, details.get(AccountDetailSrtp.CONFIG_SRTP_KEY_EXCHANGE));
-                            toAdd = new Conference(secureCall);
-                        } else {
-                            toAdd = new Conference(call);
-                        }
-                        Log.i(TAG, "SipService.placeCall() returned with call id " + call_id);
-                        mConferences.put(call_id, toAdd);
-                        Notification noti = new Notification.Builder(SipService.this)
-                                .setContentTitle("Ongoing call with " + call.getContact().getDisplayName())
-                                .setContentText("outgoing call")
-                                .setOngoing(true)
-                                .setSmallIcon(R.drawable.ic_launcher)
-                                //.setContentIntent()
-                                /*.setContentText(subject)
-                                .setSmallIcon(R.drawable.new_mail)
-                                .setLargeIcon(aBitmap)*/
-                                .build();
-                        //startForeground(toAdd.notificationId, noti);
-                        Log.w("CallNotification ", "Adding for outgoing " + toAdd.notificationId);
-                        mNotificationManager.notificationManager.notify(toAdd.notificationId, noti);
-                    }
-                    return call_id;
+                    Log.i(TAG, "DRingService.placeCall() calling... " + number);
+                    return Ringservice.placeCall(call.getAccount(), number);
                 }
             });
         }
@@ -515,7 +427,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.refuse() thread running...");
+                    Log.i(TAG, "DRingService.refuse() thread running...");
                     Ringservice.refuse(callID);
                     Ringservice.hangUp(callID);
                 }
@@ -529,7 +441,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.accept() thread running...");
+                    Log.i(TAG, "DRingService.accept() thread running...");
                     Ringservice.accept(callID);
                     mMediaManager.RouteToInternalSpeaker();
                 }
@@ -543,13 +455,8 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.hangUp() thread running...");
+                    Log.i(TAG, "DRingService.hangUp() thread running...");
                     Ringservice.hangUp(callID);
-                    removeCall(callID);
-                    if(mConferences.size() == 0) {
-                        Log.i(TAG, "No more calls!");
-                        mMediaManager.abandonAudioFocus();
-                    }
                 }
             });
         }
@@ -559,7 +466,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.hold() thread running...");
+                    Log.i(TAG, "DRingService.hold() thread running...");
                     Ringservice.hold(callID);
                 }
             });
@@ -570,18 +477,23 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.unhold() thread running...");
+                    Log.i(TAG, "DRingService.unhold() thread running...");
                     Ringservice.unhold(callID);
                 }
             });
         }
 
+        @Override
+        public boolean isStarted() throws RemoteException {
+            return isPjSipStackStarted;
+        }
+
         @Override
         public Map<String, String> getCallDetails(final String callID) throws RemoteException {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
                 @Override
                 protected Map<String, String> doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getCallDetails() thread running...");
+                    Log.i(TAG, "DRingService.getCallDetails() thread running...");
                     return Ringservice.getCallDetails(callID).toNative();
                 }
             });
@@ -592,7 +504,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.setAudioPlugin() thread running...");
+                    Log.i(TAG, "DRingService.setAudioPlugin() thread running...");
                     Ringservice.setAudioPlugin(audioPlugin);
                 }
             });
@@ -603,7 +515,7 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<String>() {
                 @Override
                 protected String doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getCurrentAudioOutputPlugin() thread running...");
+                    Log.i(TAG, "DRingService.getCurrentAudioOutputPlugin() thread running...");
                     return Ringservice.getCurrentAudioOutputPlugin();
                 }
             });
@@ -614,7 +526,7 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<List<String>>() {
                 @Override
                 protected List<String> doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getAccountList() thread running...");
+                    Log.i(TAG, "DRingService.getAccountList() thread running...");
                     return new ArrayList<>(Ringservice.getAccountList());
                 }
             });
@@ -625,7 +537,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.setAccountsOrder() thread running...");
+                    Log.i(TAG, "DRingService.setAccountsOrder() thread running...");
                     Ringservice.setAccountsOrder(order);
                 }
             });
@@ -636,7 +548,7 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
                 @Override
                 protected Map<String, String> doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getAccountDetails() thread running...");
+                    Log.i(TAG, "DRingService.getAccountDetails() thread running...");
                     return Ringservice.getAccountDetails(accountID).toNative();
                 }
             });
@@ -646,7 +558,7 @@ public class SipService extends Service {
         // Hashmap runtime cast
         @Override
         public void setAccountDetails(final String accountId, final Map map) {
-            Log.i(TAG, "SipService.setAccountDetails() " + map.get("Account.hostname"));
+            Log.i(TAG, "DRingService.setAccountDetails() " + map.get("Account.hostname"));
             final StringMap swigmap = StringMap.toSwig(map);
 
             getExecutor().execute(new SipRunnable() {
@@ -654,7 +566,7 @@ public class SipService extends Service {
                 protected void doRun() throws SameThreadException {
 
                     Ringservice.setAccountDetails(accountId, swigmap);
-                    Log.i(TAG, "SipService.setAccountDetails() thread running... " + swigmap.get("Account.hostname"));
+                    Log.i(TAG, "DRingService.setAccountDetails() thread running... " + swigmap.get("Account.hostname"));
                 }
 
             });
@@ -665,7 +577,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.setAccountActive() thread running... " + accountId + " -> " + active);
+                    Log.i(TAG, "DRingService.setAccountActive() thread running... " + accountId + " -> " + active);
                     Ringservice.setAccountActive(accountId, active);
                 }
             });
@@ -676,7 +588,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.setAccountsActive() thread running... " + active);
+                    Log.i(TAG, "DRingService.setAccountsActive() thread running... " + active);
                     StringVect list = Ringservice.getAccountList();
                     for (int i=0, n=list.size(); i<n; i++)
                         Ringservice.setAccountActive(list.get(i), active);
@@ -689,7 +601,7 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
                 @Override
                 protected Map<String, String> doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getVolatileAccountDetails() thread running...");
+                    Log.i(TAG, "DRingService.getVolatileAccountDetails() thread running...");
                     return Ringservice.getVolatileAccountDetails(accountId).toNative();
                 }
             });
@@ -700,7 +612,7 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
                 @Override
                 protected Map<String, String> doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getAccountTemplate() thread running...");
+                    Log.i(TAG, "DRingService.getAccountTemplate() thread running...");
                     return Ringservice.getAccountTemplate(accountType).toNative();
                 }
             });
@@ -713,7 +625,7 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<String>() {
                 @Override
                 protected String doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.addAccount() thread running...");
+                    Log.i(TAG, "DRingService.addAccount() thread running...");
                     return Ringservice.addAccount(StringMap.toSwig(map));
                 }
             });
@@ -724,7 +636,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.setAccountDetails() thread running...");
+                    Log.i(TAG, "DRingService.setAccountDetails() thread running...");
                     Ringservice.removeAccount(accountId);
                 }
             });
@@ -739,7 +651,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.transfer() thread running...");
+                    Log.i(TAG, "DRingService.transfer() thread running...");
                     if (Ringservice.transfer(callID, to)) {
                         Bundle bundle = new Bundle();
                         bundle.putString("CallID", callID);
@@ -759,7 +671,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.attendedTransfer() thread running...");
+                    Log.i(TAG, "DRingService.attendedTransfer() thread running...");
                     if (Ringservice.attendedTransfer(transferID, targetID)) {
                         Log.i(TAG, "OK");
                     } else
@@ -778,7 +690,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.createConference() thread running...");
+                    Log.i(TAG, "DRingService.createConference() thread running...");
                     Ringservice.removeConference(confID);
                 }
             });
@@ -790,7 +702,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.joinParticipant() thread running...");
+                    Log.i(TAG, "DRingService.joinParticipant() thread running...");
                     Ringservice.joinParticipant(sel_callID, drag_callID);
                     // Generate a CONF_CREATED callback
                 }
@@ -803,9 +715,8 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.addParticipant() thread running...");
+                    Log.i(TAG, "DRingService.addParticipant() thread running...");
                     Ringservice.addParticipant(call.getCallId(), confID);
-                    mConferences.get(confID).getParticipants().add(call);
                 }
             });
 
@@ -816,7 +727,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.addMainParticipant() thread running...");
+                    Log.i(TAG, "DRingService.addMainParticipant() thread running...");
                     Ringservice.addMainParticipant(confID);
                 }
             });
@@ -828,19 +739,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.detachParticipant() thread running...");
-                    Log.i(TAG, "Detaching " + callID);
-                    Iterator<Entry<String, Conference>> it = mConferences.entrySet().iterator();
-                    Log.i(TAG, "mConferences size " + mConferences.size());
-                    while (it.hasNext()) {
-                        Conference tmp = it.next().getValue();
-                        Log.i(TAG, "conf has " + tmp.getParticipants().size() + " participants");
-                        if (tmp.contains(callID)) {
-                            Conference toDetach = new Conference(tmp.getCallById(callID));
-                            mConferences.put(toDetach.getId(), toDetach);
-                            Log.i(TAG, "Call found and put in current_calls");
-                        }
-                    }
+                    Log.i(TAG, "DRingService.detachParticipant() thread running... " + callID);
                     Ringservice.detachParticipant(callID);
                 }
             });
@@ -852,7 +751,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.joinConference() thread running...");
+                    Log.i(TAG, "DRingService.joinConference() thread running...");
                     Ringservice.joinConference(sel_confID, drag_confID);
                 }
             });
@@ -865,7 +764,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.joinConference() thread running...");
+                    Log.i(TAG, "DRingService.joinConference() thread running...");
                     Ringservice.hangUpConference(confID);
                 }
             });
@@ -877,7 +776,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.holdConference() thread running...");
+                    Log.i(TAG, "DRingService.holdConference() thread running...");
                     Ringservice.holdConference(confID);
                 }
             });
@@ -889,7 +788,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.unholdConference() thread running...");
+                    Log.i(TAG, "DRingService.unholdConference() thread running...");
                     Ringservice.unholdConference(confID);
                 }
             });
@@ -901,36 +800,27 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<Boolean>() {
                 @Override
                 protected Boolean doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.isRecording() thread running...");
+                    Log.i(TAG, "DRingService.isRecording() thread running...");
                     return Ringservice.isConferenceParticipant(callID);
                 }
             });
         }
 
         @Override
-        public HashMap<String, Conference> getConferenceList() throws RemoteException {
-            // class ConfList extends SipRunnableWithReturn {
-            // @Override
-            // protected StringVect doRun() throws SameThreadException {
-            // Log.i(TAG, "SipService.getConferenceList() thread running...");
-            // return callManagerJNI.getConferenceList();
-            // }
-            // }
-            // ;
-            // ConfList runInstance = new ConfList();
-            // getExecutor().execute(runInstance);
-            // while (!runInstance.isDone()) {
-            // // Log.w(TAG, "Waiting for getConferenceList");
-            // }
-            // StringVect swigvect = (StringVect) runInstance.getVal();
-            //
-            // ArrayList<String> nativelist = new ArrayList<String>();
-            //
-            // for (int i = 0; i < swigvect.size(); i++)
-            // nativelist.add(swigvect.get(i));
-            //
-            // return nativelist;
-            return mConferences;
+        public Map<String, Map<String, String>> getConferenceList() throws RemoteException {
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, Map<String, String>>>() {
+                @Override
+                protected Map<String, Map<String, String>> doRun() throws SameThreadException {
+                    Log.i(TAG, "DRingService.getConferenceList() thread running...");
+                    StringVect ids = Ringservice.getConferenceList();
+                    HashMap<String, Map<String, String>> confs = new HashMap<>(ids.size());
+                    for (int i=0; i<ids.size(); i++) {
+                        String id = ids.get(i);
+                        confs.put(id, Ringservice.getConferenceDetails(id).toNative());
+                    }
+                    return confs;
+                }
+            });
         }
 
         @Override
@@ -938,7 +828,7 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<List<String>>() {
                 @Override
                 protected List<String> doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getParticipantList() thread running...");
+                    Log.i(TAG, "DRingService.getParticipantList() thread running...");
                     return new ArrayList<>(Ringservice.getParticipantList(confID));
                 }
             });
@@ -955,7 +845,7 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<String>() {
                 @Override
                 protected String doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getConferenceDetails() thread running...");
+                    Log.i(TAG, "DRingService.getConferenceDetails() thread running...");
                     return Ringservice.getConferenceDetails(callID).get("CONF_STATE");
                 }
             });
@@ -966,7 +856,7 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<String>() {
                 @Override
                 protected String doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getRecordPath() thread running...");
+                    Log.i(TAG, "DRingService.getRecordPath() thread running...");
                     return Ringservice.getRecordPath();
                 }
             });
@@ -977,18 +867,8 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<Boolean>() {
                 @Override
                 protected Boolean doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.toggleRecordingCall() thread running...");
-                    boolean result = Ringservice.toggleRecording(id);
-
-                    if (getConferences().containsKey(id)) {
-                        getConferences().get(id).setRecording(result);
-                    } else {
-                        for (Conference c : getConferences().values()) {
-                            if (c.getCallById(id) != null)
-                                c.getCallById(id).setRecording(result);
-                        }
-                    }
-                    return result;
+                    Log.i(TAG, "DRingService.toggleRecordingCall() thread running...");
+                    return Ringservice.toggleRecording(id);
                 }
             });
         }
@@ -998,7 +878,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.setRecordingCall() thread running...");
+                    Log.i(TAG, "DRingService.setRecordingCall() thread running...");
                     Ringservice.startRecordedFilePlayback(filepath);
                 }
             });
@@ -1010,7 +890,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.stopRecordedFilePlayback() thread running...");
+                    Log.i(TAG, "DRingService.stopRecordedFilePlayback() thread running...");
                     Ringservice.stopRecordedFilePlayback(filepath);
                 }
             });
@@ -1021,7 +901,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.setRecordPath() " + path + " thread running...");
+                    Log.i(TAG, "DRingService.setRecordPath() " + path + " thread running...");
                     Ringservice.setRecordPath(path);
                 }
             });
@@ -1032,18 +912,12 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.sendTextMessage() thread running...");
+                    Log.i(TAG, "DRingService.sendTextMessage() thread running...");
                     message.setCallId(callID);
-                    //Conference conf = findConference(callID);
                     mHistoryManager.insertNewTextMessage(new HistoryText(message));
                     StringMap messages  = new StringMap();
                     messages.set("text/plain", message.getMessage());
                     Ringservice.sendTextMessage(callID, messages, "", false);
-                    if (getConferences().get(callID) != null)
-                        getConferences().get(callID).addSipMessage(message);
-                    Intent intent = new Intent(CallManagerCallBack.INCOMING_TEXT);
-                    intent.putExtra("txt", message);
-                    sendBroadcast(intent);
                 }
             });
         }
@@ -1053,7 +927,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.sendAccountTextMessage() thread running... " + accountID + " " + to + " " + msg);
+                    Log.i(TAG, "DRingService.sendAccountTextMessage() thread running... " + accountID + " " + to + " " + msg);
                     TextMessage message = new TextMessage(false, msg, to, null, accountID);
                     mHistoryManager.insertNewTextMessage(new HistoryText(message));
                     Ringservice.sendAccountTextMessage(accountID, to, msg);
@@ -1069,12 +943,12 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<ArrayList<Codec>>() {
                 @Override
                 protected ArrayList<Codec> doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getAudioCodecList() thread running...");
+                    Log.i(TAG, "DRingService.getAudioCodecList() thread running...");
                     ArrayList<Codec> results = new ArrayList<>();
 
                     UintVect active_payloads = Ringservice.getActiveCodecList(accountID);
                     for (int i = 0; i < active_payloads.size(); ++i) {
-                        Log.i(TAG, "SipService.getCodecDetails(" + accountID +", "+ active_payloads.get(i) +")");
+                        Log.i(TAG, "DRingService.getCodecDetails(" + accountID +", "+ active_payloads.get(i) +")");
                         results.add(new Codec(active_payloads.get(i), Ringservice.getCodecDetails(accountID, active_payloads.get(i)), true));
 
                     }
@@ -1107,7 +981,7 @@ public class SipService extends Service {
 
                 @Override
                 protected StringMap doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getRingtoneList() thread running...");
+                    Log.i(TAG, "DRingService.getRingtoneList() thread running...");
                     return Ringservice.getR();
                 }
             }
@@ -1132,7 +1006,7 @@ public class SipService extends Service {
 
                 @Override
                 protected Boolean doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.isCaptureMuted() thread running...");
+                    Log.i(TAG, "DRingService.isCaptureMuted() thread running...");
                     return Ringservice.sflph_config_check_for_private_key(pemPath);
                 }
             }
@@ -1151,7 +1025,7 @@ public class SipService extends Service {
 
                 @Override
                 protected Boolean doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.isCaptureMuted() thread running...");
+                    Log.i(TAG, "DRingService.isCaptureMuted() thread running...");
                     return Ringservice.sflph_config_check_certificate_validity(pemPath, pemPath);
                 }
             }
@@ -1170,7 +1044,7 @@ public class SipService extends Service {
 
                 @Override
                 protected Boolean doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.isCaptureMuted() thread running...");
+                    Log.i(TAG, "DRingService.isCaptureMuted() thread running...");
                     return Ringservice.sflph_config_check_hostname_certificate(host, port);
                 }
             }
@@ -1189,7 +1063,7 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
                 @Override
                 protected Map<String, String> doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.validateCertificatePath() thread running...");
+                    Log.i(TAG, "DRingService.validateCertificatePath() thread running...");
                     return Ringservice.validateCertificatePath(accountID, certificatePath, privateKeyPath, "", "").toNative();
                 }
             });
@@ -1200,7 +1074,7 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
                 @Override
                 protected Map<String, String> doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.validateCertificate() thread running...");
+                    Log.i(TAG, "DRingService.validateCertificate() thread running...");
                     return Ringservice.validateCertificate(accountID, certificate).toNative();
                 }
             });
@@ -1211,7 +1085,7 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
                 @Override
                 protected Map<String, String> doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getCertificateDetailsPath() thread running...");
+                    Log.i(TAG, "DRingService.getCertificateDetailsPath() thread running...");
                     return Ringservice.getCertificateDetails(certificatePath).toNative();
                 }
             });
@@ -1222,7 +1096,7 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
                 @Override
                 protected Map<String, String> doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getCertificateDetails() thread running...");
+                    Log.i(TAG, "DRingService.getCertificateDetails() thread running...");
                     return Ringservice.getCertificateDetails(certificateRaw).toNative();
                 }
             });
@@ -1233,7 +1107,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.setActiveAudioCodecList() thread running...");
+                    Log.i(TAG, "DRingService.setActiveAudioCodecList() thread running...");
                     UintVect list = new UintVect();
                     for (Object codec : codecs) {
                         list.add((Long) codec);
@@ -1243,41 +1117,26 @@ public class SipService extends Service {
             });
         }
 
-
-        @Override
-        public Conference getCurrentCall() throws RemoteException {
-            for (Conference conf : mConferences.values()) {
-                if (conf.isIncoming())
-                    return conf;
-            }
-
-            for (Conference conf : mConferences.values()) {
-                if (conf.isOnGoing())
-                    return conf;
-            }
-
-            return null;
-        }
-
         @Override
         public void playDtmf(final String key) throws RemoteException {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.playDtmf() thread running...");
+                    Log.i(TAG, "DRingService.playDtmf() thread running...");
                     Ringservice.playDTMF(key);
                 }
             });
         }
 
         @Override
-        public List<Conference> getConcurrentCalls() throws RemoteException {
-            return new ArrayList<>(mConferences.values());
-        }
-
-        @Override
-        public Conference getConference(String id) throws RemoteException {
-            return mConferences.get(id);
+        public Map<String, String> getConference(final String id) throws RemoteException {
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
+                @Override
+                protected Map<String, String> doRun() throws SameThreadException {
+                    Log.i(TAG, "DRingService.getCredentials() thread running...");
+                    return Ringservice.getConferenceDetails(id).toNative();
+                }
+            });
         }
 
         @Override
@@ -1285,7 +1144,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.setMuted() thread running...");
+                    Log.i(TAG, "DRingService.setMuted() thread running...");
                     Ringservice.muteCapture(mute);
                 }
             });
@@ -1297,7 +1156,7 @@ public class SipService extends Service {
 
                 @Override
                 protected Boolean doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.isCaptureMuted() thread running...");
+                    Log.i(TAG, "DRingService.isCaptureMuted() thread running...");
                     return Ringservice.isCaptureMuted();
                 }
             });
@@ -1308,9 +1167,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.confirmSAS() thread running...");
-                    SecureSipCall call = (SecureSipCall) getCallById(callID);
-                    call.setSASConfirmed(true);
+                    Log.i(TAG, "DRingService.confirmSAS() thread running...");
                     Ringservice.setSASVerified(callID);
                 }
             });
@@ -1322,7 +1179,7 @@ public class SipService extends Service {
             return getExecutor().executeAndReturn(new SipRunnableWithReturn<List<String>>() {
                 @Override
                 protected List<String> doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getCredentials() thread running...");
+                    Log.i(TAG, "DRingService.getCredentials() thread running...");
                     return SwigNativeConverter.convertSwigToNative(Ringservice.getSupportedTlsMethod());
                 }
             });
@@ -1334,7 +1191,7 @@ public class SipService extends Service {
 
                 @Override
                 protected List doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getCredentials() thread running...");
+                    Log.i(TAG, "DRingService.getCredentials() thread running...");
                     return Ringservice.getCredentials(accountID).toNative();
                 }
             }
@@ -1349,7 +1206,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.setCredentials() thread running...");
+                    Log.i(TAG, "DRingService.setCredentials() thread running...");
                     Ringservice.setCredentials(accountID, SwigNativeConverter.convertFromNativeToSwig(creds));
                 }
             });
@@ -1360,7 +1217,7 @@ public class SipService extends Service {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
-                    Log.i(TAG, "SipService.registerAllAccounts() thread running...");
+                    Log.i(TAG, "DRingService.registerAllAccounts() thread running...");
                     Ringservice.registerAllAccounts();
                 }
             });
@@ -1375,31 +1232,4 @@ public class SipService extends Service {
         }
 
     };
-
-    private void removeCall(String callID) {
-        Conference conf = findConference(callID);
-        if(conf == null)
-            return;
-        if(conf.getParticipants().size() == 1)
-            getConferences().remove(conf.getId());
-        else
-            conf.removeParticipant(conf.getCallById(callID));
-        Log.w("CallNotification ", "Canceling " + conf.notificationId);
-        mNotificationManager.notificationManager.cancel(conf.notificationId);
-    }
-
-    protected Conference findConference(String callID) {
-        Conference result = getConferences().get(callID);
-        if (result != null)
-            return result;
-        for (Entry<String, Conference> stringConferenceEntry : getConferences().entrySet()) {
-            Conference tmp = stringConferenceEntry.getValue();
-            for (SipCall c : tmp.getParticipants()) {
-                if (c.getCallId() != null && callID.contentEquals(c.getCallId())) {
-                    return tmp;
-                }
-            }
-        }
-        return null;
-    }
 }
diff --git a/ring-android/app/src/main/java/cx/ring/service/ISipService.aidl b/ring-android/app/src/main/java/cx/ring/service/IDRingService.aidl
similarity index 94%
rename from ring-android/app/src/main/java/cx/ring/service/ISipService.aidl
rename to ring-android/app/src/main/java/cx/ring/service/IDRingService.aidl
index bd77ecfcf998cba38a5c823f7d75b46e83a82727..d51a998ed4e38cdc54415c7e6d5fe7d55163ecf4 100644
--- a/ring-android/app/src/main/java/cx/ring/service/ISipService.aidl
+++ b/ring-android/app/src/main/java/cx/ring/service/IDRingService.aidl
@@ -2,10 +2,11 @@ package cx.ring.service;
 
 import cx.ring.model.SipCall;
 import cx.ring.model.TextMessage;
-import cx.ring.model.Conference;
 
-interface ISipService {
-    
+interface IDRingService {
+
+    boolean isStarted();
+
     Map getCallDetails(in String callID);
     String placeCall(in SipCall call);
     void refuse(in String callID);
@@ -83,10 +84,7 @@ interface ISipService {
     List getParticipantList(in String confID);
     String getConferenceId(in String callID);
     String getConferenceDetails(in String callID);
-    
-    Conference getCurrentCall();
-    List getConcurrentCalls();
 
-    Conference getConference(in String id);
+    Map getConference(in String id);
 
 }
diff --git a/ring-android/app/src/main/java/cx/ring/service/LocalService.java b/ring-android/app/src/main/java/cx/ring/service/LocalService.java
index 3da1a133d423c8f8c697062370aa61f21d32ad22..1c79d80a8f282c092bdb16f4148c8d8af100dd33 100644
--- a/ring-android/app/src/main/java/cx/ring/service/LocalService.java
+++ b/ring-android/app/src/main/java/cx/ring/service/LocalService.java
@@ -46,6 +46,7 @@ import android.os.RemoteException;
 import android.provider.Contacts;
 import android.provider.ContactsContract;
 import android.support.annotation.NonNull;
+import android.support.v4.app.NotificationManagerCompat;
 import android.support.v4.content.ContextCompat;
 import android.util.Log;
 import android.util.LongSparseArray;
@@ -72,10 +73,13 @@ import cx.ring.loaders.ContactsLoader;
 import cx.ring.model.CallContact;
 import cx.ring.model.Conference;
 import cx.ring.model.Conversation;
+import cx.ring.model.SecureSipCall;
 import cx.ring.model.SipCall;
 import cx.ring.model.SipUri;
 import cx.ring.model.TextMessage;
 import cx.ring.model.account.Account;
+import cx.ring.model.account.AccountDetailSrtp;
+import cx.ring.model.account.AccountDetailTls;
 
 
 public class LocalService extends Service
@@ -90,7 +94,7 @@ public class LocalService extends Service
 
     public final static String[] REQUIRED_RUNTIME_PERMISSIONS = {Manifest.permission.READ_CONTACTS, Manifest.permission.RECORD_AUDIO};
 
-    private ISipService mService = null;
+    private IDRingService mService = null;
     private final ContactsContentObserver contactContentObserver = new ContactsContentObserver();
 
     // Binder given to clients
@@ -139,13 +143,42 @@ public class LocalService extends Service
         return isWifiConn;
     }
 
+    public Conference placeCall(SipCall call) {
+        Conference conf = null;
+        CallContact contact = call.getContact();
+        Conversation conv = startConversation(contact);
+        try {
+            String callId = mService.placeCall(call);
+            if (callId == null || callId.isEmpty()) {
+                //CallActivity.this.terminateCall();
+                return null;
+            }
+            call.setCallID(callId);
+            Account acc = getAccount(call.getAccount());
+            if(acc.isRing()
+                    || acc.getSrtpDetails().getDetailBoolean(AccountDetailSrtp.CONFIG_SRTP_ENABLE)
+                    || acc.getTlsDetails().getDetailBoolean(AccountDetailTls.CONFIG_TLS_ENABLE)) {
+                Log.i(TAG, "DRingService.placeCall() call is secure");
+                SecureSipCall secureCall = new SecureSipCall(call, acc.getSrtpDetails().getDetailString(AccountDetailSrtp.CONFIG_SRTP_KEY_EXCHANGE));
+                conf = new Conference(secureCall);
+            } else {
+                conf = new Conference(call);
+            }
+            conf.getParticipants().get(0).setContact(contact);
+            conv.addConference(conf);
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+        return conf;
+    }
+
     public interface Callbacks {
-        ISipService getRemoteService();
+        IDRingService getRemoteService();
         LocalService getService();
     }
     public static class DummyCallbacks implements Callbacks {
         @Override
-        public ISipService getRemoteService() {
+        public IDRingService getRemoteService() {
             return null;
         }
         @Override
@@ -170,7 +203,7 @@ public class LocalService extends Service
         };
 
         historyManager = new HistoryManager(this);
-        Intent intent = new Intent(this, SipService.class);
+        Intent intent = new Intent(this, DRingService.class);
         startService(intent);
         bindService(intent, mConnection, BIND_AUTO_CREATE | BIND_IMPORTANT | BIND_ABOVE_CLIENT);
 
@@ -220,7 +253,12 @@ public class LocalService extends Service
             for (CallContact c : data.contacts)
                 systemContactCache.put(c.getId(), c);
 
-            sendBroadcast(new Intent(ACTION_CONF_UPDATE));
+            new ConversationLoader(LocalService.this, systemContactCache){
+                @Override
+                protected void onPostExecute(Map<String, Conversation> res) {
+                    updated(res);
+                }
+            }.execute();
         }
     };
 
@@ -228,12 +266,18 @@ public class LocalService extends Service
         @Override
         public void onServiceConnected(ComponentName className, IBinder service) {
             Log.w(TAG, "onServiceConnected " + className.getClassName());
-            mService = ISipService.Stub.asInterface(service);
+            mService = IDRingService.Stub.asInterface(service);
             //mBound = true;
             mAccountLoader = new AccountsLoader(LocalService.this);
             mAccountLoader.registerListener(1, onAccountsLoaded);
-            mAccountLoader.startLoading();
-            mAccountLoader.forceLoad();
+            try {
+                if (mService.isStarted()) {
+                    mAccountLoader.startLoading();
+                    mAccountLoader.forceLoad();
+                }
+            } catch (RemoteException e) {
+                e.printStackTrace();
+            }
 
             mSystemContactLoader = new ContactsLoader(LocalService.this);
             mSystemContactLoader.registerListener(1, onSystemContactsLoaded);
@@ -303,7 +347,7 @@ public class LocalService extends Service
         return perms.toArray(new String[perms.size()]);
     }
 
-    public ISipService getRemoteService() {
+    public IDRingService getRemoteService() {
         return mService;
     }
 
@@ -674,140 +718,151 @@ public class LocalService extends Service
         protected Map<String, Conversation> doInBackground(Void... params) {
             List<HistoryCall> history = null;
             List<HistoryText> historyTexts = null;
-            Map<String, Conference> confs = null;
+            Map<String, Map<String, String>> confs = null;
             final Map<String, Conversation> ret = new HashMap<>();
             final HashMap<String, CallContact> localNumberCache = new HashMap<>(64);
 
-
             try {
                 history = historyManager.getAll();
                 historyTexts = historyManager.getAllTextMessages();
                 confs = mService.getConferenceList();
-            } catch (RemoteException | SQLException e) {
-                e.printStackTrace();
-            }
 
-            for (HistoryCall call : history) {
-                //Log.w(TAG, "History call : " + call.getNumber() + " " + call.call_start + " " + call.call_end + " " + call.getEndDate().toString());
-                CallContact contact;
-                if (call.getContactID() <= CallContact.DEFAULT_ID) {
-                    contact = getByNumber(localNumberCache, call.getNumber());
-                } else {
-                    contact = localContactCache.get(call.getContactID());
-                    if (contact == null) {
-                        contact = findById(cr, call.getContactID());
-                        if (contact != null)
-                            contact.addPhoneNumber(call.getNumber(), 0);
-                        else {
-                            Log.w(TAG, "Can't find contact with id " + call.getContactID());
-                            contact = getByNumber(localNumberCache, call.getNumber());
+                for (HistoryCall call : history) {
+                    //Log.w(TAG, "History call : " + call.getNumber() + " " + call.call_start + " " + call.call_end + " " + call.getEndDate().toString());
+                    CallContact contact;
+                    if (call.getContactID() <= CallContact.DEFAULT_ID) {
+                        contact = getByNumber(localNumberCache, call.getNumber());
+                    } else {
+                        contact = localContactCache.get(call.getContactID());
+                        if (contact == null) {
+                            contact = findById(cr, call.getContactID());
+                            if (contact != null)
+                                contact.addPhoneNumber(call.getNumber(), 0);
+                            else {
+                                Log.w(TAG, "Can't find contact with id " + call.getContactID());
+                                contact = getByNumber(localNumberCache, call.getNumber());
+                            }
+                            localContactCache.put(contact.getId(), contact);
                         }
-                        localContactCache.put(contact.getId(), contact);
                     }
-                }
 
-                Map.Entry<String, Conversation> merge = null;
-                for (Map.Entry<String, Conversation> ce : ret.entrySet()) {
-                    Conversation c = ce.getValue();
-                    if ((contact.getId() > 0 && contact.getId() == c.contact.getId()) || c.contact.hasNumber(call.getNumber())) {
-                        merge = ce;
-                        break;
+                    Map.Entry<String, Conversation> merge = null;
+                    for (Map.Entry<String, Conversation> ce : ret.entrySet()) {
+                        Conversation c = ce.getValue();
+                        if ((contact.getId() > 0 && contact.getId() == c.contact.getId()) || c.contact.hasNumber(call.getNumber())) {
+                            merge = ce;
+                            break;
+                        }
                     }
-                }
-                if (merge != null) {
-                    Conversation c = merge.getValue();
-                    //Log.w(TAG, "        Join to " + merge.getKey() + " " + c.getContact().getDisplayName() + " " + call.getNumber());
-                    if (c.getContact().getId() <= 0 && contact.getId() > 0) {
-                        c.contact = contact;
-                        ret.remove(merge.getKey());
-                        ret.put(contact.getIds().get(0), c);
+                    if (merge != null) {
+                        Conversation c = merge.getValue();
+                        //Log.w(TAG, "        Join to " + merge.getKey() + " " + c.getContact().getDisplayName() + " " + call.getNumber());
+                        if (c.getContact().getId() <= 0 && contact.getId() > 0) {
+                            c.contact = contact;
+                            ret.remove(merge.getKey());
+                            ret.put(contact.getIds().get(0), c);
+                        }
+                        c.addHistoryCall(call);
+                        continue;
+                    }
+                    String key = contact.getIds().get(0);
+                    if (ret.containsKey(key)) {
+                        ret.get(key).addHistoryCall(call);
+                    } else {
+                        Conversation c = new Conversation(contact);
+                        c.addHistoryCall(call);
+                        ret.put(key, c);
                     }
-                    c.addHistoryCall(call);
-                    continue;
-                }
-                String key = contact.getIds().get(0);
-                if (ret.containsKey(key)) {
-                    ret.get(key).addHistoryCall(call);
-                } else {
-                    Conversation c = new Conversation(contact);
-                    c.addHistoryCall(call);
-                    ret.put(key, c);
                 }
-            }
 
-            for (HistoryText htext : historyTexts) {
-                CallContact contact;
-
-                if (htext.getContactID() <= CallContact.DEFAULT_ID) {
-                    contact = getByNumber(localNumberCache, htext.getNumber());
-                } else {
-                    contact = localContactCache.get(htext.getContactID());
-                    if (contact == null) {
-                        contact = findById(cr, htext.getContactID());
-                        if (contact != null)
-                            contact.addPhoneNumber(htext.getNumber(), 0);
-                        else {
-                            Log.w(TAG, "Can't find contact with id " + htext.getContactID());
-                            contact = getByNumber(localNumberCache, htext.getNumber());
+                for (HistoryText htext : historyTexts) {
+                    CallContact contact;
+
+                    if (htext.getContactID() <= CallContact.DEFAULT_ID) {
+                        contact = getByNumber(localNumberCache, htext.getNumber());
+                    } else {
+                        contact = localContactCache.get(htext.getContactID());
+                        if (contact == null) {
+                            contact = findById(cr, htext.getContactID());
+                            if (contact != null)
+                                contact.addPhoneNumber(htext.getNumber(), 0);
+                            else {
+                                Log.w(TAG, "Can't find contact with id " + htext.getContactID());
+                                contact = getByNumber(localNumberCache, htext.getNumber());
+                            }
+                            localContactCache.put(contact.getId(), contact);
                         }
-                        localContactCache.put(contact.getId(), contact);
                     }
-                }
 
-                Pair<HistoryEntry, HistoryCall> p = findHistoryByCallId(ret, htext.getCallId());
+                    Pair<HistoryEntry, HistoryCall> p = findHistoryByCallId(ret, htext.getCallId());
 
-                if (contact == null && p != null)
-                    contact = p.first.getContact();
-                if (contact == null)
-                    continue;
+                    if (contact == null && p != null)
+                        contact = p.first.getContact();
+                    if (contact == null)
+                        continue;
 
-                TextMessage msg = new TextMessage(htext);
-                msg.setContact(contact);
+                    TextMessage msg = new TextMessage(htext);
+                    msg.setContact(contact);
 
-                if (p  != null) {
-                    if (msg.getNumber() == null || msg.getNumber().isEmpty())
-                        msg.setNumber(p.second.getNumber());
-                    p.first.addTextMessage(msg);
-                }
+                    if (p  != null) {
+                        if (msg.getNumber() == null || msg.getNumber().isEmpty())
+                            msg.setNumber(p.second.getNumber());
+                        p.first.addTextMessage(msg);
+                    }
 
-                String key = contact.getIds().get(0);
-                if (ret.containsKey(key)) {
-                    ret.get(key).addTextMessage(msg);
-                } else {
-                    Conversation c = new Conversation(contact);
-                    c.addTextMessage(msg);
-                    ret.put(key, c);
+                    String key = contact.getIds().get(0);
+                    if (ret.containsKey(key)) {
+                        ret.get(key).addTextMessage(msg);
+                    } else {
+                        Conversation c = new Conversation(contact);
+                        c.addTextMessage(msg);
+                        ret.put(key, c);
+                    }
                 }
-            }
 
-            /*context.clear();
-            ctx = null;*/
-            for (Map.Entry<String, Conference> c : confs.entrySet()) {
-                //Log.w(TAG, "ConversationLoader handling " + c.getKey() + " " + c.getValue().getId());
-                Conference conf = c.getValue();
-                ArrayList<SipCall> calls = conf.getParticipants();
-                if (calls.size() >= 1) {
-                    CallContact contact = calls.get(0).getContact();
-                    //Log.w(TAG, "Contact : " + contact.getId() + " " + contact.getDisplayName());
-                    Conversation conv = null;
-                    ArrayList<String> ids = contact.getIds();
-                    for (String id : ids) {
-                        //Log.w(TAG, "    uri attempt : " + id);
-                        conv = ret.get(id);
-                        if (conv != null) break;
+                for (Map.Entry<String, Map<String, String>> c : confs.entrySet()) {
+                    String conf_id = c.getKey();
+                    Map<String, String> conf_details = c.getValue();
+                    List<String> callsIds = mService.getParticipantList(conf_id);
+                    Conference conf = new Conference(conf_id);
+                    for (String callId : callsIds) {
+                        Map<String, String> call_details = mService.getCallDetails(callId);
+                        SipCall call = new SipCall(callId, call_details);
+                        Account acc = getAccount(call.getAccount());
+                        if(acc.isRing()
+                                || acc.getSrtpDetails().getDetailBoolean(AccountDetailSrtp.CONFIG_SRTP_ENABLE)
+                                || acc.getTlsDetails().getDetailBoolean(AccountDetailTls.CONFIG_TLS_ENABLE)) {
+                            Log.i(TAG, "DRingService.placeCall() call is secure");
+                            call = new SecureSipCall(call, acc.getSrtpDetails().getDetailString(AccountDetailSrtp.CONFIG_SRTP_KEY_EXCHANGE));
+                        }
+                        conf.addParticipant(call);
                     }
-                    if (conv != null) {
-                        //Log.w(TAG, "Adding conference to existing conversation ");
-                        conv.current_calls.add(conf);
-                    } else {
-                        conv = new Conversation(contact);
-                        conv.current_calls.add(conf);
-                        ret.put(ids.get(0), conv);
+                    List<SipCall> calls = conf.getParticipants();
+                    if (calls.size() == 1) {
+                        SipCall call = calls.get(0);
+                        Conversation conv = null;
+                        String number = call.getNumber();
+                        CallContact contact = findContactByNumber(number);
+                        ArrayList<String> ids = contact.getIds();
+                        for (String id : ids) {
+                            //Log.w(TAG, "    uri attempt : " + id);
+                            conv = ret.get(id);
+                            if (conv != null) break;
+                        }
+                        if (conv != null) {
+                            conv.addConference(conf);
+                        } else {
+                            conv = new Conversation(contact);
+                            conv.addConference(conf);
+                            ret.put(ids.get(0), conv);
+                        }
                     }
                 }
+                for (Conversation c : ret.values())
+                    Log.w(TAG, "Conversation : " + c.getContact().getId() + " " + c.getContact().getDisplayName() + " " + c.getContact().getPhones().get(0).getNumber() + " " + c.getLastInteraction().toString());
+            } catch (RemoteException | SQLException e) {
+                e.printStackTrace();
             }
-            for (Conversation c : ret.values())
-                Log.w(TAG, "Conversation : " + c.getContact().getId() + " " + c.getContact().getDisplayName() + " " + c.getContact().getPhones().get(0).getNumber() + " " + c.getLastInteraction().toString());
             return ret;
         }
     }
@@ -885,17 +940,29 @@ public class LocalService extends Service
     private final BroadcastReceiver receiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
+            Log.w(TAG, "BroadcastReceiver onReceive " + intent.getAction());
             switch(intent.getAction()) {
+                case DRingService.DRING_CONNECTION_CHANGED: {
+                    boolean connected = intent.getBooleanExtra("connected", false);
+                    if (connected) {
+                        mAccountLoader.onContentChanged();
+                        mAccountLoader.startLoading();
+                        mAccountLoader.forceLoad();
+                    } else {
+                        Log.w(TAG, "DRing connection lost ");
+                    }
+                    break;
+                }
                 case ConnectivityManager.CONNECTIVITY_ACTION:
                     Log.w(TAG, "ConnectivityManager.CONNECTIVITY_ACTION " + " " + intent.getStringExtra(ConnectivityManager.EXTRA_EXTRA_INFO) + " " + intent.getStringExtra(ConnectivityManager.EXTRA_EXTRA_INFO));
                     updateConnectivityState();
                     break;
                 case ConfigurationManagerCallback.ACCOUNT_STATE_CHANGED:
-                    Log.w(TAG, "Received " + intent.getAction() + " " + intent.getStringExtra("Account") + " " + intent.getStringExtra("State") + " " + intent.getIntExtra("code", 0));
+                    Log.w(TAG, "Received " + intent.getAction() + " " + intent.getStringExtra("account") + " " + intent.getStringExtra("state") + " " + intent.getIntExtra("code", 0));
                     //accountStateChanged(intent.getStringExtra("Account"), intent.getStringExtra("State"), intent.getIntExtra("code", 0));
                     for (Account a : accounts) {
-                        if (a.getAccountID().contentEquals(intent.getStringExtra("Account"))) {
-                            a.setRegistrationState(intent.getStringExtra("State"), intent.getIntExtra("code", 0));
+                        if (a.getAccountID().contentEquals(intent.getStringExtra("account"))) {
+                            a.setRegistrationState(intent.getStringExtra("state"), intent.getIntExtra("code", 0));
                             //notifyDataSetChanged();
                             sendBroadcast(new Intent(ACTION_ACCOUNT_UPDATE));
                             break;
@@ -903,24 +970,21 @@ public class LocalService extends Service
                     }
                     break;
                 case ConfigurationManagerCallback.ACCOUNTS_CHANGED:
-                    Log.w(TAG, "Received" + intent.getAction());
                     //accountsChanged();
                     mAccountLoader.onContentChanged();
                     mAccountLoader.startLoading();
+                    mAccountLoader.forceLoad();
                     break;
                 case CallManagerCallBack.INCOMING_TEXT:
                 case ConfigurationManagerCallback.INCOMING_TEXT: {
                     TextMessage txt = intent.getParcelableExtra("txt");
                     String call = txt.getCallId();
+                    Conversation conv;
                     if (call != null && !call.isEmpty()) {
-                        Conversation conv = getConversationByCallId(call);
+                        conv = getConversationByCallId(call);
                         conv.addTextMessage(txt);
-                        /*Conference conf = conv.getConference(call);
-                        conf.addSipMessage(txt);
-                        Conversation conv = getByContact(conf.)*/
                     } else {
-                        CallContact contact = findContactByNumber(txt.getNumber());
-                        Conversation conv = startConversation(contact);
+                        conv = startConversation(findContactByNumber(txt.getNumber()));
                         txt.setContact(conv.getContact());
                         Log.w(TAG, "New text messsage " + txt.getAccount() + " " + txt.getContact().getId() + " " + txt.getMessage());
                         conv.addTextMessage(txt);
@@ -928,8 +992,75 @@ public class LocalService extends Service
                     sendBroadcast(new Intent(ACTION_CONF_UPDATE));
                     break;
                 }
+                case CallManagerCallBack.INCOMING_CALL: {
+                    String callId = intent.getStringExtra("call");
+                    String accountId = intent.getStringExtra("account");
+                    String number = intent.getStringExtra("from");
+                    CallContact contact = findContactByNumber(number);
+                    Conversation conv = startConversation(contact);
+
+                    SipCall call = new SipCall(callId, accountId, number, SipCall.Direction.INCOMING);
+                    call.setContact(contact);
+
+                    Account account = getAccount(accountId);
+
+                    Conference toAdd;
+                    if (account.useSecureLayer()) {
+                        SecureSipCall secureCall = new SecureSipCall(call, account.getSrtpDetails().getDetailString(AccountDetailSrtp.CONFIG_SRTP_KEY_EXCHANGE));
+                        toAdd = new Conference(secureCall);
+                    } else {
+                        toAdd = new Conference(call);
+                    }
+
+                    conv.addConference(toAdd);
+                    break;
+                }
+                case CallManagerCallBack.CALL_STATE_CHANGED: {
+                    String callid = intent.getStringExtra("call");
+                    Conversation conversation = null;
+                    Conference found = null;
+
+                    for (Conversation conv : conversations.values()) {
+                        Conference tconf = conv.getConference(callid);
+                        if (tconf != null) {
+                            conversation = conv;
+                            found = tconf;
+                            break;
+                        }
+                    }
+
+                    if (found == null) {
+                        Log.w(TAG, "CALL_STATE_CHANGED : Can't find conference " + callid);
+                    } else {
+                        SipCall call = found.getCallById(callid);
+                        int old_state = call.getCallState();
+                        int new_state = SipCall.stateFromString(intent.getStringExtra("state"));
+
+                        if (new_state != old_state) {
+                            Log.w(TAG, "CALL_STATE_CHANGED : updating call state to " + new_state);
+                            call.setCallState(new_state);
+                        }
+                        if (new_state == SipCall.State.HUNGUP
+                                || new_state == SipCall.State.BUSY
+                                || new_state == SipCall.State.FAILURE
+                                || new_state == SipCall.State.INACTIVE) {
+                            Log.w(TAG, "Removing call and notification " + found.getId());
+                            NotificationManagerCompat notificationManager = NotificationManagerCompat.from(LocalService.this);
+                            notificationManager.cancel(found.notificationId);
+                            found.removeParticipant(call);
+                        }
+                        if (new_state == SipCall.State.HUNGUP) {
+                            call.setTimestampEnd(System.currentTimeMillis());
+                            conversation.addHistoryCall(new HistoryCall(call));
+                        }
+                        if (found.getParticipants().isEmpty()) {
+                            conversation.removeConference(found);
+                        }
+                    }
+                    sendBroadcast(new Intent(ACTION_CONF_UPDATE));
+                    break;
+                }
                 default:
-                    Log.w(TAG, "onReceive " + intent.getAction() + " " + intent.getDataString());
                     new ConversationLoader(context, systemContactCache){
                         @Override
                         protected void onPostExecute(Map<String, Conversation> res) {
@@ -955,6 +1086,9 @@ public class LocalService extends Service
         }.execute();
 
         IntentFilter intentFilter = new IntentFilter();
+
+        intentFilter.addAction(DRingService.DRING_CONNECTION_CHANGED);
+
         intentFilter.addAction(ConfigurationManagerCallback.ACCOUNT_STATE_CHANGED);
         intentFilter.addAction(ConfigurationManagerCallback.ACCOUNTS_CHANGED);
         intentFilter.addAction(ConfigurationManagerCallback.INCOMING_TEXT);
diff --git a/ring-android/app/src/main/java/cx/ring/utils/MediaManager.java b/ring-android/app/src/main/java/cx/ring/utils/MediaManager.java
index c9b59cb165828142fe360e291dcd4c4dad89baaf..d3842a494f498f787c9e1096c5f318f093d7a232 100644
--- a/ring-android/app/src/main/java/cx/ring/utils/MediaManager.java
+++ b/ring-android/app/src/main/java/cx/ring/utils/MediaManager.java
@@ -31,7 +31,7 @@
 
 package cx.ring.utils;
 
-import cx.ring.service.SipService;
+import cx.ring.service.DRingService;
 
 import android.content.Context;
 import android.media.AudioManager;
@@ -43,14 +43,14 @@ import cx.ring.utils.bluetooth.BluetoothWrapper;
 public class MediaManager implements OnAudioFocusChangeListener, BluetoothWrapper.BluetoothChangeListener {
 
     private static final String TAG = MediaManager.class.getSimpleName();
-    private SipService mService;
+    private DRingService mService;
     private SettingsContentObserver mSettingsContentObserver;
     AudioManager mAudioManager;
     private Ringer ringer;
     //Bluetooth related
     private BluetoothWrapper bluetoothWrapper;
 
-    public MediaManager(SipService aService) {
+    public MediaManager(DRingService aService) {
         mService = aService;
         mSettingsContentObserver = new SettingsContentObserver(mService, new Handler());
         mAudioManager = (AudioManager) aService.getSystemService(Context.AUDIO_SERVICE);
diff --git a/ring-android/app/src/main/java/cx/ring/utils/SettingsContentObserver.java b/ring-android/app/src/main/java/cx/ring/utils/SettingsContentObserver.java
index 018cf28b6513d4fbf86d4c6c829ad9fede65e391..08e330aaa054d982ae25f6462b5e2d3a2a04d136 100644
--- a/ring-android/app/src/main/java/cx/ring/utils/SettingsContentObserver.java
+++ b/ring-android/app/src/main/java/cx/ring/utils/SettingsContentObserver.java
@@ -31,7 +31,7 @@
 
 package cx.ring.utils;
 
-import cx.ring.service.SipService;
+import cx.ring.service.DRingService;
 
 import android.content.Context;
 import android.database.ContentObserver;
@@ -41,10 +41,10 @@ import android.util.Log;
 
 public class SettingsContentObserver extends ContentObserver {
     double previousVolume;
-    SipService context;
+    DRingService context;
     private static final String TAG = "Settings";
 
-    public SettingsContentObserver(SipService c, Handler handler) {
+    public SettingsContentObserver(DRingService c, Handler handler) {
         super(handler);
         context=c;  
         AudioManager audio = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);