~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2015-01-07 14:51:16 UTC
  • mfrom: (4.3.5 sid)
  • Revision ID: package-import@ubuntu.com-20150107145116-yxnafinf4lrdvrmx
Tags: 1.4.1-0.1ubuntu1
* Merge with Debian, remaining changes:
 - Drop soprano, nepomuk build-dep
* Drop ubuntu patches, now upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
#include "audio_symmetric_rtp_session.h"
36
36
#include "logger.h"
37
37
#include "sip/sipcall.h"
 
38
#include "manager.h"
 
39
#include "client/callmanager.h"
38
40
 
39
41
namespace sfl {
40
42
 
41
43
AudioSymmetricRtpSession::AudioSymmetricRtpSession(SIPCall &call) :
42
 
    ost::SymmetricRTPSession(ost::InetHostAddress(call.getLocalIp().c_str()), call.getLocalAudioPort())
 
44
    ost::SymmetricRTPSession(static_cast<ost::IPV4Host>(call.getLocalIp()), call.getLocalAudioPort())
43
45
    , AudioRtpSession(call, *this)
44
46
{
45
47
    DEBUG("Setting new RTP session with destination %s:%d",
46
 
          call_.getLocalIp().c_str(), call_.getLocalAudioPort());
47
 
    audioRtpRecord_.callId_ = call_.getCallId();
 
48
          call_.getLocalIp().toString().c_str(), call_.getLocalAudioPort());
 
49
}
 
50
 
 
51
AudioSymmetricRtpSession::~AudioSymmetricRtpSession()
 
52
{
 
53
    // This would normally be invoked in ost::~SymmetricRTPSession() BUT
 
54
    // we must stop it here because onRTPPacketRecv() runs in the other thread
 
55
    // and uses member variables that are destroyed here
 
56
    if (ost::Thread::isRunning()) {
 
57
        disableStack();
 
58
        ost::Thread::join();
 
59
    }
48
60
}
49
61
 
50
62
std::vector<long>
56
68
    return result;
57
69
}
58
70
 
59
 
void AudioSymmetricRtpSession::startReceiveThread()
 
71
void AudioSymmetricRtpSession::startRTPLoop()
60
72
{
61
 
    ost::SymmetricRTPSession::start();
 
73
    ost::SymmetricRTPSession::startRunning();
62
74
}
63
75
 
64
76
// redefined from QueueRTCPManager
65
77
void AudioSymmetricRtpSession::onGotRR(ost::SyncSource& source, ost::RTCPCompoundHandler::RecvReport& RR, uint8 blocks)
66
78
{
67
79
    ost::SymmetricRTPSession::onGotRR(source, RR, blocks);
 
80
#ifdef RTP_DEBUG
 
81
    DEBUG("onGotRR");
 
82
    DEBUG("Unpacking %d blocks",blocks);
 
83
    for (int i = 0; i < blocks; ++i)
 
84
    {
 
85
        DEBUG("fractionLost : %hhu", RR.blocks[i].rinfo.fractionLost);
 
86
        DEBUG("lostMSB : %hhu", RR.blocks[i].rinfo.lostMSB);
 
87
        DEBUG("lostLSW : %hu", RR.blocks[i].rinfo.lostLSW);
 
88
        DEBUG("highestSeqNum : %u", RR.blocks[i].rinfo.highestSeqNum);
 
89
        DEBUG("jitter : %u", RR.blocks[i].rinfo.jitter);
 
90
        DEBUG("lsr : %u", RR.blocks[i].rinfo.lsr);
 
91
        DEBUG("dlsr : %u", RR.blocks[i].rinfo.dlsr);
 
92
     }
 
93
#endif
 
94
}
 
95
 
 
96
// redefined from QueueRTCPManager
 
97
void AudioSymmetricRtpSession::onGotSR(ost::SyncSource& source, ost::RTCPCompoundHandler::SendReport& SR, uint8 blocks)
 
98
{
 
99
#ifdef RTP_DEBUG
 
100
    DEBUG("onGotSR");
 
101
    std::cout << "I got an SR RTCP report from "
 
102
            << std::hex << (int)source.getID() << "@"
 
103
            << std::dec
 
104
            << source.getNetworkAddress() << ":"
 
105
            << source.getControlTransportPort() << std::endl;
 
106
#endif
 
107
 
 
108
    std::map<std::string, int> stats;
 
109
    ost::SymmetricRTPSession::onGotSR(source, SR, blocks);
 
110
    ost::RTCPSenderInfo report(SR.sinfo);
 
111
 
 
112
    for (int i = 0; i < blocks; ++i)
 
113
    {
 
114
        // If this is the first report drop it, stats are not complete
 
115
        if(SR.blocks[i].rinfo.lsr == 0 || SR.blocks[i].rinfo.dlsr == 0)
 
116
            continue;
 
117
 
 
118
        ost::RTCPReceiverInfo receiver_report(SR.blocks[i].rinfo);
 
119
        /*
 
120
        How to calculate RTT (Round Trip delay)
 
121
        A : NTP timestamp
 
122
        lsr : The middle 32 bits out of 64 in the NTP timestamp (as explained in Section 4) received as part of the most
 
123
        recent RTCP sender report (SR) packet from source SSRC_n. If no SR has been received yet, the field is set to zero.
 
124
        dlsr : The delay, expressed in units of 1/65536 seconds, between receiving the last SR packet from source SSRC_n and
 
125
        sending this reception report block. If no SR packet has been received yet from SSRC_n, the DLSR field is set to zero.
 
126
        RTT = A - lsr - dlsr;
 
127
        */
 
128
 
 
129
        // integer portion of timestamp is in least significant 16-bits
 
130
        const uint16 timestamp = (uint16) report.getNTPTimestampInt() & 0x0000FFFF;
 
131
        // fractional portion of timestamp is in most significant 16-bits
 
132
        const uint16 timestampFrac = (uint16) report.getNTPTimestampFrac() >> 16;
 
133
 
 
134
 
 
135
        const uint16 rttMSW =  timestamp - receiver_report.getLastSRNTPTimestampInt();
 
136
        const uint16 rttLSW = timestampFrac - receiver_report.getLastSRNTPTimestampFrac();
 
137
 
 
138
        uint32 rtt = rttMSW;
 
139
        rtt = rtt << 16 | rttLSW;
 
140
        rtt -= receiver_report.getDelayLastSR();
 
141
        stats["PACKET_COUNT"] = report.getPacketCount();
 
142
        stats["PACKET_LOSS"] = receiver_report.getFractionLost();
 
143
        stats["CUMUL_PACKET_LOSS"] = receiver_report.getCumulativePacketLost();
 
144
        stats["RTT"] = rtt;
 
145
        stats["LATENCY"] = 0; //TODO
 
146
        stats["HIGH_SEC_NUM"] = receiver_report.getExtendedSeqNum();
 
147
        stats["JITTER"] = receiver_report.getJitter();
 
148
        stats["DLSR"] = receiver_report.getDelayLastSR();
 
149
 
 
150
#ifdef RTP_DEBUG
 
151
        DEBUG("lastSR NTPTimestamp : %lu", receiver_report.getLastSRNTPTimestampFrac() << 16);
 
152
        DEBUG("NTPTimestampFrac : %lu", timestampFrac);
 
153
        DEBUG("rttMSW : %u", rttMSW);
 
154
        DEBUG("rttLSW : %u", rttLSW);
 
155
        DEBUG("RTT recomposed: %lu", rtt);
 
156
        DEBUG("LDSR: %lu", receiver_report.getDelayLastSR());
 
157
        DEBUG("Packet count : %u", stats["PACKET_COUNT"]);
 
158
        DEBUG("Fraction packet loss : %.2f", (double) stats["PACKET_LOSS"] * 100 / 256);
 
159
        DEBUG("Cumulative packet loss : %d", stats["CUMUL_PACKET_LOSS"]);
 
160
        DEBUG("HighestSeqNum : %u", stats["HIGH_SEC_NUM"]);
 
161
        DEBUG("Jitter : %u", stats["JITTER"]);
 
162
        DEBUG("RTT : %.2f", (double) stats["RTT"] / 65536);
 
163
        DEBUG("Delay since last report %.2f seconds", (double) stats["DLSR"] / 65536.0);
 
164
#endif
 
165
        Manager::instance().getClient()->getCallManager()->onRtcpReportReceived(call_.getCallId(), stats);
 
166
    }
 
167
}
 
168
 
 
169
#if HAVE_IPV6
 
170
 
 
171
AudioSymmetricRtpSessionIPv6::AudioSymmetricRtpSessionIPv6(SIPCall &call) :
 
172
    ost::SymmetricRTPSessionIPV6(static_cast<ost::IPV6Host>(call.getLocalIp()), call.getLocalAudioPort())
 
173
    , AudioRtpSession(call, *this)
 
174
{
 
175
    DEBUG("Setting new RTP/IPv6 session with destination %s:%d",
 
176
          call_.getLocalIp().toString().c_str(), call_.getLocalAudioPort());
 
177
}
 
178
 
 
179
AudioSymmetricRtpSessionIPv6::~AudioSymmetricRtpSessionIPv6()
 
180
{
 
181
    // see explanation in AudioSymmetricRtpSessionIPv6()
 
182
    if (ost::Thread::isRunning()) {
 
183
        disableStack();
 
184
        ost::Thread::join();
 
185
    }
 
186
}
 
187
 
 
188
std::vector<long>
 
189
AudioSymmetricRtpSessionIPv6::getSocketDescriptors() const
 
190
{
 
191
    std::vector<long> result;
 
192
    result.push_back(dso->getRecvSocket());
 
193
    result.push_back(cso->getRecvSocket());
 
194
    return result;
 
195
}
 
196
 
 
197
void AudioSymmetricRtpSessionIPv6::startRTPLoop()
 
198
{
 
199
    ost::SymmetricRTPSessionIPV6::startRunning();
 
200
}
 
201
 
 
202
// redefined from QueueRTCPManager
 
203
void AudioSymmetricRtpSessionIPv6::onGotRR(ost::SyncSource& source, ost::RTCPCompoundHandler::RecvReport& RR, uint8 blocks)
 
204
{
 
205
    ost::SymmetricRTPSessionIPV6::onGotRR(source, RR, blocks);
68
206
    // TODO: do something with this data
69
207
#if 0
70
208
    std::cout << "I got an RR RTCP report from "
76
214
}
77
215
 
78
216
// redefined from QueueRTCPManager
79
 
void AudioSymmetricRtpSession::onGotSR(ost::SyncSource& source, ost::RTCPCompoundHandler::SendReport& SR, uint8 blocks)
 
217
void AudioSymmetricRtpSessionIPv6::onGotSR(ost::SyncSource& source, ost::RTCPCompoundHandler::SendReport& SR, uint8 blocks)
80
218
{
81
 
    ost::SymmetricRTPSession::onGotSR(source, SR, blocks);
 
219
    ost::SymmetricRTPSessionIPV6::onGotSR(source, SR, blocks);
82
220
    // TODO: do something with this data
83
221
}
84
222
 
 
223
size_t
 
224
AudioSymmetricRtpSessionIPv6::recvData(unsigned char* buffer, size_t len, ost::IPV4Host&, ost::tpport_t& port)
 
225
{
 
226
    ost::IPV6Host hostv6 = call_.getLocalIp();
 
227
    ERROR("recvData %d ", hostv6.getAddressCount());
 
228
    size_t r = ost::SymmetricRTPSessionIPV6::recvData(buffer, len, hostv6, port);
 
229
    ERROR("recvData from %s %d called in ipv6 stack, size %d", IpAddr(hostv6.getAddress()).toString().c_str(), port, len);
 
230
    return r;
 
231
}
 
232
 
 
233
size_t
 
234
AudioSymmetricRtpSessionIPv6::recvControl(unsigned char* buffer, size_t len, ost::IPV4Host&, ost::tpport_t& port)
 
235
{
 
236
    ost::IPV6Host hostv6 = call_.getLocalIp();
 
237
    size_t r = ost::SymmetricRTPSessionIPV6::recvControl(buffer, len, hostv6, port);
 
238
    ERROR("recvControl from %s %d called in ipv6 stack, size %d", IpAddr(hostv6.getAddress()).toString().c_str(), port, len);
 
239
    return r;
 
240
}
 
241
 
 
242
 
 
243
#endif // HAVE_IPV6
 
244
 
85
245
}