aboutsummaryrefslogtreecommitdiff
path: root/src/QXmppCallManager.h
blob: 29da58dd485c8c4e6843f7acd12b477109a5cedf (plain) (blame)
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
/*
 * Copyright (C) 2008-2010 The QXmpp developers
 *
 * Author:
 *  Jeremy Lainé
 *
 * Source:
 *  http://code.google.com/p/qxmpp
 *
 * This file is a part of QXmpp library.
 *
 * 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.
 *
 */

#ifndef QXMPPCALLMANAGER_H
#define QXMPPCALLMANAGER_H

#include <QObject>
#include <QIODevice>
#include <QMetaType>

#include "QXmppClientExtension.h"
#include "QXmppLogger.h"

class QXmppCallPrivate;
class QXmppIq;
class QXmppJingleCandidate;
class QXmppJingleIq;
class QXmppJinglePayloadType;
class QXmppRtpChannel;

/// \brief The QXmppCall class represents a Voice-Over-IP call to a remote party.
///
/// To get the QIODevice from which you can read / write audio samples, call
/// audioChannel().
///
/// \note THIS API IS NOT FINALIZED YET

class QXmppCall : public QXmppLoggable
{
    Q_OBJECT

public:
    /// This enum is used to describe the direction of a call.
    enum Direction
    {
        IncomingDirection, ///< The call is incoming.
        OutgoingDirection, ///< The call is outgoing.
    };

    /// This enum is used to describe the state of a call.
    enum State
    {
        OfferState = 0,         ///< The remote part is being called.
        ConnectingState = 1,    ///< The call is being connected.
        ActiveState = 2,        ///< The call is active.
        DisconnectingState = 3, ///< The call is being disconnected.
        FinishedState = 4,      ///< The call is finished.
    };

    ~QXmppCall();

    QXmppCall::Direction direction() const;
    QString jid() const;
    QString sid() const;
    QXmppCall::State state() const;

    QXmppRtpChannel *audioChannel() const;

signals:
    /// This signal is emitted when a call is connected.
    ///
    /// Once this signal is emitted, you can connect a QAudioOutput and
    /// QAudioInput to the call. You can determine the appropriate clockrate
    /// and the number of channels by calling payloadType().
    void connected();

    /// This signal is emitted when a call is finished.
    ///
    /// Note: Do not delete the call in the slot connected to this signal,
    /// instead use deleteLater().
    void finished();

    /// \internal
    void localCandidatesChanged();

    /// This signal is emitted when the remote party is ringing.
    void ringing();

    /// This signal is emitted when the call state changes.
    void stateChanged(QXmppCall::State state);

public slots:
    void accept();
    void hangup();

private slots:
    void datagramReceived(int component, const QByteArray &datagram);
    void updateOpenMode();
    void terminate();
    void terminated();

private:
    QXmppCall(const QString &jid, QXmppCall::Direction direction, QObject *parent);
    void setPayloadType(const QXmppJinglePayloadType &type);
    void addRemoteCandidates(const QList<QXmppJingleCandidate> &candidates);
    void setState(QXmppCall::State state);

    QXmppCallPrivate * const d;
    friend class QXmppCallManager;
};

/// \brief The QXmppCallManager class provides support for making and
/// receiving voice calls.
///
/// Session initiation is performed as described by XEP-0166: Jingle,
/// XEP-0167: Jingle RTP Sessions and XEP-0176: Jingle ICE-UDP Transport
/// Method.
///
/// The data stream is connected using Interactive Connectivity Establishment
/// (RFC 5245) and data is transferred using Real Time Protocol (RFC 3550)
/// packets.
///
/// \ingroup Managers

class QXmppCallManager : public QXmppClientExtension
{
    Q_OBJECT

public:
    QXmppCallManager(QXmppClient *client);
    QXmppCall *call(const QString &jid);

    /// \cond
    QStringList discoveryFeatures() const;
    bool handleStanza(const QDomElement &element);
    /// \endcond

signals:
    /// This signal is emitted when a new incoming call is received.
    ///
    /// To accept the call, invoke the call's QXmppCall::accept() method.
    /// To refuse the call, invoke the call's QXmppCall::abort() method.
    void callReceived(QXmppCall *call);

private slots:
    void callDestroyed(QObject *object);
    void callStateChanged(QXmppCall::State state);
    void iqReceived(const QXmppIq &iq);
    void jingleIqReceived(const QXmppJingleIq &iq);
    void localCandidatesChanged();

private:
    bool checkPayloadTypes(QXmppCall *call, const QList<QXmppJinglePayloadType> &remotePayloadTypes);
    QXmppCall *findCall(const QString &sid) const;
    QXmppCall *findCall(const QString &sid, QXmppCall::Direction direction) const;
    bool sendAck(const QXmppJingleIq &iq);
    bool sendRequest(QXmppCall *call, const QXmppJingleIq &iq);

    QList<QXmppCall*> m_calls;
};

Q_DECLARE_METATYPE(QXmppCall::State)

#endif