35
35
#include "audio_symmetric_rtp_session.h"
36
36
#include "logger.h"
37
37
#include "sip/sipcall.h"
39
#include "client/callmanager.h"
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)
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());
51
AudioSymmetricRtpSession::~AudioSymmetricRtpSession()
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()) {
59
void AudioSymmetricRtpSession::startReceiveThread()
71
void AudioSymmetricRtpSession::startRTPLoop()
61
ost::SymmetricRTPSession::start();
73
ost::SymmetricRTPSession::startRunning();
64
76
// redefined from QueueRTCPManager
65
77
void AudioSymmetricRtpSession::onGotRR(ost::SyncSource& source, ost::RTCPCompoundHandler::RecvReport& RR, uint8 blocks)
67
79
ost::SymmetricRTPSession::onGotRR(source, RR, blocks);
82
DEBUG("Unpacking %d blocks",blocks);
83
for (int i = 0; i < blocks; ++i)
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);
96
// redefined from QueueRTCPManager
97
void AudioSymmetricRtpSession::onGotSR(ost::SyncSource& source, ost::RTCPCompoundHandler::SendReport& SR, uint8 blocks)
101
std::cout << "I got an SR RTCP report from "
102
<< std::hex << (int)source.getID() << "@"
104
<< source.getNetworkAddress() << ":"
105
<< source.getControlTransportPort() << std::endl;
108
std::map<std::string, int> stats;
109
ost::SymmetricRTPSession::onGotSR(source, SR, blocks);
110
ost::RTCPSenderInfo report(SR.sinfo);
112
for (int i = 0; i < blocks; ++i)
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)
118
ost::RTCPReceiverInfo receiver_report(SR.blocks[i].rinfo);
120
How to calculate RTT (Round Trip delay)
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;
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;
135
const uint16 rttMSW = timestamp - receiver_report.getLastSRNTPTimestampInt();
136
const uint16 rttLSW = timestampFrac - receiver_report.getLastSRNTPTimestampFrac();
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();
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();
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);
165
Manager::instance().getClient()->getCallManager()->onRtcpReportReceived(call_.getCallId(), stats);
171
AudioSymmetricRtpSessionIPv6::AudioSymmetricRtpSessionIPv6(SIPCall &call) :
172
ost::SymmetricRTPSessionIPV6(static_cast<ost::IPV6Host>(call.getLocalIp()), call.getLocalAudioPort())
173
, AudioRtpSession(call, *this)
175
DEBUG("Setting new RTP/IPv6 session with destination %s:%d",
176
call_.getLocalIp().toString().c_str(), call_.getLocalAudioPort());
179
AudioSymmetricRtpSessionIPv6::~AudioSymmetricRtpSessionIPv6()
181
// see explanation in AudioSymmetricRtpSessionIPv6()
182
if (ost::Thread::isRunning()) {
189
AudioSymmetricRtpSessionIPv6::getSocketDescriptors() const
191
std::vector<long> result;
192
result.push_back(dso->getRecvSocket());
193
result.push_back(cso->getRecvSocket());
197
void AudioSymmetricRtpSessionIPv6::startRTPLoop()
199
ost::SymmetricRTPSessionIPV6::startRunning();
202
// redefined from QueueRTCPManager
203
void AudioSymmetricRtpSessionIPv6::onGotRR(ost::SyncSource& source, ost::RTCPCompoundHandler::RecvReport& RR, uint8 blocks)
205
ost::SymmetricRTPSessionIPV6::onGotRR(source, RR, blocks);
68
206
// TODO: do something with this data
70
208
std::cout << "I got an RR RTCP report from "
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)
81
ost::SymmetricRTPSession::onGotSR(source, SR, blocks);
219
ost::SymmetricRTPSessionIPV6::onGotSR(source, SR, blocks);
82
220
// TODO: do something with this data
224
AudioSymmetricRtpSessionIPv6::recvData(unsigned char* buffer, size_t len, ost::IPV4Host&, ost::tpport_t& port)
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);
234
AudioSymmetricRtpSessionIPv6::recvControl(unsigned char* buffer, size_t len, ost::IPV4Host&, ost::tpport_t& port)
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);