~ubuntu-branches/debian/experimental/kopete/experimental

« back to all changes in this revision

Viewing changes to protocols/jabber/libjingle/talk/session/phone/mediasessionclient_unittest.cc

  • Committer: Package Import Robot
  • Author(s): Maximiliano Curia
  • Date: 2015-02-24 11:32:57 UTC
  • mfrom: (1.1.41 vivid)
  • Revision ID: package-import@ubuntu.com-20150224113257-gnupg4v7lzz18ij0
Tags: 4:14.12.2-1
* New upstream release (14.12.2).
* Bump Standards-Version to 3.9.6, no changes needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * libjingle
 
3
 * Copyright 2004--2011, 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/p2p/base/constants.h"
 
35
#include "talk/p2p/client/basicportallocator.h"
 
36
#include "talk/session/phone/fakedevicemanager.h"
 
37
#include "talk/session/phone/fakemediaengine.h"
 
38
#include "talk/session/phone/mediasessionclient.h"
 
39
#include "talk/xmllite/xmlelement.h"
 
40
#include "talk/xmllite/xmlbuilder.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.
 
46
static 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
 
 
67
static const cricket::VideoCodec kVideoCodecs[] = {
 
68
  cricket::VideoCodec(96, "H264-SVC", 320, 200, 30, 1)
 
69
};
 
70
 
 
71
static const cricket::DataCodec kDataCodecs[] = {
 
72
  cricket::DataCodec(101, "google-data", 0)
 
73
};
 
74
 
 
75
const 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.
 
85
const 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
 
 
94
const 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
 
 
103
const 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
 
 
112
const 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
 
 
121
const 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"
 
131
const 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
 
 
140
const 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
 
 
148
const 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
 
 
194
const 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.
 
265
const 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
 
 
311
const 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
 
 
380
const 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
 
 
395
const 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
 
 
419
const std::string kJingleVideoInitiateWithData(
 
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='101' name='google-data'/>               " \
 
443
     "        <rtcp-mux/>                                               " \
 
444
     "      </description>                                              " \
 
445
     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>   " \
 
446
     "    </content>                                                    " \
 
447
     "  </jingle>                                                       " \
 
448
     "</iq>                                                             ");
 
449
 
 
450
const std::string kJingleVideoInitiateWithBandwidth(
 
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
     "        <bandwidth type='AS'>42</bandwidth>                       " \
 
469
     "      </description>                                              " \
 
470
     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>   " \
 
471
     "    </content>                                                    " \
 
472
     "  </jingle>                                                       " \
 
473
     "</iq>                                                             ");
 
474
 
 
475
const std::string kJingleVideoInitiateWithRtcpMux(
 
476
     "<iq xmlns='jabber:client' from='me@domain.com/resource'           " \
 
477
     "    to='user@domain.com/resource' type='set' id='123'>            " \
 
478
     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'     " \
 
479
     "         sid='abcdef' initiator='me@domain.com/resource'>         " \
 
480
     "    <content name='test audio'>                                   " \
 
481
     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \
 
482
     "        <payload-type id='103' name='ISAC' clockrate='16000'/>    " \
 
483
     "      </description>                                              " \
 
484
     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>   " \
 
485
     "    </content>                                                    " \
 
486
     "    <content name='test video'>                                   " \
 
487
     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='video'> " \
 
488
     "        <payload-type id='99' name='H264-SVC'>                    " \
 
489
     "          <parameter name='height' value='200'/>                  " \
 
490
     "          <parameter name='width' value='320'/>                   " \
 
491
     "          <parameter name='framerate' value='30'/>                " \
 
492
     "        </payload-type>                                           " \
 
493
     "        <rtcp-mux/>                                               " \
 
494
     "      </description>                                              " \
 
495
     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>   " \
 
496
     "    </content>                                                    " \
 
497
     "  </jingle>                                                       " \
 
498
     "</iq>                                                             ");
 
499
 
 
500
// Initiate string with a combination of supported and unsupported codecs
 
501
// Should accept the supported ones
 
502
const std::string kGingleInitiateSomeUnsupported(
 
503
     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
 
504
     "    to='user@domain.com/resource' type='set' id='123'>          " \
 
505
     "  <session xmlns='http://www.google.com/session' type='initiate'" \
 
506
     "    id='abcdef' initiator='me@domain.com/resource'>             " \
 
507
     "    <description xmlns='http://www.google.com/session/phone'>   " \
 
508
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
509
     "        id='103' name='ISAC' clockrate='16000' />               " \
 
510
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
511
     "        id='97' name='ASDFDS' />                                " \
 
512
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
513
     "        id='102' name='1010' />                                 " \
 
514
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
515
     "        id='107' name='DFAS' />                                 " \
 
516
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
517
     "        id='100' name='EG711U' />                               " \
 
518
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
519
     "        id='101' name='EG711A' />                               " \
 
520
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
521
     "        id='0' name='PCMU' />                                   " \
 
522
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
523
     "        id='110' name=':)' />                                   " \
 
524
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
525
     "        id='13' name='CN' />                                    " \
 
526
     "    </description>                                              " \
 
527
     "  </session>                                                    " \
 
528
     "</iq>                                                           ");
 
529
 
 
530
const std::string kJingleInitiateSomeUnsupported(
 
531
     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
 
532
     "    to='user@domain.com/resource' type='set' id='123'>          " \
 
533
     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'   " \
 
534
     "          sid='abcdef' initiator='me@domain.com/resource'>      " \
 
535
     "    <content name='test audio'>                                 " \
 
536
     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \
 
537
     "        <payload-type                                           " \
 
538
     "          id='103' name='ISAC' clockrate='16000' />             " \
 
539
     "        <payload-type                                           " \
 
540
     "          id='97' name='ASDFDS' />                              " \
 
541
     "        <payload-type                                           " \
 
542
     "          id='102' name='1010' />                               " \
 
543
     "        <payload-type                                           " \
 
544
     "          id='107' name='DFAS' />                               " \
 
545
     "        <payload-type                                           " \
 
546
     "          id='100' name='EG711U' />                             " \
 
547
     "        <payload-type                                           " \
 
548
     "          id='101' name='EG711A' />                             " \
 
549
     "        <payload-type                                           " \
 
550
     "          id='0' name='PCMU' />                                 " \
 
551
     "        <payload-type                                           " \
 
552
     "          id='110' name=':)' />                                 " \
 
553
     "        <payload-type                                           " \
 
554
     "          id='13' name='CN' />                                  " \
 
555
     "      </description>                                            " \
 
556
     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \
 
557
     "    </content>                                                  " \
 
558
     "  </jingle>                                                     " \
 
559
     "</iq>                                                           ");
 
560
 
 
561
const std::string kGingleVideoInitiateWithBandwidth(
 
562
     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
 
563
     "    to='user@domain.com/resource' type='set' id='123'>          " \
 
564
     "  <session xmlns='http://www.google.com/session' type='initiate'" \
 
565
     "    id='abcdef' initiator='me@domain.com/resource'>             " \
 
566
     "    <description xmlns='http://www.google.com/session/video'>   " \
 
567
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
568
     "        id='103' name='ISAC' clockrate='16000' />               " \
 
569
     "      <payload-type xmlns='http://www.google.com/session/video' " \
 
570
     "        id='99' name='H264-SVC' framerate='30'                  " \
 
571
     "        height='200' width='320'/>                              " \
 
572
     "      <bandwidth type='AS'>42</bandwidth>                       " \
 
573
     "    </description>                                              " \
 
574
     "  </session>                                                    " \
 
575
     "</iq>                                                           ");
 
576
 
 
577
// Initiate string without any supported codecs. Should send a reject.
 
578
const std::string kGingleInitiateNoSupportedAudioCodecs(
 
579
     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
 
580
     "    to='user@domain.com/resource' type='set' id='123'>          " \
 
581
     "  <session xmlns='http://www.google.com/session' type='initiate'" \
 
582
     "    id='abcdef' initiator='me@domain.com/resource'>             " \
 
583
     "    <description xmlns='http://www.google.com/session/phone'>   " \
 
584
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
585
     "        id='123' name='Supercodec6000' />                       " \
 
586
     "    </description>                                              " \
 
587
     "  </session>                                                    " \
 
588
     "</iq>                                                           ");
 
589
 
 
590
const std::string kJingleInitiateNoSupportedAudioCodecs(
 
591
     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
 
592
     "    to='user@domain.com/resource' type='set' id='123'>          " \
 
593
     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'   " \
 
594
     "          sid='abcdef' initiator='me@domain.com/resource'>      " \
 
595
     "    <content name='test audio'>                                 " \
 
596
     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \
 
597
     "        <payload-type                                           " \
 
598
     "          id='123' name='Supercodec6000' />                     " \
 
599
     "      </description>                                            " \
 
600
     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>  " \
 
601
     "    </content>                                                  " \
 
602
     "  </jingle>                                                     " \
 
603
     "</iq>                                                           ");
 
604
 
 
605
// Initiate string without any codecs. Assumes ancient version of Cricket
 
606
// and tries a session with ISAC and PCMU
 
607
const std::string kGingleInitiateNoAudioCodecs(
 
608
     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
 
609
     "    to='user@domain.com/resource' type='set' id='123'>          " \
 
610
     "  <session xmlns='http://www.google.com/session' type='initiate'" \
 
611
     "    id='abcdef' initiator='me@domain.com/resource'>             " \
 
612
     "    <description xmlns='http://www.google.com/session/phone'>   " \
 
613
     "    </description>                                              " \
 
614
     "  </session>                                                    " \
 
615
     "</iq>                                                           ");
 
616
 
 
617
const std::string kJingleInitiateNoAudioCodecs(
 
618
     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
 
619
     "    to='user@domain.com/resource' type='set' id='123'>          " \
 
620
     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'   " \
 
621
     "          sid='abcdef' initiator='me@domain.com/resource'>      " \
 
622
     "    <content name='test audio'>                                 " \
 
623
     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \
 
624
     "      </description>                                            " \
 
625
     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>  " \
 
626
     "    </content>                                                  " \
 
627
     "  </jingle>                                                     " \
 
628
     "</iq>                                                           ");
 
629
 
 
630
// The codecs are supported, but not at the given clockrates. Should send
 
631
// a reject.
 
632
const std::string kGingleInitiateWrongClockrates(
 
633
     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
 
634
     "    to='user@domain.com/resource' type='set' id='123'>          " \
 
635
     "  <session xmlns='http://www.google.com/session' type='initiate'" \
 
636
     "    id='abcdef' initiator='me@domain.com/resource'>             " \
 
637
     "    <description xmlns='http://www.google.com/session/phone'>   " \
 
638
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
639
     "        id='103' name='ISAC' clockrate='8000'/>                 " \
 
640
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
641
     "        id='97' name='IPCMWB' clockrate='1337'/>                " \
 
642
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
643
     "        id='102' name='iLBC' clockrate='1982' />                " \
 
644
     "    </description>                                              " \
 
645
     "  </session>                                                    " \
 
646
     "</iq>                                                           ");
 
647
 
 
648
const std::string kJingleInitiateWrongClockrates(
 
649
     "<iq xmlns='jabber:client' from='me@domain.com/resource'           " \
 
650
     "    to='user@domain.com/resource' type='set' id='123'>            " \
 
651
     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'     " \
 
652
     "          sid='abcdef' initiator='me@domain.com/resource'>        " \
 
653
     "    <content name='test audio'>                                   " \
 
654
     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \
 
655
     "        <payload-type                                             " \
 
656
     "          id='103' name='ISAC' clockrate='8000'/>                 " \
 
657
     "        <payload-type                                             " \
 
658
     "          id='97' name='IPCMWB' clockrate='1337'/>                " \
 
659
     "       <payload-type                                              " \
 
660
     "          id='102' name='iLBC' clockrate='1982' />                " \
 
661
     "      </description>                                              " \
 
662
     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>  " \
 
663
     "    </content>                                                    " \
 
664
     "  </jingle>                                                       " \
 
665
     "</iq>                                                             ");
 
666
 
 
667
// The codecs are supported, but not with the given number of channels.
 
668
// Should send a reject.
 
669
const std::string kGingleInitiateWrongChannels(
 
670
     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
 
671
     "    to='user@domain.com/resource' type='set' id='123'>          " \
 
672
     "  <session xmlns='http://www.google.com/session' type='initiate'" \
 
673
     "    id='abcdef' initiator='me@domain.com/resource'>             " \
 
674
     "    <description xmlns='http://www.google.com/session/phone'>   " \
 
675
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
676
     "        id='103' name='ISAC' channels='2'/>                     " \
 
677
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
678
     "        id='97' name='IPCMWB' channels='3'/>                    " \
 
679
     "    </description>                                              " \
 
680
     "  </session>                                                    " \
 
681
     "</iq>                                                           ");
 
682
 
 
683
const std::string kJingleInitiateWrongChannels(
 
684
     "<iq xmlns='jabber:client' from='me@domain.com/resource'           " \
 
685
     "    to='user@domain.com/resource' type='set' id='123'>            " \
 
686
     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'>    " \
 
687
     "    <content name='test audio'>                                   " \
 
688
     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \
 
689
     "        <payload-type                                             " \
 
690
     "          id='103' name='ISAC' channels='2'/>                     " \
 
691
     "        <payload-type                                             " \
 
692
     "          id='97' name='IPCMWB' channels='3'/>                    " \
 
693
     "      </description>                                              " \
 
694
     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>   " \
 
695
     "    </content>                                                    " \
 
696
     "  </jingle>                                                       " \
 
697
     "</iq>                                                             ");
 
698
 
 
699
// Initiate with a dynamic codec not using GIPS default payload id. Should
 
700
// accept with provided payload id.
 
701
const std::string kGingleInitiateDynamicAudioCodecs(
 
702
     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
 
703
     "    to='user@domain.com/resource' type='set' id='123'>          " \
 
704
     "  <session xmlns='http://www.google.com/session' type='initiate'" \
 
705
     "    id='abcdef' initiator='me@domain.com/resource'>             " \
 
706
     "    <description xmlns='http://www.google.com/session/phone'>   " \
 
707
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
708
     "        id='123' name='speex' clockrate='16000'/>               " \
 
709
     "    </description>                                              " \
 
710
     "  </session>                                                    " \
 
711
     "</iq>                                                           ");
 
712
 
 
713
const std::string kJingleInitiateDynamicAudioCodecs(
 
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
     "          sid='abcdef' initiator='me@domain.com/resource'>        " \
 
718
     "    <content name='test audio'>                                   " \
 
719
     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \
 
720
     "        <payload-type                                             " \
 
721
     "          id='123' name='speex' clockrate='16000'/>               " \
 
722
     "      </description>                                              " \
 
723
     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>   " \
 
724
     "    </content>                                                    " \
 
725
     "  </jingle>                                                       " \
 
726
     "</iq>                                                             ");
 
727
 
 
728
// Initiate string with nothing but static codec id's. Should accept.
 
729
const std::string kGingleInitiateStaticAudioCodecs(
 
730
     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
 
731
     "    to='user@domain.com/resource' type='set' id='123'>          " \
 
732
     "  <session xmlns='http://www.google.com/session' type='initiate'" \
 
733
     "    id='abcdef' initiator='me@domain.com/resource'>             " \
 
734
     "    <description xmlns='http://www.google.com/session/phone'>   " \
 
735
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
736
     "        id='3' />                                               " \
 
737
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
738
     "        id='0' />                                               " \
 
739
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
740
     "        id='8' />                                               " \
 
741
     "    </description>                                              " \
 
742
     "  </session>                                                    " \
 
743
     "</iq>                                                           ");
 
744
 
 
745
const std::string kJingleInitiateStaticAudioCodecs(
 
746
     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
 
747
     "    to='user@domain.com/resource' type='set' id='123'>          " \
 
748
     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'   " \
 
749
     "          sid='abcdef' initiator='me@domain.com/resource'>      " \
 
750
     "    <content name='test audio'>                                 " \
 
751
     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \
 
752
     "        <payload-type id='3' />                                 " \
 
753
     "        <payload-type id='0' />                                 " \
 
754
     "        <payload-type id='8' />                                 " \
 
755
     "      </description>                                            " \
 
756
     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \
 
757
     "    </content>                                                  " \
 
758
     "  </jingle>                                                     " \
 
759
     "</iq>                                                           ");
 
760
 
 
761
// Initiate with payload type-less codecs. Should reject.
 
762
const std::string kGingleInitiateNoPayloadTypes(
 
763
     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
 
764
     "    to='user@domain.com/resource' type='set' id='123'>          " \
 
765
     "  <session xmlns='http://www.google.com/session' type='initiate'" \
 
766
     "    id='abcdef' initiator='me@domain.com/resource'>             " \
 
767
     "    <description xmlns='http://www.google.com/session/phone'>   " \
 
768
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
769
     "       name='ISAC' clockrate='16000'/>                          " \
 
770
     "    </description>                                              " \
 
771
     "  </session>                                                    " \
 
772
     "</iq>                                                           ");
 
773
 
 
774
const std::string kJingleInitiateNoPayloadTypes(
 
775
     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
 
776
     "    to='user@domain.com/resource' type='set' id='123'>          " \
 
777
     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'>  " \
 
778
     "          sid='abcdef' initiator='me@domain.com/resource'>      " \
 
779
     "    <content name='test audio'>                                 " \
 
780
     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \
 
781
     "        <payload-type  name='ISAC' clockrate='16000'/>          " \
 
782
     "      </description>                                            " \
 
783
     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \
 
784
     "    </content>                                                  " \
 
785
     "  </jingle>                                                     " \
 
786
     "</iq>                                                           ");
 
787
 
 
788
// Initiate with unnamed dynamic codces. Should reject.
 
789
const std::string kGingleInitiateDynamicWithoutNames(
 
790
     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
 
791
     "    to='user@domain.com/resource' type='set' id='123'>          " \
 
792
     "  <session xmlns='http://www.google.com/session' type='initiate'" \
 
793
     "    id='abcdef' initiator='me@domain.com/resource'>             " \
 
794
     "    <description xmlns='http://www.google.com/session/phone'>   " \
 
795
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
796
     "       id='100' clockrate='16000'/>                             " \
 
797
     "    </description>                                              " \
 
798
     "  </session>                                                    " \
 
799
     "</iq>                                                           ");
 
800
 
 
801
const std::string kJingleInitiateDynamicWithoutNames(
 
802
     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
 
803
     "    to='user@domain.com/resource' type='set' id='123'>          " \
 
804
     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'>  " \
 
805
     "          sid='abcdef' initiator='me@domain.com/resource'>      " \
 
806
     "    <content name='test audio'>                                 " \
 
807
     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \
 
808
     "        <payload-type id='100' clockrate='16000'/>              " \
 
809
     "      </description>                                            " \
 
810
     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>  " \
 
811
     "    </content>                                                  " \
 
812
     "  </jingle>                                                     " \
 
813
     "</iq>                                                           ");
 
814
 
 
815
const uint32 kAudioSsrc = 4294967295U;
 
816
const uint32 kVideoSsrc = 87654321;
 
817
const uint32 kDataSsrc = 1010101;
 
818
// Note that this message does not specify a session ID. It must be populated
 
819
// before use.
 
820
const std::string kGingleAcceptWithSsrcs(
 
821
     "<iq xmlns='jabber:client' from='me@mydomain.com'                " \
 
822
     "    to='user@domain.com/resource' type='set' id='150'>          " \
 
823
     "  <session xmlns='http://www.google.com/session' type='accept'  " \
 
824
     "    initiator='me@domain.com/resource'>                         " \
 
825
     "    <description xmlns='http://www.google.com/session/video'>   " \
 
826
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
827
     "        id='103' name='ISAC' clockrate='16000' />               " \
 
828
     "      <payload-type xmlns='http://www.google.com/session/phone' " \
 
829
     "        id='104' name='ISAC' clockrate='32000' />               " \
 
830
     "      <src-id xmlns='http://www.google.com/session/phone'>      " \
 
831
     "        4294967295</src-id>                                       " \
 
832
     "      <src-id>87654321</src-id>                                 " \
 
833
     "    </description>                                              " \
 
834
     "  </session>                                                    " \
 
835
     "</iq>                                                           ");
 
836
 
 
837
const std::string kJingleAcceptWithSsrcs(
 
838
     "<iq xmlns='jabber:client' from='me@mydomain.com'                " \
 
839
     "    to='user@domain.com/resource' type='set' id='150'>          " \
 
840
     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-accept'     " \
 
841
     "          initiator='me@domain.com/resource'>                   " \
 
842
     "    <content name='audio'>                                      " \
 
843
     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1'           " \
 
844
     "          media='audio' ssrc='4294967295'>                      " \
 
845
     "        <payload-type id='103' name='ISAC' clockrate='16000'/>  " \
 
846
     "        <payload-type id='104' name='ISAC' clockrate='32000'/>  " \
 
847
     "      </description>                                            " \
 
848
     "     <transport xmlns='http://www.google.com/transport/p2p'/>   " \
 
849
     "    </content>                                                  " \
 
850
     "    <content name='video'>                                      " \
 
851
     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1'           " \
 
852
     "          media='video' ssrc='87654321'>                        " \
 
853
     "      </description>                                            " \
 
854
     "     <transport xmlns='http://www.google.com/transport/p2p'/>   " \
 
855
     "    </content>                                                  " \
 
856
     "  </jingle>                                                     " \
 
857
     "</iq>                                                           ");
 
858
 
 
859
const std::string kJingleAcceptWithDataSsrcs(
 
860
     "<iq xmlns='jabber:client' from='me@mydomain.com'                " \
 
861
     "    to='user@domain.com/resource' type='set' id='150'>          " \
 
862
     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-accept'     " \
 
863
     "          initiator='me@domain.com/resource'>                   " \
 
864
     "    <content name='audio'>                                      " \
 
865
     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1'           " \
 
866
     "          media='audio' ssrc='4294967295'>                      " \
 
867
     "        <payload-type id='103' name='ISAC' clockrate='16000'/>  " \
 
868
     "        <payload-type id='104' name='ISAC' clockrate='32000'/>  " \
 
869
     "      </description>                                            " \
 
870
     "     <transport xmlns='http://www.google.com/transport/p2p'/>   " \
 
871
     "    </content>                                                  " \
 
872
     "    <content name='video'>                                      " \
 
873
     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1'           " \
 
874
     "          media='video' ssrc='87654321'>                        " \
 
875
     "      </description>                                            " \
 
876
     "     <transport xmlns='http://www.google.com/transport/p2p'/>   " \
 
877
     "    </content>                                                  " \
 
878
     "    <content name='data'>                                       " \
 
879
     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1'           " \
 
880
     "          media='data' ssrc='1010101'>                          " \
 
881
     "      </description>                                            " \
 
882
     "     <transport xmlns='http://www.google.com/transport/p2p'/>   " \
 
883
     "    </content>                                                  " \
 
884
     "  </jingle>                                                     " \
 
885
     "</iq>                                                           ");
 
886
 
 
887
std::string JingleView(const std::string& ssrc,
 
888
                       const std::string& width,
 
889
                       const std::string& height,
 
890
                       const std::string& framerate) {
 
891
  // We have some slightly weird whitespace formatting to make the
 
892
  // actual XML generated match the expected XML here.
 
893
  return \
 
894
      "<cli:iq"
 
895
      "  to='me@mydomain.com'"
 
896
      "  type='set'"
 
897
      "  xmlns:cli='jabber:client'>"
 
898
        "<jingle"
 
899
      "    xmlns='urn:xmpp:jingle:1'"
 
900
      "    action='session-info'"
 
901
      "    sid=''>"
 
902
          "<view xmlns='google:jingle'"
 
903
      "      name='video'"
 
904
      "      type='static'"
 
905
      "      ssrc='" + ssrc + "'>"
 
906
            "<params"
 
907
      "        width='" + width + "'"
 
908
      "        height='" + height + "'"
 
909
      "        framerate='" + framerate + "'"
 
910
      "        preference='0'/>"
 
911
          "</view>"
 
912
        "</jingle>"
 
913
      "</cli:iq>";
 
914
}
 
915
 
 
916
std::string JingleStreamAdd(const std::string& content_name,
 
917
                            const std::string& nick,
 
918
                            const std::string& name,
 
919
                            const std::string& ssrc) {
 
920
  return \
 
921
      "<iq"
 
922
      "  xmlns='jabber:client'"
 
923
      "  from='me@mydomain.com'"
 
924
      "  to='user@domain.com/resource'"
 
925
      "  type='set'"
 
926
      "  id='150'>"
 
927
      "  <jingle"
 
928
      "    xmlns='urn:xmpp:jingle:1'"
 
929
      "    action='description-info'>"
 
930
      "    <content"
 
931
      "      xmlns='urn:xmpp:jingle:1'"
 
932
      "      name='" + content_name + "'>"
 
933
      "      <description"
 
934
      "        xmlns='urn:xmpp:jingle:apps:rtp:1'"
 
935
      "        media='" + content_name + "'>"
 
936
      "        <streams"
 
937
      "          xmlns='google:jingle'>"
 
938
      "          <stream"
 
939
      "            nick='" + nick + "'"
 
940
      "            name='" + name + "'>"
 
941
      "            <ssrc>"  + ssrc + "</ssrc>"
 
942
      "          </stream>"
 
943
      "        </streams>"
 
944
      "      </description>"
 
945
      "    </content>"
 
946
      "  </jingle>"
 
947
      "</iq>";
 
948
}
 
949
 
 
950
std::string JingleStreamAddWithoutSsrc(const std::string& content_name,
 
951
                                       const std::string& nick,
 
952
                                       const std::string& name) {
 
953
  return \
 
954
      "<iq"
 
955
      "  xmlns='jabber:client'"
 
956
      "  from='me@mydomain.com'"
 
957
      "  to='user@domain.com/resource'"
 
958
      "  type='set'"
 
959
      "  id='150'>"
 
960
      "  <jingle"
 
961
      "    xmlns='urn:xmpp:jingle:1'"
 
962
      "    action='description-info'>"
 
963
      "    <content"
 
964
      "      xmlns='urn:xmpp:jingle:1'"
 
965
      "      name='" + content_name + "'>"
 
966
      "      <description"
 
967
      "        xmlns='urn:xmpp:jingle:apps:rtp:1'"
 
968
      "        media='" + content_name + "'>"
 
969
      "        <streams"
 
970
      "          xmlns='google:jingle'>"
 
971
      "          <stream"
 
972
      "            nick='" + nick + "'"
 
973
      "            name='" + name + "'>"
 
974
       "          </stream>"
 
975
      "        </streams>"
 
976
      "      </description>"
 
977
      "    </content>"
 
978
      "  </jingle>"
 
979
      "</iq>";
 
980
}
 
981
 
 
982
std::string JingleStreamRemove(const std::string& content_name,
 
983
                               const std::string& nick,
 
984
                               const std::string& name) {
 
985
  return \
 
986
      "<iq"
 
987
      "  xmlns='jabber:client'"
 
988
      "  from='me@mydomain.com'"
 
989
      "  to='user@domain.com/resource'"
 
990
      "  type='set'"
 
991
      "  id='150'>"
 
992
      "  <jingle"
 
993
      "    xmlns='urn:xmpp:jingle:1'"
 
994
      "    action='description-info'>"
 
995
      "    <content"
 
996
      "      xmlns='urn:xmpp:jingle:1'"
 
997
      "      name='" + content_name + "'>"
 
998
      "      <description"
 
999
      "        xmlns='urn:xmpp:jingle:apps:rtp:1'"
 
1000
      "        media='" + content_name + "'>"
 
1001
      "        <streams"
 
1002
      "          xmlns='google:jingle'>"
 
1003
      "          <stream"
 
1004
      "            nick='" + nick + "'"
 
1005
      "            name='" + name + "'/>"
 
1006
      "        </streams>"
 
1007
      "      </description>"
 
1008
      "    </content>"
 
1009
      "  </jingle>"
 
1010
      "</iq>";
 
1011
}
 
1012
 
 
1013
buzz::XmlElement* CopyElement(const buzz::XmlElement* elem) {
 
1014
  return new buzz::XmlElement(*elem);
 
1015
}
 
1016
 
 
1017
static std::string AddEncryption(std::string stanza, std::string encryption) {
 
1018
  std::string::size_type pos = stanza.find("</description>");
 
1019
  while (pos != std::string::npos) {
 
1020
      stanza = stanza.insert(pos, encryption);
 
1021
      pos = stanza.find("</description>", pos + encryption.length() + 1);
 
1022
  }
 
1023
  return stanza;
 
1024
}
 
1025
 
 
1026
 
 
1027
int IntFromJingleCodecParameter(const buzz::XmlElement* parameter,
 
1028
                                const std::string& expected_name) {
 
1029
  if (parameter) {
 
1030
    const std::string& actual_name =
 
1031
        parameter->Attr(cricket::QN_PAYLOADTYPE_PARAMETER_NAME);
 
1032
 
 
1033
    EXPECT_EQ(expected_name, actual_name)
 
1034
        << "wrong parameter name.  Expected '"
 
1035
        << expected_name << "'. Actually '"
 
1036
        << actual_name << "'.";
 
1037
 
 
1038
    return atoi(parameter->Attr(
 
1039
        cricket::QN_PAYLOADTYPE_PARAMETER_VALUE).c_str());
 
1040
  }
 
1041
  return 0;
 
1042
}
 
1043
 
 
1044
// Parses and extracts payload and codec info from test XML.  Since
 
1045
// that XML will be in various contents (Gingle and Jingle), we need an
 
1046
// abstract parser with one concrete implementation per XML content.
 
1047
class MediaSessionTestParser {
 
1048
 public:
 
1049
  virtual buzz::XmlElement* ActionFromStanza(buzz::XmlElement* stanza) = 0;
 
1050
  virtual buzz::XmlElement* ContentFromAction(buzz::XmlElement* action) = 0;
 
1051
  virtual buzz::XmlElement* NextContent(buzz::XmlElement* content) = 0;
 
1052
  virtual buzz::XmlElement* PayloadTypeFromContent(
 
1053
      buzz::XmlElement* content) = 0;
 
1054
  virtual buzz::XmlElement* NextFromPayloadType(
 
1055
      buzz::XmlElement* payload_type) = 0;
 
1056
  virtual cricket::AudioCodec AudioCodecFromPayloadType(
 
1057
      const buzz::XmlElement* payload_type) = 0;
 
1058
  virtual cricket::VideoCodec VideoCodecFromPayloadType(
 
1059
      const buzz::XmlElement* payload_type) = 0;
 
1060
  virtual cricket::DataCodec DataCodecFromPayloadType(
 
1061
      const buzz::XmlElement* payload_type) = 0;
 
1062
  virtual buzz::XmlElement* EncryptionFromContent(
 
1063
      buzz::XmlElement* content) = 0;
 
1064
  virtual buzz::XmlElement* NextFromEncryption(
 
1065
      buzz::XmlElement* encryption) = 0;
 
1066
  virtual const buzz::XmlElement* BandwidthFromContent(
 
1067
      buzz::XmlElement* content) = 0;
 
1068
  virtual const buzz::XmlElement* RtcpMuxFromContent(
 
1069
      buzz::XmlElement* content) = 0;
 
1070
  virtual bool ActionIsTerminate(const buzz::XmlElement* action) = 0;
 
1071
  virtual ~MediaSessionTestParser() {}
 
1072
};
 
1073
 
 
1074
class JingleSessionTestParser : public MediaSessionTestParser {
 
1075
 public:
 
1076
  JingleSessionTestParser() : action_(NULL) {}
 
1077
 
 
1078
  ~JingleSessionTestParser() {
 
1079
    delete action_;
 
1080
  }
 
1081
 
 
1082
  buzz::XmlElement* ActionFromStanza(buzz::XmlElement* stanza) {
 
1083
    return stanza->FirstNamed(cricket::QN_JINGLE);
 
1084
  }
 
1085
 
 
1086
  buzz::XmlElement* ContentFromAction(buzz::XmlElement* action) {
 
1087
    // We need to be able to use multiple contents, but the action
 
1088
    // gets deleted before we can call NextContent, so we need to
 
1089
    // stash away a copy.
 
1090
    action_ = CopyElement(action);
 
1091
    return action_->FirstNamed(cricket::QN_JINGLE_CONTENT);
 
1092
  }
 
1093
 
 
1094
  buzz::XmlElement* NextContent(buzz::XmlElement* content) {
 
1095
    // For some reason, content->NextNamed(cricket::QN_JINGLE_CONTENT)
 
1096
    // doesn't work.
 
1097
    return action_->FirstNamed(cricket::QN_JINGLE_CONTENT)
 
1098
        ->NextNamed(cricket::QN_JINGLE_CONTENT);
 
1099
  }
 
1100
 
 
1101
  buzz::XmlElement* PayloadTypeFromContent(buzz::XmlElement* content) {
 
1102
    buzz::XmlElement* content_desc =
 
1103
        content->FirstNamed(cricket::QN_JINGLE_RTP_CONTENT);
 
1104
    if (!content_desc)
 
1105
      return NULL;
 
1106
 
 
1107
    return content_desc->FirstNamed(cricket::QN_JINGLE_RTP_PAYLOADTYPE);
 
1108
  }
 
1109
 
 
1110
  buzz::XmlElement* NextFromPayloadType(buzz::XmlElement* payload_type) {
 
1111
    return payload_type->NextNamed(cricket::QN_JINGLE_RTP_PAYLOADTYPE);
 
1112
  }
 
1113
 
 
1114
  cricket::AudioCodec AudioCodecFromPayloadType(
 
1115
      const buzz::XmlElement* payload_type) {
 
1116
    int id = 0;
 
1117
    if (payload_type->HasAttr(cricket::QN_ID))
 
1118
      id = atoi(payload_type->Attr(cricket::QN_ID).c_str());
 
1119
 
 
1120
    std::string name;
 
1121
    if (payload_type->HasAttr(cricket::QN_NAME))
 
1122
      name = payload_type->Attr(cricket::QN_NAME);
 
1123
 
 
1124
    int clockrate = 0;
 
1125
    if (payload_type->HasAttr(cricket::QN_CLOCKRATE))
 
1126
      clockrate = atoi(payload_type->Attr(cricket::QN_CLOCKRATE).c_str());
 
1127
 
 
1128
    int bitrate = IntFromJingleCodecParameter(
 
1129
        payload_type->FirstNamed(cricket::QN_PARAMETER), "bitrate");
 
1130
 
 
1131
    int channels = 1;
 
1132
    if (payload_type->HasAttr(cricket::QN_CHANNELS))
 
1133
      channels = atoi(payload_type->Attr(
 
1134
          cricket::QN_CHANNELS).c_str());
 
1135
 
 
1136
    return cricket::AudioCodec(id, name, clockrate, bitrate, channels, 0);
 
1137
  }
 
1138
 
 
1139
  cricket::VideoCodec VideoCodecFromPayloadType(
 
1140
      const buzz::XmlElement* payload_type) {
 
1141
    int id = 0;
 
1142
    if (payload_type->HasAttr(cricket::QN_ID))
 
1143
      id = atoi(payload_type->Attr(cricket::QN_ID).c_str());
 
1144
 
 
1145
    std::string name;
 
1146
    if (payload_type->HasAttr(cricket::QN_NAME))
 
1147
      name = payload_type->Attr(cricket::QN_NAME);
 
1148
 
 
1149
    int width = 0;
 
1150
    int height = 0;
 
1151
    int framerate = 0;
 
1152
    const buzz::XmlElement* param =
 
1153
        payload_type->FirstNamed(cricket::QN_PARAMETER);
 
1154
    if (param) {
 
1155
      width = IntFromJingleCodecParameter(param, "width");
 
1156
      param = param->NextNamed(cricket::QN_PARAMETER);
 
1157
      if (param) {
 
1158
        height = IntFromJingleCodecParameter(param, "height");
 
1159
        param = param->NextNamed(cricket::QN_PARAMETER);
 
1160
        if (param) {
 
1161
          framerate = IntFromJingleCodecParameter(param, "framerate");
 
1162
        }
 
1163
      }
 
1164
    }
 
1165
 
 
1166
    return cricket::VideoCodec(id, name, width, height, framerate, 0);
 
1167
  }
 
1168
 
 
1169
  cricket::DataCodec DataCodecFromPayloadType(
 
1170
      const buzz::XmlElement* payload_type) {
 
1171
    int id = 0;
 
1172
    if (payload_type->HasAttr(cricket::QN_ID))
 
1173
      id = atoi(payload_type->Attr(cricket::QN_ID).c_str());
 
1174
 
 
1175
    std::string name;
 
1176
    if (payload_type->HasAttr(cricket::QN_NAME))
 
1177
      name = payload_type->Attr(cricket::QN_NAME);
 
1178
 
 
1179
    return cricket::DataCodec(id, name, 0);
 
1180
  }
 
1181
 
 
1182
  bool ActionIsTerminate(const buzz::XmlElement* action) {
 
1183
    return (action->HasAttr(cricket::QN_ACTION) &&
 
1184
            action->Attr(cricket::QN_ACTION) == "session-terminate");
 
1185
  }
 
1186
 
 
1187
  buzz::XmlElement* EncryptionFromContent(buzz::XmlElement* content) {
 
1188
    buzz::XmlElement* content_desc =
 
1189
        content->FirstNamed(cricket::QN_JINGLE_RTP_CONTENT);
 
1190
    if (!content_desc)
 
1191
      return NULL;
 
1192
 
 
1193
    return content_desc->FirstNamed(cricket::QN_ENCRYPTION);
 
1194
  }
 
1195
 
 
1196
  buzz::XmlElement* NextFromEncryption(buzz::XmlElement* encryption) {
 
1197
    return encryption->NextNamed(cricket::QN_ENCRYPTION);
 
1198
  }
 
1199
 
 
1200
  const buzz::XmlElement* BandwidthFromContent(buzz::XmlElement* content) {
 
1201
    buzz::XmlElement* content_desc =
 
1202
        content->FirstNamed(cricket::QN_JINGLE_RTP_CONTENT);
 
1203
    if (!content_desc)
 
1204
      return NULL;
 
1205
 
 
1206
    return content_desc->FirstNamed(cricket::QN_JINGLE_RTP_BANDWIDTH);
 
1207
  }
 
1208
 
 
1209
  const buzz::XmlElement* RtcpMuxFromContent(buzz::XmlElement* content) {
 
1210
    return content->FirstNamed(cricket::QN_JINGLE_RTCP_MUX);
 
1211
  }
 
1212
 
 
1213
 private:
 
1214
  buzz::XmlElement* action_;
 
1215
};
 
1216
 
 
1217
class GingleSessionTestParser : public MediaSessionTestParser {
 
1218
 public:
 
1219
  GingleSessionTestParser() : found_content_count_(0) {}
 
1220
 
 
1221
  buzz::XmlElement* ActionFromStanza(buzz::XmlElement* stanza) {
 
1222
    return stanza->FirstNamed(cricket::QN_GINGLE_SESSION);
 
1223
  }
 
1224
 
 
1225
  buzz::XmlElement* ContentFromAction(buzz::XmlElement* session) {
 
1226
    buzz::XmlElement* content =
 
1227
        session->FirstNamed(cricket::QN_GINGLE_AUDIO_CONTENT);
 
1228
    if (content == NULL)
 
1229
      content = session->FirstNamed(cricket::QN_GINGLE_VIDEO_CONTENT);
 
1230
    return content;
 
1231
  }
 
1232
 
 
1233
  // Assumes contents are in order of audio, and then video.
 
1234
  buzz::XmlElement* NextContent(buzz::XmlElement* content) {
 
1235
    found_content_count_++;
 
1236
    return content;
 
1237
  }
 
1238
 
 
1239
  buzz::XmlElement* PayloadTypeFromContent(buzz::XmlElement* content) {
 
1240
    if (found_content_count_ > 0) {
 
1241
      return content->FirstNamed(cricket::QN_GINGLE_VIDEO_PAYLOADTYPE);
 
1242
    } else {
 
1243
      return content->FirstNamed(cricket::QN_GINGLE_AUDIO_PAYLOADTYPE);
 
1244
    }
 
1245
  }
 
1246
 
 
1247
  buzz::XmlElement* NextFromPayloadType(buzz::XmlElement* payload_type) {
 
1248
    if (found_content_count_ > 0) {
 
1249
      return payload_type->NextNamed(cricket::QN_GINGLE_VIDEO_PAYLOADTYPE);
 
1250
    } else {
 
1251
      return payload_type->NextNamed(cricket::QN_GINGLE_AUDIO_PAYLOADTYPE);
 
1252
    }
 
1253
  }
 
1254
 
 
1255
  cricket::AudioCodec AudioCodecFromPayloadType(
 
1256
      const buzz::XmlElement* payload_type) {
 
1257
    int id = 0;
 
1258
    if (payload_type->HasAttr(cricket::QN_ID))
 
1259
      id = atoi(payload_type->Attr(cricket::QN_ID).c_str());
 
1260
 
 
1261
    std::string name;
 
1262
    if (payload_type->HasAttr(cricket::QN_NAME))
 
1263
      name = payload_type->Attr(cricket::QN_NAME);
 
1264
 
 
1265
    int clockrate = 0;
 
1266
    if (payload_type->HasAttr(cricket::QN_CLOCKRATE))
 
1267
      clockrate = atoi(payload_type->Attr(cricket::QN_CLOCKRATE).c_str());
 
1268
 
 
1269
    int bitrate = 0;
 
1270
    if (payload_type->HasAttr(cricket::QN_BITRATE))
 
1271
      bitrate = atoi(payload_type->Attr(cricket::QN_BITRATE).c_str());
 
1272
 
 
1273
    int channels = 1;
 
1274
    if (payload_type->HasAttr(cricket::QN_CHANNELS))
 
1275
      channels = atoi(payload_type->Attr(cricket::QN_CHANNELS).c_str());
 
1276
 
 
1277
    return cricket::AudioCodec(id, name, clockrate, bitrate, channels, 0);
 
1278
  }
 
1279
 
 
1280
  cricket::VideoCodec VideoCodecFromPayloadType(
 
1281
      const buzz::XmlElement* payload_type) {
 
1282
    int id = 0;
 
1283
    if (payload_type->HasAttr(cricket::QN_ID))
 
1284
      id = atoi(payload_type->Attr(cricket::QN_ID).c_str());
 
1285
 
 
1286
    std::string name;
 
1287
    if (payload_type->HasAttr(cricket::QN_NAME))
 
1288
      name = payload_type->Attr(cricket::QN_NAME);
 
1289
 
 
1290
    int width = 0;
 
1291
    if (payload_type->HasAttr(cricket::QN_WIDTH))
 
1292
      width = atoi(payload_type->Attr(cricket::QN_WIDTH).c_str());
 
1293
 
 
1294
    int height = 0;
 
1295
    if (payload_type->HasAttr(cricket::QN_HEIGHT))
 
1296
      height = atoi(payload_type->Attr(cricket::QN_HEIGHT).c_str());
 
1297
 
 
1298
    int framerate = 1;
 
1299
    if (payload_type->HasAttr(cricket::QN_FRAMERATE))
 
1300
      framerate = atoi(payload_type->Attr(cricket::QN_FRAMERATE).c_str());
 
1301
 
 
1302
    return cricket::VideoCodec(id, name, width, height, framerate, 0);
 
1303
  }
 
1304
 
 
1305
  cricket::DataCodec DataCodecFromPayloadType(
 
1306
      const buzz::XmlElement* payload_type) {
 
1307
    // Gingle can't do data codecs.
 
1308
    return cricket::DataCodec(0, "", 0);
 
1309
  }
 
1310
 
 
1311
  buzz::XmlElement* EncryptionFromContent(
 
1312
      buzz::XmlElement* content) {
 
1313
    return content->FirstNamed(cricket::QN_ENCRYPTION);
 
1314
  }
 
1315
 
 
1316
  buzz::XmlElement* NextFromEncryption(buzz::XmlElement* encryption) {
 
1317
    return encryption->NextNamed(cricket::QN_ENCRYPTION);
 
1318
  }
 
1319
 
 
1320
  const buzz::XmlElement* BandwidthFromContent(buzz::XmlElement* content) {
 
1321
    return content->FirstNamed(cricket::QN_GINGLE_VIDEO_BANDWIDTH);
 
1322
  }
 
1323
 
 
1324
  const buzz::XmlElement* RtcpMuxFromContent(buzz::XmlElement* content) {
 
1325
    return NULL;
 
1326
  }
 
1327
 
 
1328
  bool ActionIsTerminate(const buzz::XmlElement* session) {
 
1329
    return (session->HasAttr(buzz::QN_TYPE) &&
 
1330
            session->Attr(buzz::QN_TYPE) == "terminate");
 
1331
  }
 
1332
 
 
1333
  int found_content_count_;
 
1334
};
 
1335
 
 
1336
class MediaSessionClientTest : public sigslot::has_slots<> {
 
1337
 public:
 
1338
  explicit MediaSessionClientTest(MediaSessionTestParser* parser,
 
1339
                                  cricket::SignalingProtocol initial_protocol) {
 
1340
    nm_ = new talk_base::BasicNetworkManager();
 
1341
    pa_ = new cricket::BasicPortAllocator(nm_);
 
1342
    sm_ = new cricket::SessionManager(pa_, NULL);
 
1343
    fme_ = new cricket::FakeMediaEngine();
 
1344
    fdme_ = new cricket::FakeDataEngine();
 
1345
 
 
1346
    std::vector<cricket::AudioCodec>
 
1347
        audio_codecs(kAudioCodecs, kAudioCodecs + ARRAY_SIZE(kAudioCodecs));
 
1348
    fme_->SetAudioCodecs(audio_codecs);
 
1349
    std::vector<cricket::VideoCodec>
 
1350
        video_codecs(kVideoCodecs, kVideoCodecs + ARRAY_SIZE(kVideoCodecs));
 
1351
    fme_->SetVideoCodecs(video_codecs);
 
1352
    std::vector<cricket::DataCodec>
 
1353
        data_codecs(kDataCodecs, kDataCodecs + ARRAY_SIZE(kDataCodecs));
 
1354
    fdme_->SetDataCodecs(data_codecs);
 
1355
 
 
1356
    client_ = new cricket::MediaSessionClient(
 
1357
        buzz::Jid("user@domain.com/resource"), sm_,
 
1358
        fme_, fdme_, new cricket::FakeDeviceManager());
 
1359
    client_->session_manager()->SignalOutgoingMessage.connect(
 
1360
        this, &MediaSessionClientTest::OnSendStanza);
 
1361
    client_->session_manager()->SignalSessionCreate.connect(
 
1362
        this, &MediaSessionClientTest::OnSessionCreate);
 
1363
    client_->SignalCallCreate.connect(
 
1364
        this, &MediaSessionClientTest::OnCallCreate);
 
1365
    client_->SignalCallDestroy.connect(
 
1366
        this, &MediaSessionClientTest::OnCallDestroy);
 
1367
 
 
1368
    call_ = NULL;
 
1369
    parser_ = parser;
 
1370
    initial_protocol_ = initial_protocol;
 
1371
    expect_incoming_crypto_ = false;
 
1372
    expect_outgoing_crypto_ = false;
 
1373
    expected_video_bandwidth_ = cricket::kAutoBandwidth;
 
1374
    expected_video_rtcp_mux_ = false;
 
1375
  }
 
1376
 
 
1377
  ~MediaSessionClientTest() {
 
1378
    delete client_;
 
1379
    delete sm_;
 
1380
    delete pa_;
 
1381
    delete nm_;
 
1382
    delete parser_;
 
1383
  }
 
1384
 
 
1385
  buzz::XmlElement* ActionFromStanza(buzz::XmlElement* stanza) {
 
1386
    return parser_->ActionFromStanza(stanza);
 
1387
  }
 
1388
 
 
1389
  buzz::XmlElement* ContentFromAction(buzz::XmlElement* action) {
 
1390
    return parser_->ContentFromAction(action);
 
1391
  }
 
1392
 
 
1393
  buzz::XmlElement* PayloadTypeFromContent(buzz::XmlElement* payload) {
 
1394
    return parser_->PayloadTypeFromContent(payload);
 
1395
  }
 
1396
 
 
1397
  buzz::XmlElement* NextFromPayloadType(buzz::XmlElement* payload_type) {
 
1398
    return parser_->NextFromPayloadType(payload_type);
 
1399
  }
 
1400
 
 
1401
  buzz::XmlElement* EncryptionFromContent(buzz::XmlElement* content) {
 
1402
    return parser_->EncryptionFromContent(content);
 
1403
  }
 
1404
 
 
1405
  buzz::XmlElement* NextFromEncryption(buzz::XmlElement* encryption) {
 
1406
    return parser_->NextFromEncryption(encryption);
 
1407
  }
 
1408
 
 
1409
  cricket::AudioCodec AudioCodecFromPayloadType(
 
1410
      const buzz::XmlElement* payload_type) {
 
1411
    return parser_->AudioCodecFromPayloadType(payload_type);
 
1412
  }
 
1413
 
 
1414
  const cricket::AudioContentDescription* GetFirstAudioContentDescription(
 
1415
      const cricket::SessionDescription* sdesc) {
 
1416
    const cricket::ContentInfo* content =
 
1417
        cricket::GetFirstAudioContent(sdesc);
 
1418
    if (content == NULL)
 
1419
      return NULL;
 
1420
    return static_cast<const cricket::AudioContentDescription*>(
 
1421
        content->description);
 
1422
  }
 
1423
 
 
1424
  const cricket::VideoContentDescription* GetFirstVideoContentDescription(
 
1425
      const cricket::SessionDescription* sdesc) {
 
1426
    const cricket::ContentInfo* content =
 
1427
        cricket::GetFirstVideoContent(sdesc);
 
1428
    if (content == NULL)
 
1429
      return NULL;
 
1430
    return static_cast<const cricket::VideoContentDescription*>(
 
1431
        content->description);
 
1432
  }
 
1433
 
 
1434
  void CheckCryptoFromGoodIncomingInitiate(const cricket::Session* session) {
 
1435
    ASSERT_TRUE(session != NULL);
 
1436
    const cricket::AudioContentDescription* content =
 
1437
        GetFirstAudioContentDescription(session->remote_description());
 
1438
    ASSERT_TRUE(content != NULL);
 
1439
    ASSERT_EQ(2U, content->cryptos().size());
 
1440
    ASSERT_EQ(145, content->cryptos()[0].tag);
 
1441
    ASSERT_EQ("AES_CM_128_HMAC_SHA1_32", content->cryptos()[0].cipher_suite);
 
1442
    ASSERT_EQ("inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9",
 
1443
              content->cryptos()[0].key_params);
 
1444
    ASSERT_EQ(51, content->cryptos()[1].tag);
 
1445
    ASSERT_EQ("AES_CM_128_HMAC_SHA1_80", content->cryptos()[1].cipher_suite);
 
1446
    ASSERT_EQ("inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy",
 
1447
              content->cryptos()[1].key_params);
 
1448
  }
 
1449
 
 
1450
  void CheckCryptoForGoodOutgoingAccept(const cricket::Session* session) {
 
1451
    const cricket::AudioContentDescription* content =
 
1452
        GetFirstAudioContentDescription(session->local_description());
 
1453
    ASSERT_EQ(1U, content->cryptos().size());
 
1454
    ASSERT_EQ(145, content->cryptos()[0].tag);
 
1455
    ASSERT_EQ("AES_CM_128_HMAC_SHA1_32", content->cryptos()[0].cipher_suite);
 
1456
    ASSERT_EQ(47U, content->cryptos()[0].key_params.size());
 
1457
  }
 
1458
 
 
1459
  void CheckBadCryptoFromIncomingInitiate(const cricket::Session* session) {
 
1460
    const cricket::AudioContentDescription* content =
 
1461
        GetFirstAudioContentDescription(session->remote_description());
 
1462
    ASSERT_EQ(1U, content->cryptos().size());
 
1463
    ASSERT_EQ(145, content->cryptos()[0].tag);
 
1464
    ASSERT_EQ("NOT_SUPPORTED", content->cryptos()[0].cipher_suite);
 
1465
    ASSERT_EQ("inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9",
 
1466
              content->cryptos()[0].key_params);
 
1467
  }
 
1468
 
 
1469
  void CheckNoCryptoForOutgoingAccept(const cricket::Session* session) {
 
1470
    const cricket::AudioContentDescription* content =
 
1471
        GetFirstAudioContentDescription(session->local_description());
 
1472
    ASSERT_TRUE(content->cryptos().empty());
 
1473
  }
 
1474
 
 
1475
  void CheckVideoBandwidth(int expected_bandwidth,
 
1476
                           const cricket::SessionDescription* sdesc) {
 
1477
    const cricket::VideoContentDescription* video =
 
1478
        GetFirstVideoContentDescription(sdesc);
 
1479
    if (video != NULL) {
 
1480
      ASSERT_EQ(expected_bandwidth, video->bandwidth());
 
1481
    }
 
1482
  }
 
1483
 
 
1484
  void CheckVideoRtcpMux(bool expected_video_rtcp_mux,
 
1485
                         const cricket::SessionDescription* sdesc) {
 
1486
    const cricket::VideoContentDescription* video =
 
1487
        GetFirstVideoContentDescription(sdesc);
 
1488
    if (video != NULL) {
 
1489
      ASSERT_EQ(expected_video_rtcp_mux, video->rtcp_mux());
 
1490
    }
 
1491
  }
 
1492
 
 
1493
  virtual void CheckDataContent(buzz::XmlElement* content) {
 
1494
    if (initial_protocol_) {
 
1495
      // Gingle can not write out data content.
 
1496
      return;
 
1497
    }
 
1498
 
 
1499
    buzz::XmlElement* e = PayloadTypeFromContent(content);
 
1500
    ASSERT_TRUE(e != NULL);
 
1501
    cricket::DataCodec codec = parser_->DataCodecFromPayloadType(e);
 
1502
    EXPECT_EQ(101, codec.id);
 
1503
    EXPECT_EQ("google-data", codec.name);
 
1504
 
 
1505
    CheckDataRtcpMux(true, call_->sessions()[0]->local_description());
 
1506
    CheckDataRtcpMux(true, call_->sessions()[0]->remote_description());
 
1507
    if (expect_outgoing_crypto_) {
 
1508
      content = parser_->NextContent(content);
 
1509
      buzz::XmlElement* encryption = EncryptionFromContent(content);
 
1510
      ASSERT_TRUE(encryption != NULL);
 
1511
      // TODO: Check encryption parameters?
 
1512
    }
 
1513
  }
 
1514
 
 
1515
  void CheckDataRtcpMux(bool expected_data_rtcp_mux,
 
1516
                        const cricket::SessionDescription* sdesc) {
 
1517
    const cricket::DataContentDescription* data =
 
1518
        GetFirstDataContentDescription(sdesc);
 
1519
    if (data != NULL) {
 
1520
      ASSERT_EQ(expected_data_rtcp_mux, data->rtcp_mux());
 
1521
    }
 
1522
  }
 
1523
 
 
1524
  void CheckAudioSsrcForIncomingAccept(const cricket::Session* session) {
 
1525
    const cricket::AudioContentDescription* audio =
 
1526
        GetFirstAudioContentDescription(session->remote_description());
 
1527
    ASSERT_TRUE(audio != NULL);
 
1528
    ASSERT_EQ(kAudioSsrc, audio->first_ssrc());
 
1529
  }
 
1530
 
 
1531
  void CheckVideoSsrcForIncomingAccept(const cricket::Session* session) {
 
1532
    const cricket::VideoContentDescription* video =
 
1533
        GetFirstVideoContentDescription(session->remote_description());
 
1534
    ASSERT_TRUE(video != NULL);
 
1535
    ASSERT_EQ(kVideoSsrc, video->first_ssrc());
 
1536
  }
 
1537
 
 
1538
  void CheckDataSsrcForIncomingAccept(const cricket::Session* session) {
 
1539
    const cricket::DataContentDescription* data =
 
1540
        GetFirstDataContentDescription(session->remote_description());
 
1541
    ASSERT_TRUE(data != NULL);
 
1542
    ASSERT_EQ(kDataSsrc, data->first_ssrc());
 
1543
  }
 
1544
 
 
1545
  void TestGoodIncomingInitiate(const std::string &initiate_string,
 
1546
                                buzz::XmlElement** element) {
 
1547
    *element = NULL;
 
1548
 
 
1549
    buzz::XmlElement* el = buzz::XmlElement::ForStr(initiate_string);
 
1550
    client_->session_manager()->OnIncomingMessage(el);
 
1551
    ASSERT_TRUE(call_ != NULL);
 
1552
    ASSERT_TRUE(call_->sessions()[0] != NULL);
 
1553
    ASSERT_EQ(cricket::Session::STATE_RECEIVEDINITIATE,
 
1554
              call_->sessions()[0]->state());
 
1555
    ASSERT_EQ(1U, stanzas_.size());
 
1556
    ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name());
 
1557
    ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE));
 
1558
    ASSERT_EQ(std::string(buzz::STR_RESULT), stanzas_[0]->Attr(buzz::QN_TYPE));
 
1559
    delete stanzas_[0];
 
1560
    stanzas_.clear();
 
1561
    CheckVideoBandwidth(expected_video_bandwidth_,
 
1562
                        call_->sessions()[0]->remote_description());
 
1563
    CheckVideoRtcpMux(expected_video_rtcp_mux_,
 
1564
                      call_->sessions()[0]->remote_description());
 
1565
    if (expect_incoming_crypto_) {
 
1566
      CheckCryptoFromGoodIncomingInitiate(call_->sessions()[0]);
 
1567
    }
 
1568
 
 
1569
    // TODO: Add tests for sending <bandwidth> in accept.
 
1570
    cricket::CallOptions opts;
 
1571
    opts.has_video = (GetFirstVideoContentDescription(
 
1572
        call_->sessions()[0]->remote_description()) != NULL);
 
1573
    opts.has_data = (GetFirstDataContentDescription(
 
1574
        call_->sessions()[0]->remote_description()) != NULL);
 
1575
    call_->AcceptSession(call_->sessions()[0], opts);
 
1576
    ASSERT_EQ(cricket::Session::STATE_SENTACCEPT,
 
1577
              call_->sessions()[0]->state());
 
1578
    ASSERT_EQ(1U, stanzas_.size());
 
1579
    ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name());
 
1580
    ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE));
 
1581
    ASSERT_EQ(std::string(buzz::STR_SET), stanzas_[0]->Attr(buzz::QN_TYPE));
 
1582
 
 
1583
    buzz::XmlElement* e = ActionFromStanza(stanzas_[0]);
 
1584
    ASSERT_TRUE(e != NULL);
 
1585
    ASSERT_TRUE(ContentFromAction(e) != NULL);
 
1586
    *element = CopyElement(ContentFromAction(e));
 
1587
    ASSERT_TRUE(*element != NULL);
 
1588
    delete stanzas_[0];
 
1589
    stanzas_.clear();
 
1590
    if (expect_outgoing_crypto_) {
 
1591
      CheckCryptoForGoodOutgoingAccept(call_->sessions()[0]);
 
1592
    }
 
1593
 
 
1594
    if (opts.has_data) {
 
1595
      CheckDataRtcpMux(true, call_->sessions()[0]->local_description());
 
1596
      CheckDataRtcpMux(true, call_->sessions()[0]->remote_description());
 
1597
      // TODO: Check rtcpmux and crypto?
 
1598
    }
 
1599
 
 
1600
    call_->Terminate();
 
1601
    ASSERT_EQ(cricket::Session::STATE_SENTTERMINATE,
 
1602
              call_->sessions()[0]->state());
 
1603
    ASSERT_EQ(1U, stanzas_.size());
 
1604
    ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name());
 
1605
    ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE));
 
1606
    ASSERT_EQ(std::string(buzz::STR_SET), stanzas_[0]->Attr(buzz::QN_TYPE));
 
1607
    e = ActionFromStanza(stanzas_[0]);
 
1608
    ASSERT_TRUE(e != NULL);
 
1609
    ASSERT_TRUE(parser_->ActionIsTerminate(e));
 
1610
    delete stanzas_[0];
 
1611
    stanzas_.clear();
 
1612
  }
 
1613
 
 
1614
  void TestBadIncomingInitiate(const std::string& initiate_string) {
 
1615
    buzz::XmlElement* el = buzz::XmlElement::ForStr(initiate_string);
 
1616
    client_->session_manager()->OnIncomingMessage(el);
 
1617
    ASSERT_TRUE(call_ != NULL);
 
1618
    ASSERT_TRUE(call_->sessions()[0] != NULL);
 
1619
    ASSERT_EQ(cricket::Session::STATE_SENTREJECT,
 
1620
              call_->sessions()[0]->state());
 
1621
    ASSERT_EQ(2U, stanzas_.size());
 
1622
    ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name());
 
1623
    ASSERT_TRUE(stanzas_[1]->HasAttr(buzz::QN_TYPE));
 
1624
    ASSERT_EQ(std::string(buzz::STR_RESULT), stanzas_[1]->Attr(buzz::QN_TYPE));
 
1625
    delete stanzas_[0];
 
1626
    stanzas_.clear();
 
1627
  }
 
1628
 
 
1629
  void TestGoodOutgoingInitiate() {
 
1630
    cricket::CallOptions options;
 
1631
    TestGoodOutgoingInitiate(options);
 
1632
  }
 
1633
 
 
1634
  void TestGoodOutgoingInitiate(const cricket::CallOptions& options) {
 
1635
    client_->CreateCall();
 
1636
    ASSERT_TRUE(call_ != NULL);
 
1637
    call_->InitiateSession(buzz::Jid("me@mydomain.com"), options);
 
1638
    ASSERT_TRUE(call_->sessions()[0] != NULL);
 
1639
    ASSERT_EQ(cricket::Session::STATE_SENTINITIATE,
 
1640
              call_->sessions()[0]->state());
 
1641
    ASSERT_EQ(1U, stanzas_.size());
 
1642
    ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name());
 
1643
    ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE));
 
1644
    ASSERT_EQ(std::string(buzz::STR_SET), stanzas_[0]->Attr(buzz::QN_TYPE));
 
1645
    buzz::XmlElement* action = ActionFromStanza(stanzas_[0]);
 
1646
    ASSERT_TRUE(action != NULL);
 
1647
    buzz::XmlElement* content = ContentFromAction(action);
 
1648
    ASSERT_TRUE(content != NULL);
 
1649
 
 
1650
    buzz::XmlElement* e = PayloadTypeFromContent(content);
 
1651
    ASSERT_TRUE(e != NULL);
 
1652
    cricket::AudioCodec codec = AudioCodecFromPayloadType(e);
 
1653
    ASSERT_EQ(103, codec.id);
 
1654
    ASSERT_EQ("ISAC", codec.name);
 
1655
    ASSERT_EQ(16000, codec.clockrate);
 
1656
    ASSERT_EQ(0, codec.bitrate);
 
1657
    ASSERT_EQ(1, codec.channels);
 
1658
 
 
1659
    e = NextFromPayloadType(e);
 
1660
    ASSERT_TRUE(e != NULL);
 
1661
    codec = AudioCodecFromPayloadType(e);
 
1662
    ASSERT_EQ(104, codec.id);
 
1663
    ASSERT_EQ("ISAC", codec.name);
 
1664
    ASSERT_EQ(32000, codec.clockrate);
 
1665
    ASSERT_EQ(0, codec.bitrate);
 
1666
    ASSERT_EQ(1, codec.channels);
 
1667
 
 
1668
    e = NextFromPayloadType(e);
 
1669
    ASSERT_TRUE(e != NULL);
 
1670
    codec = AudioCodecFromPayloadType(e);
 
1671
    ASSERT_EQ(119, codec.id);
 
1672
    ASSERT_EQ("ISACLC", codec.name);
 
1673
    ASSERT_EQ(16000, codec.clockrate);
 
1674
    ASSERT_EQ(40000, codec.bitrate);
 
1675
    ASSERT_EQ(1, codec.channels);
 
1676
 
 
1677
    e = NextFromPayloadType(e);
 
1678
    ASSERT_TRUE(e != NULL);
 
1679
    codec = AudioCodecFromPayloadType(e);
 
1680
    ASSERT_EQ(99, codec.id);
 
1681
    ASSERT_EQ("speex", codec.name);
 
1682
    ASSERT_EQ(16000, codec.clockrate);
 
1683
    ASSERT_EQ(22000, codec.bitrate);
 
1684
    ASSERT_EQ(1, codec.channels);
 
1685
 
 
1686
    e = NextFromPayloadType(e);
 
1687
    ASSERT_TRUE(e != NULL);
 
1688
    codec = AudioCodecFromPayloadType(e);
 
1689
    ASSERT_EQ(97, codec.id);
 
1690
    ASSERT_EQ("IPCMWB", codec.name);
 
1691
    ASSERT_EQ(16000, codec.clockrate);
 
1692
    ASSERT_EQ(80000, codec.bitrate);
 
1693
    ASSERT_EQ(1, codec.channels);
 
1694
 
 
1695
     e = NextFromPayloadType(e);
 
1696
    ASSERT_TRUE(e != NULL);
 
1697
    codec = AudioCodecFromPayloadType(e);
 
1698
    ASSERT_EQ(9, codec.id);
 
1699
    ASSERT_EQ("G722", codec.name);
 
1700
    ASSERT_EQ(16000, codec.clockrate);
 
1701
    ASSERT_EQ(64000, codec.bitrate);
 
1702
    ASSERT_EQ(1, codec.channels);
 
1703
 
 
1704
    e = NextFromPayloadType(e);
 
1705
    ASSERT_TRUE(e != NULL);
 
1706
    codec = AudioCodecFromPayloadType(e);
 
1707
    ASSERT_EQ(102, codec.id);
 
1708
    ASSERT_EQ("iLBC", codec.name);
 
1709
    ASSERT_EQ(8000, codec.clockrate);
 
1710
    ASSERT_EQ(13300, codec.bitrate);
 
1711
    ASSERT_EQ(1, codec.channels);
 
1712
 
 
1713
    e = NextFromPayloadType(e);
 
1714
    ASSERT_TRUE(e != NULL);
 
1715
    codec = AudioCodecFromPayloadType(e);
 
1716
    ASSERT_EQ(98, codec.id);
 
1717
    ASSERT_EQ("speex", codec.name);
 
1718
    ASSERT_EQ(8000, codec.clockrate);
 
1719
    ASSERT_EQ(11000, codec.bitrate);
 
1720
    ASSERT_EQ(1, codec.channels);
 
1721
 
 
1722
    e = NextFromPayloadType(e);
 
1723
    ASSERT_TRUE(e != NULL);
 
1724
    codec = AudioCodecFromPayloadType(e);
 
1725
    ASSERT_EQ(3, codec.id);
 
1726
    ASSERT_EQ("GSM", codec.name);
 
1727
    ASSERT_EQ(8000, codec.clockrate);
 
1728
    ASSERT_EQ(13000, codec.bitrate);
 
1729
    ASSERT_EQ(1, codec.channels);
 
1730
 
 
1731
    e = NextFromPayloadType(e);
 
1732
    ASSERT_TRUE(e != NULL);
 
1733
    codec = AudioCodecFromPayloadType(e);
 
1734
    ASSERT_EQ(100, codec.id);
 
1735
    ASSERT_EQ("EG711U", codec.name);
 
1736
    ASSERT_EQ(8000, codec.clockrate);
 
1737
    ASSERT_EQ(64000, codec.bitrate);
 
1738
    ASSERT_EQ(1, codec.channels);
 
1739
 
 
1740
    e = NextFromPayloadType(e);
 
1741
    ASSERT_TRUE(e != NULL);
 
1742
    codec = AudioCodecFromPayloadType(e);
 
1743
    ASSERT_EQ(101, codec.id);
 
1744
    ASSERT_EQ("EG711A", codec.name);
 
1745
    ASSERT_EQ(8000, codec.clockrate);
 
1746
    ASSERT_EQ(64000, codec.bitrate);
 
1747
    ASSERT_EQ(1, codec.channels);
 
1748
 
 
1749
    e = NextFromPayloadType(e);
 
1750
    ASSERT_TRUE(e != NULL);
 
1751
    codec = AudioCodecFromPayloadType(e);
 
1752
    ASSERT_EQ(0, codec.id);
 
1753
    ASSERT_EQ("PCMU", codec.name);
 
1754
    ASSERT_EQ(8000, codec.clockrate);
 
1755
    ASSERT_EQ(64000, codec.bitrate);
 
1756
    ASSERT_EQ(1, codec.channels);
 
1757
 
 
1758
    e = NextFromPayloadType(e);
 
1759
    ASSERT_TRUE(e != NULL);
 
1760
    codec = AudioCodecFromPayloadType(e);
 
1761
    ASSERT_EQ(8, codec.id);
 
1762
    ASSERT_EQ("PCMA", codec.name);
 
1763
    ASSERT_EQ(8000, codec.clockrate);
 
1764
    ASSERT_EQ(64000, codec.bitrate);
 
1765
    ASSERT_EQ(1, codec.channels);
 
1766
 
 
1767
    e = NextFromPayloadType(e);
 
1768
    ASSERT_TRUE(e != NULL);
 
1769
    codec = AudioCodecFromPayloadType(e);
 
1770
    ASSERT_EQ(126, codec.id);
 
1771
    ASSERT_EQ("CN", codec.name);
 
1772
    ASSERT_EQ(32000, codec.clockrate);
 
1773
    ASSERT_EQ(1, codec.channels);
 
1774
 
 
1775
    e = NextFromPayloadType(e);
 
1776
    ASSERT_TRUE(e != NULL);
 
1777
    codec = AudioCodecFromPayloadType(e);
 
1778
    ASSERT_EQ(105, codec.id);
 
1779
    ASSERT_EQ("CN", codec.name);
 
1780
    ASSERT_EQ(16000, codec.clockrate);
 
1781
    ASSERT_EQ(1, codec.channels);
 
1782
 
 
1783
    e = NextFromPayloadType(e);
 
1784
    ASSERT_TRUE(e != NULL);
 
1785
    codec = AudioCodecFromPayloadType(e);
 
1786
    ASSERT_EQ(13, codec.id);
 
1787
    ASSERT_EQ("CN", codec.name);
 
1788
    ASSERT_EQ(8000, codec.clockrate);
 
1789
    ASSERT_EQ(1, codec.channels);
 
1790
 
 
1791
    e = NextFromPayloadType(e);
 
1792
    ASSERT_TRUE(e != NULL);
 
1793
    codec = AudioCodecFromPayloadType(e);
 
1794
    ASSERT_EQ(117, codec.id);
 
1795
    ASSERT_EQ("red", codec.name);
 
1796
    ASSERT_EQ(8000, codec.clockrate);
 
1797
    ASSERT_EQ(1, codec.channels);
 
1798
 
 
1799
    e = NextFromPayloadType(e);
 
1800
    ASSERT_TRUE(e != NULL);
 
1801
    codec = AudioCodecFromPayloadType(e);
 
1802
    ASSERT_EQ(106, codec.id);
 
1803
    ASSERT_EQ("telephone-event", codec.name);
 
1804
    ASSERT_EQ(8000, codec.clockrate);
 
1805
    ASSERT_EQ(1, codec.channels);
 
1806
 
 
1807
    e = NextFromPayloadType(e);
 
1808
    ASSERT_TRUE(e == NULL);
 
1809
 
 
1810
    if (expect_outgoing_crypto_) {
 
1811
      buzz::XmlElement* encryption = EncryptionFromContent(content);
 
1812
      ASSERT_TRUE(encryption != NULL);
 
1813
 
 
1814
      if (client_->secure() == cricket::SEC_REQUIRED) {
 
1815
        ASSERT_TRUE(cricket::GetXmlAttr(
 
1816
            encryption, cricket::QN_ENCRYPTION_REQUIRED, false));
 
1817
      }
 
1818
 
 
1819
      if (content->Name().Namespace() == cricket::NS_GINGLE_AUDIO) {
 
1820
        e = encryption->FirstNamed(cricket::QN_GINGLE_AUDIO_CRYPTO_USAGE);
 
1821
        ASSERT_TRUE(e != NULL);
 
1822
        ASSERT_TRUE(
 
1823
            e->NextNamed(cricket::QN_GINGLE_AUDIO_CRYPTO_USAGE) == NULL);
 
1824
        ASSERT_TRUE(
 
1825
            e->FirstNamed(cricket::QN_GINGLE_VIDEO_CRYPTO_USAGE) == NULL);
 
1826
      }
 
1827
 
 
1828
      e = encryption->FirstNamed(cricket::QN_CRYPTO);
 
1829
      ASSERT_TRUE(e != NULL);
 
1830
      ASSERT_EQ("0", e->Attr(cricket::QN_CRYPTO_TAG));
 
1831
      ASSERT_EQ("AES_CM_128_HMAC_SHA1_32", e->Attr(cricket::QN_CRYPTO_SUITE));
 
1832
      std::string key_0 = e->Attr(cricket::QN_CRYPTO_KEY_PARAMS);
 
1833
      ASSERT_EQ(47U, key_0.length());
 
1834
      ASSERT_EQ("inline:", key_0.substr(0, 7));
 
1835
 
 
1836
      e = e->NextNamed(cricket::QN_CRYPTO);
 
1837
      ASSERT_TRUE(e != NULL);
 
1838
      ASSERT_EQ("1", e->Attr(cricket::QN_CRYPTO_TAG));
 
1839
      ASSERT_EQ("AES_CM_128_HMAC_SHA1_80", e->Attr(cricket::QN_CRYPTO_SUITE));
 
1840
      std::string key_1 = e->Attr(cricket::QN_CRYPTO_KEY_PARAMS);
 
1841
      ASSERT_EQ(47U, key_1.length());
 
1842
      ASSERT_EQ("inline:", key_1.substr(0, 7));
 
1843
      ASSERT_NE(key_0, key_1);
 
1844
 
 
1845
      encryption = NextFromEncryption(encryption);
 
1846
      ASSERT_TRUE(encryption == NULL);
 
1847
    }
 
1848
 
 
1849
    if (options.has_video) {
 
1850
      CheckVideoBandwidth(options.video_bandwidth,
 
1851
                          call_->sessions()[0]->local_description());
 
1852
      CheckVideoRtcpMux(expected_video_rtcp_mux_,
 
1853
                        call_->sessions()[0]->remote_description());
 
1854
      content = parser_->NextContent(content);
 
1855
      const buzz::XmlElement* bandwidth =
 
1856
          parser_->BandwidthFromContent(content);
 
1857
      if (options.video_bandwidth == cricket::kAutoBandwidth) {
 
1858
        ASSERT_TRUE(bandwidth == NULL);
 
1859
      } else {
 
1860
        ASSERT_TRUE(bandwidth != NULL);
 
1861
        ASSERT_EQ("AS", bandwidth->Attr(buzz::QName("", "type")));
 
1862
        ASSERT_EQ(talk_base::ToString(options.video_bandwidth / 1000),
 
1863
                  bandwidth->BodyText());
 
1864
      }
 
1865
    }
 
1866
 
 
1867
    if (options.has_data) {
 
1868
      content = parser_->NextContent(content);
 
1869
      CheckDataContent(content);
 
1870
    }
 
1871
 
 
1872
    delete stanzas_[0];
 
1873
    stanzas_.clear();
 
1874
  }
 
1875
 
 
1876
  void TestHasAllSupportedAudioCodecs(buzz::XmlElement* e) {
 
1877
    ASSERT_TRUE(e != NULL);
 
1878
 
 
1879
    e = PayloadTypeFromContent(e);
 
1880
    ASSERT_TRUE(e != NULL);
 
1881
    cricket::AudioCodec codec = AudioCodecFromPayloadType(e);
 
1882
    ASSERT_EQ(103, codec.id);
 
1883
    ASSERT_EQ("ISAC", codec.name);
 
1884
    ASSERT_EQ(16000, codec.clockrate);
 
1885
    ASSERT_EQ(1, codec.channels);
 
1886
 
 
1887
    e = NextFromPayloadType(e);
 
1888
    ASSERT_TRUE(e != NULL);
 
1889
    codec = AudioCodecFromPayloadType(e);
 
1890
    ASSERT_EQ(104, codec.id);
 
1891
    ASSERT_EQ("ISAC", codec.name);
 
1892
    ASSERT_EQ(32000, codec.clockrate);
 
1893
    ASSERT_EQ(1, codec.channels);
 
1894
 
 
1895
    e = NextFromPayloadType(e);
 
1896
    ASSERT_TRUE(e != NULL);
 
1897
    codec = AudioCodecFromPayloadType(e);
 
1898
    ASSERT_EQ(119, codec.id);
 
1899
    ASSERT_EQ("ISACLC", codec.name);
 
1900
    ASSERT_EQ(16000, codec.clockrate);
 
1901
    ASSERT_EQ(40000, codec.bitrate);
 
1902
    ASSERT_EQ(1, codec.channels);
 
1903
 
 
1904
    e = NextFromPayloadType(e);
 
1905
    ASSERT_TRUE(e != NULL);
 
1906
    codec = AudioCodecFromPayloadType(e);
 
1907
    ASSERT_EQ(99, codec.id);
 
1908
    ASSERT_EQ("speex", codec.name);
 
1909
    ASSERT_EQ(16000, codec.clockrate);
 
1910
    ASSERT_EQ(22000, codec.bitrate);
 
1911
    ASSERT_EQ(1, codec.channels);
 
1912
 
 
1913
    e = NextFromPayloadType(e);
 
1914
    ASSERT_TRUE(e != NULL);
 
1915
    codec = AudioCodecFromPayloadType(e);
 
1916
    ASSERT_EQ(97, codec.id);
 
1917
    ASSERT_EQ("IPCMWB", codec.name);
 
1918
    ASSERT_EQ(16000, codec.clockrate);
 
1919
    ASSERT_EQ(80000, codec.bitrate);
 
1920
    ASSERT_EQ(1, codec.channels);
 
1921
 
 
1922
    e = NextFromPayloadType(e);
 
1923
    ASSERT_TRUE(e != NULL);
 
1924
    codec = AudioCodecFromPayloadType(e);
 
1925
    ASSERT_EQ(9, codec.id);
 
1926
    ASSERT_EQ("G722", codec.name);
 
1927
    ASSERT_EQ(16000, codec.clockrate);
 
1928
    ASSERT_EQ(64000, codec.bitrate);
 
1929
    ASSERT_EQ(1, codec.channels);
 
1930
 
 
1931
    e = NextFromPayloadType(e);
 
1932
    ASSERT_TRUE(e != NULL);
 
1933
    codec = AudioCodecFromPayloadType(e);
 
1934
    ASSERT_EQ(102, codec.id);
 
1935
    ASSERT_EQ("iLBC", codec.name);
 
1936
    ASSERT_EQ(8000, codec.clockrate);
 
1937
    ASSERT_EQ(13300, codec.bitrate);
 
1938
    ASSERT_EQ(1, codec.channels);
 
1939
 
 
1940
    e = NextFromPayloadType(e);
 
1941
    ASSERT_TRUE(e != NULL);
 
1942
    codec = AudioCodecFromPayloadType(e);
 
1943
    ASSERT_EQ(98, codec.id);
 
1944
    ASSERT_EQ("speex", codec.name);
 
1945
    ASSERT_EQ(8000, codec.clockrate);
 
1946
    ASSERT_EQ(11000, codec.bitrate);
 
1947
    ASSERT_EQ(1, codec.channels);
 
1948
 
 
1949
    e = NextFromPayloadType(e);
 
1950
    ASSERT_TRUE(e != NULL);
 
1951
    codec = AudioCodecFromPayloadType(e);
 
1952
    ASSERT_EQ(3, codec.id);
 
1953
    ASSERT_EQ("GSM", codec.name);
 
1954
    ASSERT_EQ(8000, codec.clockrate);
 
1955
    ASSERT_EQ(13000, codec.bitrate);
 
1956
    ASSERT_EQ(1, codec.channels);
 
1957
 
 
1958
    e = NextFromPayloadType(e);
 
1959
    ASSERT_TRUE(e != NULL);
 
1960
    codec = AudioCodecFromPayloadType(e);
 
1961
    ASSERT_EQ(100, codec.id);
 
1962
    ASSERT_EQ("EG711U", codec.name);
 
1963
    ASSERT_EQ(8000, codec.clockrate);
 
1964
    ASSERT_EQ(64000, codec.bitrate);
 
1965
    ASSERT_EQ(1, codec.channels);
 
1966
 
 
1967
    e = NextFromPayloadType(e);
 
1968
    ASSERT_TRUE(e != NULL);
 
1969
    codec = AudioCodecFromPayloadType(e);
 
1970
    ASSERT_EQ(101, codec.id);
 
1971
    ASSERT_EQ("EG711A", codec.name);
 
1972
    ASSERT_EQ(8000, codec.clockrate);
 
1973
    ASSERT_EQ(64000, codec.bitrate);
 
1974
    ASSERT_EQ(1, codec.channels);
 
1975
 
 
1976
    e = NextFromPayloadType(e);
 
1977
    ASSERT_TRUE(e != NULL);
 
1978
    codec = AudioCodecFromPayloadType(e);
 
1979
    ASSERT_EQ(0, codec.id);
 
1980
    ASSERT_EQ("PCMU", codec.name);
 
1981
    ASSERT_EQ(8000, codec.clockrate);
 
1982
    ASSERT_EQ(64000, codec.bitrate);
 
1983
    ASSERT_EQ(1, codec.channels);
 
1984
 
 
1985
    e = NextFromPayloadType(e);
 
1986
    ASSERT_TRUE(e != NULL);
 
1987
    codec = AudioCodecFromPayloadType(e);
 
1988
    ASSERT_EQ(8, codec.id);
 
1989
    ASSERT_EQ("PCMA", codec.name);
 
1990
    ASSERT_EQ(8000, codec.clockrate);
 
1991
    ASSERT_EQ(64000, codec.bitrate);
 
1992
    ASSERT_EQ(1, codec.channels);
 
1993
 
 
1994
    e = NextFromPayloadType(e);
 
1995
    ASSERT_TRUE(e != NULL);
 
1996
    codec = AudioCodecFromPayloadType(e);
 
1997
    ASSERT_EQ(126, codec.id);
 
1998
    ASSERT_EQ("CN", codec.name);
 
1999
    ASSERT_EQ(32000, 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(105, codec.id);
 
2006
    ASSERT_EQ("CN", codec.name);
 
2007
    ASSERT_EQ(16000, 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(13, codec.id);
 
2014
    ASSERT_EQ("CN", 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
    codec = AudioCodecFromPayloadType(e);
 
2021
    ASSERT_EQ(117, codec.id);
 
2022
    ASSERT_EQ("red", codec.name);
 
2023
    ASSERT_EQ(8000, codec.clockrate);
 
2024
    ASSERT_EQ(1, codec.channels);
 
2025
 
 
2026
    e = NextFromPayloadType(e);
 
2027
    ASSERT_TRUE(e != NULL);
 
2028
    codec = AudioCodecFromPayloadType(e);
 
2029
    ASSERT_EQ(106, codec.id);
 
2030
    ASSERT_EQ("telephone-event", codec.name);
 
2031
    ASSERT_EQ(8000, codec.clockrate);
 
2032
    ASSERT_EQ(1, codec.channels);
 
2033
 
 
2034
    e = NextFromPayloadType(e);
 
2035
    ASSERT_TRUE(e == NULL);
 
2036
  }
 
2037
 
 
2038
  void TestCodecsOfVideoInitiate(buzz::XmlElement* content) {
 
2039
    ASSERT_TRUE(content != NULL);
 
2040
    buzz::XmlElement* payload_type = PayloadTypeFromContent(content);
 
2041
    ASSERT_TRUE(payload_type != NULL);
 
2042
    cricket::AudioCodec codec = AudioCodecFromPayloadType(payload_type);
 
2043
    ASSERT_EQ(103, codec.id);
 
2044
    ASSERT_EQ("ISAC", codec.name);
 
2045
    ASSERT_EQ(16000, codec.clockrate);
 
2046
    ASSERT_EQ(1, codec.channels);
 
2047
 
 
2048
    content = parser_->NextContent(content);
 
2049
    ASSERT_TRUE(content != NULL);
 
2050
    payload_type = PayloadTypeFromContent(content);
 
2051
    ASSERT_TRUE(payload_type != NULL);
 
2052
    cricket::VideoCodec vcodec =
 
2053
        parser_->VideoCodecFromPayloadType(payload_type);
 
2054
    ASSERT_EQ(99, vcodec.id);
 
2055
    ASSERT_EQ("H264-SVC", vcodec.name);
 
2056
    ASSERT_EQ(320, vcodec.width);
 
2057
    ASSERT_EQ(200, vcodec.height);
 
2058
    ASSERT_EQ(30, vcodec.framerate);
 
2059
  }
 
2060
 
 
2061
  void TestHasAudioCodecsFromInitiateSomeUnsupported(buzz::XmlElement* e) {
 
2062
    ASSERT_TRUE(e != NULL);
 
2063
    e = PayloadTypeFromContent(e);
 
2064
    ASSERT_TRUE(e != NULL);
 
2065
 
 
2066
    cricket::AudioCodec codec = AudioCodecFromPayloadType(e);
 
2067
    ASSERT_EQ(103, codec.id);
 
2068
    ASSERT_EQ("ISAC", codec.name);
 
2069
    ASSERT_EQ(16000, codec.clockrate);
 
2070
    ASSERT_EQ(1, codec.channels);
 
2071
 
 
2072
    e = NextFromPayloadType(e);
 
2073
    ASSERT_TRUE(e != NULL);
 
2074
    codec = AudioCodecFromPayloadType(e);
 
2075
    ASSERT_EQ(100, codec.id);
 
2076
    ASSERT_EQ("EG711U", codec.name);
 
2077
 
 
2078
    e = NextFromPayloadType(e);
 
2079
    ASSERT_TRUE(e != NULL);
 
2080
    codec = AudioCodecFromPayloadType(e);
 
2081
    ASSERT_EQ(101, codec.id);
 
2082
    ASSERT_EQ("EG711A", codec.name);
 
2083
 
 
2084
    e = NextFromPayloadType(e);
 
2085
    ASSERT_TRUE(e != NULL);
 
2086
    codec = AudioCodecFromPayloadType(e);
 
2087
    ASSERT_EQ(0, codec.id);
 
2088
    ASSERT_EQ("PCMU", codec.name);
 
2089
 
 
2090
    e = NextFromPayloadType(e);
 
2091
    ASSERT_TRUE(e != NULL);
 
2092
    codec = AudioCodecFromPayloadType(e);
 
2093
    ASSERT_EQ(13, codec.id);
 
2094
    ASSERT_EQ("CN", codec.name);
 
2095
 
 
2096
    e = NextFromPayloadType(e);
 
2097
    ASSERT_TRUE(e == NULL);
 
2098
  }
 
2099
 
 
2100
  void TestHasAudioCodecsFromInitiateDynamicAudioCodecs(
 
2101
      buzz::XmlElement* e) {
 
2102
    ASSERT_TRUE(e != NULL);
 
2103
    e = PayloadTypeFromContent(e);
 
2104
    ASSERT_TRUE(e != NULL);
 
2105
 
 
2106
    cricket::AudioCodec codec = AudioCodecFromPayloadType(e);
 
2107
    ASSERT_EQ(123, codec.id);
 
2108
    ASSERT_EQ(16000, codec.clockrate);
 
2109
    ASSERT_EQ(1, codec.channels);
 
2110
 
 
2111
    e = NextFromPayloadType(e);
 
2112
    ASSERT_TRUE(e == NULL);
 
2113
  }
 
2114
 
 
2115
  void TestHasDefaultAudioCodecs(buzz::XmlElement* e) {
 
2116
    ASSERT_TRUE(e != NULL);
 
2117
    e = PayloadTypeFromContent(e);
 
2118
    ASSERT_TRUE(e != NULL);
 
2119
 
 
2120
    cricket::AudioCodec codec = AudioCodecFromPayloadType(e);
 
2121
    ASSERT_EQ(103, codec.id);
 
2122
    ASSERT_EQ("ISAC", codec.name);
 
2123
 
 
2124
    e = NextFromPayloadType(e);
 
2125
    ASSERT_TRUE(e != NULL);
 
2126
    codec = AudioCodecFromPayloadType(e);
 
2127
    ASSERT_EQ(0, codec.id);
 
2128
    ASSERT_EQ("PCMU", codec.name);
 
2129
 
 
2130
    e = NextFromPayloadType(e);
 
2131
    ASSERT_TRUE(e == NULL);
 
2132
  }
 
2133
 
 
2134
  void TestHasAudioCodecsFromInitiateStaticAudioCodecs(
 
2135
      buzz::XmlElement* e) {
 
2136
    ASSERT_TRUE(e != NULL);
 
2137
    e = PayloadTypeFromContent(e);
 
2138
    ASSERT_TRUE(e != NULL);
 
2139
 
 
2140
    cricket::AudioCodec codec = AudioCodecFromPayloadType(e);
 
2141
    ASSERT_EQ(3, codec.id);
 
2142
 
 
2143
    e = NextFromPayloadType(e);
 
2144
    ASSERT_TRUE(e != NULL);
 
2145
    codec = AudioCodecFromPayloadType(e);
 
2146
    ASSERT_EQ(0, codec.id);
 
2147
 
 
2148
    e = NextFromPayloadType(e);
 
2149
    ASSERT_TRUE(e != NULL);
 
2150
    codec = AudioCodecFromPayloadType(e);
 
2151
    ASSERT_EQ(8, codec.id);
 
2152
 
 
2153
    e = NextFromPayloadType(e);
 
2154
    ASSERT_TRUE(e == NULL);
 
2155
  }
 
2156
 
 
2157
  void TestGingleInitiateWithUnsupportedCrypto(
 
2158
      const std::string &initiate_string,
 
2159
      buzz::XmlElement** element) {
 
2160
    *element = NULL;
 
2161
 
 
2162
    buzz::XmlElement* el = buzz::XmlElement::ForStr(initiate_string);
 
2163
    client_->session_manager()->OnIncomingMessage(el);
 
2164
 
 
2165
    ASSERT_EQ(cricket::Session::STATE_RECEIVEDINITIATE,
 
2166
              call_->sessions()[0]->state());
 
2167
    delete stanzas_[0];
 
2168
    stanzas_.clear();
 
2169
    CheckBadCryptoFromIncomingInitiate(call_->sessions()[0]);
 
2170
 
 
2171
    call_->AcceptSession(call_->sessions()[0], cricket::CallOptions());
 
2172
    delete stanzas_[0];
 
2173
    stanzas_.clear();
 
2174
    CheckNoCryptoForOutgoingAccept(call_->sessions()[0]);
 
2175
 
 
2176
    call_->Terminate();
 
2177
    ASSERT_EQ(cricket::Session::STATE_SENTTERMINATE,
 
2178
              call_->sessions()[0]->state());
 
2179
    delete stanzas_[0];
 
2180
    stanzas_.clear();
 
2181
  }
 
2182
 
 
2183
  void TestIncomingAcceptWithSsrcs(
 
2184
      const std::string& accept_string, bool has_data) {
 
2185
    client_->CreateCall();
 
2186
    ASSERT_TRUE(call_ != NULL);
 
2187
 
 
2188
    cricket::CallOptions options;
 
2189
    options.has_video = true;
 
2190
    options.has_data = has_data;
 
2191
    options.is_muc = true;
 
2192
 
 
2193
    call_->InitiateSession(buzz::Jid("me@mydomain.com"), options);
 
2194
    ASSERT_TRUE(call_->sessions()[0] != NULL);
 
2195
    ASSERT_EQ(cricket::Session::STATE_SENTINITIATE,
 
2196
              call_->sessions()[0]->state());
 
2197
    ASSERT_EQ(1U, stanzas_.size());
 
2198
    ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name());
 
2199
    ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE));
 
2200
    ASSERT_EQ(std::string(buzz::STR_SET), stanzas_[0]->Attr(buzz::QN_TYPE));
 
2201
    buzz::XmlElement* action = ActionFromStanza(stanzas_[0]);
 
2202
    ASSERT_TRUE(action != NULL);
 
2203
    buzz::XmlElement* content = ContentFromAction(action);
 
2204
    ASSERT_TRUE(content != NULL);
 
2205
    if (initial_protocol_ == cricket::PROTOCOL_JINGLE) {
 
2206
      buzz::XmlElement* content_desc =
 
2207
          content->FirstNamed(cricket::QN_JINGLE_RTP_CONTENT);
 
2208
      ASSERT_TRUE(content_desc != NULL);
 
2209
      ASSERT_EQ("", content_desc->Attr(cricket::QN_SSRC));
 
2210
    }
 
2211
    delete stanzas_[0];
 
2212
    stanzas_.clear();
 
2213
 
 
2214
    // We need to insert the session ID into the session accept message.
 
2215
    buzz::XmlElement* el = buzz::XmlElement::ForStr(accept_string);
 
2216
    const std::string sid = call_->sessions()[0]->id();
 
2217
    if (initial_protocol_ == cricket::PROTOCOL_JINGLE) {
 
2218
      buzz::XmlElement* jingle = el->FirstNamed(cricket::QN_JINGLE);
 
2219
      jingle->SetAttr(cricket::QN_SID, sid);
 
2220
    } else {
 
2221
      buzz::XmlElement* session = el->FirstNamed(cricket::QN_GINGLE_SESSION);
 
2222
      session->SetAttr(cricket::QN_ID, sid);
 
2223
    }
 
2224
 
 
2225
    client_->session_manager()->OnIncomingMessage(el);
 
2226
 
 
2227
    ASSERT_EQ(cricket::Session::STATE_RECEIVEDACCEPT,
 
2228
              call_->sessions()[0]->state());
 
2229
    ASSERT_EQ(1U, stanzas_.size());
 
2230
    ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name());
 
2231
    ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE));
 
2232
    ASSERT_EQ(std::string(buzz::STR_RESULT), stanzas_[0]->Attr(buzz::QN_TYPE));
 
2233
    delete stanzas_[0];
 
2234
    stanzas_.clear();
 
2235
 
 
2236
    CheckAudioSsrcForIncomingAccept(call_->sessions()[0]);
 
2237
    CheckVideoSsrcForIncomingAccept(call_->sessions()[0]);
 
2238
    if (has_data) {
 
2239
      CheckDataSsrcForIncomingAccept(call_->sessions()[0]);
 
2240
    }
 
2241
  }
 
2242
 
 
2243
  size_t ClearStanzas() {
 
2244
    size_t size = stanzas_.size();
 
2245
    for (size_t i = 0; i < size; i++) {
 
2246
      delete stanzas_[i];
 
2247
    }
 
2248
    stanzas_.clear();
 
2249
    return size;
 
2250
  }
 
2251
 
 
2252
  void SetJingleSid(buzz::XmlElement* stanza) {
 
2253
    buzz::XmlElement* jingle =
 
2254
        stanza->FirstNamed(cricket::QN_JINGLE);
 
2255
    jingle->SetAttr(cricket::QN_SID, call_->sessions()[0]->id());
 
2256
  }
 
2257
 
 
2258
  void TestStreamsUpdateAndViewRequests() {
 
2259
    cricket::CallOptions options;
 
2260
    options.has_video = true;
 
2261
    options.is_muc = true;
 
2262
 
 
2263
    client_->CreateCall();
 
2264
    call_->InitiateSession(buzz::Jid("me@mydomain.com"), options);
 
2265
    ASSERT_EQ(1U, ClearStanzas());
 
2266
    ASSERT_EQ(0U, last_streams_added_.audio().size());
 
2267
    ASSERT_EQ(0U, last_streams_added_.video().size());
 
2268
    ASSERT_EQ(0U, last_streams_removed_.audio().size());
 
2269
    ASSERT_EQ(0U, last_streams_removed_.video().size());
 
2270
 
 
2271
    talk_base::scoped_ptr<buzz::XmlElement> accept_stanza(
 
2272
        buzz::XmlElement::ForStr(kJingleAcceptWithSsrcs));
 
2273
    SetJingleSid(accept_stanza.get());
 
2274
    client_->session_manager()->OnIncomingMessage(accept_stanza.get());
 
2275
    ASSERT_EQ(cricket::Session::STATE_RECEIVEDACCEPT,
 
2276
              call_->sessions()[0]->state());
 
2277
    ASSERT_EQ(1U, stanzas_.size());
 
2278
    ASSERT_EQ(std::string(buzz::STR_RESULT), stanzas_[0]->Attr(buzz::QN_TYPE));
 
2279
    ClearStanzas();
 
2280
    call_->sessions()[0]->SetState(cricket::Session::STATE_INPROGRESS);
 
2281
 
 
2282
    talk_base::scoped_ptr<buzz::XmlElement> streams_stanza(
 
2283
        buzz::XmlElement::ForStr(
 
2284
            JingleStreamAdd("video", "Bob", "video1", "ABC")));
 
2285
    SetJingleSid(streams_stanza.get());
 
2286
    client_->session_manager()->OnIncomingMessage(streams_stanza.get());
 
2287
    // First one is ignored because of bad syntax.
 
2288
    ASSERT_EQ(1U, stanzas_.size());
 
2289
    // TODO: Figure out how to make this an ERROR rather than RESULT.
 
2290
    ASSERT_EQ(std::string(buzz::STR_ERROR), stanzas_[0]->Attr(buzz::QN_TYPE));
 
2291
    ClearStanzas();
 
2292
    ASSERT_EQ(0U, last_streams_added_.audio().size());
 
2293
    ASSERT_EQ(0U, last_streams_added_.video().size());
 
2294
    ASSERT_EQ(0U, last_streams_removed_.audio().size());
 
2295
    ASSERT_EQ(0U, last_streams_removed_.video().size());
 
2296
 
 
2297
    streams_stanza.reset(buzz::XmlElement::ForStr(
 
2298
        JingleStreamAdd("audio", "Bob", "audio1", "1234")));
 
2299
    SetJingleSid(streams_stanza.get());
 
2300
    client_->session_manager()->OnIncomingMessage(streams_stanza.get());
 
2301
    ASSERT_EQ(1U, last_streams_added_.audio().size());
 
2302
    ASSERT_EQ("Bob", last_streams_added_.audio()[0].nick);
 
2303
    ASSERT_EQ(1U, last_streams_added_.audio()[0].ssrcs.size());
 
2304
    ASSERT_EQ(1234U, last_streams_added_.audio()[0].first_ssrc());
 
2305
 
 
2306
    // Ignores adds without ssrcs.
 
2307
    streams_stanza.reset(buzz::XmlElement::ForStr(
 
2308
        JingleStreamAddWithoutSsrc("audio", "Bob", "audioX")));
 
2309
    SetJingleSid(streams_stanza.get());
 
2310
    client_->session_manager()->OnIncomingMessage(streams_stanza.get());
 
2311
    ASSERT_EQ(1U, last_streams_added_.audio().size());
 
2312
    ASSERT_EQ(1234U, last_streams_added_.audio()[0].first_ssrc());
 
2313
 
 
2314
    // Ignores stream updates with unknown content names. (Don't terminate).
 
2315
    streams_stanza.reset(buzz::XmlElement::ForStr(
 
2316
        JingleStreamAddWithoutSsrc("foo", "Bob", "foo")));
 
2317
    SetJingleSid(streams_stanza.get());
 
2318
    client_->session_manager()->OnIncomingMessage(streams_stanza.get());
 
2319
 
 
2320
    streams_stanza.reset(buzz::XmlElement::ForStr(
 
2321
        JingleStreamAdd("audio", "Joe", "audio1", "2468")));
 
2322
    SetJingleSid(streams_stanza.get());
 
2323
    client_->session_manager()->OnIncomingMessage(streams_stanza.get());
 
2324
    ASSERT_EQ(1U, last_streams_added_.audio().size());
 
2325
    ASSERT_EQ("Joe", last_streams_added_.audio()[0].nick);
 
2326
    ASSERT_EQ(1U, last_streams_added_.audio()[0].ssrcs.size());
 
2327
    ASSERT_EQ(2468U, last_streams_added_.audio()[0].first_ssrc());
 
2328
 
 
2329
    streams_stanza.reset(buzz::XmlElement::ForStr(
 
2330
        JingleStreamAdd("video", "Bob", "video1", "5678")));
 
2331
    SetJingleSid(streams_stanza.get());
 
2332
    client_->session_manager()->OnIncomingMessage(streams_stanza.get());
 
2333
    ASSERT_EQ(1U, last_streams_added_.video().size());
 
2334
    ASSERT_EQ("Bob", last_streams_added_.video()[0].nick);
 
2335
    ASSERT_EQ(1U, last_streams_added_.video()[0].ssrcs.size());
 
2336
    ASSERT_EQ(5678U, last_streams_added_.video()[0].first_ssrc());
 
2337
 
 
2338
    // We're testing that a "duplicate" is effectively ignored.
 
2339
    last_streams_added_.mutable_video()->clear();
 
2340
    last_streams_removed_.mutable_video()->clear();
 
2341
    streams_stanza.reset(buzz::XmlElement::ForStr(
 
2342
        JingleStreamAdd("video", "Bob", "video1", "5678")));
 
2343
    SetJingleSid(streams_stanza.get());
 
2344
    client_->session_manager()->OnIncomingMessage(streams_stanza.get());
 
2345
    ASSERT_EQ(0U, last_streams_added_.video().size());
 
2346
    ASSERT_EQ(0U, last_streams_removed_.video().size());
 
2347
 
 
2348
    streams_stanza.reset(buzz::XmlElement::ForStr(
 
2349
        JingleStreamAdd("video", "Bob", "video2", "5679")));
 
2350
    SetJingleSid(streams_stanza.get());
 
2351
    client_->session_manager()->OnIncomingMessage(streams_stanza.get());
 
2352
    ASSERT_EQ(1U, last_streams_added_.video().size());
 
2353
    ASSERT_EQ("Bob", last_streams_added_.video()[0].nick);
 
2354
    ASSERT_EQ(1U, last_streams_added_.video()[0].ssrcs.size());
 
2355
    ASSERT_EQ(5679U, last_streams_added_.video()[0].first_ssrc());
 
2356
 
 
2357
    cricket::FakeVoiceMediaChannel* voice_channel = fme_->GetVoiceChannel(0);
 
2358
    ASSERT_TRUE(voice_channel != NULL);
 
2359
    ASSERT_TRUE(voice_channel->HasRecvStream(1234U));
 
2360
    ASSERT_TRUE(voice_channel->HasRecvStream(2468U));
 
2361
    cricket::FakeVideoMediaChannel* video_channel = fme_->GetVideoChannel(0);
 
2362
    ASSERT_TRUE(video_channel != NULL);
 
2363
    ASSERT_TRUE(video_channel->HasRecvStream(5678U));
 
2364
    ClearStanzas();
 
2365
 
 
2366
    cricket::ViewRequest viewRequest;
 
2367
    cricket::StaticVideoView staticVideoView(5678U, 640, 480, 30);
 
2368
    viewRequest.static_video_views.push_back(staticVideoView);
 
2369
    talk_base::scoped_ptr<buzz::XmlElement> expected_view_elem(
 
2370
        buzz::XmlElement::ForStr(JingleView("5678", "640", "480", "30")));
 
2371
    SetJingleSid(expected_view_elem.get());
 
2372
 
 
2373
    ASSERT_TRUE(
 
2374
        call_->SendViewRequest(call_->sessions()[0], viewRequest));
 
2375
    ASSERT_EQ(1U, stanzas_.size());
 
2376
    ASSERT_EQ(expected_view_elem->Str(), stanzas_[0]->Str());
 
2377
    ClearStanzas();
 
2378
 
 
2379
    streams_stanza.reset(buzz::XmlElement::ForStr(
 
2380
        JingleStreamRemove("audio", "Bob", "audio1")));
 
2381
    SetJingleSid(streams_stanza.get());
 
2382
    client_->session_manager()->OnIncomingMessage(streams_stanza.get());
 
2383
    ASSERT_EQ(1U, last_streams_removed_.audio().size());
 
2384
    ASSERT_EQ(1U, last_streams_removed_.audio()[0].ssrcs.size());
 
2385
    EXPECT_EQ(1234U, last_streams_removed_.audio()[0].first_ssrc());
 
2386
 
 
2387
    streams_stanza.reset(buzz::XmlElement::ForStr(
 
2388
        JingleStreamRemove("video", "Bob", "video1")));
 
2389
    SetJingleSid(streams_stanza.get());
 
2390
    client_->session_manager()->OnIncomingMessage(streams_stanza.get());
 
2391
    ASSERT_EQ(1U, last_streams_removed_.video().size());
 
2392
    ASSERT_EQ(1U, last_streams_removed_.video()[0].ssrcs.size());
 
2393
    EXPECT_EQ(5678U, last_streams_removed_.video()[0].first_ssrc());
 
2394
 
 
2395
    streams_stanza.reset(buzz::XmlElement::ForStr(
 
2396
        JingleStreamRemove("video", "Bob", "video2")));
 
2397
    SetJingleSid(streams_stanza.get());
 
2398
    client_->session_manager()->OnIncomingMessage(streams_stanza.get());
 
2399
    ASSERT_EQ(1U, last_streams_removed_.video().size());
 
2400
    ASSERT_EQ(1U, last_streams_removed_.video()[0].ssrcs.size());
 
2401
    EXPECT_EQ(5679U, last_streams_removed_.video()[0].first_ssrc());
 
2402
 
 
2403
    // Duplicate removal: should be ignored.
 
2404
    last_streams_removed_.mutable_audio()->clear();
 
2405
    streams_stanza.reset(buzz::XmlElement::ForStr(
 
2406
        JingleStreamRemove("audio", "Bob", "audio1")));
 
2407
    SetJingleSid(streams_stanza.get());
 
2408
    client_->session_manager()->OnIncomingMessage(streams_stanza.get());
 
2409
    ASSERT_EQ(0U, last_streams_removed_.audio().size());
 
2410
 
 
2411
    // Duplicate removal: should be ignored.
 
2412
    last_streams_removed_.mutable_video()->clear();
 
2413
    streams_stanza.reset(buzz::XmlElement::ForStr(
 
2414
        JingleStreamRemove("video", "Bob", "video1")));
 
2415
    SetJingleSid(streams_stanza.get());
 
2416
    client_->session_manager()->OnIncomingMessage(streams_stanza.get());
 
2417
    ASSERT_EQ(0U, last_streams_removed_.video().size());
 
2418
 
 
2419
    voice_channel = fme_->GetVoiceChannel(0);
 
2420
    ASSERT_TRUE(voice_channel != NULL);
 
2421
    ASSERT_FALSE(voice_channel->HasRecvStream(1234U));
 
2422
    ASSERT_TRUE(voice_channel->HasRecvStream(2468U));
 
2423
    video_channel = fme_->GetVideoChannel(0);
 
2424
    ASSERT_TRUE(video_channel != NULL);
 
2425
    ASSERT_FALSE(video_channel->HasRecvStream(5678U));
 
2426
 
 
2427
    // Fails because ssrc is now invalid.
 
2428
    ASSERT_FALSE(
 
2429
        call_->SendViewRequest(call_->sessions()[0], viewRequest));
 
2430
 
 
2431
    ClearStanzas();
 
2432
  }
 
2433
 
 
2434
  void MakeSignalingSecure(cricket::SecureMediaPolicy secure) {
 
2435
    client_->set_secure(secure);
 
2436
  }
 
2437
 
 
2438
  void ExpectCrypto(cricket::SecureMediaPolicy secure) {
 
2439
    MakeSignalingSecure(secure);
 
2440
    expect_incoming_crypto_ = true;
 
2441
#ifdef HAVE_SRTP
 
2442
    expect_outgoing_crypto_ = true;
 
2443
#endif
 
2444
  }
 
2445
 
 
2446
  void ExpectVideoBandwidth(int bandwidth) {
 
2447
    expected_video_bandwidth_ = bandwidth;
 
2448
  }
 
2449
 
 
2450
  void ExpectVideoRtcpMux(bool rtcp_mux) {
 
2451
    expected_video_rtcp_mux_ = rtcp_mux;
 
2452
  }
 
2453
 
 
2454
 private:
 
2455
  void OnSendStanza(cricket::SessionManager* manager,
 
2456
                    const buzz::XmlElement* stanza) {
 
2457
    LOG(LS_INFO) << stanza->Str();
 
2458
    stanzas_.push_back(new buzz::XmlElement(*stanza));
 
2459
  }
 
2460
 
 
2461
  void OnSessionCreate(cricket::Session* session, bool initiate) {
 
2462
    session->set_current_protocol(initial_protocol_);
 
2463
  }
 
2464
 
 
2465
  void OnCallCreate(cricket::Call *call) {
 
2466
    call_ = call;
 
2467
    call->SignalMediaStreamsUpdate.connect(
 
2468
        this, &MediaSessionClientTest::OnMediaStreamsUpdate);
 
2469
  }
 
2470
 
 
2471
  void OnCallDestroy(cricket::Call *call) {
 
2472
    call_ = NULL;
 
2473
  }
 
2474
 
 
2475
  void OnMediaStreamsUpdate(cricket::Call *call,
 
2476
                            cricket::Session *session,
 
2477
                            const cricket::MediaStreams& added,
 
2478
                            const cricket::MediaStreams& removed) {
 
2479
    last_streams_added_.CopyFrom(added);
 
2480
    last_streams_removed_.CopyFrom(removed);
 
2481
  }
 
2482
 
 
2483
  talk_base::NetworkManager* nm_;
 
2484
  cricket::PortAllocator* pa_;
 
2485
  cricket::SessionManager* sm_;
 
2486
  cricket::FakeMediaEngine* fme_;
 
2487
  cricket::FakeDataEngine* fdme_;
 
2488
  cricket::MediaSessionClient* client_;
 
2489
 
 
2490
  cricket::Call* call_;
 
2491
  std::vector<buzz::XmlElement* > stanzas_;
 
2492
  MediaSessionTestParser* parser_;
 
2493
  cricket::SignalingProtocol initial_protocol_;
 
2494
  bool expect_incoming_crypto_;
 
2495
  bool expect_outgoing_crypto_;
 
2496
  int expected_video_bandwidth_;
 
2497
  bool expected_video_rtcp_mux_;
 
2498
  cricket::MediaStreams last_streams_added_;
 
2499
  cricket::MediaStreams last_streams_removed_;
 
2500
};
 
2501
 
 
2502
MediaSessionClientTest* GingleTest() {
 
2503
  return new MediaSessionClientTest(new GingleSessionTestParser(),
 
2504
                                    cricket::PROTOCOL_GINGLE);
 
2505
}
 
2506
 
 
2507
MediaSessionClientTest* JingleTest() {
 
2508
  return new MediaSessionClientTest(new JingleSessionTestParser(),
 
2509
                                    cricket::PROTOCOL_JINGLE);
 
2510
}
 
2511
 
 
2512
TEST(MediaSessionTest, JingleGoodVideoInitiate) {
 
2513
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2514
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2515
  test->TestGoodIncomingInitiate(kJingleVideoInitiate, elem.use());
 
2516
  test->TestCodecsOfVideoInitiate(elem.get());
 
2517
}
 
2518
 
 
2519
TEST(MediaSessionTest, JingleGoodVideoInitiateWithBandwidth) {
 
2520
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2521
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2522
  test->ExpectVideoBandwidth(42000);
 
2523
  test->TestGoodIncomingInitiate(kJingleVideoInitiateWithBandwidth, elem.use());
 
2524
}
 
2525
 
 
2526
TEST(MediaSessionTest, JingleGoodVideoInitiateWithRtcpMux) {
 
2527
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2528
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2529
  test->ExpectVideoRtcpMux(true);
 
2530
  test->TestGoodIncomingInitiate(kJingleVideoInitiateWithRtcpMux, elem.use());
 
2531
}
 
2532
 
 
2533
TEST(MediaSessionTest, JingleGoodVideoInitiateWithData) {
 
2534
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2535
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2536
  test->TestGoodIncomingInitiate(AddEncryption(kJingleVideoInitiateWithData,
 
2537
                                               kJingleCryptoOffer),
 
2538
                                 elem.use());
 
2539
}
 
2540
 
 
2541
TEST(MediaSessionTest, JingleGoodInitiateAllSupportedAudioCodecs) {
 
2542
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2543
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2544
  test->TestGoodIncomingInitiate(kJingleInitiate, elem.use());
 
2545
  test->TestHasAllSupportedAudioCodecs(elem.get());
 
2546
}
 
2547
 
 
2548
TEST(MediaSessionTest, JingleGoodInitiateDifferentPreferenceAudioCodecs) {
 
2549
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2550
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2551
  test->TestGoodIncomingInitiate(kJingleInitiateDifferentPreference,
 
2552
      elem.use());
 
2553
  test->TestHasAllSupportedAudioCodecs(elem.get());
 
2554
}
 
2555
 
 
2556
TEST(MediaSessionTest, JingleGoodInitiateSomeUnsupportedAudioCodecs) {
 
2557
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2558
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2559
  test->TestGoodIncomingInitiate(kJingleInitiateSomeUnsupported, elem.use());
 
2560
  test->TestHasAudioCodecsFromInitiateSomeUnsupported(elem.get());
 
2561
}
 
2562
 
 
2563
TEST(MediaSessionTest, JingleGoodInitiateDynamicAudioCodecs) {
 
2564
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2565
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2566
  test->TestGoodIncomingInitiate(kJingleInitiateDynamicAudioCodecs, elem.use());
 
2567
  test->TestHasAudioCodecsFromInitiateDynamicAudioCodecs(elem.get());
 
2568
}
 
2569
 
 
2570
TEST(MediaSessionTest, JingleGoodInitiateStaticAudioCodecs) {
 
2571
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2572
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2573
  test->TestGoodIncomingInitiate(kJingleInitiateStaticAudioCodecs, elem.use());
 
2574
  test->TestHasAudioCodecsFromInitiateStaticAudioCodecs(elem.get());
 
2575
}
 
2576
 
 
2577
TEST(MediaSessionTest, JingleBadInitiateNoAudioCodecs) {
 
2578
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2579
  test->TestBadIncomingInitiate(kJingleInitiateNoAudioCodecs);
 
2580
}
 
2581
 
 
2582
TEST(MediaSessionTest, JingleBadInitiateNoSupportedAudioCodecs) {
 
2583
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2584
  test->TestBadIncomingInitiate(kJingleInitiateNoSupportedAudioCodecs);
 
2585
}
 
2586
 
 
2587
TEST(MediaSessionTest, JingleBadInitiateWrongClockrates) {
 
2588
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2589
  test->TestBadIncomingInitiate(kJingleInitiateWrongClockrates);
 
2590
}
 
2591
 
 
2592
TEST(MediaSessionTest, JingleBadInitiateWrongChannels) {
 
2593
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2594
  test->TestBadIncomingInitiate(kJingleInitiateWrongChannels);
 
2595
}
 
2596
 
 
2597
TEST(MediaSessionTest, JingleBadInitiateNoPayloadTypes) {
 
2598
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2599
  test->TestBadIncomingInitiate(kJingleInitiateNoPayloadTypes);
 
2600
}
 
2601
 
 
2602
TEST(MediaSessionTest, JingleBadInitiateDynamicWithoutNames) {
 
2603
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2604
  test->TestBadIncomingInitiate(kJingleInitiateDynamicWithoutNames);
 
2605
}
 
2606
 
 
2607
TEST(MediaSessionTest, JingleGoodOutgoingInitiate) {
 
2608
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2609
  test->TestGoodOutgoingInitiate();
 
2610
}
 
2611
 
 
2612
TEST(MediaSessionTest, JingleGoodOutgoingInitiateWithBandwidth) {
 
2613
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2614
  cricket::CallOptions options;
 
2615
  options.has_video = true;
 
2616
  options.video_bandwidth = 42000;
 
2617
  test->TestGoodOutgoingInitiate(options);
 
2618
}
 
2619
 
 
2620
TEST(MediaSessionTest, JingleGoodOutgoingInitiateWithRtcpMux) {
 
2621
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2622
  cricket::CallOptions options;
 
2623
  options.has_video = true;
 
2624
  options.rtcp_mux_enabled = true;
 
2625
  test->TestGoodOutgoingInitiate(options);
 
2626
}
 
2627
 
 
2628
TEST(MediaSessionTest, JingleGoodOutgoingInitiateWithData) {
 
2629
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2630
  cricket::CallOptions options;
 
2631
  options.has_data = true;
 
2632
  test->ExpectCrypto(cricket::SEC_ENABLED);
 
2633
  test->TestGoodOutgoingInitiate(options);
 
2634
}
 
2635
 
 
2636
// Crypto related tests.
 
2637
 
 
2638
// Offer has crypto but the session is not secured, just ignore it.
 
2639
TEST(MediaSessionTest, JingleInitiateWithCryptoIsIgnoredWhenNotSecured) {
 
2640
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2641
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2642
  test->TestGoodIncomingInitiate(AddEncryption(kJingleVideoInitiate,
 
2643
                                              kJingleCryptoOffer), elem.use());
 
2644
}
 
2645
 
 
2646
// Offer has crypto required but the session is not secure, fail.
 
2647
TEST(MediaSessionTest, JingleInitiateWithCryptoRequiredWhenNotSecured) {
 
2648
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2649
  test->TestBadIncomingInitiate(AddEncryption(kJingleVideoInitiate,
 
2650
                                             kJingleRequiredCryptoOffer));
 
2651
}
 
2652
 
 
2653
// Offer has no crypto but the session is secure required, fail.
 
2654
TEST(MediaSessionTest, JingleInitiateWithNoCryptoFailsWhenSecureRequired) {
 
2655
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2656
  test->ExpectCrypto(cricket::SEC_REQUIRED);
 
2657
  test->TestBadIncomingInitiate(kJingleInitiate);
 
2658
}
 
2659
 
 
2660
// Offer has crypto and session is secure, expect crypto in the answer.
 
2661
TEST(MediaSessionTest, JingleInitiateWithCryptoWhenSecureEnabled) {
 
2662
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2663
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2664
  test->ExpectCrypto(cricket::SEC_ENABLED);
 
2665
  test->TestGoodIncomingInitiate(AddEncryption(kJingleVideoInitiate,
 
2666
                                              kJingleCryptoOffer), elem.use());
 
2667
}
 
2668
 
 
2669
// Offer has crypto and session is secure required, expect crypto in
 
2670
// the answer.
 
2671
TEST(MediaSessionTest, JingleInitiateWithCryptoWhenSecureRequired) {
 
2672
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2673
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2674
  test->ExpectCrypto(cricket::SEC_REQUIRED);
 
2675
  test->TestGoodIncomingInitiate(AddEncryption(kJingleVideoInitiate,
 
2676
                                              kJingleCryptoOffer), elem.use());
 
2677
}
 
2678
 
 
2679
// Offer has unsupported crypto and session is secure, no crypto in
 
2680
// the answer.
 
2681
TEST(MediaSessionTest, JingleInitiateWithUnsupportedCrypto) {
 
2682
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2683
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2684
  test->MakeSignalingSecure(cricket::SEC_ENABLED);
 
2685
  test->TestGoodIncomingInitiate(
 
2686
      AddEncryption(kJingleInitiate, kJingleUnsupportedCryptoOffer),
 
2687
      elem.use());
 
2688
}
 
2689
 
 
2690
// Offer has unsupported REQUIRED crypto and session is not secure, fail.
 
2691
TEST(MediaSessionTest, JingleInitiateWithRequiredUnsupportedCrypto) {
 
2692
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2693
  test->TestBadIncomingInitiate(
 
2694
      AddEncryption(kJingleInitiate, kJingleRequiredUnsupportedCryptoOffer));
 
2695
}
 
2696
 
 
2697
// Offer has unsupported REQUIRED crypto and session is secure, fail.
 
2698
TEST(MediaSessionTest, JingleInitiateWithRequiredUnsupportedCryptoWhenSecure) {
 
2699
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2700
  test->MakeSignalingSecure(cricket::SEC_ENABLED);
 
2701
  test->TestBadIncomingInitiate(
 
2702
      AddEncryption(kJingleInitiate, kJingleRequiredUnsupportedCryptoOffer));
 
2703
}
 
2704
 
 
2705
// Offer has unsupported REQUIRED crypto and session is required secure, fail.
 
2706
TEST(MediaSessionTest,
 
2707
     JingleInitiateWithRequiredUnsupportedCryptoWhenSecureRequired) {
 
2708
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2709
  test->MakeSignalingSecure(cricket::SEC_REQUIRED);
 
2710
  test->TestBadIncomingInitiate(
 
2711
      AddEncryption(kJingleInitiate, kJingleRequiredUnsupportedCryptoOffer));
 
2712
}
 
2713
 
 
2714
 
 
2715
TEST(MediaSessionTest, JingleGoodOutgoingInitiateWithCrypto) {
 
2716
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2717
  test->ExpectCrypto(cricket::SEC_ENABLED);
 
2718
  test->TestGoodOutgoingInitiate();
 
2719
}
 
2720
 
 
2721
TEST(MediaSessionTest, JingleGoodOutgoingInitiateWithCryptoRequired) {
 
2722
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2723
  test->ExpectCrypto(cricket::SEC_REQUIRED);
 
2724
  test->TestGoodOutgoingInitiate();
 
2725
}
 
2726
 
 
2727
TEST(MediaSessionTest, JingleIncomingAcceptWithSsrcs) {
 
2728
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2729
  test->TestIncomingAcceptWithSsrcs(kJingleAcceptWithSsrcs, false);
 
2730
}
 
2731
 
 
2732
TEST(MediaSessionTest, JingleIncomingAcceptWithDataSsrcs) {
 
2733
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2734
  test->TestIncomingAcceptWithSsrcs(kJingleAcceptWithDataSsrcs, true);
 
2735
}
 
2736
 
 
2737
TEST(MediaSessionTest, JingleStreamsUpdateAndView) {
 
2738
  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
 
2739
  test->TestStreamsUpdateAndViewRequests();
 
2740
}
 
2741
 
 
2742
// Gingle tests
 
2743
 
 
2744
TEST(MediaSessionTest, GingleGoodVideoInitiate) {
 
2745
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2746
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2747
  test->TestGoodIncomingInitiate(kGingleVideoInitiate, elem.use());
 
2748
  test->TestCodecsOfVideoInitiate(elem.get());
 
2749
}
 
2750
 
 
2751
TEST(MediaSessionTest, GingleGoodVideoInitiateWithBandwidth) {
 
2752
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2753
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2754
  test->ExpectVideoBandwidth(42000);
 
2755
  test->TestGoodIncomingInitiate(kGingleVideoInitiateWithBandwidth, elem.use());
 
2756
}
 
2757
 
 
2758
TEST(MediaSessionTest, GingleGoodInitiateAllSupportedAudioCodecs) {
 
2759
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2760
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2761
  test->TestGoodIncomingInitiate(kGingleInitiate, elem.use());
 
2762
  test->TestHasAllSupportedAudioCodecs(elem.get());
 
2763
}
 
2764
 
 
2765
TEST(MediaSessionTest, GingleGoodInitiateAllSupportedAudioCodecsWithCrypto) {
 
2766
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2767
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2768
  test->ExpectCrypto(cricket::SEC_ENABLED);
 
2769
  test->TestGoodIncomingInitiate(AddEncryption(kGingleInitiate,
 
2770
                                              kGingleCryptoOffer), elem.use());
 
2771
  test->TestHasAllSupportedAudioCodecs(elem.get());
 
2772
}
 
2773
 
 
2774
TEST(MediaSessionTest, GingleGoodInitiateDifferentPreferenceAudioCodecs) {
 
2775
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2776
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2777
  test->TestGoodIncomingInitiate(kGingleInitiateDifferentPreference,
 
2778
      elem.use());
 
2779
  test->TestHasAllSupportedAudioCodecs(elem.get());
 
2780
}
 
2781
 
 
2782
TEST(MediaSessionTest, GingleGoodInitiateSomeUnsupportedAudioCodecs) {
 
2783
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2784
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2785
  test->TestGoodIncomingInitiate(kGingleInitiateSomeUnsupported, elem.use());
 
2786
  test->TestHasAudioCodecsFromInitiateSomeUnsupported(elem.get());
 
2787
}
 
2788
 
 
2789
TEST(MediaSessionTest, GingleGoodInitiateDynamicAudioCodecs) {
 
2790
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2791
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2792
  test->TestGoodIncomingInitiate(kGingleInitiateDynamicAudioCodecs, elem.use());
 
2793
  test->TestHasAudioCodecsFromInitiateDynamicAudioCodecs(elem.get());
 
2794
}
 
2795
 
 
2796
TEST(MediaSessionTest, GingleGoodInitiateStaticAudioCodecs) {
 
2797
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2798
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2799
  test->TestGoodIncomingInitiate(kGingleInitiateStaticAudioCodecs, elem.use());
 
2800
  test->TestHasAudioCodecsFromInitiateStaticAudioCodecs(elem.get());
 
2801
}
 
2802
 
 
2803
TEST(MediaSessionTest, GingleGoodInitiateNoAudioCodecs) {
 
2804
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2805
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2806
  test->TestGoodIncomingInitiate(kGingleInitiateNoAudioCodecs, elem.use());
 
2807
  test->TestHasDefaultAudioCodecs(elem.get());
 
2808
}
 
2809
 
 
2810
TEST(MediaSessionTest, GingleBadInitiateNoSupportedAudioCodecs) {
 
2811
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2812
  test->TestBadIncomingInitiate(kGingleInitiateNoSupportedAudioCodecs);
 
2813
}
 
2814
 
 
2815
TEST(MediaSessionTest, GingleBadInitiateWrongClockrates) {
 
2816
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2817
  test->TestBadIncomingInitiate(kGingleInitiateWrongClockrates);
 
2818
}
 
2819
 
 
2820
TEST(MediaSessionTest, GingleBadInitiateWrongChannels) {
 
2821
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2822
  test->TestBadIncomingInitiate(kGingleInitiateWrongChannels);
 
2823
}
 
2824
 
 
2825
 
 
2826
TEST(MediaSessionTest, GingleBadInitiateNoPayloadTypes) {
 
2827
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2828
  test->TestBadIncomingInitiate(kGingleInitiateNoPayloadTypes);
 
2829
}
 
2830
 
 
2831
TEST(MediaSessionTest, GingleBadInitiateDynamicWithoutNames) {
 
2832
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2833
  test->TestBadIncomingInitiate(kGingleInitiateDynamicWithoutNames);
 
2834
}
 
2835
 
 
2836
TEST(MediaSessionTest, GingleGoodOutgoingInitiate) {
 
2837
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2838
  test->TestGoodOutgoingInitiate();
 
2839
}
 
2840
 
 
2841
TEST(MediaSessionTest, GingleGoodOutgoingInitiateWithBandwidth) {
 
2842
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2843
  cricket::CallOptions options;
 
2844
  options.has_video = true;
 
2845
  options.video_bandwidth = 42000;
 
2846
  test->TestGoodOutgoingInitiate(options);
 
2847
}
 
2848
 
 
2849
// Crypto related tests.
 
2850
 
 
2851
// Offer has crypto but the session is not secured, just ignore it.
 
2852
TEST(MediaSessionTest, GingleInitiateWithCryptoIsIgnoredWhenNotSecured) {
 
2853
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2854
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2855
  test->TestGoodIncomingInitiate(AddEncryption(kGingleInitiate,
 
2856
                                              kGingleCryptoOffer), elem.use());
 
2857
}
 
2858
 
 
2859
// Offer has crypto required but the session is not secure, fail.
 
2860
TEST(MediaSessionTest, GingleInitiateWithCryptoRequiredWhenNotSecured) {
 
2861
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2862
  test->TestBadIncomingInitiate(AddEncryption(kGingleInitiate,
 
2863
                                             kGingleRequiredCryptoOffer));
 
2864
}
 
2865
 
 
2866
// Offer has no crypto but the session is secure required, fail.
 
2867
TEST(MediaSessionTest, GingleInitiateWithNoCryptoFailsWhenSecureRequired) {
 
2868
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2869
  test->ExpectCrypto(cricket::SEC_REQUIRED);
 
2870
  test->TestBadIncomingInitiate(kGingleInitiate);
 
2871
}
 
2872
 
 
2873
// Offer has crypto and session is secure, expect crypto in the answer.
 
2874
TEST(MediaSessionTest, GingleInitiateWithCryptoWhenSecureEnabled) {
 
2875
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2876
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2877
  test->ExpectCrypto(cricket::SEC_ENABLED);
 
2878
  test->TestGoodIncomingInitiate(AddEncryption(kGingleInitiate,
 
2879
                                              kGingleCryptoOffer), elem.use());
 
2880
}
 
2881
 
 
2882
// Offer has crypto and session is secure required, expect crypto in
 
2883
// the answer.
 
2884
TEST(MediaSessionTest, GingleInitiateWithCryptoWhenSecureRequired) {
 
2885
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2886
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2887
  test->ExpectCrypto(cricket::SEC_REQUIRED);
 
2888
  test->TestGoodIncomingInitiate(AddEncryption(kGingleInitiate,
 
2889
                                              kGingleCryptoOffer), elem.use());
 
2890
}
 
2891
 
 
2892
// Offer has unsupported crypto and session is secure, no crypto in
 
2893
// the answer.
 
2894
TEST(MediaSessionTest, GingleInitiateWithUnsupportedCrypto) {
 
2895
  talk_base::scoped_ptr<buzz::XmlElement> elem;
 
2896
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2897
  test->MakeSignalingSecure(cricket::SEC_ENABLED);
 
2898
  test->TestGoodIncomingInitiate(
 
2899
      AddEncryption(kGingleInitiate, kGingleUnsupportedCryptoOffer),
 
2900
      elem.use());
 
2901
}
 
2902
 
 
2903
// Offer has unsupported REQUIRED crypto and session is not secure, fail.
 
2904
TEST(MediaSessionTest, GingleInitiateWithRequiredUnsupportedCrypto) {
 
2905
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2906
  test->TestBadIncomingInitiate(
 
2907
      AddEncryption(kGingleInitiate, kGingleRequiredUnsupportedCryptoOffer));
 
2908
}
 
2909
 
 
2910
// Offer has unsupported REQUIRED crypto and session is secure, fail.
 
2911
TEST(MediaSessionTest, GingleInitiateWithRequiredUnsupportedCryptoWhenSecure) {
 
2912
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2913
  test->MakeSignalingSecure(cricket::SEC_ENABLED);
 
2914
  test->TestBadIncomingInitiate(
 
2915
      AddEncryption(kGingleInitiate, kGingleRequiredUnsupportedCryptoOffer));
 
2916
}
 
2917
 
 
2918
// Offer has unsupported REQUIRED crypto and session is required secure, fail.
 
2919
TEST(MediaSessionTest,
 
2920
     GingleInitiateWithRequiredUnsupportedCryptoWhenSecureRequired) {
 
2921
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2922
  test->MakeSignalingSecure(cricket::SEC_REQUIRED);
 
2923
  test->TestBadIncomingInitiate(
 
2924
      AddEncryption(kGingleInitiate, kGingleRequiredUnsupportedCryptoOffer));
 
2925
}
 
2926
 
 
2927
TEST(MediaSessionTest, GingleGoodOutgoingInitiateWithCrypto) {
 
2928
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2929
  test->ExpectCrypto(cricket::SEC_ENABLED);
 
2930
  test->TestGoodOutgoingInitiate();
 
2931
}
 
2932
 
 
2933
TEST(MediaSessionTest, GingleGoodOutgoingInitiateWithCryptoRequired) {
 
2934
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2935
  test->ExpectCrypto(cricket::SEC_REQUIRED);
 
2936
  test->TestGoodOutgoingInitiate();
 
2937
}
 
2938
 
 
2939
TEST(MediaSessionTest, GingleIncomingAcceptWithSsrcs) {
 
2940
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2941
  test->TestIncomingAcceptWithSsrcs(kGingleAcceptWithSsrcs, false);
 
2942
}
 
2943
 
 
2944
TEST(MediaSessionTest, GingleGoodOutgoingInitiateWithData) {
 
2945
  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
 
2946
  cricket::CallOptions options;
 
2947
  options.has_data = true;
 
2948
  test->ExpectCrypto(cricket::SEC_ENABLED);
 
2949
  test->TestGoodOutgoingInitiate(options);
 
2950
}