From 5b56cc7e422abf4bdd60ce217c1e8a62fbaa1b88 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Tue, 4 May 2021 14:41:33 -0400
Subject: [PATCH] fileTransfer: massive cleanup

The new logic is there! Swarm is working since some time now, so we can
remove previous logic.

GitLab: #524
Change-Id: I5ca172e9349694d944c9561d97fe8a63d190ebf3
---
 .../cx.ring.Ring.ConfigurationManager.xml     |  25 -
 bin/dbus/dbusconfigurationmanager.cpp         |  52 --
 bin/dbus/dbusconfigurationmanager.h           |  10 -
 bin/jni/datatransfer.i                        |   3 -
 src/CMakeLists.txt                            |   2 -
 src/Makefile.am                               |   2 -
 src/client/datatransfer.cpp                   |  49 -
 src/connectivity/peer_connection.h            |   2 -
 src/data_transfer.cpp                         | 847 +-----------------
 src/data_transfer.h                           |  43 +-
 src/ftp_server.cpp                            | 223 -----
 src/ftp_server.h                              | 106 ---
 src/jami/datatransfer_interface.h             |  57 +-
 src/jamidht/CMakeLists.txt                    |   4 -
 src/jamidht/Makefile.am                       |   4 -
 src/jamidht/channeled_transfers.cpp           | 106 ---
 src/jamidht/channeled_transfers.h             |  63 --
 src/jamidht/conversation.cpp                  |  11 +
 src/jamidht/jamiaccount.cpp                   | 130 +--
 src/jamidht/jamiaccount.h                     |  34 +-
 src/jamidht/p2p.cpp                           | 316 -------
 src/jamidht/p2p.h                             |  61 --
 src/jamidht/transfer_channel_handler.cpp      |   5 +-
 src/meson.build                               |   3 -
 test/unitTest/conversation/conversation.cpp   | 415 +++++----
 test/unitTest/fileTransfer/fileTransfer.cpp   | 275 +-----
 26 files changed, 283 insertions(+), 2565 deletions(-)
 delete mode 100644 src/ftp_server.cpp
 delete mode 100644 src/ftp_server.h
 delete mode 100644 src/jamidht/channeled_transfers.cpp
 delete mode 100644 src/jamidht/channeled_transfers.h
 delete mode 100644 src/jamidht/p2p.cpp
 delete mode 100644 src/jamidht/p2p.h

diff --git a/bin/dbus/cx.ring.Ring.ConfigurationManager.xml b/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
index 71b4bcd8e4..01763f6a23 100644
--- a/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
+++ b/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
@@ -1602,23 +1602,6 @@
            <arg type="s" name="replyTo" direction="in"/>
        </method>
 
-       <method name="sendFileLegacy" tp:name-for-bindings="sendFileLegacy">
-           <tp:added version="10.0.0"/>
-           <arg type="u" name="dataTransferError" direction="out"/>
-           <arg type="(suuxxssssss)" name="DataTransferInfo" direction="in"/>
-           <annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="DataTransferInfo"/>
-           <arg type="t" name="dataTransferId" direction="out"/>
-       </method>
-
-       <method name="dataTransferInfo" tp:name-for-bindings="dataTransferInfo">
-           <tp:added version="10.0.0"/>
-           <arg type="u" name="dataTransferError" direction="out"/>
-           <arg type="s" name="accountId" direction="in"/>
-           <arg type="s" name="fileId" direction="in"/>
-           <arg type="(suuxxssssss)" name="dataTransferInfo" direction="out"/>
-           <annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="DataTransferInfo"/>
-       </method>
-
        <method name="fileTransferInfo" tp:name-for-bindings="fileTransferInfo">
            <tp:added version="10.0.0"/>
            <arg type="u" name="dataTransferError" direction="out"/>
@@ -1630,14 +1613,6 @@
            <arg type="x" name="bytesProgress" direction="out"/>
        </method>
 
-       <method name="acceptFileTransfer" tp:name-for-bindings="acceptFileTransfer">
-           <tp:added version="10.0.0"/>
-           <arg type="u" name="dataTransferError" direction="out"/>
-           <arg type="s" name="accountId" direction="in"/>
-           <arg type="s" name="fileId" direction="in"/>
-           <arg type="s" name="filePath" direction="in"/>
-       </method>
-
        <method name="downloadFile" tp:name-for-bindings="downloadFile">
            <tp:added version="10.1.0"/>
            <arg type="b" name="result" direction="out"/>
diff --git a/bin/dbus/dbusconfigurationmanager.cpp b/bin/dbus/dbusconfigurationmanager.cpp
index 7896840266..026a228ff6 100644
--- a/bin/dbus/dbusconfigurationmanager.cpp
+++ b/bin/dbus/dbusconfigurationmanager.cpp
@@ -738,26 +738,6 @@ DBusConfigurationManager::connectivityChanged()
     libjami::connectivityChanged();
 }
 
-void
-DBusConfigurationManager::sendFileLegacy(const RingDBusDataTransferInfo& in,
-                                         uint32_t& error,
-                                         libjami::DataTransferId& id)
-{
-    libjami::DataTransferInfo info;
-    info.accountId = in._1;
-    info.lastEvent = libjami::DataTransferEventCode(in._2);
-    info.flags = in._3;
-    info.totalSize = in._4;
-    info.bytesProgress = in._5;
-    info.author = in._6;
-    info.peer = in._7;
-    info.conversationId = in._8;
-    info.displayName = in._9;
-    info.path = in._10;
-    info.mimetype = in._11;
-    error = uint32_t(libjami::sendFileLegacy(info, id));
-}
-
 void
 DBusConfigurationManager::sendFile(const std::string& accountId,
                                    const std::string& conversationId,
@@ -768,30 +748,6 @@ DBusConfigurationManager::sendFile(const std::string& accountId,
     libjami::sendFile(accountId, conversationId, path, displayName, replyTo);
 }
 
-void
-DBusConfigurationManager::dataTransferInfo(const std::string& accountId,
-                                           const std::string& fileId,
-                                           uint32_t& error,
-                                           RingDBusDataTransferInfo& out)
-{
-    libjami::DataTransferInfo info;
-    auto res = libjami::dataTransferInfo(accountId, fileId, info);
-    if (res == libjami::DataTransferError::success) {
-        out._1 = info.accountId;
-        out._2 = uint32_t(info.lastEvent);
-        out._3 = info.flags;
-        out._4 = info.totalSize;
-        out._5 = info.bytesProgress;
-        out._6 = info.author;
-        out._7 = info.peer;
-        out._8 = info.conversationId;
-        out._9 = info.displayName;
-        out._10 = info.path;
-        out._11 = info.mimetype;
-    }
-    error = uint32_t(res);
-}
-
 void
 DBusConfigurationManager::fileTransferInfo(const std::string& accountId,
                                            const std::string& conversationId,
@@ -805,14 +761,6 @@ DBusConfigurationManager::fileTransferInfo(const std::string& accountId,
         libjami::fileTransferInfo(accountId, conversationId, fileId, path, total, progress));
 }
 
-uint32_t
-DBusConfigurationManager::acceptFileTransfer(const std::string& accountId,
-                                             const std::string& fileId,
-                                             const std::string& file_path)
-{
-    return uint32_t(libjami::acceptFileTransfer(accountId, fileId, file_path));
-}
-
 bool
 DBusConfigurationManager::downloadFile(const std::string& accountId,
                                        const std::string& conversationUri,
diff --git a/bin/dbus/dbusconfigurationmanager.h b/bin/dbus/dbusconfigurationmanager.h
index c176849c8a..2a1a77c2c7 100644
--- a/bin/dbus/dbusconfigurationmanager.h
+++ b/bin/dbus/dbusconfigurationmanager.h
@@ -213,18 +213,11 @@ public:
                                                          const std::string& uri);
     std::vector<std::map<std::string, std::string>> getContacts(const std::string& accountId);
     void connectivityChanged();
-    void sendFileLegacy(const RingDBusDataTransferInfo& info,
-                        uint32_t& error,
-                        libjami::DataTransferId& id);
     void sendFile(const std::string& accountId,
                   const std::string& conversationId,
                   const std::string& path,
                   const std::string& displayName,
                   const std::string& replyTo);
-    void dataTransferInfo(const std::string& accountId,
-                          const std::string& fileId,
-                          uint32_t& error,
-                          RingDBusDataTransferInfo& info);
     void fileTransferInfo(const std::string& accountId,
                           const std::string& conversationId,
                           const std::string& fileId,
@@ -232,9 +225,6 @@ public:
                           std::string& path,
                           int64_t& total,
                           int64_t& progress);
-    uint32_t acceptFileTransfer(const std::string& accountId,
-                                const std::string& fileId,
-                                const std::string& file_path);
     bool downloadFile(const std::string& accountId,
                       const std::string& conversationId,
                       const std::string& interactionId,
diff --git a/bin/jni/datatransfer.i b/bin/jni/datatransfer.i
index b24d6f4a40..7fec440963 100644
--- a/bin/jni/datatransfer.i
+++ b/bin/jni/datatransfer.i
@@ -80,11 +80,8 @@ namespace libjami {
 
   void sendFile(const std::string& accountId, const std::string& conversationId, const std::string& path, const std::string& displayName, const std::string& replyTo);
 
-  libjami::DataTransferError sendFileLegacy(const libjami::DataTransferInfo info, libjami::DataTransferId& id);
-  libjami::DataTransferError acceptFileTransfer(const std::string& accountId, const std::string& fileId, const std::string& file_path);
   uint64_t downloadFile(const std::string& accountId, const std::string& conversationId, const std::string& interactionId,const std::string& fileId, const std::string& path);
   libjami::DataTransferError cancelDataTransfer(const std::string& accountId, const std::string& conversationId, const std::string& fileId);
-  libjami::DataTransferError dataTransferInfo(const std::string& accountId, const std::string& fileId, libjami::DataTransferInfo &info);
   libjami::DataTransferError fileTransferInfo(const std::string& accountId, const std::string& conversationId, const std::string& fileId, std::string &path_out, int64_t &total_out, int64_t &progress_out);
 
 }
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a7b7fa3ca7..35cb404eec 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -31,8 +31,6 @@ list (APPEND Source_Files
       "${CMAKE_CURRENT_SOURCE_DIR}/enumclass_utils.h"
       "${CMAKE_CURRENT_SOURCE_DIR}/fileutils.cpp"
       "${CMAKE_CURRENT_SOURCE_DIR}/fileutils.h"
-      "${CMAKE_CURRENT_SOURCE_DIR}/ftp_server.cpp"
-      "${CMAKE_CURRENT_SOURCE_DIR}/ftp_server.h"
       "${CMAKE_CURRENT_SOURCE_DIR}/gittransport.cpp"
       "${CMAKE_CURRENT_SOURCE_DIR}/gittransport.h"
       "${CMAKE_CURRENT_SOURCE_DIR}/logger.cpp"
diff --git a/src/Makefile.am b/src/Makefile.am
index 973b7bc02d..deaf5dd1f6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -115,8 +115,6 @@ libjami_la_SOURCES = \
 		base64.cpp \
 		data_transfer.cpp \
 		data_transfer.h \
-		ftp_server.cpp \
-		ftp_server.h \
 		scheduled_executor.h \
 		scheduled_executor.cpp \
 		string_utils.cpp \
diff --git a/src/client/datatransfer.cpp b/src/client/datatransfer.cpp
index a5ed206a71..fce477a396 100644
--- a/src/client/datatransfer.cpp
+++ b/src/client/datatransfer.cpp
@@ -33,17 +33,6 @@ registerDataXferHandlers(const std::map<std::string, std::shared_ptr<CallbackWra
     registerSignalHandlers(handlers);
 }
 
-DataTransferError
-sendFileLegacy(const DataTransferInfo& info, DataTransferId& tid) noexcept
-{
-    if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(info.accountId)) {
-        tid = acc->sendFile(info.peer, info.path);
-        return libjami::DataTransferError::success;
-    }
-
-    return libjami::DataTransferError::invalid_argument;
-}
-
 void
 sendFile(const std::string& accountId,
          const std::string& conversationId,
@@ -56,25 +45,6 @@ sendFile(const std::string& accountId,
     }
 }
 
-DataTransferError
-acceptFileTransfer(const std::string& accountId,
-                   const std::string& fileId,
-                   const std::string& file_path) noexcept
-{
-    if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
-        if (auto dt = acc->dataTransfer()) {
-            try {
-                return dt->acceptFile(std::stoull(fileId), file_path)
-                           ? libjami::DataTransferError::success
-                           : libjami::DataTransferError::invalid_argument;
-            } catch (...) {
-                JAMI_ERR() << "Invalid file Id" << fileId;
-            }
-        }
-    }
-    return libjami::DataTransferError::invalid_argument;
-}
-
 bool
 downloadFile(const std::string& accountId,
              const std::string& conversationId,
@@ -118,23 +88,4 @@ fileTransferInfo(const std::string& accountId,
     return libjami::DataTransferError::invalid_argument;
 }
 
-DataTransferError
-dataTransferInfo(const std::string& accountId,
-                 const std::string& fileId,
-                 DataTransferInfo& info) noexcept
-{
-    if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
-        if (auto dt = acc->dataTransfer()) {
-            try {
-                return dt->info(std::stoull(fileId), info)
-                           ? libjami::DataTransferError::success
-                           : libjami::DataTransferError::invalid_argument;
-            } catch (...) {
-                JAMI_ERR() << "Invalid fileId: " << fileId;
-            }
-        }
-    }
-    return libjami::DataTransferError::invalid_argument;
-}
-
 } // namespace libjami
diff --git a/src/connectivity/peer_connection.h b/src/connectivity/peer_connection.h
index d3a74fdf10..be7f102961 100644
--- a/src/connectivity/peer_connection.h
+++ b/src/connectivity/peer_connection.h
@@ -68,8 +68,6 @@ public:
     {
         // Not implemented
     }
-
-    virtual void setOnStateChangedCb(const OnStateChangedCb&) {}
 };
 
 //==============================================================================
diff --git a/src/data_transfer.cpp b/src/data_transfer.cpp
index 6ee15c1e0a..489aa8e9b0 100644
--- a/src/data_transfer.cpp
+++ b/src/data_transfer.cpp
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 2004-2022 Savoir-faire Linux Inc.
  *
- *  Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
+ *  Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -21,25 +21,17 @@
 #include "data_transfer.h"
 
 #include "base64.h"
-#include "client/ring_signal.h"
 #include "fileutils.h"
-#include "jamidht/jamiaccount.h"
-#include "jamidht/p2p.h"
 #include "manager.h"
 #include "map_utils.h"
-#include "connectivity/peer_connection.h"
 #include "string_utils.h"
+#include "client/ring_signal.h"
 
 #include <thread>
 #include <stdexcept>
-#include <fstream>
-#include <sstream>
-#include <ios>
-#include <iostream>
-#include <unordered_map>
 #include <mutex>
 #include <future>
-#include <atomic>
+#include <charconv> // std::from_chars
 #include <cstdlib>  // mkstemp
 #include <filesystem>
 
@@ -55,650 +47,6 @@ generateUID()
     return std::uniform_int_distribution<libjami::DataTransferId> {1, JAMI_ID_MAX_VAL}(rd);
 }
 
-constexpr const uint32_t MAX_BUFFER_SIZE {65534}; /* Channeled max packet size */
-//==============================================================================
-
-class DataTransfer : public Stream
-{
-public:
-    DataTransfer(libjami::DataTransferId id, InternalCompletionCb cb = {})
-        : Stream()
-        , id {id}
-        , internalCompletionCb_ {std::move(cb)}
-    {}
-
-    virtual ~DataTransfer() = default;
-
-    libjami::DataTransferId getId() const override { return id; }
-
-    virtual void accept(const std::string&, std::size_t) {};
-
-    virtual bool start()
-    {
-        wasStarted_ = true;
-        bool expected = false;
-        return started_.compare_exchange_strong(expected, true);
-    }
-
-    virtual bool hasBeenStarted() const { return wasStarted_; }
-
-    void close() noexcept override { started_ = false; }
-
-    void bytesProgress(int64_t& total, int64_t& progress) const
-    {
-        std::lock_guard<std::mutex> lk {infoMutex_};
-        total = info_.totalSize;
-        progress = info_.bytesProgress;
-    }
-
-    void setBytesProgress(int64_t progress) const
-    {
-        std::lock_guard<std::mutex> lk {infoMutex_};
-        info_.bytesProgress = progress;
-    }
-
-    void info(libjami::DataTransferInfo& info) const
-    {
-        std::lock_guard<std::mutex> lk {infoMutex_};
-        info = info_;
-    }
-
-    bool isFinished() const
-    {
-        std::lock_guard<std::mutex> lk {infoMutex_};
-        return info_.lastEvent >= libjami::DataTransferEventCode::finished;
-    }
-
-    libjami::DataTransferInfo info() const { return info_; }
-
-    virtual void emit(libjami::DataTransferEventCode code) const;
-
-    const libjami::DataTransferId id;
-
-    virtual void cancel() {}
-
-    void setOnStateChangedCb(const OnStateChangedCb& cb) override;
-
-protected:
-    mutable std::mutex infoMutex_;
-    mutable libjami::DataTransferInfo info_;
-    mutable std::atomic_bool started_ {false};
-    std::atomic_bool wasStarted_ {false};
-    InternalCompletionCb internalCompletionCb_ {};
-    OnStateChangedCb stateChangedCb_ {};
-};
-
-void
-DataTransfer::emit(libjami::DataTransferEventCode code) const
-{
-    std::string accountId, to;
-    {
-        std::lock_guard<std::mutex> lk {infoMutex_};
-        info_.lastEvent = code;
-        accountId = info_.accountId;
-        to = info_.conversationId;
-        if (to.empty())
-            to = info_.peer;
-    }
-    if (stateChangedCb_)
-        stateChangedCb_(id, code);
-    if (internalCompletionCb_)
-        return; // VCard transfer is just for the daemon
-    runOnMainThread([id = id, code, accountId, to]() {
-        emitSignal<libjami::DataTransferSignal::DataTransferEvent>(accountId,
-                                                                 "",
-                                                                 "",
-                                                                 std::to_string(id),
-                                                                 uint32_t(code));
-    });
-}
-
-void
-DataTransfer::setOnStateChangedCb(const OnStateChangedCb& cb)
-{
-    stateChangedCb_ = std::move(cb);
-}
-
-//==============================================================================
-
-/**
- * This class is used as a sort of buffer between the OutgoingFileTransfer
- * used by clients to represent a transfer between the user and a contact
- * and SubOutgoingFileTransfer representing the transfer between the user and
- * each peer devices. It gives the optimistic view of a transfer (show a failure)
- * only if all related transfer has failed. If one transfer succeed, ignore failures.
- */
-class OptimisticMetaOutgoingInfo
-{
-public:
-    OptimisticMetaOutgoingInfo(const DataTransfer* parent, const libjami::DataTransferInfo& info);
-    /**
-     * Update the DataTransferInfo of the parent if necessary (if the event is more *interesting*
-     * for the user)
-     * @param info the last modified linked info (for example if a subtransfer is accepted, it will
-     * gives as a parameter its info)
-     */
-    void updateInfo(const libjami::DataTransferInfo& info) const;
-    /**
-     * Add a subtransfer as a linked transfer
-     * @param linked
-     */
-    void addLinkedTransfer(DataTransfer* linked) const;
-    /**
-     * Return the optimistic representation of the transfer
-     */
-    const libjami::DataTransferInfo& info() const;
-
-private:
-    const DataTransfer* parent_;
-    mutable std::mutex infoMutex_;
-    mutable libjami::DataTransferInfo info_;
-    mutable std::vector<DataTransfer*> linkedTransfers_;
-};
-
-OptimisticMetaOutgoingInfo::OptimisticMetaOutgoingInfo(const DataTransfer* parent,
-                                                       const libjami::DataTransferInfo& info)
-    : parent_(parent)
-    , info_(info)
-{}
-
-void
-OptimisticMetaOutgoingInfo::updateInfo(const libjami::DataTransferInfo& info) const
-{
-    bool emitCodeChanged = false;
-    bool checkOngoing = false;
-    {
-        std::lock_guard<std::mutex> lk {infoMutex_};
-        if (info_.lastEvent > libjami::DataTransferEventCode::timeout_expired) {
-            info_.lastEvent = libjami::DataTransferEventCode::invalid;
-        }
-        if (info.lastEvent >= libjami::DataTransferEventCode::created
-            && info.lastEvent <= libjami::DataTransferEventCode::finished
-            && info.lastEvent > info_.lastEvent) {
-            // Show the more advanced info
-            info_.lastEvent = info.lastEvent;
-            emitCodeChanged = true;
-        }
-
-        if (info.lastEvent >= libjami::DataTransferEventCode::closed_by_host
-            && info.lastEvent <= libjami::DataTransferEventCode::timeout_expired
-            && info_.lastEvent < libjami::DataTransferEventCode::finished) {
-            // if not finished show error if all failed
-            // if the transfer was ongoing and canceled, we should go to the best status
-            bool isAllFailed = true;
-            checkOngoing = info_.lastEvent == libjami::DataTransferEventCode::ongoing;
-            libjami::DataTransferEventCode bestEvent {libjami::DataTransferEventCode::invalid};
-            for (const auto* transfer : linkedTransfers_) {
-                const auto& i = transfer->info();
-                if (i.lastEvent >= libjami::DataTransferEventCode::created
-                    && i.lastEvent <= libjami::DataTransferEventCode::finished) {
-                    isAllFailed = false;
-                    if (checkOngoing)
-                        bestEvent = bestEvent > i.lastEvent ? bestEvent : i.lastEvent;
-                    else
-                        break;
-                }
-            }
-            if (isAllFailed) {
-                info_.lastEvent = info.lastEvent;
-                emitCodeChanged = true;
-            } else if (checkOngoing && bestEvent != libjami::DataTransferEventCode::invalid) {
-                info_.lastEvent = bestEvent;
-                emitCodeChanged = true;
-            }
-        }
-
-        int64_t bytesProgress {0};
-        for (const auto* transfer : linkedTransfers_) {
-            const auto& i = transfer->info();
-            if (i.bytesProgress > bytesProgress) {
-                bytesProgress = i.bytesProgress;
-            }
-        }
-        if (bytesProgress > info_.bytesProgress) {
-            info_.bytesProgress = bytesProgress;
-            parent_->setBytesProgress(info_.bytesProgress);
-        }
-        if (checkOngoing && info_.lastEvent != libjami::DataTransferEventCode::invalid) {
-            parent_->setBytesProgress(0);
-        }
-    }
-
-    if (emitCodeChanged) {
-        parent_->emit(info_.lastEvent);
-    }
-}
-
-void
-OptimisticMetaOutgoingInfo::addLinkedTransfer(DataTransfer* linked) const
-{
-    std::lock_guard<std::mutex> lk {infoMutex_};
-    linkedTransfers_.emplace_back(linked);
-}
-
-const libjami::DataTransferInfo&
-OptimisticMetaOutgoingInfo::info() const
-{
-    return info_;
-}
-
-/**
- * Represent a outgoing file transfer between a user and a device
- */
-class SubOutgoingFileTransfer final : public DataTransfer
-{
-public:
-    SubOutgoingFileTransfer(libjami::DataTransferId tid,
-                            const std::string& peerUri,
-                            const InternalCompletionCb& cb,
-                            std::shared_ptr<OptimisticMetaOutgoingInfo> metaInfo);
-    ~SubOutgoingFileTransfer();
-
-    void close() noexcept override;
-    void closeAndEmit(libjami::DataTransferEventCode code) const noexcept;
-    bool write(std::string_view) override;
-    void emit(libjami::DataTransferEventCode code) const override;
-    const std::string& peer() { return peerUri_; }
-
-    void cancel() override
-    {
-        if (auto account = Manager::instance().getAccount<JamiAccount>(info_.accountId))
-            account->closePeerConnection(id);
-    }
-
-    void setOnRecv(std::function<void(std::string_view)>&& cb) override
-    {
-        bool send = false;
-        {
-            std::lock_guard<std::mutex> lock(onRecvCbMtx_);
-            if (cb)
-                send = true;
-            onRecvCb_ = std::move(cb);
-        }
-        if (send) {
-            sendHeader(); // Pass headers to the new callback
-        }
-    }
-
-private:
-    SubOutgoingFileTransfer() = delete;
-
-    void sendHeader() const
-    {
-        auto header = fmt::format("Content-Length: {}\n"
-                                  "Display-Name: {}\n"
-                                  "Offset: 0\n\n",
-                                  info_.totalSize,
-                                  info_.displayName);
-        headerSent_ = true;
-        emit(libjami::DataTransferEventCode::wait_peer_acceptance);
-        if (onRecvCb_)
-            onRecvCb_(header);
-    }
-
-    void sendFile() const
-    {
-        dht::ThreadPool::io().run([this]() {
-            std::vector<char> buf;
-            while (!input_.eof() && onRecvCb_) {
-                buf.resize(MAX_BUFFER_SIZE);
-
-                input_.read(&buf[0], buf.size());
-                buf.resize(input_.gcount());
-                if (buf.size()) {
-                    std::lock_guard<std::mutex> lk {infoMutex_};
-                    info_.bytesProgress += buf.size();
-                    metaInfo_->updateInfo(info_);
-                }
-                if (onRecvCb_)
-                    onRecvCb_(std::string_view(buf.data(), buf.size()));
-            }
-            JAMI_DBG() << "FTP#" << getId() << ": sent " << info_.bytesProgress << " bytes";
-
-            if (info_.bytesProgress != info_.totalSize)
-                emit(libjami::DataTransferEventCode::closed_by_peer);
-            else {
-                if (internalCompletionCb_)
-                    internalCompletionCb_(info_.path);
-                emit(libjami::DataTransferEventCode::finished);
-            }
-        });
-    }
-
-    mutable std::shared_ptr<OptimisticMetaOutgoingInfo> metaInfo_;
-    mutable std::ifstream input_;
-    mutable bool headerSent_ {false};
-    bool peerReady_ {false};
-    const std::string peerUri_;
-    mutable std::shared_ptr<Task> timeoutTask_;
-    std::mutex onRecvCbMtx_;
-    std::function<void(std::string_view)> onRecvCb_ {};
-};
-
-SubOutgoingFileTransfer::SubOutgoingFileTransfer(libjami::DataTransferId tid,
-                                                 const std::string& peerUri,
-                                                 const InternalCompletionCb& cb,
-                                                 std::shared_ptr<OptimisticMetaOutgoingInfo> metaInfo)
-    : DataTransfer(tid, cb)
-    , metaInfo_(std::move(metaInfo))
-    , peerUri_(peerUri)
-{
-    info_ = metaInfo_->info();
-    fileutils::openStream(input_, info_.path, std::ios::in | std::ios::binary);
-    if (!input_)
-        throw std::runtime_error("input file open failed");
-    metaInfo_->addLinkedTransfer(this);
-}
-
-SubOutgoingFileTransfer::~SubOutgoingFileTransfer()
-{
-    if (timeoutTask_)
-        timeoutTask_->cancel();
-}
-
-void
-SubOutgoingFileTransfer::close() noexcept
-{
-    closeAndEmit(libjami::DataTransferEventCode::closed_by_host);
-}
-
-void
-SubOutgoingFileTransfer::closeAndEmit(libjami::DataTransferEventCode code) const noexcept
-{
-    started_ = false; // NOTE: replace DataTransfer::close(); which is non const
-    input_.close();
-
-    if (info_.lastEvent < libjami::DataTransferEventCode::finished)
-        emit(code);
-}
-
-bool
-SubOutgoingFileTransfer::write(std::string_view buffer)
-{
-    if (buffer.empty())
-        return true;
-    if (not peerReady_ and headerSent_) {
-        // detect GO or NGO msg
-        if (buffer.size() == 3 and buffer[0] == 'G' and buffer[1] == 'O' and buffer[2] == '\n') {
-            peerReady_ = true;
-            emit(libjami::DataTransferEventCode::ongoing);
-            if (onRecvCb_)
-                sendFile();
-        } else {
-            // consider any other response as a cancel msg
-            JAMI_WARN() << "FTP#" << getId() << ": refused by peer";
-            emit(libjami::DataTransferEventCode::closed_by_peer);
-            return false;
-        }
-    }
-    return true;
-}
-
-void
-SubOutgoingFileTransfer::emit(libjami::DataTransferEventCode code) const
-{
-    {
-        std::lock_guard<std::mutex> lk {infoMutex_};
-        info_.lastEvent = code;
-    }
-    if (stateChangedCb_)
-        stateChangedCb_(id, code);
-    metaInfo_->updateInfo(info_);
-    if (code == libjami::DataTransferEventCode::wait_peer_acceptance) {
-        if (timeoutTask_)
-            timeoutTask_->cancel();
-        timeoutTask_ = Manager::instance().scheduleTaskIn(
-            [this]() {
-                JAMI_WARN() << "FTP#" << getId() << ": timeout. Cancel";
-                closeAndEmit(libjami::DataTransferEventCode::timeout_expired);
-            },
-            std::chrono::minutes(10));
-    } else if (timeoutTask_) {
-        timeoutTask_->cancel();
-        timeoutTask_.reset();
-    }
-}
-
-/**
- * Represent a file transfer between a user and a peer (all of its device)
- */
-class OutgoingFileTransfer final : public DataTransfer
-{
-public:
-    OutgoingFileTransfer(libjami::DataTransferId tid,
-                         const libjami::DataTransferInfo& info,
-                         const InternalCompletionCb& cb = {});
-    ~OutgoingFileTransfer() {}
-
-    std::shared_ptr<DataTransfer> startNewOutgoing(const std::string& peer_uri)
-    {
-        auto newTransfer = std::make_shared<SubOutgoingFileTransfer>(id,
-                                                                     peer_uri,
-                                                                     internalCompletionCb_,
-                                                                     metaInfo_);
-        newTransfer->setOnStateChangedCb(stateChangedCb_);
-        subtransfer_.emplace_back(newTransfer);
-        newTransfer->start();
-        return newTransfer;
-    }
-
-    bool hasBeenStarted() const override
-    {
-        // Started if one subtransfer is started
-        for (const auto& subtransfer : subtransfer_)
-            if (subtransfer->hasBeenStarted())
-                return true;
-        return false;
-    }
-
-    void close() noexcept override;
-
-    bool cancelWithPeer(const std::string& peer)
-    {
-        auto allFinished = true;
-        for (const auto& subtransfer : subtransfer_) {
-            if (subtransfer->peer() == peer)
-                subtransfer->cancel();
-            else if (!subtransfer->isFinished())
-                allFinished = false;
-        }
-        return allFinished;
-    }
-
-private:
-    OutgoingFileTransfer() = delete;
-
-    mutable std::shared_ptr<OptimisticMetaOutgoingInfo> metaInfo_;
-    mutable std::ifstream input_;
-    mutable std::vector<std::shared_ptr<SubOutgoingFileTransfer>> subtransfer_;
-};
-
-OutgoingFileTransfer::OutgoingFileTransfer(libjami::DataTransferId tid,
-                                           const libjami::DataTransferInfo& info,
-                                           const InternalCompletionCb& cb)
-    : DataTransfer(tid, cb)
-{
-    fileutils::openStream(input_, info.path, std::ios::binary);
-    if (!input_)
-        throw std::runtime_error("input file open failed");
-
-    info_ = info;
-    info_.flags &= ~((uint32_t) 1 << int(libjami::DataTransferFlags::direction)); // outgoing
-
-    // File size?
-    input_.seekg(0, std::ios_base::end);
-    info_.totalSize = input_.tellg();
-    input_.close();
-
-    metaInfo_ = std::make_shared<OptimisticMetaOutgoingInfo>(this, this->info_);
-}
-
-void
-OutgoingFileTransfer::close() noexcept
-{
-    for (const auto& subtransfer : subtransfer_)
-        subtransfer->close();
-}
-
-//==============================================================================
-
-class IncomingFileTransfer final : public DataTransfer
-{
-public:
-    IncomingFileTransfer(const libjami::DataTransferInfo&,
-                         libjami::DataTransferId,
-                         const InternalCompletionCb& cb = {});
-
-    bool start() override;
-
-    void close() noexcept override;
-
-    void requestFilename(const std::function<void(const std::string&)>& cb);
-
-    void accept(const std::string&, std::size_t offset) override;
-
-    bool write(std::string_view data) override;
-
-    void setFilename(const std::string& filename);
-
-    void cancel() override
-    {
-        auto account = Manager::instance().getAccount<JamiAccount>(info_.accountId);
-        if (account)
-            account->closePeerConnection(internalId_);
-    }
-
-private:
-    IncomingFileTransfer() = delete;
-
-    libjami::DataTransferId internalId_;
-
-    std::ofstream fout_;
-    std::mutex cbMtx_ {};
-    std::function<void(const std::string&)> onFilenameCb_ {};
-};
-
-IncomingFileTransfer::IncomingFileTransfer(const libjami::DataTransferInfo& info,
-                                           libjami::DataTransferId internalId,
-                                           const InternalCompletionCb& cb)
-    : DataTransfer(internalId, cb)
-    , internalId_(internalId)
-{
-    JAMI_WARN() << "[FTP] incoming transfert of " << info.totalSize
-                << " byte(s): " << info.displayName;
-
-    info_ = info;
-    info_.flags |= (uint32_t) 1 << int(libjami::DataTransferFlags::direction); // incoming
-}
-
-void
-IncomingFileTransfer::setFilename(const std::string& filename)
-{
-    info_.path = filename;
-}
-
-void
-IncomingFileTransfer::requestFilename(const std::function<void(const std::string&)>& cb)
-{
-    if (!internalCompletionCb_) {
-        std::lock_guard<std::mutex> lk(cbMtx_);
-        onFilenameCb_ = cb;
-    }
-
-    emit(libjami::DataTransferEventCode::wait_host_acceptance);
-
-    if (internalCompletionCb_) {
-        std::string path = fmt::format("{}/{}/profiles",
-                                       fileutils::get_cache_dir(),
-                                       info_.accountId);
-        fileutils::recursive_mkdir(path);
-        auto filename = fmt::format("{}/{}", path, id);
-        fileutils::ofstream(filename);
-        if (not fileutils::isFile(filename))
-            throw std::system_error(errno, std::generic_category());
-        info_.path = filename;
-        cb(filename);
-    }
-}
-
-bool
-IncomingFileTransfer::start()
-{
-    if (!DataTransfer::start())
-        return false;
-
-    fileutils::openStream(fout_, &info_.path[0], std::ios::binary);
-    if (!fout_) {
-        JAMI_ERR() << "[FTP] Can't open file " << info_.path;
-        return false;
-    }
-
-    emit(libjami::DataTransferEventCode::ongoing);
-    return true;
-}
-
-void
-IncomingFileTransfer::close() noexcept
-{
-    {
-        std::lock_guard<std::mutex> lk {infoMutex_};
-        if (info_.lastEvent >= libjami::DataTransferEventCode::finished)
-            return;
-    }
-    DataTransfer::close();
-
-    decltype(onFilenameCb_) cb;
-    {
-        std::lock_guard<std::mutex> lk(cbMtx_);
-        cb = std::move(onFilenameCb_);
-    }
-    if (cb)
-        cb("");
-
-    fout_.close();
-
-    JAMI_DBG() << "[FTP] file closed, rx " << info_.bytesProgress << " on " << info_.totalSize;
-    if (info_.bytesProgress >= info_.totalSize) {
-        if (internalCompletionCb_)
-            internalCompletionCb_(info_.path);
-        emit(libjami::DataTransferEventCode::finished);
-    } else
-        emit(libjami::DataTransferEventCode::closed_by_host);
-}
-
-void
-IncomingFileTransfer::accept(const std::string& filename, std::size_t offset)
-{
-    // TODO: offset?
-    (void) offset;
-
-    info_.path = filename;
-    decltype(onFilenameCb_) cb;
-    {
-        std::lock_guard<std::mutex> lk(cbMtx_);
-        cb = std::move(onFilenameCb_);
-    }
-    if (cb)
-        cb(filename);
-}
-
-bool
-IncomingFileTransfer::write(std::string_view buffer)
-{
-    if (buffer.empty())
-        return true;
-    fout_ << buffer;
-    if (!fout_)
-        return false;
-    std::lock_guard<std::mutex> lk {infoMutex_};
-    info_.bytesProgress += buffer.size();
-    return true;
-}
-
-//==============================================================================
-//                                 With Swarm
-//==============================================================================
-
 FileInfo::FileInfo(const std::shared_ptr<ChannelSocket>& channel,
                    const std::string& fileId,
                    const std::string& interactionId,
@@ -718,10 +66,10 @@ FileInfo::emit(libjami::DataTransferEventCode code)
         // Else it's an internal transfer
         runOnMainThread([info = info_, iid = interactionId_, fid = fileId_, code]() {
             emitSignal<libjami::DataTransferSignal::DataTransferEvent>(info.accountId,
-                                                                     info.conversationId,
-                                                                     iid,
-                                                                     fid,
-                                                                     uint32_t(code));
+                                                                       info.conversationId,
+                                                                       iid,
+                                                                       fid,
+                                                                       uint32_t(code));
         });
     }
 }
@@ -934,10 +282,6 @@ public:
     std::string profilesPath_ {};
     std::string conversationDataPath_ {};
 
-    // Pre swarm
-    std::map<libjami::DataTransferId, std::shared_ptr<OutgoingFileTransfer>> oMap_ {};
-    std::map<libjami::DataTransferId, std::shared_ptr<IncomingFileTransfer>> iMap_ {};
-
     std::mutex mapMutex_ {};
     std::map<std::string, WaitingRequest> waitingIds_ {};
     std::map<std::shared_ptr<ChannelSocket>, std::shared_ptr<OutgoingFile>> outgoings_ {};
@@ -951,86 +295,6 @@ TransferManager::TransferManager(const std::string& accountId, const std::string
 
 TransferManager::~TransferManager() {}
 
-libjami::DataTransferId
-TransferManager::sendFile(const std::string& path,
-                          const std::string& peer,
-                          const InternalCompletionCb& icb)
-{
-    // IMPLEMENTATION NOTE: requestPeerConnection() may call the given callback a multiple time.
-    // This happen when multiple agents handle communications of the given peer for the given
-    // account. Example: Jami account supports multi-devices, each can answer to the request.
-    auto account = Manager::instance().getAccount<JamiAccount>(pimpl_->accountId_);
-    if (!account) {
-        return {};
-    }
-
-    auto tid = generateUID();
-    std::size_t found = path.find_last_of(DIR_SEPARATOR_CH);
-    auto filename = path.substr(found + 1);
-
-    libjami::DataTransferInfo info;
-    info.accountId = pimpl_->accountId_;
-    info.author = account->getUsername();
-    info.peer = peer;
-    info.path = path;
-    info.displayName = filename;
-    info.bytesProgress = 0;
-
-    auto transfer = std::make_shared<OutgoingFileTransfer>(tid, info, icb);
-    {
-        std::lock_guard<std::mutex> lk {pimpl_->mapMutex_};
-        auto it = pimpl_->oMap_.find(tid);
-        if (it != pimpl_->oMap_.end()) {
-            // If the transfer is already in progress (aka not finished)
-            // we do not need to send the request and can ignore it.
-            if (!it->second->isFinished()) {
-                JAMI_DEBUG("Can't send request for {}. Already sending the file", tid);
-                return {};
-            }
-            pimpl_->oMap_.erase(it);
-        }
-        pimpl_->oMap_.emplace(tid, transfer);
-    }
-    transfer->emit(libjami::DataTransferEventCode::created);
-
-    try {
-        account->requestConnection(
-            info,
-            tid,
-            static_cast<bool>(icb),
-            [transfer](const std::shared_ptr<ChanneledOutgoingTransfer>& out) {
-                if (out)
-                    out->linkTransfer(transfer->startNewOutgoing(out->peer()));
-            },
-            [transfer](const std::string& peer) {
-                auto allFinished = transfer->cancelWithPeer(peer);
-                if (allFinished and not transfer->hasBeenStarted()) {
-                    transfer->emit(libjami::DataTransferEventCode::unjoinable_peer);
-                    transfer->cancel();
-                    transfer->close();
-                }
-            });
-    } catch (const std::exception& ex) {
-        JAMI_ERR() << "[XFER] exception during sendFile(): " << ex.what();
-        return {};
-    }
-
-    return tid;
-}
-
-bool
-TransferManager::acceptFile(const libjami::DataTransferId& id, const std::string& path)
-{
-    std::lock_guard<std::mutex> lk {pimpl_->mapMutex_};
-    auto it = pimpl_->iMap_.find(id);
-    if (it == pimpl_->iMap_.end()) {
-        JAMI_WARNING("Cannot accept {:d}, request not found", id);
-        return false;
-    }
-    it->second->accept(path, 0);
-    return true;
-}
-
 void
 TransferManager::transferFile(const std::shared_ptr<ChannelSocket>& channel,
                               const std::string& fileId,
@@ -1071,60 +335,18 @@ TransferManager::cancel(const std::string& fileId)
 {
     std::shared_ptr<ChannelSocket> channel;
     std::lock_guard<std::mutex> lk {pimpl_->mapMutex_};
-    if (!pimpl_->to_.empty()) {
-        // Remove from waiting, this avoid auto-download
-        auto itW = pimpl_->waitingIds_.find(fileId);
-        if (itW != pimpl_->waitingIds_.end()) {
-            pimpl_->waitingIds_.erase(itW);
-            JAMI_DBG() << "Cancel " << fileId;
-            pimpl_->saveWaiting();
-        }
-        // Note: For now, there is no cancel for outgoings.
-        // The client can just remove the file.
-        auto itC = pimpl_->incomings_.find(fileId);
-        if (itC == pimpl_->incomings_.end())
-            return false;
-        itC->second->cancel();
-        return true;
-    }
-    // Else, this is fallack.
-    try {
-        auto it = pimpl_->iMap_.find(std::stoull(fileId));
-        if (it != pimpl_->iMap_.end()) {
-            if (it->second)
-                it->second->close();
-            return true;
-        }
-        auto itO = pimpl_->oMap_.find(std::stoull(fileId));
-        if (itO != pimpl_->oMap_.end()) {
-            if (itO->second)
-                itO->second->close();
-            return true;
-        }
-    } catch (...) {
-        JAMI_ERR() << "Invalid fileId: " << fileId;
+    // Remove from waiting, this avoid auto-download
+    auto itW = pimpl_->waitingIds_.find(fileId);
+    if (itW != pimpl_->waitingIds_.end()) {
+        pimpl_->waitingIds_.erase(itW);
+        JAMI_DBG() << "Cancel " << fileId;
+        pimpl_->saveWaiting();
     }
-    return false;
-}
-
-bool
-TransferManager::info(const libjami::DataTransferId& id, libjami::DataTransferInfo& info) const noexcept
-{
-    std::unique_lock<std::mutex> lk {pimpl_->mapMutex_};
-    if (!pimpl_->to_.empty())
+    auto itC = pimpl_->incomings_.find(fileId);
+    if (itC == pimpl_->incomings_.end())
         return false;
-    // Else it's fallback
-    if (auto it = pimpl_->iMap_.find(id); it != pimpl_->iMap_.end()) {
-        if (it->second)
-            it->second->info(info);
-        return true;
-    }
-    if (auto it = pimpl_->oMap_.find(id); it != pimpl_->oMap_.end()) {
-        if (it->second)
-            it->second->info(info);
-        return true;
-    }
-    return false;
+    itC->second->cancel();
+    return true;
 }
 
 bool
@@ -1165,26 +387,6 @@ TransferManager::info(const std::string& fileId,
     return false;
 }
 
-void
-TransferManager::onIncomingFileRequest(const libjami::DataTransferInfo& info,
-                                       const libjami::DataTransferId& id,
-                                       const std::function<void(const IncomingFileInfo&)>& cb,
-                                       const InternalCompletionCb& icb)
-{
-    auto transfer = std::make_shared<IncomingFileTransfer>(info, id, icb);
-    {
-        std::lock_guard<std::mutex> lk {pimpl_->mapMutex_};
-        pimpl_->iMap_.emplace(id, transfer);
-    }
-    transfer->emit(libjami::DataTransferEventCode::created);
-    transfer->requestFilename([transfer, id, cb = std::move(cb)](const std::string& filename) {
-        if (!filename.empty() && transfer->start())
-            cb({id, std::static_pointer_cast<Stream>(transfer)});
-        else
-            cb({id, nullptr});
-    });
-}
-
 void
 TransferManager::waitForTransfer(const std::string& fileId,
                                  const std::string& interactionId,
@@ -1197,16 +399,7 @@ TransferManager::waitForTransfer(const std::string& fileId,
     if (itW != pimpl_->waitingIds_.end())
         return;
     pimpl_->waitingIds_[fileId] = {fileId, interactionId, sha3sum, path, total};
-    JAMI_DBG() << "Wait for " << fileId;
-    if (!pimpl_->to_.empty())
-        pimpl_->saveWaiting();
-    lk.unlock();
-    emitSignal<libjami::DataTransferSignal::DataTransferEvent>(
-        pimpl_->accountId_,
-        pimpl_->to_,
-        interactionId,
-        fileId,
-        uint32_t(libjami::DataTransferEventCode::wait_peer_acceptance));
+    pimpl_->saveWaiting();
 }
 
 void
@@ -1341,8 +534,8 @@ TransferManager::onIncomingProfile(const std::shared_ptr<ChannelSocket>& channel
                         pimpl->vcards_.erase(itO);
                     if (code == uint32_t(libjami::DataTransferEventCode::finished)) {
                         emitSignal<libjami::ConfigurationSignal::ProfileReceived>(accountId,
-                                                                                uri,
-                                                                                path);
+                                                                                  uri,
+                                                                                  path);
                     }
                 }
             });
diff --git a/src/data_transfer.h b/src/data_transfer.h
index c3751c5194..c4a60db426 100644
--- a/src/data_transfer.h
+++ b/src/data_transfer.h
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 2004-2022 Savoir-faire Linux Inc.
  *
- *  Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
+ *  Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -52,8 +52,6 @@ struct WaitingRequest
 };
 
 typedef std::function<void(const std::string&)> InternalCompletionCb;
-typedef std::function<void(const libjami::DataTransferId&, const libjami::DataTransferEventCode&)>
-    OnStateChangedCb;
 
 class FileInfo
 {
@@ -125,45 +123,6 @@ public:
     TransferManager(const std::string& accountId, const std::string& to);
     ~TransferManager();
 
-    /**
-     * Send a file
-     * @param path      of the file
-     * @param peer      DeviceId for vcard or dest
-     * @param icb       used for internal files (like vcard)
-     */
-    /*[[deprecated("Non swarm method")]]*/ libjami::DataTransferId sendFile(
-        const std::string& path, const std::string& peer, const InternalCompletionCb& icb = {});
-
-    /**
-     * Accepts a transfer
-     * @param id        of the transfer
-     * @param path      of the file
-     */
-    /*[[deprecated("Non swarm method")]]*/ bool acceptFile(const libjami::DataTransferId& id,
-                                                           const std::string& path);
-
-    /**
-     * Inform the transfer manager that a new file is incoming
-     * @param info      of the transfer
-     * @param id        of the transfer
-     * @param cb        callback to trigger when connected
-     * @param icb       used for vcard
-     */
-    /*[[deprecated("Non swarm method")]]*/ void onIncomingFileRequest(
-        const libjami::DataTransferInfo& info,
-        const libjami::DataTransferId& id,
-        const std::function<void(const IncomingFileInfo&)>& cb,
-        const InternalCompletionCb& icb = {});
-
-    /**
-     * Get current transfer infos
-     * @param id        of the transfer
-     * @param info      to fill
-     * @return if found
-     */
-    /*[[deprecated("Non swarm method")]]*/ bool info(const libjami::DataTransferId& id,
-                                                     libjami::DataTransferInfo& info) const noexcept;
-
     /**
      * Send a file to a channel
      * @param channel       channel to use
diff --git a/src/ftp_server.cpp b/src/ftp_server.cpp
deleted file mode 100644
index 712c513779..0000000000
--- a/src/ftp_server.cpp
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- *  Copyright (C) 2004-2022 Savoir-faire Linux Inc.
- *
- *  Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- */
-
-#include "ftp_server.h"
-
-#include "logger.h"
-#include "string_utils.h"
-#include "manager.h"
-#include "jamidht/jamiaccount.h"
-
-#include <opendht/thread_pool.h>
-
-#include <algorithm>
-#include <array>
-#include <stdexcept>
-#include <iterator>
-#include <charconv>
-
-using namespace std::literals;
-
-namespace jami {
-
-//==============================================================================
-
-FtpServer::FtpServer(const libjami::DataTransferInfo& info,
-                     const libjami::DataTransferId& id,
-                     const InternalCompletionCb& cb)
-    : Stream()
-    , info_ {info}
-    , transferId_(id)
-    , cb_(cb)
-{}
-
-libjami::DataTransferId
-FtpServer::getId() const
-{
-    // Because FtpServer is just the protocol on the top of a stream so the id
-    // of the stream is the id of out_.
-    if (isTreatingRequest_)
-        return transferId_;
-    return out_.id;
-}
-
-void
-FtpServer::close() noexcept
-{
-    closeCurrentFile();
-    JAMI_WARN() << "[FTP] server closed";
-}
-
-void
-FtpServer::startNewFile()
-{
-    // Request filename from client (WARNING: synchrone call!)
-    info_.totalSize = fileSize_;
-    info_.bytesProgress = 0;
-    rx_ = 0;
-    isTreatingRequest_ = true;
-
-    auto to = info_.conversationId;
-    if (to.empty())
-        to = info_.peer;
-
-    if (auto acc = Manager::instance().getAccount<JamiAccount>(info_.accountId)) {
-        acc->dataTransfer()->onIncomingFileRequest(
-            info_,
-            transferId_,
-            [w = weak()](const IncomingFileInfo& fileInfo) {
-                auto shared = w.lock();
-                if (!shared)
-                    return;
-                shared->out_ = fileInfo;
-                shared->isTreatingRequest_ = false;
-                if (!shared->out_.stream) {
-                    JAMI_DBG() << "[FTP] transfer aborted by client";
-                    shared->closed_ = true; // send NOK msg at next read()
-                } else {
-                    if (shared->tmpOnStateChangedCb_)
-                        shared->out_.stream->setOnStateChangedCb(
-                            std::move(shared->tmpOnStateChangedCb_));
-                    shared->go_ = true;
-                }
-
-                if (shared->onRecvCb_) {
-                    shared->onRecvCb_(shared->go_ ? "GO\n"sv : "NGO\n"sv);
-                }
-
-                if (shared->out_.stream) {
-                    shared->state_ = FtpState::READ_DATA;
-                    while (shared->headerStream_) {
-                        shared->headerStream_.read(&shared->line_[0], shared->line_.size());
-                        std::size_t count = shared->headerStream_.gcount();
-                        if (!count)
-                            break;
-                        auto size_needed = shared->fileSize_ - shared->rx_;
-                        count = std::min(count, size_needed);
-                        shared->out_.stream->write(std::string_view(shared->line_.data(), count));
-                        shared->rx_ += count;
-                        if (shared->rx_ == shared->fileSize_) {
-                            shared->closeCurrentFile();
-                            shared->state_ = FtpState::PARSE_HEADERS;
-                            return;
-                        }
-                    }
-                }
-                shared->headerStream_.clear();
-                shared->headerStream_.str({}); // reset
-            },
-            std::move(cb_));
-    }
-}
-
-void
-FtpServer::closeCurrentFile()
-{
-    if (out_.stream && not closed_.exchange(true)) {
-        out_.stream->close();
-        out_.stream.reset();
-    }
-}
-
-bool
-FtpServer::write(std::string_view buffer)
-{
-    switch (state_) {
-    case FtpState::WAIT_ACCEPTANCE:
-        // Receiving data while waiting, this is incorrect, because we didn't accept yet
-        closeCurrentFile();
-        state_ = FtpState::PARSE_HEADERS;
-        break;
-    case FtpState::PARSE_HEADERS:
-        if (parseStream(buffer)) {
-            state_ = FtpState::WAIT_ACCEPTANCE;
-            startNewFile();
-        }
-        break;
-
-    case FtpState::READ_DATA: {
-        if (out_.stream)
-            out_.stream->write(buffer);
-        auto size_needed = fileSize_ - rx_;
-        auto read_size = std::min(buffer.size(), size_needed);
-        rx_ += read_size;
-        if (rx_ == fileSize_) {
-            closeCurrentFile();
-            // data may remains into the buffer: copy into the header stream for next header parsing
-            if (read_size < buffer.size())
-                headerStream_.write((const char*) (buffer.data() + read_size),
-                                    buffer.size() - read_size);
-            state_ = FtpState::PARSE_HEADERS;
-        }
-    } break;
-
-    default:
-        break;
-    }
-
-    return true; // server always alive
-}
-
-bool
-FtpServer::parseStream(std::string_view buffer)
-{
-    headerStream_ << buffer;
-
-    // Simple line stream parser
-    while (headerStream_.getline(&line_[0], line_.size())) {
-        if (parseLine(std::string_view(line_.data(), headerStream_.gcount() - 1)))
-            return true; // headers EOF, data may remain in headerStream_
-    }
-
-    if (headerStream_.fail())
-        throw std::runtime_error("[FTP] header parsing error");
-
-    headerStream_.clear();
-    return false; // need more data
-}
-
-bool
-FtpServer::parseLine(std::string_view line)
-{
-    if (line.empty())
-        return true;
-
-    // Valid line found, parse it as "key: value" and store until end of headers detection
-    const auto& sep_pos = line.find(':');
-    if (sep_pos == std::string_view::npos)
-        throw std::runtime_error("[FTP] stream protocol error: bad format");
-
-    handleHeader(trim(line.substr(0, sep_pos)), trim(line.substr(sep_pos + 1)));
-    return false;
-}
-
-void
-FtpServer::handleHeader(std::string_view key, std::string_view value)
-{
-    JAMI_DBG() << "[FTP] header: '" << key << "' = '" << value << "'";
-
-    if (key == "Content-Length") {
-        fileSize_ = to_int<size_t>(value);
-    } else if (key == "Display-Name") {
-        info_.displayName = value;
-    }
-}
-
-} // namespace jami
diff --git a/src/ftp_server.h b/src/ftp_server.h
deleted file mode 100644
index 26591fed4f..0000000000
--- a/src/ftp_server.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- *  Copyright (C) 2004-2022 Savoir-faire Linux Inc.
- *
- *  Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- */
-
-#pragma once
-
-#include "data_transfer.h"
-#include "connectivity/peer_connection.h"
-
-#include <vector>
-#include <array>
-#include <sstream>
-#include <memory>
-
-namespace jami {
-
-using RecvCb = std::function<void(std::string_view buf)>;
-
-class FtpServer final : public Stream, public std::enable_shared_from_this<FtpServer>
-{
-public:
-    FtpServer(const libjami::DataTransferInfo& info,
-              const libjami::DataTransferId& id,
-              const InternalCompletionCb& cb = {});
-
-    bool write(std::string_view data) override;
-    libjami::DataTransferId getId() const override;
-    void close() noexcept override;
-
-    void setOnRecv(RecvCb&& cb) override { onRecvCb_ = cb; }
-    void setOnStateChangedCb(const OnStateChangedCb& cb) override
-    {
-        // If out_ is not attached, store the callback
-        // inside a temporary object. Will be linked when out_.stream
-        // will be attached
-        if (out_.stream)
-            out_.stream->setOnStateChangedCb(std::move(cb));
-        else
-            tmpOnStateChangedCb_ = std::move(cb);
-    }
-
-private:
-    bool parseStream(std::string_view);
-    bool parseLine(std::string_view);
-    void handleHeader(std::string_view key, std::string_view value);
-    void startNewFile();
-    void closeCurrentFile();
-
-    enum class FtpState {
-        PARSE_HEADERS,
-        WAIT_ACCEPTANCE,
-        READ_DATA,
-    };
-
-    libjami::DataTransferInfo info_;
-    InternalCompletionCb cb_ {};
-    std::atomic_bool isVCard_ {false};
-    std::atomic_bool isTreatingRequest_ {false};
-    libjami::DataTransferId transferId_ {0};
-    IncomingFileInfo out_ {0, nullptr};
-    std::size_t fileSize_ {0};
-    std::size_t rx_ {0};
-    std::stringstream headerStream_;
-    std::array<char, 1024> line_;
-    mutable std::atomic_bool closed_ {false};
-    mutable bool go_ {false};
-    FtpState state_ {FtpState::PARSE_HEADERS};
-
-    RecvCb onRecvCb_ {};
-    OnStateChangedCb tmpOnStateChangedCb_ {};
-
-    std::shared_ptr<FtpServer> shared()
-    {
-        return std::static_pointer_cast<FtpServer>(shared_from_this());
-    }
-    std::shared_ptr<FtpServer const> shared() const
-    {
-        return std::static_pointer_cast<FtpServer const>(shared_from_this());
-    }
-    std::weak_ptr<FtpServer> weak()
-    {
-        return std::static_pointer_cast<FtpServer>(shared_from_this());
-    }
-    std::weak_ptr<FtpServer const> weak() const
-    {
-        return std::static_pointer_cast<FtpServer const>(shared_from_this());
-    }
-};
-
-} // namespace jami
diff --git a/src/jami/datatransfer_interface.h b/src/jami/datatransfer_interface.h
index b2aaedbd7d..af5a6ac9fe 100644
--- a/src/jami/datatransfer_interface.h
+++ b/src/jami/datatransfer_interface.h
@@ -108,31 +108,12 @@ struct LIBJAMI_PUBLIC DataTransferInfo
 /// DataTransferEvent signal for such event. There is no reserved or special values on
 /// DataTransferId type.
 ///
-LIBJAMI_PUBLIC DataTransferError sendFileLegacy(const DataTransferInfo& info,
-                                              DataTransferId& tid) noexcept;
 
 LIBJAMI_PUBLIC void sendFile(const std::string& accountId,
-                           const std::string& conversationId,
-                           const std::string& path,
-                           const std::string& displayName,
-                           const std::string& replyTo) noexcept;
-
-/// Accept an incoming file transfer.
-///
-/// Use this function when you receive an incoming transfer request throught DataTransferEvent signal.
-/// The data reception and writting will occurs asynchronously.
-/// User should listen to DataTransferEvent event to follow the transfer progess.
-/// This function can be used only once per data transfer identifiant, when used more it's ignored.
-///
-/// \param id data transfer identification value as given by a DataTransferEvent signal.
-/// \param file_path file path going to be open in binary write mode to put incoming data.
-///
-/// \return DataTransferError::invalid_argument if id is unknown.
-/// \note unknown \a id results to a no-op call.
-///
-LIBJAMI_PUBLIC DataTransferError acceptFileTransfer(const std::string& accountId,
-                                                  const std::string& fileId,
-                                                  const std::string& file_path) noexcept;
+                             const std::string& conversationId,
+                             const std::string& path,
+                             const std::string& displayName,
+                             const std::string& replyTo) noexcept;
 
 /// Asks for retransferring a file. Generally this means that the file is missing
 /// from the conversation
@@ -143,10 +124,10 @@ LIBJAMI_PUBLIC DataTransferError acceptFileTransfer(const std::string& accountId
 /// \param path
 ///
 LIBJAMI_PUBLIC bool downloadFile(const std::string& accountId,
-                               const std::string& conversationId,
-                               const std::string& interactionId,
-                               const std::string& fileId,
-                               const std::string& path) noexcept;
+                                 const std::string& conversationId,
+                                 const std::string& interactionId,
+                                 const std::string& fileId,
+                                 const std::string& path) noexcept;
 
 /// Refuse or abort an outgoing or an incoming file transfer.
 ///
@@ -164,18 +145,6 @@ DataTransferError cancelDataTransfer(const std::string& accountId,
                                      const std::string& conversationId,
                                      const std::string& fileId) noexcept LIBJAMI_PUBLIC;
 
-/// Return some information on given data transfer.
-///
-/// \param id data transfer identification value as given by a DataTransferEvent signal.
-/// \param[out] info data transfer information.
-///
-/// \return DataTransferError::invalid_argument if id is unknown.
-/// \note \a info structure is in undefined state in case of error.
-///
-LIBJAMI_PUBLIC DataTransferError dataTransferInfo(const std::string& accountId,
-                                                const std::string& fileId,
-                                                DataTransferInfo& info) noexcept;
-
 /// Return the amount of sent/received bytes of an existing data transfer.
 ///
 /// \param id data transfer identification value as given by a DataTransferEvent signal.
@@ -186,11 +155,11 @@ LIBJAMI_PUBLIC DataTransferError dataTransferInfo(const std::string& accountId,
 /// DataTransferError::invalid_argument if the id is unknown.
 ///
 LIBJAMI_PUBLIC DataTransferError fileTransferInfo(const std::string& accountId,
-                                                const std::string& conversationId,
-                                                const std::string& fileId,
-                                                std::string& path,
-                                                int64_t& total,
-                                                int64_t& progress) noexcept;
+                                                  const std::string& conversationId,
+                                                  const std::string& fileId,
+                                                  std::string& path,
+                                                  int64_t& total,
+                                                  int64_t& progress) noexcept;
 
 // Signals
 struct LIBJAMI_PUBLIC DataTransferSignal
diff --git a/src/jamidht/CMakeLists.txt b/src/jamidht/CMakeLists.txt
index a929bb867e..e8bebfc7d7 100644
--- a/src/jamidht/CMakeLists.txt
+++ b/src/jamidht/CMakeLists.txt
@@ -19,8 +19,6 @@ list (APPEND Source_Files__jamidht
       "${CMAKE_CURRENT_SOURCE_DIR}/conversation.h"
       "${CMAKE_CURRENT_SOURCE_DIR}/channeled_transport.cpp"
       "${CMAKE_CURRENT_SOURCE_DIR}/channeled_transport.h"
-      "${CMAKE_CURRENT_SOURCE_DIR}/channeled_transfers.cpp"
-      "${CMAKE_CURRENT_SOURCE_DIR}/channeled_transfers.h"
       "${CMAKE_CURRENT_SOURCE_DIR}/contact_list.cpp"
       "${CMAKE_CURRENT_SOURCE_DIR}/contact_list.h"
       "${CMAKE_CURRENT_SOURCE_DIR}/gitserver.cpp"
@@ -39,8 +37,6 @@ list (APPEND Source_Files__jamidht
       "${CMAKE_CURRENT_SOURCE_DIR}/conversation_module.cpp"
       "${CMAKE_CURRENT_SOURCE_DIR}/namedirectory.cpp"
       "${CMAKE_CURRENT_SOURCE_DIR}/namedirectory.h"
-      "${CMAKE_CURRENT_SOURCE_DIR}/p2p.cpp"
-      "${CMAKE_CURRENT_SOURCE_DIR}/p2p.h"
       "${CMAKE_CURRENT_SOURCE_DIR}/jami_contact.h"
       "${CMAKE_CURRENT_SOURCE_DIR}/server_account_manager.cpp"
       "${CMAKE_CURRENT_SOURCE_DIR}/server_account_manager.h"
diff --git a/src/jamidht/Makefile.am b/src/jamidht/Makefile.am
index 3a626939cd..632362026c 100644
--- a/src/jamidht/Makefile.am
+++ b/src/jamidht/Makefile.am
@@ -12,8 +12,6 @@ libjamiacc_la_SOURCES = \
 	./jamidht/jamiaccount_config.h \
 	./jamidht/channeled_transport.h \
 	./jamidht/channeled_transport.cpp \
-	./jamidht/channeled_transfers.h \
-	./jamidht/channeled_transfers.cpp \
 	./jamidht/conversation.h \
 	./jamidht/conversation.cpp \
 	./jamidht/conversationrepository.h \
@@ -27,8 +25,6 @@ libjamiacc_la_SOURCES = \
 	./jamidht/conversation_module.cpp \
 	./jamidht/accountarchive.cpp \
 	./jamidht/accountarchive.h \
-	./jamidht/p2p.cpp \
-	./jamidht/p2p.h \
 	./jamidht/jami_contact.h \
 	./jamidht/contact_list.h \
 	./jamidht/contact_list.cpp \
diff --git a/src/jamidht/channeled_transfers.cpp b/src/jamidht/channeled_transfers.cpp
deleted file mode 100644
index 329229c4e0..0000000000
--- a/src/jamidht/channeled_transfers.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- *  Copyright (C) 2020-2022 Savoir-faire Linux Inc.
- *
- *  Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- */
-
-#include "channeled_transfers.h"
-
-#include "ftp_server.h"
-#include "connectivity/multiplexed_socket.h"
-
-#include <opendht/thread_pool.h>
-
-#include "jamiaccount.h"
-
-namespace jami {
-
-ChanneledOutgoingTransfer::ChanneledOutgoingTransfer(const std::shared_ptr<ChannelSocket>& channel,
-                                                     OnStateChangedCb&& cb)
-    : stateChangedCb_(cb)
-    , channel_(channel)
-{}
-
-ChanneledOutgoingTransfer::~ChanneledOutgoingTransfer()
-{
-    channel_->setOnRecv({});
-    if (file_)
-        file_->setOnRecv({});
-    channel_->shutdown();
-    if (file_)
-        file_->close();
-}
-
-std::string
-ChanneledOutgoingTransfer::peer() const
-{
-    return channel_ ? channel_->deviceId().toString() : "";
-}
-
-void
-ChanneledOutgoingTransfer::linkTransfer(const std::shared_ptr<Stream>& file)
-{
-    if (!file)
-        return;
-    file_ = file;
-    channel_->setOnRecv([this](const uint8_t* buf, size_t len) {
-        file_->write(std::string_view((const char*) buf, len));
-        return len;
-    });
-    file_->setOnRecv([channel = std::weak_ptr<ChannelSocket>(channel_)](std::string_view data) {
-        if (auto c = channel.lock()) {
-            std::error_code ec;
-            c->write((const uint8_t*) data.data(), data.size(), ec);
-        }
-    });
-    file_->setOnStateChangedCb(stateChangedCb_);
-}
-
-ChanneledIncomingTransfer::ChanneledIncomingTransfer(const std::shared_ptr<ChannelSocket>& channel,
-                                                     const std::shared_ptr<FtpServer>& ftp,
-                                                     OnStateChangedCb&& cb)
-    : ftp_(ftp)
-    , channel_(channel)
-{
-    channel_->setOnRecv([this](const uint8_t* buf, size_t len) {
-        ftp_->write(std::string_view((const char*) buf, len));
-        return len;
-    });
-    ftp_->setOnRecv([channel = std::weak_ptr<ChannelSocket>(channel_)](std::string_view data) {
-        if (auto c = channel.lock()) {
-            std::error_code ec;
-            c->write((const uint8_t*) data.data(), data.size(), ec);
-        }
-    });
-    ftp_->setOnStateChangedCb(cb);
-}
-
-ChanneledIncomingTransfer::~ChanneledIncomingTransfer()
-{
-    channel_->setOnRecv({});
-    channel_->shutdown();
-    if (ftp_)
-        ftp_->close();
-}
-
-std::string
-ChanneledIncomingTransfer::peer() const
-{
-    return channel_ ? channel_->deviceId().toString() : "";
-}
-
-} // namespace jami
\ No newline at end of file
diff --git a/src/jamidht/channeled_transfers.h b/src/jamidht/channeled_transfers.h
deleted file mode 100644
index 548f239ddb..0000000000
--- a/src/jamidht/channeled_transfers.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *  Copyright (C) 2020-2022 Savoir-faire Linux Inc.
- *
- *  Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- */
-
-#pragma once
-
-#include <string>
-#include <memory>
-
-#include "jami/datatransfer_interface.h"
-#include "data_transfer.h"
-
-namespace jami {
-
-class ChannelSocket;
-class Stream;
-class FtpServer;
-
-class ChanneledOutgoingTransfer
-{
-public:
-    ChanneledOutgoingTransfer(const std::shared_ptr<ChannelSocket>& channel, OnStateChangedCb&& cb);
-    ~ChanneledOutgoingTransfer();
-    void linkTransfer(const std::shared_ptr<Stream>& file);
-    std::string peer() const;
-
-private:
-    OnStateChangedCb stateChangedCb_ {};
-    std::shared_ptr<ChannelSocket> channel_ {};
-    std::shared_ptr<Stream> file_;
-};
-
-class ChanneledIncomingTransfer
-{
-public:
-    ChanneledIncomingTransfer(const std::shared_ptr<ChannelSocket>& channel,
-                              const std::shared_ptr<FtpServer>& ftp,
-                              OnStateChangedCb&& cb);
-    ~ChanneledIncomingTransfer();
-    std::string peer() const;
-
-private:
-    std::shared_ptr<FtpServer> ftp_;
-    std::shared_ptr<ChannelSocket> channel_;
-};
-
-} // namespace jami
diff --git a/src/jamidht/conversation.cpp b/src/jamidht/conversation.cpp
index f7c2f8523c..bf903950f6 100644
--- a/src/jamidht/conversation.cpp
+++ b/src/jamidht/conversation.cpp
@@ -1204,6 +1204,17 @@ Conversation::sync(const std::string& member,
         }
         // We need a new channel
         account->transferFile(id(), account->profilePath(), deviceId, "profile.vcf", "");
+        // Mark the VCard as sent
+        auto sendDir = fmt::format("{}/{}/vcard/{}",
+                                   fileutils::get_cache_dir(),
+                                   account->getAccountID(),
+                                   member);
+        auto path = fmt::format("{}/{}", sendDir, deviceId);
+        fileutils::recursive_mkdir(sendDir);
+        std::lock_guard<std::mutex> lock(fileutils::getFileLock(path));
+        if (fileutils::isFile(path))
+            return;
+        fileutils::ofstream(path);
     }
 }
 
diff --git a/src/jamidht/jamiaccount.cpp b/src/jamidht/jamiaccount.cpp
index 258f3e1d38..ee003ccfeb 100644
--- a/src/jamidht/jamiaccount.cpp
+++ b/src/jamidht/jamiaccount.cpp
@@ -40,8 +40,8 @@
 #include "sip/sipcall.h"
 #include "sip/siptransport.h"
 #include "connectivity/sip_utils.h"
+#include "connectivity/ice_transport.h"
 
-#include "p2p.h"
 #include "uri.h"
 
 #include "client/ring_signal.h"
@@ -288,7 +288,6 @@ JamiAccount::JamiAccount(const std::string& accountId)
     , idPath_(fileutils::get_data_dir() + DIR_SEPARATOR_STR + accountId)
     , cachePath_(fileutils::get_cache_dir() + DIR_SEPARATOR_STR + accountId)
     , dataPath_(cachePath_ + DIR_SEPARATOR_STR "values")
-    , dhtPeerConnector_ {}
     , connectionManager_ {}
     , nonSwarmTransferManager_(std::make_shared<TransferManager>(accountId, ""))
 {
@@ -321,7 +320,6 @@ JamiAccount::shutdownConnections()
         connectionManager_.reset();
     }
     gitSocketList_.clear();
-    dhtPeerConnector_.reset();
     std::lock_guard<std::mutex> lk(sipConnsMtx_);
     sipConns_.clear();
 }
@@ -1978,17 +1976,8 @@ JamiAccount::doRegister_()
                 auto itHandler = channelHandlers_.find(uri.scheme());
                 if (itHandler != channelHandlers_.end() && itHandler->second)
                     return itHandler->second->onRequest(cert, name);
-                // TODO replace
-                auto isFile = name.substr(0, 7) == FILE_URI;
-                auto isVCard = name.substr(0, 8) == VCARD_URI;
-
                 if (name == "sip") {
                     return true;
-                } else if (isFile or isVCard) {
-                    auto tid = isFile ? name.substr(7) : name.substr(8);
-                    std::lock_guard<std::mutex> lk(transfersMtx_);
-                    incomingFileTransfers_.emplace(tid);
-                    return true;
                 }
                 return false;
             });
@@ -2000,39 +1989,8 @@ JamiAccount::doRegister_()
                 if (!cert || !cert->issuer)
                     return;
                 auto peerId = cert->issuer->getId().toString();
-                auto isFile = name.substr(0, 7) == FILE_URI;
-                auto isVCard = name.substr(0, 8) == VCARD_URI;
                 if (name == "sip") {
                     cacheSIPConnection(std::move(channel), peerId, deviceId);
-                } else if (isFile or isVCard) {
-                    auto tid = isFile ? name.substr(7) : name.substr(8);
-                    std::unique_lock<std::mutex> lk(transfersMtx_);
-                    auto it = incomingFileTransfers_.find(tid);
-                    // Note, outgoing file transfers are ignored.
-                    if (it == incomingFileTransfers_.end())
-                        return;
-                    incomingFileTransfers_.erase(it);
-                    lk.unlock();
-                    InternalCompletionCb cb;
-                    if (isVCard)
-                        cb = [peerId, accountId = getAccountID()](const std::string& path) {
-                            emitSignal<libjami::ConfigurationSignal::ProfileReceived>(accountId,
-                                                                                      peerId,
-                                                                                      path);
-                        };
-
-                    libjami::DataTransferInfo info;
-                    info.accountId = getAccountID();
-                    info.peer = peerId;
-                    try {
-                        dhtPeerConnector_->onIncomingConnection(info,
-                                                                std::stoull(tid),
-                                                                std::move(channel),
-                                                                std::move(cb));
-                    } catch (...) {
-                        JAMI_ERR() << "Invalid tid: " << tid;
-                    }
-
                 } else if (name.find("git://") == 0) {
                     auto sep = name.find_last_of('/');
                     auto conversationId = name.substr(sep + 1);
@@ -2136,9 +2094,6 @@ JamiAccount::doRegister_()
             return true;
         });
 
-        if (!dhtPeerConnector_)
-            dhtPeerConnector_ = std::make_unique<DhtPeerConnector>(*this);
-
         std::lock_guard<std::mutex> lock(buddyInfoMtx);
         for (auto& buddy : trackedBuddies_) {
             buddy.second.devices_cnt = 0;
@@ -3168,7 +3123,7 @@ JamiAccount::sendMessage(const std::string& to,
                                    JAMI_DBG()
                                        << "[Account " << getAccountID() << "] [message " << token
                                        << "] Put encrypted " << (ok ? "ok" : "failed");
-                                   if (not ok && dhtPeerConnector_ /* Check if not joining */) {
+                                   if (not ok && connectionManager_ /* Check if not joining */) {
                                        std::unique_lock<std::mutex> l(confirm->lock);
                                        auto lt = confirm->listenTokens.find(h);
                                        if (lt != confirm->listenTokens.end()) {
@@ -3323,33 +3278,6 @@ JamiAccount::storeActiveIpAddress(std::function<void()>&& cb)
     });
 }
 
-void
-JamiAccount::requestConnection(
-    const libjami::DataTransferInfo& info,
-    const libjami::DataTransferId& tid,
-    bool isVCard,
-    const std::function<void(const std::shared_ptr<ChanneledOutgoingTransfer>&)>&
-        channeledConnectedCb,
-    const std::function<void(const std::string&)>& onChanneledCancelled)
-{
-    if (not dhtPeerConnector_) {
-        runOnMainThread([onChanneledCancelled, info] { onChanneledCancelled(info.peer); });
-        return;
-    }
-    dhtPeerConnector_->requestConnection(info,
-                                         tid,
-                                         isVCard,
-                                         channeledConnectedCb,
-                                         onChanneledCancelled);
-}
-
-void
-JamiAccount::closePeerConnection(const libjami::DataTransferId& tid)
-{
-    if (dhtPeerConnector_)
-        dhtPeerConnector_->closeConnection(tid);
-}
-
 void
 JamiAccount::setPushNotificationToken(const std::string& token)
 {
@@ -3794,22 +3722,22 @@ JamiAccount::requestSIPConnection(const std::string& peerId,
 bool
 JamiAccount::needToSendProfile(const std::string& peerUri, const std::string& deviceId)
 {
-    auto vCardMd5 = fileutils::sha3File(fmt::format("{}/profile.vcf", idPath_));
-    std::string currentMd5 {};
+    auto currentSha3 = fileutils::sha3File(fmt::format("{}/profile.vcf", idPath_));
+    std::string previousSha3 {};
     auto vCardPath = fmt::format("{}/vcard", cachePath_);
     auto sha3Path = fmt::format("{}/sha3", vCardPath);
     fileutils::check_dir(vCardPath.c_str(), 0700);
     try {
-        currentMd5 = fileutils::loadTextFile(sha3Path);
+        previousSha3 = fileutils::loadTextFile(sha3Path);
     } catch (...) {
-        fileutils::saveFile(sha3Path, {vCardMd5.begin(), vCardMd5.end()}, 0600);
+        fileutils::saveFile(sha3Path, {currentSha3.begin(), currentSha3.end()}, 0600);
         return true;
     }
-    if (currentMd5 != vCardMd5) {
+    if (currentSha3 != previousSha3) {
         // Incorrect sha3 stored. Update it
         fileutils::removeAll(vCardPath, true);
         fileutils::check_dir(vCardPath.c_str(), 0700);
-        fileutils::saveFile(sha3Path, {vCardMd5.begin(), vCardMd5.end()}, 0600);
+        fileutils::saveFile(sha3Path, {currentSha3.begin(), currentSha3.end()}, 0600);
         return true;
     }
     fileutils::recursive_mkdir(fmt::format("{}/{}/", vCardPath, peerUri));
@@ -3906,32 +3834,6 @@ JamiAccount::sendSIPMessage(SipConnection& conn,
     return true;
 }
 
-void
-JamiAccount::sendProfile(const std::string& peerUri, const std::string& deviceId)
-{
-    try {
-        if (not needToSendProfile(peerUri, deviceId)) {
-            JAMI_DEBUG("Peer {:s} ({:s}) already got an up-to-date vcard", deviceId, peerUri);
-            return;
-        }
-
-        sendFile(deviceId,
-                 idPath_ + DIR_SEPARATOR_STR + "profile.vcf",
-                 [deviceId, this](const std::string&) {
-                     // Mark the VCard as sent
-                     auto path = fileutils::get_cache_dir() + DIR_SEPARATOR_STR + getAccountID()
-                                 + DIR_SEPARATOR_STR + "vcard" + DIR_SEPARATOR_STR + deviceId;
-                     std::lock_guard<std::mutex> lock(fileutils::getFileLock(path));
-                     if (fileutils::isFile(path))
-                         return;
-                     fileutils::ofstream(path);
-                 });
-
-    } catch (const std::exception& e) {
-        JAMI_ERR() << e.what();
-    }
-}
-
 void
 JamiAccount::clearProfileCache(const std::string& peerUri)
 {
@@ -3992,10 +3894,7 @@ JamiAccount::cacheSIPConnection(std::shared_ptr<ChannelSocket>&& socket,
               deviceId.to_c_str());
     lk.unlock();
 
-    sendProfile(peerId, deviceId.toString());
-
     convModule()->syncConversations(peerId, deviceId.toString());
-
     // Retry messages
     messageEngine_.onPeerOnline(peerId);
 
@@ -4116,19 +4015,6 @@ JamiAccount::sendFile(const std::string& conversationId,
     });
 }
 
-libjami::DataTransferId
-JamiAccount::sendFile(const std::string& peer,
-                      const std::string& path,
-                      const InternalCompletionCb& icb)
-{
-    if (!fileutils::isFile(path)) {
-        JAMI_ERR() << "invalid filename '" << path << "'";
-        return {};
-    }
-
-    return nonSwarmTransferManager_->sendFile(path, peer, icb);
-}
-
 void
 JamiAccount::transferFile(const std::string& conversationId,
                           const std::string& path,
diff --git a/src/jamidht/jamiaccount.h b/src/jamidht/jamiaccount.h
index 2b5bb1f29c..7c68f9f82e 100644
--- a/src/jamidht/jamiaccount.h
+++ b/src/jamidht/jamiaccount.h
@@ -352,30 +352,6 @@ public:
 #endif
     bool searchUser(const std::string& nameQuery);
 
-    /**
-     * Send a E2E connection request to a given peer for the given transfer id
-     * @param peer RingID on request's recipient
-     * @param tid linked outgoing data transfer
-     * @param isVcard if transfer is a vcard transfer
-     * @param channeledConnectedCb callback when channel is connected
-     * @param onChanneledCancelled callback when channel is canceled
-     */
-    void requestConnection(
-        const libjami::DataTransferInfo& info,
-        const libjami::DataTransferId& tid,
-        bool isVCard,
-        const std::function<void(const std::shared_ptr<ChanneledOutgoingTransfer>&)>&
-            channeledConnectedCb,
-        const std::function<void(const std::string&)>& onChanneledCancelled);
-
-    ///
-    /// Close a E2E connection between a given peer and a given transfer id.
-    ///
-    /// /// \param[in] peer RingID on request's recipient
-    /// /// \param[in] tid linked outgoing data transfer
-    ///
-    void closePeerConnection(const libjami::DataTransferId& tid);
-
     /// \return true if the given DHT message identifier has been treated
     /// \note if message has not been treated yet this method store this id and returns true at
     /// further calls
@@ -528,7 +504,6 @@ public:
                   const std::string& path,
                   const std::string& name,
                   const std::string& replyTo);
-
     // non-swarm version
     libjami::DataTransferId sendFile(const std::string& peer,
                                      const std::string& path,
@@ -793,7 +768,6 @@ private:
 
     pjsip_transport* via_tp_ {nullptr};
 
-    std::unique_ptr<DhtPeerConnector> dhtPeerConnector_;
     mutable std::mutex connManagerMtx_ {};
     std::unique_ptr<ConnectionManager> connectionManager_;
     GitSocketList gitSocketList_ {};
@@ -901,12 +875,10 @@ private:
     std::mutex gitServersMtx_ {};
     std::map<dht::Value::Id, std::unique_ptr<GitServer>> gitServers_ {};
 
-    std::atomic_bool deviceAnnounced_ {false};
-
-    //// File transfer
+    //// File transfer (for profiles)
     std::shared_ptr<TransferManager> nonSwarmTransferManager_;
-    std::mutex transferMutex_ {};
-    std::map<std::string, std::shared_ptr<TransferManager>> transferManagers_ {};
+
+    std::atomic_bool deviceAnnounced_ {false};
 
     bool noSha3sumVerification_ {false};
 
diff --git a/src/jamidht/p2p.cpp b/src/jamidht/p2p.cpp
deleted file mode 100644
index 3a10ccfda9..0000000000
--- a/src/jamidht/p2p.cpp
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- *  Copyright (C) 2004-2022 Savoir-faire Linux Inc.
- *
- *  Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
- *  Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- */
-
-#include "p2p.h"
-
-#include "account_schema.h"
-#include "jamiaccount.h"
-#include "ftp_server.h"
-#include "manager.h"
-#include "connectivity/peer_connection.h"
-#include "account_manager.h"
-#include "connectivity/multiplexed_socket.h"
-#include "connectivity/connectionmanager.h"
-#include "fileutils.h"
-
-#include <opendht/default_types.h>
-#include <opendht/rng.h>
-#include <opendht/thread_pool.h>
-
-#include <memory>
-#include <map>
-#include <vector>
-#include <chrono>
-#include <array>
-#include <future>
-#include <algorithm>
-#include <type_traits>
-
-namespace jami {
-
-using Clock = std::chrono::system_clock;
-using ValueIdDist = std::uniform_int_distribution<dht::Value::Id>;
-
-//==============================================================================
-
-class DhtPeerConnector::Impl : public std::enable_shared_from_this<DhtPeerConnector::Impl>
-{
-public:
-    class ClientConnector;
-
-    explicit Impl(const std::weak_ptr<JamiAccount>& account)
-        : account {account}
-    {}
-
-    std::weak_ptr<JamiAccount> account;
-
-    void closeConnection(const libjami::DataTransferId& tid, const std::string& peer = "");
-    void stateChanged(const libjami::DataTransferId& tid,
-                      const libjami::DataTransferEventCode& code,
-                      const std::string& peer);
-
-    std::shared_ptr<DhtPeerConnector::Impl> shared()
-    {
-        return std::static_pointer_cast<DhtPeerConnector::Impl>(shared_from_this());
-    }
-    std::shared_ptr<DhtPeerConnector::Impl const> shared() const
-    {
-        return std::static_pointer_cast<DhtPeerConnector::Impl const>(shared_from_this());
-    }
-    std::weak_ptr<DhtPeerConnector::Impl> weak()
-    {
-        return std::static_pointer_cast<DhtPeerConnector::Impl>(shared_from_this());
-    }
-    std::weak_ptr<DhtPeerConnector::Impl const> weak() const
-    {
-        return std::static_pointer_cast<DhtPeerConnector::Impl const>(shared_from_this());
-    }
-
-    void removeIncoming(const libjami::DataTransferId& tid, const std::string& peer)
-    {
-        std::vector<std::unique_ptr<ChanneledIncomingTransfer>> ifiles;
-        {
-            std::lock_guard<std::mutex> lk(channeledIncomingMtx_);
-            auto it = channeledIncoming_.find(tid);
-            if (it != channeledIncoming_.end()) {
-                for (auto chanIt = it->second.begin(); chanIt != it->second.end();) {
-                    if ((*chanIt)->peer() == peer) {
-                        ifiles.emplace_back(std::move(*chanIt));
-                        chanIt = it->second.erase(chanIt);
-                    } else {
-                        ++chanIt;
-                    }
-                }
-                if (it->second.empty())
-                    channeledIncoming_.erase(it);
-            }
-        }
-    }
-
-    void removeOutgoing(const libjami::DataTransferId& tid, const std::string& peer)
-    {
-        std::vector<std::shared_ptr<ChanneledOutgoingTransfer>> ofiles;
-        {
-            std::lock_guard<std::mutex> lk(channeledOutgoingMtx_);
-            auto it = channeledOutgoing_.find(tid);
-            if (it != channeledOutgoing_.end()) {
-                for (auto chanIt = it->second.begin(); chanIt != it->second.end();) {
-                    if ((*chanIt)->peer() == peer) {
-                        ofiles.emplace_back(std::move(*chanIt));
-                        chanIt = it->second.erase(chanIt);
-                    } else {
-                        ++chanIt;
-                    }
-                }
-                if (it->second.empty())
-                    channeledOutgoing_.erase(it);
-            }
-        }
-    }
-
-    // For Channeled transports
-    std::mutex channeledIncomingMtx_;
-    std::map<libjami::DataTransferId, std::vector<std::unique_ptr<ChanneledIncomingTransfer>>>
-        channeledIncoming_;
-    std::mutex channeledOutgoingMtx_;
-    // TODO change <<id, peer>, Channeled>
-    std::map<libjami::DataTransferId, std::vector<std::shared_ptr<ChanneledOutgoingTransfer>>>
-        channeledOutgoing_;
-};
-//==============================================================================
-
-void
-DhtPeerConnector::Impl::stateChanged(const libjami::DataTransferId& tid,
-                                     const libjami::DataTransferEventCode& code,
-                                     const std::string& peer)
-{
-    if (code == libjami::DataTransferEventCode::finished
-        or code == libjami::DataTransferEventCode::closed_by_peer
-        or code == libjami::DataTransferEventCode::timeout_expired)
-        closeConnection(tid, peer);
-}
-
-void
-DhtPeerConnector::Impl::closeConnection(const libjami::DataTransferId& tid, const std::string& peer)
-{
-    dht::ThreadPool::io().run([w = weak(), tid, peer] {
-        auto shared = w.lock();
-        if (!shared)
-            return;
-        shared->removeIncoming(tid, peer);
-        shared->removeOutgoing(tid, peer);
-    });
-}
-
-//==============================================================================
-
-DhtPeerConnector::DhtPeerConnector(JamiAccount& account)
-    : pimpl_ {std::make_shared<Impl>(account.weak())}
-{}
-
-void
-DhtPeerConnector::requestConnection(
-    const libjami::DataTransferInfo& info,
-    const libjami::DataTransferId& tid,
-    bool isVCard,
-    const std::function<void(const std::shared_ptr<ChanneledOutgoingTransfer>&)>&
-        channeledConnectedCb,
-    const std::function<void(const std::string&)>& onChanneledCancelled)
-{
-    auto acc = pimpl_->account.lock();
-    if (!acc)
-        return;
-
-    auto channelReadyCb = [this,
-                           tid,
-                           channeledConnectedCb,
-                           onChanneledCancelled](const std::shared_ptr<ChannelSocket>& channel,
-                                                 const DeviceId& deviceId) {
-        auto shared = pimpl_->account.lock();
-        if (!channel) {
-            onChanneledCancelled(deviceId.toString());
-            return;
-        }
-        if (!shared)
-            return;
-        JAMI_DEBUG("New file channel for outgoing transfer with id {:d}", tid);
-
-        auto outgoingFile = std::make_shared<ChanneledOutgoingTransfer>(
-            channel,
-            [this, deviceId](const libjami::DataTransferId& id,
-                             const libjami::DataTransferEventCode& code) {
-                pimpl_->stateChanged(id, code, deviceId.toString());
-            });
-        if (!outgoingFile)
-            return;
-        {
-            std::lock_guard<std::mutex> lk(pimpl_->channeledOutgoingMtx_);
-            pimpl_->channeledOutgoing_[tid].emplace_back(outgoingFile);
-        }
-
-        channel->onShutdown([w = pimpl_->weak(), tid, onChanneledCancelled, peer = outgoingFile->peer()]() {
-            JAMI_DEBUG("Channel down for outgoing transfer with id {:d}", tid);
-            onChanneledCancelled(peer);
-            dht::ThreadPool::io().run([w = std::move(w), tid, peer] {
-                if (auto shared = w.lock())
-                    shared->removeOutgoing(tid, peer);
-            });
-        });
-        channeledConnectedCb(outgoingFile);
-    };
-
-    if (isVCard) {
-        acc->connectionManager().connectDevice(DeviceId(info.peer),
-                                               fmt::format("vcard://{}", tid),
-                                               channelReadyCb);
-        return;
-    }
-
-    std::string channelName = "file://" + std::to_string(tid);
-    std::vector<dht::InfoHash> contacts;
-    if (!info.conversationId.empty()) {
-        // TODO remove preSwarmCompat
-        // In a one_to_one conv with an old version, the contact here can be in an invited
-        // state and will not support data-transfer. So if one_to_oe with non accepted, just
-        // force to file:// for now.
-        auto members = acc->convModule()->getConversationMembers(info.conversationId);
-        auto preSwarmCompat = members.size() == 2 && members[1]["role"] == "invited";
-        if (preSwarmCompat) {
-            auto infos = acc->convModule()->conversationInfos(info.conversationId);
-            preSwarmCompat = infos["mode"] == "0";
-        }
-        if (!preSwarmCompat)
-            channelName = fmt::format("data-transfer://{}/{}/{}",
-                                      info.conversationId,
-                                      acc->currentDeviceId(),
-                                      tid);
-        // If peer is not empty this means that we want to send to one device only
-        if (!info.peer.empty()) {
-            acc->connectionManager().connectDevice(DeviceId(info.peer), channelName, channelReadyCb);
-            return;
-        }
-        for (const auto& member : members) {
-            contacts.emplace_back(dht::InfoHash(member.at("uri")));
-        }
-    } else {
-        contacts.emplace_back(dht::InfoHash(info.peer));
-    }
-
-    for (const auto& peer_h : contacts) {
-        acc->forEachDevice(
-            peer_h,
-            [this, channelName, channelReadyCb = std::move(channelReadyCb)](
-                const std::shared_ptr<dht::crypto::PublicKey>& dev) {
-                auto acc = pimpl_->account.lock();
-                if (!acc)
-                    return;
-                const auto& deviceId = dev->getLongId();
-                if (deviceId == acc->dht()->getPublicKey()->getLongId()) {
-                    // No connection to same device
-                    return;
-                }
-
-                acc->connectionManager().connectDevice(deviceId, channelName, channelReadyCb);
-            },
-            [peer_h, onChanneledCancelled, accId = acc->getAccountID()](bool found) {
-                if (!found) {
-                    JAMI_WARN() << accId << "[CNX] aborted, no devices for " << peer_h;
-                    onChanneledCancelled(peer_h.toString());
-                }
-            });
-    }
-}
-
-void
-DhtPeerConnector::closeConnection(const libjami::DataTransferId& tid)
-{
-    pimpl_->closeConnection(tid);
-}
-
-void
-DhtPeerConnector::onIncomingConnection(const libjami::DataTransferInfo& info,
-                                       const libjami::DataTransferId& id,
-                                       const std::shared_ptr<ChannelSocket>& channel,
-                                       const InternalCompletionCb& cb)
-{
-    if (!channel)
-        return;
-    auto peer_id = info.peer;
-    auto incomingFile = std::make_unique<ChanneledIncomingTransfer>(
-        channel,
-        std::make_shared<FtpServer>(info, id, std::move(cb)),
-        [this, peer_id](const libjami::DataTransferId& id, const libjami::DataTransferEventCode& code) {
-            pimpl_->stateChanged(id, code, peer_id);
-        });
-    {
-        std::lock_guard<std::mutex> lk(pimpl_->channeledIncomingMtx_);
-        pimpl_->channeledIncoming_[id].emplace_back(std::move(incomingFile));
-    }
-    channel->onShutdown([w = pimpl_->weak(), id, peer_id]() {
-        JAMI_DEBUG("Channel down for incoming transfer with id {:d}", id);
-        dht::ThreadPool::io().run([w=std::move(w), id, peer_id] {
-            if (auto shared = w.lock())
-                shared->removeIncoming(id, peer_id);
-        });
-    });
-}
-
-} // namespace jami
diff --git a/src/jamidht/p2p.h b/src/jamidht/p2p.h
deleted file mode 100644
index 4aa426a104..0000000000
--- a/src/jamidht/p2p.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *  Copyright (C) 2004-2022 Savoir-faire Linux Inc.
- *
- *  Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
- *  Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- */
-
-#pragma once
-
-#include "jami/datatransfer_interface.h"
-#include "data_transfer.h"
-#include "channeled_transfers.h"
-
-#include <string>
-#include <memory>
-#include <functional>
-
-namespace jami {
-
-class JamiAccount;
-
-class DhtPeerConnector
-{
-public:
-    DhtPeerConnector(JamiAccount& account);
-
-    void requestConnection(
-        const libjami::DataTransferInfo& info,
-        const libjami::DataTransferId& tid,
-        bool isVCard,
-        const std::function<void(const std::shared_ptr<ChanneledOutgoingTransfer>&)>&
-            channeledConnectedCb,
-        const std::function<void(const std::string&)>& onChanneledCancelled);
-    void closeConnection(const libjami::DataTransferId& tid);
-    void onIncomingConnection(const libjami::DataTransferInfo& info,
-                              const libjami::DataTransferId& id,
-                              const std::shared_ptr<ChannelSocket>& channel,
-                              const InternalCompletionCb& cb = {});
-
-private:
-    DhtPeerConnector() = delete;
-
-    class Impl;
-    std::shared_ptr<Impl> pimpl_;
-};
-
-} // namespace jami
diff --git a/src/jamidht/transfer_channel_handler.cpp b/src/jamidht/transfer_channel_handler.cpp
index 684f82fdb7..851df6ff77 100644
--- a/src/jamidht/transfer_channel_handler.cpp
+++ b/src/jamidht/transfer_channel_handler.cpp
@@ -67,7 +67,7 @@ TransferChannelHandler::onRequest(const std::shared_ptr<dht::crypto::Certificate
     }
 
     // Check if peer is member of the conversation
-    if (fileId == fmt::format("{}.vcf", acc->getUsername())) {
+    if (fileId == fmt::format("{}.vcf", acc->getUsername()) || fileId == "profile.vcf") {
         auto members = acc->convModule()->getConversationMembers(conversationId);
         return std::find_if(members.begin(), members.end(), [&](auto m) { return m["uri"] == uri; })
                != members.end();
@@ -122,6 +122,9 @@ TransferChannelHandler::onReady(const std::shared_ptr<dht::crypto::Certificate>&
         auto path = acc->dataTransfer()->profilePath(fileId.substr(0, fileId.size() - 4));
         acc->dataTransfer()->transferFile(channel, fileId, "", path);
         return;
+    } else if (fileId == "profile.vcf") {
+        acc->dataTransfer()->onIncomingProfile(channel);
+        return;
     }
     auto dt = acc->dataTransfer(conversationId);
     sep = fileId.find('_');
diff --git a/src/meson.build b/src/meson.build
index fd0fe308f8..06da38ed7c 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -40,7 +40,6 @@ libjami_sources = files(
     'jamidht/accountarchive.cpp',
     'jamidht/account_manager.cpp',
     'jamidht/archive_account_manager.cpp',
-    'jamidht/channeled_transfers.cpp',
     'jamidht/channeled_transport.cpp',
     'jamidht/contact_list.cpp',
     'jamidht/conversation.cpp',
@@ -51,7 +50,6 @@ libjami_sources = files(
     'jamidht/jamiaccount.cpp',
     'jamidht/jamiaccount_config.cpp',
     'jamidht/namedirectory.cpp',
-    'jamidht/p2p.cpp',
     'jamidht/server_account_manager.cpp',
     'jamidht/sync_channel_handler.cpp',
     'jamidht/sync_module.cpp',
@@ -105,7 +103,6 @@ libjami_sources = files(
     'conference_protocol.cpp',
     'data_transfer.cpp',
     'fileutils.cpp',
-    'ftp_server.cpp',
     'gittransport.cpp',
     'logger.cpp',
     'manager.cpp',
diff --git a/test/unitTest/conversation/conversation.cpp b/test/unitTest/conversation/conversation.cpp
index fa8d07b2af..29991f6291 100644
--- a/test/unitTest/conversation/conversation.cpp
+++ b/test/unitTest/conversation/conversation.cpp
@@ -173,7 +173,8 @@ void
 ConversationTest::setUp()
 {
     // Init daemon
-    libjami::init(libjami::InitFlag(libjami::LIBJAMI_FLAG_DEBUG | libjami::LIBJAMI_FLAG_CONSOLE_LOG));
+    libjami::init(
+        libjami::InitFlag(libjami::LIBJAMI_FLAG_DEBUG | libjami::LIBJAMI_FLAG_CONSOLE_LOG));
     if (not Manager::instance().initialized)
         CPPUNIT_ASSERT(libjami::start("jami-sample.yml"));
 
@@ -425,15 +426,16 @@ ConversationTest::testReplaceWithBadCertificate()
             }
         }));
     auto errorDetected = false;
-    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
-        [&](const std::string& /* accountId */,
-            const std::string& /* conversationId */,
-            int code,
-            const std::string& /* what */) {
-            if (code == 3)
-                errorDetected = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
+            [&](const std::string& /* accountId */,
+                const std::string& /* conversationId */,
+                int code,
+                const std::string& /* what */) {
+                if (code == 3)
+                    errorDetected = true;
+                cv.notify_one();
+            }));
     libjami::registerSignalHandlers(confHandlers);
 
     auto convId = libjami::startConversation(aliceId);
@@ -615,7 +617,8 @@ ConversationTest::testMergeAfterMigration()
         libjami::exportable_callback<libjami::ConfigurationSignal::VolatileDetailsChanged>(
             [&](const std::string&, const std::map<std::string, std::string>&) {
                 auto details = carlaAccount->getVolatileAccountDetails();
-                auto deviceAnnounced = details[libjami::Account::VolatileProperties::DEVICE_ANNOUNCED];
+                auto deviceAnnounced
+                    = details[libjami::Account::VolatileProperties::DEVICE_ANNOUNCED];
                 if (deviceAnnounced == "true") {
                     carlaConnected = true;
                     cv.notify_one();
@@ -694,7 +697,8 @@ ConversationTest::testSendMessageToMultipleParticipants()
         libjami::exportable_callback<libjami::ConfigurationSignal::VolatileDetailsChanged>(
             [&](const std::string&, const std::map<std::string, std::string>&) {
                 auto details = carlaAccount->getVolatileAccountDetails();
-                auto deviceAnnounced = details[libjami::Account::VolatileProperties::DEVICE_ANNOUNCED];
+                auto deviceAnnounced
+                    = details[libjami::Account::VolatileProperties::DEVICE_ANNOUNCED];
                 if (deviceAnnounced == "true") {
                     carlaConnected = true;
                     cv.notify_one();
@@ -1498,7 +1502,8 @@ ConversationTest::testVoteNonEmpty()
         libjami::exportable_callback<libjami::ConfigurationSignal::VolatileDetailsChanged>(
             [&](const std::string&, const std::map<std::string, std::string>&) {
                 auto details = carlaAccount->getVolatileAccountDetails();
-                auto deviceAnnounced = details[libjami::Account::VolatileProperties::DEVICE_ANNOUNCED];
+                auto deviceAnnounced
+                    = details[libjami::Account::VolatileProperties::DEVICE_ANNOUNCED];
                 if (deviceAnnounced == "true") {
                     carlaConnected = true;
                     cv.notify_one();
@@ -1518,15 +1523,16 @@ ConversationTest::testVoteNonEmpty()
             }
             cv.notify_one();
         }));
-    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
-        [&](const std::string& /* accountId */,
-            const std::string& /* conversationId */,
-            int code,
-            const std::string& /* what */) {
-            if (code == 3)
-                errorDetected = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
+            [&](const std::string& /* accountId */,
+                const std::string& /* conversationId */,
+                int code,
+                const std::string& /* what */) {
+                if (code == 3)
+                    errorDetected = true;
+                cv.notify_one();
+            }));
     libjami::registerSignalHandlers(confHandlers);
     Manager::instance().sendRegister(carlaId, true);
     CPPUNIT_ASSERT(cv.wait_for(lk, 60s, [&] { return carlaConnected; }));
@@ -1594,21 +1600,23 @@ ConversationTest::testNoBadFileInInitialCommit()
         libjami::exportable_callback<libjami::ConfigurationSignal::VolatileDetailsChanged>(
             [&](const std::string&, const std::map<std::string, std::string>&) {
                 auto details = carlaAccount->getVolatileAccountDetails();
-                auto deviceAnnounced = details[libjami::Account::VolatileProperties::DEVICE_ANNOUNCED];
+                auto deviceAnnounced
+                    = details[libjami::Account::VolatileProperties::DEVICE_ANNOUNCED];
                 if (deviceAnnounced == "true") {
                     carlaConnected = true;
                     cv.notify_one();
                 }
             }));
-    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
-        [&](const std::string& /* accountId */,
-            const std::string& /* conversationId */,
-            int code,
-            const std::string& /* what */) {
-            if (code == 3)
-                errorDetected = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
+            [&](const std::string& /* accountId */,
+                const std::string& /* conversationId */,
+                int code,
+                const std::string& /* what */) {
+                if (code == 3)
+                    errorDetected = true;
+                cv.notify_one();
+            }));
     libjami::registerSignalHandlers(confHandlers);
 
     Manager::instance().sendRegister(carlaId, true);
@@ -1667,21 +1675,23 @@ ConversationTest::testNoBadCertInInitialCommit()
         libjami::exportable_callback<libjami::ConfigurationSignal::VolatileDetailsChanged>(
             [&](const std::string&, const std::map<std::string, std::string>&) {
                 auto details = carlaAccount->getVolatileAccountDetails();
-                auto deviceAnnounced = details[libjami::Account::VolatileProperties::DEVICE_ANNOUNCED];
+                auto deviceAnnounced
+                    = details[libjami::Account::VolatileProperties::DEVICE_ANNOUNCED];
                 if (deviceAnnounced == "true") {
                     carlaConnected = true;
                     cv.notify_one();
                 }
             }));
-    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
-        [&](const std::string& /* accountId */,
-            const std::string& /* conversationId */,
-            int code,
-            const std::string& /* what */) {
-            if (code == 3)
-                errorDetected = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
+            [&](const std::string& /* accountId */,
+                const std::string& /* conversationId */,
+                int code,
+                const std::string& /* what */) {
+                if (code == 3)
+                    errorDetected = true;
+                cv.notify_one();
+            }));
     libjami::registerSignalHandlers(confHandlers);
 
     Manager::instance().sendRegister(carlaId, true);
@@ -1737,15 +1747,16 @@ ConversationTest::testPlainTextNoBadFile()
                 cv.notify_one();
             }
         }));
-    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
-        [&](const std::string& /* accountId */,
-            const std::string& /* conversationId */,
-            int code,
-            const std::string& /* what */) {
-            if (code == 3)
-                errorDetected = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
+            [&](const std::string& /* accountId */,
+                const std::string& /* conversationId */,
+                int code,
+                const std::string& /* what */) {
+                if (code == 3)
+                    errorDetected = true;
+                cv.notify_one();
+            }));
     libjami::registerSignalHandlers(confHandlers);
 
     libjami::addConversationMember(aliceId, convId, bobUri);
@@ -1807,7 +1818,8 @@ ConversationTest::testVoteNoBadFile()
         libjami::exportable_callback<libjami::ConfigurationSignal::VolatileDetailsChanged>(
             [&](const std::string&, const std::map<std::string, std::string>&) {
                 auto details = carlaAccount->getVolatileAccountDetails();
-                auto deviceAnnounced = details[libjami::Account::VolatileProperties::DEVICE_ANNOUNCED];
+                auto deviceAnnounced
+                    = details[libjami::Account::VolatileProperties::DEVICE_ANNOUNCED];
                 if (deviceAnnounced == "true") {
                     carlaConnected = true;
                     cv.notify_one();
@@ -1907,15 +1919,16 @@ ConversationTest::testETooBigClone()
                 cv.notify_one();
             }
         }));
-    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
-        [&](const std::string& /* accountId */,
-            const std::string& /* conversationId */,
-            int code,
-            const std::string& /* what */) {
-            if (code == 3)
-                errorDetected = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
+            [&](const std::string& /* accountId */,
+                const std::string& /* conversationId */,
+                int code,
+                const std::string& /* what */) {
+                if (code == 3)
+                    errorDetected = true;
+                cv.notify_one();
+            }));
     libjami::registerSignalHandlers(confHandlers);
 
     auto convId = libjami::startConversation(aliceId);
@@ -1981,15 +1994,16 @@ ConversationTest::testETooBigFetch()
                 cv.notify_one();
             }
         }));
-    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
-        [&](const std::string& /* accountId */,
-            const std::string& /* conversationId */,
-            int code,
-            const std::string& /* what */) {
-            if (code == 3)
-                errorDetected = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
+            [&](const std::string& /* accountId */,
+                const std::string& /* conversationId */,
+                int code,
+                const std::string& /* what */) {
+                if (code == 3)
+                    errorDetected = true;
+                cv.notify_one();
+            }));
     libjami::registerSignalHandlers(confHandlers);
 
     auto convId = libjami::startConversation(aliceId);
@@ -2068,15 +2082,16 @@ ConversationTest::testUnknownModeDetected()
                 cv.notify_one();
             }
         }));
-    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
-        [&](const std::string& /* accountId */,
-            const std::string& /* conversationId */,
-            int code,
-            const std::string& /* what */) {
-            if (code == 2)
-                errorDetected = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
+            [&](const std::string& /* accountId */,
+                const std::string& /* conversationId */,
+                int code,
+                const std::string& /* what */) {
+                if (code == 2)
+                    errorDetected = true;
+                cv.notify_one();
+            }));
     libjami::registerSignalHandlers(confHandlers);
     libjami::addConversationMember(aliceId, convId, bobUri);
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
@@ -2285,18 +2300,19 @@ VERSION:2.1\n\
 FN:TITLE\n\
 DESCRIPTION:DESC\n\
 END:VCARD";
-    confHandlers.insert(libjami::exportable_callback<libjami::ConfigurationSignal::IncomingTrustRequest>(
-        [&](const std::string& account_id,
-            const std::string& /*from*/,
-            const std::string& /*conversationId*/,
-            const std::vector<uint8_t>& payload,
-            time_t /*received*/) {
-            auto pstr = std::string(payload.begin(), payload.begin() + payload.size());
-            if (account_id == bobId
-                && std::string(payload.data(), payload.data() + payload.size()) == vcard)
-                requestReceived = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConfigurationSignal::IncomingTrustRequest>(
+            [&](const std::string& account_id,
+                const std::string& /*from*/,
+                const std::string& /*conversationId*/,
+                const std::vector<uint8_t>& payload,
+                time_t /*received*/) {
+                auto pstr = std::string(payload.begin(), payload.begin() + payload.size());
+                if (account_id == bobId
+                    && std::string(payload.data(), payload.data() + payload.size()) == vcard)
+                    requestReceived = true;
+                cv.notify_one();
+            }));
     confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::ConversationReady>(
         [&](const std::string& accountId, const std::string& conversationId) {
             if (accountId == aliceId) {
@@ -2356,15 +2372,16 @@ ConversationTest::testMemberCannotUpdateProfile()
                 cv.notify_one();
             }
         }));
-    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
-        [&](const std::string& accountId,
-            const std::string& conversationId,
-            int code,
-            const std::string& /* what */) {
-            if (accountId == bobId && conversationId == convId && code == 4)
-                errorDetected = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
+            [&](const std::string& accountId,
+                const std::string& conversationId,
+                int code,
+                const std::string& /* what */) {
+                if (accountId == bobId && conversationId == convId && code == 4)
+                    errorDetected = true;
+                cv.notify_one();
+            }));
     libjami::registerSignalHandlers(confHandlers);
 
     libjami::addConversationMember(aliceId, convId, bobUri);
@@ -2424,15 +2441,16 @@ ConversationTest::testUpdateProfileWithBadFile()
                 cv.notify_one();
             }
         }));
-    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
-        [&](const std::string& accountId,
-            const std::string& conversationId,
-            int code,
-            const std::string& /* what */) {
-            if (accountId == bobId && conversationId == convId && code == 3)
-                errorDetected = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
+            [&](const std::string& accountId,
+                const std::string& conversationId,
+                int code,
+                const std::string& /* what */) {
+                if (accountId == bobId && conversationId == convId && code == 3)
+                    errorDetected = true;
+                cv.notify_one();
+            }));
     libjami::registerSignalHandlers(confHandlers);
 
     libjami::addConversationMember(aliceId, convId, bobUri);
@@ -2503,15 +2521,16 @@ ConversationTest::testFetchProfileUnauthorized()
                 cv.notify_one();
             }
         }));
-    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
-        [&](const std::string& accountId,
-            const std::string& conversationId,
-            int code,
-            const std::string& /* what */) {
-            if (accountId == aliceId && conversationId == convId && code == 3)
-                errorDetected = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
+            [&](const std::string& accountId,
+                const std::string& conversationId,
+                int code,
+                const std::string& /* what */) {
+                if (accountId == aliceId && conversationId == convId && code == 3)
+                    errorDetected = true;
+                cv.notify_one();
+            }));
     libjami::registerSignalHandlers(confHandlers);
 
     libjami::addConversationMember(aliceId, convId, bobUri);
@@ -2577,16 +2596,17 @@ ConversationTest::testSyncingWhileAccepting()
     std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> confHandlers;
     bool conversationReady = false, requestReceived = false;
     std::string convId = "";
-    confHandlers.insert(libjami::exportable_callback<libjami::ConfigurationSignal::IncomingTrustRequest>(
-        [&](const std::string& account_id,
-            const std::string& /*from*/,
-            const std::string& /*conversationId*/,
-            const std::vector<uint8_t>& /*payload*/,
-            time_t /*received*/) {
-            if (account_id == bobId)
-                requestReceived = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConfigurationSignal::IncomingTrustRequest>(
+            [&](const std::string& account_id,
+                const std::string& /*from*/,
+                const std::string& /*conversationId*/,
+                const std::vector<uint8_t>& /*payload*/,
+                time_t /*received*/) {
+                if (account_id == bobId)
+                    requestReceived = true;
+                cv.notify_one();
+            }));
     confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::ConversationReady>(
         [&](const std::string& accountId, const std::string& conversationId) {
             if (accountId == aliceId) {
@@ -2665,16 +2685,17 @@ ConversationTest::testReplayConversation()
          conversationRemoved = false, messageReceived = false;
     std::vector<std::string> bobMessages;
     std::string convId = "";
-    confHandlers.insert(libjami::exportable_callback<libjami::ConfigurationSignal::IncomingTrustRequest>(
-        [&](const std::string& account_id,
-            const std::string& /*from*/,
-            const std::string& /*conversationId*/,
-            const std::vector<uint8_t>& /*payload*/,
-            time_t /*received*/) {
-            if (account_id == bobId)
-                requestReceived = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConfigurationSignal::IncomingTrustRequest>(
+            [&](const std::string& account_id,
+                const std::string& /*from*/,
+                const std::string& /*conversationId*/,
+                const std::vector<uint8_t>& /*payload*/,
+                time_t /*received*/) {
+                if (account_id == bobId)
+                    requestReceived = true;
+                cv.notify_one();
+            }));
     confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::ConversationReady>(
         [&](const std::string& accountId, const std::string& conversationId) {
             if (accountId == aliceId) {
@@ -2684,12 +2705,13 @@ ConversationTest::testReplayConversation()
             }
             cv.notify_one();
         }));
-    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::ConversationRemoved>(
-        [&](const std::string& accountId, const std::string&) {
-            if (accountId == aliceId)
-                conversationRemoved = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::ConversationRemoved>(
+            [&](const std::string& accountId, const std::string&) {
+                if (accountId == aliceId)
+                    conversationRemoved = true;
+                cv.notify_one();
+            }));
     confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::MessageReceived>(
         [&](const std::string& accountId,
             const std::string& conversationId,
@@ -2750,16 +2772,17 @@ ConversationTest::testSyncWithoutPinnedCert()
     std::string convId = "";
     auto requestReceived = false, conversationReady = false, memberMessageGenerated = false,
          aliceMessageReceived = false;
-    confHandlers.insert(libjami::exportable_callback<libjami::ConfigurationSignal::IncomingTrustRequest>(
-        [&](const std::string& account_id,
-            const std::string& /*from*/,
-            const std::string& /*conversationId*/,
-            const std::vector<uint8_t>& /*payload*/,
-            time_t /*received*/) {
-            if (account_id == bobId)
-                requestReceived = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConfigurationSignal::IncomingTrustRequest>(
+            [&](const std::string& account_id,
+                const std::string& /*from*/,
+                const std::string& /*conversationId*/,
+                const std::vector<uint8_t>& /*payload*/,
+                time_t /*received*/) {
+                if (account_id == bobId)
+                    requestReceived = true;
+                cv.notify_one();
+            }));
     confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::ConversationReady>(
         [&](const std::string& accountId, const std::string& conversationId) {
             if (accountId == aliceId) {
@@ -2945,14 +2968,15 @@ END:VCARD";
                 cv.notify_one();
             }));
     auto conversationRmBob = false, conversationRmBob2 = false;
-    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::ConversationRemoved>(
-        [&](const std::string& accountId, const std::string&) {
-            if (accountId == bobId)
-                conversationRmBob = true;
-            else if (accountId == bob2Id)
-                conversationRmBob2 = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::ConversationRemoved>(
+            [&](const std::string& accountId, const std::string&) {
+                if (accountId == bobId)
+                    conversationRmBob = true;
+                else if (accountId == bob2Id)
+                    conversationRmBob2 = true;
+                cv.notify_one();
+            }));
     auto aliceProfileReceivedBob = false, aliceProfileReceivedBob2 = false;
     confHandlers.insert(libjami::exportable_callback<libjami::ConfigurationSignal::ProfileReceived>(
         [&](const std::string& accountId, const std::string& peerId, const std::string& path) {
@@ -3102,16 +3126,17 @@ ConversationTest::testSearchInConv()
          messageReceived = false;
     std::vector<std::string> bobMessages;
     std::string convId = "";
-    confHandlers.insert(libjami::exportable_callback<libjami::ConfigurationSignal::IncomingTrustRequest>(
-        [&](const std::string& account_id,
-            const std::string& /*from*/,
-            const std::string& /*conversationId*/,
-            const std::vector<uint8_t>& /*payload*/,
-            time_t /*received*/) {
-            if (account_id == bobId)
-                requestReceived = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConfigurationSignal::IncomingTrustRequest>(
+            [&](const std::string& account_id,
+                const std::string& /*from*/,
+                const std::string& /*conversationId*/,
+                const std::vector<uint8_t>& /*payload*/,
+                time_t /*received*/) {
+                if (account_id == bobId)
+                    requestReceived = true;
+                cv.notify_one();
+            }));
     confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::ConversationReady>(
         [&](const std::string& accountId, const std::string& conversationId) {
             if (accountId == aliceId) {
@@ -3192,12 +3217,13 @@ ConversationTest::testConversationPreferences()
                 cv.notify_one();
             }
         }));
-    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::ConversationRemoved>(
-        [&](const std::string& accountId, const std::string&) {
-            if (accountId == aliceId)
-                conversationRemoved = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::ConversationRemoved>(
+            [&](const std::string& accountId, const std::string&) {
+                if (accountId == aliceId)
+                    conversationRemoved = true;
+                cv.notify_one();
+            }));
     libjami::registerSignalHandlers(confHandlers);
     // Start conversation and set preferences
     auto convId = libjami::startConversation(aliceId);
@@ -3369,12 +3395,13 @@ ConversationTest::testRemoveOneToOneNotInDetails()
             cv.notify_one();
         }));
     bool conversationRemoved = false;
-    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::ConversationRemoved>(
-        [&](const std::string& accountId, const std::string& cid) {
-            if (accountId == aliceId && cid == secondConv)
-                conversationRemoved = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::ConversationRemoved>(
+            [&](const std::string& accountId, const std::string& cid) {
+                if (accountId == aliceId && cid == secondConv)
+                    conversationRemoved = true;
+                cv.notify_one();
+            }));
     libjami::registerSignalHandlers(confHandlers);
 
     aliceAccount->addContact(bobUri);
@@ -3416,7 +3443,6 @@ ConversationTest::testMessageEdition()
             std::map<std::string, std::string> message) {
             if (accountId == bobId) {
                 messageBobReceived.emplace_back(message);
-                JAMI_ERR("@@@ EMPLACE!");
             } else if (accountId == aliceId && message["type"] == "member") {
                 memberMessageGenerated = true;
             }
@@ -3439,15 +3465,16 @@ ConversationTest::testMessageEdition()
             }
         }));
     auto errorDetected = false;
-    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
-        [&](const std::string& /* accountId */,
-            const std::string& /* conversationId */,
-            int code,
-            const std::string& /* what */) {
-            if (code == 3)
-                errorDetected = true;
-            cv.notify_one();
-        }));
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::OnConversationError>(
+            [&](const std::string& /* accountId */,
+                const std::string& /* conversationId */,
+                int code,
+                const std::string& /* what */) {
+                if (code == 3)
+                    errorDetected = true;
+                cv.notify_one();
+            }));
     libjami::registerSignalHandlers(confHandlers);
     auto convId = libjami::startConversation(aliceId);
     libjami::addConversationMember(aliceId, convId, bobUri);
diff --git a/test/unitTest/fileTransfer/fileTransfer.cpp b/test/unitTest/fileTransfer/fileTransfer.cpp
index 698a5f91bd..d8f27686a0 100644
--- a/test/unitTest/fileTransfer/fileTransfer.cpp
+++ b/test/unitTest/fileTransfer/fileTransfer.cpp
@@ -46,7 +46,8 @@ public:
     FileTransferTest()
     {
         // Init daemon
-        libjami::init(libjami::InitFlag(libjami::LIBJAMI_FLAG_DEBUG | libjami::LIBJAMI_FLAG_CONSOLE_LOG));
+        libjami::init(
+            libjami::InitFlag(libjami::LIBJAMI_FLAG_DEBUG | libjami::LIBJAMI_FLAG_CONSOLE_LOG));
         if (not Manager::instance().initialized)
             CPPUNIT_ASSERT(libjami::start("jami-sample.yml"));
     }
@@ -65,9 +66,6 @@ public:
     std::string recv2Path {std::filesystem::current_path() / "RECV2"};
 
 private:
-    void testFileTransfer();
-    void testDataTransferInfo();
-    void testMultipleFileTransfer();
     void testConversationFileTransfer();
     void testFileTransferInConversation();
     void testVcfFileTransferInConversation();
@@ -79,9 +77,6 @@ private:
     void testTransferInfo();
 
     CPPUNIT_TEST_SUITE(FileTransferTest);
-    CPPUNIT_TEST(testFileTransfer);
-    CPPUNIT_TEST(testDataTransferInfo);
-    CPPUNIT_TEST(testMultipleFileTransfer);
     CPPUNIT_TEST(testConversationFileTransfer);
     CPPUNIT_TEST(testFileTransferInConversation);
     CPPUNIT_TEST(testVcfFileTransferInConversation);
@@ -127,272 +122,6 @@ FileTransferTest::tearDown()
     wait_for_removal_of({aliceId, bobId, carlaId});
 }
 
-void
-FileTransferTest::testFileTransfer()
-{
-    auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
-    auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
-    auto bobUri = bobAccount->getUsername();
-    auto aliceUri = aliceAccount->getUsername();
-
-    std::mutex mtx;
-    std::unique_lock<std::mutex> lk {mtx};
-    std::condition_variable cv;
-    std::condition_variable cv2;
-    std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> confHandlers;
-    bool transferWaiting = false, transferFinished = false;
-    std::string finalId;
-    // Watch signals
-    confHandlers.insert(libjami::exportable_callback<libjami::DataTransferSignal::DataTransferEvent>(
-        [&](const std::string& accountId,
-            const std::string&,
-            const std::string&,
-            const std::string& fileId,
-            int code) {
-            if (accountId == bobId
-                && code == static_cast<int>(libjami::DataTransferEventCode::wait_host_acceptance)) {
-                transferWaiting = true;
-                finalId = fileId;
-                cv.notify_one();
-            } else if (accountId == aliceId
-                       && code == static_cast<int>(libjami::DataTransferEventCode::finished)) {
-                transferFinished = true;
-                finalId = fileId;
-                cv.notify_one();
-            }
-        }));
-    libjami::registerSignalHandlers(confHandlers);
-
-    // Create file to send
-    auto sendVcfPath = sendPath + ".vcf";
-    auto recvVcfPath = recvPath + ".vcf";
-    std::ofstream sendFile(sendVcfPath);
-    CPPUNIT_ASSERT(sendFile.is_open());
-    sendFile << std::string(64000, 'A');
-    sendFile.close();
-
-    // Send File
-    libjami::DataTransferInfo info;
-    uint64_t id;
-    info.accountId = aliceAccount->getAccountID();
-    info.peer = bobUri;
-    info.path = sendVcfPath;
-    info.displayName = "SEND.vcf";
-    info.bytesProgress = 0;
-    CPPUNIT_ASSERT(libjami::sendFileLegacy(info, id) == libjami::DataTransferError::success);
-
-    cv.wait_for(lk, std::chrono::seconds(30));
-    CPPUNIT_ASSERT(transferWaiting);
-
-    CPPUNIT_ASSERT(libjami::acceptFileTransfer(bobId, finalId, recvVcfPath)
-                   == libjami::DataTransferError::success);
-
-    // Wait 2 times, both sides will got a finished status
-    cv.wait_for(lk, std::chrono::seconds(30));
-    cv.wait_for(lk, std::chrono::seconds(30));
-    CPPUNIT_ASSERT(transferFinished);
-
-    CPPUNIT_ASSERT(compare(info.path, recvVcfPath));
-
-    // TODO FIX ME. The ICE take some time to stop and it doesn't seems to like
-    // when stopping the daemon and removing the accounts to soon.
-    std::remove(sendVcfPath.c_str());
-    std::remove(recvVcfPath.c_str());
-}
-
-void
-FileTransferTest::testDataTransferInfo()
-{
-    auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
-    auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
-    auto bobUri = bobAccount->getUsername();
-    auto aliceUri = aliceAccount->getUsername();
-
-    std::mutex mtx;
-    std::unique_lock<std::mutex> lk {mtx};
-    std::condition_variable cv;
-    std::condition_variable cv2;
-    std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> confHandlers;
-    bool transferWaiting = false, transferFinished = false;
-    std::string finalId;
-    // Watch signals
-    confHandlers.insert(libjami::exportable_callback<libjami::DataTransferSignal::DataTransferEvent>(
-        [&](const std::string& accountId,
-            const std::string&,
-            const std::string&,
-            const std::string& fileId,
-            int code) {
-            if (accountId == bobId
-                && code == static_cast<int>(libjami::DataTransferEventCode::wait_host_acceptance)) {
-                transferWaiting = true;
-                finalId = fileId;
-                cv.notify_one();
-            } else if (accountId == aliceId
-                       && code == static_cast<int>(libjami::DataTransferEventCode::finished)) {
-                transferFinished = true;
-                finalId = fileId;
-                cv.notify_one();
-            }
-        }));
-    libjami::registerSignalHandlers(confHandlers);
-
-    // Create file to send
-    std::ofstream sendFile(sendPath);
-    CPPUNIT_ASSERT(sendFile.is_open());
-    sendFile << std::string(64000, 'A');
-    sendFile.close();
-
-    // Send File
-    libjami::DataTransferInfo info;
-    uint64_t id;
-    info.accountId = aliceAccount->getAccountID();
-    info.peer = bobUri;
-    info.path = sendPath;
-    info.displayName = "SEND";
-    info.bytesProgress = 0;
-    CPPUNIT_ASSERT(libjami::sendFileLegacy(info, id) == libjami::DataTransferError::success);
-
-    cv.wait_for(lk, std::chrono::seconds(30));
-    CPPUNIT_ASSERT(transferWaiting);
-
-    CPPUNIT_ASSERT(libjami::dataTransferInfo(bobId, std::to_string(id), info)
-                   == libjami::DataTransferError::success);
-
-    CPPUNIT_ASSERT(info.lastEvent == libjami::DataTransferEventCode::wait_host_acceptance);
-    CPPUNIT_ASSERT(info.bytesProgress == 0);
-    CPPUNIT_ASSERT(info.totalSize == 64000);
-
-    CPPUNIT_ASSERT(libjami::dataTransferInfo(aliceId, std::to_string(id), info)
-                   == libjami::DataTransferError::success);
-
-    CPPUNIT_ASSERT(info.lastEvent == libjami::DataTransferEventCode::wait_peer_acceptance);
-    CPPUNIT_ASSERT(info.bytesProgress == 0);
-    CPPUNIT_ASSERT(info.totalSize == 64000);
-
-    CPPUNIT_ASSERT(libjami::acceptFileTransfer(bobId, finalId, recvPath)
-                   == libjami::DataTransferError::success);
-
-    // Wait 2 times, both sides will got a finished status
-    cv.wait_for(lk, std::chrono::seconds(30));
-    cv.wait_for(lk, std::chrono::seconds(30));
-    CPPUNIT_ASSERT(transferFinished);
-
-    CPPUNIT_ASSERT(compare(info.path, recvPath));
-
-    CPPUNIT_ASSERT(libjami::dataTransferInfo(bobId, std::to_string(id), info)
-                   == libjami::DataTransferError::success);
-
-    CPPUNIT_ASSERT(info.lastEvent == libjami::DataTransferEventCode::finished);
-    CPPUNIT_ASSERT(info.bytesProgress == 64000);
-    CPPUNIT_ASSERT(info.totalSize == 64000);
-
-    // TODO FIX ME. The ICE take some time to stop and it doesn't seems to like
-    // when stopping the daemon and removing the accounts to soon.
-    std::remove(sendPath.c_str());
-    std::remove(recvPath.c_str());
-}
-
-void
-FileTransferTest::testMultipleFileTransfer()
-{
-    auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
-    auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
-    auto bobUri = bobAccount->getUsername();
-    auto aliceUri = aliceAccount->getUsername();
-
-    std::mutex mtx;
-    std::unique_lock<std::mutex> lk {mtx};
-    std::condition_variable cv;
-    std::condition_variable cv2;
-    std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> confHandlers;
-    bool transferWaiting = false, transferFinished = false;
-    std::string finalId;
-    // Watch signals
-    confHandlers.insert(libjami::exportable_callback<libjami::DataTransferSignal::DataTransferEvent>(
-        [&](const std::string& accountId,
-            const std::string&,
-            const std::string&,
-            const std::string& fileId,
-            int code) {
-            if (accountId == bobId
-                && code == static_cast<int>(libjami::DataTransferEventCode::wait_host_acceptance)) {
-                transferWaiting = true;
-                finalId = fileId;
-                cv.notify_one();
-            } else if (accountId == aliceId
-                       && code == static_cast<int>(libjami::DataTransferEventCode::finished)) {
-                transferFinished = true;
-                finalId = fileId;
-                cv.notify_one();
-            }
-        }));
-    libjami::registerSignalHandlers(confHandlers);
-
-    // Create file to send
-    std::ofstream sendFile(sendPath);
-    CPPUNIT_ASSERT(sendFile.is_open());
-    sendFile << std::string(64000, 'A');
-    sendFile.close();
-    auto sendPath2 = std::filesystem::current_path().u8string() + DIR_SEPARATOR_CH + "SEND2";
-    std::ofstream sendFile2(sendPath2);
-    CPPUNIT_ASSERT(sendFile2.is_open());
-    sendFile2 << std::string(64000, 'B');
-    sendFile2.close();
-
-    // Send first File
-    libjami::DataTransferInfo info;
-    uint64_t id;
-    info.accountId = aliceAccount->getAccountID();
-    info.peer = bobUri;
-    info.path = sendPath;
-    info.displayName = "SEND";
-    info.bytesProgress = 0;
-    CPPUNIT_ASSERT(libjami::sendFileLegacy(info, id) == libjami::DataTransferError::success);
-
-    cv.wait_for(lk, std::chrono::seconds(30));
-    CPPUNIT_ASSERT(transferWaiting);
-    transferWaiting = false;
-
-    CPPUNIT_ASSERT(libjami::acceptFileTransfer(bobId, finalId, recvPath)
-                   == libjami::DataTransferError::success);
-
-    // Wait 2 times, both sides will got a finished status
-    cv.wait_for(lk, std::chrono::seconds(30));
-    cv.wait_for(lk, std::chrono::seconds(30));
-    CPPUNIT_ASSERT(transferFinished);
-
-    CPPUNIT_ASSERT(compare(info.path, recvPath));
-
-    // Send File
-    libjami::DataTransferInfo info2;
-    info2.accountId = aliceAccount->getAccountID();
-    info2.peer = bobUri;
-    info2.path = sendPath2;
-    info2.displayName = "SEND2";
-    info2.bytesProgress = 0;
-    CPPUNIT_ASSERT(libjami::sendFileLegacy(info2, id) == libjami::DataTransferError::success);
-
-    cv.wait_for(lk, std::chrono::seconds(30));
-    CPPUNIT_ASSERT(transferWaiting);
-
-    CPPUNIT_ASSERT(libjami::acceptFileTransfer(bobId, finalId, recv2Path)
-                   == libjami::DataTransferError::success);
-
-    // Wait 2 times, both sides will got a finished status
-    cv.wait_for(lk, std::chrono::seconds(30));
-    cv.wait_for(lk, std::chrono::seconds(30));
-    CPPUNIT_ASSERT(transferFinished);
-
-    CPPUNIT_ASSERT(compare(info2.path, recv2Path));
-
-    // TODO FIX ME. The ICE take some time to stop and it doesn't seems to like
-    // when stopping the daemon and removing the accounts to soon.
-    std::remove(sendPath.c_str());
-    std::remove(sendPath2.c_str());
-    std::remove(recvPath.c_str());
-    std::remove(recv2Path.c_str());
-}
-
 void
 FileTransferTest::testConversationFileTransfer()
 {
-- 
GitLab