|
1 /* |
|
2 * Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: RTP Datasource |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 // INCLUDE FILES |
|
22 #include <in_sock.h> |
|
23 #include <mmf/common/mmfcontroller.h> |
|
24 |
|
25 #include "rtpapi.h" |
|
26 #include "mccrtpdatasource.h" |
|
27 #include "mccinternalevents.h" |
|
28 #include "formatstatemachine.h" |
|
29 #include "mccrtpdefs.h" |
|
30 #include "mmccinterfacedef.h" |
|
31 #include "mcctimermanager.h" |
|
32 |
|
33 #include <srtpcryptocontext.h> |
|
34 #include <srtpstreamin.h> |
|
35 |
|
36 // MACROS |
|
37 #define MCC_RTPSOURCE_ENDPOINT_ID reinterpret_cast<TUint32>( static_cast<MDataSource*>( this ) ) |
|
38 |
|
39 |
|
40 // ============================= LOCAL FUNCTIONS =============================== |
|
41 |
|
42 // ============================ MEMBER FUNCTIONS =============================== |
|
43 |
|
44 // ----------------------------------------------------------------------------- |
|
45 // CMccRtpDataSource::CMccRtpDataSource |
|
46 // C++ default constructor can NOT contain any code, that |
|
47 // might leave. |
|
48 // ----------------------------------------------------------------------------- |
|
49 // |
|
50 CMccRtpDataSource::CMccRtpDataSource() : |
|
51 CMccDataSource( KMccRtpSourceUid ), |
|
52 MMccRtpInterface(), |
|
53 iStandByTimerValue( KRtpStandByTimer ), |
|
54 iRtpStreamId( KNullId ), |
|
55 iInactivityTimerId( KMaxTUint32 ) |
|
56 { |
|
57 iCurRecvPayloadType = KMccPTNotDefined; |
|
58 } |
|
59 |
|
60 // ----------------------------------------------------------------------------- |
|
61 // CMccRtpDataSource::ConstructSourceL |
|
62 // Symbian 2nd phase constructor can leave. |
|
63 // ----------------------------------------------------------------------------- |
|
64 // |
|
65 void CMccRtpDataSource::ConstructSourceL( const TDesC8& aInitData ) |
|
66 { |
|
67 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::ConstructSourceL" ) |
|
68 |
|
69 SetStateL( ERtpStateConstructed ); |
|
70 |
|
71 TMccRtpSourceSetting rtpSettings; |
|
72 rtpSettings.iStandByTimerValue = 200; |
|
73 TMccRtpSourceSettingBuf rtpSettingsBuf( rtpSettings ); |
|
74 |
|
75 if ( aInitData.Length() > 0) |
|
76 { |
|
77 TMccRtpSourceSettingBuf settingsBuf; |
|
78 settingsBuf.Copy( aInitData ); |
|
79 iStandByTimerValue = settingsBuf().iStandByTimerValue; |
|
80 } |
|
81 |
|
82 iTimer = CMccTimerManager::NewL(); |
|
83 |
|
84 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::ConstructSourceL iStandByTimerValue %d", |
|
85 iStandByTimerValue ) |
|
86 } |
|
87 |
|
88 // ----------------------------------------------------------------------------- |
|
89 // CMccRtpDataSource::NewSourceL |
|
90 // Static constructor. |
|
91 // ----------------------------------------------------------------------------- |
|
92 // |
|
93 MDataSource* CMccRtpDataSource::NewSourceL( TUid /*aImplementationUid*/, |
|
94 const TDesC8& /*aInitData*/ ) |
|
95 { |
|
96 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::NewSourceL" ) |
|
97 |
|
98 CMccRtpDataSource* self = new ( ELeave ) CMccRtpDataSource(); |
|
99 return static_cast<MDataSource*>( self ); |
|
100 } |
|
101 |
|
102 |
|
103 // ----------------------------------------------------------------------------- |
|
104 // CMccRtpDataSource::~CMccRtpDataSource() |
|
105 // Destructor. |
|
106 // ----------------------------------------------------------------------------- |
|
107 // |
|
108 CMccRtpDataSource::~CMccRtpDataSource() |
|
109 { |
|
110 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::~CMccRtpDataSource 0x%x", this ) |
|
111 |
|
112 iBufferToFill = NULL; |
|
113 iEventHandler = NULL; |
|
114 iFillBufferRequester = NULL; |
|
115 |
|
116 CloseStreams(); |
|
117 iUsers.Close(); |
|
118 |
|
119 delete iTimer; |
|
120 delete iJitCalc; |
|
121 |
|
122 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::~CMccRtpDataSource OUT" ) |
|
123 } |
|
124 |
|
125 // ----------------------------------------------------------------------------- |
|
126 // CMccRtpDataSource::FillBufferL |
|
127 // FillBufferL works synchronously. |
|
128 // ----------------------------------------------------------------------------- |
|
129 // |
|
130 void CMccRtpDataSource::FillBufferL( CMMFBuffer* aBuffer, |
|
131 MDataSink* aConsumer, |
|
132 TMediaId /*aMediaId*/ ) |
|
133 { |
|
134 TRACE_RTP_SOURCE_PRINT ( "CMccRtpDataSource::FillBufferL" ) |
|
135 |
|
136 // Sink might want to indicate pause/stop by passing NULL buffer |
|
137 if ( aBuffer ) |
|
138 { |
|
139 __ASSERT_ALWAYS ( aConsumer, User::Leave( KErrArgument ) ); |
|
140 __ASSERT_ALWAYS ( KUidMmfDataBuffer == aBuffer->Type( ), |
|
141 User::Leave( KErrNotSupported ) ); |
|
142 } |
|
143 |
|
144 iBufferToFill = static_cast<CMMFDataBuffer*>( aBuffer ); |
|
145 } |
|
146 |
|
147 // ----------------------------------------------------------------------------- |
|
148 // CMccRtpDataSource::CanCreateSourceBuffer |
|
149 // NOT SUPPORTED. MDataSource pure virtual function must to be implemented. |
|
150 // ----------------------------------------------------------------------------- |
|
151 // |
|
152 TBool CMccRtpDataSource::CanCreateSourceBuffer() |
|
153 { |
|
154 return EFalse; |
|
155 } |
|
156 |
|
157 // ----------------------------------------------------------------------------- |
|
158 // CMccRtpDataSource::CreateSourceBufferL |
|
159 // NOT SUPPORTED. MDataSource pure virtual function must to be implemented. |
|
160 // ----------------------------------------------------------------------------- |
|
161 // |
|
162 CMMFBuffer* CMccRtpDataSource::CreateSourceBufferL( TMediaId /*aMediaId*/, |
|
163 TBool& /*aReference*/ ) |
|
164 { |
|
165 TRACE_RTP_SOURCE_PRINT ( "CMccRtpDataSource::CreateSourceBufferL KErrNotSupported" ) |
|
166 |
|
167 User::Leave( KErrNotSupported ); |
|
168 return NULL; |
|
169 } |
|
170 |
|
171 // ----------------------------------------------------------------------------- |
|
172 // CMccRtpDataSource::RtpPacketReceived |
|
173 // RTP stack callback function for received RTP packet. |
|
174 // ----------------------------------------------------------------------------- |
|
175 // |
|
176 void CMccRtpDataSource::RtpPacketReceived( TRtpId aStreamId, |
|
177 const TRtpRecvHeader& aHeaderInfo, |
|
178 const TDesC8& aPayloadData ) |
|
179 { |
|
180 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceived iSecureKeyExpired: %d", |
|
181 iSecureKeyExpired ) |
|
182 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceived iPayloadType: %u", |
|
183 aHeaderInfo.iPayloadType ) |
|
184 |
|
185 // Filter out also bogus payload types here. NB; should something be done |
|
186 // for the trapped errorcode and bogus RTP packets. Though they should not |
|
187 // reach this point. |
|
188 if ( !iSecureKeyExpired && |
|
189 aHeaderInfo.iPayloadType < KPayloadTypeUndefined ) |
|
190 { |
|
191 TRAP_IGNORE( RtpPacketReceivedL( aStreamId, aHeaderInfo, aPayloadData ) ) |
|
192 } |
|
193 } |
|
194 |
|
195 // ----------------------------------------------------------------------------- |
|
196 // CMccRtpDataSource::RtpPacketReceivedL |
|
197 // RTP stack callback function for received RTP packet. |
|
198 // ----------------------------------------------------------------------------- |
|
199 // |
|
200 void CMccRtpDataSource::RtpPacketReceivedL( TRtpId aStreamId, |
|
201 const TRtpRecvHeader& aHeaderInfo, |
|
202 const TDesC8& aPayloadData ) |
|
203 { |
|
204 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceivedL DATALEN: %d", |
|
205 aPayloadData.Length() ) |
|
206 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceivedL ASTREAM: %d", |
|
207 aStreamId ) |
|
208 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceivedL ISTREAM: %d", |
|
209 iRtpStreamId ) |
|
210 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceivedL SEQ_NUM: %d", |
|
211 aHeaderInfo.iSeqNum ) |
|
212 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceivedL T_STAMP: %d", |
|
213 aHeaderInfo.iTimestamp ) |
|
214 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceivedL MARKER: %d", |
|
215 aHeaderInfo.iMarker ) |
|
216 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RtpPacketReceivedL STATE: %d", |
|
217 State() ) |
|
218 |
|
219 if ( ERtpStatePlaying == State() ) |
|
220 { |
|
221 __ASSERT_ALWAYS( iBufferToFill, User::Leave( KErrNotReady ) ); |
|
222 __ASSERT_ALWAYS( iFillBufferRequester, User::Leave( KErrNotReady ) ); |
|
223 |
|
224 TMccRtpUser* currentUser = ValidatePacketL( aStreamId, aHeaderInfo, aPayloadData ); |
|
225 TBool isCN = EFalse; |
|
226 |
|
227 // Change the main receive PT only if it is not CN. |
|
228 if ( KCnPayloadType != aHeaderInfo.iPayloadType && |
|
229 KCnPayloadTypeReserved != aHeaderInfo.iPayloadType ) |
|
230 { |
|
231 iCurRecvPayloadType = aHeaderInfo.iPayloadType; |
|
232 } |
|
233 else |
|
234 { |
|
235 isCN = ETrue; |
|
236 } |
|
237 |
|
238 if ( InactivityTimerActive() ) |
|
239 { |
|
240 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::resetting inactivity timer" ) |
|
241 |
|
242 StartInactivityTimerL( iTimeoutTime ); |
|
243 } |
|
244 |
|
245 // Note that ValidataPacketL may return a NULL ptr, thus guard against |
|
246 // it. |
|
247 if ( currentUser ) |
|
248 { |
|
249 StartRtpStandByTimerL( currentUser ); |
|
250 DoStandByDecision( currentUser ); |
|
251 } |
|
252 |
|
253 // Do jitter calculations |
|
254 if ( iJitCalc->IsObserving() ) |
|
255 { |
|
256 iJitCalc->RtpPacketReceived( aHeaderInfo.iTimestamp, |
|
257 aHeaderInfo.iMarker ); |
|
258 } |
|
259 |
|
260 // First packet after SourcePlayL, notify event handler by sending |
|
261 // the event. |
|
262 if ( !iDlStreamStarted ) |
|
263 { |
|
264 iDlStreamStarted = ETrue; |
|
265 SendInternalRtpEventToClient( iEventHandler, |
|
266 KMccRtpSourceUid, |
|
267 KMccInternalRtpSrcMmfEvent, |
|
268 KMccActivityEvent, |
|
269 MCC_RTPSOURCE_ENDPOINT_ID ); |
|
270 } |
|
271 |
|
272 // CN is not currently sent forward to decoding and playback. It |
|
273 // causes problems with jitterbuffering and results into a degraded |
|
274 // audio quality. |
|
275 if ( !isCN ) |
|
276 { |
|
277 TRAPD( err, PlayoutRtpPacketL( aHeaderInfo, aPayloadData ) ) |
|
278 |
|
279 // Notify the event handler about error cases so appropriate |
|
280 // actions can be taken. |
|
281 if ( KErrNone != err ) |
|
282 { |
|
283 SendInternalRtpEventToClient( iEventHandler, |
|
284 KMccRtpSourceUid, |
|
285 KMccInternalRtpSrcMmfEvent, |
|
286 KMccStreamError, |
|
287 MCC_RTPSOURCE_ENDPOINT_ID, |
|
288 err ); |
|
289 } |
|
290 } |
|
291 } |
|
292 } |
|
293 |
|
294 // ----------------------------------------------------------------------------- |
|
295 // CMccRtpDataSource::SetSourceDataTypeCode |
|
296 // Sets the sources datatype code ( Codec ) |
|
297 // ----------------------------------------------------------------------------- |
|
298 // |
|
299 TInt CMccRtpDataSource::SetSourceDataTypeCode( TFourCC aCodec, TMediaId /*aMedia*/ ) |
|
300 { |
|
301 iCodecInfo.iFourCC = aCodec; |
|
302 return KErrNone; |
|
303 } |
|
304 |
|
305 // ----------------------------------------------------------------------------- |
|
306 // CMccRtpDataSource::SourceDataTypeCode() |
|
307 // Sets the datatype code ( codec ) |
|
308 // ----------------------------------------------------------------------------- |
|
309 // |
|
310 TFourCC CMccRtpDataSource::SourceDataTypeCode( TMediaId /*aMediaId*/ ) |
|
311 { |
|
312 return iCodecInfo.iFourCC; |
|
313 } |
|
314 |
|
315 // ----------------------------------------------------------------------------- |
|
316 // CMccRtpDataSource::BufferEmptiedL |
|
317 // CMccRtpDataSource supports only passive mode of operation. |
|
318 // Thus, Datapath->EmptyBufferL isn't called. |
|
319 // ----------------------------------------------------------------------------- |
|
320 // |
|
321 void CMccRtpDataSource::BufferEmptiedL( CMMFBuffer* /*aBuffer*/ ) |
|
322 { |
|
323 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::BufferEmptiedL KErrNotSupported" ) |
|
324 |
|
325 User::Leave( KErrNotSupported ); |
|
326 } |
|
327 |
|
328 // ----------------------------------------------------------------------------- |
|
329 // CMccRtpDataSource::SourceThreadLogon |
|
330 // |
|
331 // Method to 'logon' the data source to the same thread that source will be |
|
332 // consuming data in. Thread specific initialisation is done here. |
|
333 // ----------------------------------------------------------------------------- |
|
334 // |
|
335 TInt CMccRtpDataSource::SourceThreadLogon( MAsyncEventHandler& aEventHandler ) |
|
336 { |
|
337 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourceThreadLogon" ) |
|
338 |
|
339 TInt err( KErrNone ); |
|
340 |
|
341 iEventHandler = &aEventHandler; |
|
342 if ( NULL == iJitCalc ) |
|
343 { |
|
344 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourceThreadLogon,\ |
|
345 create jitter calculator" ) |
|
346 TRAP( err, iJitCalc = CMccJitterCalculator::NewL( *this ) ); |
|
347 } |
|
348 |
|
349 return err; |
|
350 } |
|
351 |
|
352 // ----------------------------------------------------------------------------- |
|
353 // CMccRtpDataSource::SourceThreadLogoff |
|
354 // |
|
355 // Method to 'logoff' the data source from the same thread that source consumes |
|
356 // data in. Thread specific releasing of resources is done here. |
|
357 // ----------------------------------------------------------------------------- |
|
358 // |
|
359 void CMccRtpDataSource::SourceThreadLogoff() |
|
360 { |
|
361 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourceThreadLogoff" ) |
|
362 StopKeepalive(); |
|
363 |
|
364 iEventHandler = NULL; |
|
365 |
|
366 // Close the streams (if any) |
|
367 if ( KNullId != iRtpStreamId ) |
|
368 { |
|
369 iRtpAPI->UnregisterRtpObserver( iSessionID ); |
|
370 } |
|
371 |
|
372 CloseStreams(); |
|
373 iRtpAPI = NULL; |
|
374 iRtpStreamId = KNullId; |
|
375 |
|
376 iBufferToFill = NULL; |
|
377 |
|
378 delete iTimer; |
|
379 iTimer = NULL; |
|
380 |
|
381 delete iJitCalc; |
|
382 iJitCalc = NULL; |
|
383 } |
|
384 |
|
385 // --------------------------------------------------------------------------- |
|
386 // CMccRtpDataSource::SourcePrimeL |
|
387 // Source must be primed before playing. |
|
388 // ----------------------------------------------------------------------------- |
|
389 // |
|
390 void CMccRtpDataSource::SourcePrimeL() |
|
391 { |
|
392 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourcePrimeL" ) |
|
393 |
|
394 SetStateL( ERtpStatePrimed ); |
|
395 |
|
396 SendStreamEventToClient( KMccStreamPrepared ); |
|
397 } |
|
398 |
|
399 // ----------------------------------------------------------------------------- |
|
400 // CMccRtpDataSource::SourcePlayL |
|
401 // Start receiving RTP packets. |
|
402 // ----------------------------------------------------------------------------- |
|
403 // |
|
404 void CMccRtpDataSource::SourcePlayL() |
|
405 { |
|
406 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourcePlayL" ) |
|
407 if ( iSecureKeyExpired ) |
|
408 { |
|
409 TRACE_RTP_SINK_PRINT( "Leave becuase the secure key expired" ) |
|
410 User::Leave( KErrGeneral ); |
|
411 } |
|
412 //Leave when is the secure evnet key expired and try to restart |
|
413 iPacketsReceived = 0; |
|
414 iDlStreamStarted = EFalse; |
|
415 |
|
416 TSourceSinkState oldState = State(); |
|
417 |
|
418 __ASSERT_ALWAYS( iJitCalc, User::Leave( KErrNotFound ) ); |
|
419 iJitCalc->ResetCounters(); |
|
420 |
|
421 ResetStandBy(); |
|
422 |
|
423 SetStateL( ERtpStatePlaying ); |
|
424 |
|
425 // Enable keepalive while receiving (depending on codec settings) |
|
426 // Keepalive is not supported in recvonly secure sessions |
|
427 if ( !iSecSession ) |
|
428 { |
|
429 StartKeepaliveL( *iRtpMediaClock ); |
|
430 } |
|
431 |
|
432 if ( oldState == ERtpStatePaused ) |
|
433 { |
|
434 SendStreamEventToClient( KMccStreamResumed ); |
|
435 } |
|
436 else |
|
437 { |
|
438 SendStreamEventToClient( KMccStreamStarted ); |
|
439 } |
|
440 } |
|
441 |
|
442 // ----------------------------------------------------------------------------- |
|
443 // CMccRtpDataSource::SourcePauseL |
|
444 // Pause RTP packet receiving. |
|
445 // ----------------------------------------------------------------------------- |
|
446 // |
|
447 void CMccRtpDataSource::SourcePauseL() |
|
448 { |
|
449 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourcePauseL" ) |
|
450 |
|
451 iPacketsReceived = 0; |
|
452 __ASSERT_ALWAYS( iJitCalc, User::Leave( KErrNotFound ) ); |
|
453 iJitCalc->ResetCounters(); |
|
454 |
|
455 SetStateL( ERtpStatePaused ); |
|
456 |
|
457 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourcePauseL\ |
|
458 stop standby timers" ) |
|
459 |
|
460 StopRtpStandByTimers(); |
|
461 |
|
462 SendStreamEventToClient( KMccStreamPaused ); |
|
463 } |
|
464 |
|
465 // ----------------------------------------------------------------------------- |
|
466 // CMccRtpDataSource::SourceStopL |
|
467 // Stop RTP packet receiving. |
|
468 // ----------------------------------------------------------------------------- |
|
469 // |
|
470 void CMccRtpDataSource::SourceStopL() |
|
471 { |
|
472 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourceStopL" ) |
|
473 |
|
474 iDlStreamStarted = EFalse; |
|
475 SetStateL( ERtpStateStopped ); |
|
476 |
|
477 StopKeepalive(); |
|
478 |
|
479 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SourceStopL,\ |
|
480 Stop standby timers" ) |
|
481 |
|
482 StopRtpStandByTimers(); |
|
483 |
|
484 SendStreamEventToClient( KMccStreamStopped ); |
|
485 } |
|
486 |
|
487 // ----------------------------------------------------------------------------- |
|
488 // CMccRtpDataSource::PlayoutRtpPacketL |
|
489 // Pass filled buffer to the data sink of RTP data source. |
|
490 // ----------------------------------------------------------------------------- |
|
491 // |
|
492 void CMccRtpDataSource::PlayoutRtpPacketL( const TRtpRecvHeader& aHeaderInfo, |
|
493 const TDesC8& aPayloadData ) |
|
494 { |
|
495 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::PlayoutRtpPacketL" ) |
|
496 __ASSERT_ALWAYS( iBufferToFill, User::Leave( KErrNotReady ) ); |
|
497 __ASSERT_ALWAYS( iFillBufferRequester, User::Leave( KErrNotReady ) ); |
|
498 |
|
499 iBufferToFill->Data().Copy( aPayloadData ); |
|
500 |
|
501 CPayloadFormatRead* sink = static_cast<CPayloadFormatRead*>( iFillBufferRequester ); |
|
502 User::LeaveIfNull( sink ); |
|
503 sink->DataBufferFilledL( iBufferToFill, aHeaderInfo ); |
|
504 } |
|
505 |
|
506 |
|
507 // ----------------------------------------------------------------------------- |
|
508 // CMccRtpDataSource::DoCreateStreamL |
|
509 // Creates a receive stream. |
|
510 // ----------------------------------------------------------------------------- |
|
511 // |
|
512 void CMccRtpDataSource::DoCreateStreamL() |
|
513 { |
|
514 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::DoCreateStreamL IN !!!!" ) |
|
515 __ASSERT_ALWAYS( KNullId == iRtpStreamId, User::Leave( KErrAlreadyExists ) ); |
|
516 __ASSERT_ALWAYS( NULL != iRtpAPI, User::Leave( KErrNotReady ) ); |
|
517 |
|
518 TRcvStreamParams rcvParams; |
|
519 rcvParams.iPayloadType = iCodecInfo.iPayloadType; |
|
520 |
|
521 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::DoCreateStreamL CONFIGURED_PT: %u", |
|
522 iCodecInfo.iPayloadType ) |
|
523 |
|
524 iRtpStreamId = iRtpAPI->CreateReceiveStreamL( iSessionID, rcvParams ); |
|
525 if ( KNullId == iRtpStreamId ) |
|
526 { |
|
527 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::DoCreateStreamL KErrCouldNotConnect 1" ) |
|
528 |
|
529 User::Leave( KErrCouldNotConnect ); |
|
530 } |
|
531 |
|
532 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::DoCreateStreamL SetSamplingRate 1" ) |
|
533 |
|
534 User::LeaveIfError( |
|
535 iRtpAPI->SetSamplingRate( iCodecInfo.iPayloadType, KDefSampleRate ) ); |
|
536 |
|
537 if ( KMccPayloadTypeMax != iCodecInfo.iRedundantPayload ) |
|
538 { |
|
539 User::LeaveIfError( iRtpAPI->SetSamplingRate( |
|
540 iCodecInfo.iRedundantPayload, KDefSampleRate ) ); |
|
541 } |
|
542 |
|
543 User::LeaveIfError( iRtpAPI->RegisterRtpObserver( iSessionID, *this ) ); |
|
544 |
|
545 DoCreateSrtpStreamL(); |
|
546 |
|
547 TRACE_RTP_SINK_PRINT( "CMccRtpDataSource::DoCreateStreamL OUT" ) |
|
548 } |
|
549 |
|
550 // ----------------------------------------------------------------------------- |
|
551 // CMccRtpDataSource::DoCreateSrtpStreamL |
|
552 // ----------------------------------------------------------------------------- |
|
553 // |
|
554 void CMccRtpDataSource::DoCreateSrtpStreamL() |
|
555 { |
|
556 TRACE_RTP_SINK_PRINT( "CMccRtpDataSource::DoCreateStreamL IN" ) |
|
557 if ( !iSrtpStream && iContext && iSecSession && KNullId != iRtpStreamId ) |
|
558 { |
|
559 TRACE_RTP_SINK_PRINT( "CMccRtpDataSource::DoCreateStreamL, creating" ) |
|
560 iSrtpStream = CSRTPStreamIn::NewL( *iSecSession, iContext, *this ); |
|
561 } |
|
562 TRACE_RTP_SINK_PRINT( "CMccRtpDataSource::DoCreateStreamL OUT" ) |
|
563 } |
|
564 |
|
565 // ----------------------------------------------------------------------------- |
|
566 // CMccRtpDataSource::NegotiateSourceL |
|
567 // Derived from MDataSource |
|
568 // ----------------------------------------------------------------------------- |
|
569 // |
|
570 void CMccRtpDataSource::NegotiateSourceL( MDataSink& aDataSink ) |
|
571 { |
|
572 iFillBufferRequester = &aDataSink; |
|
573 } |
|
574 |
|
575 // ----------------------------------------------------------------------------- |
|
576 // CMccRtpDataSource::SendMediaSignallingL |
|
577 // Derived from CRtpInterface |
|
578 // ----------------------------------------------------------------------------- |
|
579 // |
|
580 void CMccRtpDataSource::SendMediaSignallingL( const TMccEvent& aEvent ) |
|
581 { |
|
582 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SendMediaSignallingL" ) |
|
583 |
|
584 __ASSERT_ALWAYS( aEvent.iEventCategory == KMccEventCategoryRtcp && |
|
585 aEvent.iEventType == KMccRtcpControl && |
|
586 iEnableRtcp, |
|
587 User::Leave( KErrNotSupported ) ); |
|
588 |
|
589 __ASSERT_ALWAYS( iRtpAPI, User::Leave( KErrNotReady ) ); |
|
590 |
|
591 const TMccRtcpEventData& rtcpEvent = |
|
592 (*reinterpret_cast<const TMccRtcpEventDataPackage*>( |
|
593 &aEvent.iEventData ))(); |
|
594 |
|
595 switch ( rtcpEvent.iRtcpPacketType ) |
|
596 { |
|
597 case KRtcpRrPacket: |
|
598 { |
|
599 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SendMediaSignallingL, RR" ) |
|
600 |
|
601 __ASSERT_ALWAYS( KNullId != iRtpStreamId, User::Leave( KErrNotReady ) ); |
|
602 User::LeaveIfError( iRtpAPI->SendRtcpRrPacket( iRtpStreamId ) ); |
|
603 break; |
|
604 } |
|
605 default: |
|
606 { |
|
607 User::Leave( KErrArgument ); |
|
608 break; |
|
609 } |
|
610 } |
|
611 } |
|
612 |
|
613 // ----------------------------------------------------------------------------- |
|
614 // CMccRtpDataSource::StartInactivityTimer |
|
615 // Starts inactivity timer for a stream |
|
616 // ----------------------------------------------------------------------------- |
|
617 // |
|
618 void CMccRtpDataSource::StartInactivityTimerL( TUint32 aTimeoutTime ) |
|
619 { |
|
620 TRACE_RTP_SOURCE_PRINT ( "CMccRtpDataSource::StartInactivityTimerL" ) |
|
621 |
|
622 if( aTimeoutTime == 0 ) |
|
623 { |
|
624 User::Leave( KErrArgument ); |
|
625 } |
|
626 |
|
627 iTimeoutTime = aTimeoutTime; |
|
628 |
|
629 StopInactivityTimerL(); |
|
630 |
|
631 iInactivityTimerId = iTimer->StartL( this, aTimeoutTime ); |
|
632 |
|
633 TRACE_RTP_SOURCE_PRINT2 ( "CMccRtpDataSource::StartInactivityTimerL, timer id: %d", |
|
634 iInactivityTimerId ) |
|
635 |
|
636 TRACE_RTP_SOURCE_PRINT ( "CMccRtpDataSource::StartInactivityTimerL, Exit" ) |
|
637 } |
|
638 |
|
639 // ----------------------------------------------------------------------------- |
|
640 // CMccRtpDataSource::StopInactivityTimer |
|
641 // Stops inactivity timer for a stream |
|
642 // ----------------------------------------------------------------------------- |
|
643 // |
|
644 void CMccRtpDataSource::StopInactivityTimerL() |
|
645 { |
|
646 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::StopInactivityTimerL" ) |
|
647 |
|
648 // It does not matter whether timer is active or not |
|
649 iTimer->Stop( iInactivityTimerId ); |
|
650 } |
|
651 |
|
652 |
|
653 // ----------------------------------------------------------------------------- |
|
654 // CMccRtpDataSource::StandBy |
|
655 // ----------------------------------------------------------------------------- |
|
656 // |
|
657 TInt CMccRtpDataSource::StandBy( |
|
658 TMccStandbyActionType aActionType, |
|
659 TUint aPayloadType ) |
|
660 { |
|
661 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::StandBy, action type:%d", aActionType ) |
|
662 |
|
663 TRAPD( err, StandByL( aActionType, aPayloadType ) ); |
|
664 if ( err != KErrNone ) |
|
665 { |
|
666 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::StandByL, error=%d", err ) |
|
667 } |
|
668 |
|
669 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::StandBy, Exit" ) |
|
670 return err; |
|
671 } |
|
672 |
|
673 // ----------------------------------------------------------------------------- |
|
674 // CMccRtpDataSource::RtpStreamId |
|
675 // ----------------------------------------------------------------------------- |
|
676 // |
|
677 TRtpId CMccRtpDataSource::RtpStreamId() |
|
678 { |
|
679 return iRtpStreamId; |
|
680 } |
|
681 |
|
682 // ----------------------------------------------------------------------------- |
|
683 // CMccRtpDataSource::RegisterPayloadTypesL |
|
684 // ----------------------------------------------------------------------------- |
|
685 // |
|
686 void CMccRtpDataSource::RegisterPayloadTypesL( const RArray<TUint>& aPayloadTypes ) |
|
687 { |
|
688 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::RegisterPayloadTypesL" ) |
|
689 |
|
690 #ifdef _DEBUG |
|
691 |
|
692 for( TInt k = 0; k < aPayloadTypes.Count(); k++ ) |
|
693 { |
|
694 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::RegisterPayloadTypesL PT: %u", |
|
695 aPayloadTypes[k] ) |
|
696 } |
|
697 |
|
698 #endif |
|
699 |
|
700 |
|
701 TInt ind = aPayloadTypes.Count(); |
|
702 while ( ind-- ) |
|
703 { |
|
704 if ( !FindUserEntryByPayloadType( aPayloadTypes[ind] ) ) |
|
705 { |
|
706 TMccRtpUser entry( iEventHandler ); |
|
707 entry.iPayloadType = aPayloadTypes[ind]; |
|
708 iUsers.AppendL( entry ); |
|
709 } |
|
710 } |
|
711 } |
|
712 |
|
713 // ----------------------------------------------------------------------------- |
|
714 // CMccRtpDataSource::UnRegisterPayloadTypes |
|
715 // Unregisters payload types to accept. |
|
716 // ----------------------------------------------------------------------------- |
|
717 // |
|
718 void CMccRtpDataSource::UnRegisterPayloadTypes( const RArray<TUint>& aPayloadTypes ) |
|
719 { |
|
720 #ifdef _DEBUG |
|
721 |
|
722 for( TInt k = 0; k < aPayloadTypes.Count(); k++ ) |
|
723 { |
|
724 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::UnRegisterPayloadTypes PT: %u", |
|
725 aPayloadTypes[k] ) |
|
726 } |
|
727 |
|
728 #endif |
|
729 |
|
730 TInt ind = aPayloadTypes.Count(); |
|
731 while ( ind-- ) |
|
732 { |
|
733 TMccRtpUser* userEntry = FindUserEntryByPayloadType( aPayloadTypes[ind] ); |
|
734 TInt index = FindUserEntryIndex( userEntry ); |
|
735 if ( index != KErrNotFound ) |
|
736 { |
|
737 iUsers.Remove( index ); |
|
738 } |
|
739 } |
|
740 } |
|
741 |
|
742 // ----------------------------------------------------------------------------- |
|
743 // CMccRtpDataSource::ValidatePacketL |
|
744 // Validates the received RTP packet and it's header |
|
745 // ----------------------------------------------------------------------------- |
|
746 // |
|
747 TMccRtpUser* CMccRtpDataSource::ValidatePacketL( const TRtpId aStreamId, |
|
748 const TRtpRecvHeader& aHeader, const TDesC8& aData ) |
|
749 { |
|
750 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::ValidatePacketL" ) |
|
751 |
|
752 __ASSERT_ALWAYS( iBufferToFill, User::Leave( KErrNotReady ) ); |
|
753 __ASSERT_ALWAYS( iBufferToFill->Data().MaxSize() >= aData.Size(), |
|
754 User::Leave( KErrOverflow ) ); |
|
755 |
|
756 TMccRtpUser* userEntry = FindUserEntryByPayloadType( aHeader.iPayloadType ); |
|
757 TBool isCN = EFalse; |
|
758 |
|
759 if ( KCnPayloadType == aHeader.iPayloadType || |
|
760 KCnPayloadTypeReserved == aHeader.iPayloadType ) |
|
761 { |
|
762 isCN = ETrue; |
|
763 } |
|
764 |
|
765 if ( !userEntry ) |
|
766 { |
|
767 if ( iCurRecvPayloadType != aHeader.iPayloadType && !isCN ) |
|
768 { |
|
769 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::ValidatePacketL Unknown media" ) |
|
770 |
|
771 iCurRecvPayloadType = aHeader.iPayloadType; |
|
772 |
|
773 // Support for unsymmetric speech codecs, payload type is reported as |
|
774 // an error code in this case. |
|
775 SendStreamEventToClient( KMccUnknownMediaReceived, |
|
776 aHeader.iPayloadType ); |
|
777 } |
|
778 |
|
779 if ( !isCN ) |
|
780 { |
|
781 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::ValidatePacketL PT NOK" ) |
|
782 |
|
783 User::Leave( KErrNotSupported ); |
|
784 } |
|
785 |
|
786 // Try to find user on current PT so the inactivity could be reset. |
|
787 userEntry = FindUserEntryByPayloadType( iCurRecvPayloadType ); |
|
788 } |
|
789 else if ( userEntry && |
|
790 KMaxTUint == userEntry->iTimerId && |
|
791 isCN ) |
|
792 { |
|
793 // This is because timers are used against the main payloadtype in CN |
|
794 // cases. |
|
795 userEntry = FindUserEntryByPayloadType( iCurRecvPayloadType ); |
|
796 } |
|
797 |
|
798 if ( iRtpAPI && ( iRtpStreamId != aStreamId ) ) |
|
799 { |
|
800 // Adapt to SSRC change |
|
801 iRtpAPI->CloseStream( iRtpStreamId ); |
|
802 iRtpStreamId = aStreamId; |
|
803 } |
|
804 |
|
805 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::ValidatePacketL userEntry: 0x%x", |
|
806 userEntry ) |
|
807 |
|
808 return userEntry; |
|
809 } |
|
810 |
|
811 // ----------------------------------------------------------------------------- |
|
812 // CMccRtpDataSource::SendStreamEventToClient() |
|
813 // ----------------------------------------------------------------------------- |
|
814 // |
|
815 void CMccRtpDataSource::SendStreamEventToClient( |
|
816 TMccEventType aEventType, |
|
817 TInt aError, |
|
818 TUint32 aTargetPayloadType ) |
|
819 { |
|
820 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SendStreamEventToClient" ) |
|
821 |
|
822 if ( iEventHandler ) |
|
823 { |
|
824 ClearMccEvent(); |
|
825 |
|
826 iMccEvent.iEndpointId = MCC_RTPSOURCE_ENDPOINT_ID; |
|
827 iMccEvent.iEventCategory = KMccEventCategoryStream; |
|
828 iMccEvent.iEventType = aEventType; |
|
829 iMccEvent.iErrorCode = aError; |
|
830 |
|
831 if ( aTargetPayloadType != KMccPTNotDefined ) |
|
832 { |
|
833 iMccEvent.iEventNumData = KMccPayloadSpecificEvent; |
|
834 iMccEvent.iReserved = aTargetPayloadType; |
|
835 } |
|
836 |
|
837 TMccInternalEvent internalEvent( KMccRtpSourceUid, |
|
838 EMccInternalEventNone, |
|
839 iMccEvent ); |
|
840 |
|
841 iEventHandler->SendEventToClient( internalEvent ); |
|
842 } |
|
843 else |
|
844 { |
|
845 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SendStreamEventToClient, \ |
|
846 iEventHandler=NULL" ) |
|
847 } |
|
848 } |
|
849 |
|
850 // ----------------------------------------------------------------------------- |
|
851 // CMccRtpDataSource::SendJitterEvent() |
|
852 // ----------------------------------------------------------------------------- |
|
853 // |
|
854 void CMccRtpDataSource::SendJitterEvent( TMccRtpEventData aEvent, TInt aError ) |
|
855 { |
|
856 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::SendJitterEvent" ) |
|
857 |
|
858 SendInternalRtpEventToClient( iEventHandler, |
|
859 KMccRtpSourceUid, |
|
860 EMccInternalJitterEventStatusReport, |
|
861 KMccMediaQualityStatus, |
|
862 MCC_RTPSOURCE_ENDPOINT_ID, |
|
863 aError, |
|
864 aEvent.iJitterEstimate, |
|
865 aEvent.iPacketsReceived, |
|
866 aEvent.iPrevTransTime, |
|
867 aEvent.iTriggeredJitterLevel ); |
|
868 } |
|
869 |
|
870 // ----------------------------------------------------------------------------- |
|
871 // CMccRtpDataSource::SourceCustomCommand() |
|
872 // |
|
873 // ----------------------------------------------------------------------------- |
|
874 // |
|
875 void CMccRtpDataSource::SourceCustomCommand( TMMFMessage& aMessage ) |
|
876 { |
|
877 TRAPD( err, SourceCustomCommandL( aMessage ) ); |
|
878 |
|
879 #ifdef TRACE_RTP_SOURCE |
|
880 RDebug::Print( _L("CMcpRtpDataSource::SourceCustomCommand ERR: %d"), err ); |
|
881 #endif |
|
882 |
|
883 aMessage.Complete( err ); |
|
884 } |
|
885 |
|
886 // ----------------------------------------------------------------------------- |
|
887 // CMccRtpDataSource::SourceCustomCommandL() |
|
888 // Worker function for TRAP'ping possible leaves that custom commands may have |
|
889 // ----------------------------------------------------------------------------- |
|
890 // |
|
891 void CMccRtpDataSource::SourceCustomCommandL( TMMFMessage& aMessage ) |
|
892 { |
|
893 #ifdef TRACE_RTP_SOURCE |
|
894 RDebug::Print( _L("CMcpRtpDataSource::SourceCustomCommandL FUNC: %d"), aMessage.Function() ); |
|
895 #endif |
|
896 |
|
897 switch( aMessage.Function() ) |
|
898 { |
|
899 case EStartMediaQualityObserving: |
|
900 // Send message data to jitter calculator, SetMediaConfigsL will |
|
901 // leave with KErrAlreadyExists if there is already a pending |
|
902 // client request, which will propagate to SourceCustomCommand() |
|
903 iJitCalc->SetMediaConfigsL( aMessage ); |
|
904 User::LeaveIfError( iJitCalc->StartObserving() ); |
|
905 break; |
|
906 |
|
907 case ECancelMediaQualityObserving: |
|
908 if ( iJitCalc->IsObserving() ) |
|
909 { |
|
910 iJitCalc->CancelObserving(); |
|
911 } |
|
912 else |
|
913 { |
|
914 User::Leave( KErrNotReady ); |
|
915 } |
|
916 break; |
|
917 |
|
918 default: |
|
919 // Not supported CustomCommand => Leave |
|
920 User::Leave( KErrNotSupported ); |
|
921 break; |
|
922 } |
|
923 } |
|
924 |
|
925 // ----------------------------------------------------------------------------- |
|
926 // CMccRtpDataSource::InactivityTimerActive |
|
927 // ----------------------------------------------------------------------------- |
|
928 // |
|
929 TBool CMccRtpDataSource::InactivityTimerActive() const |
|
930 { |
|
931 return ( iInactivityTimerId != KMaxTUint32 && |
|
932 iTimer && |
|
933 iTimer->IsRunning( iInactivityTimerId ) ); |
|
934 } |
|
935 |
|
936 // ----------------------------------------------------------------------------- |
|
937 // CMccRtpDataSource::StandbyEnabled |
|
938 // ----------------------------------------------------------------------------- |
|
939 // |
|
940 TBool CMccRtpDataSource::StandbyEnabled( TMccRtpUser* aUser ) const |
|
941 { |
|
942 return ( iCodecInfo.iType == KUidMediaTypeAudio && |
|
943 iStandByTimerValue > 0 && |
|
944 aUser && |
|
945 aUser->iStandbyState != ETurnedOff ); |
|
946 } |
|
947 |
|
948 // ----------------------------------------------------------------------------- |
|
949 // CMccRtpDataSource::StandByL |
|
950 // ----------------------------------------------------------------------------- |
|
951 // |
|
952 void CMccRtpDataSource::StandByL( |
|
953 TMccStandbyActionType aActionType, |
|
954 TUint aPayloadType ) |
|
955 { |
|
956 TMccRtpUser* userEntry = FindUserEntryByPayloadType( aPayloadType ); |
|
957 __ASSERT_ALWAYS( userEntry, User::Leave( KErrNotFound ) ); |
|
958 |
|
959 switch ( aActionType ) |
|
960 { |
|
961 case EForceStandby: |
|
962 { |
|
963 if ( ERtpStatePlaying == State() ) |
|
964 { |
|
965 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::StandByL, force" ) |
|
966 iTimer->Stop( userEntry->iTimerId ); |
|
967 HandleStandByL( userEntry ); |
|
968 } |
|
969 break; |
|
970 } |
|
971 case EActivateStandby: |
|
972 { |
|
973 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::StandByL, activate, \ |
|
974 standby state before: %d", userEntry->iStandbyState ) |
|
975 |
|
976 if ( userEntry->iStandbyState == EActivating ) |
|
977 { |
|
978 // If currently activating, activation was not possible, |
|
979 // stop timer and wait that mechanism is activated again |
|
980 iTimer->Stop( userEntry->iTimerId ); |
|
981 } |
|
982 else if ( userEntry->iStandbyState == EActive ) |
|
983 { |
|
984 // If was active, re-activation can |
|
985 // be tried when data for this user is received. |
|
986 iTimer->Stop( userEntry->iTimerId ); |
|
987 userEntry->iStandbyState = EInactive; |
|
988 } |
|
989 else |
|
990 { |
|
991 // NOP |
|
992 } |
|
993 |
|
994 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::StandByL, activate, \ |
|
995 standby state after: %d", userEntry->iStandbyState ) |
|
996 |
|
997 break; |
|
998 } |
|
999 case EDeactivateStandby: |
|
1000 { |
|
1001 TRACE_RTP_SOURCE_PRINT( "CMccRtpDataSource::StandByL, deactivate" ) |
|
1002 iTimer->Stop( userEntry->iTimerId ); |
|
1003 userEntry->iStandbyState = ETurnedOff; |
|
1004 break; |
|
1005 } |
|
1006 default: |
|
1007 { |
|
1008 User::Leave( KErrArgument ); |
|
1009 break; |
|
1010 } |
|
1011 } |
|
1012 } |
|
1013 |
|
1014 // ----------------------------------------------------------------------------- |
|
1015 // CMccRtpDataSource::StartRtpStandByTimerL |
|
1016 // Starts rtp standby timer |
|
1017 // ----------------------------------------------------------------------------- |
|
1018 // |
|
1019 void CMccRtpDataSource::StartRtpStandByTimerL( TMccRtpUser* aUser ) |
|
1020 { |
|
1021 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::StartRtpStandByTimer iStartedOnce: %d", |
|
1022 aUser->iStartedOnce ) |
|
1023 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::StartRtpStandByTimer iPayloadType: %d", |
|
1024 aUser->iPayloadType ) |
|
1025 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::StartRtpStandByTimer iTimerId: %d", |
|
1026 aUser->iTimerId ) |
|
1027 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::StartRtpStandByTimer iStandbyState: %d", |
|
1028 aUser->iStandbyState ) |
|
1029 |
|
1030 if ( StandbyEnabled( aUser ) ) |
|
1031 { |
|
1032 // It does not matter whether timer is active or not |
|
1033 iTimer->Stop( aUser->iTimerId ); |
|
1034 aUser->iTimerId = iTimer->StartL( this, iStandByTimerValue ); |
|
1035 |
|
1036 TRACE_RTP_SOURCE_PRINT ( "CMCCRtpDataSource::StartRtpStandByTimer standby enabled" ) |
|
1037 } |
|
1038 } |
|
1039 |
|
1040 // ----------------------------------------------------------------------------- |
|
1041 // CMccRtpDataSource::StopRtpStandByTimers |
|
1042 // Stop rtp standby timers |
|
1043 // ----------------------------------------------------------------------------- |
|
1044 // |
|
1045 void CMccRtpDataSource::StopRtpStandByTimers() |
|
1046 { |
|
1047 TRACE_RTP_SOURCE_PRINT ( "CMccRtpDataSource::StopRtpStandByTimer" ) |
|
1048 |
|
1049 // Stop all rtp standby timers |
|
1050 for ( TInt i = 0; i < iUsers.Count(); i++ ) |
|
1051 { |
|
1052 iTimer->Stop( iUsers[ i ].iTimerId ); |
|
1053 } |
|
1054 } |
|
1055 |
|
1056 // ----------------------------------------------------------------------------- |
|
1057 // CMccRtpDataSource::ResetStandBy |
|
1058 // ----------------------------------------------------------------------------- |
|
1059 // |
|
1060 void CMccRtpDataSource::ResetStandBy() |
|
1061 { |
|
1062 TRACE_RTP_SOURCE_PRINT ( "CMccRtpDataSource::ResetStandBy" ) |
|
1063 |
|
1064 // Stop all rtp standby timers |
|
1065 for ( TInt i = 0; i < iUsers.Count(); i++ ) |
|
1066 { |
|
1067 iUsers[ i ].iStandbyState = EInactive; |
|
1068 } |
|
1069 } |
|
1070 |
|
1071 // ----------------------------------------------------------------------------- |
|
1072 // CMccRtpDataSource::HandleStandByL |
|
1073 // ----------------------------------------------------------------------------- |
|
1074 // |
|
1075 void CMccRtpDataSource::HandleStandByL( TMccRtpUser* aUser ) |
|
1076 { |
|
1077 __ASSERT_ALWAYS( StandbyEnabled( aUser ), User::Leave( KErrNotSupported ) ); |
|
1078 |
|
1079 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::HandleStandByL, deactivate, \ |
|
1080 standby state before: %d", aUser->iStandbyState ) |
|
1081 |
|
1082 aUser->iStandbyState = EDeactivating; |
|
1083 |
|
1084 SendStreamEventToClient( KMccStandbyInactivityEvent, |
|
1085 KErrNone, |
|
1086 aUser->iPayloadType ); |
|
1087 |
|
1088 aUser->iStandbyState = EInactive; |
|
1089 |
|
1090 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::HandleStandByL, deactivate, \ |
|
1091 standby state after: %d", aUser->iStandbyState ) |
|
1092 } |
|
1093 |
|
1094 // --------------------------------------------------------------------------- |
|
1095 // CMccRtpDataSource::DoStandByDecision |
|
1096 // If standby activation has been done for some other payload type than |
|
1097 // currently received payload type, stream for old payload type is paused |
|
1098 // and stream for the new payload type is started/resumed. |
|
1099 // --------------------------------------------------------------------------- |
|
1100 // |
|
1101 void CMccRtpDataSource::DoStandByDecision( TMccRtpUser* aUser ) |
|
1102 { |
|
1103 |
|
1104 |
|
1105 if ( StandbyEnabled( aUser ) && |
|
1106 ( aUser->iStandbyState == EInactive || aUser->iStandbyState == EDeactivating ) ) |
|
1107 { |
|
1108 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::DoStandByDecision, \ |
|
1109 standby state before: %d", aUser->iStandbyState ) |
|
1110 |
|
1111 aUser->iStandbyState = EActivating; |
|
1112 |
|
1113 SendStreamEventToClient( KMccStandbyActivityEvent, |
|
1114 KErrNone, |
|
1115 iCurRecvPayloadType ); |
|
1116 |
|
1117 if ( aUser->iStandbyState == EActivating ) |
|
1118 { |
|
1119 aUser->iStandbyState = EActive; |
|
1120 } |
|
1121 |
|
1122 TRACE_RTP_SOURCE_PRINT2( "CMccRtpDataSource::DoStandByDecision, \ |
|
1123 standby state after: %d", aUser->iStandbyState ) |
|
1124 } |
|
1125 } |
|
1126 |
|
1127 // --------------------------------------------------------------------------- |
|
1128 // CMccRtpDataSource::FindUserEntryByPayloadType |
|
1129 // --------------------------------------------------------------------------- |
|
1130 // |
|
1131 TMccRtpUser* CMccRtpDataSource::FindUserEntryByPayloadType( TUint aPayloadType ) |
|
1132 { |
|
1133 TMccRtpUser entry( iEventHandler ); |
|
1134 entry.iPayloadType = aPayloadType; |
|
1135 TIdentityRelation<TMccRtpUser> comparison( RtpUserMatch ); |
|
1136 const TInt index = iUsers.Find( entry, comparison ); |
|
1137 if ( index != KErrNotFound ) |
|
1138 { |
|
1139 return &iUsers[ index ]; |
|
1140 } |
|
1141 |
|
1142 return NULL; |
|
1143 } |
|
1144 |
|
1145 // --------------------------------------------------------------------------- |
|
1146 // CMccRtpDataSource::FindRtpUserEntryByTimerId |
|
1147 // --------------------------------------------------------------------------- |
|
1148 // |
|
1149 TMccRtpUser* CMccRtpDataSource::FindUserEntryByTimerId( TMccTimerId aTimerId ) |
|
1150 { |
|
1151 TMccRtpUser entry( iEventHandler ); |
|
1152 entry.iTimerId = aTimerId; |
|
1153 TIdentityRelation<TMccRtpUser> comparison( RtpUserMatch ); |
|
1154 TInt index = iUsers.Find( entry, comparison ); |
|
1155 if ( index != KErrNotFound ) |
|
1156 { |
|
1157 return &iUsers[ index ]; |
|
1158 } |
|
1159 return NULL; |
|
1160 } |
|
1161 |
|
1162 // --------------------------------------------------------------------------- |
|
1163 // CMccRtpDataSource::FindUserEntryIndex |
|
1164 // --------------------------------------------------------------------------- |
|
1165 // |
|
1166 TInt CMccRtpDataSource::FindUserEntryIndex( TMccRtpUser* aUser ) |
|
1167 { |
|
1168 TInt index( KErrNotFound ); |
|
1169 if ( aUser ) |
|
1170 { |
|
1171 TIdentityRelation<TMccRtpUser> comparison( RtpUserMatch ); |
|
1172 index = iUsers.Find( *aUser, comparison ); |
|
1173 } |
|
1174 return index; |
|
1175 } |
|
1176 |
|
1177 // --------------------------------------------------------------------------- |
|
1178 // CMccRtpDataSource::RtpUserMatch |
|
1179 // --------------------------------------------------------------------------- |
|
1180 // |
|
1181 TBool CMccRtpDataSource::RtpUserMatch( |
|
1182 const TMccRtpUser& aUser1, |
|
1183 const TMccRtpUser& aUser2 ) |
|
1184 { |
|
1185 // First argument is always the search term |
|
1186 |
|
1187 TBool match( EFalse ); |
|
1188 if ( aUser1.iPayloadType != KMccPTNotDefined ) |
|
1189 { |
|
1190 match = ( aUser1.iPayloadType == aUser2.iPayloadType ); |
|
1191 } |
|
1192 else if ( aUser1.iTimerId != KMaxTUint32 ) |
|
1193 { |
|
1194 match = ( aUser1.iTimerId == aUser2.iTimerId ); |
|
1195 } |
|
1196 else |
|
1197 { |
|
1198 match = ( &aUser1 == &aUser2 ); |
|
1199 } |
|
1200 return match; |
|
1201 } |
|
1202 |
|
1203 // --------------------------------------------------------------------------- |
|
1204 // FROM SRTP API |
|
1205 // This function is called by SRTP Stream initiated with |
|
1206 // MSRTPReKeyingObserver when a master key is stale and needs |
|
1207 // to be refreshed. |
|
1208 // --------------------------------------------------------------------------- |
|
1209 // |
|
1210 void CMccRtpDataSource::SRTPMasterKeyStaleEvent( const CSRTPStream& aStream ) |
|
1211 { |
|
1212 TRACE_RTP_INTERFACE_PRINT( "CMccRtpDataSource::SRTPMasterKeyStaleEvent" ) |
|
1213 |
|
1214 if ( iSrtpStream == &aStream ) |
|
1215 { |
|
1216 iSecureKeyExpired = ETrue; |
|
1217 SendSecureRtpEventToClient( iEventHandler, |
|
1218 KMccRtpSourceUid, |
|
1219 EMccInternalEventNone, |
|
1220 KMccMasterKeyStaled, |
|
1221 MCC_RTPSOURCE_ENDPOINT_ID ); |
|
1222 } |
|
1223 else |
|
1224 { |
|
1225 TRACE_RTP_INTERFACE_PRINT( "CMccRtpDataSource::SRTPMasterKeyStaleEvent - Wrong stream" ) |
|
1226 } |
|
1227 } |
|
1228 |
|
1229 // --------------------------------------------------------------------------- |
|
1230 // FROM SRTP API |
|
1231 // This function is called by SRTP Stream initiated with |
|
1232 // CSRTPSession when a master key is stale and |
|
1233 // needs to be refreshed. |
|
1234 // --------------------------------------------------------------------------- |
|
1235 // |
|
1236 void CMccRtpDataSource::SRTPMasterKeyStaleEvent(const CSRTPSession& aSession ) |
|
1237 { |
|
1238 TRACE_RTP_INTERFACE_PRINT( "CMccRtpStream::SRTPMasterKeyStaleEvent" ) |
|
1239 |
|
1240 if ( iSecSession == &aSession ) |
|
1241 { |
|
1242 iSecureKeyExpired = ETrue; |
|
1243 SendSecureRtpEventToClient( iEventHandler, |
|
1244 KMccRtpSourceUid, |
|
1245 EMccInternalEventNone, |
|
1246 KMccMasterKeyStaled, |
|
1247 MCC_RTPSOURCE_ENDPOINT_ID ); |
|
1248 |
|
1249 } |
|
1250 else |
|
1251 { |
|
1252 TRACE_RTP_INTERFACE_PRINT( "MccRtpStream::SRTPMasterKeyStaleEvent - Wrong session" ) |
|
1253 } |
|
1254 } |
|
1255 |
|
1256 // ----------------------------------------------------------------------------- |
|
1257 // CMccRtpDataSource::TimerExpiredL |
|
1258 // From MMccExpirationHandler |
|
1259 // ----------------------------------------------------------------------------- |
|
1260 // |
|
1261 void CMccRtpDataSource::TimerExpiredL( TMccTimerId aTimerId, TAny* /*aTimerParam*/ ) |
|
1262 { |
|
1263 TRACE_RTP_SOURCE_PRINT2( "CMccRtpStream::TimerExpiredL, timer id: %d", aTimerId ) |
|
1264 if ( aTimerId == iInactivityTimerId ) |
|
1265 { |
|
1266 TRACE_RTP_SOURCE_PRINT ( "CMccRtpDataSource::TimerExpiredL, inactivity timer expired" ) |
|
1267 |
|
1268 SendInternalRtpEventToClient( iEventHandler, |
|
1269 KMccRtpSourceUid, |
|
1270 KMccInternalRtpSrcMmfEvent, |
|
1271 KMccInactivityEvent, |
|
1272 MCC_RTPSOURCE_ENDPOINT_ID ); |
|
1273 } |
|
1274 else |
|
1275 { |
|
1276 // Standby timeout |
|
1277 TMccRtpUser* userEntry = FindUserEntryByTimerId( aTimerId ); |
|
1278 HandleStandByL( userEntry ); |
|
1279 } |
|
1280 } |
|
1281 |
|
1282 // ========================== OTHER EXPORTED FUNCTIONS ========================= |
|
1283 |
|
1284 // End of File |