summaryrefslogtreecommitdiff
path: root/TelepathyQt/outgoing-dbus-tube-channel.cpp
blob: 1911fa879d2bf0a3ae4ad7edd173db74caa1d3bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/*
 * This file is part of TelepathyQt
 *
 * Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
 *
 * 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) any later version.
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt/OutgoingDBusTubeChannel>

#include "TelepathyQt/_gen/outgoing-dbus-tube-channel.moc.hpp"

#include "TelepathyQt/debug-internal.h"

#include <TelepathyQt/Connection>
#include <TelepathyQt/ContactManager>
#include <TelepathyQt/PendingDBusTubeOffer>
#include <TelepathyQt/PendingString>
#include <TelepathyQt/Types>

namespace Tp
{

struct TP_QT_NO_EXPORT OutgoingDBusTubeChannel::Private
{
    Private(OutgoingDBusTubeChannel *parent);
    virtual ~Private();

    // Public object
    OutgoingDBusTubeChannel *parent;
};

OutgoingDBusTubeChannel::Private::Private(OutgoingDBusTubeChannel *parent)
        : parent(parent)
{
}

OutgoingDBusTubeChannel::Private::~Private()
{
}

/**
 * \class OutgoingDBusTubeChannel
 * \headerfile TelepathyQt/outgoing-dbus-tube-channel.h <TelepathyQt/OutgoingDBusTubeChannel>
 *
 * An high level wrapper for managing an outgoing DBus tube
 *
 * \c OutgoingDBusTubeChannel is an high level wrapper for managing Telepathy interface
 * #TELEPATHY_INTERFACE_CHANNEL_TYPE_DBUS_TUBE.
 * In particular, this class is meant to be used as a comfortable way for exposing new tubes.
 *
 * \section outgoing_dbus_tube_usage_sec Usage
 *
 * \subsection outgoing_dbus_tube_create_sec Creating an outgoing DBus tube
 *
 * The easiest way to create a DBus tube is through Account. One can
 * just use the Account convenience methods such as
 * Account::createDBusTube() to get a brand new DBus tube channel ready to be used.
 *
 * To create such a channel, it is required to pass Account::createDBusTube()
 * the contact identifier and the DBus service name which will be used over the tube.
 * For example:
 *
 * \code
 * AccountPtr myaccount = getMyAccountSomewhere();
 * ContactPtr myfriend = getMyFriendSomewhereElse();
 *
 * PendingChannelRequest *tube = myaccount->createDBusTube(myfriend, "org.my.service");
 * \endcode
 *
 * Be sure to track the pending request to retrieve your outgoing DBus tube upon success.
 *
 * \subsection outgoing_dbus_tube_offer_sec Offering the tube
 *
 * Before being ready to offer the tube, we must be sure the required features on our object
 * are ready. In this case, we need to enable TubeChannel::FeatureTube
 * and StreamTubeChannel::FeatureDBusTube.
 *
 * \code
 *
 * Features features = Features() << TubeChannel::FeatureTube
 *                                << DBusTubeChannel::FeatureDBusTube;
 * connect(myTube->becomeReady(features),
 *         SIGNAL(finished(Tp::PendingOperation *)),
 *         SLOT(onDBusTubeChannelReady(Tp::PendingOperation *)));
 *
 * \endcode
 *
 * To learn more on how to use introspectable and features, please see \ref account_ready_sec.
 *
 * You can also enable DBusTubeChannel::FeatureBusNameMonitoring to monitor connections
 * to the tube.
 *
 * Once your object is ready, you can use offerTube to create a brand new DBus connection and offer
 * it over the tube.
 *
 * You can now monitor the returned operation to know when the tube will be ready.
 * It is guaranteed that when the operation finishes,
 * the tube will be already opened and ready to be used.
 *
 * See \ref async_model, \ref shared_ptr
 */

/**
 * Create a new OutgoingDBusTubeChannel channel.
 *
 * \param connection Connection owning this channel, and specifying the
 *                   service.
 * \param objectPath The object path of this channel.
 * \param immutableProperties The immutable properties of this channel.
 * \return A OutgoingDBusTubeChannelPtr object pointing to the newly created
 *         OutgoingDBusTubeChannel object.
 */
OutgoingDBusTubeChannelPtr OutgoingDBusTubeChannel::create(const ConnectionPtr &connection,
        const QString &objectPath, const QVariantMap &immutableProperties)
{
    return OutgoingDBusTubeChannelPtr(new OutgoingDBusTubeChannel(connection, objectPath,
                immutableProperties));
}

/**
 * Construct a new OutgoingDBusTubeChannel object.
 *
 * \param connection Connection owning this channel, and specifying the
 *                   service.
 * \param objectPath The object path of this channel.
 * \param immutableProperties The immutable properties of this channel.
 */
OutgoingDBusTubeChannel::OutgoingDBusTubeChannel(const ConnectionPtr &connection,
        const QString &objectPath,
        const QVariantMap &immutableProperties)
    : DBusTubeChannel(connection, objectPath, immutableProperties),
      mPriv(new Private(this))
{
}

/**
 * Class destructor.
 */
OutgoingDBusTubeChannel::~OutgoingDBusTubeChannel()
{
    delete mPriv;
}

/**
 * Offer the tube
 *
 * This method creates a brand new private DBus connection, and offers it through the tube.
 *
 * The %PendingDBusTubeOffer returned by this method will be completed as soon as the tube is
 * opened and ready to be used.
 *
 * \param parameters A dictionary of arbitrary Parameters to send with the tube offer.
 *                   Please read the specification for more details.
 * \param requireCredentials Whether the server should require an SCM_CREDENTIALS message
 *                           upon connection.
 *
 * \returns A %PendingDBusTubeOffer which will finish as soon as the tube is ready to be used
 *          (hence in the Open state)
 */
PendingDBusTubeOffer *OutgoingDBusTubeChannel::offerTube(const QVariantMap &parameters,
        bool requireCredentials)
{
    SocketAccessControl accessControl = requireCredentials ?
                                        SocketAccessControlCredentials :
                                        SocketAccessControlLocalhost;

    if (!isReady(DBusTubeChannel::FeatureDBusTube)) {
        warning() << "DBusTubeChannel::FeatureDBusTube must be ready before "
            "calling offerTube";
        return new PendingDBusTubeOffer(QLatin1String(TP_QT_ERROR_NOT_AVAILABLE),
                QLatin1String("Channel not ready"), OutgoingDBusTubeChannelPtr(this));
    }

    // The tube must be not offered
    if (state() != TubeChannelStateNotOffered) {
        warning() << "You can not expose more than a bus for each DBus Tube";
        return new PendingDBusTubeOffer(QLatin1String(TP_QT_ERROR_NOT_AVAILABLE),
                QLatin1String("Channel busy"), OutgoingDBusTubeChannelPtr(this));
    }

    // Let's offer the tube
    if (requireCredentials && !supportsCredentials()) {
        warning() << "You requested an access control "
            "not supported by this channel";
        return new PendingDBusTubeOffer(QLatin1String(TP_QT_ERROR_NOT_IMPLEMENTED),
                QLatin1String("The requested access control is not supported"),
                OutgoingDBusTubeChannelPtr(this));
    }

    PendingString *ps = new PendingString(
        interface<Client::ChannelTypeDBusTubeInterface>()->Offer(
            parameters,
            accessControl),
        OutgoingDBusTubeChannelPtr(this));

    PendingDBusTubeOffer *op = new PendingDBusTubeOffer(ps, OutgoingDBusTubeChannelPtr(this));
    return op;
}

}