/[resiprocate]/main/reflow/MediaStream.cxx
ViewVC logotype

Contents of /main/reflow/MediaStream.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11159 - (show annotations) (download)
Fri Apr 25 14:03:32 2014 UTC (5 years, 8 months ago) by sgodin
File MIME type: text/plain
File size: 10477 byte(s)
-modified asio and boost include file ordering to avoid multiply defined symbol errors on linking
 -in preparation for upgrade of asio drop and support for latest boost 
 -include asio/ssh.hpp everywhere asio.hpp is included
 -include boost headers before others, to ensure we are not redefining stdint definitions in some includes
  and not others

1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include <boost/function.hpp>
6
7 #include <rutil/Log.hxx>
8 #include <rutil/Logger.hxx>
9 #include <rutil/Timer.hxx>
10
11 #include "MediaStream.hxx"
12 #include "FlowManagerSubsystem.hxx"
13 #include "FlowManager.hxx"
14
15
16 using namespace flowmanager;
17 #ifdef USE_SSL
18 using namespace dtls;
19 #endif
20 using namespace resip;
21 using namespace std;
22
23 #define RESIPROCATE_SUBSYSTEM FlowManagerSubsystem::FLOWMANAGER
24
25 MediaStream::MediaStream(asio::io_service& ioService,
26 #ifdef USE_SSL
27 asio::ssl::context& sslContext,
28 #endif
29 MediaStreamHandler& mediaStreamHandler,
30 const StunTuple& localRtpBinding,
31 const StunTuple& localRtcpBinding,
32 #ifdef USE_SSL
33 DtlsFactory* dtlsFactory,
34 #endif
35 NatTraversalMode natTraversalMode,
36 const char* natTraversalServerHostname,
37 unsigned short natTraversalServerPort,
38 const char* stunUsername,
39 const char* stunPassword) :
40 #ifdef USE_SSL
41 mDtlsFactory(dtlsFactory),
42 #endif
43 mSRTPSessionInCreated(false),
44 mSRTPSessionOutCreated(false),
45 mNatTraversalMode(natTraversalMode),
46 mNatTraversalServerHostname(natTraversalServerHostname),
47 mNatTraversalServerPort(natTraversalServerPort),
48 mStunUsername(stunUsername),
49 mStunPassword(stunPassword),
50 mMediaStreamHandler(mediaStreamHandler)
51 {
52 // Rtcp is enabled if localRtcpBinding transport type != None
53 mRtcpEnabled = localRtcpBinding.getTransportType() != StunTuple::None;
54
55 if(mRtcpEnabled)
56 {
57 mRtpFlow = new Flow(ioService,
58 #ifdef USE_SSL
59 sslContext,
60 #endif
61 RTP_COMPONENT_ID,
62 localRtpBinding,
63 *this);
64
65 mRtcpFlow = new Flow(ioService,
66 #ifdef USE_SSL
67 sslContext,
68 #endif
69 RTCP_COMPONENT_ID,
70 localRtcpBinding,
71 *this);
72
73 mRtpFlow->activateFlow(StunMessage::PropsPortPair);
74
75 // If doing an allocation then wait until RTP flow is allocated, then activate RTCP flow
76 if(natTraversalMode != TurnAllocation)
77 {
78 mRtcpFlow->activateFlow();
79 }
80 }
81 else
82 {
83 mRtpFlow = new Flow(ioService,
84 #ifdef USE_SSL
85 sslContext,
86 #endif
87 RTP_COMPONENT_ID,
88 localRtpBinding,
89 *this);
90 mRtpFlow->activateFlow(StunMessage::PropsPortEven);
91 mRtcpFlow = 0;
92 }
93 }
94
95 MediaStream::~MediaStream()
96 {
97 {
98 Lock lock(mMutex);
99
100 if(mSRTPSessionOutCreated)
101 {
102 mSRTPSessionOutCreated = false;
103 srtp_dealloc(mSRTPSessionOut);
104 }
105 if(mSRTPSessionInCreated)
106 {
107 mSRTPSessionInCreated = false;
108 srtp_dealloc(mSRTPSessionIn);
109 }
110 }
111 delete mRtpFlow;
112 if(mRtcpEnabled)
113 {
114 delete mRtcpFlow;
115 }
116 }
117
118 bool
119 MediaStream::createOutboundSRTPSession(SrtpCryptoSuite cryptoSuite, const char* key, unsigned int keyLen)
120 {
121 if(keyLen != SRTP_MASTER_KEY_LEN)
122 {
123 ErrLog(<< "Unable to create outbound SRTP session, invalid keyLen=" << keyLen);
124 return false;
125 }
126
127 err_status_t status;
128 Lock lock(mMutex);
129 if(mSRTPSessionOutCreated)
130 {
131 // Check if settings are the same - if so just return true
132 if(cryptoSuite == mCryptoSuiteOut && memcmp(mSRTPMasterKeyOut, key, keyLen) == 0)
133 {
134 InfoLog(<< "Outbound SRTP session settings unchanged.");
135 return true;
136 }
137 else
138 {
139 InfoLog(<< "Re-creating outbound SRTP session with new settings.");
140 mSRTPSessionOutCreated = false;
141 srtp_dealloc(mSRTPSessionOut);
142 }
143 }
144 memset(&mSRTPPolicyOut, 0, sizeof(mSRTPPolicyOut));
145
146 // Copy key locally
147 memcpy(mSRTPMasterKeyOut, key, SRTP_MASTER_KEY_LEN);
148
149 // load default srtp/srtcp policy settings
150 mCryptoSuiteOut = cryptoSuite;
151 switch(cryptoSuite)
152 {
153 case SRTP_AES_CM_128_HMAC_SHA1_80:
154 crypto_policy_set_aes_cm_128_hmac_sha1_80(&mSRTPPolicyOut.rtp);
155 crypto_policy_set_aes_cm_128_hmac_sha1_80(&mSRTPPolicyOut.rtcp);
156 break;
157 case SRTP_AES_CM_128_HMAC_SHA1_32:
158 crypto_policy_set_aes_cm_128_hmac_sha1_32(&mSRTPPolicyOut.rtp);
159 crypto_policy_set_aes_cm_128_hmac_sha1_32(&mSRTPPolicyOut.rtcp);
160 break;
161 default:
162 ErrLog(<< "Unable to create outbound SRTP session, invalid crypto suite=" << cryptoSuite);
163 return false;
164 }
165
166 // set remaining policy settings
167 mSRTPPolicyOut.ssrc.type = ssrc_any_outbound;
168 mSRTPPolicyOut.key = mSRTPMasterKeyOut;
169 mSRTPPolicyOut.window_size = 64;
170
171 // Allocate and initailize the SRTP sessions
172 status = srtp_create(&mSRTPSessionOut, &mSRTPPolicyOut);
173 if(status)
174 {
175 ErrLog(<< "Unable to create srtp out session, error code=" << status);
176 return false;
177 }
178 mSRTPSessionOutCreated = true;
179
180 return true;
181 }
182
183 bool
184 MediaStream::createInboundSRTPSession(SrtpCryptoSuite cryptoSuite, const char* key, unsigned int keyLen)
185 {
186 if(keyLen != SRTP_MASTER_KEY_LEN)
187 {
188 ErrLog(<< "Unable to create inbound SRTP session, invalid keyLen=" << keyLen);
189 return false;
190 }
191
192 err_status_t status;
193 Lock lock(mMutex);
194 if(mSRTPSessionInCreated)
195 {
196 // Check if settings are the same - if so just return true
197 if(cryptoSuite == mCryptoSuiteIn && memcmp(mSRTPMasterKeyIn, key, keyLen) == 0)
198 {
199 InfoLog(<< "Inbound SRTP session settings unchanged.");
200 return true;
201 }
202 else
203 {
204 InfoLog(<< "Re-creating inbound SRTP session with new settings.");
205 mSRTPSessionInCreated = false;
206 srtp_dealloc(mSRTPSessionIn);
207 }
208 }
209 memset(&mSRTPPolicyIn, 0, sizeof(mSRTPPolicyIn));
210
211 // Copy key locally
212 memcpy(mSRTPMasterKeyIn, key, SRTP_MASTER_KEY_LEN);
213
214 // load default srtp/srtcp policy settings
215 mCryptoSuiteIn = cryptoSuite;
216 switch(cryptoSuite)
217 {
218 case SRTP_AES_CM_128_HMAC_SHA1_80:
219 crypto_policy_set_aes_cm_128_hmac_sha1_80(&mSRTPPolicyIn.rtp);
220 crypto_policy_set_aes_cm_128_hmac_sha1_80(&mSRTPPolicyIn.rtcp);
221 break;
222 case SRTP_AES_CM_128_HMAC_SHA1_32:
223 crypto_policy_set_aes_cm_128_hmac_sha1_32(&mSRTPPolicyIn.rtp);
224 crypto_policy_set_aes_cm_128_hmac_sha1_32(&mSRTPPolicyIn.rtcp);
225 break;
226 default:
227 ErrLog(<< "Unable to create inbound SRTP session, invalid crypto suite=" << cryptoSuite);
228 return false;
229 }
230
231 // set remaining policy settings
232 mSRTPPolicyIn.ssrc.type = ssrc_any_inbound;
233 mSRTPPolicyIn.key = mSRTPMasterKeyIn;
234 mSRTPPolicyIn.window_size = 64;
235
236 // Allocate and initailize the SRTP sessions
237 status = srtp_create(&mSRTPSessionIn, &mSRTPPolicyIn);
238 if(status)
239 {
240 ErrLog(<< "Unable to create srtp in session, error code=" << status);
241 return false;
242 }
243 mSRTPSessionInCreated = true;
244
245 return true;
246 }
247
248 err_status_t
249 MediaStream::srtpProtect(void* data, int* size, bool rtcp)
250 {
251 Lock lock(mMutex);
252 err_status_t status = err_status_no_ctx;
253 if(mSRTPSessionOutCreated)
254 {
255 if(rtcp)
256 {
257 status = srtp_protect_rtcp(mSRTPSessionOut, data, size);
258 }
259 else
260 {
261 status = srtp_protect(mSRTPSessionOut, data, size);
262 }
263 }
264 return status;
265 }
266
267 err_status_t
268 MediaStream::srtpUnprotect(void* data, int* size, bool rtcp)
269 {
270 Lock lock(mMutex);
271 err_status_t status = err_status_no_ctx;
272 if(mSRTPSessionInCreated)
273 {
274 if(rtcp)
275 {
276 status = srtp_unprotect_rtcp(mSRTPSessionIn, data, size);
277 }
278 else
279 {
280 status = srtp_unprotect(mSRTPSessionIn, data, size);
281 }
282 }
283 return status;
284 }
285
286 void
287 MediaStream::onFlowReady(unsigned int componentId)
288 {
289 if(componentId == RTP_COMPONENT_ID && mNatTraversalMode == TurnAllocation && mRtcpFlow)
290 {
291 // RTP Flow is ready - we can now activate RTCP flow using the reservation token
292 mRtcpFlow->activateFlow(mRtpFlow->getReservationToken());
293 }
294 else
295 {
296 if(mRtpFlow && mRtcpFlow)
297 {
298 if(mRtpFlow->isReady() && mRtcpFlow->isReady())
299 {
300 mMediaStreamHandler.onMediaStreamReady(mRtpFlow->getSessionTuple(), mRtcpFlow->getSessionTuple());
301 }
302 }
303 else if(mRtpFlow && mRtpFlow->isReady())
304 {
305 mMediaStreamHandler.onMediaStreamReady(mRtpFlow->getSessionTuple(), StunTuple());
306 }
307 }
308 }
309
310 void
311 MediaStream::onFlowError(unsigned int componentId, unsigned int errorCode)
312 {
313 mMediaStreamHandler.onMediaStreamError(errorCode); // TODO assign real error code
314 }
315
316
317 /* ====================================================================
318
319 Copyright (c) 2007-2008, Plantronics, Inc.
320 All rights reserved.
321
322 Redistribution and use in source and binary forms, with or without
323 modification, are permitted provided that the following conditions are
324 met:
325
326 1. Redistributions of source code must retain the above copyright
327 notice, this list of conditions and the following disclaimer.
328
329 2. Redistributions in binary form must reproduce the above copyright
330 notice, this list of conditions and the following disclaimer in the
331 documentation and/or other materials provided with the distribution.
332
333 3. Neither the name of Plantronics nor the names of its contributors
334 may be used to endorse or promote products derived from this
335 software without specific prior written permission.
336
337 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
338 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
339 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
340 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
341 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
342 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
343 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
344 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
345 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
346 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
347 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
348
349 ==================================================================== */

Properties

Name Value
svn:eol-style native
svn:mime-type text/plain

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27