1 /* 2 * libjingle 3 * Copyright 2004 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "talk/session/media/bundlefilter.h" 29 #include "webrtc/base/gunit.h" 30 31 using cricket::StreamParams; 32 33 static const int kSsrc1 = 0x1111; 34 static const int kSsrc2 = 0x2222; 35 static const int kSsrc3 = 0x3333; 36 static const int kPayloadType1 = 0x11; 37 static const int kPayloadType2 = 0x22; 38 static const int kPayloadType3 = 0x33; 39 40 // SSRC = 0x1111, Payload type = 0x11 41 static const unsigned char kRtpPacketPt1Ssrc1[] = { 42 0x80, kPayloadType1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 43 0x11, 44 }; 45 46 // SSRC = 0x2222, Payload type = 0x22 47 static const unsigned char kRtpPacketPt2Ssrc2[] = { 48 0x80, 0x80 + kPayloadType2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 0x22, 0x22, 50 }; 51 52 // SSRC = 0x2222, Payload type = 0x33 53 static const unsigned char kRtpPacketPt3Ssrc2[] = { 54 0x80, kPayloadType3, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 55 0x22, 56 }; 57 58 // PT = 200 = SR, len = 28, SSRC of sender = 0x0001 59 // NTP TS = 0, RTP TS = 0, packet count = 0 60 static const unsigned char kRtcpPacketSrSsrc01[] = { 61 0x80, 0xC8, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x01, 62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 0x00, 0x00, 0x00, 0x00, 65 }; 66 67 // PT = 200 = SR, len = 28, SSRC of sender = 0x2222 68 // NTP TS = 0, RTP TS = 0, packet count = 0 69 static const unsigned char kRtcpPacketSrSsrc2[] = { 70 0x80, 0xC8, 0x00, 0x1B, 0x00, 0x00, 0x22, 0x22, 71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73 0x00, 0x00, 0x00, 0x00, 74 }; 75 76 // First packet - SR = PT = 200, len = 0, SSRC of sender = 0x1111 77 // NTP TS = 0, RTP TS = 0, packet count = 0 78 // second packet - SDES = PT = 202, count = 0, SSRC = 0x1111, cname len = 0 79 static const unsigned char kRtcpPacketCompoundSrSdesSsrc1[] = { 80 0x80, 0xC8, 0x00, 0x01, 0x00, 0x00, 0x11, 0x11, 81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 83 0x00, 0x00, 0x00, 0x00, 84 0x81, 0xCA, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x01, 0x00, 85 }; 86 87 // SDES = PT = 202, count = 0, SSRC = 0x2222, cname len = 0 88 static const unsigned char kRtcpPacketSdesSsrc2[] = { 89 0x81, 0xCA, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 0x00, 90 }; 91 92 // Packet has only mandatory fixed RTCP header 93 static const unsigned char kRtcpPacketFixedHeaderOnly[] = { 94 0x80, 0xC8, 0x00, 0x00, 95 }; 96 97 // Small packet for SSRC demux. 98 static const unsigned char kRtcpPacketTooSmall[] = { 99 0x80, 0xC8, 0x00, 0x00, 0x00, 0x00, 100 }; 101 102 // PT = 206, FMT = 1, Sender SSRC = 0x1111, Media SSRC = 0x1111 103 // No FCI information is needed for PLI. 104 static const unsigned char kRtcpPacketNonCompoundRtcpPliFeedback[] = { 105 0x81, 0xCE, 0x00, 0x0C, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x11, 0x11, 106 }; 107 108 // An SCTP packet. 109 static const unsigned char kSctpPacket[] = { 110 0x00, 0x01, 0x00, 0x01, 111 0xff, 0xff, 0xff, 0xff, 112 0x00, 0x00, 0x00, 0x00, 113 0x03, 0x00, 0x00, 0x04, 114 0x00, 0x00, 0x00, 0x00, 115 }; 116 117 TEST(BundleFilterTest, AddRemoveStreamTest) { 118 cricket::BundleFilter bundle_filter; 119 EXPECT_FALSE(bundle_filter.HasStreams()); 120 EXPECT_TRUE(bundle_filter.AddStream(StreamParams::CreateLegacy(kSsrc1))); 121 StreamParams stream2; 122 stream2.ssrcs.push_back(kSsrc2); 123 stream2.ssrcs.push_back(kSsrc3); 124 EXPECT_TRUE(bundle_filter.AddStream(stream2)); 125 126 EXPECT_TRUE(bundle_filter.HasStreams()); 127 EXPECT_TRUE(bundle_filter.FindStream(kSsrc1)); 128 EXPECT_TRUE(bundle_filter.FindStream(kSsrc2)); 129 EXPECT_TRUE(bundle_filter.FindStream(kSsrc3)); 130 EXPECT_TRUE(bundle_filter.RemoveStream(kSsrc1)); 131 EXPECT_FALSE(bundle_filter.FindStream(kSsrc1)); 132 EXPECT_TRUE(bundle_filter.RemoveStream(kSsrc3)); 133 EXPECT_FALSE(bundle_filter.RemoveStream(kSsrc2)); // Already removed. 134 EXPECT_FALSE(bundle_filter.HasStreams()); 135 } 136 137 TEST(BundleFilterTest, RtpPacketTest) { 138 cricket::BundleFilter bundle_filter; 139 bundle_filter.AddPayloadType(kPayloadType1); 140 EXPECT_TRUE(bundle_filter.DemuxPacket( 141 reinterpret_cast<const char*>(kRtpPacketPt1Ssrc1), 142 sizeof(kRtpPacketPt1Ssrc1), false)); 143 bundle_filter.AddPayloadType(kPayloadType2); 144 EXPECT_TRUE(bundle_filter.DemuxPacket( 145 reinterpret_cast<const char*>(kRtpPacketPt2Ssrc2), 146 sizeof(kRtpPacketPt2Ssrc2), false)); 147 148 // Payload type 0x33 is not added. 149 EXPECT_FALSE(bundle_filter.DemuxPacket( 150 reinterpret_cast<const char*>(kRtpPacketPt3Ssrc2), 151 sizeof(kRtpPacketPt3Ssrc2), false)); 152 // Size is too small. 153 EXPECT_FALSE(bundle_filter.DemuxPacket( 154 reinterpret_cast<const char*>(kRtpPacketPt1Ssrc1), 11, false)); 155 156 bundle_filter.ClearAllPayloadTypes(); 157 EXPECT_FALSE(bundle_filter.DemuxPacket( 158 reinterpret_cast<const char*>(kRtpPacketPt1Ssrc1), 159 sizeof(kRtpPacketPt1Ssrc1), false)); 160 EXPECT_FALSE(bundle_filter.DemuxPacket( 161 reinterpret_cast<const char*>(kRtpPacketPt2Ssrc2), 162 sizeof(kRtpPacketPt2Ssrc2), false)); 163 } 164 165 TEST(BundleFilterTest, RtcpPacketTest) { 166 cricket::BundleFilter bundle_filter; 167 EXPECT_TRUE(bundle_filter.AddStream(StreamParams::CreateLegacy(kSsrc1))); 168 EXPECT_TRUE(bundle_filter.DemuxPacket( 169 reinterpret_cast<const char*>(kRtcpPacketCompoundSrSdesSsrc1), 170 sizeof(kRtcpPacketCompoundSrSdesSsrc1), true)); 171 EXPECT_TRUE(bundle_filter.AddStream(StreamParams::CreateLegacy(kSsrc2))); 172 EXPECT_TRUE(bundle_filter.DemuxPacket( 173 reinterpret_cast<const char*>(kRtcpPacketSrSsrc2), 174 sizeof(kRtcpPacketSrSsrc2), true)); 175 EXPECT_TRUE(bundle_filter.DemuxPacket( 176 reinterpret_cast<const char*>(kRtcpPacketSdesSsrc2), 177 sizeof(kRtcpPacketSdesSsrc2), true)); 178 EXPECT_TRUE(bundle_filter.RemoveStream(kSsrc2)); 179 // RTCP Packets other than SR and RR are demuxed regardless of SSRC. 180 EXPECT_TRUE(bundle_filter.DemuxPacket( 181 reinterpret_cast<const char*>(kRtcpPacketSdesSsrc2), 182 sizeof(kRtcpPacketSdesSsrc2), true)); 183 // RTCP Packets with 'special' SSRC 0x01 are demuxed also 184 EXPECT_TRUE(bundle_filter.DemuxPacket( 185 reinterpret_cast<const char*>(kRtcpPacketSrSsrc01), 186 sizeof(kRtcpPacketSrSsrc01), true)); 187 EXPECT_FALSE(bundle_filter.DemuxPacket( 188 reinterpret_cast<const char*>(kRtcpPacketSrSsrc2), 189 sizeof(kRtcpPacketSrSsrc2), true)); 190 EXPECT_FALSE(bundle_filter.DemuxPacket( 191 reinterpret_cast<const char*>(kRtcpPacketFixedHeaderOnly), 192 sizeof(kRtcpPacketFixedHeaderOnly), true)); 193 EXPECT_FALSE(bundle_filter.DemuxPacket( 194 reinterpret_cast<const char*>(kRtcpPacketTooSmall), 195 sizeof(kRtcpPacketTooSmall), true)); 196 EXPECT_TRUE(bundle_filter.DemuxPacket( 197 reinterpret_cast<const char*>(kRtcpPacketNonCompoundRtcpPliFeedback), 198 sizeof(kRtcpPacketNonCompoundRtcpPliFeedback), true)); 199 // If the streams_ is empty, rtcp packet passes through 200 EXPECT_TRUE(bundle_filter.RemoveStream(kSsrc1)); 201 EXPECT_FALSE(bundle_filter.HasStreams()); 202 EXPECT_TRUE(bundle_filter.DemuxPacket( 203 reinterpret_cast<const char*>(kRtcpPacketSrSsrc2), 204 sizeof(kRtcpPacketSrSsrc2), true)); 205 } 206 207 TEST(BundleFilterTest, InvalidRtpPacket) { 208 cricket::BundleFilter bundle_filter; 209 EXPECT_TRUE(bundle_filter.AddStream(StreamParams::CreateLegacy(kSsrc1))); 210 EXPECT_FALSE(bundle_filter.DemuxPacket( 211 reinterpret_cast<const char*>(kSctpPacket), 212 sizeof(kSctpPacket), false)); 213 } 214