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 <string> 29 #include <vector> 30 31 #include "talk/base/gunit.h" 32 #include "talk/base/logging.h" 33 #include "talk/base/scoped_ptr.h" 34 #include "talk/media/base/fakemediaengine.h" 35 #include "talk/media/devices/fakedevicemanager.h" 36 #include "talk/p2p/base/constants.h" 37 #include "talk/p2p/client/basicportallocator.h" 38 #include "talk/session/media/mediasessionclient.h" 39 #include "talk/xmllite/xmlbuilder.h" 40 #include "talk/xmllite/xmlelement.h" 41 #include "talk/xmllite/xmlprinter.h" 42 #include "talk/xmpp/constants.h" 43 44 using cricket::AudioCodec; 45 using cricket::AudioContentDescription; 46 using cricket::Codec; 47 using cricket::DataCodec; 48 using cricket::DataContentDescription; 49 using cricket::FeedbackParam; 50 using cricket::FeedbackParams; 51 using cricket::VideoCodec; 52 using cricket::VideoContentDescription; 53 54 // The codecs that our FakeMediaEngine will support. Order is important, since 55 // the tests check that our messages have codecs in the correct order. 56 static const cricket::AudioCodec kAudioCodecs[] = { 57 cricket::AudioCodec(103, "ISAC", 16000, -1, 1, 18), 58 cricket::AudioCodec(104, "ISAC", 32000, -1, 1, 17), 59 cricket::AudioCodec(119, "ISACLC", 16000, 40000, 1, 16), 60 cricket::AudioCodec(99, "speex", 16000, 22000, 1, 15), 61 cricket::AudioCodec(97, "IPCMWB", 16000, 80000, 1, 14), 62 cricket::AudioCodec(9, "G722", 16000, 64000, 1, 13), 63 cricket::AudioCodec(102, "iLBC", 8000, 13300, 1, 12), 64 cricket::AudioCodec(98, "speex", 8000, 11000, 1, 11), 65 cricket::AudioCodec(3, "GSM", 8000, 13000, 1, 10), 66 cricket::AudioCodec(100, "EG711U", 8000, 64000, 1, 9), 67 cricket::AudioCodec(101, "EG711A", 8000, 64000, 1, 8), 68 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 7), 69 cricket::AudioCodec(8, "PCMA", 8000, 64000, 1, 6), 70 cricket::AudioCodec(126, "CN", 32000, 0, 1, 5), 71 cricket::AudioCodec(105, "CN", 16000, 0, 1, 4), 72 cricket::AudioCodec(13, "CN", 8000, 0, 1, 3), 73 cricket::AudioCodec(117, "red", 8000, 0, 1, 2), 74 cricket::AudioCodec(106, "telephone-event", 8000, 0, 1, 1) 75 }; 76 77 static const cricket::VideoCodec kVideoCodecs[] = { 78 cricket::VideoCodec(96, "H264-SVC", 320, 200, 30, 1) 79 }; 80 81 static const cricket::DataCodec kDataCodecs[] = { 82 cricket::DataCodec(127, "google-data", 0) 83 }; 84 85 const std::string kGingleCryptoOffer = \ 86 "<rtp:encryption xmlns:rtp='urn:xmpp:jingle:apps:rtp:1'> " \ 87 " <usage/> " \ 88 " <rtp:crypto tag='145' crypto-suite='AES_CM_128_HMAC_SHA1_32'" \ 89 " key-params='inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9'/>" \ 90 " <rtp:crypto tag='51' crypto-suite='AES_CM_128_HMAC_SHA1_80'" \ 91 " key-params='inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy'/>" \ 92 "</rtp:encryption> "; 93 94 // Jingle offer does not have any <usage> element. 95 const std::string kJingleCryptoOffer = \ 96 "<rtp:encryption xmlns:rtp='urn:xmpp:jingle:apps:rtp:1'> " \ 97 " <rtp:crypto tag='145' crypto-suite='AES_CM_128_HMAC_SHA1_32'" \ 98 " key-params='inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9'/>" \ 99 " <rtp:crypto tag='51' crypto-suite='AES_CM_128_HMAC_SHA1_80'" \ 100 " key-params='inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy'/>" \ 101 "</rtp:encryption> "; 102 103 104 const std::string kGingleRequiredCryptoOffer = \ 105 "<rtp:encryption xmlns:rtp='urn:xmpp:jingle:apps:rtp:1' required='true'> "\ 106 " <usage/> " \ 107 " <rtp:crypto tag='145' crypto-suite='AES_CM_128_HMAC_SHA1_32'" \ 108 " key-params='inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9'/>" \ 109 " <rtp:crypto tag='51' crypto-suite='AES_CM_128_HMAC_SHA1_80'" \ 110 " key-params='inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy'/>" \ 111 "</rtp:encryption> "; 112 113 const std::string kJingleRequiredCryptoOffer = \ 114 "<rtp:encryption xmlns:rtp='urn:xmpp:jingle:apps:rtp:1' required='true'> "\ 115 " <rtp:crypto tag='145' crypto-suite='AES_CM_128_HMAC_SHA1_32'" \ 116 " key-params='inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9'/>" \ 117 " <rtp:crypto tag='51' crypto-suite='AES_CM_128_HMAC_SHA1_80'" \ 118 " key-params='inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy'/>" \ 119 "</rtp:encryption> "; 120 121 122 const std::string kGingleUnsupportedCryptoOffer = \ 123 "<rtp:encryption xmlns:rtp='urn:xmpp:jingle:apps:rtp:1'> " \ 124 " <usage/> " \ 125 " <rtp:crypto tag='145' crypto-suite='NOT_SUPPORTED_1'" \ 126 " key-params='inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9'/>" \ 127 " <rtp:crypto tag='51' crypto-suite='NOT_SUPPORTED_2'" \ 128 " key-params='inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy'/>" \ 129 "</rtp:encryption> "; 130 131 const std::string kJingleUnsupportedCryptoOffer = \ 132 "<rtp:encryption xmlns:rtp='urn:xmpp:jingle:apps:rtp:1'> " \ 133 " <rtp:crypto tag='145' crypto-suite='NOT_SUPPORTED_1'" \ 134 " key-params='inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9'/>" \ 135 " <rtp:crypto tag='51' crypto-suite='NOT_SUPPORTED_2'" \ 136 " key-params='inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy'/>" \ 137 "</rtp:encryption> "; 138 139 140 // With unsupported but with required="true" 141 const std::string kGingleRequiredUnsupportedCryptoOffer = \ 142 "<rtp:encryption xmlns:rtp='urn:xmpp:jingle:apps:rtp:1' required='true'>" \ 143 " <usage/> " \ 144 " <rtp:crypto tag='145' crypto-suite='NOT_SUPPORTED_1'" \ 145 " key-params='inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9'/>" \ 146 " <rtp:crypto tag='51' crypto-suite='NOT_SUPPORTED_2'" \ 147 " key-params='inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy'/>" \ 148 "</rtp:encryption> "; 149 150 const std::string kJingleRequiredUnsupportedCryptoOffer = \ 151 "<rtp:encryption xmlns:rtp='urn:xmpp:jingle:apps:rtp:1' required='true'>" \ 152 " <rtp:crypto tag='145' crypto-suite='NOT_SUPPORTED_1' " \ 153 " key-params='inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9'/> " \ 154 " <rtp:crypto tag='51' crypto-suite='NOT_SUPPORTED_2' " \ 155 " key-params='inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy'/>" \ 156 "</rtp:encryption> "; 157 158 const std::string kGingleInitiate( 159 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 160 " to='user (at) domain.com/resource' type='set' id='123'> " \ 161 " <session xmlns='http://www.google.com/session' type='initiate'" \ 162 " id='abcdef' initiator='me (at) domain.com/resource'> " \ 163 " <description xmlns='http://www.google.com/session/phone'> " \ 164 " <payload-type xmlns='http://www.google.com/session/phone' " \ 165 " id='103' name='ISAC' clockrate='16000' /> " \ 166 " <payload-type xmlns='http://www.google.com/session/phone' " \ 167 " id='104' name='ISAC' clockrate='32000' /> " \ 168 " <payload-type xmlns='http://www.google.com/session/phone' " \ 169 " id='119' name='ISACLC' clockrate='16000' bitrate='40000' /> " \ 170 " <payload-type xmlns='http://www.google.com/session/phone' " \ 171 " id='99' name='speex' clockrate='16000' bitrate='22000' /> " \ 172 " <payload-type xmlns='http://www.google.com/session/phone' " \ 173 " id='97' name='IPCMWB' clockrate='16000' bitrate='80000' /> " \ 174 " <payload-type xmlns='http://www.google.com/session/phone' " \ 175 " id='9' name='G722' clockrate='16000' bitrate='64000' /> " \ 176 " <payload-type xmlns='http://www.google.com/session/phone' " \ 177 " id='102' name='iLBC' clockrate='8000' bitrate='13300' />" \ 178 " <payload-type xmlns='http://www.google.com/session/phone' " \ 179 " id='98' name='speex' clockrate='8000' bitrate='11000' />" \ 180 " <payload-type xmlns='http://www.google.com/session/phone' " \ 181 " id='3' name='GSM' clockrate='8000' bitrate='13000' /> " \ 182 " <payload-type xmlns='http://www.google.com/session/phone' " \ 183 " id='100' name='EG711U' clockrate='8000' bitrate='64000' /> " \ 184 " <payload-type xmlns='http://www.google.com/session/phone' " \ 185 " id='101' name='EG711A' clockrate='8000' bitrate='64000' /> " \ 186 " <payload-type xmlns='http://www.google.com/session/phone' " \ 187 " id='0' name='PCMU' clockrate='8000' bitrate='64000' /> " \ 188 " <payload-type xmlns='http://www.google.com/session/phone' " \ 189 " id='8' name='PCMA' clockrate='8000' bitrate='64000' /> " \ 190 " <payload-type xmlns='http://www.google.com/session/phone' " \ 191 " id='126' name='CN' clockrate='32000' /> " \ 192 " <payload-type xmlns='http://www.google.com/session/phone' " \ 193 " id='105' name='CN' clockrate='16000' /> " \ 194 " <payload-type xmlns='http://www.google.com/session/phone' " \ 195 " id='13' name='CN' clockrate='8000' /> " \ 196 " <payload-type xmlns='http://www.google.com/session/phone' " \ 197 " id='117' name='red' clockrate='8000' /> " \ 198 " <payload-type xmlns='http://www.google.com/session/phone' " \ 199 " id='106' name='telephone-event' clockrate='8000' /> " \ 200 " </description> " \ 201 " </session> " \ 202 "</iq> "); 203 204 const std::string kJingleInitiate( 205 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 206 " to='user (at) domain.com/resource' type='set' id='123'> " \ 207 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' " \ 208 " sid='abcdef' initiator='me (at) domain.com/resource'> " \ 209 " <content name='test audio'> " \ 210 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \ 211 " <payload-type id='103' name='ISAC' clockrate='16000'/> " \ 212 " <payload-type id='104' name='ISAC' clockrate='32000'/> " \ 213 " <payload-type " \ 214 " id='119' name='ISACLC' clockrate='16000'> " \ 215 " <parameter name='bitrate' value='40000'/> " \ 216 " </payload-type> " \ 217 " <payload-type " \ 218 " id='99' name='speex' clockrate='16000'> " \ 219 " <parameter name='bitrate' value='22000'/> " \ 220 " </payload-type> " \ 221 " <payload-type " \ 222 " id='97' name='IPCMWB' clockrate='16000'> " \ 223 " <parameter name='bitrate' value='80000'/> " \ 224 " </payload-type> " \ 225 " <payload-type " \ 226 " id='9' name='G722' clockrate='16000'> " \ 227 " <parameter name='bitrate' value='64000'/> " \ 228 " </payload-type> " \ 229 " <payload-type " \ 230 " id='102' name='iLBC' clockrate='8000'> " \ 231 " <parameter name='bitrate' value='13300'/> " \ 232 " </payload-type> " \ 233 " <payload-type " \ 234 " id='98' name='speex' clockrate='8000'> " \ 235 " <parameter name='bitrate' value='11000'/> " \ 236 " </payload-type> " \ 237 " <payload-type " \ 238 " id='3' name='GSM' clockrate='8000'> " \ 239 " <parameter name='bitrate' value='13000'/> " \ 240 " </payload-type> " \ 241 " <payload-type " \ 242 " id='100' name='EG711U' clockrate='8000'> " \ 243 " <parameter name='bitrate' value='64000'/> " \ 244 " </payload-type> " \ 245 " <payload-type " \ 246 " id='101' name='EG711A' clockrate='8000'> " \ 247 " <parameter name='bitrate' value='64000'/> " \ 248 " </payload-type> " \ 249 " <payload-type " \ 250 " id='0' name='PCMU' clockrate='8000'> " \ 251 " <parameter name='bitrate' value='64000'/> " \ 252 " </payload-type> " \ 253 " <payload-type " \ 254 " id='8' name='PCMA' clockrate='8000'> " \ 255 " <parameter name='bitrate' value='64000'/> " \ 256 " </payload-type> " \ 257 " <payload-type " \ 258 " id='126' name='CN' clockrate='32000' /> " \ 259 " <payload-type " \ 260 " id='105' name='CN' clockrate='16000' /> " \ 261 " <payload-type " \ 262 " id='13' name='CN' clockrate='8000' /> " \ 263 " <payload-type " \ 264 " id='117' name='red' clockrate='8000' /> " \ 265 " <payload-type " \ 266 " id='106' name='telephone-event' clockrate='8000' /> " \ 267 " </description> " \ 268 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 269 " </content> " \ 270 " </jingle> " \ 271 "</iq> "); 272 273 // Initiate string with a different order of supported codecs. 274 // Should accept the supported ones, but with our desired order. 275 const std::string kGingleInitiateDifferentPreference( 276 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 277 " to='user (at) domain.com/resource' type='set' id='123'> " \ 278 " <session xmlns='http://www.google.com/session' type='initiate'" \ 279 " id='abcdef' initiator='me (at) domain.com/resource'> " \ 280 " <description xmlns='http://www.google.com/session/phone'> " \ 281 " <payload-type xmlns='http://www.google.com/session/phone' " \ 282 " id='104' name='ISAC' clockrate='32000' /> " \ 283 " <payload-type xmlns='http://www.google.com/session/phone' " \ 284 " id='97' name='IPCMWB' clockrate='16000' bitrate='80000' /> " \ 285 " <payload-type xmlns='http://www.google.com/session/phone' " \ 286 " id='9' name='G722' clockrate='16000' bitrate='64000' /> " \ 287 " <payload-type xmlns='http://www.google.com/session/phone' " \ 288 " id='119' name='ISACLC' clockrate='16000' bitrate='40000' /> " \ 289 " <payload-type xmlns='http://www.google.com/session/phone' " \ 290 " id='103' name='ISAC' clockrate='16000' /> " \ 291 " <payload-type xmlns='http://www.google.com/session/phone' " \ 292 " id='99' name='speex' clockrate='16000' bitrate='22000' /> " \ 293 " <payload-type xmlns='http://www.google.com/session/phone' " \ 294 " id='100' name='EG711U' clockrate='8000' bitrate='64000' /> " \ 295 " <payload-type xmlns='http://www.google.com/session/phone' " \ 296 " id='101' name='EG711A' clockrate='8000' bitrate='64000' /> " \ 297 " <payload-type xmlns='http://www.google.com/session/phone' " \ 298 " id='0' name='PCMU' clockrate='8000' bitrate='64000' /> " \ 299 " <payload-type xmlns='http://www.google.com/session/phone' " \ 300 " id='8' name='PCMA' clockrate='8000' bitrate='64000' /> " \ 301 " <payload-type xmlns='http://www.google.com/session/phone' " \ 302 " id='102' name='iLBC' clockrate='8000' bitrate='13300' />" \ 303 " <payload-type xmlns='http://www.google.com/session/phone' " \ 304 " id='3' name='GSM' clockrate='8000' bitrate='13000' /> " \ 305 " <payload-type xmlns='http://www.google.com/session/phone' " \ 306 " id='98' name='speex' clockrate='8000' bitrate='11000' />" \ 307 " <payload-type xmlns='http://www.google.com/session/phone' " \ 308 " id='126' name='CN' clockrate='32000' /> " \ 309 " <payload-type xmlns='http://www.google.com/session/phone' " \ 310 " id='105' name='CN' clockrate='16000' /> " \ 311 " <payload-type xmlns='http://www.google.com/session/phone' " \ 312 " id='13' name='CN' clockrate='8000' /> " \ 313 " <payload-type xmlns='http://www.google.com/session/phone' " \ 314 " id='117' name='red' clockrate='8000' /> " \ 315 " <payload-type xmlns='http://www.google.com/session/phone' " \ 316 " id='106' name='telephone-event' clockrate='8000' /> " \ 317 " </description> " \ 318 " </session> " \ 319 "</iq> "); 320 321 const std::string kJingleInitiateDifferentPreference( 322 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 323 " to='user (at) domain.com/resource' type='set' id='123'> " \ 324 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' " \ 325 " sid='abcdef' initiator='me (at) domain.com/resource'> " \ 326 " <content name='test audio'> " \ 327 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \ 328 " <payload-type id='104' name='ISAC' clockrate='32000'/> " \ 329 " <payload-type " \ 330 " id='97' name='IPCMWB' clockrate='16000'> " \ 331 " <parameter name='bitrate' value='80000'/> " \ 332 " </payload-type> " \ 333 " <payload-type " \ 334 " id='9' name='G722' clockrate='16000'> " \ 335 " <parameter name='bitrate' value='64000'/> " \ 336 " </payload-type> " \ 337 " <payload-type " \ 338 " id='119' name='ISACLC' clockrate='16000'> " \ 339 " <parameter name='bitrate' value='40000'/> " \ 340 " </payload-type> " \ 341 " <payload-type id='103' name='ISAC' clockrate='16000'/> " \ 342 " <payload-type " \ 343 " id='99' name='speex' clockrate='16000'> " \ 344 " <parameter name='bitrate' value='22000'/> " \ 345 " </payload-type> " \ 346 " <payload-type " \ 347 " id='100' name='EG711U' clockrate='8000'> " \ 348 " <parameter name='bitrate' value='64000'/> " \ 349 " </payload-type> " \ 350 " <payload-type " \ 351 " id='101' name='EG711A' clockrate='8000'> " \ 352 " <parameter name='bitrate' value='64000'/> " \ 353 " </payload-type> " \ 354 " <payload-type " \ 355 " id='0' name='PCMU' clockrate='8000'> " \ 356 " <parameter name='bitrate' value='64000'/> " \ 357 " </payload-type> " \ 358 " <payload-type " \ 359 " id='8' name='PCMA' clockrate='8000'> " \ 360 " <parameter name='bitrate' value='64000'/> " \ 361 " </payload-type> " \ 362 " <payload-type " \ 363 " id='102' name='iLBC' clockrate='8000'> " \ 364 " <parameter name='bitrate' value='13300'/> " \ 365 " </payload-type> " \ 366 " <payload-type " \ 367 " id='3' name='GSM' clockrate='8000'> " \ 368 " <parameter name='bitrate' value='13000'/> " \ 369 " </payload-type> " \ 370 " <payload-type " \ 371 " id='98' name='speex' clockrate='8000'> " \ 372 " <parameter name='bitrate' value='11000'/> " \ 373 " </payload-type> " \ 374 " <payload-type " \ 375 " id='126' name='CN' clockrate='32000' /> " \ 376 " <payload-type " \ 377 " id='105' name='CN' clockrate='16000' /> " \ 378 " <payload-type " \ 379 " id='13' name='CN' clockrate='8000' /> " \ 380 " <payload-type " \ 381 " id='117' name='red' clockrate='8000' /> " \ 382 " <payload-type " \ 383 " id='106' name='telephone-event' clockrate='8000' /> " \ 384 " </description> " \ 385 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 386 " </content> " \ 387 " </jingle> " \ 388 "</iq> "); 389 390 const std::string kJingleInitiateWithRtcpFb( 391 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 392 " to='user (at) domain.com/resource' type='set' id='123'> " \ 393 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' " \ 394 " sid='abcdef' initiator='me (at) domain.com/resource'> " \ 395 " <content name='test audio'> " \ 396 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \ 397 " <payload-type id='103' name='ISAC' clockrate='16000'> " \ 398 " <rtcp-fb type='nack'/> " \ 399 " </payload-type> " \ 400 " </description> " \ 401 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 402 " </content> " \ 403 " <content name='test video'> " \ 404 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='video'> " \ 405 " <rtcp-fb type='nack'/> " \ 406 " <payload-type id='99' name='H264-SVC'> " \ 407 " <rtcp-fb type='ccm' subtype='fir'/> " \ 408 " <parameter name='height' value='200'/> " \ 409 " <parameter name='width' value='320'/> " \ 410 " <parameter name='framerate' value='30'/> " \ 411 " </payload-type> " \ 412 " </description> " \ 413 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 414 " </content> " \ 415 " <content name='test data'> " \ 416 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='data'> " \ 417 " <rtcp-fb type='nack'/> " \ 418 " <payload-type id='127' name='google-data'> " \ 419 " </payload-type> " \ 420 " </description> " \ 421 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 422 " </content> " \ 423 " </jingle> " \ 424 "</iq> "); 425 426 const std::string kGingleVideoInitiate( 427 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 428 " to='user (at) domain.com/resource' type='set' id='123'> " \ 429 " <session xmlns='http://www.google.com/session' type='initiate'" \ 430 " id='abcdef' initiator='me (at) domain.com/resource'> " \ 431 " <description xmlns='http://www.google.com/session/video'> " \ 432 " <payload-type xmlns='http://www.google.com/session/phone' " \ 433 " id='103' name='ISAC' clockrate='16000' /> " \ 434 " <payload-type xmlns='http://www.google.com/session/video' " \ 435 " id='99' name='H264-SVC' framerate='30' " \ 436 " height='200' width='320'/> " \ 437 " </description> " \ 438 " </session> " \ 439 "</iq> "); 440 441 const std::string kJingleVideoInitiate( 442 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 443 " to='user (at) domain.com/resource' type='set' id='123'> " \ 444 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' " \ 445 " sid='abcdef' initiator='me (at) domain.com/resource'> " \ 446 " <content name='test audio'> " \ 447 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \ 448 " <payload-type id='103' name='ISAC' clockrate='16000'/> " \ 449 " </description> " \ 450 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 451 " </content> " \ 452 " <content name='test video'> " \ 453 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='video'> " \ 454 " <payload-type id='99' name='H264-SVC'> " \ 455 " <parameter name='height' value='200'/> " \ 456 " <parameter name='width' value='320'/> " \ 457 " <parameter name='framerate' value='30'/> " \ 458 " </payload-type> " \ 459 " </description> " \ 460 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 461 " </content> " \ 462 " </jingle> " \ 463 "</iq> "); 464 465 const std::string kJingleVideoInitiateWithRtpData( 466 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 467 " to='user (at) domain.com/resource' type='set' id='123'> " \ 468 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' " \ 469 " sid='abcdef' initiator='me (at) domain.com/resource'> " \ 470 " <content name='test audio'> " \ 471 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \ 472 " <payload-type id='103' name='ISAC' clockrate='16000'/> " \ 473 " </description> " \ 474 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 475 " </content> " \ 476 " <content name='test video'> " \ 477 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='video'> " \ 478 " <payload-type id='99' name='H264-SVC'> " \ 479 " <parameter name='height' value='200'/> " \ 480 " <parameter name='width' value='320'/> " \ 481 " <parameter name='framerate' value='30'/> " \ 482 " </payload-type> " \ 483 " </description> " \ 484 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 485 " </content> " \ 486 " <content name='test data'> " \ 487 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='data'> " \ 488 " <payload-type id='127' name='google-data'/> " \ 489 " <rtcp-mux/> " \ 490 " </description> " \ 491 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 492 " </content> " \ 493 " </jingle> " \ 494 "</iq> "); 495 496 const std::string kJingleVideoInitiateWithSctpData( 497 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 498 " to='user (at) domain.com/resource' type='set' id='123'> " \ 499 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' " \ 500 " sid='abcdef' initiator='me (at) domain.com/resource'> " \ 501 " <content name='test audio'> " \ 502 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \ 503 " <payload-type id='103' name='ISAC' clockrate='16000'/> " \ 504 " </description> " \ 505 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 506 " </content> " \ 507 " <content name='test video'> " \ 508 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='video'> " \ 509 " <payload-type id='99' name='H264-SVC'> " \ 510 " <parameter name='height' value='200'/> " \ 511 " <parameter name='width' value='320'/> " \ 512 " <parameter name='framerate' value='30'/> " \ 513 " </payload-type> " \ 514 " </description> " \ 515 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 516 " </content> " \ 517 " <content name='test data'> " \ 518 " <description xmlns='google:jingle:sctp' media='data'> " \ 519 " <stream sid='1'/> " \ 520 " </description> " \ 521 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 522 " </content> " \ 523 " </jingle> " \ 524 "</iq> "); 525 526 const std::string kJingleVideoInitiateWithBandwidth( 527 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 528 " to='user (at) domain.com/resource' type='set' id='123'> " \ 529 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' " \ 530 " sid='abcdef' initiator='me (at) domain.com/resource'> " \ 531 " <content name='test audio'> " \ 532 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \ 533 " <payload-type id='103' name='ISAC' clockrate='16000'/> " \ 534 " </description> " \ 535 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 536 " </content> " \ 537 " <content name='test video'> " \ 538 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='video'> " \ 539 " <payload-type id='99' name='H264-SVC'> " \ 540 " <parameter name='height' value='200'/> " \ 541 " <parameter name='width' value='320'/> " \ 542 " <parameter name='framerate' value='30'/> " \ 543 " </payload-type> " \ 544 " <bandwidth type='AS'>42</bandwidth> " \ 545 " </description> " \ 546 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 547 " </content> " \ 548 " </jingle> " \ 549 "</iq> "); 550 551 const std::string kJingleVideoInitiateWithRtcpMux( 552 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 553 " to='user (at) domain.com/resource' type='set' id='123'> " \ 554 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' " \ 555 " sid='abcdef' initiator='me (at) domain.com/resource'> " \ 556 " <content name='test audio'> " \ 557 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \ 558 " <payload-type id='103' name='ISAC' clockrate='16000'/> " \ 559 " </description> " \ 560 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 561 " </content> " \ 562 " <content name='test video'> " \ 563 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='video'> " \ 564 " <payload-type id='99' name='H264-SVC'> " \ 565 " <parameter name='height' value='200'/> " \ 566 " <parameter name='width' value='320'/> " \ 567 " <parameter name='framerate' value='30'/> " \ 568 " </payload-type> " \ 569 " <rtcp-mux/> " \ 570 " </description> " \ 571 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 572 " </content> " \ 573 " </jingle> " \ 574 "</iq> "); 575 576 // Initiate string with a combination of supported and unsupported codecs 577 // Should accept the supported ones 578 const std::string kGingleInitiateSomeUnsupported( 579 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 580 " to='user (at) domain.com/resource' type='set' id='123'> " \ 581 " <session xmlns='http://www.google.com/session' type='initiate'" \ 582 " id='abcdef' initiator='me (at) domain.com/resource'> " \ 583 " <description xmlns='http://www.google.com/session/phone'> " \ 584 " <payload-type xmlns='http://www.google.com/session/phone' " \ 585 " id='103' name='ISAC' clockrate='16000' /> " \ 586 " <payload-type xmlns='http://www.google.com/session/phone' " \ 587 " id='97' name='ASDFDS' /> " \ 588 " <payload-type xmlns='http://www.google.com/session/phone' " \ 589 " id='102' name='1010' /> " \ 590 " <payload-type xmlns='http://www.google.com/session/phone' " \ 591 " id='107' name='DFAS' /> " \ 592 " <payload-type xmlns='http://www.google.com/session/phone' " \ 593 " id='100' name='EG711U' /> " \ 594 " <payload-type xmlns='http://www.google.com/session/phone' " \ 595 " id='101' name='EG711A' /> " \ 596 " <payload-type xmlns='http://www.google.com/session/phone' " \ 597 " id='0' name='PCMU' /> " \ 598 " <payload-type xmlns='http://www.google.com/session/phone' " \ 599 " id='110' name=':)' /> " \ 600 " <payload-type xmlns='http://www.google.com/session/phone' " \ 601 " id='13' name='CN' /> " \ 602 " </description> " \ 603 " </session> " \ 604 "</iq> "); 605 606 const std::string kJingleInitiateSomeUnsupported( 607 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 608 " to='user (at) domain.com/resource' type='set' id='123'> " \ 609 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' " \ 610 " sid='abcdef' initiator='me (at) domain.com/resource'> " \ 611 " <content name='test audio'> " \ 612 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \ 613 " <payload-type " \ 614 " id='103' name='ISAC' clockrate='16000' /> " \ 615 " <payload-type " \ 616 " id='97' name='ASDFDS' /> " \ 617 " <payload-type " \ 618 " id='102' name='1010' /> " \ 619 " <payload-type " \ 620 " id='107' name='DFAS' /> " \ 621 " <payload-type " \ 622 " id='100' name='EG711U' /> " \ 623 " <payload-type " \ 624 " id='101' name='EG711A' /> " \ 625 " <payload-type " \ 626 " id='0' name='PCMU' /> " \ 627 " <payload-type " \ 628 " id='110' name=':)' /> " \ 629 " <payload-type " \ 630 " id='13' name='CN' /> " \ 631 " </description> " \ 632 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 633 " </content> " \ 634 " </jingle> " \ 635 "</iq> "); 636 637 const std::string kGingleVideoInitiateWithBandwidth( 638 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 639 " to='user (at) domain.com/resource' type='set' id='123'> " \ 640 " <session xmlns='http://www.google.com/session' type='initiate'" \ 641 " id='abcdef' initiator='me (at) domain.com/resource'> " \ 642 " <description xmlns='http://www.google.com/session/video'> " \ 643 " <payload-type xmlns='http://www.google.com/session/phone' " \ 644 " id='103' name='ISAC' clockrate='16000' /> " \ 645 " <payload-type xmlns='http://www.google.com/session/video' " \ 646 " id='99' name='H264-SVC' framerate='30' " \ 647 " height='200' width='320'/> " \ 648 " <bandwidth type='AS'>42</bandwidth> " \ 649 " </description> " \ 650 " </session> " \ 651 "</iq> "); 652 653 // Initiate string without any supported codecs. Should send a reject. 654 const std::string kGingleInitiateNoSupportedAudioCodecs( 655 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 656 " to='user (at) domain.com/resource' type='set' id='123'> " \ 657 " <session xmlns='http://www.google.com/session' type='initiate'" \ 658 " id='abcdef' initiator='me (at) domain.com/resource'> " \ 659 " <description xmlns='http://www.google.com/session/phone'> " \ 660 " <payload-type xmlns='http://www.google.com/session/phone' " \ 661 " id='123' name='Supercodec6000' /> " \ 662 " </description> " \ 663 " </session> " \ 664 "</iq> "); 665 666 const std::string kJingleInitiateNoSupportedAudioCodecs( 667 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 668 " to='user (at) domain.com/resource' type='set' id='123'> " \ 669 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' " \ 670 " sid='abcdef' initiator='me (at) domain.com/resource'> " \ 671 " <content name='test audio'> " \ 672 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \ 673 " <payload-type " \ 674 " id='123' name='Supercodec6000' /> " \ 675 " </description> " \ 676 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 677 " </content> " \ 678 " </jingle> " \ 679 "</iq> "); 680 681 // Initiate string without any codecs. Assumes ancient version of Cricket 682 // and tries a session with ISAC and PCMU 683 const std::string kGingleInitiateNoAudioCodecs( 684 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 685 " to='user (at) domain.com/resource' type='set' id='123'> " \ 686 " <session xmlns='http://www.google.com/session' type='initiate'" \ 687 " id='abcdef' initiator='me (at) domain.com/resource'> " \ 688 " <description xmlns='http://www.google.com/session/phone'> " \ 689 " </description> " \ 690 " </session> " \ 691 "</iq> "); 692 693 const std::string kJingleInitiateNoAudioCodecs( 694 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 695 " to='user (at) domain.com/resource' type='set' id='123'> " \ 696 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' " \ 697 " sid='abcdef' initiator='me (at) domain.com/resource'> " \ 698 " <content name='test audio'> " \ 699 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \ 700 " </description> " \ 701 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 702 " </content> " \ 703 " </jingle> " \ 704 "</iq> "); 705 706 // The codecs are supported, but not at the given clockrates. Should send 707 // a reject. 708 const std::string kGingleInitiateWrongClockrates( 709 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 710 " to='user (at) domain.com/resource' type='set' id='123'> " \ 711 " <session xmlns='http://www.google.com/session' type='initiate'" \ 712 " id='abcdef' initiator='me (at) domain.com/resource'> " \ 713 " <description xmlns='http://www.google.com/session/phone'> " \ 714 " <payload-type xmlns='http://www.google.com/session/phone' " \ 715 " id='103' name='ISAC' clockrate='8000'/> " \ 716 " <payload-type xmlns='http://www.google.com/session/phone' " \ 717 " id='97' name='IPCMWB' clockrate='1337'/> " \ 718 " <payload-type xmlns='http://www.google.com/session/phone' " \ 719 " id='102' name='iLBC' clockrate='1982' /> " \ 720 " </description> " \ 721 " </session> " \ 722 "</iq> "); 723 724 const std::string kJingleInitiateWrongClockrates( 725 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 726 " to='user (at) domain.com/resource' type='set' id='123'> " \ 727 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' " \ 728 " sid='abcdef' initiator='me (at) domain.com/resource'> " \ 729 " <content name='test audio'> " \ 730 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \ 731 " <payload-type " \ 732 " id='103' name='ISAC' clockrate='8000'/> " \ 733 " <payload-type " \ 734 " id='97' name='IPCMWB' clockrate='1337'/> " \ 735 " <payload-type " \ 736 " id='102' name='iLBC' clockrate='1982' /> " \ 737 " </description> " \ 738 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 739 " </content> " \ 740 " </jingle> " \ 741 "</iq> "); 742 743 // The codecs are supported, but not with the given number of channels. 744 // Should send a reject. 745 const std::string kGingleInitiateWrongChannels( 746 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 747 " to='user (at) domain.com/resource' type='set' id='123'> " \ 748 " <session xmlns='http://www.google.com/session' type='initiate'" \ 749 " id='abcdef' initiator='me (at) domain.com/resource'> " \ 750 " <description xmlns='http://www.google.com/session/phone'> " \ 751 " <payload-type xmlns='http://www.google.com/session/phone' " \ 752 " id='103' name='ISAC' channels='2'/> " \ 753 " <payload-type xmlns='http://www.google.com/session/phone' " \ 754 " id='97' name='IPCMWB' channels='3'/> " \ 755 " </description> " \ 756 " </session> " \ 757 "</iq> "); 758 759 const std::string kJingleInitiateWrongChannels( 760 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 761 " to='user (at) domain.com/resource' type='set' id='123'> " \ 762 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'> " \ 763 " <content name='test audio'> " \ 764 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \ 765 " <payload-type " \ 766 " id='103' name='ISAC' channels='2'/> " \ 767 " <payload-type " \ 768 " id='97' name='IPCMWB' channels='3'/> " \ 769 " </description> " \ 770 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 771 " </content> " \ 772 " </jingle> " \ 773 "</iq> "); 774 775 // Initiate with a dynamic codec not using webrtc default payload id. Should 776 // accept with provided payload id. 777 const std::string kGingleInitiateDynamicAudioCodecs( 778 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 779 " to='user (at) domain.com/resource' type='set' id='123'> " \ 780 " <session xmlns='http://www.google.com/session' type='initiate'" \ 781 " id='abcdef' initiator='me (at) domain.com/resource'> " \ 782 " <description xmlns='http://www.google.com/session/phone'> " \ 783 " <payload-type xmlns='http://www.google.com/session/phone' " \ 784 " id='123' name='speex' clockrate='16000'/> " \ 785 " </description> " \ 786 " </session> " \ 787 "</iq> "); 788 789 const std::string kJingleInitiateDynamicAudioCodecs( 790 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 791 " to='user (at) domain.com/resource' type='set' id='123'> " \ 792 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' " \ 793 " sid='abcdef' initiator='me (at) domain.com/resource'> " \ 794 " <content name='test audio'> " \ 795 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \ 796 " <payload-type " \ 797 " id='123' name='speex' clockrate='16000'/> " \ 798 " </description> " \ 799 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 800 " </content> " \ 801 " </jingle> " \ 802 "</iq> "); 803 804 // Initiate string with nothing but static codec id's. Should accept. 805 const std::string kGingleInitiateStaticAudioCodecs( 806 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 807 " to='user (at) domain.com/resource' type='set' id='123'> " \ 808 " <session xmlns='http://www.google.com/session' type='initiate'" \ 809 " id='abcdef' initiator='me (at) domain.com/resource'> " \ 810 " <description xmlns='http://www.google.com/session/phone'> " \ 811 " <payload-type xmlns='http://www.google.com/session/phone' " \ 812 " id='3' /> " \ 813 " <payload-type xmlns='http://www.google.com/session/phone' " \ 814 " id='0' /> " \ 815 " <payload-type xmlns='http://www.google.com/session/phone' " \ 816 " id='8' /> " \ 817 " </description> " \ 818 " </session> " \ 819 "</iq> "); 820 821 const std::string kJingleInitiateStaticAudioCodecs( 822 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 823 " to='user (at) domain.com/resource' type='set' id='123'> " \ 824 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' " \ 825 " sid='abcdef' initiator='me (at) domain.com/resource'> " \ 826 " <content name='test audio'> " \ 827 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \ 828 " <payload-type id='3' /> " \ 829 " <payload-type id='0' /> " \ 830 " <payload-type id='8' /> " \ 831 " </description> " \ 832 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 833 " </content> " \ 834 " </jingle> " \ 835 "</iq> "); 836 837 // Initiate with payload type-less codecs. Should reject. 838 const std::string kGingleInitiateNoPayloadTypes( 839 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 840 " to='user (at) domain.com/resource' type='set' id='123'> " \ 841 " <session xmlns='http://www.google.com/session' type='initiate'" \ 842 " id='abcdef' initiator='me (at) domain.com/resource'> " \ 843 " <description xmlns='http://www.google.com/session/phone'> " \ 844 " <payload-type xmlns='http://www.google.com/session/phone' " \ 845 " name='ISAC' clockrate='16000'/> " \ 846 " </description> " \ 847 " </session> " \ 848 "</iq> "); 849 850 const std::string kJingleInitiateNoPayloadTypes( 851 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 852 " to='user (at) domain.com/resource' type='set' id='123'> " \ 853 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'> " \ 854 " sid='abcdef' initiator='me (at) domain.com/resource'> " \ 855 " <content name='test audio'> " \ 856 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \ 857 " <payload-type name='ISAC' clockrate='16000'/> " \ 858 " </description> " \ 859 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 860 " </content> " \ 861 " </jingle> " \ 862 "</iq> "); 863 864 // Initiate with unnamed dynamic codces. Should reject. 865 const std::string kGingleInitiateDynamicWithoutNames( 866 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 867 " to='user (at) domain.com/resource' type='set' id='123'> " \ 868 " <session xmlns='http://www.google.com/session' type='initiate'" \ 869 " id='abcdef' initiator='me (at) domain.com/resource'> " \ 870 " <description xmlns='http://www.google.com/session/phone'> " \ 871 " <payload-type xmlns='http://www.google.com/session/phone' " \ 872 " id='100' clockrate='16000'/> " \ 873 " </description> " \ 874 " </session> " \ 875 "</iq> "); 876 877 const std::string kJingleInitiateDynamicWithoutNames( 878 "<iq xmlns='jabber:client' from='me (at) domain.com/resource' " \ 879 " to='user (at) domain.com/resource' type='set' id='123'> " \ 880 " <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'> " \ 881 " sid='abcdef' initiator='me (at) domain.com/resource'> " \ 882 " <content name='test audio'> " \ 883 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \ 884 " <payload-type id='100' clockrate='16000'/> " \ 885 " </description> " \ 886 " <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \ 887 " </content> " \ 888 " </jingle> " \ 889 "</iq> "); 890 891 const uint32 kAudioSsrc = 4294967295U; 892 const uint32 kVideoSsrc = 87654321; 893 const uint32 kDataSsrc = 1010101; 894 const uint32 kDataSid = 0; 895 // Note that this message does not specify a session ID. It must be populated 896 // before use. 897 const std::string kGingleAcceptWithSsrcs( 898 "<iq xmlns='jabber:client' from='me (at) mydomain.com' " \ 899 " to='user (at) domain.com/resource' type='set' id='150'> " \ 900 " <session xmlns='http://www.google.com/session' type='accept' " \ 901 " initiator='me (at) domain.com/resource'> " \ 902 " <description xmlns='http://www.google.com/session/video'> " \ 903 " <payload-type xmlns='http://www.google.com/session/phone' " \ 904 " id='103' name='ISAC' clockrate='16000' /> " \ 905 " <payload-type xmlns='http://www.google.com/session/phone' " \ 906 " id='104' name='ISAC' clockrate='32000' /> " \ 907 " <src-id xmlns='http://www.google.com/session/phone'> " \ 908 " 4294967295</src-id> " \ 909 " <src-id>87654321</src-id> " \ 910 " </description> " \ 911 " </session> " \ 912 "</iq> "); 913 914 const std::string kJingleAcceptWithSsrcs( 915 "<iq xmlns='jabber:client' from='me (at) mydomain.com' " \ 916 " to='user (at) domain.com/resource' type='set' id='150'> " \ 917 " <jingle xmlns='urn:xmpp:jingle:1' action='session-accept' " \ 918 " initiator='me (at) domain.com/resource'> " \ 919 " <content name='audio'> " \ 920 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' " \ 921 " media='audio' ssrc='4294967295'> " \ 922 " <payload-type id='103' name='ISAC' clockrate='16000'/> " \ 923 " <payload-type id='104' name='ISAC' clockrate='32000'/> " \ 924 " </description> " \ 925 " <transport xmlns='http://www.google.com/transport/p2p'/> " \ 926 " </content> " \ 927 " <content name='video'> " \ 928 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' " \ 929 " media='video' ssrc='87654321'> " \ 930 " </description> " \ 931 " <transport xmlns='http://www.google.com/transport/p2p'/> " \ 932 " </content> " \ 933 " </jingle> " \ 934 "</iq> "); 935 936 const std::string kJingleAcceptWithRtpDataSsrcs( 937 "<iq xmlns='jabber:client' from='me (at) mydomain.com' " \ 938 " to='user (at) domain.com/resource' type='set' id='150'> " \ 939 " <jingle xmlns='urn:xmpp:jingle:1' action='session-accept' " \ 940 " initiator='me (at) domain.com/resource'> " \ 941 " <content name='audio'> " \ 942 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' " \ 943 " media='audio' ssrc='4294967295'> " \ 944 " <payload-type id='103' name='ISAC' clockrate='16000'/> " \ 945 " <payload-type id='104' name='ISAC' clockrate='32000'/> " \ 946 " </description> " \ 947 " <transport xmlns='http://www.google.com/transport/p2p'/> " \ 948 " </content> " \ 949 " <content name='video'> " \ 950 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' " \ 951 " media='video' ssrc='87654321'> " \ 952 " </description> " \ 953 " <transport xmlns='http://www.google.com/transport/p2p'/> " \ 954 " </content> " \ 955 " <content name='data'> " \ 956 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' " \ 957 " media='data' ssrc='1010101'> " \ 958 " </description> " \ 959 " <transport xmlns='http://www.google.com/transport/p2p'/> " \ 960 " </content> " \ 961 " </jingle> " \ 962 "</iq> "); 963 964 const std::string kJingleAcceptWithSctpData( 965 "<iq xmlns='jabber:client' from='me (at) mydomain.com' " \ 966 " to='user (at) domain.com/resource' type='set' id='150'> " \ 967 " <jingle xmlns='urn:xmpp:jingle:1' action='session-accept' " \ 968 " initiator='me (at) domain.com/resource'> " \ 969 " <content name='audio'> " \ 970 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' " \ 971 " media='audio' ssrc='4294967295'> " \ 972 " <payload-type id='103' name='ISAC' clockrate='16000'/> " \ 973 " <payload-type id='104' name='ISAC' clockrate='32000'/> " \ 974 " </description> " \ 975 " <transport xmlns='http://www.google.com/transport/p2p'/> " \ 976 " </content> " \ 977 " <content name='video'> " \ 978 " <description xmlns='urn:xmpp:jingle:apps:rtp:1' " \ 979 " media='video' ssrc='87654321'> " \ 980 " </description> " \ 981 " <transport xmlns='http://www.google.com/transport/p2p'/> " \ 982 " </content> " \ 983 " <content name='data'> " \ 984 " <description xmlns='google:jingle:sctp'> " \ 985 " <stream sid='1'/> " \ 986 " </description> " \ 987 " <transport xmlns='http://www.google.com/transport/p2p'/> " \ 988 " </content> " \ 989 " </jingle> " \ 990 "</iq> "); 991 992 std::string JingleView(const std::string& ssrc, 993 const std::string& width, 994 const std::string& height, 995 const std::string& framerate) { 996 // We have some slightly weird whitespace formatting to make the 997 // actual XML generated match the expected XML here. 998 return \ 999 "<cli:iq" 1000 " to='me (at) mydomain.com'" 1001 " type='set'" 1002 " xmlns:cli='jabber:client'>" 1003 "<jingle" 1004 " xmlns='urn:xmpp:jingle:1'" 1005 " action='session-info'" 1006 " sid=''>" 1007 "<view xmlns='google:jingle'" 1008 " name='video'" 1009 " type='static'" 1010 " ssrc='" + ssrc + "'>" 1011 "<params" 1012 " width='" + width + "'" 1013 " height='" + height + "'" 1014 " framerate='" + framerate + "'" 1015 " preference='0'/>" 1016 "</view>" 1017 "</jingle>" 1018 "</cli:iq>"; 1019 } 1020 1021 std::string JingleStreamAdd(const std::string& content_name, 1022 const std::string& nick, 1023 const std::string& name, 1024 const std::string& ssrc) { 1025 return \ 1026 "<iq" 1027 " xmlns='jabber:client'" 1028 " from='me (at) mydomain.com'" 1029 " to='user (at) domain.com/resource'" 1030 " type='set'" 1031 " id='150'>" 1032 " <jingle" 1033 " xmlns='urn:xmpp:jingle:1'" 1034 " action='description-info'>" 1035 " <content" 1036 " xmlns='urn:xmpp:jingle:1'" 1037 " name='" + content_name + "'>" 1038 " <description" 1039 " xmlns='urn:xmpp:jingle:apps:rtp:1'" 1040 " media='" + content_name + "'>" 1041 " <streams" 1042 " xmlns='google:jingle'>" 1043 " <stream" 1044 " nick='" + nick + "'" 1045 " name='" + name + "'>" 1046 " <ssrc>" + ssrc + "</ssrc>" 1047 " </stream>" 1048 " </streams>" 1049 " </description>" 1050 " </content>" 1051 " </jingle>" 1052 "</iq>"; 1053 } 1054 1055 std::string JingleOutboundStreamRemove(const std::string& sid, 1056 const std::string& content_name, 1057 const std::string& name) { 1058 return \ 1059 "<cli:iq" 1060 " to='me (at) mydomain.com'" 1061 " type='set'" 1062 " xmlns:cli='jabber:client'>" 1063 "<jingle" 1064 " xmlns='urn:xmpp:jingle:1'" 1065 " action='description-info'" 1066 " sid='" + sid + "'>" 1067 "<content" 1068 " name='" + content_name + "'" 1069 " creator='initiator'>" 1070 "<description" 1071 " xmlns='urn:xmpp:jingle:apps:rtp:1'" 1072 " media='" + content_name + "'>" 1073 "<streams" 1074 " xmlns='google:jingle'>" 1075 "<stream" 1076 " name='" + name + "'>" 1077 "</stream>" 1078 "</streams>" 1079 "</description>" 1080 "</content>" 1081 "</jingle>" 1082 "</cli:iq>"; 1083 } 1084 1085 std::string JingleOutboundStreamAdd(const std::string& sid, 1086 const std::string& content_name, 1087 const std::string& name, 1088 const std::string& ssrc) { 1089 return \ 1090 "<cli:iq" 1091 " to='me (at) mydomain.com'" 1092 " type='set'" 1093 " xmlns:cli='jabber:client'>" 1094 "<jingle" 1095 " xmlns='urn:xmpp:jingle:1'" 1096 " action='description-info'" 1097 " sid='" + sid + "'>" 1098 "<content" 1099 " name='" + content_name + "'" 1100 " creator='initiator'>" 1101 "<description" 1102 " xmlns='urn:xmpp:jingle:apps:rtp:1'" 1103 " media='" + content_name + "'>" 1104 "<streams" 1105 " xmlns='google:jingle'>" 1106 "<stream" 1107 " name='" + name + "'>" 1108 "<ssrc>" + ssrc + "</ssrc>" 1109 "</stream>" 1110 "</streams>" 1111 "</description>" 1112 "</content>" 1113 "</jingle>" 1114 "</cli:iq>"; 1115 } 1116 1117 std::string JingleStreamAddWithoutSsrc(const std::string& content_name, 1118 const std::string& nick, 1119 const std::string& name) { 1120 return \ 1121 "<iq" 1122 " xmlns='jabber:client'" 1123 " from='me (at) mydomain.com'" 1124 " to='user (at) domain.com/resource'" 1125 " type='set'" 1126 " id='150'>" 1127 " <jingle" 1128 " xmlns='urn:xmpp:jingle:1'" 1129 " action='description-info'>" 1130 " <content" 1131 " xmlns='urn:xmpp:jingle:1'" 1132 " name='" + content_name + "'>" 1133 " <description" 1134 " xmlns='urn:xmpp:jingle:apps:rtp:1'" 1135 " media='" + content_name + "'>" 1136 " <streams" 1137 " xmlns='google:jingle'>" 1138 " <stream" 1139 " nick='" + nick + "'" 1140 " name='" + name + "'>" 1141 " </stream>" 1142 " </streams>" 1143 " </description>" 1144 " </content>" 1145 " </jingle>" 1146 "</iq>"; 1147 } 1148 1149 std::string JingleStreamRemove(const std::string& content_name, 1150 const std::string& nick, 1151 const std::string& name) { 1152 return \ 1153 "<iq" 1154 " xmlns='jabber:client'" 1155 " from='me (at) mydomain.com'" 1156 " to='user (at) domain.com/resource'" 1157 " type='set'" 1158 " id='150'>" 1159 " <jingle" 1160 " xmlns='urn:xmpp:jingle:1'" 1161 " action='description-info'>" 1162 " <content" 1163 " xmlns='urn:xmpp:jingle:1'" 1164 " name='" + content_name + "'>" 1165 " <description" 1166 " xmlns='urn:xmpp:jingle:apps:rtp:1'" 1167 " media='" + content_name + "'>" 1168 " <streams" 1169 " xmlns='google:jingle'>" 1170 " <stream" 1171 " nick='" + nick + "'" 1172 " name='" + name + "'/>" 1173 " </streams>" 1174 " </description>" 1175 " </content>" 1176 " </jingle>" 1177 "</iq>"; 1178 } 1179 1180 // Convenience function to get CallOptions that have audio enabled, 1181 // but not video or data. 1182 static cricket::CallOptions AudioCallOptions() { 1183 cricket::CallOptions options; 1184 options.has_audio = true; 1185 options.has_video = false; 1186 options.data_channel_type = cricket::DCT_NONE; 1187 return options; 1188 } 1189 1190 // Convenience function to get CallOptions that have audio and video 1191 // enabled, but not data. 1192 static cricket::CallOptions VideoCallOptions() { 1193 cricket::CallOptions options; 1194 options.has_audio = true; 1195 options.has_video = true; 1196 options.data_channel_type = cricket::DCT_NONE; 1197 return options; 1198 } 1199 1200 static buzz::XmlElement* CopyElement(const buzz::XmlElement* elem) { 1201 return new buzz::XmlElement(*elem); 1202 } 1203 1204 static std::string AddEncryption(std::string stanza, std::string encryption) { 1205 std::string::size_type pos = stanza.find("</description>"); 1206 while (pos != std::string::npos) { 1207 stanza = stanza.insert(pos, encryption); 1208 pos = stanza.find("</description>", pos + encryption.length() + 1); 1209 } 1210 return stanza; 1211 } 1212 1213 static int IntFromJingleCodecParameter(const buzz::XmlElement* parameter, 1214 const std::string& expected_name) { 1215 if (parameter) { 1216 const std::string& actual_name = 1217 parameter->Attr(cricket::QN_PAYLOADTYPE_PARAMETER_NAME); 1218 1219 EXPECT_EQ(expected_name, actual_name) 1220 << "wrong parameter name. Expected '" 1221 << expected_name << "'. Actually '" 1222 << actual_name << "'."; 1223 1224 return atoi(parameter->Attr( 1225 cricket::QN_PAYLOADTYPE_PARAMETER_VALUE).c_str()); 1226 } 1227 return 0; 1228 } 1229 1230 template <class CodecClass, class DescriptionClass> 1231 static void VerifyCodecFbParams(const FeedbackParams& expected, 1232 const DescriptionClass* desc) { 1233 if (!expected.params().empty()) { 1234 ASSERT_TRUE(desc != NULL); 1235 const std::vector<CodecClass> codecs = desc->codecs(); 1236 for (size_t i = 0; i < codecs.size(); ++i) { 1237 EXPECT_EQ(expected, codecs[i].feedback_params); 1238 } 1239 } 1240 } 1241 1242 // Parses and extracts payload and codec info from test XML. Since 1243 // that XML will be in various contents (Gingle and Jingle), we need an 1244 // abstract parser with one concrete implementation per XML content. 1245 class MediaSessionTestParser { 1246 public: 1247 virtual buzz::XmlElement* ActionFromStanza(buzz::XmlElement* stanza) = 0; 1248 virtual buzz::XmlElement* ContentFromAction(buzz::XmlElement* action) = 0; 1249 virtual buzz::XmlElement* NextContent(buzz::XmlElement* content) = 0; 1250 virtual buzz::XmlElement* PayloadTypeFromContent( 1251 buzz::XmlElement* content) = 0; 1252 virtual buzz::XmlElement* NextFromPayloadType( 1253 buzz::XmlElement* payload_type) = 0; 1254 virtual cricket::AudioCodec AudioCodecFromPayloadType( 1255 const buzz::XmlElement* payload_type) = 0; 1256 virtual cricket::VideoCodec VideoCodecFromPayloadType( 1257 const buzz::XmlElement* payload_type) = 0; 1258 virtual cricket::DataCodec DataCodecFromPayloadType( 1259 const buzz::XmlElement* payload_type) = 0; 1260 virtual buzz::XmlElement* EncryptionFromContent( 1261 buzz::XmlElement* content) = 0; 1262 virtual buzz::XmlElement* NextFromEncryption( 1263 buzz::XmlElement* encryption) = 0; 1264 virtual const buzz::XmlElement* BandwidthFromContent( 1265 buzz::XmlElement* content) = 0; 1266 virtual const buzz::XmlElement* RtcpMuxFromContent( 1267 buzz::XmlElement* content) = 0; 1268 virtual bool ActionIsTerminate(const buzz::XmlElement* action) = 0; 1269 virtual ~MediaSessionTestParser() {} 1270 }; 1271 1272 class JingleSessionTestParser : public MediaSessionTestParser { 1273 public: 1274 JingleSessionTestParser() {} 1275 1276 ~JingleSessionTestParser() { 1277 } 1278 1279 buzz::XmlElement* ActionFromStanza(buzz::XmlElement* stanza) { 1280 return stanza->FirstNamed(cricket::QN_JINGLE); 1281 } 1282 1283 buzz::XmlElement* ContentFromAction(buzz::XmlElement* action) { 1284 // We need to be able to use multiple contents, but the action 1285 // gets deleted before we can call NextContent, so we need to 1286 // stash away a copy. 1287 action_.reset(CopyElement(action)); 1288 return action_->FirstNamed(cricket::QN_JINGLE_CONTENT); 1289 } 1290 1291 buzz::XmlElement* NextContent(buzz::XmlElement* content) { 1292 // For some reason, content->NextNamed(cricket::QN_JINGLE_CONTENT) 1293 // doesn't work. 1294 return action_->FirstNamed(cricket::QN_JINGLE_CONTENT) 1295 ->NextNamed(cricket::QN_JINGLE_CONTENT); 1296 } 1297 1298 buzz::XmlElement* PayloadTypeFromContent(buzz::XmlElement* content) { 1299 buzz::XmlElement* content_desc = 1300 content->FirstNamed(cricket::QN_JINGLE_RTP_CONTENT); 1301 if (!content_desc) 1302 return NULL; 1303 1304 return content_desc->FirstNamed(cricket::QN_JINGLE_RTP_PAYLOADTYPE); 1305 } 1306 1307 buzz::XmlElement* NextFromPayloadType(buzz::XmlElement* payload_type) { 1308 return payload_type->NextNamed(cricket::QN_JINGLE_RTP_PAYLOADTYPE); 1309 } 1310 1311 void ParsePayloadTypeFeedbackParameters(const buzz::XmlElement* element, 1312 FeedbackParams* params) { 1313 const buzz::XmlElement* param = 1314 element->FirstNamed(cricket::QN_JINGLE_RTCP_FB); 1315 for (; param != NULL; 1316 param = param->NextNamed(cricket::QN_JINGLE_RTCP_FB)) { 1317 std::string type = param->Attr(cricket::QN_TYPE); 1318 std::string subtype = param->Attr(cricket::QN_SUBTYPE); 1319 if (!type.empty()) { 1320 params->Add(FeedbackParam(type, subtype)); 1321 } 1322 } 1323 } 1324 1325 cricket::AudioCodec AudioCodecFromPayloadType( 1326 const buzz::XmlElement* payload_type) { 1327 int id = 0; 1328 if (payload_type->HasAttr(cricket::QN_ID)) 1329 id = atoi(payload_type->Attr(cricket::QN_ID).c_str()); 1330 1331 std::string name; 1332 if (payload_type->HasAttr(cricket::QN_NAME)) 1333 name = payload_type->Attr(cricket::QN_NAME); 1334 1335 int clockrate = 0; 1336 if (payload_type->HasAttr(cricket::QN_CLOCKRATE)) 1337 clockrate = atoi(payload_type->Attr(cricket::QN_CLOCKRATE).c_str()); 1338 1339 int bitrate = IntFromJingleCodecParameter( 1340 payload_type->FirstNamed(cricket::QN_PARAMETER), "bitrate"); 1341 1342 int channels = 1; 1343 if (payload_type->HasAttr(cricket::QN_CHANNELS)) 1344 channels = atoi(payload_type->Attr( 1345 cricket::QN_CHANNELS).c_str()); 1346 1347 AudioCodec codec = AudioCodec(id, name, clockrate, bitrate, channels, 0); 1348 ParsePayloadTypeFeedbackParameters(payload_type, &codec.feedback_params); 1349 return codec; 1350 } 1351 1352 cricket::VideoCodec VideoCodecFromPayloadType( 1353 const buzz::XmlElement* payload_type) { 1354 int id = 0; 1355 if (payload_type->HasAttr(cricket::QN_ID)) 1356 id = atoi(payload_type->Attr(cricket::QN_ID).c_str()); 1357 1358 std::string name; 1359 if (payload_type->HasAttr(cricket::QN_NAME)) 1360 name = payload_type->Attr(cricket::QN_NAME); 1361 1362 int width = 0; 1363 int height = 0; 1364 int framerate = 0; 1365 const buzz::XmlElement* param = 1366 payload_type->FirstNamed(cricket::QN_PARAMETER); 1367 if (param) { 1368 width = IntFromJingleCodecParameter(param, "width"); 1369 param = param->NextNamed(cricket::QN_PARAMETER); 1370 if (param) { 1371 height = IntFromJingleCodecParameter(param, "height"); 1372 param = param->NextNamed(cricket::QN_PARAMETER); 1373 if (param) { 1374 framerate = IntFromJingleCodecParameter(param, "framerate"); 1375 } 1376 } 1377 } 1378 VideoCodec codec = VideoCodec(id, name, width, height, framerate, 0); 1379 ParsePayloadTypeFeedbackParameters(payload_type, &codec.feedback_params); 1380 return codec; 1381 } 1382 1383 cricket::DataCodec DataCodecFromPayloadType( 1384 const buzz::XmlElement* payload_type) { 1385 int id = 0; 1386 if (payload_type->HasAttr(cricket::QN_ID)) 1387 id = atoi(payload_type->Attr(cricket::QN_ID).c_str()); 1388 1389 std::string name; 1390 if (payload_type->HasAttr(cricket::QN_NAME)) 1391 name = payload_type->Attr(cricket::QN_NAME); 1392 1393 DataCodec codec = DataCodec(id, name, 0); 1394 ParsePayloadTypeFeedbackParameters(payload_type, &codec.feedback_params); 1395 return codec; 1396 } 1397 1398 bool ActionIsTerminate(const buzz::XmlElement* action) { 1399 return (action->HasAttr(cricket::QN_ACTION) && 1400 action->Attr(cricket::QN_ACTION) == "session-terminate"); 1401 } 1402 1403 buzz::XmlElement* EncryptionFromContent(buzz::XmlElement* content) { 1404 buzz::XmlElement* content_desc = 1405 content->FirstNamed(cricket::QN_JINGLE_RTP_CONTENT); 1406 if (!content_desc) 1407 return NULL; 1408 1409 return content_desc->FirstNamed(cricket::QN_ENCRYPTION); 1410 } 1411 1412 buzz::XmlElement* NextFromEncryption(buzz::XmlElement* encryption) { 1413 return encryption->NextNamed(cricket::QN_ENCRYPTION); 1414 } 1415 1416 const buzz::XmlElement* BandwidthFromContent(buzz::XmlElement* content) { 1417 buzz::XmlElement* content_desc = 1418 content->FirstNamed(cricket::QN_JINGLE_RTP_CONTENT); 1419 if (!content_desc) 1420 return NULL; 1421 1422 return content_desc->FirstNamed(cricket::QN_JINGLE_RTP_BANDWIDTH); 1423 } 1424 1425 const buzz::XmlElement* RtcpMuxFromContent(buzz::XmlElement* content) { 1426 return content->FirstNamed(cricket::QN_JINGLE_RTCP_MUX); 1427 } 1428 1429 private: 1430 talk_base::scoped_ptr<buzz::XmlElement> action_; 1431 }; 1432 1433 class GingleSessionTestParser : public MediaSessionTestParser { 1434 public: 1435 GingleSessionTestParser() : found_content_count_(0) {} 1436 1437 buzz::XmlElement* ActionFromStanza(buzz::XmlElement* stanza) { 1438 return stanza->FirstNamed(cricket::QN_GINGLE_SESSION); 1439 } 1440 1441 buzz::XmlElement* ContentFromAction(buzz::XmlElement* session) { 1442 buzz::XmlElement* content = 1443 session->FirstNamed(cricket::QN_GINGLE_AUDIO_CONTENT); 1444 if (content == NULL) 1445 content = session->FirstNamed(cricket::QN_GINGLE_VIDEO_CONTENT); 1446 return content; 1447 } 1448 1449 // Assumes contents are in order of audio, and then video. 1450 buzz::XmlElement* NextContent(buzz::XmlElement* content) { 1451 found_content_count_++; 1452 return content; 1453 } 1454 1455 buzz::XmlElement* PayloadTypeFromContent(buzz::XmlElement* content) { 1456 if (found_content_count_ > 0) { 1457 return content->FirstNamed(cricket::QN_GINGLE_VIDEO_PAYLOADTYPE); 1458 } else { 1459 return content->FirstNamed(cricket::QN_GINGLE_AUDIO_PAYLOADTYPE); 1460 } 1461 } 1462 1463 buzz::XmlElement* NextFromPayloadType(buzz::XmlElement* payload_type) { 1464 if (found_content_count_ > 0) { 1465 return payload_type->NextNamed(cricket::QN_GINGLE_VIDEO_PAYLOADTYPE); 1466 } else { 1467 return payload_type->NextNamed(cricket::QN_GINGLE_AUDIO_PAYLOADTYPE); 1468 } 1469 } 1470 1471 cricket::AudioCodec AudioCodecFromPayloadType( 1472 const buzz::XmlElement* payload_type) { 1473 int id = 0; 1474 if (payload_type->HasAttr(cricket::QN_ID)) 1475 id = atoi(payload_type->Attr(cricket::QN_ID).c_str()); 1476 1477 std::string name; 1478 if (payload_type->HasAttr(cricket::QN_NAME)) 1479 name = payload_type->Attr(cricket::QN_NAME); 1480 1481 int clockrate = 0; 1482 if (payload_type->HasAttr(cricket::QN_CLOCKRATE)) 1483 clockrate = atoi(payload_type->Attr(cricket::QN_CLOCKRATE).c_str()); 1484 1485 int bitrate = 0; 1486 if (payload_type->HasAttr(cricket::QN_BITRATE)) 1487 bitrate = atoi(payload_type->Attr(cricket::QN_BITRATE).c_str()); 1488 1489 int channels = 1; 1490 if (payload_type->HasAttr(cricket::QN_CHANNELS)) 1491 channels = atoi(payload_type->Attr(cricket::QN_CHANNELS).c_str()); 1492 1493 return cricket::AudioCodec(id, name, clockrate, bitrate, channels, 0); 1494 } 1495 1496 cricket::VideoCodec VideoCodecFromPayloadType( 1497 const buzz::XmlElement* payload_type) { 1498 int id = 0; 1499 if (payload_type->HasAttr(cricket::QN_ID)) 1500 id = atoi(payload_type->Attr(cricket::QN_ID).c_str()); 1501 1502 std::string name; 1503 if (payload_type->HasAttr(cricket::QN_NAME)) 1504 name = payload_type->Attr(cricket::QN_NAME); 1505 1506 int width = 0; 1507 if (payload_type->HasAttr(cricket::QN_WIDTH)) 1508 width = atoi(payload_type->Attr(cricket::QN_WIDTH).c_str()); 1509 1510 int height = 0; 1511 if (payload_type->HasAttr(cricket::QN_HEIGHT)) 1512 height = atoi(payload_type->Attr(cricket::QN_HEIGHT).c_str()); 1513 1514 int framerate = 1; 1515 if (payload_type->HasAttr(cricket::QN_FRAMERATE)) 1516 framerate = atoi(payload_type->Attr(cricket::QN_FRAMERATE).c_str()); 1517 1518 return cricket::VideoCodec(id, name, width, height, framerate, 0); 1519 } 1520 1521 cricket::DataCodec DataCodecFromPayloadType( 1522 const buzz::XmlElement* payload_type) { 1523 // Gingle can't do data codecs. 1524 return cricket::DataCodec(0, "", 0); 1525 } 1526 1527 buzz::XmlElement* EncryptionFromContent( 1528 buzz::XmlElement* content) { 1529 return content->FirstNamed(cricket::QN_ENCRYPTION); 1530 } 1531 1532 buzz::XmlElement* NextFromEncryption(buzz::XmlElement* encryption) { 1533 return encryption->NextNamed(cricket::QN_ENCRYPTION); 1534 } 1535 1536 const buzz::XmlElement* BandwidthFromContent(buzz::XmlElement* content) { 1537 return content->FirstNamed(cricket::QN_GINGLE_VIDEO_BANDWIDTH); 1538 } 1539 1540 const buzz::XmlElement* RtcpMuxFromContent(buzz::XmlElement* content) { 1541 return NULL; 1542 } 1543 1544 bool ActionIsTerminate(const buzz::XmlElement* session) { 1545 return (session->HasAttr(buzz::QN_TYPE) && 1546 session->Attr(buzz::QN_TYPE) == "terminate"); 1547 } 1548 1549 int found_content_count_; 1550 }; 1551 1552 class MediaSessionClientTest : public sigslot::has_slots<> { 1553 public: 1554 explicit MediaSessionClientTest(MediaSessionTestParser* parser, 1555 cricket::SignalingProtocol initial_protocol) { 1556 nm_ = new talk_base::BasicNetworkManager(); 1557 pa_ = new cricket::BasicPortAllocator(nm_); 1558 sm_ = new cricket::SessionManager(pa_, NULL); 1559 fme_ = new cricket::FakeMediaEngine(); 1560 fdme_ = new cricket::FakeDataEngine(); 1561 1562 FeedbackParams params_nack_fir; 1563 params_nack_fir.Add(FeedbackParam(cricket::kRtcpFbParamCcm, 1564 cricket::kRtcpFbCcmParamFir)); 1565 params_nack_fir.Add(FeedbackParam(cricket::kRtcpFbParamNack)); 1566 FeedbackParams params_nack; 1567 params_nack.Add(FeedbackParam(cricket::kRtcpFbParamNack)); 1568 1569 std::vector<cricket::AudioCodec> 1570 audio_codecs(kAudioCodecs, kAudioCodecs + ARRAY_SIZE(kAudioCodecs)); 1571 SetCodecFeedbackParams(&audio_codecs, params_nack); 1572 fme_->SetAudioCodecs(audio_codecs); 1573 std::vector<cricket::VideoCodec> 1574 video_codecs(kVideoCodecs, kVideoCodecs + ARRAY_SIZE(kVideoCodecs)); 1575 SetCodecFeedbackParams(&video_codecs, params_nack_fir); 1576 fme_->SetVideoCodecs(video_codecs); 1577 std::vector<cricket::DataCodec> 1578 data_codecs(kDataCodecs, kDataCodecs + ARRAY_SIZE(kDataCodecs)); 1579 SetCodecFeedbackParams(&data_codecs, params_nack); 1580 fdme_->SetDataCodecs(data_codecs); 1581 1582 client_ = new cricket::MediaSessionClient( 1583 buzz::Jid("user (at) domain.com/resource"), sm_, 1584 fme_, fdme_, new cricket::FakeDeviceManager()); 1585 client_->session_manager()->SignalOutgoingMessage.connect( 1586 this, &MediaSessionClientTest::OnSendStanza); 1587 client_->session_manager()->SignalSessionCreate.connect( 1588 this, &MediaSessionClientTest::OnSessionCreate); 1589 client_->SignalCallCreate.connect( 1590 this, &MediaSessionClientTest::OnCallCreate); 1591 client_->SignalCallDestroy.connect( 1592 this, &MediaSessionClientTest::OnCallDestroy); 1593 1594 call_ = NULL; 1595 parser_ = parser; 1596 initial_protocol_ = initial_protocol; 1597 expect_incoming_crypto_ = false; 1598 expect_outgoing_crypto_ = false; 1599 expected_video_bandwidth_ = cricket::kAutoBandwidth; 1600 expected_video_rtcp_mux_ = false; 1601 } 1602 1603 ~MediaSessionClientTest() { 1604 delete client_; 1605 delete sm_; 1606 delete pa_; 1607 delete nm_; 1608 delete parser_; 1609 ClearStanzas(); 1610 } 1611 1612 buzz::XmlElement* ActionFromStanza(buzz::XmlElement* stanza) { 1613 return parser_->ActionFromStanza(stanza); 1614 } 1615 1616 buzz::XmlElement* ContentFromAction(buzz::XmlElement* action) { 1617 return parser_->ContentFromAction(action); 1618 } 1619 1620 buzz::XmlElement* PayloadTypeFromContent(buzz::XmlElement* payload) { 1621 return parser_->PayloadTypeFromContent(payload); 1622 } 1623 1624 buzz::XmlElement* NextFromPayloadType(buzz::XmlElement* payload_type) { 1625 return parser_->NextFromPayloadType(payload_type); 1626 } 1627 1628 buzz::XmlElement* EncryptionFromContent(buzz::XmlElement* content) { 1629 return parser_->EncryptionFromContent(content); 1630 } 1631 1632 buzz::XmlElement* NextFromEncryption(buzz::XmlElement* encryption) { 1633 return parser_->NextFromEncryption(encryption); 1634 } 1635 1636 cricket::AudioCodec AudioCodecFromPayloadType( 1637 const buzz::XmlElement* payload_type) { 1638 return parser_->AudioCodecFromPayloadType(payload_type); 1639 } 1640 1641 cricket::VideoCodec VideoCodecFromPayloadType( 1642 const buzz::XmlElement* payload_type) { 1643 return parser_->VideoCodecFromPayloadType(payload_type); 1644 } 1645 1646 cricket::DataCodec DataCodecFromPayloadType( 1647 const buzz::XmlElement* payload_type) { 1648 return parser_->DataCodecFromPayloadType(payload_type); 1649 } 1650 1651 const AudioContentDescription* GetFirstAudioContentDescription( 1652 const cricket::SessionDescription* sdesc) { 1653 const cricket::ContentInfo* content = 1654 cricket::GetFirstAudioContent(sdesc); 1655 if (content == NULL) 1656 return NULL; 1657 return static_cast<const AudioContentDescription*>(content->description); 1658 } 1659 1660 const cricket::VideoContentDescription* GetFirstVideoContentDescription( 1661 const cricket::SessionDescription* sdesc) { 1662 const cricket::ContentInfo* content = 1663 cricket::GetFirstVideoContent(sdesc); 1664 if (content == NULL) 1665 return NULL; 1666 return static_cast<const cricket::VideoContentDescription*>( 1667 content->description); 1668 } 1669 1670 void CheckCryptoFromGoodIncomingInitiate(const cricket::Session* session) { 1671 ASSERT_TRUE(session != NULL); 1672 const AudioContentDescription* content = 1673 GetFirstAudioContentDescription(session->remote_description()); 1674 ASSERT_TRUE(content != NULL); 1675 ASSERT_EQ(2U, content->cryptos().size()); 1676 ASSERT_EQ(145, content->cryptos()[0].tag); 1677 ASSERT_EQ("AES_CM_128_HMAC_SHA1_32", content->cryptos()[0].cipher_suite); 1678 ASSERT_EQ("inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9", 1679 content->cryptos()[0].key_params); 1680 ASSERT_EQ(51, content->cryptos()[1].tag); 1681 ASSERT_EQ("AES_CM_128_HMAC_SHA1_80", content->cryptos()[1].cipher_suite); 1682 ASSERT_EQ("inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy", 1683 content->cryptos()[1].key_params); 1684 } 1685 1686 void CheckCryptoForGoodOutgoingAccept(const cricket::Session* session) { 1687 const AudioContentDescription* content = 1688 GetFirstAudioContentDescription(session->local_description()); 1689 ASSERT_EQ(1U, content->cryptos().size()); 1690 ASSERT_EQ(145, content->cryptos()[0].tag); 1691 ASSERT_EQ("AES_CM_128_HMAC_SHA1_32", content->cryptos()[0].cipher_suite); 1692 ASSERT_EQ(47U, content->cryptos()[0].key_params.size()); 1693 } 1694 1695 void CheckBadCryptoFromIncomingInitiate(const cricket::Session* session) { 1696 const AudioContentDescription* content = 1697 GetFirstAudioContentDescription(session->remote_description()); 1698 ASSERT_EQ(1U, content->cryptos().size()); 1699 ASSERT_EQ(145, content->cryptos()[0].tag); 1700 ASSERT_EQ("NOT_SUPPORTED", content->cryptos()[0].cipher_suite); 1701 ASSERT_EQ("inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9", 1702 content->cryptos()[0].key_params); 1703 } 1704 1705 void CheckNoCryptoForOutgoingAccept(const cricket::Session* session) { 1706 const AudioContentDescription* content = 1707 GetFirstAudioContentDescription(session->local_description()); 1708 ASSERT_TRUE(content->cryptos().empty()); 1709 } 1710 1711 void CheckRtcpFb(const cricket::SessionDescription* sdesc) { 1712 VerifyCodecFbParams<AudioCodec>(expected_audio_fb_params_, 1713 GetFirstAudioContentDescription(sdesc)); 1714 1715 VerifyCodecFbParams<VideoCodec>(expected_video_fb_params_, 1716 GetFirstVideoContentDescription(sdesc)); 1717 1718 VerifyCodecFbParams<DataCodec>(expected_data_fb_params_, 1719 GetFirstDataContentDescription(sdesc)); 1720 } 1721 1722 void CheckVideoBandwidth(int expected_bandwidth, 1723 const cricket::SessionDescription* sdesc) { 1724 const cricket::VideoContentDescription* video = 1725 GetFirstVideoContentDescription(sdesc); 1726 if (video != NULL) { 1727 ASSERT_EQ(expected_bandwidth, video->bandwidth()); 1728 } 1729 } 1730 1731 void CheckVideoRtcpMux(bool expected_video_rtcp_mux, 1732 const cricket::SessionDescription* sdesc) { 1733 const cricket::VideoContentDescription* video = 1734 GetFirstVideoContentDescription(sdesc); 1735 if (video != NULL) { 1736 ASSERT_EQ(expected_video_rtcp_mux, video->rtcp_mux()); 1737 } 1738 } 1739 1740 virtual void CheckRtpDataContent(buzz::XmlElement* content) { 1741 if (initial_protocol_) { 1742 // Gingle can not write out data content. 1743 return; 1744 } 1745 1746 buzz::XmlElement* e = PayloadTypeFromContent(content); 1747 ASSERT_TRUE(e != NULL); 1748 cricket::DataCodec codec = DataCodecFromPayloadType(e); 1749 EXPECT_EQ(127, codec.id); 1750 EXPECT_EQ("google-data", codec.name); 1751 EXPECT_EQ(expected_data_fb_params_, codec.feedback_params); 1752 1753 CheckDataRtcpMux(true, call_->sessions()[0]->local_description()); 1754 CheckDataRtcpMux(true, call_->sessions()[0]->remote_description()); 1755 if (expect_outgoing_crypto_) { 1756 content = parser_->NextContent(content); 1757 buzz::XmlElement* encryption = EncryptionFromContent(content); 1758 ASSERT_TRUE(encryption != NULL); 1759 // TODO(pthatcher): Check encryption parameters? 1760 } 1761 } 1762 1763 virtual void CheckSctpDataContent(buzz::XmlElement* content) { 1764 if (initial_protocol_) { 1765 // Gingle can not write out data content. 1766 return; 1767 } 1768 1769 buzz::XmlElement* payload_type = PayloadTypeFromContent(content); 1770 ASSERT_TRUE(payload_type == NULL); 1771 buzz::XmlElement* encryption = EncryptionFromContent(content); 1772 ASSERT_TRUE(encryption == NULL); 1773 // TODO(pthatcher): Check for <streams>. 1774 } 1775 1776 void CheckDataRtcpMux(bool expected_data_rtcp_mux, 1777 const cricket::SessionDescription* sdesc) { 1778 const cricket::DataContentDescription* data = 1779 GetFirstDataContentDescription(sdesc); 1780 if (data != NULL) { 1781 ASSERT_EQ(expected_data_rtcp_mux, data->rtcp_mux()); 1782 } 1783 } 1784 1785 void CheckAudioSsrcForIncomingAccept(const cricket::Session* session) { 1786 const AudioContentDescription* audio = 1787 GetFirstAudioContentDescription(session->remote_description()); 1788 ASSERT_TRUE(audio != NULL); 1789 ASSERT_EQ(kAudioSsrc, audio->first_ssrc()); 1790 } 1791 1792 void CheckVideoSsrcForIncomingAccept(const cricket::Session* session) { 1793 const cricket::VideoContentDescription* video = 1794 GetFirstVideoContentDescription(session->remote_description()); 1795 ASSERT_TRUE(video != NULL); 1796 ASSERT_EQ(kVideoSsrc, video->first_ssrc()); 1797 } 1798 1799 void CheckDataSsrcForIncomingAccept(const cricket::Session* session) { 1800 const cricket::DataContentDescription* data = 1801 GetFirstDataContentDescription(session->remote_description()); 1802 ASSERT_TRUE(data != NULL); 1803 ASSERT_EQ(kDataSsrc, data->first_ssrc()); 1804 } 1805 1806 void TestGoodIncomingInitiate(const std::string& initiate_string, 1807 const cricket::CallOptions& options, 1808 buzz::XmlElement** element) { 1809 *element = NULL; 1810 1811 talk_base::scoped_ptr<buzz::XmlElement> el( 1812 buzz::XmlElement::ForStr(initiate_string)); 1813 client_->session_manager()->OnIncomingMessage(el.get()); 1814 ASSERT_TRUE(call_ != NULL); 1815 ASSERT_TRUE(call_->sessions()[0] != NULL); 1816 ASSERT_EQ(cricket::Session::STATE_RECEIVEDINITIATE, 1817 call_->sessions()[0]->state()); 1818 ASSERT_EQ(1U, stanzas_.size()); 1819 ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name()); 1820 ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE)); 1821 ASSERT_EQ(std::string(buzz::STR_RESULT), stanzas_[0]->Attr(buzz::QN_TYPE)); 1822 ClearStanzas(); 1823 CheckVideoBandwidth(expected_video_bandwidth_, 1824 call_->sessions()[0]->remote_description()); 1825 CheckVideoRtcpMux(expected_video_rtcp_mux_, 1826 call_->sessions()[0]->remote_description()); 1827 CheckRtcpFb(call_->sessions()[0]->remote_description()); 1828 if (expect_incoming_crypto_) { 1829 CheckCryptoFromGoodIncomingInitiate(call_->sessions()[0]); 1830 } 1831 1832 // TODO(pthatcher): Add tests for sending <bandwidth> in accept. 1833 call_->AcceptSession(call_->sessions()[0], options); 1834 ASSERT_EQ(cricket::Session::STATE_SENTACCEPT, 1835 call_->sessions()[0]->state()); 1836 ASSERT_EQ(1U, stanzas_.size()); 1837 ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name()); 1838 ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE)); 1839 ASSERT_EQ(std::string(buzz::STR_SET), stanzas_[0]->Attr(buzz::QN_TYPE)); 1840 1841 buzz::XmlElement* e = ActionFromStanza(stanzas_[0]); 1842 ASSERT_TRUE(e != NULL); 1843 ASSERT_TRUE(ContentFromAction(e) != NULL); 1844 *element = CopyElement(ContentFromAction(e)); 1845 ASSERT_TRUE(*element != NULL); 1846 ClearStanzas(); 1847 if (expect_outgoing_crypto_) { 1848 CheckCryptoForGoodOutgoingAccept(call_->sessions()[0]); 1849 } 1850 1851 if (options.data_channel_type == cricket::DCT_RTP) { 1852 CheckDataRtcpMux(true, call_->sessions()[0]->local_description()); 1853 CheckDataRtcpMux(true, call_->sessions()[0]->remote_description()); 1854 // TODO(pthatcher): Check rtcpmux and crypto? 1855 } 1856 1857 call_->Terminate(); 1858 ASSERT_EQ(cricket::Session::STATE_SENTTERMINATE, 1859 call_->sessions()[0]->state()); 1860 ASSERT_EQ(1U, stanzas_.size()); 1861 ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name()); 1862 ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE)); 1863 ASSERT_EQ(std::string(buzz::STR_SET), stanzas_[0]->Attr(buzz::QN_TYPE)); 1864 e = ActionFromStanza(stanzas_[0]); 1865 ASSERT_TRUE(e != NULL); 1866 ASSERT_TRUE(parser_->ActionIsTerminate(e)); 1867 ClearStanzas(); 1868 } 1869 1870 void TestRejectOffer(const std::string &initiate_string, 1871 const cricket::CallOptions& options, 1872 buzz::XmlElement** element) { 1873 *element = NULL; 1874 1875 talk_base::scoped_ptr<buzz::XmlElement> el( 1876 buzz::XmlElement::ForStr(initiate_string)); 1877 client_->session_manager()->OnIncomingMessage(el.get()); 1878 ASSERT_TRUE(call_ != NULL); 1879 ASSERT_TRUE(call_->sessions()[0] != NULL); 1880 ASSERT_EQ(cricket::Session::STATE_RECEIVEDINITIATE, 1881 call_->sessions()[0]->state()); 1882 ASSERT_EQ(1U, stanzas_.size()); 1883 ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name()); 1884 ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE)); 1885 ASSERT_EQ(std::string(buzz::STR_RESULT), stanzas_[0]->Attr(buzz::QN_TYPE)); 1886 ClearStanzas(); 1887 1888 call_->AcceptSession(call_->sessions()[0], options); 1889 ASSERT_EQ(cricket::Session::STATE_SENTACCEPT, 1890 call_->sessions()[0]->state()); 1891 ASSERT_EQ(1U, stanzas_.size()); 1892 ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name()); 1893 ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE)); 1894 ASSERT_EQ(std::string(buzz::STR_SET), stanzas_[0]->Attr(buzz::QN_TYPE)); 1895 1896 buzz::XmlElement* e = ActionFromStanza(stanzas_[0]); 1897 ASSERT_TRUE(e != NULL); 1898 ASSERT_TRUE(ContentFromAction(e) != NULL); 1899 *element = CopyElement(ContentFromAction(e)); 1900 ASSERT_TRUE(*element != NULL); 1901 ClearStanzas(); 1902 1903 buzz::XmlElement* content = *element; 1904 // The NextContent method actually returns the second content. So we 1905 // can't handle the case when audio, video and data are all enabled. But 1906 // since we are testing rejection, it won't be the case. 1907 if (options.has_audio) { 1908 ASSERT_TRUE(content != NULL); 1909 ASSERT_EQ("test audio", content->Attr(buzz::QName("", "name"))); 1910 content = parser_->NextContent(content); 1911 } 1912 1913 if (options.has_video) { 1914 ASSERT_TRUE(content != NULL); 1915 ASSERT_EQ("test video", content->Attr(buzz::QName("", "name"))); 1916 content = parser_->NextContent(content); 1917 } 1918 1919 if (options.has_data()) { 1920 ASSERT_TRUE(content != NULL); 1921 ASSERT_EQ("test data", content->Attr(buzz::QName("", "name"))); 1922 content = parser_->NextContent(content); 1923 } 1924 1925 call_->Terminate(); 1926 ASSERT_EQ(cricket::Session::STATE_SENTTERMINATE, 1927 call_->sessions()[0]->state()); 1928 ASSERT_EQ(1U, stanzas_.size()); 1929 ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name()); 1930 ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE)); 1931 ASSERT_EQ(std::string(buzz::STR_SET), stanzas_[0]->Attr(buzz::QN_TYPE)); 1932 e = ActionFromStanza(stanzas_[0]); 1933 ASSERT_TRUE(e != NULL); 1934 ASSERT_TRUE(parser_->ActionIsTerminate(e)); 1935 ClearStanzas(); 1936 } 1937 1938 void TestBadIncomingInitiate(const std::string& initiate_string) { 1939 talk_base::scoped_ptr<buzz::XmlElement> el( 1940 buzz::XmlElement::ForStr(initiate_string)); 1941 client_->session_manager()->OnIncomingMessage(el.get()); 1942 ASSERT_TRUE(call_ != NULL); 1943 ASSERT_TRUE(call_->sessions()[0] != NULL); 1944 ASSERT_EQ(cricket::Session::STATE_SENTREJECT, 1945 call_->sessions()[0]->state()); 1946 ASSERT_EQ(2U, stanzas_.size()); 1947 ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name()); 1948 ASSERT_TRUE(stanzas_[1]->HasAttr(buzz::QN_TYPE)); 1949 ASSERT_EQ(std::string(buzz::STR_RESULT), stanzas_[1]->Attr(buzz::QN_TYPE)); 1950 ClearStanzas(); 1951 } 1952 1953 void VerifyAudioCodec(const AudioCodec& codec, int id, 1954 const std::string& name, int clockrate, 1955 int bitrate, int channels) { 1956 ASSERT_EQ(id, codec.id); 1957 ASSERT_EQ(name, codec.name); 1958 ASSERT_EQ(clockrate, codec.clockrate); 1959 ASSERT_EQ(bitrate, codec.bitrate); 1960 ASSERT_EQ(channels, codec.channels); 1961 ASSERT_EQ(expected_audio_fb_params_, codec.feedback_params); 1962 } 1963 1964 void TestGoodOutgoingInitiate(const cricket::CallOptions& options) { 1965 if (initial_protocol_ == cricket::PROTOCOL_JINGLE) { 1966 // rtcp fb is only implemented for jingle. 1967 ExpectRtcpFb(); 1968 } 1969 1970 client_->CreateCall(); 1971 ASSERT_TRUE(call_ != NULL); 1972 call_->InitiateSession(buzz::Jid("me (at) mydomain.com"), 1973 buzz::Jid("me (at) mydomain.com"), options); 1974 ASSERT_TRUE(call_->sessions()[0] != NULL); 1975 ASSERT_EQ(cricket::Session::STATE_SENTINITIATE, 1976 call_->sessions()[0]->state()); 1977 ASSERT_EQ(1U, stanzas_.size()); 1978 ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name()); 1979 ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE)); 1980 ASSERT_EQ(std::string(buzz::STR_SET), stanzas_[0]->Attr(buzz::QN_TYPE)); 1981 buzz::XmlElement* action = ActionFromStanza(stanzas_[0]); 1982 ASSERT_TRUE(action != NULL); 1983 buzz::XmlElement* content = ContentFromAction(action); 1984 ASSERT_TRUE(content != NULL); 1985 1986 buzz::XmlElement* e = PayloadTypeFromContent(content); 1987 ASSERT_TRUE(e != NULL); 1988 cricket::AudioCodec codec = AudioCodecFromPayloadType(e); 1989 VerifyAudioCodec(codec, 103, "ISAC", 16000, 0, 1); 1990 1991 e = NextFromPayloadType(e); 1992 ASSERT_TRUE(e != NULL); 1993 codec = AudioCodecFromPayloadType(e); 1994 VerifyAudioCodec(codec, 104, "ISAC", 32000, 0, 1); 1995 1996 e = NextFromPayloadType(e); 1997 ASSERT_TRUE(e != NULL); 1998 codec = AudioCodecFromPayloadType(e); 1999 VerifyAudioCodec(codec, 119, "ISACLC", 16000, 40000, 1); 2000 2001 e = NextFromPayloadType(e); 2002 ASSERT_TRUE(e != NULL); 2003 codec = AudioCodecFromPayloadType(e); 2004 VerifyAudioCodec(codec, 99, "speex", 16000, 22000, 1); 2005 2006 e = NextFromPayloadType(e); 2007 ASSERT_TRUE(e != NULL); 2008 codec = AudioCodecFromPayloadType(e); 2009 VerifyAudioCodec(codec, 97, "IPCMWB", 16000, 80000, 1); 2010 2011 e = NextFromPayloadType(e); 2012 ASSERT_TRUE(e != NULL); 2013 codec = AudioCodecFromPayloadType(e); 2014 VerifyAudioCodec(codec, 9, "G722", 16000, 64000, 1); 2015 2016 e = NextFromPayloadType(e); 2017 ASSERT_TRUE(e != NULL); 2018 codec = AudioCodecFromPayloadType(e); 2019 VerifyAudioCodec(codec, 102, "iLBC", 8000, 13300, 1); 2020 2021 e = NextFromPayloadType(e); 2022 ASSERT_TRUE(e != NULL); 2023 codec = AudioCodecFromPayloadType(e); 2024 VerifyAudioCodec(codec, 98, "speex", 8000, 11000, 1); 2025 2026 e = NextFromPayloadType(e); 2027 ASSERT_TRUE(e != NULL); 2028 codec = AudioCodecFromPayloadType(e); 2029 VerifyAudioCodec(codec, 3, "GSM", 8000, 13000, 1); 2030 2031 e = NextFromPayloadType(e); 2032 ASSERT_TRUE(e != NULL); 2033 codec = AudioCodecFromPayloadType(e); 2034 VerifyAudioCodec(codec, 100, "EG711U", 8000, 64000, 1); 2035 2036 e = NextFromPayloadType(e); 2037 ASSERT_TRUE(e != NULL); 2038 codec = AudioCodecFromPayloadType(e); 2039 VerifyAudioCodec(codec, 101, "EG711A", 8000, 64000, 1); 2040 2041 e = NextFromPayloadType(e); 2042 ASSERT_TRUE(e != NULL); 2043 codec = AudioCodecFromPayloadType(e); 2044 VerifyAudioCodec(codec, 0, "PCMU", 8000, 64000, 1); 2045 2046 e = NextFromPayloadType(e); 2047 ASSERT_TRUE(e != NULL); 2048 codec = AudioCodecFromPayloadType(e); 2049 VerifyAudioCodec(codec, 8, "PCMA", 8000, 64000, 1); 2050 2051 e = NextFromPayloadType(e); 2052 ASSERT_TRUE(e != NULL); 2053 codec = AudioCodecFromPayloadType(e); 2054 VerifyAudioCodec(codec, 126, "CN", 32000, 0, 1); 2055 2056 e = NextFromPayloadType(e); 2057 ASSERT_TRUE(e != NULL); 2058 codec = AudioCodecFromPayloadType(e); 2059 VerifyAudioCodec(codec, 105, "CN", 16000, 0, 1); 2060 2061 e = NextFromPayloadType(e); 2062 ASSERT_TRUE(e != NULL); 2063 codec = AudioCodecFromPayloadType(e); 2064 VerifyAudioCodec(codec, 13, "CN", 8000, 0, 1); 2065 2066 e = NextFromPayloadType(e); 2067 ASSERT_TRUE(e != NULL); 2068 codec = AudioCodecFromPayloadType(e); 2069 VerifyAudioCodec(codec, 117, "red", 8000, 0, 1); 2070 2071 e = NextFromPayloadType(e); 2072 ASSERT_TRUE(e != NULL); 2073 codec = AudioCodecFromPayloadType(e); 2074 VerifyAudioCodec(codec, 106, "telephone-event", 8000, 0, 1); 2075 2076 e = NextFromPayloadType(e); 2077 ASSERT_TRUE(e == NULL); 2078 2079 if (expect_outgoing_crypto_) { 2080 buzz::XmlElement* encryption = EncryptionFromContent(content); 2081 ASSERT_TRUE(encryption != NULL); 2082 2083 if (client_->secure() == cricket::SEC_REQUIRED) { 2084 ASSERT_TRUE(cricket::GetXmlAttr( 2085 encryption, cricket::QN_ENCRYPTION_REQUIRED, false)); 2086 } 2087 2088 if (content->Name().Namespace() == cricket::NS_GINGLE_AUDIO) { 2089 e = encryption->FirstNamed(cricket::QN_GINGLE_AUDIO_CRYPTO_USAGE); 2090 ASSERT_TRUE(e != NULL); 2091 ASSERT_TRUE( 2092 e->NextNamed(cricket::QN_GINGLE_AUDIO_CRYPTO_USAGE) == NULL); 2093 ASSERT_TRUE( 2094 e->FirstNamed(cricket::QN_GINGLE_VIDEO_CRYPTO_USAGE) == NULL); 2095 } 2096 2097 e = encryption->FirstNamed(cricket::QN_CRYPTO); 2098 ASSERT_TRUE(e != NULL); 2099 ASSERT_EQ("0", e->Attr(cricket::QN_CRYPTO_TAG)); 2100 ASSERT_EQ("AES_CM_128_HMAC_SHA1_32", e->Attr(cricket::QN_CRYPTO_SUITE)); 2101 std::string key_0 = e->Attr(cricket::QN_CRYPTO_KEY_PARAMS); 2102 ASSERT_EQ(47U, key_0.length()); 2103 ASSERT_EQ("inline:", key_0.substr(0, 7)); 2104 2105 e = e->NextNamed(cricket::QN_CRYPTO); 2106 ASSERT_TRUE(e != NULL); 2107 ASSERT_EQ("1", e->Attr(cricket::QN_CRYPTO_TAG)); 2108 ASSERT_EQ("AES_CM_128_HMAC_SHA1_80", e->Attr(cricket::QN_CRYPTO_SUITE)); 2109 std::string key_1 = e->Attr(cricket::QN_CRYPTO_KEY_PARAMS); 2110 ASSERT_EQ(47U, key_1.length()); 2111 ASSERT_EQ("inline:", key_1.substr(0, 7)); 2112 ASSERT_NE(key_0, key_1); 2113 2114 encryption = NextFromEncryption(encryption); 2115 ASSERT_TRUE(encryption == NULL); 2116 } 2117 2118 if (options.has_video) { 2119 CheckVideoBandwidth(options.video_bandwidth, 2120 call_->sessions()[0]->local_description()); 2121 CheckVideoRtcpMux(expected_video_rtcp_mux_, 2122 call_->sessions()[0]->remote_description()); 2123 content = parser_->NextContent(content); 2124 const buzz::XmlElement* bandwidth = 2125 parser_->BandwidthFromContent(content); 2126 if (options.video_bandwidth == cricket::kAutoBandwidth) { 2127 ASSERT_TRUE(bandwidth == NULL); 2128 } else { 2129 ASSERT_TRUE(bandwidth != NULL); 2130 ASSERT_EQ("AS", bandwidth->Attr(buzz::QName("", "type"))); 2131 ASSERT_EQ(talk_base::ToString(options.video_bandwidth / 1000), 2132 bandwidth->BodyText()); 2133 } 2134 2135 buzz::XmlElement* e = PayloadTypeFromContent(content); 2136 ASSERT_TRUE(e != NULL); 2137 VideoCodec codec = VideoCodecFromPayloadType(e); 2138 VideoCodec expected_codec = kVideoCodecs[0]; 2139 expected_codec.preference = codec.preference; 2140 expected_codec.feedback_params = expected_video_fb_params_; 2141 EXPECT_EQ(expected_codec, codec); 2142 } 2143 2144 if (options.data_channel_type == cricket::DCT_RTP) { 2145 content = parser_->NextContent(content); 2146 CheckRtpDataContent(content); 2147 } 2148 2149 if (options.data_channel_type == cricket::DCT_SCTP) { 2150 content = parser_->NextContent(content); 2151 CheckSctpDataContent(content); 2152 } 2153 2154 ClearStanzas(); 2155 } 2156 2157 void TestHasAllSupportedAudioCodecs(buzz::XmlElement* e) { 2158 ASSERT_TRUE(e != NULL); 2159 2160 e = PayloadTypeFromContent(e); 2161 ASSERT_TRUE(e != NULL); 2162 cricket::AudioCodec codec = AudioCodecFromPayloadType(e); 2163 ASSERT_EQ(103, codec.id); 2164 ASSERT_EQ("ISAC", codec.name); 2165 ASSERT_EQ(16000, codec.clockrate); 2166 ASSERT_EQ(1, codec.channels); 2167 2168 e = NextFromPayloadType(e); 2169 ASSERT_TRUE(e != NULL); 2170 codec = AudioCodecFromPayloadType(e); 2171 ASSERT_EQ(104, codec.id); 2172 ASSERT_EQ("ISAC", codec.name); 2173 ASSERT_EQ(32000, codec.clockrate); 2174 ASSERT_EQ(1, codec.channels); 2175 2176 e = NextFromPayloadType(e); 2177 ASSERT_TRUE(e != NULL); 2178 codec = AudioCodecFromPayloadType(e); 2179 ASSERT_EQ(119, codec.id); 2180 ASSERT_EQ("ISACLC", codec.name); 2181 ASSERT_EQ(16000, codec.clockrate); 2182 ASSERT_EQ(40000, codec.bitrate); 2183 ASSERT_EQ(1, codec.channels); 2184 2185 e = NextFromPayloadType(e); 2186 ASSERT_TRUE(e != NULL); 2187 codec = AudioCodecFromPayloadType(e); 2188 ASSERT_EQ(99, codec.id); 2189 ASSERT_EQ("speex", codec.name); 2190 ASSERT_EQ(16000, codec.clockrate); 2191 ASSERT_EQ(22000, codec.bitrate); 2192 ASSERT_EQ(1, codec.channels); 2193 2194 e = NextFromPayloadType(e); 2195 ASSERT_TRUE(e != NULL); 2196 codec = AudioCodecFromPayloadType(e); 2197 ASSERT_EQ(97, codec.id); 2198 ASSERT_EQ("IPCMWB", codec.name); 2199 ASSERT_EQ(16000, codec.clockrate); 2200 ASSERT_EQ(80000, codec.bitrate); 2201 ASSERT_EQ(1, codec.channels); 2202 2203 e = NextFromPayloadType(e); 2204 ASSERT_TRUE(e != NULL); 2205 codec = AudioCodecFromPayloadType(e); 2206 ASSERT_EQ(9, codec.id); 2207 ASSERT_EQ("G722", codec.name); 2208 ASSERT_EQ(16000, codec.clockrate); 2209 ASSERT_EQ(64000, codec.bitrate); 2210 ASSERT_EQ(1, codec.channels); 2211 2212 e = NextFromPayloadType(e); 2213 ASSERT_TRUE(e != NULL); 2214 codec = AudioCodecFromPayloadType(e); 2215 ASSERT_EQ(102, codec.id); 2216 ASSERT_EQ("iLBC", codec.name); 2217 ASSERT_EQ(8000, codec.clockrate); 2218 ASSERT_EQ(13300, codec.bitrate); 2219 ASSERT_EQ(1, codec.channels); 2220 2221 e = NextFromPayloadType(e); 2222 ASSERT_TRUE(e != NULL); 2223 codec = AudioCodecFromPayloadType(e); 2224 ASSERT_EQ(98, codec.id); 2225 ASSERT_EQ("speex", codec.name); 2226 ASSERT_EQ(8000, codec.clockrate); 2227 ASSERT_EQ(11000, codec.bitrate); 2228 ASSERT_EQ(1, codec.channels); 2229 2230 e = NextFromPayloadType(e); 2231 ASSERT_TRUE(e != NULL); 2232 codec = AudioCodecFromPayloadType(e); 2233 ASSERT_EQ(3, codec.id); 2234 ASSERT_EQ("GSM", codec.name); 2235 ASSERT_EQ(8000, codec.clockrate); 2236 ASSERT_EQ(13000, codec.bitrate); 2237 ASSERT_EQ(1, codec.channels); 2238 2239 e = NextFromPayloadType(e); 2240 ASSERT_TRUE(e != NULL); 2241 codec = AudioCodecFromPayloadType(e); 2242 ASSERT_EQ(100, codec.id); 2243 ASSERT_EQ("EG711U", codec.name); 2244 ASSERT_EQ(8000, codec.clockrate); 2245 ASSERT_EQ(64000, codec.bitrate); 2246 ASSERT_EQ(1, codec.channels); 2247 2248 e = NextFromPayloadType(e); 2249 ASSERT_TRUE(e != NULL); 2250 codec = AudioCodecFromPayloadType(e); 2251 ASSERT_EQ(101, codec.id); 2252 ASSERT_EQ("EG711A", codec.name); 2253 ASSERT_EQ(8000, codec.clockrate); 2254 ASSERT_EQ(64000, codec.bitrate); 2255 ASSERT_EQ(1, codec.channels); 2256 2257 e = NextFromPayloadType(e); 2258 ASSERT_TRUE(e != NULL); 2259 codec = AudioCodecFromPayloadType(e); 2260 ASSERT_EQ(0, codec.id); 2261 ASSERT_EQ("PCMU", codec.name); 2262 ASSERT_EQ(8000, codec.clockrate); 2263 ASSERT_EQ(64000, codec.bitrate); 2264 ASSERT_EQ(1, codec.channels); 2265 2266 e = NextFromPayloadType(e); 2267 ASSERT_TRUE(e != NULL); 2268 codec = AudioCodecFromPayloadType(e); 2269 ASSERT_EQ(8, codec.id); 2270 ASSERT_EQ("PCMA", codec.name); 2271 ASSERT_EQ(8000, codec.clockrate); 2272 ASSERT_EQ(64000, codec.bitrate); 2273 ASSERT_EQ(1, codec.channels); 2274 2275 e = NextFromPayloadType(e); 2276 ASSERT_TRUE(e != NULL); 2277 codec = AudioCodecFromPayloadType(e); 2278 ASSERT_EQ(126, codec.id); 2279 ASSERT_EQ("CN", codec.name); 2280 ASSERT_EQ(32000, codec.clockrate); 2281 ASSERT_EQ(1, codec.channels); 2282 2283 e = NextFromPayloadType(e); 2284 ASSERT_TRUE(e != NULL); 2285 codec = AudioCodecFromPayloadType(e); 2286 ASSERT_EQ(105, codec.id); 2287 ASSERT_EQ("CN", codec.name); 2288 ASSERT_EQ(16000, codec.clockrate); 2289 ASSERT_EQ(1, codec.channels); 2290 2291 e = NextFromPayloadType(e); 2292 ASSERT_TRUE(e != NULL); 2293 codec = AudioCodecFromPayloadType(e); 2294 ASSERT_EQ(13, codec.id); 2295 ASSERT_EQ("CN", codec.name); 2296 ASSERT_EQ(8000, codec.clockrate); 2297 ASSERT_EQ(1, codec.channels); 2298 2299 e = NextFromPayloadType(e); 2300 ASSERT_TRUE(e != NULL); 2301 codec = AudioCodecFromPayloadType(e); 2302 ASSERT_EQ(117, codec.id); 2303 ASSERT_EQ("red", codec.name); 2304 ASSERT_EQ(8000, codec.clockrate); 2305 ASSERT_EQ(1, codec.channels); 2306 2307 e = NextFromPayloadType(e); 2308 ASSERT_TRUE(e != NULL); 2309 codec = AudioCodecFromPayloadType(e); 2310 ASSERT_EQ(106, codec.id); 2311 ASSERT_EQ("telephone-event", codec.name); 2312 ASSERT_EQ(8000, codec.clockrate); 2313 ASSERT_EQ(1, codec.channels); 2314 2315 e = NextFromPayloadType(e); 2316 ASSERT_TRUE(e == NULL); 2317 } 2318 2319 void TestCodecsOfVideoInitiate(buzz::XmlElement* content) { 2320 ASSERT_TRUE(content != NULL); 2321 buzz::XmlElement* payload_type = PayloadTypeFromContent(content); 2322 ASSERT_TRUE(payload_type != NULL); 2323 cricket::AudioCodec codec = AudioCodecFromPayloadType(payload_type); 2324 ASSERT_EQ(103, codec.id); 2325 ASSERT_EQ("ISAC", codec.name); 2326 ASSERT_EQ(16000, codec.clockrate); 2327 ASSERT_EQ(1, codec.channels); 2328 2329 content = parser_->NextContent(content); 2330 ASSERT_TRUE(content != NULL); 2331 payload_type = PayloadTypeFromContent(content); 2332 ASSERT_TRUE(payload_type != NULL); 2333 cricket::VideoCodec vcodec = 2334 parser_->VideoCodecFromPayloadType(payload_type); 2335 ASSERT_EQ(99, vcodec.id); 2336 ASSERT_EQ("H264-SVC", vcodec.name); 2337 ASSERT_EQ(320, vcodec.width); 2338 ASSERT_EQ(200, vcodec.height); 2339 ASSERT_EQ(30, vcodec.framerate); 2340 } 2341 2342 void TestHasAudioCodecsFromInitiateSomeUnsupported(buzz::XmlElement* e) { 2343 ASSERT_TRUE(e != NULL); 2344 e = PayloadTypeFromContent(e); 2345 ASSERT_TRUE(e != NULL); 2346 2347 cricket::AudioCodec codec = AudioCodecFromPayloadType(e); 2348 ASSERT_EQ(103, codec.id); 2349 ASSERT_EQ("ISAC", codec.name); 2350 ASSERT_EQ(16000, codec.clockrate); 2351 ASSERT_EQ(1, codec.channels); 2352 2353 e = NextFromPayloadType(e); 2354 ASSERT_TRUE(e != NULL); 2355 codec = AudioCodecFromPayloadType(e); 2356 ASSERT_EQ(100, codec.id); 2357 ASSERT_EQ("EG711U", codec.name); 2358 2359 e = NextFromPayloadType(e); 2360 ASSERT_TRUE(e != NULL); 2361 codec = AudioCodecFromPayloadType(e); 2362 ASSERT_EQ(101, codec.id); 2363 ASSERT_EQ("EG711A", codec.name); 2364 2365 e = NextFromPayloadType(e); 2366 ASSERT_TRUE(e != NULL); 2367 codec = AudioCodecFromPayloadType(e); 2368 ASSERT_EQ(0, codec.id); 2369 ASSERT_EQ("PCMU", codec.name); 2370 2371 e = NextFromPayloadType(e); 2372 ASSERT_TRUE(e != NULL); 2373 codec = AudioCodecFromPayloadType(e); 2374 ASSERT_EQ(13, codec.id); 2375 ASSERT_EQ("CN", codec.name); 2376 2377 e = NextFromPayloadType(e); 2378 ASSERT_TRUE(e == NULL); 2379 } 2380 2381 void TestHasAudioCodecsFromInitiateDynamicAudioCodecs( 2382 buzz::XmlElement* e) { 2383 ASSERT_TRUE(e != NULL); 2384 e = PayloadTypeFromContent(e); 2385 ASSERT_TRUE(e != NULL); 2386 2387 cricket::AudioCodec codec = AudioCodecFromPayloadType(e); 2388 ASSERT_EQ(123, codec.id); 2389 ASSERT_EQ(16000, codec.clockrate); 2390 ASSERT_EQ(1, codec.channels); 2391 2392 e = NextFromPayloadType(e); 2393 ASSERT_TRUE(e == NULL); 2394 } 2395 2396 void TestHasDefaultAudioCodecs(buzz::XmlElement* e) { 2397 ASSERT_TRUE(e != NULL); 2398 e = PayloadTypeFromContent(e); 2399 ASSERT_TRUE(e != NULL); 2400 2401 cricket::AudioCodec codec = AudioCodecFromPayloadType(e); 2402 ASSERT_EQ(103, codec.id); 2403 ASSERT_EQ("ISAC", codec.name); 2404 2405 e = NextFromPayloadType(e); 2406 ASSERT_TRUE(e != NULL); 2407 codec = AudioCodecFromPayloadType(e); 2408 ASSERT_EQ(0, codec.id); 2409 ASSERT_EQ("PCMU", codec.name); 2410 2411 e = NextFromPayloadType(e); 2412 ASSERT_TRUE(e == NULL); 2413 } 2414 2415 void TestHasAudioCodecsFromInitiateStaticAudioCodecs( 2416 buzz::XmlElement* e) { 2417 ASSERT_TRUE(e != NULL); 2418 e = PayloadTypeFromContent(e); 2419 ASSERT_TRUE(e != NULL); 2420 2421 cricket::AudioCodec codec = AudioCodecFromPayloadType(e); 2422 ASSERT_EQ(3, codec.id); 2423 2424 e = NextFromPayloadType(e); 2425 ASSERT_TRUE(e != NULL); 2426 codec = AudioCodecFromPayloadType(e); 2427 ASSERT_EQ(0, codec.id); 2428 2429 e = NextFromPayloadType(e); 2430 ASSERT_TRUE(e != NULL); 2431 codec = AudioCodecFromPayloadType(e); 2432 ASSERT_EQ(8, codec.id); 2433 2434 e = NextFromPayloadType(e); 2435 ASSERT_TRUE(e == NULL); 2436 } 2437 2438 void TestGingleInitiateWithUnsupportedCrypto( 2439 const std::string &initiate_string, 2440 buzz::XmlElement** element) { 2441 *element = NULL; 2442 2443 talk_base::scoped_ptr<buzz::XmlElement> el( 2444 buzz::XmlElement::ForStr(initiate_string)); 2445 client_->session_manager()->OnIncomingMessage(el.get()); 2446 2447 ASSERT_EQ(cricket::Session::STATE_RECEIVEDINITIATE, 2448 call_->sessions()[0]->state()); 2449 ClearStanzas(); 2450 CheckBadCryptoFromIncomingInitiate(call_->sessions()[0]); 2451 2452 call_->AcceptSession(call_->sessions()[0], cricket::CallOptions()); 2453 ClearStanzas(); 2454 CheckNoCryptoForOutgoingAccept(call_->sessions()[0]); 2455 2456 call_->Terminate(); 2457 ASSERT_EQ(cricket::Session::STATE_SENTTERMINATE, 2458 call_->sessions()[0]->state()); 2459 ClearStanzas(); 2460 } 2461 2462 void TestIncomingAcceptWithSsrcs( 2463 const std::string& accept_string, 2464 cricket::CallOptions& options) { 2465 client_->CreateCall(); 2466 ASSERT_TRUE(call_ != NULL); 2467 2468 call_->InitiateSession(buzz::Jid("me (at) mydomain.com"), 2469 buzz::Jid("me (at) mydomain.com"), options); 2470 ASSERT_TRUE(call_->sessions()[0] != NULL); 2471 ASSERT_EQ(cricket::Session::STATE_SENTINITIATE, 2472 call_->sessions()[0]->state()); 2473 ASSERT_EQ(1U, stanzas_.size()); 2474 ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name()); 2475 ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE)); 2476 ASSERT_EQ(std::string(buzz::STR_SET), stanzas_[0]->Attr(buzz::QN_TYPE)); 2477 buzz::XmlElement* action = ActionFromStanza(stanzas_[0]); 2478 ASSERT_TRUE(action != NULL); 2479 buzz::XmlElement* content = ContentFromAction(action); 2480 ASSERT_TRUE(content != NULL); 2481 if (initial_protocol_ == cricket::PROTOCOL_JINGLE) { 2482 buzz::XmlElement* content_desc = 2483 content->FirstNamed(cricket::QN_JINGLE_RTP_CONTENT); 2484 ASSERT_TRUE(content_desc != NULL); 2485 ASSERT_EQ("", content_desc->Attr(cricket::QN_SSRC)); 2486 } 2487 ClearStanzas(); 2488 2489 // We need to insert the session ID into the session accept message. 2490 talk_base::scoped_ptr<buzz::XmlElement> el( 2491 buzz::XmlElement::ForStr(accept_string)); 2492 const std::string sid = call_->sessions()[0]->id(); 2493 if (initial_protocol_ == cricket::PROTOCOL_JINGLE) { 2494 buzz::XmlElement* jingle = el->FirstNamed(cricket::QN_JINGLE); 2495 jingle->SetAttr(cricket::QN_SID, sid); 2496 } else { 2497 buzz::XmlElement* session = el->FirstNamed(cricket::QN_GINGLE_SESSION); 2498 session->SetAttr(cricket::QN_ID, sid); 2499 } 2500 2501 client_->session_manager()->OnIncomingMessage(el.get()); 2502 2503 ASSERT_EQ(cricket::Session::STATE_RECEIVEDACCEPT, 2504 call_->sessions()[0]->state()); 2505 ASSERT_EQ(1U, stanzas_.size()); 2506 ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name()); 2507 ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE)); 2508 ASSERT_EQ(std::string(buzz::STR_RESULT), stanzas_[0]->Attr(buzz::QN_TYPE)); 2509 ClearStanzas(); 2510 2511 CheckAudioSsrcForIncomingAccept(call_->sessions()[0]); 2512 CheckVideoSsrcForIncomingAccept(call_->sessions()[0]); 2513 if (options.data_channel_type == cricket::DCT_RTP) { 2514 CheckDataSsrcForIncomingAccept(call_->sessions()[0]); 2515 } 2516 // TODO(pthatcher): Check kDataSid if DCT_SCTP. 2517 } 2518 2519 size_t ClearStanzas() { 2520 size_t size = stanzas_.size(); 2521 for (size_t i = 0; i < size; i++) { 2522 delete stanzas_[i]; 2523 } 2524 stanzas_.clear(); 2525 return size; 2526 } 2527 2528 buzz::XmlElement* SetJingleSid(buzz::XmlElement* stanza) { 2529 buzz::XmlElement* jingle = 2530 stanza->FirstNamed(cricket::QN_JINGLE); 2531 jingle->SetAttr(cricket::QN_SID, call_->sessions()[0]->id()); 2532 return stanza; 2533 } 2534 2535 void TestSendVideoStreamUpdate() { 2536 cricket::CallOptions options = VideoCallOptions(); 2537 options.is_muc = true; 2538 2539 client_->CreateCall(); 2540 call_->InitiateSession(buzz::Jid("me (at) mydomain.com"), 2541 buzz::Jid("me (at) mydomain.com"), options); 2542 ClearStanzas(); 2543 2544 cricket::StreamParams stream; 2545 stream.id = "test-stream"; 2546 stream.ssrcs.push_back(1001); 2547 talk_base::scoped_ptr<buzz::XmlElement> expected_stream_add( 2548 buzz::XmlElement::ForStr( 2549 JingleOutboundStreamAdd( 2550 call_->sessions()[0]->id(), 2551 "video", stream.id, "1001"))); 2552 talk_base::scoped_ptr<buzz::XmlElement> expected_stream_remove( 2553 buzz::XmlElement::ForStr( 2554 JingleOutboundStreamRemove( 2555 call_->sessions()[0]->id(), 2556 "video", stream.id))); 2557 2558 call_->SendVideoStreamUpdate(call_->sessions()[0], 2559 call_->CreateVideoStreamUpdate(stream)); 2560 ASSERT_EQ(1U, stanzas_.size()); 2561 EXPECT_EQ(expected_stream_add->Str(), stanzas_[0]->Str()); 2562 ClearStanzas(); 2563 2564 stream.ssrcs.clear(); 2565 call_->SendVideoStreamUpdate(call_->sessions()[0], 2566 call_->CreateVideoStreamUpdate(stream)); 2567 ASSERT_EQ(1U, stanzas_.size()); 2568 EXPECT_EQ(expected_stream_remove->Str(), stanzas_[0]->Str()); 2569 ClearStanzas(); 2570 } 2571 2572 void TestStreamsUpdateAndViewRequests() { 2573 cricket::CallOptions options = VideoCallOptions(); 2574 options.is_muc = true; 2575 2576 client_->CreateCall(); 2577 call_->InitiateSession(buzz::Jid("me (at) mydomain.com"), 2578 buzz::Jid("me (at) mydomain.com"), options); 2579 ASSERT_EQ(1U, ClearStanzas()); 2580 ASSERT_EQ(0U, last_streams_added_.audio().size()); 2581 ASSERT_EQ(0U, last_streams_added_.video().size()); 2582 ASSERT_EQ(0U, last_streams_removed_.audio().size()); 2583 ASSERT_EQ(0U, last_streams_removed_.video().size()); 2584 2585 talk_base::scoped_ptr<buzz::XmlElement> accept_stanza( 2586 buzz::XmlElement::ForStr(kJingleAcceptWithSsrcs)); 2587 SetJingleSid(accept_stanza.get()); 2588 client_->session_manager()->OnIncomingMessage(accept_stanza.get()); 2589 ASSERT_EQ(cricket::Session::STATE_RECEIVEDACCEPT, 2590 call_->sessions()[0]->state()); 2591 ASSERT_EQ(1U, stanzas_.size()); 2592 ASSERT_EQ(std::string(buzz::STR_RESULT), stanzas_[0]->Attr(buzz::QN_TYPE)); 2593 ClearStanzas(); 2594 // Need to clear the added streams, because they are populated when 2595 // receiving an accept message now. 2596 last_streams_added_.mutable_video()->clear(); 2597 last_streams_added_.mutable_audio()->clear(); 2598 2599 call_->sessions()[0]->SetState(cricket::Session::STATE_INPROGRESS); 2600 2601 talk_base::scoped_ptr<buzz::XmlElement> streams_stanza( 2602 buzz::XmlElement::ForStr( 2603 JingleStreamAdd("video", "Bob", "video1", "ABC"))); 2604 SetJingleSid(streams_stanza.get()); 2605 client_->session_manager()->OnIncomingMessage(streams_stanza.get()); 2606 // First one is ignored because of bad syntax. 2607 ASSERT_EQ(1U, stanzas_.size()); 2608 // TODO(pthatcher): Figure out how to make this an ERROR rather than RESULT. 2609 ASSERT_EQ(std::string(buzz::STR_ERROR), stanzas_[0]->Attr(buzz::QN_TYPE)); 2610 ClearStanzas(); 2611 ASSERT_EQ(0U, last_streams_added_.audio().size()); 2612 ASSERT_EQ(0U, last_streams_added_.video().size()); 2613 ASSERT_EQ(0U, last_streams_removed_.audio().size()); 2614 ASSERT_EQ(0U, last_streams_removed_.video().size()); 2615 2616 streams_stanza.reset(buzz::XmlElement::ForStr( 2617 JingleStreamAdd("audio", "Bob", "audio1", "1234"))); 2618 SetJingleSid(streams_stanza.get()); 2619 client_->session_manager()->OnIncomingMessage(streams_stanza.get()); 2620 ASSERT_EQ(1U, last_streams_added_.audio().size()); 2621 ASSERT_EQ("Bob", last_streams_added_.audio()[0].groupid); 2622 ASSERT_EQ(1U, last_streams_added_.audio()[0].ssrcs.size()); 2623 ASSERT_EQ(1234U, last_streams_added_.audio()[0].first_ssrc()); 2624 2625 // Ignores adds without ssrcs. 2626 streams_stanza.reset(buzz::XmlElement::ForStr( 2627 JingleStreamAddWithoutSsrc("audio", "Bob", "audioX"))); 2628 SetJingleSid(streams_stanza.get()); 2629 client_->session_manager()->OnIncomingMessage(streams_stanza.get()); 2630 ASSERT_EQ(1U, last_streams_added_.audio().size()); 2631 ASSERT_EQ(1234U, last_streams_added_.audio()[0].first_ssrc()); 2632 2633 // Ignores stream updates with unknown content names. (Don't terminate). 2634 streams_stanza.reset(buzz::XmlElement::ForStr( 2635 JingleStreamAddWithoutSsrc("foo", "Bob", "foo"))); 2636 SetJingleSid(streams_stanza.get()); 2637 client_->session_manager()->OnIncomingMessage(streams_stanza.get()); 2638 2639 streams_stanza.reset(buzz::XmlElement::ForStr( 2640 JingleStreamAdd("audio", "Joe", "audio1", "2468"))); 2641 SetJingleSid(streams_stanza.get()); 2642 client_->session_manager()->OnIncomingMessage(streams_stanza.get()); 2643 ASSERT_EQ(1U, last_streams_added_.audio().size()); 2644 ASSERT_EQ("Joe", last_streams_added_.audio()[0].groupid); 2645 ASSERT_EQ(1U, last_streams_added_.audio()[0].ssrcs.size()); 2646 ASSERT_EQ(2468U, last_streams_added_.audio()[0].first_ssrc()); 2647 2648 streams_stanza.reset(buzz::XmlElement::ForStr( 2649 JingleStreamAdd("video", "Bob", "video1", "5678"))); 2650 SetJingleSid(streams_stanza.get()); 2651 client_->session_manager()->OnIncomingMessage(streams_stanza.get()); 2652 ASSERT_EQ(1U, last_streams_added_.video().size()); 2653 ASSERT_EQ("Bob", last_streams_added_.video()[0].groupid); 2654 ASSERT_EQ(1U, last_streams_added_.video()[0].ssrcs.size()); 2655 ASSERT_EQ(5678U, last_streams_added_.video()[0].first_ssrc()); 2656 2657 // We're testing that a "duplicate" is effectively ignored. 2658 last_streams_added_.mutable_video()->clear(); 2659 last_streams_removed_.mutable_video()->clear(); 2660 streams_stanza.reset(buzz::XmlElement::ForStr( 2661 JingleStreamAdd("video", "Bob", "video1", "5678"))); 2662 SetJingleSid(streams_stanza.get()); 2663 client_->session_manager()->OnIncomingMessage(streams_stanza.get()); 2664 ASSERT_EQ(0U, last_streams_added_.video().size()); 2665 ASSERT_EQ(0U, last_streams_removed_.video().size()); 2666 2667 streams_stanza.reset(buzz::XmlElement::ForStr( 2668 JingleStreamAdd("video", "Bob", "video2", "5679"))); 2669 SetJingleSid(streams_stanza.get()); 2670 client_->session_manager()->OnIncomingMessage(streams_stanza.get()); 2671 ASSERT_EQ(1U, last_streams_added_.video().size()); 2672 ASSERT_EQ("Bob", last_streams_added_.video()[0].groupid); 2673 ASSERT_EQ(1U, last_streams_added_.video()[0].ssrcs.size()); 2674 ASSERT_EQ(5679U, last_streams_added_.video()[0].first_ssrc()); 2675 2676 cricket::FakeVoiceMediaChannel* voice_channel = fme_->GetVoiceChannel(0); 2677 ASSERT_TRUE(voice_channel != NULL); 2678 ASSERT_TRUE(voice_channel->HasRecvStream(1234U)); 2679 ASSERT_TRUE(voice_channel->HasRecvStream(2468U)); 2680 cricket::FakeVideoMediaChannel* video_channel = fme_->GetVideoChannel(0); 2681 ASSERT_TRUE(video_channel != NULL); 2682 ASSERT_TRUE(video_channel->HasRecvStream(5678U)); 2683 ClearStanzas(); 2684 2685 cricket::ViewRequest viewRequest; 2686 cricket::StaticVideoView staticVideoView( 2687 cricket::StreamSelector(5678U), 640, 480, 30); 2688 viewRequest.static_video_views.push_back(staticVideoView); 2689 talk_base::scoped_ptr<buzz::XmlElement> expected_view_elem( 2690 buzz::XmlElement::ForStr(JingleView("5678", "640", "480", "30"))); 2691 SetJingleSid(expected_view_elem.get()); 2692 2693 ASSERT_TRUE( 2694 call_->SendViewRequest(call_->sessions()[0], viewRequest)); 2695 ASSERT_EQ(1U, stanzas_.size()); 2696 ASSERT_EQ(expected_view_elem->Str(), stanzas_[0]->Str()); 2697 ClearStanzas(); 2698 2699 streams_stanza.reset(buzz::XmlElement::ForStr( 2700 JingleStreamRemove("audio", "Bob", "audio1"))); 2701 SetJingleSid(streams_stanza.get()); 2702 client_->session_manager()->OnIncomingMessage(streams_stanza.get()); 2703 ASSERT_EQ(1U, last_streams_removed_.audio().size()); 2704 ASSERT_EQ(1U, last_streams_removed_.audio()[0].ssrcs.size()); 2705 EXPECT_EQ(1234U, last_streams_removed_.audio()[0].first_ssrc()); 2706 2707 streams_stanza.reset(buzz::XmlElement::ForStr( 2708 JingleStreamRemove("video", "Bob", "video1"))); 2709 SetJingleSid(streams_stanza.get()); 2710 client_->session_manager()->OnIncomingMessage(streams_stanza.get()); 2711 ASSERT_EQ(1U, last_streams_removed_.video().size()); 2712 ASSERT_EQ(1U, last_streams_removed_.video()[0].ssrcs.size()); 2713 EXPECT_EQ(5678U, last_streams_removed_.video()[0].first_ssrc()); 2714 2715 streams_stanza.reset(buzz::XmlElement::ForStr( 2716 JingleStreamRemove("video", "Bob", "video2"))); 2717 SetJingleSid(streams_stanza.get()); 2718 client_->session_manager()->OnIncomingMessage(streams_stanza.get()); 2719 ASSERT_EQ(1U, last_streams_removed_.video().size()); 2720 ASSERT_EQ(1U, last_streams_removed_.video()[0].ssrcs.size()); 2721 EXPECT_EQ(5679U, last_streams_removed_.video()[0].first_ssrc()); 2722 2723 // Duplicate removal: should be ignored. 2724 last_streams_removed_.mutable_audio()->clear(); 2725 streams_stanza.reset(buzz::XmlElement::ForStr( 2726 JingleStreamRemove("audio", "Bob", "audio1"))); 2727 SetJingleSid(streams_stanza.get()); 2728 client_->session_manager()->OnIncomingMessage(streams_stanza.get()); 2729 ASSERT_EQ(0U, last_streams_removed_.audio().size()); 2730 2731 // Duplicate removal: should be ignored. 2732 last_streams_removed_.mutable_video()->clear(); 2733 streams_stanza.reset(buzz::XmlElement::ForStr( 2734 JingleStreamRemove("video", "Bob", "video1"))); 2735 SetJingleSid(streams_stanza.get()); 2736 client_->session_manager()->OnIncomingMessage(streams_stanza.get()); 2737 ASSERT_EQ(0U, last_streams_removed_.video().size()); 2738 2739 voice_channel = fme_->GetVoiceChannel(0); 2740 ASSERT_TRUE(voice_channel != NULL); 2741 ASSERT_FALSE(voice_channel->HasRecvStream(1234U)); 2742 ASSERT_TRUE(voice_channel->HasRecvStream(2468U)); 2743 video_channel = fme_->GetVideoChannel(0); 2744 ASSERT_TRUE(video_channel != NULL); 2745 ASSERT_FALSE(video_channel->HasRecvStream(5678U)); 2746 2747 // Fails because ssrc is now invalid. 2748 ASSERT_FALSE( 2749 call_->SendViewRequest(call_->sessions()[0], viewRequest)); 2750 2751 ClearStanzas(); 2752 } 2753 2754 void MakeSignalingSecure(cricket::SecureMediaPolicy secure) { 2755 client_->set_secure(secure); 2756 } 2757 2758 void ExpectCrypto(cricket::SecureMediaPolicy secure) { 2759 MakeSignalingSecure(secure); 2760 expect_incoming_crypto_ = true; 2761 #ifdef HAVE_SRTP 2762 expect_outgoing_crypto_ = true; 2763 #endif 2764 } 2765 2766 void ExpectVideoBandwidth(int bandwidth) { 2767 expected_video_bandwidth_ = bandwidth; 2768 } 2769 2770 void ExpectVideoRtcpMux(bool rtcp_mux) { 2771 expected_video_rtcp_mux_ = rtcp_mux; 2772 } 2773 2774 template <class C> 2775 void SetCodecFeedbackParams(std::vector<C>* codecs, 2776 const FeedbackParams& fb_params) { 2777 for (size_t i = 0; i < codecs->size(); ++i) { 2778 codecs->at(i).feedback_params = fb_params; 2779 } 2780 } 2781 2782 void ExpectRtcpFb() { 2783 FeedbackParams params_nack_fir; 2784 params_nack_fir.Add(FeedbackParam(cricket::kRtcpFbParamCcm, 2785 cricket::kRtcpFbCcmParamFir)); 2786 params_nack_fir.Add(FeedbackParam(cricket::kRtcpFbParamNack)); 2787 2788 FeedbackParams params_nack; 2789 params_nack.Add(FeedbackParam(cricket::kRtcpFbParamNack)); 2790 2791 expected_audio_fb_params_ = params_nack; 2792 expected_video_fb_params_ = params_nack_fir; 2793 expected_data_fb_params_ = params_nack; 2794 } 2795 2796 private: 2797 void OnSendStanza(cricket::SessionManager* manager, 2798 const buzz::XmlElement* stanza) { 2799 LOG(LS_INFO) << stanza->Str(); 2800 stanzas_.push_back(new buzz::XmlElement(*stanza)); 2801 } 2802 2803 void OnSessionCreate(cricket::Session* session, bool initiate) { 2804 session->set_current_protocol(initial_protocol_); 2805 } 2806 2807 void OnCallCreate(cricket::Call *call) { 2808 call_ = call; 2809 call->SignalMediaStreamsUpdate.connect( 2810 this, &MediaSessionClientTest::OnMediaStreamsUpdate); 2811 } 2812 2813 void OnCallDestroy(cricket::Call *call) { 2814 call_ = NULL; 2815 } 2816 2817 void OnMediaStreamsUpdate(cricket::Call *call, 2818 cricket::Session *session, 2819 const cricket::MediaStreams& added, 2820 const cricket::MediaStreams& removed) { 2821 last_streams_added_.CopyFrom(added); 2822 last_streams_removed_.CopyFrom(removed); 2823 } 2824 2825 talk_base::NetworkManager* nm_; 2826 cricket::PortAllocator* pa_; 2827 cricket::SessionManager* sm_; 2828 cricket::FakeMediaEngine* fme_; 2829 cricket::FakeDataEngine* fdme_; 2830 cricket::MediaSessionClient* client_; 2831 2832 cricket::Call* call_; 2833 std::vector<buzz::XmlElement* > stanzas_; 2834 MediaSessionTestParser* parser_; 2835 cricket::SignalingProtocol initial_protocol_; 2836 bool expect_incoming_crypto_; 2837 bool expect_outgoing_crypto_; 2838 int expected_video_bandwidth_; 2839 bool expected_video_rtcp_mux_; 2840 FeedbackParams expected_audio_fb_params_; 2841 FeedbackParams expected_video_fb_params_; 2842 FeedbackParams expected_data_fb_params_; 2843 cricket::MediaStreams last_streams_added_; 2844 cricket::MediaStreams last_streams_removed_; 2845 }; 2846 2847 MediaSessionClientTest* GingleTest() { 2848 return new MediaSessionClientTest(new GingleSessionTestParser(), 2849 cricket::PROTOCOL_GINGLE); 2850 } 2851 2852 MediaSessionClientTest* JingleTest() { 2853 return new MediaSessionClientTest(new JingleSessionTestParser(), 2854 cricket::PROTOCOL_JINGLE); 2855 } 2856 2857 TEST(MediaSessionTest, JingleGoodInitiateWithRtcpFb) { 2858 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2859 talk_base::scoped_ptr<buzz::XmlElement> elem; 2860 2861 cricket::CallOptions options = VideoCallOptions(); 2862 options.data_channel_type = cricket::DCT_SCTP; 2863 test->ExpectRtcpFb(); 2864 test->TestGoodIncomingInitiate( 2865 kJingleInitiateWithRtcpFb, options, elem.use()); 2866 } 2867 2868 TEST(MediaSessionTest, JingleGoodVideoInitiate) { 2869 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2870 talk_base::scoped_ptr<buzz::XmlElement> elem; 2871 test->TestGoodIncomingInitiate( 2872 kJingleVideoInitiate, VideoCallOptions(), elem.use()); 2873 test->TestCodecsOfVideoInitiate(elem.get()); 2874 } 2875 2876 TEST(MediaSessionTest, JingleGoodVideoInitiateWithBandwidth) { 2877 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2878 talk_base::scoped_ptr<buzz::XmlElement> elem; 2879 test->ExpectVideoBandwidth(42000); 2880 test->TestGoodIncomingInitiate( 2881 kJingleVideoInitiateWithBandwidth, VideoCallOptions(), elem.use()); 2882 } 2883 2884 TEST(MediaSessionTest, JingleGoodVideoInitiateWithRtcpMux) { 2885 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2886 talk_base::scoped_ptr<buzz::XmlElement> elem; 2887 test->ExpectVideoRtcpMux(true); 2888 test->TestGoodIncomingInitiate( 2889 kJingleVideoInitiateWithRtcpMux, VideoCallOptions(), elem.use()); 2890 } 2891 2892 TEST(MediaSessionTest, JingleGoodVideoInitiateWithRtpData) { 2893 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2894 talk_base::scoped_ptr<buzz::XmlElement> elem; 2895 cricket::CallOptions options = VideoCallOptions(); 2896 options.data_channel_type = cricket::DCT_RTP; 2897 test->TestGoodIncomingInitiate( 2898 AddEncryption(kJingleVideoInitiateWithRtpData, kJingleCryptoOffer), 2899 options, 2900 elem.use()); 2901 } 2902 2903 TEST(MediaSessionTest, JingleGoodVideoInitiateWithSctpData) { 2904 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2905 talk_base::scoped_ptr<buzz::XmlElement> elem; 2906 cricket::CallOptions options = VideoCallOptions(); 2907 options.data_channel_type = cricket::DCT_SCTP; 2908 test->TestGoodIncomingInitiate(kJingleVideoInitiateWithSctpData, 2909 options, 2910 elem.use()); 2911 } 2912 2913 TEST(MediaSessionTest, JingleRejectAudio) { 2914 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2915 talk_base::scoped_ptr<buzz::XmlElement> elem; 2916 cricket::CallOptions options = VideoCallOptions(); 2917 options.has_audio = false; 2918 options.data_channel_type = cricket::DCT_RTP; 2919 test->TestRejectOffer(kJingleVideoInitiateWithRtpData, options, elem.use()); 2920 } 2921 2922 TEST(MediaSessionTest, JingleRejectVideo) { 2923 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2924 talk_base::scoped_ptr<buzz::XmlElement> elem; 2925 cricket::CallOptions options = AudioCallOptions(); 2926 options.data_channel_type = cricket::DCT_RTP; 2927 test->TestRejectOffer(kJingleVideoInitiateWithRtpData, options, elem.use()); 2928 } 2929 2930 TEST(MediaSessionTest, JingleRejectData) { 2931 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2932 talk_base::scoped_ptr<buzz::XmlElement> elem; 2933 test->TestRejectOffer( 2934 kJingleVideoInitiateWithRtpData, VideoCallOptions(), elem.use()); 2935 } 2936 2937 TEST(MediaSessionTest, JingleRejectVideoAndData) { 2938 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2939 talk_base::scoped_ptr<buzz::XmlElement> elem; 2940 test->TestRejectOffer( 2941 kJingleVideoInitiateWithRtpData, AudioCallOptions(), elem.use()); 2942 } 2943 2944 TEST(MediaSessionTest, JingleGoodInitiateAllSupportedAudioCodecs) { 2945 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2946 talk_base::scoped_ptr<buzz::XmlElement> elem; 2947 test->TestGoodIncomingInitiate( 2948 kJingleInitiate, AudioCallOptions(), elem.use()); 2949 test->TestHasAllSupportedAudioCodecs(elem.get()); 2950 } 2951 2952 TEST(MediaSessionTest, JingleGoodInitiateDifferentPreferenceAudioCodecs) { 2953 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2954 talk_base::scoped_ptr<buzz::XmlElement> elem; 2955 test->TestGoodIncomingInitiate( 2956 kJingleInitiateDifferentPreference, AudioCallOptions(), elem.use()); 2957 test->TestHasAllSupportedAudioCodecs(elem.get()); 2958 } 2959 2960 TEST(MediaSessionTest, JingleGoodInitiateSomeUnsupportedAudioCodecs) { 2961 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2962 talk_base::scoped_ptr<buzz::XmlElement> elem; 2963 test->TestGoodIncomingInitiate( 2964 kJingleInitiateSomeUnsupported, AudioCallOptions(), elem.use()); 2965 test->TestHasAudioCodecsFromInitiateSomeUnsupported(elem.get()); 2966 } 2967 2968 TEST(MediaSessionTest, JingleGoodInitiateDynamicAudioCodecs) { 2969 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2970 talk_base::scoped_ptr<buzz::XmlElement> elem; 2971 test->TestGoodIncomingInitiate( 2972 kJingleInitiateDynamicAudioCodecs, AudioCallOptions(), elem.use()); 2973 test->TestHasAudioCodecsFromInitiateDynamicAudioCodecs(elem.get()); 2974 } 2975 2976 TEST(MediaSessionTest, JingleGoodInitiateStaticAudioCodecs) { 2977 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2978 talk_base::scoped_ptr<buzz::XmlElement> elem; 2979 test->TestGoodIncomingInitiate( 2980 kJingleInitiateStaticAudioCodecs, AudioCallOptions(), elem.use()); 2981 test->TestHasAudioCodecsFromInitiateStaticAudioCodecs(elem.get()); 2982 } 2983 2984 TEST(MediaSessionTest, JingleBadInitiateNoAudioCodecs) { 2985 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2986 test->TestBadIncomingInitiate(kJingleInitiateNoAudioCodecs); 2987 } 2988 2989 TEST(MediaSessionTest, JingleBadInitiateNoSupportedAudioCodecs) { 2990 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2991 test->TestBadIncomingInitiate(kJingleInitiateNoSupportedAudioCodecs); 2992 } 2993 2994 TEST(MediaSessionTest, JingleBadInitiateWrongClockrates) { 2995 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 2996 test->TestBadIncomingInitiate(kJingleInitiateWrongClockrates); 2997 } 2998 2999 TEST(MediaSessionTest, JingleBadInitiateWrongChannels) { 3000 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3001 test->TestBadIncomingInitiate(kJingleInitiateWrongChannels); 3002 } 3003 3004 TEST(MediaSessionTest, JingleBadInitiateNoPayloadTypes) { 3005 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3006 test->TestBadIncomingInitiate(kJingleInitiateNoPayloadTypes); 3007 } 3008 3009 TEST(MediaSessionTest, JingleBadInitiateDynamicWithoutNames) { 3010 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3011 test->TestBadIncomingInitiate(kJingleInitiateDynamicWithoutNames); 3012 } 3013 3014 TEST(MediaSessionTest, JingleGoodOutgoingInitiate) { 3015 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3016 test->TestGoodOutgoingInitiate(AudioCallOptions()); 3017 } 3018 3019 TEST(MediaSessionTest, JingleGoodOutgoingInitiateWithBandwidth) { 3020 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3021 cricket::CallOptions options = VideoCallOptions(); 3022 options.video_bandwidth = 42000; 3023 test->TestGoodOutgoingInitiate(options); 3024 } 3025 3026 TEST(MediaSessionTest, JingleGoodOutgoingInitiateWithRtcpMux) { 3027 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3028 cricket::CallOptions options = VideoCallOptions(); 3029 options.rtcp_mux_enabled = true; 3030 test->TestGoodOutgoingInitiate(options); 3031 } 3032 3033 TEST(MediaSessionTest, JingleGoodOutgoingInitiateWithRtpData) { 3034 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3035 cricket::CallOptions options; 3036 options.data_channel_type = cricket::DCT_RTP; 3037 test->ExpectCrypto(cricket::SEC_ENABLED); 3038 test->TestGoodOutgoingInitiate(options); 3039 } 3040 3041 TEST(MediaSessionTest, JingleGoodOutgoingInitiateWithSctpData) { 3042 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3043 cricket::CallOptions options; 3044 options.data_channel_type = cricket::DCT_SCTP; 3045 test->TestGoodOutgoingInitiate(options); 3046 } 3047 3048 // Crypto related tests. 3049 3050 // Offer has crypto but the session is not secured, just ignore it. 3051 TEST(MediaSessionTest, JingleInitiateWithCryptoIsIgnoredWhenNotSecured) { 3052 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3053 talk_base::scoped_ptr<buzz::XmlElement> elem; 3054 test->TestGoodIncomingInitiate( 3055 AddEncryption(kJingleVideoInitiate, kJingleCryptoOffer), 3056 VideoCallOptions(), 3057 elem.use()); 3058 } 3059 3060 // Offer has crypto required but the session is not secure, fail. 3061 TEST(MediaSessionTest, JingleInitiateWithCryptoRequiredWhenNotSecured) { 3062 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3063 test->TestBadIncomingInitiate(AddEncryption(kJingleVideoInitiate, 3064 kJingleRequiredCryptoOffer)); 3065 } 3066 3067 // Offer has no crypto but the session is secure required, fail. 3068 TEST(MediaSessionTest, JingleInitiateWithNoCryptoFailsWhenSecureRequired) { 3069 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3070 test->ExpectCrypto(cricket::SEC_REQUIRED); 3071 test->TestBadIncomingInitiate(kJingleInitiate); 3072 } 3073 3074 // Offer has crypto and session is secure, expect crypto in the answer. 3075 TEST(MediaSessionTest, JingleInitiateWithCryptoWhenSecureEnabled) { 3076 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3077 talk_base::scoped_ptr<buzz::XmlElement> elem; 3078 test->ExpectCrypto(cricket::SEC_ENABLED); 3079 test->TestGoodIncomingInitiate( 3080 AddEncryption(kJingleVideoInitiate, kJingleCryptoOffer), 3081 VideoCallOptions(), 3082 elem.use()); 3083 } 3084 3085 // Offer has crypto and session is secure required, expect crypto in 3086 // the answer. 3087 TEST(MediaSessionTest, JingleInitiateWithCryptoWhenSecureRequired) { 3088 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3089 talk_base::scoped_ptr<buzz::XmlElement> elem; 3090 test->ExpectCrypto(cricket::SEC_REQUIRED); 3091 test->TestGoodIncomingInitiate( 3092 AddEncryption(kJingleVideoInitiate, kJingleCryptoOffer), 3093 VideoCallOptions(), 3094 elem.use()); 3095 } 3096 3097 // Offer has unsupported crypto and session is secure, no crypto in 3098 // the answer. 3099 TEST(MediaSessionTest, JingleInitiateWithUnsupportedCrypto) { 3100 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3101 talk_base::scoped_ptr<buzz::XmlElement> elem; 3102 test->MakeSignalingSecure(cricket::SEC_ENABLED); 3103 test->TestGoodIncomingInitiate( 3104 AddEncryption(kJingleInitiate, kJingleUnsupportedCryptoOffer), 3105 VideoCallOptions(), 3106 elem.use()); 3107 } 3108 3109 // Offer has unsupported REQUIRED crypto and session is not secure, fail. 3110 TEST(MediaSessionTest, JingleInitiateWithRequiredUnsupportedCrypto) { 3111 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3112 test->TestBadIncomingInitiate( 3113 AddEncryption(kJingleInitiate, kJingleRequiredUnsupportedCryptoOffer)); 3114 } 3115 3116 // Offer has unsupported REQUIRED crypto and session is secure, fail. 3117 TEST(MediaSessionTest, JingleInitiateWithRequiredUnsupportedCryptoWhenSecure) { 3118 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3119 test->MakeSignalingSecure(cricket::SEC_ENABLED); 3120 test->TestBadIncomingInitiate( 3121 AddEncryption(kJingleInitiate, kJingleRequiredUnsupportedCryptoOffer)); 3122 } 3123 3124 // Offer has unsupported REQUIRED crypto and session is required secure, fail. 3125 TEST(MediaSessionTest, 3126 JingleInitiateWithRequiredUnsupportedCryptoWhenSecureRequired) { 3127 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3128 test->MakeSignalingSecure(cricket::SEC_REQUIRED); 3129 test->TestBadIncomingInitiate( 3130 AddEncryption(kJingleInitiate, kJingleRequiredUnsupportedCryptoOffer)); 3131 } 3132 3133 3134 TEST(MediaSessionTest, JingleGoodOutgoingInitiateWithCrypto) { 3135 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3136 test->ExpectCrypto(cricket::SEC_ENABLED); 3137 test->TestGoodOutgoingInitiate(AudioCallOptions()); 3138 } 3139 3140 TEST(MediaSessionTest, JingleGoodOutgoingInitiateWithCryptoRequired) { 3141 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3142 test->ExpectCrypto(cricket::SEC_REQUIRED); 3143 test->TestGoodOutgoingInitiate(AudioCallOptions()); 3144 } 3145 3146 TEST(MediaSessionTest, JingleIncomingAcceptWithSsrcs) { 3147 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3148 cricket::CallOptions options = VideoCallOptions(); 3149 options.is_muc = true; 3150 test->TestIncomingAcceptWithSsrcs(kJingleAcceptWithSsrcs, options); 3151 } 3152 3153 TEST(MediaSessionTest, JingleIncomingAcceptWithRtpDataSsrcs) { 3154 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3155 cricket::CallOptions options = VideoCallOptions(); 3156 options.is_muc = true; 3157 options.data_channel_type = cricket::DCT_RTP; 3158 test->TestIncomingAcceptWithSsrcs(kJingleAcceptWithRtpDataSsrcs, options); 3159 } 3160 3161 TEST(MediaSessionTest, JingleIncomingAcceptWithSctpData) { 3162 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3163 cricket::CallOptions options = VideoCallOptions(); 3164 options.is_muc = true; 3165 options.data_channel_type = cricket::DCT_SCTP; 3166 test->TestIncomingAcceptWithSsrcs(kJingleAcceptWithSctpData, options); 3167 } 3168 3169 TEST(MediaSessionTest, JingleStreamsUpdateAndView) { 3170 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3171 test->TestStreamsUpdateAndViewRequests(); 3172 } 3173 3174 TEST(MediaSessionTest, JingleSendVideoStreamUpdate) { 3175 talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest()); 3176 test->TestSendVideoStreamUpdate(); 3177 } 3178 3179 // Gingle tests 3180 3181 TEST(MediaSessionTest, GingleGoodVideoInitiate) { 3182 talk_base::scoped_ptr<buzz::XmlElement> elem; 3183 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3184 test->TestGoodIncomingInitiate( 3185 kGingleVideoInitiate, VideoCallOptions(), elem.use()); 3186 test->TestCodecsOfVideoInitiate(elem.get()); 3187 } 3188 3189 TEST(MediaSessionTest, GingleGoodVideoInitiateWithBandwidth) { 3190 talk_base::scoped_ptr<buzz::XmlElement> elem; 3191 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3192 test->ExpectVideoBandwidth(42000); 3193 test->TestGoodIncomingInitiate( 3194 kGingleVideoInitiateWithBandwidth, VideoCallOptions(), elem.use()); 3195 } 3196 3197 TEST(MediaSessionTest, GingleGoodInitiateAllSupportedAudioCodecs) { 3198 talk_base::scoped_ptr<buzz::XmlElement> elem; 3199 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3200 test->TestGoodIncomingInitiate( 3201 kGingleInitiate, AudioCallOptions(), elem.use()); 3202 test->TestHasAllSupportedAudioCodecs(elem.get()); 3203 } 3204 3205 TEST(MediaSessionTest, GingleGoodInitiateAllSupportedAudioCodecsWithCrypto) { 3206 talk_base::scoped_ptr<buzz::XmlElement> elem; 3207 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3208 test->ExpectCrypto(cricket::SEC_ENABLED); 3209 test->TestGoodIncomingInitiate( 3210 AddEncryption(kGingleInitiate, kGingleCryptoOffer), 3211 AudioCallOptions(), 3212 elem.use()); 3213 test->TestHasAllSupportedAudioCodecs(elem.get()); 3214 } 3215 3216 TEST(MediaSessionTest, GingleGoodInitiateDifferentPreferenceAudioCodecs) { 3217 talk_base::scoped_ptr<buzz::XmlElement> elem; 3218 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3219 test->TestGoodIncomingInitiate( 3220 kGingleInitiateDifferentPreference, AudioCallOptions(), elem.use()); 3221 test->TestHasAllSupportedAudioCodecs(elem.get()); 3222 } 3223 3224 TEST(MediaSessionTest, GingleGoodInitiateSomeUnsupportedAudioCodecs) { 3225 talk_base::scoped_ptr<buzz::XmlElement> elem; 3226 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3227 test->TestGoodIncomingInitiate( 3228 kGingleInitiateSomeUnsupported, AudioCallOptions(), elem.use()); 3229 test->TestHasAudioCodecsFromInitiateSomeUnsupported(elem.get()); 3230 } 3231 3232 TEST(MediaSessionTest, GingleGoodInitiateDynamicAudioCodecs) { 3233 talk_base::scoped_ptr<buzz::XmlElement> elem; 3234 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3235 test->TestGoodIncomingInitiate( 3236 kGingleInitiateDynamicAudioCodecs, AudioCallOptions(), elem.use()); 3237 test->TestHasAudioCodecsFromInitiateDynamicAudioCodecs(elem.get()); 3238 } 3239 3240 TEST(MediaSessionTest, GingleGoodInitiateStaticAudioCodecs) { 3241 talk_base::scoped_ptr<buzz::XmlElement> elem; 3242 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3243 test->TestGoodIncomingInitiate( 3244 kGingleInitiateStaticAudioCodecs, AudioCallOptions(), elem.use()); 3245 test->TestHasAudioCodecsFromInitiateStaticAudioCodecs(elem.get()); 3246 } 3247 3248 TEST(MediaSessionTest, GingleGoodInitiateNoAudioCodecs) { 3249 talk_base::scoped_ptr<buzz::XmlElement> elem; 3250 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3251 test->TestGoodIncomingInitiate( 3252 kGingleInitiateNoAudioCodecs, AudioCallOptions(), elem.use()); 3253 test->TestHasDefaultAudioCodecs(elem.get()); 3254 } 3255 3256 TEST(MediaSessionTest, GingleBadInitiateNoSupportedAudioCodecs) { 3257 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3258 test->TestBadIncomingInitiate(kGingleInitiateNoSupportedAudioCodecs); 3259 } 3260 3261 TEST(MediaSessionTest, GingleBadInitiateWrongClockrates) { 3262 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3263 test->TestBadIncomingInitiate(kGingleInitiateWrongClockrates); 3264 } 3265 3266 TEST(MediaSessionTest, GingleBadInitiateWrongChannels) { 3267 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3268 test->TestBadIncomingInitiate(kGingleInitiateWrongChannels); 3269 } 3270 3271 3272 TEST(MediaSessionTest, GingleBadInitiateNoPayloadTypes) { 3273 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3274 test->TestBadIncomingInitiate(kGingleInitiateNoPayloadTypes); 3275 } 3276 3277 TEST(MediaSessionTest, GingleBadInitiateDynamicWithoutNames) { 3278 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3279 test->TestBadIncomingInitiate(kGingleInitiateDynamicWithoutNames); 3280 } 3281 3282 TEST(MediaSessionTest, GingleGoodOutgoingInitiate) { 3283 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3284 test->TestGoodOutgoingInitiate(AudioCallOptions()); 3285 } 3286 3287 TEST(MediaSessionTest, GingleGoodOutgoingInitiateWithBandwidth) { 3288 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3289 cricket::CallOptions options = VideoCallOptions(); 3290 options.video_bandwidth = 42000; 3291 test->TestGoodOutgoingInitiate(options); 3292 } 3293 3294 // Crypto related tests. 3295 3296 // Offer has crypto but the session is not secured, just ignore it. 3297 TEST(MediaSessionTest, GingleInitiateWithCryptoIsIgnoredWhenNotSecured) { 3298 talk_base::scoped_ptr<buzz::XmlElement> elem; 3299 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3300 test->TestGoodIncomingInitiate( 3301 AddEncryption(kGingleInitiate, kGingleCryptoOffer), 3302 VideoCallOptions(), 3303 elem.use()); 3304 } 3305 3306 // Offer has crypto required but the session is not secure, fail. 3307 TEST(MediaSessionTest, GingleInitiateWithCryptoRequiredWhenNotSecured) { 3308 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3309 test->TestBadIncomingInitiate(AddEncryption(kGingleInitiate, 3310 kGingleRequiredCryptoOffer)); 3311 } 3312 3313 // Offer has no crypto but the session is secure required, fail. 3314 TEST(MediaSessionTest, GingleInitiateWithNoCryptoFailsWhenSecureRequired) { 3315 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3316 test->ExpectCrypto(cricket::SEC_REQUIRED); 3317 test->TestBadIncomingInitiate(kGingleInitiate); 3318 } 3319 3320 // Offer has crypto and session is secure, expect crypto in the answer. 3321 TEST(MediaSessionTest, GingleInitiateWithCryptoWhenSecureEnabled) { 3322 talk_base::scoped_ptr<buzz::XmlElement> elem; 3323 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3324 test->ExpectCrypto(cricket::SEC_ENABLED); 3325 test->TestGoodIncomingInitiate( 3326 AddEncryption(kGingleInitiate, kGingleCryptoOffer), 3327 VideoCallOptions(), 3328 elem.use()); 3329 } 3330 3331 // Offer has crypto and session is secure required, expect crypto in 3332 // the answer. 3333 TEST(MediaSessionTest, GingleInitiateWithCryptoWhenSecureRequired) { 3334 talk_base::scoped_ptr<buzz::XmlElement> elem; 3335 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3336 test->ExpectCrypto(cricket::SEC_REQUIRED); 3337 test->TestGoodIncomingInitiate( 3338 AddEncryption(kGingleInitiate, kGingleCryptoOffer), 3339 VideoCallOptions(), 3340 elem.use()); 3341 } 3342 3343 // Offer has unsupported crypto and session is secure, no crypto in 3344 // the answer. 3345 TEST(MediaSessionTest, GingleInitiateWithUnsupportedCrypto) { 3346 talk_base::scoped_ptr<buzz::XmlElement> elem; 3347 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3348 test->MakeSignalingSecure(cricket::SEC_ENABLED); 3349 test->TestGoodIncomingInitiate( 3350 AddEncryption(kGingleInitiate, kGingleUnsupportedCryptoOffer), 3351 VideoCallOptions(), 3352 elem.use()); 3353 } 3354 3355 // Offer has unsupported REQUIRED crypto and session is not secure, fail. 3356 TEST(MediaSessionTest, GingleInitiateWithRequiredUnsupportedCrypto) { 3357 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3358 test->TestBadIncomingInitiate( 3359 AddEncryption(kGingleInitiate, kGingleRequiredUnsupportedCryptoOffer)); 3360 } 3361 3362 // Offer has unsupported REQUIRED crypto and session is secure, fail. 3363 TEST(MediaSessionTest, GingleInitiateWithRequiredUnsupportedCryptoWhenSecure) { 3364 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3365 test->MakeSignalingSecure(cricket::SEC_ENABLED); 3366 test->TestBadIncomingInitiate( 3367 AddEncryption(kGingleInitiate, kGingleRequiredUnsupportedCryptoOffer)); 3368 } 3369 3370 // Offer has unsupported REQUIRED crypto and session is required secure, fail. 3371 TEST(MediaSessionTest, 3372 GingleInitiateWithRequiredUnsupportedCryptoWhenSecureRequired) { 3373 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3374 test->MakeSignalingSecure(cricket::SEC_REQUIRED); 3375 test->TestBadIncomingInitiate( 3376 AddEncryption(kGingleInitiate, kGingleRequiredUnsupportedCryptoOffer)); 3377 } 3378 3379 TEST(MediaSessionTest, GingleGoodOutgoingInitiateWithCrypto) { 3380 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3381 test->ExpectCrypto(cricket::SEC_ENABLED); 3382 test->TestGoodOutgoingInitiate(AudioCallOptions()); 3383 } 3384 3385 TEST(MediaSessionTest, GingleGoodOutgoingInitiateWithCryptoRequired) { 3386 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3387 test->ExpectCrypto(cricket::SEC_REQUIRED); 3388 test->TestGoodOutgoingInitiate(AudioCallOptions()); 3389 } 3390 3391 TEST(MediaSessionTest, GingleIncomingAcceptWithSsrcs) { 3392 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3393 cricket::CallOptions options = VideoCallOptions(); 3394 options.is_muc = true; 3395 test->TestIncomingAcceptWithSsrcs(kGingleAcceptWithSsrcs, options); 3396 } 3397 3398 TEST(MediaSessionTest, GingleGoodOutgoingInitiateWithRtpData) { 3399 talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest()); 3400 cricket::CallOptions options; 3401 options.data_channel_type = cricket::DCT_RTP; 3402 test->ExpectCrypto(cricket::SEC_ENABLED); 3403 test->TestGoodOutgoingInitiate(options); 3404 } 3405