1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
12#include "webrtc/system_wrappers/include/file_wrapper.h"
13#include "webrtc/system_wrappers/include/trace.h"
14#include "webrtc/voice_engine/include/voe_errors.h"
15#include "webrtc/voice_engine/voe_rtp_rtcp_impl.h"
16#include "webrtc/voice_engine/voice_engine_impl.h"
17
18#include "webrtc/voice_engine/channel.h"
19#include "webrtc/voice_engine/transmit_mixer.h"
20
21namespace webrtc {
22
23VoERTP_RTCP* VoERTP_RTCP::GetInterface(VoiceEngine* voiceEngine) {
24#ifndef WEBRTC_VOICE_ENGINE_RTP_RTCP_API
25  return NULL;
26#else
27  if (NULL == voiceEngine) {
28    return NULL;
29  }
30  VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
31  s->AddRef();
32  return s;
33#endif
34}
35
36#ifdef WEBRTC_VOICE_ENGINE_RTP_RTCP_API
37
38VoERTP_RTCPImpl::VoERTP_RTCPImpl(voe::SharedData* shared) : _shared(shared) {
39  WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
40               "VoERTP_RTCPImpl::VoERTP_RTCPImpl() - ctor");
41}
42
43VoERTP_RTCPImpl::~VoERTP_RTCPImpl() {
44  WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
45               "VoERTP_RTCPImpl::~VoERTP_RTCPImpl() - dtor");
46}
47
48int VoERTP_RTCPImpl::SetLocalSSRC(int channel, unsigned int ssrc) {
49  WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
50               "SetLocalSSRC(channel=%d, %lu)", channel, ssrc);
51  if (!_shared->statistics().Initialized()) {
52    _shared->SetLastError(VE_NOT_INITED, kTraceError);
53    return -1;
54  }
55  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
56  voe::Channel* channelPtr = ch.channel();
57  if (channelPtr == NULL) {
58    _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
59                          "SetLocalSSRC() failed to locate channel");
60    return -1;
61  }
62  return channelPtr->SetLocalSSRC(ssrc);
63}
64
65int VoERTP_RTCPImpl::GetLocalSSRC(int channel, unsigned int& ssrc) {
66  if (!_shared->statistics().Initialized()) {
67    _shared->SetLastError(VE_NOT_INITED, kTraceError);
68    return -1;
69  }
70  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
71  voe::Channel* channelPtr = ch.channel();
72  if (channelPtr == NULL) {
73    _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
74                          "GetLocalSSRC() failed to locate channel");
75    return -1;
76  }
77  return channelPtr->GetLocalSSRC(ssrc);
78}
79
80int VoERTP_RTCPImpl::GetRemoteSSRC(int channel, unsigned int& ssrc) {
81  if (!_shared->statistics().Initialized()) {
82    _shared->SetLastError(VE_NOT_INITED, kTraceError);
83    return -1;
84  }
85  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
86  voe::Channel* channelPtr = ch.channel();
87  if (channelPtr == NULL) {
88    _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
89                          "GetRemoteSSRC() failed to locate channel");
90    return -1;
91  }
92  return channelPtr->GetRemoteSSRC(ssrc);
93}
94
95int VoERTP_RTCPImpl::SetSendAudioLevelIndicationStatus(int channel,
96                                                       bool enable,
97                                                       unsigned char id) {
98  WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
99               "SetSendAudioLevelIndicationStatus(channel=%d, enable=%d,"
100               " ID=%u)",
101               channel, enable, id);
102  if (!_shared->statistics().Initialized()) {
103    _shared->SetLastError(VE_NOT_INITED, kTraceError);
104    return -1;
105  }
106  if (enable && (id < kVoiceEngineMinRtpExtensionId ||
107                 id > kVoiceEngineMaxRtpExtensionId)) {
108    // [RFC5285] The 4-bit id is the local identifier of this element in
109    // the range 1-14 inclusive.
110    _shared->SetLastError(
111        VE_INVALID_ARGUMENT, kTraceError,
112        "SetSendAudioLevelIndicationStatus() invalid ID parameter");
113    return -1;
114  }
115
116  // Set state and id for the specified channel.
117  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
118  voe::Channel* channelPtr = ch.channel();
119  if (channelPtr == NULL) {
120    _shared->SetLastError(
121        VE_CHANNEL_NOT_VALID, kTraceError,
122        "SetSendAudioLevelIndicationStatus() failed to locate channel");
123    return -1;
124  }
125  return channelPtr->SetSendAudioLevelIndicationStatus(enable, id);
126}
127
128int VoERTP_RTCPImpl::SetReceiveAudioLevelIndicationStatus(int channel,
129                                                          bool enable,
130                                                          unsigned char id) {
131  WEBRTC_TRACE(
132      kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
133      "SetReceiveAudioLevelIndicationStatus(channel=%d, enable=%d, id=%u)",
134      channel, enable, id);
135  if (!_shared->statistics().Initialized()) {
136    _shared->SetLastError(VE_NOT_INITED, kTraceError);
137    return -1;
138  }
139  if (enable && (id < kVoiceEngineMinRtpExtensionId ||
140                 id > kVoiceEngineMaxRtpExtensionId)) {
141    // [RFC5285] The 4-bit id is the local identifier of this element in
142    // the range 1-14 inclusive.
143    _shared->SetLastError(
144        VE_INVALID_ARGUMENT, kTraceError,
145        "SetReceiveAbsoluteSenderTimeStatus() invalid id parameter");
146    return -1;
147  }
148  // Set state and id for the specified channel.
149  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
150  voe::Channel* channel_ptr = ch.channel();
151  if (channel_ptr == NULL) {
152    _shared->SetLastError(
153        VE_CHANNEL_NOT_VALID, kTraceError,
154        "SetReceiveAudioLevelIndicationStatus() failed to locate channel");
155    return -1;
156  }
157  return channel_ptr->SetReceiveAudioLevelIndicationStatus(enable, id);
158}
159
160int VoERTP_RTCPImpl::SetSendAbsoluteSenderTimeStatus(int channel,
161                                                     bool enable,
162                                                     unsigned char id) {
163  WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
164               "SetSendAbsoluteSenderTimeStatus(channel=%d, enable=%d, id=%u)",
165               channel, enable, id);
166  if (!_shared->statistics().Initialized()) {
167    _shared->SetLastError(VE_NOT_INITED, kTraceError);
168    return -1;
169  }
170  if (enable && (id < kVoiceEngineMinRtpExtensionId ||
171                 id > kVoiceEngineMaxRtpExtensionId)) {
172    // [RFC5285] The 4-bit id is the local identifier of this element in
173    // the range 1-14 inclusive.
174    _shared->SetLastError(
175        VE_INVALID_ARGUMENT, kTraceError,
176        "SetSendAbsoluteSenderTimeStatus() invalid id parameter");
177    return -1;
178  }
179  // Set state and id for the specified channel.
180  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
181  voe::Channel* channelPtr = ch.channel();
182  if (channelPtr == NULL) {
183    _shared->SetLastError(
184        VE_CHANNEL_NOT_VALID, kTraceError,
185        "SetSendAbsoluteSenderTimeStatus() failed to locate channel");
186    return -1;
187  }
188  return channelPtr->SetSendAbsoluteSenderTimeStatus(enable, id);
189}
190
191int VoERTP_RTCPImpl::SetReceiveAbsoluteSenderTimeStatus(int channel,
192                                                        bool enable,
193                                                        unsigned char id) {
194  WEBRTC_TRACE(
195      kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
196      "SetReceiveAbsoluteSenderTimeStatus(channel=%d, enable=%d, id=%u)",
197      channel, enable, id);
198  if (!_shared->statistics().Initialized()) {
199    _shared->SetLastError(VE_NOT_INITED, kTraceError);
200    return -1;
201  }
202  if (enable && (id < kVoiceEngineMinRtpExtensionId ||
203                 id > kVoiceEngineMaxRtpExtensionId)) {
204    // [RFC5285] The 4-bit id is the local identifier of this element in
205    // the range 1-14 inclusive.
206    _shared->SetLastError(
207        VE_INVALID_ARGUMENT, kTraceError,
208        "SetReceiveAbsoluteSenderTimeStatus() invalid id parameter");
209    return -1;
210  }
211  // Set state and id for the specified channel.
212  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
213  voe::Channel* channelPtr = ch.channel();
214  if (channelPtr == NULL) {
215    _shared->SetLastError(
216        VE_CHANNEL_NOT_VALID, kTraceError,
217        "SetReceiveAbsoluteSenderTimeStatus() failed to locate channel");
218    return -1;
219  }
220  return channelPtr->SetReceiveAbsoluteSenderTimeStatus(enable, id);
221}
222
223int VoERTP_RTCPImpl::SetRTCPStatus(int channel, bool enable) {
224  WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
225               "SetRTCPStatus(channel=%d, enable=%d)", channel, enable);
226  if (!_shared->statistics().Initialized()) {
227    _shared->SetLastError(VE_NOT_INITED, kTraceError);
228    return -1;
229  }
230  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
231  voe::Channel* channelPtr = ch.channel();
232  if (channelPtr == NULL) {
233    _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
234                          "SetRTCPStatus() failed to locate channel");
235    return -1;
236  }
237  channelPtr->SetRTCPStatus(enable);
238  return 0;
239}
240
241int VoERTP_RTCPImpl::GetRTCPStatus(int channel, bool& enabled) {
242  if (!_shared->statistics().Initialized()) {
243    _shared->SetLastError(VE_NOT_INITED, kTraceError);
244    return -1;
245  }
246  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
247  voe::Channel* channelPtr = ch.channel();
248  if (channelPtr == NULL) {
249    _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
250                          "GetRTCPStatus() failed to locate channel");
251    return -1;
252  }
253  return channelPtr->GetRTCPStatus(enabled);
254}
255
256int VoERTP_RTCPImpl::SetRTCP_CNAME(int channel, const char cName[256]) {
257  WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
258               "SetRTCP_CNAME(channel=%d, cName=%s)", channel, cName);
259  if (!_shared->statistics().Initialized()) {
260    _shared->SetLastError(VE_NOT_INITED, kTraceError);
261    return -1;
262  }
263  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
264  voe::Channel* channelPtr = ch.channel();
265  if (channelPtr == NULL) {
266    _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
267                          "SetRTCP_CNAME() failed to locate channel");
268    return -1;
269  }
270  return channelPtr->SetRTCP_CNAME(cName);
271}
272
273int VoERTP_RTCPImpl::GetRemoteRTCP_CNAME(int channel, char cName[256]) {
274  if (!_shared->statistics().Initialized()) {
275    _shared->SetLastError(VE_NOT_INITED, kTraceError);
276    return -1;
277  }
278  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
279  voe::Channel* channelPtr = ch.channel();
280  if (channelPtr == NULL) {
281    _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
282                          "GetRemoteRTCP_CNAME() failed to locate channel");
283    return -1;
284  }
285  return channelPtr->GetRemoteRTCP_CNAME(cName);
286}
287
288int VoERTP_RTCPImpl::GetRemoteRTCPData(
289    int channel,
290    unsigned int& NTPHigh,           // from sender info in SR
291    unsigned int& NTPLow,            // from sender info in SR
292    unsigned int& timestamp,         // from sender info in SR
293    unsigned int& playoutTimestamp,  // derived locally
294    unsigned int* jitter,            // from report block 1 in SR/RR
295    unsigned short* fractionLost)    // from report block 1 in SR/RR
296{
297  if (!_shared->statistics().Initialized()) {
298    _shared->SetLastError(VE_NOT_INITED, kTraceError);
299    return -1;
300  }
301  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
302  voe::Channel* channelPtr = ch.channel();
303  if (channelPtr == NULL) {
304    _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
305                          "GetRemoteRTCP_CNAME() failed to locate channel");
306    return -1;
307  }
308  return channelPtr->GetRemoteRTCPData(NTPHigh, NTPLow, timestamp,
309                                       playoutTimestamp, jitter, fractionLost);
310}
311
312int VoERTP_RTCPImpl::GetRTPStatistics(int channel,
313                                      unsigned int& averageJitterMs,
314                                      unsigned int& maxJitterMs,
315                                      unsigned int& discardedPackets) {
316  if (!_shared->statistics().Initialized()) {
317    _shared->SetLastError(VE_NOT_INITED, kTraceError);
318    return -1;
319  }
320  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
321  voe::Channel* channelPtr = ch.channel();
322  if (channelPtr == NULL) {
323    _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
324                          "GetRTPStatistics() failed to locate channel");
325    return -1;
326  }
327  return channelPtr->GetRTPStatistics(averageJitterMs, maxJitterMs,
328                                      discardedPackets);
329}
330
331int VoERTP_RTCPImpl::GetRTCPStatistics(int channel, CallStatistics& stats) {
332  if (!_shared->statistics().Initialized()) {
333    _shared->SetLastError(VE_NOT_INITED, kTraceError);
334    return -1;
335  }
336  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
337  voe::Channel* channelPtr = ch.channel();
338  if (channelPtr == NULL) {
339    _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
340                          "GetRTPStatistics() failed to locate channel");
341    return -1;
342  }
343  return channelPtr->GetRTPStatistics(stats);
344}
345
346int VoERTP_RTCPImpl::GetRemoteRTCPReportBlocks(
347    int channel, std::vector<ReportBlock>* report_blocks) {
348  if (!_shared->statistics().Initialized()) {
349    _shared->SetLastError(VE_NOT_INITED, kTraceError);
350    return -1;
351  }
352  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
353  voe::Channel* channel_ptr = ch.channel();
354  if (channel_ptr == NULL) {
355    _shared->SetLastError(
356        VE_CHANNEL_NOT_VALID, kTraceError,
357        "GetRemoteRTCPReportBlocks() failed to locate channel");
358    return -1;
359  }
360  return channel_ptr->GetRemoteRTCPReportBlocks(report_blocks);
361}
362
363int VoERTP_RTCPImpl::SetREDStatus(int channel,
364                                  bool enable,
365                                  int redPayloadtype) {
366  WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
367               "SetREDStatus(channel=%d, enable=%d, redPayloadtype=%d)",
368               channel, enable, redPayloadtype);
369#ifdef WEBRTC_CODEC_RED
370  if (!_shared->statistics().Initialized()) {
371    _shared->SetLastError(VE_NOT_INITED, kTraceError);
372    return -1;
373  }
374  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
375  voe::Channel* channelPtr = ch.channel();
376  if (channelPtr == NULL) {
377    _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
378                          "SetREDStatus() failed to locate channel");
379    return -1;
380  }
381  return channelPtr->SetREDStatus(enable, redPayloadtype);
382#else
383  _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
384                        "SetREDStatus() RED is not supported");
385  return -1;
386#endif
387}
388
389int VoERTP_RTCPImpl::GetREDStatus(int channel,
390                                  bool& enabled,
391                                  int& redPayloadtype) {
392#ifdef WEBRTC_CODEC_RED
393  if (!_shared->statistics().Initialized()) {
394    _shared->SetLastError(VE_NOT_INITED, kTraceError);
395    return -1;
396  }
397  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
398  voe::Channel* channelPtr = ch.channel();
399  if (channelPtr == NULL) {
400    _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
401                          "GetREDStatus() failed to locate channel");
402    return -1;
403  }
404  return channelPtr->GetREDStatus(enabled, redPayloadtype);
405#else
406  _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
407                        "GetREDStatus() RED is not supported");
408  return -1;
409#endif
410}
411
412int VoERTP_RTCPImpl::SetNACKStatus(int channel, bool enable, int maxNoPackets) {
413  WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
414               "SetNACKStatus(channel=%d, enable=%d, maxNoPackets=%d)", channel,
415               enable, maxNoPackets);
416
417  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
418  voe::Channel* channelPtr = ch.channel();
419  if (channelPtr == NULL) {
420    _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
421                          "SetNACKStatus() failed to locate channel");
422    return -1;
423  }
424  channelPtr->SetNACKStatus(enable, maxNoPackets);
425  return 0;
426}
427
428#endif  // #ifdef WEBRTC_VOICE_ENGINE_RTP_RTCP_API
429
430}  // namespace webrtc
431