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