From a0e3381bc2555ff2b244f3a3ac248ddd3c00cae0 Mon Sep 17 00:00:00 2001
From: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
Date: Thu, 5 Oct 2017 11:34:06 -0400
Subject: [PATCH] datatransfer: API proposal

This is a DRing API proposal (no implementation) to the data transfer
feature.

Change-Id: I3dd270ae910540b5aef1f3c15dc1b7b2966156c0
Reviewed-by: Olivier Soldano <olivier.soldano@savoirfairelinux.com>
---
 src/Makefile.am                    |   1 +
 src/dring/datatransfer_interface.h | 137 +++++++++++++++++++++++++++++
 2 files changed, 138 insertions(+)
 create mode 100644 src/dring/datatransfer_interface.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 679e2bc1ee..4d608b9f03 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -156,6 +156,7 @@ nobase_include_HEADERS= dring/dring.h \
 		dring/callmanager_interface.h \
 		dring/configurationmanager_interface.h \
 		dring/presencemanager_interface.h \
+		dring/datatransfer_interface.h \
 		dring/account_const.h \
 		dring/call_const.h \
 		dring/presence_const.h \
diff --git a/src/dring/datatransfer_interface.h b/src/dring/datatransfer_interface.h
new file mode 100644
index 0000000000..2fcdafb132
--- /dev/null
+++ b/src/dring/datatransfer_interface.h
@@ -0,0 +1,137 @@
+/*
+ *  Copyright (C) 2017 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.
+ */
+
+#ifndef DRING_DATATRANSFERI_H
+#define DRING_DATATRANSFERI_H
+
+#include "dring.h"
+
+#include <string>
+#include <map>
+#include <memory>
+#include <cstdlib> // std::size_t
+#include <ios> // std::streamsize
+
+namespace DRing {
+
+using DataTransferId = uint64_t;
+
+enum class DataTransferEventCode : uint32_t {
+    CREATED,
+    UNSUPPORTED,
+    WAIT_PEER_ACCEPTANCE,
+    WAIT_HOST_ACCEPTANCE,
+    ONGOING,
+    FINISHED,
+    CLOSED_BY_HOST,
+    CLOSED_BY_PEER,
+    INVALID_PATHNAME,
+    UNJOINABLE_PEER,
+};
+
+struct DataTransferInfo {
+    bool isOutgoing; ///< Outgoing or Incoming?
+    DataTransferEventCode lastEvent {DataTransferEventCode::CREATED}; ///< Latest event code sent to the user
+    std::string displayName; ///< Human oriented transfer name
+    std::size_t totalSize {0} ; ///< Total number of bytes to sent/receive, 0 if not known
+    std::streamsize bytesProgress {0}; ///< Number of bytes sent/received
+    std::string path; ///< associated local file path if supported (empty, if not)
+};
+
+/// Asynchronously send a file to a peer using given account connection.
+///
+/// If given account supports a file transfer protocol this function creates
+/// an internal data transfer and return its identification.
+/// This identity code is used by signals and APIs to follow the transfer progress.
+///
+/// \param account_id existing account ID with file transfer support
+/// \param peer_uri peer address suitable for the given account
+/// \param file_path pathname of file to transfer
+/// \param display_name optional textual representation given to the peer when the file is proposed.
+/// When empty (or not given), \a file_path is used.
+///
+/// \return DataTransferId value representing the internal transfer.
+///
+/// \exception std::invalid_argument not existing account
+/// \exception std::ios_base::failure file opening failures
+///
+/// \note If the account is valid but doesn't support file transfer, or if the peer is unjoignable,
+/// or at events during the transfer, the function returns a valid DataTransferId and the user
+/// will be signaled throught DataTransferEvent signal for such event.
+/// There is no reserved or special values on DataTransferId type.
+///
+DataTransferId sendFile(const std::string& account_id, const std::string& peer_uri,
+                        const std::string& file_path, const std::string& display_name={});
+
+/// 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.
+/// \param offset used to indicate the remote side about the number of bytes already received in
+/// a previous transfer session, usefull in transfer continuation mode.
+///
+void acceptFileTransfer(const DataTransferId& id, const std::string& file_path, std::size_t offset);
+
+/// Refuse or abort an outgoing or an incoming file transfer.
+///
+/// Use this function when you receive an incoming or when you want to abort an outgoing
+/// data transfer.
+/// The cancellation will occurs asynchronously, a cancel event will be generated when its effective.
+/// 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.
+///
+void cancelDataTransfer(const DataTransferId& id);
+
+/// Return some information on given data transfer.
+///
+/// \param id data transfer identification value as given by a DataTransferEvent signal.
+///
+/// \return transfer information.
+///
+DataTransferInfo dataTransferInfo(const DataTransferId& id);
+
+/// Return the amount of sent bytes of an existing data transfer.
+///
+/// \param id data transfer identification value as given by a DataTransferEvent signal.
+///
+/// \return number of successfuly transfered bytes.
+///
+std::streamsize dataTransferBytesSent(const DataTransferId& id);
+
+// Signal handlers registration
+void registerDataXferHandlers(const std::map<std::string, std::shared_ptr<CallbackWrapperBase>>&);
+
+// Signals
+struct DataTransferSignal {
+    struct DataTransferEvent {
+        constexpr static const char* name = "DataTransferEvent";
+        using cb_type = void(const DataTransferId& transferId, int eventCode);
+    };
+};
+
+} // namespace DRing
+
+#endif // DRING_DATATRANSFERI_H
-- 
GitLab