syncevolution/src/dbus/server/session-common.h

278 lines
9.5 KiB
C++

/*
* Copyright (C) 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef SESSION_COMMON_H
#define SESSION_COMMON_H
#include "source-status.h"
#include "source-progress.h"
#include <syncevo/util.h>
#include <syncevo/DBusTraits.h>
#include <syncevo/FilterConfigNode.h>
#include <syncevo/SynthesisEngine.h>
#include <gdbus-cxx-bridge.h>
SE_BEGIN_CXX
/**
* This namespace holds constants and defines for Sessions and its
* consumers.
*/
namespace SessionCommon
{
const char * const SERVICE_NAME = "org.syncevolution";
const char * const CONNECTION_PATH = "/org/syncevolution/Connection";
const char * const CONNECTION_IFACE = "org.syncevolution.Connection";
const char * const SESSION_PATH = "/org/syncevolution/Session";
const char * const SESSION_IFACE = "org.syncevolution.Session";
const char * const SERVER_PATH = "/org/syncevolution/Server";
const char * const SERVER_IFACE = "org.syncevolution.Server";
const char * const HELPER_PATH = "/dbushelper";
const char * const HELPER_IFACE = "org.syncevolution.Helper";
const char * const HELPER_DESTINATION = "direct.peer"; // doesn't matter, routing is off
/**
* The operation running inside the session.
*/
enum RunOperation {
OP_SYNC, /**< running a sync */
OP_RESTORE, /**< restoring data */
OP_CMDLINE, /**< executing command line */
OP_NULL /**< idle, accepting commands via D-Bus */
};
inline std::string runOpToString(RunOperation op) {
static const char * const strings[] = {
"sync",
"restore",
"cmdline"
};
return op >= OP_SYNC && op <= OP_CMDLINE ?
strings[op] :
"";
}
/**
* Used by both Connection class (inside server) and
* DBusTransportAgent (inside helper).
*/
enum ConnectionState {
SETUP, /**< ready for first message */
PROCESSING, /**< received message, waiting for engine's reply */
WAITING, /**< waiting for next follow-up message */
FINAL, /**< engine has sent final reply, wait for ACK by peer */
DONE, /**< peer has closed normally after the final reply */
FAILED /**< in a failed state, no further operation possible */
};
/** maps to names for debugging */
inline std::string ConnectionStateToString(ConnectionState state)
{
static const char * const strings[] = {
"SETUP",
"PROCESSING",
"WAITING",
"FINAL",
"DONE",
"FAILED"
};
return state >= SETUP && state <= FAILED ?
strings[state] :
"???";
}
typedef StringMap SourceModes_t;
typedef std::map<std::string, SyncEvo::FilterConfigNode::ConfigFilter> SourceFilters_t;
/**
* all the information that syncevo-dbus-server needs to
* send to syncevo-dbus-helper before the latter can
* run a sync
*/
struct SyncParams
{
SyncParams() :
m_serverMode(false),
m_serverAlerted(false),
m_remoteInitiated(false)
{}
std::string m_config;
std::string m_mode;
SourceModes_t m_sourceModes;
bool m_serverMode;
bool m_serverAlerted;
bool m_remoteInitiated;
std::string m_sessionID;
SharedBuffer m_initialMessage;
std::string m_initialMessageType;
SyncEvo::FilterConfigNode::ConfigFilter m_syncFilter;
SyncEvo::FilterConfigNode::ConfigFilter m_sourceFilter;
SourceFilters_t m_sourceFilters;
};
}
SE_END_CXX
namespace GDBusCXX {
using namespace SyncEvo::SessionCommon;
using namespace SyncEvo;
template<> struct dbus_traits<SyncParams> :
public dbus_struct_traits<SyncParams,
dbus_member<SyncParams, std::string, &SyncParams::m_config,
dbus_member<SyncParams, std::string, &SyncParams::m_mode,
dbus_member<SyncParams, SourceModes_t, &SyncParams::m_sourceModes,
dbus_member<SyncParams, bool, &SyncParams::m_serverMode,
dbus_member<SyncParams, bool, &SyncParams::m_serverAlerted,
dbus_member<SyncParams, bool, &SyncParams::m_remoteInitiated,
dbus_member<SyncParams, std::string, &SyncParams::m_sessionID,
dbus_member<SyncParams, SharedBuffer, &SyncParams::m_initialMessage,
dbus_member<SyncParams, std::string, &SyncParams::m_initialMessageType,
dbus_member<SyncParams, FilterConfigNode::ConfigFilter, &SyncParams::m_syncFilter,
dbus_member<SyncParams, FilterConfigNode::ConfigFilter, &SyncParams::m_sourceFilter,
dbus_member_single<SyncParams, SourceFilters_t, &SyncParams::m_sourceFilters
> > > > > > > > > > > > >
{};
/**
* Similar to DBusArray<uint8_t>, but with different native
* types. Uses encoding/decoding from the base class, copies
* to/from SharedBuffer as needed.
*
* DBusArray<uint8_t> is more efficient because it avoids
* copying the bytes from the D-Bus message when decoding,
* but it is harder to use natively (cannot be copied).
* SharedBuffer does ref counting for the memory chunk,
* so once initialized, copying it is cheap.
*/
template <> struct dbus_traits<SharedBuffer> :
public dbus_traits< DBusArray<uint8_t> >
{
typedef dbus_traits< DBusArray<uint8_t> > base;
typedef SharedBuffer host_type;
typedef const SharedBuffer &arg_type;
#ifdef GDBUS_CXX_GIO
static void get(GDBusCXX::ExtractArgs &context,
GDBusCXX::reader_type &iter, host_type &buffer)
{
base::host_type array;
base::get(context, iter, array);
buffer = SharedBuffer(reinterpret_cast<const char *>(array.second), array.first);
}
#else
static void get(GDBusCXX::connection_type *conn, GDBusCXX::message_type *msg,
GDBusCXX::reader_type &iter, host_type &buffer)
{
base::host_type array;
base::get(conn, msg, iter, array);
buffer = SharedBuffer(reinterpret_cast<const char *>(array.second), array.first);
}
#endif
static void append(GDBusCXX::builder_type &builder, arg_type buffer)
{
base::host_type array(buffer.size(), reinterpret_cast<const uint8_t *>(buffer.get()));
base::append(builder, array);
}
};
template <> struct dbus_traits<SyncReport> :
public dbus_traits< std::string >
{
typedef dbus_traits< std::string > base;
typedef SyncReport host_type;
typedef const SyncReport &arg_type;
#ifdef GDBUS_CXX_GIO
static void get(GDBusCXX::ExtractArgs &context,
GDBusCXX::reader_type &iter, host_type &report)
{
std::string dump;
base::get(context, iter, dump);
report = SyncReport(dump);
}
#else
static void get(GDBusCXX::connection_type *conn, GDBusCXX::message_type *msg,
GDBusCXX::reader_type &iter, host_type &report)
{
std::string dump;
base::get(conn, msg, iter, dump);
report = SyncReport(dump);
}
#endif
static void append(GDBusCXX::builder_type &builder, arg_type report)
{
base::append(builder, report.toString());
}
};
template <> struct dbus_traits<SyncSourceReport> :
public dbus_traits< std::string >
{
typedef dbus_traits< std::string > base;
typedef SyncSourceReport host_type;
typedef const SyncSourceReport &arg_type;
#ifdef GDBUS_CXX_GIO
static void get(GDBusCXX::ExtractArgs &context,
GDBusCXX::reader_type &iter, host_type &source)
{
std::string dump;
base::get(context, iter, dump);
SyncReport report = SyncReport(dump);
const SyncSourceReport *foo = report.findSyncSourceReport("foo");
if (!foo) {
SE_THROW("incomplete SyncReport");
}
source = *foo;
}
#else
static void get(GDBusCXX::connection_type *conn, GDBusCXX::message_type *msg,
GDBusCXX::reader_type &iter, host_type &source)
{
std::string dump;
base::get(conn, msg, iter, dump);
SyncReport report = SyncReport(dump);
const SyncSourceReport *foo = report.findSyncSourceReport("foo");
if (!foo) {
SE_THROW("incomplete SyncReport");
}
source = *foo;
}
#endif
static void append(GDBusCXX::builder_type &builder, arg_type source)
{
SyncReport report;
report.addSyncSourceReport("foo", source);
base::append(builder, report.toString());
}
};
}
#endif // SESSION_COMMON_H