summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Repository.mk1
-rw-r--r--RepositoryExternal.mk28
-rw-r--r--RepositoryModule_ooo.mk1
-rw-r--r--config_host.mk.in3
-rw-r--r--configure.in30
-rw-r--r--tubes/CppunitTest_tubes_test.mk45
-rw-r--r--tubes/Library_tubes.mk63
-rw-r--r--tubes/Makefile7
-rw-r--r--tubes/Module_tubes.mk38
-rw-r--r--tubes/README33
-rw-r--r--tubes/inc/tubes/conference.hxx104
-rw-r--r--tubes/inc/tubes/manager.hxx213
-rw-r--r--tubes/inc/tubes/packet.hxx69
-rw-r--r--tubes/inc/tubes/tubesdllapi.h16
-rw-r--r--tubes/prj/build.lst2
-rw-r--r--tubes/prj/d.lst0
-rw-r--r--tubes/prj/makefile.mk1
-rw-r--r--tubes/qa/test_manager.cxx188
-rw-r--r--tubes/source/conference.cxx384
-rw-r--r--tubes/source/manager.cxx668
-rw-r--r--tubes/source/packet.cxx33
21 files changed, 1927 insertions, 0 deletions
diff --git a/Repository.mk b/Repository.mk
index 7e34039348e4..558998a3c63b 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -361,6 +361,7 @@ $(eval $(call gb_Helper_register_libraries,OOOLIBS, \
textfd \
tk \
tl \
+ tubes \
unordf \
unoxml \
updatecheckui \
diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index bdc5cdffc1d2..8a2c88d91446 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -1086,6 +1086,34 @@ $(call gb_LinkTarget_add_libs,$(1),$(DBUSMENUGTK_LIBS))
endef
+
+ifeq ($(ENABLE_TELEPATHY),TRUE)
+
+define gb_LinkTarget__use_telepathy
+$(call gb_LinkTarget_set_include,$(1),\
+ $$(INCLUDE) \
+ $(TELEPATHY_CFLAGS) \
+)
+
+$(call gb_LinkTarget_add_defs,$(1),\
+ -DENABLE_TELEPATHY \
+)
+
+$(call gb_LinkTarget_add_libs,$(1),\
+ $(TELEPATHY_LIBS) \
+)
+
+endef
+
+else # !ENABLE_TELEPATHY
+
+define gb_LinkTarget__use_telepathy
+
+endef
+
+endif # ENABLE_TELEPATHY
+
+
ifeq ($(SYSTEM_DB),YES)
define gb_LinkTarget__use_berkeleydb
diff --git a/RepositoryModule_ooo.mk b/RepositoryModule_ooo.mk
index 6d879c6b849c..f8ce7f5801b2 100644
--- a/RepositoryModule_ooo.mk
+++ b/RepositoryModule_ooo.mk
@@ -137,6 +137,7 @@ $(eval $(call gb_Module_add_moduledirs,ooo,\
$(if $(filter TRANSLATIONS,$(BUILD_TYPE)),\
translations \
) \
+ tubes \
twain \
ucb \
ucbhelper \
diff --git a/config_host.mk.in b/config_host.mk.in
index 4b4bd29bb1ec..1f78bf66a0e0 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -145,6 +145,7 @@ export ENABLE_SCRIPTING_PYTHON=@ENABLE_SCRIPTING_PYTHON@
export ENABLE_SILENT_MSI=@ENABLE_SILENT_MSI@
export ENABLE_SYMBOLS=@ENABLE_SYMBOLS@
export ENABLE_SYSTRAY_GTK=@ENABLE_SYSTRAY_GTK@
+export ENABLE_TELEPATHY=@ENABLE_TELEPATHY@
export ENABLE_XMLSEC=@ENABLE_XMLSEC@
export ENABLE_ZENITY=@ENABLE_ZENITY@
export EPM=@EPM@
@@ -545,6 +546,8 @@ export SYSTEM_STDLIBS=@SYSTEM_STDLIBS@
export SYSTEM_VIGRA=@SYSTEM_VIGRA@
export SYSTEM_ZLIB=@SYSTEM_ZLIB@
export TARFILE_LOCATION=@TARFILE_LOCATION@
+export TELEPATHY_CFLAGS=@TELEPATHY_CFLAGS@
+export TELEPATHY_LIBS=@TELEPATHY_LIBS@
export THES_SYSTEM_DIR=@THES_SYSTEM_DIR@
@x_Cygwin@ export TMP=@TMP_DIRECTORY@
export TMPDIR=@TEMP_DIRECTORY@
diff --git a/configure.in b/configure.in
index d5a75ae6e609..2225a0951a0c 100644
--- a/configure.in
+++ b/configure.in
@@ -789,6 +789,11 @@ AC_ARG_ENABLE(gio,
[Determines whether to use the GIO support.]),
,enable_gio=no)
+AC_ARG_ENABLE(telepathy,
+ AS_HELP_STRING([--enable-telepathy],
+ [Determines whether to enable Telepathy for collaboration.]),
+,enable_telepathy=no)
+
AC_ARG_ENABLE(build-mozilla,
AS_HELP_STRING([--disable-build-mozilla],
[Use this option if you do not want to build the Mozilla components from
@@ -8949,6 +8954,31 @@ AC_SUBST([ENABLE_GTK_PRINT])
AC_SUBST([GTK_PRINT_CFLAGS])
AC_SUBST([GTK_PRINT_LIBS])
+
+dnl ===================================================================
+dnl Check whether the Telepathy libraries are available.
+dnl ===================================================================
+
+ENABLE_TELEPATHY=""
+TELEPATHY_CFLAGS=""
+TELEPATHY_LIBS=""
+
+AC_MSG_CHECKING([whether to enable Telepathy support])
+if test "$_os" != "WINNT" -a "$_os" != "Darwin" -a "$enable_telepathy" = "yes"; then
+ ENABLE_TELEPATHY="TRUE"
+ AC_MSG_RESULT([yes])
+ PKG_CHECK_MODULES( TELEPATHY, telepathy-glib >= 0.16.4 )
+else
+ AC_MSG_RESULT([no])
+fi
+
+AC_SUBST(ENABLE_TELEPATHY)
+AC_SUBST(TELEPATHY_CFLAGS)
+AC_SUBST(TELEPATHY_LIBS)
+
+
+dnl ===================================================================
+
PKG_CHECK_MODULES( LIBPNG, libpng, ENABLE_QUICKSTART_LIBPNG="TRUE", ENABLE_QUICKSTART_LIBPNG="" )
AC_SUBST(LIBPNG_LIBS)
AC_SUBST(LIBPNG_CFLAGS)
diff --git a/tubes/CppunitTest_tubes_test.mk b/tubes/CppunitTest_tubes_test.mk
new file mode 100644
index 000000000000..32810f9739f4
--- /dev/null
+++ b/tubes/CppunitTest_tubes_test.mk
@@ -0,0 +1,45 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License or as specified alternatively below. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# Major Contributor(s):
+# Copyright (C) 2012 Red Hat, Inc., Eike Rathke <erack@redhat.com>
+#
+# All Rights Reserved.
+#
+# For minor contributions see the git repository.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+
+$(eval $(call gb_CppunitTest_CppunitTest,tubes_test))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,tubes_test, \
+ tubes/qa/test_manager \
+))
+
+$(eval $(call gb_CppunitTest_add_linked_libs,tubes_test, \
+ tubes \
+ sal \
+ $(gb_STDLIBS) \
+))
+
+$(eval $(call gb_CppunitTest_set_include,tubes_test,\
+ -I$(realpath $(SRCDIR)/tubes/inc) \
+ $$(TELEPATHY_CFLAGS) \
+ $$(INCLUDE) \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/tubes/Library_tubes.mk b/tubes/Library_tubes.mk
new file mode 100644
index 000000000000..2ab261644932
--- /dev/null
+++ b/tubes/Library_tubes.mk
@@ -0,0 +1,63 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License or as specified alternatively below. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# Major Contributor(s):
+# Copyright (C) 2012 Red Hat, Inc., Eike Rathke <erack@redhat.com>
+#
+# All Rights Reserved.
+#
+# For minor contributions see the git repository.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+
+$(eval $(call gb_Library_Library,tubes))
+
+$(eval $(call gb_Library_set_include,tubes,\
+ -I$(realpath $(SRCDIR)/tubes/inc) \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_add_defs,tubes,\
+ -DTUBES_DLLIMPLEMENTATION \
+))
+
+$(eval $(call gb_Library_add_cxxflags,tubes,\
+ $$(TELEPATHY_CFLAGS) \
+))
+
+$(eval $(call gb_Library_add_libs,tubes,\
+ $$(TELEPATHY_LIBS) \
+))
+
+$(eval $(call gb_Library_add_linked_libs,tubes,\
+ $(gb_STDLIBS) \
+ sal \
+ salhelper \
+))
+
+$(eval $(call gb_Library_use_externals,tubes,\
+ telepathy \
+))
+
+$(eval $(call gb_Library_add_exception_objects,tubes,\
+ tubes/source/conference \
+ tubes/source/manager \
+ tubes/source/packet \
+))
+
+# vim:set shiftwidth=4 tabstop=4 noexpandtab: */
diff --git a/tubes/Makefile b/tubes/Makefile
new file mode 100644
index 000000000000..ccb1c85a04da
--- /dev/null
+++ b/tubes/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/tubes/Module_tubes.mk b/tubes/Module_tubes.mk
new file mode 100644
index 000000000000..ce810e1a12f3
--- /dev/null
+++ b/tubes/Module_tubes.mk
@@ -0,0 +1,38 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License or as specified alternatively below. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# Major Contributor(s):
+# Copyright (C) 2012 Red Hat, Inc., Eike Rathke <erack@redhat.com>
+#
+# All Rights Reserved.
+#
+# For minor contributions see the git repository.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+
+$(eval $(call gb_Module_Module,tubes))
+
+$(eval $(call gb_Module_add_targets,tubes,\
+ Library_tubes \
+))
+
+$(eval $(call gb_Module_add_check_targets,tubes,\
+ CppunitTest_tubes_test \
+))
+
+# vim:set shiftwidth=4 tabstop=4 noexpandtab: */
diff --git a/tubes/README b/tubes/README
new file mode 100644
index 000000000000..ca8764f87707
--- /dev/null
+++ b/tubes/README
@@ -0,0 +1,33 @@
+Interface to Telepathy Tubes.
+
+To enable configure LibO with --enable-telepathy
+
+Status 2012-03-16:
+
+* no LibO code depends on this module yet, so it is not built in a regular
+ build, even if configured with --enable-telepathy, so cd tubes and make here
+ * to enable the various SAL_INFO and SAL_WARN messages emitted during
+ cppunittest pass SAL_LOG=... and do a debug build
+ * SAL_LOG="+WARN+INFO.tubes" make -rs debug=true
+ * the cppunittest will currently fail anyway (even if it wouldn't for other
+ reasons), this is on purpose to be able to see the output as otherwise it
+ is silenced down ... :-(
+
+* for the cppunittest needed:
+ * a jabber daemon running on localhost.localdomain
+ * two accounts configured in Empathy
+ * libo1@localhost.localdomain
+ * libo2@localhost.localdomain
+ * libo1 and libo2 must be contacts/buddies of each other
+ * both accounts need to be online in Empathy
+
+* very nasty GMainLoop handling for cppunittest, MAYBE we could get rid of
+ that in a real LibO, this might be responsible for some ugly behaviour
+* contact channels seem to be successfully setup
+* the client's callback TeleManager_DBusChannelHandler setup with
+ TeleManager::connect() does not appear to get ever called
+* hence the tube offer triggered by TeleManager_ChannelReadyHandler is never
+ accepted
+* unsure if the uniquify setup with tp_simple_handler_new_with_factory() would
+ work at all, hence trying to have one instance un-uniquified, but to no
+ avail
diff --git a/tubes/inc/tubes/conference.hxx b/tubes/inc/tubes/conference.hxx
new file mode 100644
index 000000000000..db78cd5e80aa
--- /dev/null
+++ b/tubes/inc/tubes/conference.hxx
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2012 Red Hat, Inc., Eike Rathke <erack@redhat.com>
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef INCLUDED_TUBES_CONFERENCE_HXX
+#define INCLUDED_TUBES_CONFERENCE_HXX
+
+#include <sal/config.h>
+#include "tubes/packet.hxx"
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <telepathy-glib/telepathy-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <queue>
+
+typedef ::std::queue<TelePacket> TelePacketQueue;
+
+class TeleManager;
+
+/** Conference setup by TeleManager */
+class TeleConference : public boost::enable_shared_from_this<TeleConference>
+{
+public:
+
+ TeleConference( TeleManager* pManager, TpChannel* pChannel, const rtl::OString& rSessionId );
+ ~TeleConference();
+
+ /// Close channel and call finalize()
+ void close();
+
+ /// Unrefs, unregisters from manager and calls dtor if last reference!
+ void finalize();
+
+ TeleManager* getManager() const { return mpManager; }
+
+ /** @param rPacket
+ non-const on purpose, see TelePacket::getData()
+ */
+ bool sendPacket( TelePacket& rPacket ) const;
+
+ /** Queue incoming data as TelePacket */
+ void queue( const char* pDBusSender, const char* pPacket, int nSize );
+
+ // --- following only to be called only by manager's callbacks ---
+ // TODO: make friends instead
+
+ /// "buddy@jabber.example.org" or "room@conference.example.org" or "UUID"
+ void setTarget( const rtl::OString& rTarget );
+ void setChannel( TpChannel* pChannel );
+ TpChannel* getChannel() const { return mpChannel; }
+ bool offerTube();
+ bool setTube( DBusConnection* pTube );
+ bool acceptTube( const char* pAddress );
+
+ // Only for callbacks.
+ void setTubeOfferedHandlerInvoked( bool b ) { mbTubeOfferedHandlerInvoked = b; }
+ bool isTubeOfferedHandlerInvoked() const { return mbTubeOfferedHandlerInvoked; }
+
+private:
+
+ rtl::OString maTarget;
+ rtl::OString maSessionId;
+ TeleManager* mpManager;
+ TpChannel* mpChannel;
+ DBusConnection* mpTube;
+ TelePacketQueue maPacketQueue;
+
+ bool mbTubeOfferedHandlerInvoked : 1;
+
+ // hide from the public
+ using boost::enable_shared_from_this<TeleConference>::shared_from_this;
+
+};
+
+
+typedef boost::shared_ptr<TeleConference> TeleConferencePtr;
+
+#endif // INCLUDED_TUBES_CONFERENCE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tubes/inc/tubes/manager.hxx b/tubes/inc/tubes/manager.hxx
new file mode 100644
index 000000000000..b47455a78ea0
--- /dev/null
+++ b/tubes/inc/tubes/manager.hxx
@@ -0,0 +1,213 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2012 Red Hat, Inc., Eike Rathke <erack@redhat.com>
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef INCLUDED_TUBES_MANAGER_HXX
+#define INCLUDED_TUBES_MANAGER_HXX
+
+#include <sal/config.h>
+#include "tubes/tubesdllapi.h"
+#include "tubes/conference.hxx"
+#include "tubes/packet.hxx"
+#include <rtl/ustring.hxx>
+#include <salhelper/thread.hxx>
+#include <rtl/ref.hxx>
+#include <telepathy-glib/telepathy-glib.h>
+#include <vector>
+
+// For testing purposes, we might need more in future.
+#define LIBO_TUBES_DBUS_MSG_METHOD "LibOMsg"
+
+typedef ::std::vector<TeleConferencePtr> TeleConferenceVector;
+
+
+/** Interface to Telepathy DBus Tubes.
+
+ Fragile, not working yet.
+
+ Accounts need to have been setup within Empathy already.
+ */
+
+/* FIXME: selective dllprivate methods */
+class TUBES_DLLPUBLIC TeleManager
+{
+public:
+
+ enum AccountManagerStatus
+ {
+ AMS_UNINITIALIZED = 0,
+ AMS_INPREPARATION,
+ AMS_UNPREPARABLE,
+ AMS_PREPARED
+ };
+
+ /** Prepare tube manager with account and service to be offered/listened
+ to.
+
+ @param rAccount
+ The account (JID) to use. This must be a valid JID that has been
+ setup with Empathy or another Telepathy client providing
+ Jabber/XMPP.
+
+ @param rService
+ "WhatEver", is prepended with "...LibreOffice"
+
+ @param bCreateOwnGMainLoop
+ Whether to create and iterate an own GMainLoop. For testing
+ purposes when no GMainLoop is available.
+ */
+ TeleManager( const rtl::OUString& rAccount, const rtl::OUString& rService, bool bCreateOwnGMainLoop = false );
+ ~TeleManager();
+
+ /** Prepare the Telepathy Account Manager.
+
+ Invokes an async call that is not ready until meAccountManagerStatus is
+ set! Until that is AMS_PREPARED nothing else will work.
+
+ TODO: this needs some signalling mechanism
+ */
+ void prepareAccountManager();
+ AccountManagerStatus getAccountManagerStatus() const
+ {
+ return meAccountManagerStatus;
+ }
+
+ /** Start a group session in a MUC.
+
+ @param rConferenceRoom
+ The MUC to be created/joined, e.g. "LibreOffice". If empty, the
+ conference's UUID is used.
+
+ @param rConferenceServer
+ Server to create the MUC on, e.g. "conference.example.org". If
+ empty, only the conference's UUID is used and rConferenceRoom is
+ ignored, hopefully resulting in a local DBus tube.
+ */
+ bool startGroupSession( const rtl::OUString& rConferenceRoom,
+ const rtl::OUString& rConferenceServer );
+
+ /** Start a session with a buddy.
+
+ @param rBuddy
+ The buddy to be connected.
+ */
+ bool startBuddySession( const rtl::OUString& rBuddy );
+
+ void unregisterConference( TeleConferencePtr pConference );
+ bool connect();
+ void disconnect();
+ void acceptTube( TpChannel* pChannel, const char* pAddress );
+
+ /** Only the callback of prepareAccountManager() is to set this. */
+ void setAccountManagerReady( bool bPrepared);
+
+ /** Send data to all registered conferences. */
+ bool sendPacket( const TelePacket& rPacket ) const;
+
+ /// "org.freedesktop.Telepathy.Client.LibreOfficeWhatEver"
+ rtl::OString getFullServiceName() const;
+
+ /// "/org/freedesktop/Telepathy/Client/LibreOfficeWhatEver"
+ rtl::OString getFullObjectPath() const;
+
+ /// Only for use with MainLoopFlusher
+ GMainLoop* getMainLoop() const { return mpLoop; }
+
+ GMainContext* getMainContext() const { return (mpLoop ? g_main_loop_get_context( mpLoop) : NULL); }
+
+ static rtl::OString createUuid();
+
+
+ // Only for callbacks.
+ void setChannelReadyHandlerInvoked( bool b ) { mbChannelReadyHandlerInvoked = b; }
+ bool isChannelReadyHandlerInvoked() const { return mbChannelReadyHandlerInvoked; }
+ void setAccountManagerReadyHandlerInvoked( bool b ) { mbAccountManagerReadyHandlerInvoked = b; }
+ bool isAccountManagerReadyHandlerInvoked() const { return mbAccountManagerReadyHandlerInvoked; }
+
+ typedef bool (TeleManager::*CallBackInvokedFunc)() const;
+ /** Iterate our GMainLoop, blocking, until the callback is done. */
+ void iterateLoop( CallBackInvokedFunc pFunc );
+
+ typedef bool (TeleConference::*ConferenceCallBackInvokedFunc)() const;
+ /** Iterate our GMainLoop, blocking, until the callback is done. */
+ void iterateLoop( const TeleConference* pConference, ConferenceCallBackInvokedFunc pFunc );
+
+ /** Iterate our GMainLoop, non-blocking, until nothing pending. */
+ void flushLoop() const;
+
+private:
+
+ rtl::OString maAccountID;
+ rtl::OString maService; // the "WhatEver" part
+ TeleConferenceVector maConferences;
+ GMainLoop* mpLoop;
+ TpDBusDaemon* mpDBus;
+ TpAccountManager* mpAccountManager;
+ TpAccount* mpAccount;
+ TpConnection* mpConnection;
+ TpBaseClient* mpClient;
+ AccountManagerStatus meAccountManagerStatus;
+
+ bool mbChannelReadyHandlerInvoked : 1;
+ bool mbAccountManagerReadyHandlerInvoked : 1;
+
+ TpAccount* getMyAccount();
+
+};
+
+
+/** The most ugly workaround for not having a GMainLoop running, i.e. in
+ cppunittest.
+ */
+class MainLoopFlusher
+{
+public:
+ explicit MainLoopFlusher( const TeleManager* pManager )
+ :
+ mpManager( pManager)
+ {
+ flush();
+ }
+
+ ~MainLoopFlusher()
+ {
+ flush();
+ }
+
+ void flush() const
+ {
+ mpManager->flushLoop();
+ }
+
+private:
+ const TeleManager* mpManager;
+};
+
+
+#endif // INCLUDED_TUBES_MANAGER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tubes/inc/tubes/packet.hxx b/tubes/inc/tubes/packet.hxx
new file mode 100644
index 000000000000..f357782aff66
--- /dev/null
+++ b/tubes/inc/tubes/packet.hxx
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2012 Red Hat, Inc., Eike Rathke <erack@redhat.com>
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef INCLUDED_TUBES_PACKET_HXX
+#define INCLUDED_TUBES_PACKET_HXX
+
+#include <sal/config.h>
+#include <rtl/string.hxx>
+#include <rtl/byteseq.hxx>
+
+
+class TelePacket
+{
+public:
+
+ TelePacket( const char* pSender, const char* pData, int nSize )
+ :
+ maSender( pSender),
+ maData( reinterpret_cast<const sal_Int8*>(pData), static_cast<sal_Int32>(nSize) )
+ {
+ }
+
+ TelePacket( const TelePacket& r )
+ :
+ maSender( r.maSender),
+ maData( r.maData)
+ {
+ }
+
+ /** Underlying getArray() ensures reference count is exactly one, hence
+ this method is non-const! */
+ const char* getData() { return reinterpret_cast<const char*>( maData.getArray()); }
+ sal_Int32 getSize() const { return maData.getLength(); }
+
+private:
+
+ rtl::OString maSender;
+ rtl::ByteSequence maData;
+
+};
+
+#endif // INCLUDED_TUBES_PACKET_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tubes/inc/tubes/tubesdllapi.h b/tubes/inc/tubes/tubesdllapi.h
new file mode 100644
index 000000000000..ea1b70770277
--- /dev/null
+++ b/tubes/inc/tubes/tubesdllapi.h
@@ -0,0 +1,16 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#ifndef INCLUDED_TUBESDLLAPI_H
+#define INCLUDED_TUBESDLLAPI_H
+
+#include "sal/types.h"
+
+#if defined(TUBES_DLLIMPLEMENTATION)
+#define TUBES_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
+#else
+#define TUBES_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
+#endif
+#define TUBES_DLLPRIVATE SAL_DLLPRIVATE
+
+#endif /* INCLUDED_TUBESDLLAPI_H */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tubes/prj/build.lst b/tubes/prj/build.lst
new file mode 100644
index 000000000000..5995a896dfcf
--- /dev/null
+++ b/tubes/prj/build.lst
@@ -0,0 +1,2 @@
+tubes tubes : solenv TELEPATHY:telepathy sal NULL
+tubes tubes\prj nmake - all tubes_prj NULL
diff --git a/tubes/prj/d.lst b/tubes/prj/d.lst
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tubes/prj/d.lst
diff --git a/tubes/prj/makefile.mk b/tubes/prj/makefile.mk
new file mode 100644
index 000000000000..0997622e00f6
--- /dev/null
+++ b/tubes/prj/makefile.mk
@@ -0,0 +1 @@
+.INCLUDE : gbuildbridge.mk
diff --git a/tubes/qa/test_manager.cxx b/tubes/qa/test_manager.cxx
new file mode 100644
index 000000000000..acf3da64bd78
--- /dev/null
+++ b/tubes/qa/test_manager.cxx
@@ -0,0 +1,188 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2012 Red Hat, Inc., Eike Rathke <erack@redhat.com>
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#include <sal/precppunit.hxx>
+
+#include <tubes/manager.hxx>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+
+namespace {
+
+class TestTeleTubes: public CppUnit::TestFixture
+{
+public:
+
+ TestTeleTubes();
+ ~TestTeleTubes();
+ void testSetupManager1();
+ void testSetupManager2();
+ void testConnect1();
+ void testConnect2();
+ void testPrepareAccountManager1();
+ void testPrepareAccountManager2();
+ void testStartBuddySession1();
+ void testStartBuddySession2();
+ void testSendPacket();
+ void testFlushLoops();
+ void testDestroyManager1();
+ void testDestroyManager2();
+ void testFailAlways();
+
+ // Order is significant.
+ CPPUNIT_TEST_SUITE( TestTeleTubes );
+ CPPUNIT_TEST( testSetupManager1 );
+ CPPUNIT_TEST( testSetupManager2 );
+ CPPUNIT_TEST( testConnect1 );
+ CPPUNIT_TEST( testConnect2 );
+ CPPUNIT_TEST( testPrepareAccountManager1 );
+ CPPUNIT_TEST( testPrepareAccountManager2 );
+ CPPUNIT_TEST( testStartBuddySession1 );
+ CPPUNIT_TEST( testStartBuddySession2 );
+ CPPUNIT_TEST( testSendPacket );
+ CPPUNIT_TEST( testFlushLoops );
+ CPPUNIT_TEST( testDestroyManager1 );
+ CPPUNIT_TEST( testDestroyManager2 );
+ CPPUNIT_TEST( testFailAlways ); // need failure to display SAL_LOG, comment out for real builds
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+
+ void runSetupManager( TeleManager* pManager, const rtl::OUString& rBuddy );
+};
+
+// static, not members, so they actually survive cppunit test iteration
+static TeleManager* mpManager1 = NULL;
+static TeleManager* mpManager2 = NULL;
+
+// XXX The accounts need to be setup in Empathy and a jabber daemon needs
+// to be running on localhost.localdomain and both accounts need to be
+// enabled and connected.
+static rtl::OUString sAcc1( RTL_CONSTASCII_USTRINGPARAM( "libo1@localhost.localdomain"));
+static rtl::OUString sAcc2( RTL_CONSTASCII_USTRINGPARAM( "libo2@localhost.localdomain"));
+static rtl::OUString sService( RTL_CONSTASCII_USTRINGPARAM( "TeleTest"));
+
+TestTeleTubes::TestTeleTubes()
+{
+}
+
+TestTeleTubes::~TestTeleTubes()
+{
+}
+
+void TestTeleTubes::testSetupManager1()
+{
+ mpManager1 = new TeleManager( sAcc1, sService, true);
+}
+
+void TestTeleTubes::testSetupManager2()
+{
+ mpManager2 = new TeleManager( sAcc2, sService);
+}
+
+void TestTeleTubes::testPrepareAccountManager1()
+{
+ mpManager1->prepareAccountManager();
+ TeleManager::AccountManagerStatus eStatus = mpManager1->getAccountManagerStatus();
+ CPPUNIT_ASSERT( eStatus == TeleManager::AMS_PREPARED);
+}
+
+void TestTeleTubes::testPrepareAccountManager2()
+{
+ mpManager2->prepareAccountManager();
+ TeleManager::AccountManagerStatus eStatus = mpManager2->getAccountManagerStatus();
+ CPPUNIT_ASSERT( eStatus == TeleManager::AMS_PREPARED);
+}
+
+void TestTeleTubes::testStartBuddySession1()
+{
+ bool bStarted = mpManager1->startBuddySession( sAcc2);
+ CPPUNIT_ASSERT( bStarted == true);
+}
+
+void TestTeleTubes::testStartBuddySession2()
+{
+ bool bStarted = mpManager2->startBuddySession( sAcc1);
+ CPPUNIT_ASSERT( bStarted == true);
+}
+
+void TestTeleTubes::testConnect1()
+{
+ bool bConnected = mpManager1->connect();
+ CPPUNIT_ASSERT( bConnected == true);
+}
+
+void TestTeleTubes::testConnect2()
+{
+ bool bConnected = mpManager2->connect();
+ CPPUNIT_ASSERT( bConnected == true);
+}
+
+void TestTeleTubes::testSendPacket()
+{
+ TelePacket aPacket( "", RTL_CONSTASCII_STRINGPARAM( "from 1 to 2"));
+ bool bPacketSent = mpManager1->sendPacket( aPacket);
+ CPPUNIT_ASSERT( bPacketSent == true);
+}
+
+void TestTeleTubes::testFlushLoops()
+{
+ mpManager1->flushLoop();
+ mpManager2->flushLoop();
+}
+
+void TestTeleTubes::testDestroyManager1()
+{
+ delete mpManager1;
+ mpManager1 = NULL;
+}
+
+void TestTeleTubes::testDestroyManager2()
+{
+ delete mpManager2;
+ mpManager2 = NULL;
+}
+
+void TestTeleTubes::testFailAlways()
+{
+ CPPUNIT_ASSERT( false);
+}
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TestTeleTubes);
+
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tubes/source/conference.cxx b/tubes/source/conference.cxx
new file mode 100644
index 000000000000..3195df6bceab
--- /dev/null
+++ b/tubes/source/conference.cxx
@@ -0,0 +1,384 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2012 Red Hat, Inc., Eike Rathke <erack@redhat.com>
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#include <tubes/conference.hxx>
+#include <tubes/manager.hxx>
+
+
+#if defined SAL_LOG_INFO
+namespace
+{
+struct InfoLogger
+{
+ const void* mpThat;
+ const char* mpMethod;
+ explicit InfoLogger( const void* pThat, const char* pMethod )
+ :
+ mpThat( pThat),
+ mpMethod( pMethod)
+ {
+ SAL_INFO( "tubes.method", mpThat << " entering " << mpMethod);
+ }
+ ~InfoLogger()
+ {
+ SAL_INFO( "tubes.method", mpThat << " leaving " << mpMethod);
+ }
+};
+}
+#define INFO_LOGGER_F(s) InfoLogger aLogger(0,(s))
+#define INFO_LOGGER(s) InfoLogger aLogger(this,(s))
+#else
+#define INFO_LOGGER_F(s)
+#define INFO_LOGGER(s)
+#endif // SAL_LOG_INFO
+
+
+static DBusHandlerResult TeleConference_DBusMessageHandler(
+ DBusConnection* pConnection,
+ DBusMessage* pMessage,
+ void* pUserData
+ )
+{
+ INFO_LOGGER_F( "TeleConference_DBusMessageHandler");
+
+ SAL_WARN_IF( !pConnection || !pMessage, "tubes", "TeleConference_DBusMessageHandler: unhandled");
+ if (!pConnection || !pMessage)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ TeleConference* pConference = reinterpret_cast<TeleConference*>(pUserData);
+ SAL_WARN_IF( !pConference, "tubes", "TeleConference_DBusMessageHandler: no conference");
+ if (!pConference)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ TeleManager* pManager = pConference->getManager();
+ SAL_WARN_IF( !pManager, "tubes", "TeleConference_DBusMessageHandler: no manager");
+ if (!pManager)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ if (dbus_message_is_method_call( pMessage, pManager->getFullServiceName().getStr(), LIBO_TUBES_DBUS_MSG_METHOD))
+ {
+ const char* pSender = dbus_message_get_sender( pMessage);
+
+ DBusError aDBusError;
+ dbus_error_init( &aDBusError);
+ const char* pPacketData = 0;
+ int nPacketSize = 0;
+ if (dbus_message_get_args( pMessage, &aDBusError,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pPacketData, &nPacketSize,
+ DBUS_TYPE_INVALID))
+ {
+ SAL_INFO( "tubes", "TeleConference_DBusMessageHandler: received packet from sender "
+ << pSender << " with size " << nPacketSize);
+ pConference->queue( pSender, pPacketData, nPacketSize);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ else
+ {
+ SAL_INFO( "tubes", "TeleConference_DBusMessageHandler: unhandled message from sender "
+ << pSender << " " << aDBusError.message);
+ dbus_error_free( &aDBusError);
+ }
+ }
+ else
+ {
+ SAL_INFO( "tubes", "TeleConference_DBusMessageHandler: unhandled method");
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+
+static void TeleConference_ChannelCloseHandler(
+ TpChannel* /*proxy*/,
+ const GError* pError,
+ gpointer pUserData,
+ GObject* /*weak_object*/
+ )
+{
+ INFO_LOGGER_F( "TeleConference_ChannelCloseHandler");
+
+ TeleConference* pConference = reinterpret_cast<TeleConference*>(pUserData);
+ SAL_WARN_IF( !pConference, "tubes", "TeleConference_ChannelCloseHandler: no conference");
+ if (!pConference)
+ return;
+
+ if (pError)
+ {
+ SAL_WARN( "tubes", "TeleConference_ChannelCloseHandler: entered with error: " << pError->message);
+ pConference->finalize();
+ return;
+ }
+
+ pConference->finalize();
+}
+
+
+static void TeleConference_TubeOfferedHandler(
+ TpChannel* pChannel,
+ const gchar* pOutAddress,
+ const GError* pError,
+ gpointer pUserData,
+ GObject* /*weak_object*/
+ )
+{
+ INFO_LOGGER_F( "TeleConference_TubeOfferedHandler");
+
+ // "can't find contact ... presence" means contact is not a contact.
+ /* FIXME: detect and handle */
+ SAL_WARN_IF( pError, "tubes", "TeleConference_TubeOfferedHandler: entered with error: " << pError->message);
+ if (pError)
+ return;
+
+ SAL_WARN_IF( !pOutAddress, "tubes", "TeleConference_TubeOfferedHandler: no out address");
+ if (!pOutAddress)
+ return;
+
+ TeleConference* pConference = reinterpret_cast<TeleConference*>(pUserData);
+ SAL_WARN_IF( !pConference, "tubes", "TeleConference_TubeOfferedHandler: no conference");
+ if (!pConference)
+ return;
+
+ SAL_WARN_IF( pChannel != pConference->getChannel(), "tubes", "TeleConference_TubeOfferedHandler: not my channel");
+ if (pChannel != pConference->getChannel())
+ return;
+
+ TeleManager* pManager = pConference->getManager();
+ SAL_WARN_IF( !pManager, "tubes", "TeleConference_TubeOfferedHandler: no manager");
+ if (!pManager)
+ return;
+
+ pConference->setTubeOfferedHandlerInvoked( true);
+
+ DBusError aDBusError;
+ dbus_error_init( &aDBusError);
+ DBusConnection* pTube = dbus_connection_open_private( pOutAddress, &aDBusError);
+ if (!pTube)
+ {
+ SAL_WARN( "tubes", "TeleConference_TubeOfferedHandler: no dbus connection: " << aDBusError.message);
+ dbus_error_free( &aDBusError);
+ return;
+ }
+
+ pConference->setTube( pTube);
+}
+
+
+TeleConference::TeleConference( TeleManager* pManager, TpChannel* pChannel, const rtl::OString& rSessionId )
+ :
+ maSessionId( rSessionId ),
+ mpManager( pManager),
+ mpChannel( pChannel),
+ mpTube( NULL),
+ mbTubeOfferedHandlerInvoked( false)
+{
+ if (mpChannel)
+ g_object_ref( mpChannel);
+}
+
+
+TeleConference::~TeleConference()
+{
+ // Do nothing here, we're destructed from finalize()
+}
+
+
+void TeleConference::setTarget( const rtl::OString& rTarget )
+{
+ maTarget = rTarget;
+}
+
+
+void TeleConference::setChannel( TpChannel* pChannel )
+{
+ OSL_ENSURE( !mpChannel, "TeleConference::setChannel: already have channel");
+ if (mpChannel)
+ g_object_unref( mpChannel);
+ mpChannel = pChannel;
+ if (mpChannel)
+ g_object_ref( mpChannel);
+}
+
+
+bool TeleConference::acceptTube( const char* pAddress )
+{
+ INFO_LOGGER( "TeleConference::acceptTube");
+
+ SAL_WARN_IF( !pAddress, "tubes", "TeleConference::acceptTube: no address");
+ if (!pAddress)
+ return false;
+ SAL_INFO( "tubes", "TeleConference::acceptTube: address: " << pAddress);
+
+ SAL_WARN_IF( !mpChannel, "tubes", "TeleConference::acceptTube: no channel setup");
+ SAL_WARN_IF( mpTube, "tubes", "TeleConference::acceptTube: already tubed");
+ if (!mpChannel || mpTube)
+ return false;
+
+ DBusError aDBusError;
+ dbus_error_init( &aDBusError);
+ mpTube = dbus_connection_open_private( pAddress, &aDBusError);
+ if (!mpTube)
+ {
+ SAL_WARN( "tubes", "TeleConference::acceptTube: no dbus connection: " << aDBusError.message);
+ dbus_error_free( &aDBusError);
+ return false;
+ }
+
+ dbus_connection_setup_with_g_main( mpTube, mpManager->getMainContext());
+ dbus_connection_add_filter( mpTube, TeleConference_DBusMessageHandler, this, NULL);
+
+ return true;
+}
+
+
+bool TeleConference::offerTube()
+{
+ INFO_LOGGER( "TeleConference::offerTube");
+
+ OSL_ENSURE( mpChannel, "TeleConference::offerTube: no channel");
+ if (!mpChannel)
+ return false;
+
+ setTubeOfferedHandlerInvoked( false);
+
+ // There must be a hash table with some content.
+ /* TODO: anything meaningful to go in here? */
+ GHashTable* pParams = tp_asv_new(
+ "LibreOffice", G_TYPE_STRING, "Collaboration",
+ NULL);
+
+ tp_cli_channel_type_dbus_tube_call_offer(
+ mpChannel, // proxy
+ -1, // timeout_ms
+ pParams, // in_parameters
+ TP_SOCKET_ACCESS_CONTROL_LOCALHOST, // in_access_control
+ TeleConference_TubeOfferedHandler, // callback
+ this, // user_data
+ NULL, // destroy
+ NULL); // weak_object
+
+ mpManager->iterateLoop( this, &TeleConference::isTubeOfferedHandlerInvoked);
+
+ g_hash_table_unref( pParams);
+
+ return true;
+}
+
+
+bool TeleConference::setTube( DBusConnection* pTube )
+{
+ INFO_LOGGER( "TeleConference::setTube");
+
+ OSL_ENSURE( !mpTube, "TeleConference::setTube: already tubed");
+ mpTube = pTube;
+
+ dbus_connection_setup_with_g_main( mpTube, mpManager->getMainContext());
+ dbus_connection_add_filter( mpTube, TeleConference_DBusMessageHandler, this, NULL);
+
+ /* TODO: anything else? */
+
+ return true;
+}
+
+
+void TeleConference::close()
+{
+ INFO_LOGGER( "TeleConference::close");
+
+ if (mpChannel)
+ tp_cli_channel_call_close( mpChannel, 5000, TeleConference_ChannelCloseHandler, this, NULL, NULL);
+ else
+ finalize();
+}
+
+
+void TeleConference::finalize()
+{
+ INFO_LOGGER( "TeleConference::finalize");
+
+ if (mpChannel)
+ {
+ g_object_unref( mpChannel);
+ mpChannel = NULL;
+ }
+
+ if (mpTube)
+ {
+ dbus_connection_remove_filter( mpTube, TeleConference_DBusMessageHandler, this);
+ dbus_connection_close( mpTube);
+ dbus_connection_unref( mpTube);
+ mpTube = NULL;
+ }
+
+ TeleConferencePtr pThis( shared_from_this());
+ mpManager->unregisterConference( pThis);
+
+ //! *this gets destructed here!
+}
+
+
+bool TeleConference::sendPacket( TelePacket& rPacket ) const
+{
+ INFO_LOGGER( "TeleConference::sendPacket");
+
+ OSL_ENSURE( mpManager, "tubes: TeleConference::sendPacket: no TeleManager");
+ SAL_WARN_IF( !mpTube, "tubes", "TeleConference::sendPacket: no tube");
+ if (!(mpManager && mpTube))
+ return false;
+
+ DBusMessage* pMessage = dbus_message_new_method_call(
+ mpManager->getFullServiceName().getStr(),
+ mpManager->getFullObjectPath().getStr(),
+ mpManager->getFullServiceName().getStr(),
+ LIBO_TUBES_DBUS_MSG_METHOD);
+ SAL_WARN_IF( !pMessage, "tubes", "TeleConference::sendPacket: no DBusMessage");
+ if (!pMessage)
+ return false;
+
+ const char* pPacketData = rPacket.getData();
+ dbus_message_append_args( pMessage,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pPacketData, rPacket.getSize(),
+ DBUS_TYPE_INVALID);
+
+ SAL_INFO( "tubes", "TeleConference::sendPacket: from " <<
+ dbus_message_get_sender( pMessage) << " to " << dbus_message_get_destination( pMessage));
+
+ bool bSent = dbus_connection_send( mpTube, pMessage, NULL);
+ SAL_WARN_IF( !bSent, "tubes", "TeleConference::sendPacket: not sent");
+ dbus_message_unref( pMessage);
+ return bSent;
+}
+
+
+void TeleConference::queue( const char* pDBusSender, const char* pPacketData, int nPacketSize )
+{
+ INFO_LOGGER( "TeleConference::queue");
+
+ maPacketQueue.push( TelePacket( pDBusSender, pPacketData, nPacketSize));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tubes/source/manager.cxx b/tubes/source/manager.cxx
new file mode 100644
index 000000000000..ba9185258469
--- /dev/null
+++ b/tubes/source/manager.cxx
@@ -0,0 +1,668 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2012 Red Hat, Inc., Eike Rathke <erack@redhat.com>
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#include "tubes/manager.hxx"
+#include <rtl/strbuf.hxx>
+#include <rtl/uuid.h>
+
+
+#if defined SAL_LOG_INFO
+namespace
+{
+struct InfoLogger
+{
+ const void* mpThat;
+ const char* mpMethod;
+ explicit InfoLogger( const void* pThat, const char* pMethod )
+ :
+ mpThat( pThat),
+ mpMethod( pMethod)
+ {
+ SAL_INFO( "tubes.method", mpThat << " entering " << mpMethod);
+ }
+ ~InfoLogger()
+ {
+ SAL_INFO( "tubes.method", mpThat << " leaving " << mpMethod);
+ }
+};
+}
+#define INFO_LOGGER_F(s) InfoLogger aLogger(0,(s))
+#define INFO_LOGGER(s) InfoLogger aLogger(this,(s))
+#else
+#define INFO_LOGGER_F(s)
+#define INFO_LOGGER(s)
+#endif // SAL_LOG_INFO
+
+
+using namespace rtl;
+
+// To form "org.freedesktop.Telepathy.Client.LibreOfficeWhatEver" (bus name)
+// or "/org/freedesktop/Telepathy/Client/LibreOfficeWhatEver" (object path)
+#define LIBO_TP_NAME_PREFIX "LibreOffice"
+
+
+static void TeleManager_DBusTubeAcceptHandler(
+ TpChannel* pChannel,
+ const char* pAddress,
+ const GError* pError,
+ gpointer pUserData,
+ GObject* /*weak_object*/)
+{
+ INFO_LOGGER_F( "TeleManager_DBusTubeAcceptHandler");
+
+ SAL_WARN_IF( pError, "tubes", "TeleManager_DBusTubeAcceptHandler: entered with error: " << pError->message);
+ if (pError)
+ return;
+
+ TeleManager* pManager = reinterpret_cast<TeleManager*>(pUserData);
+ SAL_WARN_IF( !pManager, "tubes", "TeleManager_DBusTubeAcceptHandler: no manager");
+ if (!pManager)
+ return;
+
+ pManager->acceptTube( pChannel, pAddress);
+}
+
+
+static void TeleManager_DBusChannelHandler(
+ TpSimpleHandler* /*handler*/,
+ TpAccount* /*account*/,
+ TpConnection* /*connection*/,
+ GList* pChannels,
+ GList* /*requests_satisfied*/,
+ gint64 /*user_action_time*/,
+ TpHandleChannelsContext* pContext,
+ gpointer pUserData)
+{
+ INFO_LOGGER_F( "TeleManager_DBusChannelHandler");
+
+ TeleManager* pManager = reinterpret_cast<TeleManager*>(pUserData);
+ SAL_WARN_IF( !pManager, "tubes", "TeleManager_DBusChannelHandler: no manager");
+ if (!pManager)
+ return;
+
+ for (GList* p = pChannels; p; p = p->next)
+ {
+ TpChannel* pChannel = TP_CHANNEL(p->data);
+ if (!pChannel)
+ continue;
+
+ SAL_INFO( "tubes", "TeleManager_DBusChannelHandler: incoming dbus channel: "
+ << tp_channel_get_identifier( pChannel));
+
+ if (tp_channel_get_channel_type_id( pChannel) == TP_IFACE_QUARK_CHANNEL_TYPE_DBUS_TUBE)
+ {
+ SAL_INFO( "tubes", "accepting");
+ tp_cli_channel_type_dbus_tube_call_accept( pChannel, -1,
+ TP_SOCKET_ACCESS_CONTROL_LOCALHOST,
+ TeleManager_DBusTubeAcceptHandler, pUserData, NULL, NULL);
+ }
+ else
+ {
+ SAL_INFO( "tubes", "ignored");
+ }
+ }
+
+ tp_handle_channels_context_accept( pContext);
+}
+
+
+static void TeleManager_ChannelReadyHandler(
+ GObject* pSourceObject,
+ GAsyncResult* pResult,
+ gpointer pUserData
+ )
+{
+ INFO_LOGGER_F( "TeleManager_ChannelReadyHandler");
+
+ TeleConference* pConference = reinterpret_cast<TeleConference*>(pUserData);
+ SAL_WARN_IF( !pConference, "tubes", "TeleManager_ChannelReadyHandler: no conference");
+ if (!pConference)
+ return;
+
+ TeleManager* pManager = pConference->getManager();
+ SAL_WARN_IF( !pManager, "tubes", "TeleManager_ChannelReadyHandler: no manager");
+ if (!pManager)
+ return;
+
+ pManager->setChannelReadyHandlerInvoked( true);
+
+ GError* pError = NULL;
+ TpChannel * pChannel = tp_account_channel_request_create_and_handle_channel_finish(
+ TP_ACCOUNT_CHANNEL_REQUEST( pSourceObject), pResult, NULL, &pError);
+ if (!pChannel)
+ {
+ // "account isn't Enabled" means just that..
+ /* FIXME: detect and handle, domain=132, code=3 */
+ SAL_WARN( "tubes", "TeleManager_ChannelReadyHandler: no channel: " << pError->message);
+ g_error_free( pError);
+ return;
+ }
+
+ pConference->setChannel( pChannel);
+ pConference->offerTube();
+}
+
+
+static void TeleManager_AccountManagerReadyHandler(
+ GObject* pSourceObject,
+ GAsyncResult* pResult,
+ gpointer pUserData
+ )
+{
+ INFO_LOGGER_F( "TeleManager_AccountManagerReadyHandler");
+
+ TeleManager* pManager = reinterpret_cast<TeleManager*>(pUserData);
+ SAL_WARN_IF( !pManager, "tubes", "TeleManager_AccountManagerReadyHandler: no manager");
+ if (!pManager)
+ return;
+
+ pManager->setAccountManagerReadyHandlerInvoked( true);
+
+ GError* pError = NULL;
+ gboolean bPrepared = tp_proxy_prepare_finish( pSourceObject, pResult, &pError);
+ SAL_WARN_IF( !bPrepared, "tubes", "TeleManager_AccountManagerReadyHandler: not prepared");
+ if (!bPrepared || pError)
+ {
+ SAL_WARN_IF( pError, "tubes", "TeleManager_AccountManagerReadyHandler: error: " << pError->message);
+ g_error_free( pError);
+ }
+
+ pManager->setAccountManagerReady( bPrepared);
+}
+
+
+TeleManager::TeleManager( const rtl::OUString& rAccount, const rtl::OUString& rService, bool bCreateOwnGMainLoop )
+ :
+ maAccountID( OUStringToOString( rAccount, RTL_TEXTENCODING_UTF8)),
+ mpLoop( NULL),
+ mpDBus( NULL),
+ mpAccountManager( NULL),
+ mpAccount( NULL),
+ mpConnection( NULL),
+ mpClient( NULL),
+ meAccountManagerStatus( AMS_UNINITIALIZED),
+ mbChannelReadyHandlerInvoked( false),
+ mbAccountManagerReadyHandlerInvoked( false)
+{
+ OStringBuffer aBuf(64);
+ aBuf.append( RTL_CONSTASCII_STRINGPARAM( LIBO_TP_NAME_PREFIX)).append(
+ OUStringToOString( rService, RTL_TEXTENCODING_UTF8));
+ maService = aBuf.makeStringAndClear();
+ // Ensure a clean name suitable for object paths.
+ maService.replace( '.', '_');
+
+ // The glib object types need to be initialized, else we aren't going
+ // anywhere.
+ g_type_init();
+
+ // We need a main loop, else no callbacks.
+ /* TODO: could the loop be run in another thread? */
+ if (bCreateOwnGMainLoop)
+ mpLoop = g_main_loop_new( NULL, FALSE);
+}
+
+
+TeleManager::~TeleManager()
+{
+ disconnect();
+
+ if (mpDBus)
+ g_object_unref( mpDBus);
+ if (mpAccountManager)
+ g_object_unref( mpAccountManager);
+ if (mpAccount)
+ g_object_unref( mpAccount);
+ if (mpConnection)
+ g_object_unref( mpConnection);
+ if (mpClient)
+ g_object_unref( mpClient);
+
+ if (mpLoop)
+ g_main_loop_unref( mpLoop);
+}
+
+
+bool TeleManager::connect()
+{
+ INFO_LOGGER( "TeleManager::connect");
+
+ MainLoopFlusher aFlusher( this);
+
+ SAL_WARN_IF( mpDBus || mpClient, "tubes", "TeleManager::connect: already connected");
+ if (mpDBus || mpClient)
+ return false;
+
+ GError* pError = NULL;
+ mpDBus = tp_dbus_daemon_dup( &pError);
+ SAL_WARN_IF( !mpDBus, "tubes", "TeleManager::connect: no dbus daemon");
+ if (!mpDBus || pError)
+ {
+ SAL_WARN_IF( pError, "tubes", "TeleManager::connect: dbus daemon error: " << pError->message);
+ g_error_free( pError);
+ return false;
+ }
+
+ TpSimpleClientFactory* pFactory = tp_simple_client_factory_new( mpDBus);
+ SAL_WARN_IF( !pFactory, "tubes", "TeleManager::connect: no client factory");
+ if (!pFactory)
+ return false;
+
+ /* TODO: does that still work with uniquify? Or is the service not
+ * recognized anymore? Without uniquify it is not possible to register two
+ * instances of clients on the same DBus. */
+
+ /* FIXME: testing, first real, all others uniquified */
+ static gboolean bUniquify = FALSE;
+
+ mpClient = tp_simple_handler_new_with_factory(
+ pFactory, // factory
+ TRUE, // bypass_approval
+ FALSE, // requests
+ maService.getStr(), // name
+ bUniquify, // uniquify
+ TeleManager_DBusChannelHandler, // callback
+ this, // user_data
+ NULL // destroy
+ );
+ bUniquify = TRUE;
+ SAL_WARN_IF( !mpClient, "tubes", "TeleManager::connect: no client");
+ if (!mpClient)
+ return false;
+
+ // Setup client handler for buddy channels with our service.
+ tp_base_client_take_handler_filter( mpClient,
+ tp_asv_new(
+ TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
+ TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME, G_TYPE_STRING, getFullServiceName().getStr(),
+ NULL));
+
+/* FIXME: once we can handle MUCs, this is additional to buddy channels! */
+#if 0
+ // Setup client handler for MUC channels with our service.
+ tp_base_client_take_handler_filter( mpClient,
+ tp_asv_new(
+ TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_ROOM,
+ TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME, G_TYPE_STRING, getFullServiceName().getStr(),
+ NULL));
+#endif
+
+ if (!tp_base_client_register( mpClient, &pError))
+ {
+ SAL_WARN( "tubes", "TeleManager::connect: error registering client handler: " << pError->message);
+ g_error_free( pError);
+ return false;
+ }
+
+ SAL_INFO( "tubes", "TeleManager::connect: bus name: " << tp_base_client_get_bus_name( mpClient));
+ SAL_INFO( "tubes", "TeleManager::connect: object path: " << tp_base_client_get_object_path( mpClient));
+
+ return true;
+}
+
+
+/* TODO: factor out common code with startBuddySession() */
+bool TeleManager::startGroupSession( const rtl::OUString& rUConferenceRoom, const rtl::OUString& rUConferenceServer )
+{
+ INFO_LOGGER( "TeleManager::startGroupSession");
+
+ MainLoopFlusher aFlusher( this);
+
+ if (!getMyAccount())
+ return false;
+
+ OString aSessionId( TeleManager::createUuid());
+
+ TeleConferencePtr pConference( new TeleConference( this, NULL, aSessionId));
+ maConferences.push_back( pConference);
+
+ /* TODO: associate the document with this session and conference */
+
+ /* FIXME: does this work at all _creating_ a MUC? */
+ // Use conference and server if given, else create conference.
+ OString aConferenceRoom( OUStringToOString( rUConferenceRoom, RTL_TEXTENCODING_UTF8));
+ OString aConferenceServer( OUStringToOString( rUConferenceServer, RTL_TEXTENCODING_UTF8));
+ OStringBuffer aBuf(64);
+ if (!aConferenceRoom.isEmpty() && !aConferenceServer.isEmpty())
+ aBuf.append( aConferenceRoom).append( '@').append( aConferenceServer);
+ else
+ {
+ aBuf.append( aSessionId);
+ if (!aConferenceServer.isEmpty())
+ aBuf.append( '@').append( aConferenceServer);
+ /* FIXME: else? bail out? we have only a session ID without server then */
+ }
+ OString aTarget( aBuf.makeStringAndClear());
+ pConference->setTarget( aTarget);
+
+ SAL_INFO( "tubes", "TeleManager::startGroupSession: creating channel request from "
+ << maAccountID.getStr() << " to " << aTarget.getStr());
+
+ // MUC request
+ GHashTable* pRequest = tp_asv_new(
+ TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, TP_TYPE_HANDLE, TP_HANDLE_TYPE_ROOM,
+ TP_PROP_CHANNEL_TARGET_ID, G_TYPE_STRING, aTarget.getStr(),
+ TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME, G_TYPE_STRING, getFullServiceName().getStr(),
+ NULL);
+
+ TpAccountChannelRequest * pChannelRequest = tp_account_channel_request_new(
+ mpAccount, pRequest, TP_USER_ACTION_TIME_NOT_USER_ACTION);
+ g_hash_table_unref( pRequest);
+ SAL_WARN_IF( !pChannelRequest, "tubes", "TeleManager::startGroupSession: no channel");
+ if (!pChannelRequest)
+ return false;
+
+ setChannelReadyHandlerInvoked( false);
+
+ tp_account_channel_request_create_and_handle_channel_async(
+ pChannelRequest, NULL, TeleManager_ChannelReadyHandler, pConference.get());
+
+ iterateLoop( &TeleManager::isChannelReadyHandlerInvoked);
+
+ return pConference->getChannel() != NULL;
+}
+
+
+/* TODO: factor out common code with startGroupSession() */
+bool TeleManager::startBuddySession( const rtl::OUString& rBuddy )
+{
+ INFO_LOGGER( "TeleManager::startBuddySession");
+
+ MainLoopFlusher aFlusher( this);
+
+ if (!getMyAccount())
+ return false;
+
+ OString aSessionId( TeleManager::createUuid());
+
+ TeleConferencePtr pConference( new TeleConference( this, NULL, aSessionId));
+ maConferences.push_back( pConference);
+
+ /* TODO: associate the document with this session and conference */
+
+ OString aTarget( OUStringToOString( rBuddy, RTL_TEXTENCODING_UTF8));
+ pConference->setTarget( aTarget);
+
+ SAL_INFO( "tubes", "TeleManager::startBuddySession: creating channel request from "
+ << maAccountID.getStr() << " to " << aTarget.getStr());
+
+ GHashTable* pRequest = tp_asv_new(
+ TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, TP_TYPE_HANDLE, TP_HANDLE_TYPE_CONTACT,
+ TP_PROP_CHANNEL_TARGET_ID, G_TYPE_STRING, aTarget.getStr(),
+ TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME, G_TYPE_STRING, getFullServiceName().getStr(),
+ NULL);
+
+ TpAccountChannelRequest * pChannelRequest = tp_account_channel_request_new(
+ mpAccount, pRequest, TP_USER_ACTION_TIME_NOT_USER_ACTION);
+ SAL_WARN_IF( !pChannelRequest, "tubes", "TeleManager::startBuddySession: no channel");
+ if (!pChannelRequest)
+ {
+ g_hash_table_unref( pRequest);
+ return false;
+ }
+
+ setChannelReadyHandlerInvoked( false);
+
+ tp_account_channel_request_create_and_handle_channel_async(
+ pChannelRequest, NULL, TeleManager_ChannelReadyHandler, pConference.get());
+
+ iterateLoop( &TeleManager::isChannelReadyHandlerInvoked);
+
+ g_object_unref( pChannelRequest);
+ g_hash_table_unref( pRequest);
+
+ return pConference->getChannel() != NULL;
+}
+
+
+void TeleManager::prepareAccountManager()
+{
+ INFO_LOGGER( "TeleManager::prepareAccountManager");
+
+ MainLoopFlusher aFlusher( this);
+
+ SAL_WARN_IF( meAccountManagerStatus == AMS_INPREPARATION, "tubes",
+ "TeleManager::prepareAccountManager: already in preparation");
+ if (meAccountManagerStatus == AMS_INPREPARATION)
+ return;
+
+ SAL_WARN_IF( meAccountManagerStatus != AMS_UNINITIALIZED, "tubes",
+ "TeleManager::prepareAccountManager: yet another attempt");
+
+ if (!mpAccountManager)
+ {
+ mpAccountManager = tp_account_manager_dup();
+ SAL_WARN_IF( !mpAccountManager, "tubes", "TeleManager::prepareAccountManager: no account manager");
+ if (!mpAccountManager)
+ return;
+ g_object_ref( mpAccountManager);
+ }
+
+ meAccountManagerStatus = AMS_INPREPARATION;
+ setAccountManagerReadyHandlerInvoked( false);
+
+ tp_proxy_prepare_async( mpAccountManager, NULL, TeleManager_AccountManagerReadyHandler, this);
+
+ iterateLoop( &TeleManager::isAccountManagerReadyHandlerInvoked);
+}
+
+
+TpAccount* TeleManager::getMyAccount()
+{
+ INFO_LOGGER( "TeleManager::getMyAccount");
+
+ MainLoopFlusher aFlusher( this);
+
+ if (mpAccount)
+ return mpAccount;
+
+ SAL_WARN_IF( meAccountManagerStatus != AMS_PREPARED, "tubes",
+ "TeleManager::getMyAccount: Account Manager not prepared");
+ if (meAccountManagerStatus != AMS_PREPARED)
+ return NULL;
+
+ GList* pAccounts = tp_account_manager_get_valid_accounts( mpAccountManager);
+ SAL_WARN_IF( !pAccounts, "tubes", "TeleManager::getMyAccount: no valid accounts");
+ if (!pAccounts)
+ return NULL;
+
+ // Find our account to use.
+ for (GList* pA = pAccounts; pA; pA = pA->next)
+ {
+ TpAccount* pAcc = TP_ACCOUNT( pA->data);
+ const GHashTable* pPar = tp_account_get_parameters( pAcc);
+ const gchar* pID = tp_asv_get_string( pPar, "account");
+ SAL_WARN_IF( !pID, "tubes", "TeleManager::getMyAccount: account without account??");
+ if (pID && maAccountID == pID)
+ {
+ mpAccount = pAcc;
+ break; // for
+ }
+ }
+
+ g_list_free( pAccounts);
+ SAL_WARN_IF( !mpAccount, "tubes", "TeleManager::getMyAccount: no account");
+ if (!mpAccount)
+ return NULL;
+
+ g_object_ref( mpAccount);
+ return mpAccount;
+}
+
+
+bool TeleManager::sendPacket( const TelePacket& rPacket ) const
+{
+ INFO_LOGGER( "TeleManager::sendPacket");
+
+ MainLoopFlusher aFlusher( this);
+
+ bool bToSend = false;
+ bool bSent = true;
+ // Access to data ByteStream array forces reference count of one, provide
+ // non-const instance here before passing it down to each conference.
+ TelePacket aPacket( rPacket);
+ for (TeleConferenceVector::const_iterator it = maConferences.begin(); it != maConferences.end(); ++it)
+ {
+ bToSend = true;
+ if (!(*it)->sendPacket( aPacket))
+ bSent = false;
+ }
+ return bSent && bToSend;
+}
+
+
+void TeleManager::unregisterConference( TeleConferencePtr pConference )
+{
+ TeleConferenceVector::iterator it = ::std::find( maConferences.begin(), maConferences.end(), pConference);
+ if (it != maConferences.end())
+ maConferences.erase( it);
+}
+
+
+void TeleManager::disconnect()
+{
+ INFO_LOGGER( "TeleManager::disconnect");
+
+ //! No MainLoopFlusher here!
+
+ if (!mpClient)
+ return;
+
+ tp_base_client_unregister( mpClient);
+ mpClient = NULL;
+
+ size_t nSize = maConferences.size();
+ for (size_t i=0; i < nSize; /*nop*/)
+ {
+ maConferences[i]->close();
+ // close() may remove the conference from the vector and move following
+ // elements to this position (hence we don't use an iterator here),
+ // adjust accordingly.
+ size_t n = maConferences.size();
+ if (n < nSize)
+ nSize = n;
+ else
+ ++i;
+ }
+}
+
+
+void TeleManager::acceptTube( TpChannel* pChannel, const char* pAddress )
+{
+ INFO_LOGGER( "TeleManager::acceptTube");
+
+ SAL_INFO( "tubes", "TeleManager::acceptTube: address " << pAddress);
+
+ MainLoopFlusher aFlusher( this);
+
+ SAL_WARN_IF( !pChannel || !pAddress, "tubes", "TeleManager::acceptTube: no channel or no address");
+ if (!pChannel || !pAddress)
+ return;
+
+ TeleConferencePtr pConference( new TeleConference( this, pChannel, ""));
+ maConferences.push_back( pConference);
+ pConference->acceptTube( pAddress);
+}
+
+
+void TeleManager::setAccountManagerReady( bool bPrepared)
+{
+ meAccountManagerStatus = (bPrepared ? AMS_PREPARED : AMS_UNPREPARABLE);
+}
+
+
+rtl::OString TeleManager::getFullServiceName() const
+{
+ OStringBuffer aBuf(64);
+ aBuf.append( RTL_CONSTASCII_STRINGPARAM( TP_CLIENT_BUS_NAME_BASE)).append( maService);
+ return aBuf.makeStringAndClear();
+}
+
+
+rtl::OString TeleManager::getFullObjectPath() const
+{
+ OStringBuffer aBuf(64);
+ aBuf.append( RTL_CONSTASCII_STRINGPARAM( TP_CLIENT_OBJECT_PATH_BASE)).append( maService);
+ return aBuf.makeStringAndClear();
+}
+
+
+void TeleManager::iterateLoop( CallBackInvokedFunc pFunc )
+{
+ GMainContext* pContext = (mpLoop ? g_main_loop_get_context( mpLoop) : NULL);
+ while (!(this->*pFunc)())
+ {
+ g_main_context_iteration( pContext, TRUE);
+ SAL_INFO( "tubes.loop", "TeleManager::iterateLoop");
+ }
+}
+
+
+void TeleManager::iterateLoop( const TeleConference* pConference, ConferenceCallBackInvokedFunc pFunc )
+{
+ GMainContext* pContext = (mpLoop ? g_main_loop_get_context( mpLoop) : NULL);
+ while (!(pConference->*pFunc)())
+ {
+ g_main_context_iteration( pContext, TRUE);
+ SAL_INFO( "tubes.loop", "TeleManager::iterateLoop conference");
+ }
+}
+
+
+void TeleManager::flushLoop() const
+{
+ if (mpLoop)
+ {
+ GMainContext* pContext = g_main_loop_get_context( mpLoop);
+ while (g_main_context_iteration( pContext, FALSE))
+ {
+ SAL_INFO( "tubes.loop", "TeleManager::flushLoop");
+ }
+ }
+}
+
+
+// static
+rtl::OString TeleManager::createUuid()
+{
+ sal_uInt8 nId[16];
+ rtl_createUuid( nId, 0, sal_True);
+ char aBuf[33];
+ for (size_t i=0; i<16; ++i)
+ {
+ snprintf( aBuf+2*i, 3, "%02x", (unsigned char)nId[i]);
+ }
+ aBuf[32] = 0;
+ return rtl::OString( aBuf);
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tubes/source/packet.cxx b/tubes/source/packet.cxx
new file mode 100644
index 000000000000..279398603270
--- /dev/null
+++ b/tubes/source/packet.cxx
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2012 Red Hat, Inc., Eike Rathke <erack@redhat.com>
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#include <tubes/packet.hxx>
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */