changeset 2086:4633cfcbcccb

bridge (D-Bus): bad design fixes: - renamed outputed module to dbus_bridge (to avoid uppercase and conflict with dbus module) - class name is now Bridge for both frontend and core (make discovery/import more easy) - register renamed to register_method in core, and register_signal in frontend
author Goffi <goffi@goffi.org>
date Mon, 03 Oct 2016 21:15:39 +0200
parents da4097de5a95
children 159250d66407
files frontends/src/bridge/DBus.py frontends/src/bridge/dbus_bridge.py frontends/src/jp/base.py frontends/src/primitivus/primitivus frontends/src/quick_frontend/quick_app.py src/bridge/DBus.py src/bridge/bridge_constructor/constructors/dbus/constructor.py src/bridge/bridge_constructor/constructors/dbus/dbus_core_template.py src/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py src/bridge/dbus_bridge.py src/core/sat_main.py
diffstat 11 files changed, 1379 insertions(+), 1379 deletions(-) [+]
line wrap: on
line diff
--- a/frontends/src/bridge/DBus.py	Sun Oct 02 22:44:33 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,694 +0,0 @@
-#!/usr/bin/env python2
-#-*- coding: utf-8 -*-
-
-# SAT communication bridge
-# Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org)
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-from sat.core.i18n import _
-from bridge_frontend import BridgeFrontend, BridgeException
-import dbus
-from sat.core.log import getLogger
-log = getLogger(__name__)
-from sat.core.exceptions import BridgeExceptionNoService, BridgeInitError
-
-from dbus.mainloop.glib import DBusGMainLoop
-DBusGMainLoop(set_as_default=True)
-
-import ast
-
-const_INT_PREFIX = "org.goffi.SAT"  # Interface prefix
-const_ERROR_PREFIX = const_INT_PREFIX + ".error"
-const_OBJ_PATH = '/org/goffi/SAT/bridge'
-const_CORE_SUFFIX = ".core"
-const_PLUGIN_SUFFIX = ".plugin"
-const_TIMEOUT = 120
-
-
-def dbus_to_bridge_exception(dbus_e):
-    """Convert a DBusException to a BridgeException.
-
-    @param dbus_e (DBusException)
-    @return: BridgeException
-    """
-    full_name = dbus_e.get_dbus_name()
-    if full_name.startswith(const_ERROR_PREFIX):
-        name = dbus_e.get_dbus_name()[len(const_ERROR_PREFIX) + 1:]
-    else:
-        name = full_name
-    # XXX: dbus_e.args doesn't contain the original DBusException args, but we
-    # receive its serialized form in dbus_e.args[0]. From that we can rebuild
-    # the original arguments list thanks to ast.literal_eval (secure eval).
-    message = dbus_e.get_dbus_message()  # similar to dbus_e.args[0]
-    try:
-        message, condition = ast.literal_eval(message)
-    except (SyntaxError, ValueError, TypeError):
-        condition = ''
-    return BridgeException(name, message, condition)
-
-
-class DBusBridgeFrontend(BridgeFrontend):
-    def __init__(self):
-        try:
-            self.sessions_bus = dbus.SessionBus()
-            self.db_object = self.sessions_bus.get_object(const_INT_PREFIX,
-                                                          const_OBJ_PATH)
-            self.db_core_iface = dbus.Interface(self.db_object,
-                                                dbus_interface=const_INT_PREFIX + const_CORE_SUFFIX)
-            self.db_plugin_iface = dbus.Interface(self.db_object,
-                                                  dbus_interface=const_INT_PREFIX + const_PLUGIN_SUFFIX)
-        except dbus.exceptions.DBusException, e:
-            if e._dbus_error_name in ('org.freedesktop.DBus.Error.ServiceUnknown',
-                                      'org.freedesktop.DBus.Error.Spawn.ExecFailed'):
-                raise BridgeExceptionNoService
-            elif e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported':
-                log.error(_(u"D-Bus is not launched, please see README to see instructions on how to launch it"))
-                raise BridgeInitError
-            else:
-                raise e
-        #props = self.db_core_iface.getProperties()
-
-    def register(self, functionName, handler, iface="core"):
-        if iface == "core":
-            self.db_core_iface.connect_to_signal(functionName, handler)
-        elif iface == "plugin":
-            self.db_plugin_iface.connect_to_signal(functionName, handler)
-        else:
-            log.error(_('Unknown interface'))
-
-    def __getattribute__(self, name):
-        """ usual __getattribute__ if the method exists, else try to find a plugin method """
-        try:
-            return object.__getattribute__(self, name)
-        except AttributeError:
-            # The attribute is not found, we try the plugin proxy to find the requested method
-
-            def getPluginMethod(*args, **kwargs):
-                # We first check if we have an async call. We detect this in two ways:
-                #   - if we have the 'callback' and 'errback' keyword arguments
-                #   - or if the last two arguments are callable
-
-                async = False
-                args = list(args)
-
-                if kwargs:
-                    if 'callback' in kwargs:
-                        async = True
-                        _callback = kwargs.pop('callback')
-                        _errback = kwargs.pop('errback', lambda failure: log.error(unicode(failure)))
-                    try:
-                        args.append(kwargs.pop('profile'))
-                    except KeyError:
-                        try:
-                            args.append(kwargs.pop('profile_key'))
-                        except KeyError:
-                            pass
-                    # at this point, kwargs should be empty
-                    if kwargs:
-                        log.warnings(u"unexpected keyword arguments, they will be ignored: {}".format(kwargs))
-                elif len(args) >= 2 and callable(args[-1]) and callable(args[-2]):
-                    async = True
-                    _errback = args.pop()
-                    _callback = args.pop()
-
-                method = getattr(self.db_plugin_iface, name)
-
-                if async:
-                    kwargs['timeout'] = const_TIMEOUT
-                    kwargs['reply_handler'] = _callback
-                    kwargs['error_handler'] = lambda err: _errback(dbus_to_bridge_exception(err))
-
-                return method(*args, **kwargs)
-
-            return getPluginMethod
-
-    def actionsGet(self, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.actionsGet(profile_key, **kwargs)
-
-    def addContact(self, entity_jid, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.addContact(entity_jid, profile_key, **kwargs)
-
-    def asyncConnect(self, profile_key="@DEFAULT@", password='', callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return self.db_core_iface.asyncConnect(profile_key, password, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
-
-    def asyncCreateProfile(self, profile, password='', callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return self.db_core_iface.asyncCreateProfile(profile, password, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
-
-    def asyncDeleteProfile(self, profile, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return self.db_core_iface.asyncDeleteProfile(profile, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
-
-    def asyncGetParamA(self, name, category, attribute="value", security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return unicode(self.db_core_iface.asyncGetParamA(name, category, attribute, security_limit, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler))
-
-    def asyncGetParamsValuesFromCategory(self, category, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return self.db_core_iface.asyncGetParamsValuesFromCategory(category, security_limit, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
-
-    def delContact(self, entity_jid, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return self.db_core_iface.delContact(entity_jid, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
-
-    def discoInfos(self, entity_jid, profile_key, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return self.db_core_iface.discoInfos(entity_jid, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
-
-    def discoItems(self, entity_jid, profile_key, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return self.db_core_iface.discoItems(entity_jid, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
-
-    def disconnect(self, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.disconnect(profile_key, **kwargs)
-
-    def getConfig(self, section, name, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return unicode(self.db_core_iface.getConfig(section, name, **kwargs))
-
-    def getContacts(self, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return self.db_core_iface.getContacts(profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
-
-    def getContactsFromGroup(self, group, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.getContactsFromGroup(group, profile_key, **kwargs)
-
-    def getEntitiesData(self, jids, keys, profile, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.getEntitiesData(jids, keys, profile, **kwargs)
-
-    def getEntityData(self, jid, keys, profile, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.getEntityData(jid, keys, profile, **kwargs)
-
-    def getFeatures(self, profile_key, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return self.db_core_iface.getFeatures(profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
-
-    def getMainResource(self, contact_jid, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return unicode(self.db_core_iface.getMainResource(contact_jid, profile_key, **kwargs))
-
-    def getMenuHelp(self, menu_id, language, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return unicode(self.db_core_iface.getMenuHelp(menu_id, language, **kwargs))
-
-    def getMenus(self, language, security_limit, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.getMenus(language, security_limit, **kwargs)
-
-    def getParamA(self, name, category, attribute="value", profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return unicode(self.db_core_iface.getParamA(name, category, attribute, profile_key, **kwargs))
-
-    def getParamsCategories(self, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.getParamsCategories(**kwargs)
-
-    def getParamsUI(self, security_limit=-1, app='', profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return unicode(self.db_core_iface.getParamsUI(security_limit, app, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler))
-
-    def getPresenceStatuses(self, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.getPresenceStatuses(profile_key, **kwargs)
-
-    def getProfileName(self, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return unicode(self.db_core_iface.getProfileName(profile_key, **kwargs))
-
-    def getProfilesList(self, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.getProfilesList(**kwargs)
-
-    def getReady(self, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return self.db_core_iface.getReady(timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
-
-    def getVersion(self, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return unicode(self.db_core_iface.getVersion(**kwargs))
-
-    def getWaitingSub(self, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.getWaitingSub(profile_key, **kwargs)
-
-    def historyGet(self, from_jid, to_jid, limit, between=True, filters='', profile="@NONE@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return self.db_core_iface.historyGet(from_jid, to_jid, limit, between, filters, profile, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
-
-    def isConnected(self, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.isConnected(profile_key, **kwargs)
-
-    def launchAction(self, callback_id, data, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return self.db_core_iface.launchAction(callback_id, data, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
-
-    def loadParamsTemplate(self, filename, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.loadParamsTemplate(filename, **kwargs)
-
-    def messageSend(self, to_jid, message, subject={}, mess_type="auto", extra={}, profile_key="@NONE@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return self.db_core_iface.messageSend(to_jid, message, subject, mess_type, extra, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
-
-    def paramsRegisterApp(self, xml, security_limit=-1, app='', callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.paramsRegisterApp(xml, security_limit, app, **kwargs)
-
-    def profileIsSessionStarted(self, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.profileIsSessionStarted(profile_key, **kwargs)
-
-    def profileSetDefault(self, profile, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.profileSetDefault(profile, **kwargs)
-
-    def profileStartSession(self, password='', profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return self.db_core_iface.profileStartSession(password, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
-
-    def progressGet(self, id, profile, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.progressGet(id, profile, **kwargs)
-
-    def progressGetAll(self, profile, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.progressGetAll(profile, **kwargs)
-
-    def progressGetAllMetadata(self, profile, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.progressGetAllMetadata(profile, **kwargs)
-
-    def saveParamsTemplate(self, filename, callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.saveParamsTemplate(filename, **kwargs)
-
-    def setParam(self, name, value, category, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.setParam(name, value, category, security_limit, profile_key, **kwargs)
-
-    def setPresence(self, to_jid='', show='', statuses={}, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.setPresence(to_jid, show, statuses, profile_key, **kwargs)
-
-    def subscription(self, sub_type, entity, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        kwargs={}
-        if callback is not None:
-            kwargs['timeout'] = const_TIMEOUT
-            kwargs['reply_handler'] = callback
-            kwargs['error_handler'] = error_handler
-        return self.db_core_iface.subscription(sub_type, entity, profile_key, **kwargs)
-
-    def updateContact(self, entity_jid, name, groups, profile_key="@DEFAULT@", callback=None, errback=None):
-        if callback is None:
-            error_handler = None
-        else:
-            if errback is None:
-                errback = log.error
-            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
-        return self.db_core_iface.updateContact(entity_jid, name, groups, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/frontends/src/bridge/dbus_bridge.py	Mon Oct 03 21:15:39 2016 +0200
@@ -0,0 +1,694 @@
+#!/usr/bin/env python2
+#-*- coding: utf-8 -*-
+
+# SAT communication bridge
+# Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org)
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+from sat.core.i18n import _
+from bridge_frontend import BridgeFrontend, BridgeException
+import dbus
+from sat.core.log import getLogger
+log = getLogger(__name__)
+from sat.core.exceptions import BridgeExceptionNoService, BridgeInitError
+
+from dbus.mainloop.glib import DBusGMainLoop
+DBusGMainLoop(set_as_default=True)
+
+import ast
+
+const_INT_PREFIX = "org.goffi.SAT"  # Interface prefix
+const_ERROR_PREFIX = const_INT_PREFIX + ".error"
+const_OBJ_PATH = '/org/goffi/SAT/bridge'
+const_CORE_SUFFIX = ".core"
+const_PLUGIN_SUFFIX = ".plugin"
+const_TIMEOUT = 120
+
+
+def dbus_to_bridge_exception(dbus_e):
+    """Convert a DBusException to a BridgeException.
+
+    @param dbus_e (DBusException)
+    @return: BridgeException
+    """
+    full_name = dbus_e.get_dbus_name()
+    if full_name.startswith(const_ERROR_PREFIX):
+        name = dbus_e.get_dbus_name()[len(const_ERROR_PREFIX) + 1:]
+    else:
+        name = full_name
+    # XXX: dbus_e.args doesn't contain the original DBusException args, but we
+    # receive its serialized form in dbus_e.args[0]. From that we can rebuild
+    # the original arguments list thanks to ast.literal_eval (secure eval).
+    message = dbus_e.get_dbus_message()  # similar to dbus_e.args[0]
+    try:
+        message, condition = ast.literal_eval(message)
+    except (SyntaxError, ValueError, TypeError):
+        condition = ''
+    return BridgeException(name, message, condition)
+
+
+class Bridge(BridgeFrontend):
+    def __init__(self):
+        try:
+            self.sessions_bus = dbus.SessionBus()
+            self.db_object = self.sessions_bus.get_object(const_INT_PREFIX,
+                                                          const_OBJ_PATH)
+            self.db_core_iface = dbus.Interface(self.db_object,
+                                                dbus_interface=const_INT_PREFIX + const_CORE_SUFFIX)
+            self.db_plugin_iface = dbus.Interface(self.db_object,
+                                                  dbus_interface=const_INT_PREFIX + const_PLUGIN_SUFFIX)
+        except dbus.exceptions.DBusException, e:
+            if e._dbus_error_name in ('org.freedesktop.DBus.Error.ServiceUnknown',
+                                      'org.freedesktop.DBus.Error.Spawn.ExecFailed'):
+                raise BridgeExceptionNoService
+            elif e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported':
+                log.error(_(u"D-Bus is not launched, please see README to see instructions on how to launch it"))
+                raise BridgeInitError
+            else:
+                raise e
+        #props = self.db_core_iface.getProperties()
+
+    def register_signal(self, functionName, handler, iface="core"):
+        if iface == "core":
+            self.db_core_iface.connect_to_signal(functionName, handler)
+        elif iface == "plugin":
+            self.db_plugin_iface.connect_to_signal(functionName, handler)
+        else:
+            log.error(_('Unknown interface'))
+
+    def __getattribute__(self, name):
+        """ usual __getattribute__ if the method exists, else try to find a plugin method """
+        try:
+            return object.__getattribute__(self, name)
+        except AttributeError:
+            # The attribute is not found, we try the plugin proxy to find the requested method
+
+            def getPluginMethod(*args, **kwargs):
+                # We first check if we have an async call. We detect this in two ways:
+                #   - if we have the 'callback' and 'errback' keyword arguments
+                #   - or if the last two arguments are callable
+
+                async = False
+                args = list(args)
+
+                if kwargs:
+                    if 'callback' in kwargs:
+                        async = True
+                        _callback = kwargs.pop('callback')
+                        _errback = kwargs.pop('errback', lambda failure: log.error(unicode(failure)))
+                    try:
+                        args.append(kwargs.pop('profile'))
+                    except KeyError:
+                        try:
+                            args.append(kwargs.pop('profile_key'))
+                        except KeyError:
+                            pass
+                    # at this point, kwargs should be empty
+                    if kwargs:
+                        log.warnings(u"unexpected keyword arguments, they will be ignored: {}".format(kwargs))
+                elif len(args) >= 2 and callable(args[-1]) and callable(args[-2]):
+                    async = True
+                    _errback = args.pop()
+                    _callback = args.pop()
+
+                method = getattr(self.db_plugin_iface, name)
+
+                if async:
+                    kwargs['timeout'] = const_TIMEOUT
+                    kwargs['reply_handler'] = _callback
+                    kwargs['error_handler'] = lambda err: _errback(dbus_to_bridge_exception(err))
+
+                return method(*args, **kwargs)
+
+            return getPluginMethod
+
+    def actionsGet(self, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.actionsGet(profile_key, **kwargs)
+
+    def addContact(self, entity_jid, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.addContact(entity_jid, profile_key, **kwargs)
+
+    def asyncConnect(self, profile_key="@DEFAULT@", password='', callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.asyncConnect(profile_key, password, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+
+    def asyncCreateProfile(self, profile, password='', callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.asyncCreateProfile(profile, password, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+
+    def asyncDeleteProfile(self, profile, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.asyncDeleteProfile(profile, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+
+    def asyncGetParamA(self, name, category, attribute="value", security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return unicode(self.db_core_iface.asyncGetParamA(name, category, attribute, security_limit, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler))
+
+    def asyncGetParamsValuesFromCategory(self, category, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.asyncGetParamsValuesFromCategory(category, security_limit, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+
+    def delContact(self, entity_jid, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.delContact(entity_jid, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+
+    def discoInfos(self, entity_jid, profile_key, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.discoInfos(entity_jid, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+
+    def discoItems(self, entity_jid, profile_key, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.discoItems(entity_jid, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+
+    def disconnect(self, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.disconnect(profile_key, **kwargs)
+
+    def getConfig(self, section, name, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return unicode(self.db_core_iface.getConfig(section, name, **kwargs))
+
+    def getContacts(self, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.getContacts(profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+
+    def getContactsFromGroup(self, group, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.getContactsFromGroup(group, profile_key, **kwargs)
+
+    def getEntitiesData(self, jids, keys, profile, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.getEntitiesData(jids, keys, profile, **kwargs)
+
+    def getEntityData(self, jid, keys, profile, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.getEntityData(jid, keys, profile, **kwargs)
+
+    def getFeatures(self, profile_key, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.getFeatures(profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+
+    def getMainResource(self, contact_jid, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return unicode(self.db_core_iface.getMainResource(contact_jid, profile_key, **kwargs))
+
+    def getMenuHelp(self, menu_id, language, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return unicode(self.db_core_iface.getMenuHelp(menu_id, language, **kwargs))
+
+    def getMenus(self, language, security_limit, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.getMenus(language, security_limit, **kwargs)
+
+    def getParamA(self, name, category, attribute="value", profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return unicode(self.db_core_iface.getParamA(name, category, attribute, profile_key, **kwargs))
+
+    def getParamsCategories(self, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.getParamsCategories(**kwargs)
+
+    def getParamsUI(self, security_limit=-1, app='', profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return unicode(self.db_core_iface.getParamsUI(security_limit, app, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler))
+
+    def getPresenceStatuses(self, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.getPresenceStatuses(profile_key, **kwargs)
+
+    def getProfileName(self, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return unicode(self.db_core_iface.getProfileName(profile_key, **kwargs))
+
+    def getProfilesList(self, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.getProfilesList(**kwargs)
+
+    def getReady(self, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.getReady(timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+
+    def getVersion(self, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return unicode(self.db_core_iface.getVersion(**kwargs))
+
+    def getWaitingSub(self, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.getWaitingSub(profile_key, **kwargs)
+
+    def historyGet(self, from_jid, to_jid, limit, between=True, filters='', profile="@NONE@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.historyGet(from_jid, to_jid, limit, between, filters, profile, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+
+    def isConnected(self, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.isConnected(profile_key, **kwargs)
+
+    def launchAction(self, callback_id, data, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.launchAction(callback_id, data, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+
+    def loadParamsTemplate(self, filename, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.loadParamsTemplate(filename, **kwargs)
+
+    def messageSend(self, to_jid, message, subject={}, mess_type="auto", extra={}, profile_key="@NONE@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.messageSend(to_jid, message, subject, mess_type, extra, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+
+    def paramsRegisterApp(self, xml, security_limit=-1, app='', callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.paramsRegisterApp(xml, security_limit, app, **kwargs)
+
+    def profileIsSessionStarted(self, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.profileIsSessionStarted(profile_key, **kwargs)
+
+    def profileSetDefault(self, profile, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.profileSetDefault(profile, **kwargs)
+
+    def profileStartSession(self, password='', profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.profileStartSession(password, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+
+    def progressGet(self, id, profile, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.progressGet(id, profile, **kwargs)
+
+    def progressGetAll(self, profile, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.progressGetAll(profile, **kwargs)
+
+    def progressGetAllMetadata(self, profile, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.progressGetAllMetadata(profile, **kwargs)
+
+    def saveParamsTemplate(self, filename, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.saveParamsTemplate(filename, **kwargs)
+
+    def setParam(self, name, value, category, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.setParam(name, value, category, security_limit, profile_key, **kwargs)
+
+    def setPresence(self, to_jid='', show='', statuses={}, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.setPresence(to_jid, show, statuses, profile_key, **kwargs)
+
+    def subscription(self, sub_type, entity, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.subscription(sub_type, entity, profile_key, **kwargs)
+
+    def updateContact(self, entity_jid, name, groups, profile_key="@DEFAULT@", callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.updateContact(entity_jid, name, groups, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
--- a/frontends/src/jp/base.py	Sun Oct 02 22:44:33 2016 +0200
+++ b/frontends/src/jp/base.py	Mon Oct 03 21:15:39 2016 +0200
@@ -33,7 +33,7 @@
 from glob import iglob
 from importlib import import_module
 from sat_frontends.tools.jid import JID
-from sat_frontends.bridge.DBus import DBusBridgeFrontend
+from sat_frontends.bridge.dbus_bridge import Bridge
 from sat.core import exceptions
 import sat_frontends.jp
 from sat_frontends.jp.constants import Const as C
@@ -96,7 +96,7 @@
             by default display a message
         """
         try:
-            self.bridge = DBusBridgeFrontend()
+            self.bridge = Bridge()
         except exceptions.BridgeExceptionNoService:
             print(_(u"Can't connect to SàT backend, are you sure it's launched ?"))
             sys.exit(1)
--- a/frontends/src/primitivus/primitivus	Sun Oct 02 22:44:33 2016 +0200
+++ b/frontends/src/primitivus/primitivus	Mon Oct 03 21:15:39 2016 +0200
@@ -28,7 +28,7 @@
 import urwid
 from urwid.util import is_wide_char
 from urwid_satext import sat_widgets
-from sat_frontends.bridge.DBus import DBusBridgeFrontend
+from sat_frontends.bridge.dbus_bridge import Bridge
 from sat_frontends.quick_frontend.quick_app import QuickApp
 from sat_frontends.quick_frontend import quick_utils
 from sat_frontends.quick_frontend import quick_chat
@@ -276,7 +276,7 @@
     AVATAR_HANDLER = False
 
     def __init__(self):
-        QuickApp.__init__(self, create_bridge=DBusBridgeFrontend, xmlui=xmlui, check_options=quick_utils.check_options)
+        QuickApp.__init__(self, create_bridge=Bridge, xmlui=xmlui, check_options=quick_utils.check_options)
 
         ## main loop setup ##
         self.main_widget = ProfileManager(self)
--- a/frontends/src/quick_frontend/quick_app.py	Sun Oct 02 22:44:33 2016 +0200
+++ b/frontends/src/quick_frontend/quick_app.py	Mon Oct 03 21:15:39 2016 +0200
@@ -287,7 +287,7 @@
         if handler is None:
             handler = getattr(self, "{}{}".format(function_name, 'Handler'))
         if not with_profile:
-            self.bridge.register(function_name, handler, iface)
+            self.bridge.register_signal(function_name, handler, iface)
             return
 
         def signalReceived(*args, **kwargs):
@@ -303,7 +303,7 @@
                         self.signals_cache.setdefault(profile, []).append((function_name, handler, args, kwargs))
                     return  # we ignore signal for profiles we don't manage
             handler(*args, **kwargs)
-        self.bridge.register(function_name, signalReceived, iface)
+        self.bridge.register_signal(function_name, signalReceived, iface)
 
     def addListener(self, type_, callback, profiles_filter=None):
         """Add a listener for an event
--- a/src/bridge/DBus.py	Sun Oct 02 22:44:33 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,623 +0,0 @@
-#!/usr/bin/env python2
-#-*- coding: utf-8 -*-
-
-# SAT: a jabber client
-# Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org)
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-from sat.core.i18n import _
-import dbus
-import dbus.service
-import dbus.mainloop.glib
-import inspect
-from sat.core.log import getLogger
-log = getLogger(__name__)
-from twisted.internet.defer import Deferred
-from sat.core.exceptions import BridgeInitError
-
-const_INT_PREFIX = "org.goffi.SAT"  # Interface prefix
-const_ERROR_PREFIX = const_INT_PREFIX + ".error"
-const_OBJ_PATH = '/org/goffi/SAT/bridge'
-const_CORE_SUFFIX = ".core"
-const_PLUGIN_SUFFIX = ".plugin"
-
-
-class ParseError(Exception):
-    pass
-
-
-class MethodNotRegistered(dbus.DBusException):
-    _dbus_error_name = const_ERROR_PREFIX + ".MethodNotRegistered"
-
-
-class InternalError(dbus.DBusException):
-    _dbus_error_name = const_ERROR_PREFIX + ".InternalError"
-
-
-class AsyncNotDeferred(dbus.DBusException):
-    _dbus_error_name = const_ERROR_PREFIX + ".AsyncNotDeferred"
-
-
-class DeferredNotAsync(dbus.DBusException):
-    _dbus_error_name = const_ERROR_PREFIX + ".DeferredNotAsync"
-
-
-class GenericException(dbus.DBusException):
-    def __init__(self, twisted_error):
-        """
-
-        @param twisted_error (Failure): instance of twisted Failure
-        @return: DBusException
-        """
-        super(GenericException, self).__init__()
-        try:
-            # twisted_error.value is a class
-            class_ = twisted_error.value().__class__
-        except TypeError:
-            # twisted_error.value is an instance
-            class_ = twisted_error.value.__class__
-            message = twisted_error.getErrorMessage()
-            try:
-                self.args = (message, twisted_error.value.condition)
-            except AttributeError:
-                self.args = (message,)
-        self._dbus_error_name = '.'.join([const_ERROR_PREFIX, class_.__module__, class_.__name__])
-
-
-class DbusObject(dbus.service.Object):
-
-    def __init__(self, bus, path):
-        dbus.service.Object.__init__(self, bus, path)
-        log.debug("Init DbusObject...")
-        self.cb = {}
-
-    def register(self, name, cb):
-        self.cb[name] = cb
-
-    def _callback(self, name, *args, **kwargs):
-        """call the callback if it exists, raise an exception else
-        if the callback return a deferred, use async methods"""
-        if not name in self.cb:
-            raise MethodNotRegistered
-
-        if "callback" in kwargs:
-            #we must have errback too
-            if not "errback" in kwargs:
-                log.error("errback is missing in method call [%s]" % name)
-                raise InternalError
-            callback = kwargs.pop("callback")
-            errback = kwargs.pop("errback")
-            async = True
-        else:
-            async = False
-        result = self.cb[name](*args, **kwargs)
-        if async:
-            if not isinstance(result, Deferred):
-                log.error("Asynchronous method [%s] does not return a Deferred." % name)
-                raise AsyncNotDeferred
-            result.addCallback(lambda result: callback() if result is None else callback(result))
-            result.addErrback(lambda err: errback(GenericException(err)))
-        else:
-            if isinstance(result, Deferred):
-                log.error("Synchronous method [%s] return a Deferred." % name)
-                raise DeferredNotAsync
-            return result
-    ### signals ###
-
-    @dbus.service.signal(const_INT_PREFIX + const_PLUGIN_SUFFIX,
-                         signature='')
-    def dummySignal(self):
-        #FIXME: workaround for addSignal (doesn't work if one method doensn't
-        #       already exist for plugins), probably missing some initialisation, need
-        #       further investigations
-        pass
-
-    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
-                         signature='a{ss}sis')
-    def actionNew(self, action_data, id, security_limit, profile):
-        pass
-
-    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
-                         signature='ss')
-    def connected(self, profile, jid_s):
-        pass
-
-    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
-                         signature='ss')
-    def contactDeleted(self, entity_jid, profile):
-        pass
-
-    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
-                         signature='s')
-    def disconnected(self, profile):
-        pass
-
-    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
-                         signature='ssss')
-    def entityDataUpdated(self, jid, name, value, profile):
-        pass
-
-    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
-                         signature='sdssa{ss}a{ss}sa{ss}s')
-    def messageNew(self, uid, timestamp, from_jid, to_jid, message, subject, mess_type, extra, profile):
-        pass
-
-    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
-                         signature='sa{ss}ass')
-    def newContact(self, contact_jid, attributes, groups, profile):
-        pass
-
-    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
-                         signature='ssss')
-    def paramUpdate(self, name, value, category, profile):
-        pass
-
-    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
-                         signature='ssia{ss}s')
-    def presenceUpdate(self, entity_jid, show, priority, statuses, profile):
-        pass
-
-    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
-                         signature='sss')
-    def progressError(self, id, error, profile):
-        pass
-
-    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
-                         signature='sa{ss}s')
-    def progressFinished(self, id, metadata, profile):
-        pass
-
-    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
-                         signature='sa{ss}s')
-    def progressStarted(self, id, metadata, profile):
-        pass
-
-    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
-                         signature='sss')
-    def subscribe(self, sub_type, entity_jid, profile):
-        pass
-
-    ### methods ###
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='a(a{ss}si)',
-                         async_callbacks=None)
-    def actionsGet(self, profile_key="@DEFAULT@"):
-        return self._callback("actionsGet", unicode(profile_key))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ss', out_signature='',
-                         async_callbacks=None)
-    def addContact(self, entity_jid, profile_key="@DEFAULT@"):
-        return self._callback("addContact", unicode(entity_jid), unicode(profile_key))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ss', out_signature='b',
-                         async_callbacks=('callback', 'errback'))
-    def asyncConnect(self, profile_key="@DEFAULT@", password='', callback=None, errback=None):
-        return self._callback("asyncConnect", unicode(profile_key), unicode(password), callback=callback, errback=errback)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ss', out_signature='',
-                         async_callbacks=('callback', 'errback'))
-    def asyncCreateProfile(self, profile, password='', callback=None, errback=None):
-        return self._callback("asyncCreateProfile", unicode(profile), unicode(password), callback=callback, errback=errback)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='',
-                         async_callbacks=('callback', 'errback'))
-    def asyncDeleteProfile(self, profile, callback=None, errback=None):
-        return self._callback("asyncDeleteProfile", unicode(profile), callback=callback, errback=errback)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='sssis', out_signature='s',
-                         async_callbacks=('callback', 'errback'))
-    def asyncGetParamA(self, name, category, attribute="value", security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
-        return self._callback("asyncGetParamA", unicode(name), unicode(category), unicode(attribute), security_limit, unicode(profile_key), callback=callback, errback=errback)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='sis', out_signature='a{ss}',
-                         async_callbacks=('callback', 'errback'))
-    def asyncGetParamsValuesFromCategory(self, category, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
-        return self._callback("asyncGetParamsValuesFromCategory", unicode(category), security_limit, unicode(profile_key), callback=callback, errback=errback)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ss', out_signature='',
-                         async_callbacks=('callback', 'errback'))
-    def delContact(self, entity_jid, profile_key="@DEFAULT@", callback=None, errback=None):
-        return self._callback("delContact", unicode(entity_jid), unicode(profile_key), callback=callback, errback=errback)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ss', out_signature='(asa(sss)a{sa(a{ss}as)})',
-                         async_callbacks=('callback', 'errback'))
-    def discoInfos(self, entity_jid, profile_key, callback=None, errback=None):
-        return self._callback("discoInfos", unicode(entity_jid), unicode(profile_key), callback=callback, errback=errback)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ss', out_signature='a(sss)',
-                         async_callbacks=('callback', 'errback'))
-    def discoItems(self, entity_jid, profile_key, callback=None, errback=None):
-        return self._callback("discoItems", unicode(entity_jid), unicode(profile_key), callback=callback, errback=errback)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='',
-                         async_callbacks=None)
-    def disconnect(self, profile_key="@DEFAULT@"):
-        return self._callback("disconnect", unicode(profile_key))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ss', out_signature='s',
-                         async_callbacks=None)
-    def getConfig(self, section, name):
-        return self._callback("getConfig", unicode(section), unicode(name))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='a(sa{ss}as)',
-                         async_callbacks=('callback', 'errback'))
-    def getContacts(self, profile_key="@DEFAULT@", callback=None, errback=None):
-        return self._callback("getContacts", unicode(profile_key), callback=callback, errback=errback)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ss', out_signature='as',
-                         async_callbacks=None)
-    def getContactsFromGroup(self, group, profile_key="@DEFAULT@"):
-        return self._callback("getContactsFromGroup", unicode(group), unicode(profile_key))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='asass', out_signature='a{sa{ss}}',
-                         async_callbacks=None)
-    def getEntitiesData(self, jids, keys, profile):
-        return self._callback("getEntitiesData", jids, keys, unicode(profile))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='sass', out_signature='a{ss}',
-                         async_callbacks=None)
-    def getEntityData(self, jid, keys, profile):
-        return self._callback("getEntityData", unicode(jid), keys, unicode(profile))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='a{sa{ss}}',
-                         async_callbacks=('callback', 'errback'))
-    def getFeatures(self, profile_key, callback=None, errback=None):
-        return self._callback("getFeatures", unicode(profile_key), callback=callback, errback=errback)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ss', out_signature='s',
-                         async_callbacks=None)
-    def getMainResource(self, contact_jid, profile_key="@DEFAULT@"):
-        return self._callback("getMainResource", unicode(contact_jid), unicode(profile_key))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ss', out_signature='s',
-                         async_callbacks=None)
-    def getMenuHelp(self, menu_id, language):
-        return self._callback("getMenuHelp", unicode(menu_id), unicode(language))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='si', out_signature='a(ssasasa{ss})',
-                         async_callbacks=None)
-    def getMenus(self, language, security_limit):
-        return self._callback("getMenus", unicode(language), security_limit)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ssss', out_signature='s',
-                         async_callbacks=None)
-    def getParamA(self, name, category, attribute="value", profile_key="@DEFAULT@"):
-        return self._callback("getParamA", unicode(name), unicode(category), unicode(attribute), unicode(profile_key))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='', out_signature='as',
-                         async_callbacks=None)
-    def getParamsCategories(self, ):
-        return self._callback("getParamsCategories", )
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='iss', out_signature='s',
-                         async_callbacks=('callback', 'errback'))
-    def getParamsUI(self, security_limit=-1, app='', profile_key="@DEFAULT@", callback=None, errback=None):
-        return self._callback("getParamsUI", security_limit, unicode(app), unicode(profile_key), callback=callback, errback=errback)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='a{sa{s(sia{ss})}}',
-                         async_callbacks=None)
-    def getPresenceStatuses(self, profile_key="@DEFAULT@"):
-        return self._callback("getPresenceStatuses", unicode(profile_key))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='s',
-                         async_callbacks=None)
-    def getProfileName(self, profile_key="@DEFAULT@"):
-        return self._callback("getProfileName", unicode(profile_key))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='', out_signature='as',
-                         async_callbacks=None)
-    def getProfilesList(self, ):
-        return self._callback("getProfilesList", )
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='', out_signature='',
-                         async_callbacks=('callback', 'errback'))
-    def getReady(self, callback=None, errback=None):
-        return self._callback("getReady", callback=callback, errback=errback)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='', out_signature='s',
-                         async_callbacks=None)
-    def getVersion(self, ):
-        return self._callback("getVersion", )
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='a{ss}',
-                         async_callbacks=None)
-    def getWaitingSub(self, profile_key="@DEFAULT@"):
-        return self._callback("getWaitingSub", unicode(profile_key))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ssiba{ss}s', out_signature='a(sdssa{ss}a{ss}sa{ss})',
-                         async_callbacks=('callback', 'errback'))
-    def historyGet(self, from_jid, to_jid, limit, between=True, filters='', profile="@NONE@", callback=None, errback=None):
-        return self._callback("historyGet", unicode(from_jid), unicode(to_jid), limit, between, filters, unicode(profile), callback=callback, errback=errback)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='b',
-                         async_callbacks=None)
-    def isConnected(self, profile_key="@DEFAULT@"):
-        return self._callback("isConnected", unicode(profile_key))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='sa{ss}s', out_signature='a{ss}',
-                         async_callbacks=('callback', 'errback'))
-    def launchAction(self, callback_id, data, profile_key="@DEFAULT@", callback=None, errback=None):
-        return self._callback("launchAction", unicode(callback_id), data, unicode(profile_key), callback=callback, errback=errback)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='b',
-                         async_callbacks=None)
-    def loadParamsTemplate(self, filename):
-        return self._callback("loadParamsTemplate", unicode(filename))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='sa{ss}a{ss}sa{ss}s', out_signature='',
-                         async_callbacks=('callback', 'errback'))
-    def messageSend(self, to_jid, message, subject={}, mess_type="auto", extra={}, profile_key="@NONE@", callback=None, errback=None):
-        return self._callback("messageSend", unicode(to_jid), message, subject, unicode(mess_type), extra, unicode(profile_key), callback=callback, errback=errback)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='sis', out_signature='',
-                         async_callbacks=None)
-    def paramsRegisterApp(self, xml, security_limit=-1, app=''):
-        return self._callback("paramsRegisterApp", unicode(xml), security_limit, unicode(app))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='b',
-                         async_callbacks=None)
-    def profileIsSessionStarted(self, profile_key="@DEFAULT@"):
-        return self._callback("profileIsSessionStarted", unicode(profile_key))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='',
-                         async_callbacks=None)
-    def profileSetDefault(self, profile):
-        return self._callback("profileSetDefault", unicode(profile))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ss', out_signature='b',
-                         async_callbacks=('callback', 'errback'))
-    def profileStartSession(self, password='', profile_key="@DEFAULT@", callback=None, errback=None):
-        return self._callback("profileStartSession", unicode(password), unicode(profile_key), callback=callback, errback=errback)
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ss', out_signature='a{ss}',
-                         async_callbacks=None)
-    def progressGet(self, id, profile):
-        return self._callback("progressGet", unicode(id), unicode(profile))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='a{sa{sa{ss}}}',
-                         async_callbacks=None)
-    def progressGetAll(self, profile):
-        return self._callback("progressGetAll", unicode(profile))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='a{sa{sa{ss}}}',
-                         async_callbacks=None)
-    def progressGetAllMetadata(self, profile):
-        return self._callback("progressGetAllMetadata", unicode(profile))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='b',
-                         async_callbacks=None)
-    def saveParamsTemplate(self, filename):
-        return self._callback("saveParamsTemplate", unicode(filename))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='sssis', out_signature='',
-                         async_callbacks=None)
-    def setParam(self, name, value, category, security_limit=-1, profile_key="@DEFAULT@"):
-        return self._callback("setParam", unicode(name), unicode(value), unicode(category), security_limit, unicode(profile_key))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ssa{ss}s', out_signature='',
-                         async_callbacks=None)
-    def setPresence(self, to_jid='', show='', statuses={}, profile_key="@DEFAULT@"):
-        return self._callback("setPresence", unicode(to_jid), unicode(show), statuses, unicode(profile_key))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='sss', out_signature='',
-                         async_callbacks=None)
-    def subscription(self, sub_type, entity, profile_key="@DEFAULT@"):
-        return self._callback("subscription", unicode(sub_type), unicode(entity), unicode(profile_key))
-
-    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ssass', out_signature='',
-                         async_callbacks=('callback', 'errback'))
-    def updateContact(self, entity_jid, name, groups, profile_key="@DEFAULT@", callback=None, errback=None):
-        return self._callback("updateContact", unicode(entity_jid), unicode(name), groups, unicode(profile_key), callback=callback, errback=errback)
-
-    def __attributes(self, in_sign):
-        """Return arguments to user given a in_sign
-        @param in_sign: in_sign in the short form (using s,a,i,b etc)
-        @return: list of arguments that correspond to a in_sign (e.g.: "sss" return "arg1, arg2, arg3")"""
-        i = 0
-        idx = 0
-        attr = []
-        while i < len(in_sign):
-            if in_sign[i] not in ['b', 'y', 'n', 'i', 'x', 'q', 'u', 't', 'd', 's', 'a']:
-                raise ParseError("Unmanaged attribute type [%c]" % in_sign[i])
-
-            attr.append("arg_%i" % idx)
-            idx += 1
-
-            if in_sign[i] == 'a':
-                i += 1
-                if in_sign[i] != '{' and in_sign[i] != '(':  # FIXME: must manage tuples out of arrays
-                    i += 1
-                    continue  # we have a simple type for the array
-                opening_car = in_sign[i]
-                assert(opening_car in ['{', '('])
-                closing_car = '}' if opening_car == '{' else ')'
-                opening_count = 1
-                while (True):  # we have a dict or a list of tuples
-                    i += 1
-                    if i >= len(in_sign):
-                        raise ParseError("missing }")
-                    if in_sign[i] == opening_car:
-                        opening_count += 1
-                    if in_sign[i] == closing_car:
-                        opening_count -= 1
-                        if opening_count == 0:
-                            break
-            i += 1
-        return attr
-
-    def addMethod(self, name, int_suffix, in_sign, out_sign, method, async=False):
-        """Dynamically add a method to Dbus Bridge"""
-        inspect_args = inspect.getargspec(method)
-
-        _arguments = inspect_args.args
-        _defaults = list(inspect_args.defaults or [])
-
-        if inspect.ismethod(method):
-            #if we have a method, we don't want the first argument (usually 'self')
-            del(_arguments[0])
-
-        #first arguments are for the _callback method
-        arguments_callback = ', '.join([repr(name)] + ((_arguments + ['callback=callback', 'errback=errback']) if async else _arguments))
-
-        if async:
-            _arguments.extend(['callback', 'errback'])
-            _defaults.extend([None, None])
-
-        #now we create a second list with default values
-        for i in range(1, len(_defaults) + 1):
-            _arguments[-i] = "%s = %s" % (_arguments[-i], repr(_defaults[-i]))
-
-        arguments_defaults = ', '.join(_arguments)
-
-        code = compile('def %(name)s (self,%(arguments_defaults)s): return self._callback(%(arguments_callback)s)' %
-                       {'name': name, 'arguments_defaults': arguments_defaults, 'arguments_callback': arguments_callback}, '<DBus bridge>', 'exec')
-        exec (code)  # FIXME: to the same thing in a cleaner way, without compile/exec
-        method = locals()[name]
-        async_callbacks = ('callback', 'errback') if async else None
-        setattr(DbusObject, name, dbus.service.method(
-            const_INT_PREFIX + int_suffix, in_signature=in_sign, out_signature=out_sign,
-            async_callbacks=async_callbacks)(method))
-        function = getattr(self, name)
-        func_table = self._dbus_class_table[self.__class__.__module__ + '.' + self.__class__.__name__][function._dbus_interface]
-        func_table[function.__name__] = function  # Needed for introspection
-
-    def addSignal(self, name, int_suffix, signature, doc={}):
-        """Dynamically add a signal to Dbus Bridge"""
-        attributes = ', '.join(self.__attributes(signature))
-        #TODO: use doc parameter to name attributes
-
-        #code = compile ('def '+name+' (self,'+attributes+'): log.debug ("'+name+' signal")', '<DBus bridge>','exec') #XXX: the log.debug is too annoying with xmllog
-        code = compile('def ' + name + ' (self,' + attributes + '): pass', '<DBus bridge>', 'exec')
-        exec (code)
-        signal = locals()[name]
-        setattr(DbusObject, name, dbus.service.signal(
-            const_INT_PREFIX + int_suffix, signature=signature)(signal))
-        function = getattr(self, name)
-        func_table = self._dbus_class_table[self.__class__.__module__ + '.' + self.__class__.__name__][function._dbus_interface]
-        func_table[function.__name__] = function  # Needed for introspection
-
-
-class DBusBridge(object):
-    def __init__(self):
-        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-        log.info("Init DBus...")
-        try:
-            self.session_bus = dbus.SessionBus()
-        except dbus.DBusException as e:
-            if e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported':
-                log.error(_(u"D-Bus is not launched, please see README to see instructions on how to launch it"))
-            raise BridgeInitError
-        self.dbus_name = dbus.service.BusName(const_INT_PREFIX, self.session_bus)
-        self.dbus_bridge = DbusObject(self.session_bus, const_OBJ_PATH)
-
-    def actionNew(self, action_data, id, security_limit, profile):
-        self.dbus_bridge.actionNew(action_data, id, security_limit, profile)
-
-    def connected(self, profile, jid_s):
-        self.dbus_bridge.connected(profile, jid_s)
-
-    def contactDeleted(self, entity_jid, profile):
-        self.dbus_bridge.contactDeleted(entity_jid, profile)
-
-    def disconnected(self, profile):
-        self.dbus_bridge.disconnected(profile)
-
-    def entityDataUpdated(self, jid, name, value, profile):
-        self.dbus_bridge.entityDataUpdated(jid, name, value, profile)
-
-    def messageNew(self, uid, timestamp, from_jid, to_jid, message, subject, mess_type, extra, profile):
-        self.dbus_bridge.messageNew(uid, timestamp, from_jid, to_jid, message, subject, mess_type, extra, profile)
-
-    def newContact(self, contact_jid, attributes, groups, profile):
-        self.dbus_bridge.newContact(contact_jid, attributes, groups, profile)
-
-    def paramUpdate(self, name, value, category, profile):
-        self.dbus_bridge.paramUpdate(name, value, category, profile)
-
-    def presenceUpdate(self, entity_jid, show, priority, statuses, profile):
-        self.dbus_bridge.presenceUpdate(entity_jid, show, priority, statuses, profile)
-
-    def progressError(self, id, error, profile):
-        self.dbus_bridge.progressError(id, error, profile)
-
-    def progressFinished(self, id, metadata, profile):
-        self.dbus_bridge.progressFinished(id, metadata, profile)
-
-    def progressStarted(self, id, metadata, profile):
-        self.dbus_bridge.progressStarted(id, metadata, profile)
-
-    def subscribe(self, sub_type, entity_jid, profile):
-        self.dbus_bridge.subscribe(sub_type, entity_jid, profile)
-
-    def register(self, name, callback):
-        log.debug("registering DBus bridge method [%s]" % name)
-        self.dbus_bridge.register(name, callback)
-
-    def addMethod(self, name, int_suffix, in_sign, out_sign, method, async=False, doc={}):
-        """Dynamically add a method to Dbus Bridge"""
-        #FIXME: doc parameter is kept only temporary, the time to remove it from calls
-        log.debug("Adding method [%s] to DBus bridge" % name)
-        self.dbus_bridge.addMethod(name, int_suffix, in_sign, out_sign, method, async)
-        self.register(name, method)
-
-    def addSignal(self, name, int_suffix, signature, doc={}):
-        self.dbus_bridge.addSignal(name, int_suffix, signature, doc)
-        setattr(DBusBridge, name, getattr(self.dbus_bridge, name))
\ No newline at end of file
--- a/src/bridge/bridge_constructor/constructors/dbus/constructor.py	Sun Oct 02 22:44:33 2016 +0200
+++ b/src/bridge/bridge_constructor/constructors/dbus/constructor.py	Mon Oct 03 21:15:39 2016 +0200
@@ -23,7 +23,7 @@
 class DbusConstructor(base_constructor.Constructor):
     NAME = "dbus"
     CORE_TEMPLATE = "dbus_core_template.py"
-    CORE_DEST = "DBus.py"
+    CORE_DEST = "dbus_bridge.py"
     CORE_FORMATS = {
         'signals': """\
     @dbus.service.signal(const_INT_PREFIX+const_{category}_SUFFIX,
--- a/src/bridge/bridge_constructor/constructors/dbus/dbus_core_template.py	Sun Oct 02 22:44:33 2016 +0200
+++ b/src/bridge/bridge_constructor/constructors/dbus/dbus_core_template.py	Mon Oct 03 21:15:39 2016 +0200
@@ -83,7 +83,7 @@
         log.debug("Init DbusObject...")
         self.cb = {}
 
-    def register(self, name, cb):
+    def register_method(self, name, cb):
         self.cb[name] = cb
 
     def _callback(self, name, *args, **kwargs):
@@ -216,7 +216,7 @@
         func_table[function.__name__] = function  # Needed for introspection
 
 
-class DBusBridge(object):
+class Bridge(object):
     def __init__(self):
         dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
         log.info("Init DBus...")
@@ -230,17 +230,17 @@
         self.dbus_bridge = DbusObject(self.session_bus, const_OBJ_PATH)
 
 ##SIGNAL_DIRECT_CALLS_PART##
-    def register(self, name, callback):
+    def register_method(self, name, callback):
         log.debug("registering DBus bridge method [%s]" % name)
-        self.dbus_bridge.register(name, callback)
+        self.dbus_bridge.register_method(name, callback)
 
     def addMethod(self, name, int_suffix, in_sign, out_sign, method, async=False, doc={}):
         """Dynamically add a method to Dbus Bridge"""
         #FIXME: doc parameter is kept only temporary, the time to remove it from calls
         log.debug("Adding method [%s] to DBus bridge" % name)
         self.dbus_bridge.addMethod(name, int_suffix, in_sign, out_sign, method, async)
-        self.register(name, method)
+        self.register_method(name, method)
 
     def addSignal(self, name, int_suffix, signature, doc={}):
         self.dbus_bridge.addSignal(name, int_suffix, signature, doc)
-        setattr(DBusBridge, name, getattr(self.dbus_bridge, name))
+        setattr(Bridge, name, getattr(self.dbus_bridge, name))
--- a/src/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py	Sun Oct 02 22:44:33 2016 +0200
+++ b/src/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py	Mon Oct 03 21:15:39 2016 +0200
@@ -59,7 +59,7 @@
     return BridgeException(name, message, condition)
 
 
-class DBusBridgeFrontend(BridgeFrontend):
+class Bridge(BridgeFrontend):
     def __init__(self):
         try:
             self.sessions_bus = dbus.SessionBus()
@@ -80,7 +80,7 @@
                 raise e
         #props = self.db_core_iface.getProperties()
 
-    def register(self, functionName, handler, iface="core"):
+    def register_signal(self, functionName, handler, iface="core"):
         if iface == "core":
             self.db_core_iface.connect_to_signal(functionName, handler)
         elif iface == "plugin":
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/bridge/dbus_bridge.py	Mon Oct 03 21:15:39 2016 +0200
@@ -0,0 +1,623 @@
+#!/usr/bin/env python2
+#-*- coding: utf-8 -*-
+
+# SAT: a jabber client
+# Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org)
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+from sat.core.i18n import _
+import dbus
+import dbus.service
+import dbus.mainloop.glib
+import inspect
+from sat.core.log import getLogger
+log = getLogger(__name__)
+from twisted.internet.defer import Deferred
+from sat.core.exceptions import BridgeInitError
+
+const_INT_PREFIX = "org.goffi.SAT"  # Interface prefix
+const_ERROR_PREFIX = const_INT_PREFIX + ".error"
+const_OBJ_PATH = '/org/goffi/SAT/bridge'
+const_CORE_SUFFIX = ".core"
+const_PLUGIN_SUFFIX = ".plugin"
+
+
+class ParseError(Exception):
+    pass
+
+
+class MethodNotRegistered(dbus.DBusException):
+    _dbus_error_name = const_ERROR_PREFIX + ".MethodNotRegistered"
+
+
+class InternalError(dbus.DBusException):
+    _dbus_error_name = const_ERROR_PREFIX + ".InternalError"
+
+
+class AsyncNotDeferred(dbus.DBusException):
+    _dbus_error_name = const_ERROR_PREFIX + ".AsyncNotDeferred"
+
+
+class DeferredNotAsync(dbus.DBusException):
+    _dbus_error_name = const_ERROR_PREFIX + ".DeferredNotAsync"
+
+
+class GenericException(dbus.DBusException):
+    def __init__(self, twisted_error):
+        """
+
+        @param twisted_error (Failure): instance of twisted Failure
+        @return: DBusException
+        """
+        super(GenericException, self).__init__()
+        try:
+            # twisted_error.value is a class
+            class_ = twisted_error.value().__class__
+        except TypeError:
+            # twisted_error.value is an instance
+            class_ = twisted_error.value.__class__
+            message = twisted_error.getErrorMessage()
+            try:
+                self.args = (message, twisted_error.value.condition)
+            except AttributeError:
+                self.args = (message,)
+        self._dbus_error_name = '.'.join([const_ERROR_PREFIX, class_.__module__, class_.__name__])
+
+
+class DbusObject(dbus.service.Object):
+
+    def __init__(self, bus, path):
+        dbus.service.Object.__init__(self, bus, path)
+        log.debug("Init DbusObject...")
+        self.cb = {}
+
+    def register_method(self, name, cb):
+        self.cb[name] = cb
+
+    def _callback(self, name, *args, **kwargs):
+        """call the callback if it exists, raise an exception else
+        if the callback return a deferred, use async methods"""
+        if not name in self.cb:
+            raise MethodNotRegistered
+
+        if "callback" in kwargs:
+            #we must have errback too
+            if not "errback" in kwargs:
+                log.error("errback is missing in method call [%s]" % name)
+                raise InternalError
+            callback = kwargs.pop("callback")
+            errback = kwargs.pop("errback")
+            async = True
+        else:
+            async = False
+        result = self.cb[name](*args, **kwargs)
+        if async:
+            if not isinstance(result, Deferred):
+                log.error("Asynchronous method [%s] does not return a Deferred." % name)
+                raise AsyncNotDeferred
+            result.addCallback(lambda result: callback() if result is None else callback(result))
+            result.addErrback(lambda err: errback(GenericException(err)))
+        else:
+            if isinstance(result, Deferred):
+                log.error("Synchronous method [%s] return a Deferred." % name)
+                raise DeferredNotAsync
+            return result
+    ### signals ###
+
+    @dbus.service.signal(const_INT_PREFIX + const_PLUGIN_SUFFIX,
+                         signature='')
+    def dummySignal(self):
+        #FIXME: workaround for addSignal (doesn't work if one method doensn't
+        #       already exist for plugins), probably missing some initialisation, need
+        #       further investigations
+        pass
+
+    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
+                         signature='a{ss}sis')
+    def actionNew(self, action_data, id, security_limit, profile):
+        pass
+
+    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
+                         signature='ss')
+    def connected(self, profile, jid_s):
+        pass
+
+    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
+                         signature='ss')
+    def contactDeleted(self, entity_jid, profile):
+        pass
+
+    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
+                         signature='s')
+    def disconnected(self, profile):
+        pass
+
+    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
+                         signature='ssss')
+    def entityDataUpdated(self, jid, name, value, profile):
+        pass
+
+    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
+                         signature='sdssa{ss}a{ss}sa{ss}s')
+    def messageNew(self, uid, timestamp, from_jid, to_jid, message, subject, mess_type, extra, profile):
+        pass
+
+    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
+                         signature='sa{ss}ass')
+    def newContact(self, contact_jid, attributes, groups, profile):
+        pass
+
+    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
+                         signature='ssss')
+    def paramUpdate(self, name, value, category, profile):
+        pass
+
+    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
+                         signature='ssia{ss}s')
+    def presenceUpdate(self, entity_jid, show, priority, statuses, profile):
+        pass
+
+    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
+                         signature='sss')
+    def progressError(self, id, error, profile):
+        pass
+
+    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
+                         signature='sa{ss}s')
+    def progressFinished(self, id, metadata, profile):
+        pass
+
+    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
+                         signature='sa{ss}s')
+    def progressStarted(self, id, metadata, profile):
+        pass
+
+    @dbus.service.signal(const_INT_PREFIX+const_CORE_SUFFIX,
+                         signature='sss')
+    def subscribe(self, sub_type, entity_jid, profile):
+        pass
+
+    ### methods ###
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='s', out_signature='a(a{ss}si)',
+                         async_callbacks=None)
+    def actionsGet(self, profile_key="@DEFAULT@"):
+        return self._callback("actionsGet", unicode(profile_key))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ss', out_signature='',
+                         async_callbacks=None)
+    def addContact(self, entity_jid, profile_key="@DEFAULT@"):
+        return self._callback("addContact", unicode(entity_jid), unicode(profile_key))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ss', out_signature='b',
+                         async_callbacks=('callback', 'errback'))
+    def asyncConnect(self, profile_key="@DEFAULT@", password='', callback=None, errback=None):
+        return self._callback("asyncConnect", unicode(profile_key), unicode(password), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ss', out_signature='',
+                         async_callbacks=('callback', 'errback'))
+    def asyncCreateProfile(self, profile, password='', callback=None, errback=None):
+        return self._callback("asyncCreateProfile", unicode(profile), unicode(password), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='s', out_signature='',
+                         async_callbacks=('callback', 'errback'))
+    def asyncDeleteProfile(self, profile, callback=None, errback=None):
+        return self._callback("asyncDeleteProfile", unicode(profile), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='sssis', out_signature='s',
+                         async_callbacks=('callback', 'errback'))
+    def asyncGetParamA(self, name, category, attribute="value", security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
+        return self._callback("asyncGetParamA", unicode(name), unicode(category), unicode(attribute), security_limit, unicode(profile_key), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='sis', out_signature='a{ss}',
+                         async_callbacks=('callback', 'errback'))
+    def asyncGetParamsValuesFromCategory(self, category, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
+        return self._callback("asyncGetParamsValuesFromCategory", unicode(category), security_limit, unicode(profile_key), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ss', out_signature='',
+                         async_callbacks=('callback', 'errback'))
+    def delContact(self, entity_jid, profile_key="@DEFAULT@", callback=None, errback=None):
+        return self._callback("delContact", unicode(entity_jid), unicode(profile_key), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ss', out_signature='(asa(sss)a{sa(a{ss}as)})',
+                         async_callbacks=('callback', 'errback'))
+    def discoInfos(self, entity_jid, profile_key, callback=None, errback=None):
+        return self._callback("discoInfos", unicode(entity_jid), unicode(profile_key), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ss', out_signature='a(sss)',
+                         async_callbacks=('callback', 'errback'))
+    def discoItems(self, entity_jid, profile_key, callback=None, errback=None):
+        return self._callback("discoItems", unicode(entity_jid), unicode(profile_key), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='s', out_signature='',
+                         async_callbacks=None)
+    def disconnect(self, profile_key="@DEFAULT@"):
+        return self._callback("disconnect", unicode(profile_key))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ss', out_signature='s',
+                         async_callbacks=None)
+    def getConfig(self, section, name):
+        return self._callback("getConfig", unicode(section), unicode(name))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='s', out_signature='a(sa{ss}as)',
+                         async_callbacks=('callback', 'errback'))
+    def getContacts(self, profile_key="@DEFAULT@", callback=None, errback=None):
+        return self._callback("getContacts", unicode(profile_key), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ss', out_signature='as',
+                         async_callbacks=None)
+    def getContactsFromGroup(self, group, profile_key="@DEFAULT@"):
+        return self._callback("getContactsFromGroup", unicode(group), unicode(profile_key))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='asass', out_signature='a{sa{ss}}',
+                         async_callbacks=None)
+    def getEntitiesData(self, jids, keys, profile):
+        return self._callback("getEntitiesData", jids, keys, unicode(profile))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='sass', out_signature='a{ss}',
+                         async_callbacks=None)
+    def getEntityData(self, jid, keys, profile):
+        return self._callback("getEntityData", unicode(jid), keys, unicode(profile))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='s', out_signature='a{sa{ss}}',
+                         async_callbacks=('callback', 'errback'))
+    def getFeatures(self, profile_key, callback=None, errback=None):
+        return self._callback("getFeatures", unicode(profile_key), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ss', out_signature='s',
+                         async_callbacks=None)
+    def getMainResource(self, contact_jid, profile_key="@DEFAULT@"):
+        return self._callback("getMainResource", unicode(contact_jid), unicode(profile_key))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ss', out_signature='s',
+                         async_callbacks=None)
+    def getMenuHelp(self, menu_id, language):
+        return self._callback("getMenuHelp", unicode(menu_id), unicode(language))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='si', out_signature='a(ssasasa{ss})',
+                         async_callbacks=None)
+    def getMenus(self, language, security_limit):
+        return self._callback("getMenus", unicode(language), security_limit)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ssss', out_signature='s',
+                         async_callbacks=None)
+    def getParamA(self, name, category, attribute="value", profile_key="@DEFAULT@"):
+        return self._callback("getParamA", unicode(name), unicode(category), unicode(attribute), unicode(profile_key))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='', out_signature='as',
+                         async_callbacks=None)
+    def getParamsCategories(self, ):
+        return self._callback("getParamsCategories", )
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='iss', out_signature='s',
+                         async_callbacks=('callback', 'errback'))
+    def getParamsUI(self, security_limit=-1, app='', profile_key="@DEFAULT@", callback=None, errback=None):
+        return self._callback("getParamsUI", security_limit, unicode(app), unicode(profile_key), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='s', out_signature='a{sa{s(sia{ss})}}',
+                         async_callbacks=None)
+    def getPresenceStatuses(self, profile_key="@DEFAULT@"):
+        return self._callback("getPresenceStatuses", unicode(profile_key))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='s', out_signature='s',
+                         async_callbacks=None)
+    def getProfileName(self, profile_key="@DEFAULT@"):
+        return self._callback("getProfileName", unicode(profile_key))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='', out_signature='as',
+                         async_callbacks=None)
+    def getProfilesList(self, ):
+        return self._callback("getProfilesList", )
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='', out_signature='',
+                         async_callbacks=('callback', 'errback'))
+    def getReady(self, callback=None, errback=None):
+        return self._callback("getReady", callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='', out_signature='s',
+                         async_callbacks=None)
+    def getVersion(self, ):
+        return self._callback("getVersion", )
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='s', out_signature='a{ss}',
+                         async_callbacks=None)
+    def getWaitingSub(self, profile_key="@DEFAULT@"):
+        return self._callback("getWaitingSub", unicode(profile_key))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ssiba{ss}s', out_signature='a(sdssa{ss}a{ss}sa{ss})',
+                         async_callbacks=('callback', 'errback'))
+    def historyGet(self, from_jid, to_jid, limit, between=True, filters='', profile="@NONE@", callback=None, errback=None):
+        return self._callback("historyGet", unicode(from_jid), unicode(to_jid), limit, between, filters, unicode(profile), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='s', out_signature='b',
+                         async_callbacks=None)
+    def isConnected(self, profile_key="@DEFAULT@"):
+        return self._callback("isConnected", unicode(profile_key))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='sa{ss}s', out_signature='a{ss}',
+                         async_callbacks=('callback', 'errback'))
+    def launchAction(self, callback_id, data, profile_key="@DEFAULT@", callback=None, errback=None):
+        return self._callback("launchAction", unicode(callback_id), data, unicode(profile_key), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='s', out_signature='b',
+                         async_callbacks=None)
+    def loadParamsTemplate(self, filename):
+        return self._callback("loadParamsTemplate", unicode(filename))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='sa{ss}a{ss}sa{ss}s', out_signature='',
+                         async_callbacks=('callback', 'errback'))
+    def messageSend(self, to_jid, message, subject={}, mess_type="auto", extra={}, profile_key="@NONE@", callback=None, errback=None):
+        return self._callback("messageSend", unicode(to_jid), message, subject, unicode(mess_type), extra, unicode(profile_key), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='sis', out_signature='',
+                         async_callbacks=None)
+    def paramsRegisterApp(self, xml, security_limit=-1, app=''):
+        return self._callback("paramsRegisterApp", unicode(xml), security_limit, unicode(app))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='s', out_signature='b',
+                         async_callbacks=None)
+    def profileIsSessionStarted(self, profile_key="@DEFAULT@"):
+        return self._callback("profileIsSessionStarted", unicode(profile_key))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='s', out_signature='',
+                         async_callbacks=None)
+    def profileSetDefault(self, profile):
+        return self._callback("profileSetDefault", unicode(profile))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ss', out_signature='b',
+                         async_callbacks=('callback', 'errback'))
+    def profileStartSession(self, password='', profile_key="@DEFAULT@", callback=None, errback=None):
+        return self._callback("profileStartSession", unicode(password), unicode(profile_key), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ss', out_signature='a{ss}',
+                         async_callbacks=None)
+    def progressGet(self, id, profile):
+        return self._callback("progressGet", unicode(id), unicode(profile))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='s', out_signature='a{sa{sa{ss}}}',
+                         async_callbacks=None)
+    def progressGetAll(self, profile):
+        return self._callback("progressGetAll", unicode(profile))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='s', out_signature='a{sa{sa{ss}}}',
+                         async_callbacks=None)
+    def progressGetAllMetadata(self, profile):
+        return self._callback("progressGetAllMetadata", unicode(profile))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='s', out_signature='b',
+                         async_callbacks=None)
+    def saveParamsTemplate(self, filename):
+        return self._callback("saveParamsTemplate", unicode(filename))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='sssis', out_signature='',
+                         async_callbacks=None)
+    def setParam(self, name, value, category, security_limit=-1, profile_key="@DEFAULT@"):
+        return self._callback("setParam", unicode(name), unicode(value), unicode(category), security_limit, unicode(profile_key))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ssa{ss}s', out_signature='',
+                         async_callbacks=None)
+    def setPresence(self, to_jid='', show='', statuses={}, profile_key="@DEFAULT@"):
+        return self._callback("setPresence", unicode(to_jid), unicode(show), statuses, unicode(profile_key))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='sss', out_signature='',
+                         async_callbacks=None)
+    def subscription(self, sub_type, entity, profile_key="@DEFAULT@"):
+        return self._callback("subscription", unicode(sub_type), unicode(entity), unicode(profile_key))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ssass', out_signature='',
+                         async_callbacks=('callback', 'errback'))
+    def updateContact(self, entity_jid, name, groups, profile_key="@DEFAULT@", callback=None, errback=None):
+        return self._callback("updateContact", unicode(entity_jid), unicode(name), groups, unicode(profile_key), callback=callback, errback=errback)
+
+    def __attributes(self, in_sign):
+        """Return arguments to user given a in_sign
+        @param in_sign: in_sign in the short form (using s,a,i,b etc)
+        @return: list of arguments that correspond to a in_sign (e.g.: "sss" return "arg1, arg2, arg3")"""
+        i = 0
+        idx = 0
+        attr = []
+        while i < len(in_sign):
+            if in_sign[i] not in ['b', 'y', 'n', 'i', 'x', 'q', 'u', 't', 'd', 's', 'a']:
+                raise ParseError("Unmanaged attribute type [%c]" % in_sign[i])
+
+            attr.append("arg_%i" % idx)
+            idx += 1
+
+            if in_sign[i] == 'a':
+                i += 1
+                if in_sign[i] != '{' and in_sign[i] != '(':  # FIXME: must manage tuples out of arrays
+                    i += 1
+                    continue  # we have a simple type for the array
+                opening_car = in_sign[i]
+                assert(opening_car in ['{', '('])
+                closing_car = '}' if opening_car == '{' else ')'
+                opening_count = 1
+                while (True):  # we have a dict or a list of tuples
+                    i += 1
+                    if i >= len(in_sign):
+                        raise ParseError("missing }")
+                    if in_sign[i] == opening_car:
+                        opening_count += 1
+                    if in_sign[i] == closing_car:
+                        opening_count -= 1
+                        if opening_count == 0:
+                            break
+            i += 1
+        return attr
+
+    def addMethod(self, name, int_suffix, in_sign, out_sign, method, async=False):
+        """Dynamically add a method to Dbus Bridge"""
+        inspect_args = inspect.getargspec(method)
+
+        _arguments = inspect_args.args
+        _defaults = list(inspect_args.defaults or [])
+
+        if inspect.ismethod(method):
+            #if we have a method, we don't want the first argument (usually 'self')
+            del(_arguments[0])
+
+        #first arguments are for the _callback method
+        arguments_callback = ', '.join([repr(name)] + ((_arguments + ['callback=callback', 'errback=errback']) if async else _arguments))
+
+        if async:
+            _arguments.extend(['callback', 'errback'])
+            _defaults.extend([None, None])
+
+        #now we create a second list with default values
+        for i in range(1, len(_defaults) + 1):
+            _arguments[-i] = "%s = %s" % (_arguments[-i], repr(_defaults[-i]))
+
+        arguments_defaults = ', '.join(_arguments)
+
+        code = compile('def %(name)s (self,%(arguments_defaults)s): return self._callback(%(arguments_callback)s)' %
+                       {'name': name, 'arguments_defaults': arguments_defaults, 'arguments_callback': arguments_callback}, '<DBus bridge>', 'exec')
+        exec (code)  # FIXME: to the same thing in a cleaner way, without compile/exec
+        method = locals()[name]
+        async_callbacks = ('callback', 'errback') if async else None
+        setattr(DbusObject, name, dbus.service.method(
+            const_INT_PREFIX + int_suffix, in_signature=in_sign, out_signature=out_sign,
+            async_callbacks=async_callbacks)(method))
+        function = getattr(self, name)
+        func_table = self._dbus_class_table[self.__class__.__module__ + '.' + self.__class__.__name__][function._dbus_interface]
+        func_table[function.__name__] = function  # Needed for introspection
+
+    def addSignal(self, name, int_suffix, signature, doc={}):
+        """Dynamically add a signal to Dbus Bridge"""
+        attributes = ', '.join(self.__attributes(signature))
+        #TODO: use doc parameter to name attributes
+
+        #code = compile ('def '+name+' (self,'+attributes+'): log.debug ("'+name+' signal")', '<DBus bridge>','exec') #XXX: the log.debug is too annoying with xmllog
+        code = compile('def ' + name + ' (self,' + attributes + '): pass', '<DBus bridge>', 'exec')
+        exec (code)
+        signal = locals()[name]
+        setattr(DbusObject, name, dbus.service.signal(
+            const_INT_PREFIX + int_suffix, signature=signature)(signal))
+        function = getattr(self, name)
+        func_table = self._dbus_class_table[self.__class__.__module__ + '.' + self.__class__.__name__][function._dbus_interface]
+        func_table[function.__name__] = function  # Needed for introspection
+
+
+class Bridge(object):
+    def __init__(self):
+        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+        log.info("Init DBus...")
+        try:
+            self.session_bus = dbus.SessionBus()
+        except dbus.DBusException as e:
+            if e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported':
+                log.error(_(u"D-Bus is not launched, please see README to see instructions on how to launch it"))
+            raise BridgeInitError
+        self.dbus_name = dbus.service.BusName(const_INT_PREFIX, self.session_bus)
+        self.dbus_bridge = DbusObject(self.session_bus, const_OBJ_PATH)
+
+    def actionNew(self, action_data, id, security_limit, profile):
+        self.dbus_bridge.actionNew(action_data, id, security_limit, profile)
+
+    def connected(self, profile, jid_s):
+        self.dbus_bridge.connected(profile, jid_s)
+
+    def contactDeleted(self, entity_jid, profile):
+        self.dbus_bridge.contactDeleted(entity_jid, profile)
+
+    def disconnected(self, profile):
+        self.dbus_bridge.disconnected(profile)
+
+    def entityDataUpdated(self, jid, name, value, profile):
+        self.dbus_bridge.entityDataUpdated(jid, name, value, profile)
+
+    def messageNew(self, uid, timestamp, from_jid, to_jid, message, subject, mess_type, extra, profile):
+        self.dbus_bridge.messageNew(uid, timestamp, from_jid, to_jid, message, subject, mess_type, extra, profile)
+
+    def newContact(self, contact_jid, attributes, groups, profile):
+        self.dbus_bridge.newContact(contact_jid, attributes, groups, profile)
+
+    def paramUpdate(self, name, value, category, profile):
+        self.dbus_bridge.paramUpdate(name, value, category, profile)
+
+    def presenceUpdate(self, entity_jid, show, priority, statuses, profile):
+        self.dbus_bridge.presenceUpdate(entity_jid, show, priority, statuses, profile)
+
+    def progressError(self, id, error, profile):
+        self.dbus_bridge.progressError(id, error, profile)
+
+    def progressFinished(self, id, metadata, profile):
+        self.dbus_bridge.progressFinished(id, metadata, profile)
+
+    def progressStarted(self, id, metadata, profile):
+        self.dbus_bridge.progressStarted(id, metadata, profile)
+
+    def subscribe(self, sub_type, entity_jid, profile):
+        self.dbus_bridge.subscribe(sub_type, entity_jid, profile)
+
+    def register_method(self, name, callback):
+        log.debug("registering DBus bridge method [%s]" % name)
+        self.dbus_bridge.register_method(name, callback)
+
+    def addMethod(self, name, int_suffix, in_sign, out_sign, method, async=False, doc={}):
+        """Dynamically add a method to Dbus Bridge"""
+        #FIXME: doc parameter is kept only temporary, the time to remove it from calls
+        log.debug("Adding method [%s] to DBus bridge" % name)
+        self.dbus_bridge.addMethod(name, int_suffix, in_sign, out_sign, method, async)
+        self.register_method(name, method)
+
+    def addSignal(self, name, int_suffix, signature, doc={}):
+        self.dbus_bridge.addSignal(name, int_suffix, signature, doc)
+        setattr(Bridge, name, getattr(self.dbus_bridge, name))
\ No newline at end of file
--- a/src/core/sat_main.py	Sun Oct 02 22:44:33 2016 +0200
+++ b/src/core/sat_main.py	Mon Oct 03 21:15:39 2016 +0200
@@ -25,7 +25,7 @@
 from twisted.words.xish import domish
 from twisted.internet import reactor
 from wokkel.xmppim import RosterItem
-from sat.bridge.DBus import DBusBridge
+from sat.bridge.dbus_bridge import Bridge
 from sat.core import xmpp
 from sat.core import exceptions
 from sat.core.log import getLogger
@@ -61,55 +61,55 @@
         self.trigger = trigger.TriggerManager()  # trigger are used to change SàT behaviour
 
         try:
-            self.bridge = DBusBridge()
+            self.bridge = Bridge()
         except exceptions.BridgeInitError:
             log.error(u"Bridge can't be initialised, can't start SàT core")
             sys.exit(1)
-        self.bridge.register("getReady", lambda: self.initialised)
-        self.bridge.register("getVersion", lambda: self.full_version)
-        self.bridge.register("getFeatures", self.getFeatures)
-        self.bridge.register("getProfileName", self.memory.getProfileName)
-        self.bridge.register("getProfilesList", self.memory.getProfilesList)
-        self.bridge.register("getEntityData", lambda jid_, keys, profile: self.memory.getEntityData(jid.JID(jid_), keys, profile))
-        self.bridge.register("getEntitiesData", self.memory._getEntitiesData)
-        self.bridge.register("asyncCreateProfile", self.memory.asyncCreateProfile)
-        self.bridge.register("asyncDeleteProfile", self.memory.asyncDeleteProfile)
-        self.bridge.register("profileStartSession", self.memory.startSession)
-        self.bridge.register("profileIsSessionStarted", self.memory._isSessionStarted)
-        self.bridge.register("profileSetDefault", self.memory.profileSetDefault)
-        self.bridge.register("asyncConnect", self._asyncConnect)
-        self.bridge.register("disconnect", self.disconnect)
-        self.bridge.register("getContacts", self.getContacts)
-        self.bridge.register("getContactsFromGroup", self.getContactsFromGroup)
-        self.bridge.register("getMainResource", self.memory._getMainResource)
-        self.bridge.register("getPresenceStatuses", self.memory._getPresenceStatuses)
-        self.bridge.register("getWaitingSub", self.memory.getWaitingSub)
-        self.bridge.register("messageSend", self._messageSend)
-        self.bridge.register("getConfig", self._getConfig)
-        self.bridge.register("setParam", self.setParam)
-        self.bridge.register("getParamA", self.memory.getStringParamA)
-        self.bridge.register("asyncGetParamA", self.memory.asyncGetStringParamA)
-        self.bridge.register("asyncGetParamsValuesFromCategory", self.memory.asyncGetParamsValuesFromCategory)
-        self.bridge.register("getParamsUI", self.memory.getParamsUI)
-        self.bridge.register("getParamsCategories", self.memory.getParamsCategories)
-        self.bridge.register("paramsRegisterApp", self.memory.paramsRegisterApp)
-        self.bridge.register("historyGet", self.memory._historyGet)
-        self.bridge.register("setPresence", self._setPresence)
-        self.bridge.register("subscription", self.subscription)
-        self.bridge.register("addContact", self._addContact)
-        self.bridge.register("updateContact", self._updateContact)
-        self.bridge.register("delContact", self._delContact)
-        self.bridge.register("isConnected", self.isConnected)
-        self.bridge.register("launchAction", self.launchCallback)
-        self.bridge.register("actionsGet", self.actionsGet)
-        self.bridge.register("progressGet", self._progressGet)
-        self.bridge.register("progressGetAll", self._progressGetAll)
-        self.bridge.register("getMenus", self.getMenus)
-        self.bridge.register("getMenuHelp", self.getMenuHelp)
-        self.bridge.register("discoInfos", self.memory.disco._discoInfos)
-        self.bridge.register("discoItems", self.memory.disco._discoItems)
-        self.bridge.register("saveParamsTemplate", self.memory.save_xml)
-        self.bridge.register("loadParamsTemplate", self.memory.load_xml)
+        self.bridge.register_method("getReady", lambda: self.initialised)
+        self.bridge.register_method("getVersion", lambda: self.full_version)
+        self.bridge.register_method("getFeatures", self.getFeatures)
+        self.bridge.register_method("getProfileName", self.memory.getProfileName)
+        self.bridge.register_method("getProfilesList", self.memory.getProfilesList)
+        self.bridge.register_method("getEntityData", lambda jid_, keys, profile: self.memory.getEntityData(jid.JID(jid_), keys, profile))
+        self.bridge.register_method("getEntitiesData", self.memory._getEntitiesData)
+        self.bridge.register_method("asyncCreateProfile", self.memory.asyncCreateProfile)
+        self.bridge.register_method("asyncDeleteProfile", self.memory.asyncDeleteProfile)
+        self.bridge.register_method("profileStartSession", self.memory.startSession)
+        self.bridge.register_method("profileIsSessionStarted", self.memory._isSessionStarted)
+        self.bridge.register_method("profileSetDefault", self.memory.profileSetDefault)
+        self.bridge.register_method("asyncConnect", self._asyncConnect)
+        self.bridge.register_method("disconnect", self.disconnect)
+        self.bridge.register_method("getContacts", self.getContacts)
+        self.bridge.register_method("getContactsFromGroup", self.getContactsFromGroup)
+        self.bridge.register_method("getMainResource", self.memory._getMainResource)
+        self.bridge.register_method("getPresenceStatuses", self.memory._getPresenceStatuses)
+        self.bridge.register_method("getWaitingSub", self.memory.getWaitingSub)
+        self.bridge.register_method("messageSend", self._messageSend)
+        self.bridge.register_method("getConfig", self._getConfig)
+        self.bridge.register_method("setParam", self.setParam)
+        self.bridge.register_method("getParamA", self.memory.getStringParamA)
+        self.bridge.register_method("asyncGetParamA", self.memory.asyncGetStringParamA)
+        self.bridge.register_method("asyncGetParamsValuesFromCategory", self.memory.asyncGetParamsValuesFromCategory)
+        self.bridge.register_method("getParamsUI", self.memory.getParamsUI)
+        self.bridge.register_method("getParamsCategories", self.memory.getParamsCategories)
+        self.bridge.register_method("paramsRegisterApp", self.memory.paramsRegisterApp)
+        self.bridge.register_method("historyGet", self.memory._historyGet)
+        self.bridge.register_method("setPresence", self._setPresence)
+        self.bridge.register_method("subscription", self.subscription)
+        self.bridge.register_method("addContact", self._addContact)
+        self.bridge.register_method("updateContact", self._updateContact)
+        self.bridge.register_method("delContact", self._delContact)
+        self.bridge.register_method("isConnected", self.isConnected)
+        self.bridge.register_method("launchAction", self.launchCallback)
+        self.bridge.register_method("actionsGet", self.actionsGet)
+        self.bridge.register_method("progressGet", self._progressGet)
+        self.bridge.register_method("progressGetAll", self._progressGetAll)
+        self.bridge.register_method("getMenus", self.getMenus)
+        self.bridge.register_method("getMenuHelp", self.getMenuHelp)
+        self.bridge.register_method("discoInfos", self.memory.disco._discoInfos)
+        self.bridge.register_method("discoItems", self.memory.disco._discoItems)
+        self.bridge.register_method("saveParamsTemplate", self.memory.save_xml)
+        self.bridge.register_method("loadParamsTemplate", self.memory.load_xml)
 
         self.memory.initialized.addCallback(self._postMemoryInit)