1/*
2 *  Copyright (c) 2014 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/modules/interface/module_common_types.h"
12#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
13#include "webrtc/system_wrappers/interface/atomic32.h"
14#include "webrtc/system_wrappers/interface/sleep.h"
15#include "webrtc/video_engine/include/vie_network.h"
16#include "webrtc/voice_engine/test/auto_test/fixtures/before_streaming_fixture.h"
17
18using ::testing::_;
19using ::testing::AtLeast;
20using ::testing::Eq;
21using ::testing::Field;
22
23class ExtensionVerifyTransport : public webrtc::Transport {
24 public:
25  ExtensionVerifyTransport()
26      : parser_(webrtc::RtpHeaderParser::Create()),
27        received_packets_(0),
28        bad_packets_(0),
29        audio_level_id_(-1),
30        absolute_sender_time_id_(-1) {}
31
32  virtual int SendPacket(int channel, const void* data, int len) {
33    webrtc::RTPHeader header;
34    if (parser_->Parse(reinterpret_cast<const uint8_t*>(data),
35                       static_cast<size_t>(len),
36                       &header)) {
37      bool ok = true;
38      if (audio_level_id_ >= 0 &&
39          !header.extension.hasAudioLevel) {
40        ok = false;
41      }
42      if (absolute_sender_time_id_ >= 0 &&
43          !header.extension.hasAbsoluteSendTime) {
44        ok = false;
45      }
46      if (!ok) {
47        // bad_packets_ count packets we expected to have an extension but
48        // didn't have one.
49        ++bad_packets_;
50      }
51    }
52    // received_packets_ count all packets we receive.
53    ++received_packets_;
54    return len;
55  }
56
57  virtual int SendRTCPPacket(int channel, const void* data, int len) {
58    return len;
59  }
60
61  void SetAudioLevelId(int id) {
62    audio_level_id_ = id;
63    parser_->RegisterRtpHeaderExtension(webrtc::kRtpExtensionAudioLevel, id);
64  }
65
66  void SetAbsoluteSenderTimeId(int id) {
67    absolute_sender_time_id_ = id;
68    parser_->RegisterRtpHeaderExtension(webrtc::kRtpExtensionAbsoluteSendTime,
69                                        id);
70  }
71
72  bool Wait() {
73    // Wait until we've received to specified number of packets.
74    while (received_packets_.Value() < kPacketsExpected) {
75      webrtc::SleepMs(kSleepIntervalMs);
76    }
77    // Check whether any where 'bad' (didn't contain an extension when they
78    // where supposed to).
79    return bad_packets_.Value() == 0;
80  }
81
82 private:
83  enum {
84    kPacketsExpected = 10,
85    kSleepIntervalMs = 10
86  };
87  webrtc::scoped_ptr<webrtc::RtpHeaderParser> parser_;
88  webrtc::Atomic32 received_packets_;
89  webrtc::Atomic32 bad_packets_;
90  int audio_level_id_;
91  int absolute_sender_time_id_;
92};
93
94class SendRtpRtcpHeaderExtensionsTest : public BeforeStreamingFixture {
95 protected:
96  virtual void SetUp() {
97    EXPECT_EQ(0, voe_network_->DeRegisterExternalTransport(channel_));
98    EXPECT_EQ(0, voe_network_->RegisterExternalTransport(channel_,
99                                                         verifying_transport_));
100  }
101  virtual void TearDown() {
102    PausePlaying();
103  }
104
105  ExtensionVerifyTransport verifying_transport_;
106};
107
108TEST_F(SendRtpRtcpHeaderExtensionsTest, SentPacketsIncludeNoAudioLevel) {
109  verifying_transport_.SetAudioLevelId(0);
110  ResumePlaying();
111  EXPECT_FALSE(verifying_transport_.Wait());
112}
113
114TEST_F(SendRtpRtcpHeaderExtensionsTest, SentPacketsIncludeAudioLevel) {
115  EXPECT_EQ(0, voe_rtp_rtcp_->SetSendAudioLevelIndicationStatus(channel_, true,
116                                                                9));
117  verifying_transport_.SetAudioLevelId(9);
118  ResumePlaying();
119  EXPECT_TRUE(verifying_transport_.Wait());
120}
121
122TEST_F(SendRtpRtcpHeaderExtensionsTest, SentPacketsIncludeNoAbsoluteSenderTime)
123{
124  verifying_transport_.SetAbsoluteSenderTimeId(0);
125  ResumePlaying();
126  EXPECT_FALSE(verifying_transport_.Wait());
127}
128
129TEST_F(SendRtpRtcpHeaderExtensionsTest, SentPacketsIncludeAbsoluteSenderTime) {
130  EXPECT_EQ(0, voe_rtp_rtcp_->SetSendAbsoluteSenderTimeStatus(channel_, true,
131                                                              11));
132  verifying_transport_.SetAbsoluteSenderTimeId(11);
133  ResumePlaying();
134  EXPECT_TRUE(verifying_transport_.Wait());
135}
136
137TEST_F(SendRtpRtcpHeaderExtensionsTest, SentPacketsIncludeAllExtensions1) {
138  EXPECT_EQ(0, voe_rtp_rtcp_->SetSendAudioLevelIndicationStatus(channel_, true,
139                                                                9));
140  EXPECT_EQ(0, voe_rtp_rtcp_->SetSendAbsoluteSenderTimeStatus(channel_, true,
141                                                              11));
142  verifying_transport_.SetAudioLevelId(9);
143  verifying_transport_.SetAbsoluteSenderTimeId(11);
144  ResumePlaying();
145  EXPECT_TRUE(verifying_transport_.Wait());
146}
147
148TEST_F(SendRtpRtcpHeaderExtensionsTest, SentPacketsIncludeAllExtensions2) {
149  EXPECT_EQ(0, voe_rtp_rtcp_->SetSendAbsoluteSenderTimeStatus(channel_, true,
150                                                              3));
151  EXPECT_EQ(0, voe_rtp_rtcp_->SetSendAudioLevelIndicationStatus(channel_, true,
152                                                                9));
153  verifying_transport_.SetAbsoluteSenderTimeId(3);
154  // Don't register audio level with header parser - unknown extensions should
155  // be ignored when parsing.
156  ResumePlaying();
157  EXPECT_TRUE(verifying_transport_.Wait());
158}
159
160class MockViENetwork : public webrtc::ViENetwork {
161 public:
162  MockViENetwork() {}
163  virtual ~MockViENetwork() {}
164
165  MOCK_METHOD0(Release, int());
166  MOCK_METHOD2(SetNetworkTransmissionState, void(const int, const bool));
167  MOCK_METHOD2(RegisterSendTransport, int(const int, webrtc::Transport&));
168  MOCK_METHOD1(DeregisterSendTransport, int(const int));
169  MOCK_METHOD4(ReceivedRTPPacket, int(const int, const void*, const int,
170                                      const webrtc::PacketTime&));
171  MOCK_METHOD3(ReceivedRTCPPacket, int(const int, const void*, const int));
172  MOCK_METHOD2(SetMTU, int(int, unsigned int));
173  MOCK_METHOD4(ReceivedBWEPacket, int(const int, int64_t, int,
174                                      const webrtc::RTPHeader&));
175};
176
177class ReceiveRtpRtcpHeaderExtensionsTest : public BeforeStreamingFixture {
178 protected:
179  virtual void SetUp() {
180    EXPECT_EQ(0,
181        voe_rtp_rtcp_->SetSendAbsoluteSenderTimeStatus(channel_, true, 11));
182    EXPECT_EQ(0,
183        voe_rtp_rtcp_->SetReceiveAbsoluteSenderTimeStatus(channel_, true, 11));
184  }
185
186  enum {
187    kVideoChannelId1 = 667,
188    kVideoChannelId2 = 668
189  };
190  MockViENetwork mock_network_;
191};
192
193TEST_F(ReceiveRtpRtcpHeaderExtensionsTest, ReceiveASTDisabled) {
194  ResumePlaying();
195  Sleep(500);
196}
197
198TEST_F(ReceiveRtpRtcpHeaderExtensionsTest, ReceiveASTFailSetTarget) {
199  EXPECT_CALL(mock_network_, Release()).Times(1);
200  EXPECT_EQ(-1, voe_rtp_rtcp_->SetVideoEngineBWETarget(-1, &mock_network_,
201                                                      kVideoChannelId1));
202  ResumePlaying();
203}
204
205TEST_F(ReceiveRtpRtcpHeaderExtensionsTest, ReceiveASTEnabled) {
206  EXPECT_CALL(mock_network_, Release()).Times(1);
207  EXPECT_CALL(mock_network_, ReceivedBWEPacket(kVideoChannelId1, _, _,
208      Field(&webrtc::RTPHeader::extension,
209      Field(&webrtc::RTPHeaderExtension::hasAbsoluteSendTime, Eq(true)))))
210      .Times(AtLeast(1));
211  EXPECT_EQ(0, voe_rtp_rtcp_->SetVideoEngineBWETarget(channel_, &mock_network_,
212                                                      kVideoChannelId1));
213  ResumePlaying();
214  Sleep(500);
215  EXPECT_EQ(0, voe_rtp_rtcp_->SetVideoEngineBWETarget(channel_, NULL, -1));
216}
217
218TEST_F(ReceiveRtpRtcpHeaderExtensionsTest, ReceiveASTEnabledBadExtensionId) {
219  EXPECT_CALL(mock_network_, Release()).Times(1);
220  EXPECT_CALL(mock_network_, ReceivedBWEPacket(kVideoChannelId1, _, _,
221      Field(&webrtc::RTPHeader::extension,
222      Field(&webrtc::RTPHeaderExtension::hasAbsoluteSendTime, Eq(false)))))
223      .Times(AtLeast(1));
224  EXPECT_EQ(0, voe_rtp_rtcp_->SetReceiveAbsoluteSenderTimeStatus(channel_, true,
225                                                                 1));
226  EXPECT_EQ(0, voe_rtp_rtcp_->SetVideoEngineBWETarget(channel_, &mock_network_,
227                                                      kVideoChannelId1));
228  ResumePlaying();
229  Sleep(500);
230  EXPECT_EQ(0, voe_rtp_rtcp_->SetVideoEngineBWETarget(channel_, NULL, -1));
231}
232
233TEST_F(ReceiveRtpRtcpHeaderExtensionsTest, ReceiveASTEnabledNotSending) {
234  EXPECT_CALL(mock_network_, Release()).Times(1);
235  EXPECT_CALL(mock_network_, ReceivedBWEPacket(kVideoChannelId1, _, _,
236      Field(&webrtc::RTPHeader::extension,
237      Field(&webrtc::RTPHeaderExtension::hasAbsoluteSendTime, Eq(false)))))
238      .Times(AtLeast(1));
239  EXPECT_EQ(0, voe_rtp_rtcp_->SetSendAbsoluteSenderTimeStatus(channel_, false,
240                                                              11));
241  EXPECT_EQ(0, voe_rtp_rtcp_->SetVideoEngineBWETarget(channel_, &mock_network_,
242                                                      kVideoChannelId1));
243  ResumePlaying();
244  Sleep(500);
245  EXPECT_EQ(0, voe_rtp_rtcp_->SetVideoEngineBWETarget(channel_, NULL, -1));
246}
247
248TEST_F(ReceiveRtpRtcpHeaderExtensionsTest, ReceiveASTEnabledNotReceiving) {
249  EXPECT_CALL(mock_network_, Release()).Times(1);
250  EXPECT_CALL(mock_network_, ReceivedBWEPacket(kVideoChannelId1, _, _,
251      Field(&webrtc::RTPHeader::extension,
252      Field(&webrtc::RTPHeaderExtension::hasAbsoluteSendTime, Eq(false)))))
253      .Times(AtLeast(1));
254  EXPECT_EQ(0, voe_rtp_rtcp_->SetReceiveAbsoluteSenderTimeStatus(channel_,
255                                                                 false, 11));
256  EXPECT_EQ(0, voe_rtp_rtcp_->SetVideoEngineBWETarget(channel_, &mock_network_,
257                                                      kVideoChannelId1));
258  ResumePlaying();
259  Sleep(500);
260  EXPECT_EQ(0, voe_rtp_rtcp_->SetVideoEngineBWETarget(channel_, NULL, -1));
261}
262
263TEST_F(ReceiveRtpRtcpHeaderExtensionsTest, ReceiveASTSwitchViENetwork) {
264  MockViENetwork mock_network_2;
265  EXPECT_CALL(mock_network_2, Release()).Times(1);
266  EXPECT_CALL(mock_network_2, ReceivedBWEPacket(kVideoChannelId1, _, _,
267      Field(&webrtc::RTPHeader::extension,
268      Field(&webrtc::RTPHeaderExtension::hasAbsoluteSendTime, Eq(true)))))
269      .Times(AtLeast(1));
270  EXPECT_CALL(mock_network_, Release()).Times(1);
271  EXPECT_CALL(mock_network_, ReceivedBWEPacket(kVideoChannelId1, _, _,
272      Field(&webrtc::RTPHeader::extension,
273      Field(&webrtc::RTPHeaderExtension::hasAbsoluteSendTime, Eq(true)))))
274      .Times(AtLeast(1));
275  EXPECT_EQ(0, voe_rtp_rtcp_->SetVideoEngineBWETarget(channel_, &mock_network_2,
276                                                      kVideoChannelId1));
277  ResumePlaying();
278  Sleep(500);
279  EXPECT_EQ(0, voe_rtp_rtcp_->SetVideoEngineBWETarget(channel_, &mock_network_,
280                                                      kVideoChannelId1));
281  Sleep(500);
282  EXPECT_EQ(0, voe_rtp_rtcp_->SetVideoEngineBWETarget(channel_, NULL, -1));
283}
284
285TEST_F(ReceiveRtpRtcpHeaderExtensionsTest, ReceiveASTSwitchVideoChannel) {
286  EXPECT_CALL(mock_network_, Release()).Times(2);
287  EXPECT_CALL(mock_network_, ReceivedBWEPacket(kVideoChannelId1, _, _,
288      Field(&webrtc::RTPHeader::extension,
289      Field(&webrtc::RTPHeaderExtension::hasAbsoluteSendTime, Eq(true)))))
290      .Times(AtLeast(1));
291  EXPECT_CALL(mock_network_, ReceivedBWEPacket(kVideoChannelId2, _, _,
292      Field(&webrtc::RTPHeader::extension,
293      Field(&webrtc::RTPHeaderExtension::hasAbsoluteSendTime, Eq(true)))))
294      .Times(AtLeast(1));
295  EXPECT_EQ(0, voe_rtp_rtcp_->SetVideoEngineBWETarget(channel_, &mock_network_,
296                                                      kVideoChannelId1));
297  ResumePlaying();
298  Sleep(500);
299  EXPECT_EQ(0, voe_rtp_rtcp_->SetVideoEngineBWETarget(channel_, &mock_network_,
300                                                      kVideoChannelId2));
301  Sleep(500);
302  EXPECT_EQ(0, voe_rtp_rtcp_->SetVideoEngineBWETarget(channel_, NULL, -1));
303}
304