audio_rtp_factory.h 6.21 KB
Newer Older
1
/*
2
 *  Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
3
 *  Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com>
4
 *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
Julien Bonjean's avatar
Julien Bonjean committed
5
 *
6 7 8 9 10 11 12 13
 *  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.
Julien Bonjean's avatar
Julien Bonjean committed
14
 *
15 16
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
18 19 20 21 22 23 24 25 26 27 28
 *
 *  Additional permission under GNU GPL version 3 section 7:
 *
 *  If you modify this program, or any covered work, by linking or
 *  combining it with the OpenSSL project's OpenSSL library (or a
 *  modified version of that library), containing parts covered by the
 *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
 *  grants you additional permission to convey the resulting work.
 *  Corresponding Source for a non-source form of such a combination
 *  shall include the source code for the parts of OpenSSL used as well
 *  as that of the covered work.
29 30
 */

31 32
#ifndef __AUDIO_RTP_FACTORY_H__
#define __AUDIO_RTP_FACTORY_H__
33

34
#include <ccrtp/CryptoContext.h>
35
#include <stdexcept>
36
#include <mutex>
37
#include "audio_rtp_session.h"
38
#include "audio_srtp_session.h"
39
#include "noncopyable.h"
40

41
#include "sip/sdes_negotiator.h"
42 43

class SdesNegotiator;
44
class SIPCall;
45

46
namespace sfl {
47

48
#if HAVE_ZRTP
Julien Bonjean's avatar
Julien Bonjean committed
49
class AudioZrtpSession;
50
#endif
51
class AudioCodec;
52

53
class UnsupportedRtpSessionType : public std::logic_error {
Julien Bonjean's avatar
Julien Bonjean committed
54
    public:
55
        UnsupportedRtpSessionType(const std::string& msg = "") : std::logic_error(msg) {}
Julien Bonjean's avatar
Julien Bonjean committed
56 57
};

58
class AudioRtpFactoryException : public std::logic_error {
Julien Bonjean's avatar
Julien Bonjean committed
59
    public:
60
        AudioRtpFactoryException(const std::string& msg = "") : std::logic_error(msg) {}
Julien Bonjean's avatar
Julien Bonjean committed
61
};
62

63
class AudioRtpFactory {
Julien Bonjean's avatar
Julien Bonjean committed
64
    public:
65
        AudioRtpFactory(SIPCall *ca);
66 67
        ~AudioRtpFactory();

68
        std::vector<long>
69 70
        getSocketDescriptors() const;

71
        void initConfig();
Julien Bonjean's avatar
Julien Bonjean committed
72 73 74 75 76

        /**
         * 	Lazy instantiation method. Create a new RTP session of a given
         * type according to the content of the configuration file.
         * @param ca A pointer on a SIP call
77
         * @return A new AudioRtpSession object
Julien Bonjean's avatar
Julien Bonjean committed
78
         */
79
        void initSession();
Julien Bonjean's avatar
Julien Bonjean committed
80 81 82

        /**
         * Start the audio rtp thread of the type specified in the configuration
83
         * file. initAudioSymmetricRtpSession must have been called prior to that.
Julien Bonjean's avatar
Julien Bonjean committed
84 85
         * @param None
         */
86
        void start(const std::vector<AudioCodec*> &audioCodecs);
Julien Bonjean's avatar
Julien Bonjean committed
87 88 89

        /**
         * Stop the audio rtp thread of the type specified in the configuration
90
         * file. initAudioSymmetricRtpSession must have been called prior to that.
Julien Bonjean's avatar
Julien Bonjean committed
91 92 93 94
         * @param None
         */
        void stop();

95 96 97 98 99 100 101 102
        /**
         * Return the RTP payload currently used for this session
         */
        int getSessionMedia();

        /**
         * Dynamically update session media
         */
103
        void updateSessionMedia(const std::vector<AudioCodec*> &audioCodecs);
104

Julien Bonjean's avatar
Julien Bonjean committed
105 106 107 108
        /**
         * Update current RTP destination address with one stored in call
         * @param None
         */
109
        void updateDestinationIpAddress();
Julien Bonjean's avatar
Julien Bonjean committed
110

111
        bool isSdesEnabled() const {
112
            return srtpEnabled_ and keyExchangeProtocol_ == SDES;
Julien Bonjean's avatar
Julien Bonjean committed
113 114 115 116 117
        }

        /**
         * Manually set the srtpEnable option (usefull for RTP fallback)
         */
118
        void setSrtpEnabled(bool enable) {
119
            srtpEnabled_ = enable;
Julien Bonjean's avatar
Julien Bonjean committed
120 121
        }

122
#if HAVE_ZRTP
Julien Bonjean's avatar
Julien Bonjean committed
123 124 125 126 127
        /**
         * Get the current AudioZrtpSession. Throws an AudioRtpFactoryException
         * if the current rtp thread is null, or if it's not of the correct type.
         * @return The current AudioZrtpSession thread.
         */
128 129
        sfl::AudioZrtpSession* getAudioZrtpSession();
#endif
Julien Bonjean's avatar
Julien Bonjean committed
130

131
        void initLocalCryptoInfo();
132
        void initLocalCryptoInfoOnOffHold();
133

Julien Bonjean's avatar
Julien Bonjean committed
134 135 136 137
        /**
         * Set remote cryptographic info. Should be called after negotiation in SDP
         * offer/answer session.
         */
138
        void setRemoteCryptoInfo(sfl::SdesNegotiator& nego);
Julien Bonjean's avatar
Julien Bonjean committed
139

140 141
        void setDtmfPayloadType(unsigned int);

Julien Bonjean's avatar
Julien Bonjean committed
142 143 144 145 146 147
        /**
         * Send DTMF over RTP (RFC2833). The timestamp and sequence number must be
         * incremented as if it was microphone audio. This function change the payload type of the rtp session,
         * send the appropriate DTMF digit using this payload, discard coresponding data from mainbuffer and get
         * back the codec payload for further audio processing.
         */
148
        void sendDtmfDigit(int digit);
Julien Bonjean's avatar
Julien Bonjean committed
149

150 151 152 153
        void saveLocalContext();

        void restoreLocalContext();

154 155 156
        std::string
        getCurrentAudioCodecNames() const;

Julien Bonjean's avatar
Julien Bonjean committed
157
    private:
158
        NON_COPYABLE(AudioRtpFactory);
159
        enum KeyExchangeProtocol { NONE, SDES, ZRTP };
160
        AudioRtpSession *rtpSession_;
161
        std::mutex audioRtpThreadMutex_;
Julien Bonjean's avatar
Julien Bonjean committed
162

163
        // Field used when initializing audio rtp session
Julien Bonjean's avatar
Julien Bonjean committed
164
        // May be set manually or from config using initAudioRtpConfig
165
        bool srtpEnabled_;
Julien Bonjean's avatar
Julien Bonjean committed
166 167 168

        // Field used when initializinga udio rtp session
        // May be set manually or from config using initAudioRtpConfig
169
        bool helloHashEnabled_;
170

171
        /** local master key for outgoing packet encryption **/
172
        std::vector<uint8> cachedLocalMasterKey_;
173

174
        /** local master salt for outgoing packet encryption **/
175
        std::vector<uint8> cachedLocalMasterSalt_;
176

177
        /** remote master key for incoming packet decryption **/
178
        std::vector<uint8> cachedRemoteMasterKey_;
179

180
        /** remote master salt for incoming packet decryption **/
181
        std::vector<uint8> cachedRemoteMasterSalt_;
182 183 184 185

        /** Used to make sure remote crypto context not initialized twice. */
        bool remoteOfferIsSet_;

186
        SIPCall *ca_;
187
        KeyExchangeProtocol keyExchangeProtocol_;
188
};
189 190
}
#endif // __AUDIO_RTP_FACTORY_H__