diff --git a/bin/jni/datatransfer.i b/bin/jni/datatransfer.i
new file mode 100644
index 0000000000000000000000000000000000000000..943ede67b5946a20fdd926bc9b445ce293309a49
--- /dev/null
+++ b/bin/jni/datatransfer.i
@@ -0,0 +1,66 @@
+/*
+ *  Copyright (C) 2004-2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
+ *  Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
+ *  Author: Pierre Duchemin <pierre.duchemin@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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+%apply int32_t { DRing::DataTransferEventCode };
+
+%header %{
+#include "dring/dring.h"
+#include "dring/datatransfer_interface.h"
+
+
+class DataTransferCallback {
+public:
+    virtual ~DataTransferCallback(){}
+    virtual void dataTransferEvent(const uint64_t transferId, int eventCode){}
+};
+%}
+
+%feature("director") DataTransferCallback;
+
+namespace DRing {
+
+  struct DataTransferInfo
+  {
+      bool isOutgoing;
+      DRing::DataTransferEventCode lastEvent;
+      std::size_t totalSize {0};
+      std::streamsize bytesProgress {0};
+      std::string displayName;
+      std::string path;
+      std::string accountId;
+      std::string peer;
+  };
+
+  void acceptFileTransfer(const uint64_t id, const std::string &file_path, std::size_t offset);
+  void cancelDataTransfer(const uint64_t id);
+  std::streamsize dataTransferBytesProgress(const uint64_t id);
+  DRing::DataTransferInfo dataTransferInfo(const uint64_t id);
+  /* std::vector<uint64_t> dataTransferList(); */
+  uint64_t sendFile(const std::string &account_id, const std::string &peer_uri, const std::string &file_path, const std::string &display_name) throw(std::invalid_argument, std::runtime_error);
+
+}
+
+class DataTransferCallback {
+public:
+    virtual ~DataTransferCallback(){}
+    virtual void dataTransferEvent(const uint64_t transferId, int eventCode){}
+};
diff --git a/bin/jni/jni_interface.i b/bin/jni/jni_interface.i
index f25252dad8e72627fab165477987b5d86f1ddc04..35aecf365af12f3be2b269ece279967d3a6711f7 100644
--- a/bin/jni/jni_interface.i
+++ b/bin/jni/jni_interface.i
@@ -52,8 +52,24 @@
     return $jnicall;
 }
 
+/* Maps exceptions */
+%typemap(throws, throws="java.lang.IllegalArgumentException") std::invalid_argument {
+  jclass excep = jenv->FindClass("java/lang/IllegalArgumentException");
+  if (excep)
+    jenv->ThrowNew(excep, $1.what().c_str());
+  return $null;
+}
+%typemap(throws, throws="java.lang.IllegalStateException") std::runtime_error {
+  jclass excep = jenv->FindClass("java/lang/IllegalStateException");
+  if (excep)
+    jenv->ThrowNew(excep, $1.what().c_str());
+  return $null;
+}
+
 /* Avoid uint64_t to be converted to BigInteger */
 %apply int64_t { uint64_t };
+%apply int64_t { const uint64_t };
+%apply int64_t { std::streamsize };
 %apply uint64_t { time_t };
 
 namespace std {
@@ -180,6 +196,7 @@ namespace std {
 %include "managerimpl.i"
 %include "callmanager.i"
 %include "configurationmanager.i"
+%include "datatransfer.i"
 %include "presencemanager.i"
 %include "videomanager.i"
 
@@ -197,6 +214,8 @@ void init(ConfigurationCallback* confM, Callback* callM, PresenceCallback* presM
     using DRing::exportable_callback;
     using DRing::CallSignal;
     using DRing::ConfigurationSignal;
+    using DRing::DataTransferInfo;
+    using DRing::DataTransferSignal;
     using DRing::PresenceSignal;
     using DRing::VideoSignal;
 
@@ -258,6 +277,9 @@ void init(ConfigurationCallback* confM, Callback* callM, PresenceCallback* presM
         exportable_callback<PresenceSignal::SubscriptionStateChanged>(bind(&PresenceCallback::subscriptionStateChanged, presM, _1, _2, _3 ))
     };
 
+    const std::map<std::string, SharedCallback> dataTransferEvHandlers = {
+    };
+
     const std::map<std::string, SharedCallback> videoEvHandlers = {
         exportable_callback<VideoSignal::GetCameraInfo>(bind(&VideoCallback::getCameraInfo, videoM, _1, _2, _3, _4)),
         exportable_callback<VideoSignal::SetParameters>(bind(&VideoCallback::setParameters, videoM, _1, _2, _3, _4, _5)),
@@ -273,6 +295,7 @@ void init(ConfigurationCallback* confM, Callback* callM, PresenceCallback* presM
     registerCallHandlers(callEvHandlers);
     registerConfHandlers(configEvHandlers);
     registerPresHandlers(presenceEvHandlers);
+    registerDataXferHandlers(dataTransferEvHandlers);
     registerVideoHandlers(videoEvHandlers);
 
     DRing::start();