audio_zrtp_session.cpp 4.92 KB
Newer Older
1
/*
2
 *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
3
 *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
4 5 6 7 8 9 10 11 12 13
 *  Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com>
 *
 *  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.
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
#ifdef HAVE_CONFIG_H
32
#include "config.h"
33 34
#endif

35 36
#include "audio_zrtp_session.h"
#include "zrtp_session_callback.h"
37
#include "sip/sipcall.h"
38
#include "logger.h"
39
#include "manager.h"
40
#include "fileutils.h"
41

42
#include <libzrtpcpp/zrtpccrtp.h>
43 44
#include <libzrtpcpp/ZrtpQueue.h>
#include <libzrtpcpp/ZrtpUserCallback.h>
45 46
#include <ccrtp/rtp.h>

47
namespace sfl {
48

49
AudioZrtpSession::AudioZrtpSession(SIPCall &call, const std::string &zidFilename) :
50
    ost::SymmetricZRTPSession(ost::InetHostAddress(call.getLocalIp().c_str()), call.getLocalAudioPort())
51 52 53
    , AudioRtpSession(call, *this, *this)
    , zidFilename_(zidFilename)
    , rtpThread_(*this)
54 55
{
    initializeZid();
56
    DEBUG("Setting new RTP session with destination %s:%d",
57
          call_.getLocalIp().c_str(), call_.getLocalAudioPort());
58
    audioRtpRecord_.callId_ = call_.getCallId();
59 60 61 62
}

AudioZrtpSession::~AudioZrtpSession()
{
63 64 65 66
    if (rtpThread_.running_) {
        rtpThread_.running_ = false;
        rtpThread_.join();
    }
67 68
}

69

70
void AudioZrtpSession::initializeZid()
71
{
72
    if (zidFilename_.empty())
73
        throw ZrtpZidException("zid filename empty");
74

75 76
    std::string zidCompleteFilename;

77
    std::string xdg_config = std::string(HOMEDIR) + DIR_SEPARATOR_STR + ".cache" + DIR_SEPARATOR_STR + PACKAGE + "/" + zidFilename_;
78

79
    DEBUG("xdg_config %s", xdg_config.c_str());
80 81

    if (XDG_CACHE_HOME != NULL) {
82
        std::string xdg_env = std::string(XDG_CACHE_HOME) + zidFilename_;
83
        DEBUG("xdg_env %s", xdg_env.c_str());
84
        (xdg_env.length() > 0) ? zidCompleteFilename = xdg_env : zidCompleteFilename = xdg_config;
85
    } else
86
        zidCompleteFilename = xdg_config;
87

88

89 90
    if (initialize(zidCompleteFilename.c_str()) >= 0) {
        setEnableZrtp(true);
91
        setUserCallback(new ZrtpSessionCallback(call_));
92 93
        return;
    }
94

95
    DEBUG("Initialization from ZID file failed. Trying to remove...");
96

97
    if (remove(zidCompleteFilename.c_str()) != 0)
98
        throw ZrtpZidException("zid file deletion failed");
99

100
    if (initialize(zidCompleteFilename.c_str()) < 0)
101
        throw ZrtpZidException("zid initialization failed");
102 103 104

    return;
}
105

106 107 108 109 110 111 112 113 114 115 116 117
void AudioZrtpSession::sendMicData()
{
    int compSize = processDataEncode();

    // if no data return
    if (compSize == 0)
        return;

    // Increment timestamp for outgoing packet
    timestamp_ += timestampIncrement_;

    // this step is only needed for ZRTP
118
    queue_.putData(timestamp_, getMicDataEncoded(), compSize);
119 120

    // putData puts the data on RTP queue, sendImmediate bypasses this queue
121
    queue_.sendImmediate(timestamp_, getMicDataEncoded(), compSize);
122 123
}

124 125 126 127
AudioZrtpSession::AudioZrtpThread::AudioZrtpThread(AudioZrtpSession &session) : running_(true), zrtpSession_(session)
{}

void AudioZrtpSession::AudioZrtpThread::run()
128
{
129
    DEBUG("Entering Audio zrtp thread main loop %s", running_ ? "running" : "not running");
130

131
    TimerPort::setTimer(zrtpSession_.transportRate_);
132

133
    while (running_) {
134
        // Send session
135 136
        if (zrtpSession_.hasDTMFPending())
            zrtpSession_.sendDtmfEvent();
137
        else
138 139 140 141
            zrtpSession_.sendMicData();

        Thread::sleep(TimerPort::getTimer());

142
        TimerPort::incTimer(zrtpSession_.transportRate_);
143 144
    }

145
    DEBUG("Leaving audio rtp thread loop");
146
}
147

148
int AudioZrtpSession::getIncrementForDTMF() const
149
{
150
    return 160;
151 152
}

153 154 155 156 157 158 159 160 161
int AudioZrtpSession::startRtpThread(AudioCodec &audiocodec)
{
    if(isStarted_)
        return 0;

    AudioRtpSession::startRtpThread(audiocodec);
    return startZrtpThread();
}

162
}