multimediacommscontroller/mmccrtpwrapper/src/rtp_wrapper.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // class for the rtpwrapper unit test cases
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20 */
       
    21 
       
    22 #include <e32math.h>
       
    23 #include <commdbconnpref.h> 
       
    24 #include <rtp.h>
       
    25 #include <rtcp.h>
       
    26 #include <COMMDB.H> 
       
    27 #include <srtpsession.h>
       
    28 #include "rtpheader.h"
       
    29 #include "rtpmanager.h"
       
    30 
       
    31 TInt RtpSessionLinearOrderFunc(const  CRtpSessionInfo& aNew, const CRtpSessionInfo &aArrElem)
       
    32 	{
       
    33 	return aNew.iPortNumber - aArrElem.iPortNumber;
       
    34 	}
       
    35 
       
    36 CRtpSessionInfo* CRtpSessionInfo::NewL()
       
    37 	{
       
    38 	LOG_FUNC_ENTRY("CRtpSessionInfo::NewL");
       
    39 	CRtpSessionInfo *self = new(ELeave) CRtpSessionInfo();
       
    40 	
       
    41 	CleanupStack::PushL(self);
       
    42 	self->ConstructL();
       
    43 	CleanupStack::Pop();
       
    44 
       
    45 	LOG_FUNC_EXIT("CRtpSessionInfo::NewL");
       
    46 	return self;
       
    47 	}
       
    48 
       
    49 void CRtpSessionInfo::ConstructL()
       
    50 	{
       
    51 	LOG_FUNC_ENTRY("CRtpSessionInfo::ConstructL");
       
    52 	}
       
    53 
       
    54 /* Creates a CrtpManager object */
       
    55 CRtpManager* CRtpManager::NewL(MRtpErrNotify& aErrNotify )
       
    56 	{
       
    57 	LOG_FUNC_ENTRY("CRtpManager::NewL");
       
    58     CRtpManager *self = new(ELeave) CRtpManager();
       
    59 	
       
    60 	CleanupStack::PushL(self);
       
    61 	self->ConstructL(aErrNotify);
       
    62 	CleanupStack::Pop();
       
    63 
       
    64 	LOG_FUNC_EXIT("CRtpManager::NewL");
       
    65 	return self;
       
    66 	}
       
    67 
       
    68 CRtpManager::CRtpManager( )
       
    69 	{
       
    70 	LOG_FUNC_ENTRY("CRtpManager::CRtpManager");
       
    71 	iOwnsConnection   = EFalse;
       
    72 	iOwnsSocketServer = EFalse;
       
    73 	LOG_FUNC_EXIT("CRtpManager::CRtpManager");
       
    74 	}
       
    75 
       
    76 CRtpManager::~CRtpManager( )
       
    77 	{
       
    78 	LOG_FUNC_ENTRY("CRtpManager::~CRtpManager");
       
    79 	
       
    80 	Close();
       
    81 	
       
    82 	/* Clean up the Arrays */
       
    83 	iRtpSessionArr.Close();
       
    84 	iRtpStreamsArr.Close();
       
    85 	
       
    86 	if(iOwnsConnection)
       
    87 		delete iConnection;
       
    88 	if(iOwnsSocketServer)
       
    89 		delete iSocketServ;
       
    90 	
       
    91 	LOG_FUNC_EXIT("CRtpManager::~CRtpManager");
       
    92 	}
       
    93 
       
    94 void CRtpManager::ConstructL(MRtpErrNotify& aErrNotify )
       
    95 	{
       
    96 	LOG_FUNC_ENTRY("CRtpManager::ConstructL");
       
    97 	iRtpErrNotify = &aErrNotify;
       
    98 	LOG_FUNC_EXIT("CRtpManager::ConstructL");
       
    99 	}
       
   100 
       
   101         
       
   102 TInt CRtpManager::OpenL( const TRtpSdesParams& aSdesInfo,  const TDesC* aRtpPacketDll,
       
   103                          const RSocketServ* aSocketServPtr, const RConnection* aConnPtr )
       
   104 	{
       
   105 	LOG_FUNC_ENTRY("CRtpManager::OpenL");
       
   106 	/* The current implementation do not support having a different
       
   107 	 * aRtpPacketDll
       
   108 	 * So the argument is ignored */
       
   109 	(void)aRtpPacketDll;
       
   110 
       
   111 	if(aSocketServPtr)
       
   112 		{
       
   113 		iSocketServ = const_cast<RSocketServ*>(aSocketServPtr);
       
   114 		}
       
   115 	else
       
   116 		{
       
   117 		iSocketServ = new(ELeave) RSocketServ();
       
   118 		iOwnsSocketServer = ETrue;
       
   119 		}
       
   120 	
       
   121 	if(aConnPtr)
       
   122 		{
       
   123 		iConnection = const_cast<RConnection*>(aConnPtr);
       
   124 		}
       
   125 	else
       
   126 		{
       
   127 		iConnection = new(ELeave) RConnection();
       
   128 		iOwnsConnection = ETrue;
       
   129 		}
       
   130 	
       
   131 	iSdesInfo  = aSdesInfo;
       
   132 
       
   133 	User::LeaveIfError(iSocketServ->Connect());
       
   134 	
       
   135 	User::LeaveIfError(iConnection->Open(*iSocketServ));
       
   136 	
       
   137 	LOG_FUNC_EXIT("CRtpManager::OpenL");
       
   138 	return KErrNone;
       
   139 	}
       
   140 
       
   141 
       
   142  /**
       
   143   * Open and initialize the CRtpAPI object.
       
   144   * @param aIapId - [input] IAP ID. If -1, no IAP selection dialog
       
   145   *   will pop up. Instead, the default IAP will be used.
       
   146   * @return KErrNone if successful; system wide error code otherwise
       
   147  */
       
   148 TInt CRtpManager::StartConnection( TInt aIapId )
       
   149 	{
       
   150 	LOG_FUNC_ENTRY("CRtpManager::StartConnection");
       
   151 	__RTP_LOG1("IapId = %d",aIapId)
       
   152 	if(aIapId != -1)
       
   153 		{
       
   154 		TCommDbConnPref prefs;
       
   155 		prefs.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
       
   156 		prefs.SetDirection(ECommDbConnectionDirectionOutgoing);
       
   157 		prefs.SetIapId(aIapId);
       
   158 		iIapId = aIapId;
       
   159 		return iConnection->Start(prefs);
       
   160 		}
       
   161 	else
       
   162 		{
       
   163 		TRAPD(err,iIapId = GetDefaultIapIdL());
       
   164 		if(KErrNone != err)
       
   165 			{
       
   166 			__RTP_LOG1("GetDefaultIapIdL returned  %d",err)
       
   167 			return err;
       
   168 			}
       
   169 		__RTP_LOG1("GetDefaultIapIdL default Iap:  %d",iIapId)
       
   170 		LOG_FUNC_EXIT("CRtpManager::StartConnection");
       
   171 		return iConnection->Start();
       
   172 		}
       
   173 	}
       
   174 
       
   175 TInt CRtpManager::StartConnection( TRequestStatus& aStatus, TInt aIapId)
       
   176 	{
       
   177 	LOG_FUNC_ENTRY("CRtpManager::StartConnection-Async");
       
   178 	__RTP_LOG1("aIapId = %d",aIapId);
       
   179 
       
   180 	TCommDbConnPref prefs;
       
   181 	prefs.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
       
   182 	prefs.SetDirection(ECommDbConnectionDirectionOutgoing);
       
   183 	
       
   184 	if(aIapId != -1)
       
   185 		{
       
   186 		prefs.SetIapId(aIapId);	
       
   187 		iConnection->Start(prefs, aStatus);
       
   188 		iIapId = aIapId;
       
   189 		}
       
   190 	else
       
   191 		{
       
   192 		TRAPD(err,iIapId = GetDefaultIapIdL());
       
   193 		if(KErrNone != err)
       
   194 			{
       
   195 			__RTP_LOG1("GetDefaultIapIdL returned  %d",err)
       
   196 			return err;
       
   197 			}
       
   198 		__RTP_LOG1("GetDefaultIapIdL default Iap:  %d",iIapId)
       
   199 		prefs.SetIapId(iIapId);
       
   200 		iConnection->Start(prefs, aStatus);
       
   201 		}
       
   202 	LOG_FUNC_EXIT("CRtpManager::StartConnection-Async");
       
   203 	return KErrNone;
       
   204 	}
       
   205 
       
   206 
       
   207 /**
       
   208 * Cancels asynchoronous start of connection.
       
   209 * Any open requests will be completed with KErrCancel.
       
   210 * @return None
       
   211 */
       
   212 void CRtpManager::CancelStart()
       
   213 	{
       
   214 	LOG_FUNC_ENTRY("CRtpManager::CancelStart");
       
   215 	return;
       
   216 	}
       
   217 
       
   218 
       
   219 void CRtpManager::Close()
       
   220 	{
       
   221 	LOG_FUNC_ENTRY("CRtpManager::Close");
       
   222 	/* Iterate through the session array and close */
       
   223 	for(int i=0; i < iRtpSessionArr.Count(); i++)
       
   224 		{
       
   225 		__RTP_LOG1("Closing Session Key %u",iRtpSessionArr[i]->iKey);
       
   226 		iRtpSessionArr[i]->iRtpSession.Close();
       
   227 		ASSERT(iRtpSessionArr[i]->iPendingReqQue->IsEmpty());
       
   228 		delete iRtpSessionArr[i]->iPendingReqQue;
       
   229 		iRtpSessionArr[i]->iPendingReqQue = NULL;
       
   230 		}
       
   231 	if(iConnection)
       
   232 		iConnection->Close();
       
   233 	
       
   234 	if(iSocketServ)
       
   235 		iSocketServ->Close();
       
   236 	
       
   237 	LOG_FUNC_EXIT("CRtpManager::Close");
       
   238 	}
       
   239 
       
   240 /**
       
   241 * Set SDES (Source Description) information of the local participant.
       
   242 * Participant is defined as an application program and
       
   243 * only one local participant is allowed.
       
   244 */
       
   245  void CRtpManager::SetLocalSdes( const TRtpSdesParams& aSDES)
       
   246 	{
       
   247 	/* Should the SDES list be updated again here ? */
       
   248 	LOG_FUNC_ENTRY("CRtpManager::SetLocalSdes");
       
   249 	iSdesInfo = aSDES;
       
   250 	}
       
   251 
       
   252 /**
       
   253 * Get the local IP address
       
   254 * @param None
       
   255 * @return local ip address.
       
   256 */
       
   257  TInetAddr& CRtpManager::GetLocalIPAddressL()
       
   258 	{
       
   259 	LOG_FUNC_ENTRY("CRtpManager::GetLocalIPAddressL");
       
   260 	/* Open an RSocket and find its address */
       
   261 	RSocket socket;
       
   262 	User::LeaveIfError(socket.Open(*iSocketServ, KAfInet, KSockDatagram, KProtocolInetUdp,*iConnection));
       
   263     
       
   264 	CleanupClosePushL(socket);
       
   265 
       
   266 	TSoInetInterfaceInfo networkInfo;
       
   267 	TPckg<TSoInetInterfaceInfo> opt(networkInfo);
       
   268 	User::LeaveIfError(socket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl));
       
   269 	TSoInetIfQuery query;
       
   270 	TPckg<TSoInetIfQuery> queryBuf(query);
       
   271 	TInt res = KErrNone;
       
   272 	do 
       
   273 	{
       
   274 		res = socket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, opt);
       
   275 		if (!res && opt().iState == EIfUp)
       
   276 		{
       
   277 			query.iName = opt().iName;
       
   278 			res = socket.GetOpt(KSoInetIfQueryByName, KSolInetIfQuery, queryBuf);
       
   279 			if (!res && query.iZone[1] == iIapId)
       
   280 			{
       
   281 				networkInfo = opt();
       
   282 				break;
       
   283 			}
       
   284 		}
       
   285 	}
       
   286 	while (res == KErrNone);
       
   287     if(res!= KErrNone)
       
   288     	{
       
   289     	__RTP_LOG1("Found nothing! ret %d",res)
       
   290     	/* Didn't find :( */
       
   291     	User::Leave(res);
       
   292     	}
       
   293 	CleanupStack::PopAndDestroy(1);
       
   294     iSockAddr = networkInfo.iAddress;
       
   295     LOG_FUNC_EXIT("CRtpManager::GetLocalIPAddressL");
       
   296 	return iSockAddr;
       
   297 	}
       
   298  /**
       
   299  * Makes a CName that is unique for a given seesion 
       
   300  */
       
   301 void CRtpManager::MakeACnameL(TDes8 &aCname)
       
   302 	{
       
   303 	/* As of now putting the IP Address. But this is not enough.
       
   304 	 * multiple sessions should have unique CNAMES 
       
   305 	 * */
       
   306 	TBuf<50> ipAddr;
       
   307 	TInetAddr locAddr = GetLocalIPAddressL();
       
   308 	locAddr.Output(ipAddr);
       
   309 	aCname.Format(_L8("%d@"),iRtpSessionArr.Count()+1);
       
   310 	aCname.Append(ipAddr);
       
   311 	}
       
   312 /**
       
   313 * Create a new RTP Session and return the Session ID as well as the
       
   314 * local port number assigned for RTP. RTP uses an even port number and
       
   315 * RTCP, if enabled, uses the next higher (odd) port number.
       
   316 */
       
   317  TRtpId CRtpManager::CreateSessionL(const TCreateSessionParams& aSessionParams,
       
   318                            	                TUint& aPort, TBool aEnableRtcp, const TRtcpParams* aRtcpParams )
       
   319 	{
       
   320 	LOG_FUNC_ENTRY("CRtpManager::CreateSessionL");
       
   321 	__RTP_LOG1("RTCP stat %d",aEnableRtcp)
       
   322 	TInt localPort;
       
   323 	/* The RTP Session create takes in the LocalPort.*/
       
   324 	if(iRtpSessionArr.Count() == 0)
       
   325 		{
       
   326 		//In this case start from begining. Start by using the default Even RTP
       
   327 		//Port.
       
   328 		localPort = KDefaultStartRtpAddress;
       
   329 		__RTP_LOG1("LocalPort used %d",localPort)
       
   330 		}
       
   331 	else
       
   332 		{
       
   333 		/* Pick the next highest port number */
       
   334 		localPort = iRtpSessionArr[iRtpSessionArr.Count()-1]->iPortNumber + 2;
       
   335 		__RTP_LOG1("LocalPort used %d",localPort)
       
   336 		}
       
   337 	
       
   338 	//if the user has specified a port then override our selection
       
   339 	if(aPort)
       
   340 		{
       
   341 		localPort = aPort;
       
   342 		}
       
   343 	
       
   344 	//Now use this Port and try opening the RTP Session. If the Session Open
       
   345 	//fails try opening with the next even port.
       
   346     //Its much more easier to use the API which takes RSocket directly here. But
       
   347 	//ths would mean we cannot use the New CFRTP API.
       
   348 	TInetAddr locAddr(0,localPort);
       
   349 
       
   350 	/* Remote address is uninitialized. Unfortunately its required by Symbian
       
   351 	 * RTP stack. */
       
   352 	TInetAddr remAddr;
       
   353 	
       
   354 	#ifndef SYMBIAN_ENABLE_SPLIT_HEADERS
       
   355 	RRtpSession rtpSession;
       
   356 	#else
       
   357 	RRtpSession_Internal rtpSession;
       
   358 	#endif	
       
   359  	
       
   360 	TPtrC8 cnameTptr((TUint8*)"", 0);;
       
   361 	if(aEnableRtcp)
       
   362 		{
       
   363 		TBuf8<50> cnameBuf;
       
   364 		if(iSdesInfo.iCName == KNullDesC8)
       
   365 			{
       
   366 			MakeACnameL(cnameBuf);
       
   367 			iSdesInfo.iCName.Set(cnameBuf);
       
   368 			}
       
   369 		cnameTptr.Set(iSdesInfo.iCName);
       
   370 		}
       
   371 	else
       
   372 		{
       
   373 		cnameTptr.Set(KNullDesC8);
       
   374 		}
       
   375 
       
   376 	TInt tryCount = 0;
       
   377 	TInt errOpenl = KErrNone;
       
   378 
       
   379 	__RTP_LOG1("Starting Port alloc and OpenL tryCount %d",tryCount);
       
   380 	__RTP_LOG1("aSessionParams.iSocketBufSize    %d",aSessionParams.iSocketBufSize);	
       
   381    aPort = locAddr.Port();
       
   382 
       
   383     while(tryCount < 5 )
       
   384 		{
       
   385     	TRAP(errOpenl,rtpSession.OpenL(*iSocketServ, locAddr, remAddr, aSessionParams.iSocketBufSize, *iConnection, EPriorityNormal, cnameTptr));
       
   386 		if(errOpenl != KErrNone)
       
   387 			{
       
   388 			__RTP_LOG2("OpenL Failed with Error Code %d TryCount %d",errOpenl, tryCount);
       
   389 			tryCount ++;
       
   390 			locAddr.SetPort(locAddr.Port()+tryCount+1);
       
   391 			localPort += tryCount+1;
       
   392 			}
       
   393 		else
       
   394 			{
       
   395 			break;
       
   396 			}
       
   397 		}
       
   398 
       
   399     User::LeaveIfError(errOpenl);
       
   400     
       
   401 	__RTP_LOG(",rtpSession.OpenL Success!!");
       
   402 
       
   403 	TTimeIntervalMicroSeconds32 rtcpInterval;
       
   404 	if(aEnableRtcp && aRtcpParams)
       
   405 		{
       
   406 		rtpSession.SetBandwidth(aRtcpParams->iSessionBWidth);
       
   407 		__RTP_LOG1(" aRtcpParams->iRtcpTimeOut %d", aRtcpParams->iRtcpTimeOut.Int());
       
   408 		if(aRtcpParams->iRtcpTimeOut.Int())
       
   409 		    {
       
   410 			rtcpInterval = aRtcpParams->iRtcpTimeOut.Int();
       
   411 		    }
       
   412 		else
       
   413 		    {
       
   414 		    //TODO fix me!
       
   415 		    //default 500 ms
       
   416 		    rtcpInterval = 1000000;
       
   417 		    }
       
   418         rtpSession.SetRtcpInterval(rtcpInterval);
       
   419 		}
       
   420 	else
       
   421 		{
       
   422 		__RTP_LOG("Setting default RTCP Properties!!");
       
   423 		//Default Bandwidth.
       
   424 		rtpSession.SetBandwidth(KRtpDefaultBandWidth);	
       
   425 		rtcpInterval = 1000000;
       
   426 		rtpSession.SetRtcpInterval(rtcpInterval);
       
   427 		}
       
   428 	
       
   429 	//Phew! Now put these in our Array
       
   430 	CRtpSessionInfo* sessionInfo = CRtpSessionInfo::NewL();
       
   431 	//Assign a Key for this session.
       
   432 	sessionInfo->iKey         = Math::Random();
       
   433 	sessionInfo->iPortNumber  = localPort;
       
   434 	sessionInfo->iRtpSession  = rtpSession;
       
   435 	sessionInfo->iRtpManager  = this;
       
   436 	sessionInfo->iRtcpEnabled = aEnableRtcp;
       
   437 	sessionInfo->iPendingReqQue = new(ELeave)  TSglQue<TRtpSendReqNode>(_FOFF(TRtpSendReqNode,iLink));
       
   438 	iRtpSessionArr.InsertInOrder(sessionInfo, TLinearOrder<CRtpSessionInfo>(RtpSessionLinearOrderFunc)); //InsertInOrder(sessionInfo,TLinearOrder<CRtpSessionInfo>(RtpSessionLinearOrderFunc));
       
   439 
       
   440 	__RTP_LOG1("Session Created Key %u",sessionInfo->iKey)
       
   441     //Get back the reference to the object in Array.
       
   442 	TInt idx = FindSessionL(sessionInfo->iKey);
       
   443 	
       
   444     //Register for the Events  
       
   445 	RegisterEventsOnSessionL(iRtpSessionArr[idx]);
       
   446 	
       
   447 	aPort = localPort;
       
   448 
       
   449 	//TODO: Fix this in RTP Stack.
       
   450 	/* Remote Address is uninitialized now. So if RTCP is enabled disable autosend so that
       
   451 	 * no data is send to incorrect address.
       
   452 	 */
       
   453 	if(aEnableRtcp)
       
   454 		{
       
   455 		rtpSession.SetRTCPAutoSend(EFalse);
       
   456 		}
       
   457 
       
   458 
       
   459 	LOG_FUNC_EXIT("CRtpManager::CreateSessionL");
       
   460 
       
   461 	return sessionInfo->iKey;
       
   462 	}
       
   463    
       
   464 
       
   465 /**
       
   466  *Create a new, secure RTP Session and return the Session ID as well as the
       
   467 * local port number assigned for RTP. RTP uses an even port number and
       
   468 * RTCP, if enabled, uses the next higher (odd) port number.
       
   469 * User is expected to create corresponding SRTP session prior to calling this
       
   470 * function. 
       
   471 */
       
   472  TRtpId CRtpManager::CreateSessionL( const TCreateSessionParams& aSessionParams, TUint& aPort, 
       
   473 	                				TBool aEnableRtcp, const TRtcpParams* aRtcpParams, CSRTPSession& aSRTPSession)
       
   474 	{
       
   475 	LOG_FUNC_ENTRY("CRtpManager::CreateSessionL");
       
   476 	__RTP_LOG("SRTP is not supported Leaving..!!")
       
   477 	
       
   478 	TUint32 key = CreateSessionL(aSessionParams, aPort, aEnableRtcp, aRtcpParams);
       
   479 	TInt idx = FindSessionL(key);
       
   480 	iRtpSessionArr[idx]->iSRTPSession = &aSRTPSession;
       
   481 	iRtpSessionArr[idx]->iRtpSession.SetPrePostProcessingRegisterCallback(iRtpSessionArr[idx]);
       
   482 	return key;
       
   483 	}
       
   484                             
       
   485 /**
       
   486 * Start an RTP Session. If enabled, RTCP associated with the given
       
   487 * session is also started.
       
   488 */
       
   489  TInt CRtpManager::StartSession( TRtpId aSessionId )
       
   490 	{
       
   491 	LOG_FUNC_ENTRY("CRtpManager::StartSession");
       
   492 	if(FindSession(aSessionId)!= KErrNotFound)
       
   493 		{
       
   494 		/* Well we found the session. But Really nothing to do */
       
   495 		//TODO verify
       
   496 		return KErrNone;
       
   497 		}
       
   498 	else
       
   499 		{
       
   500 		return KErrNotFound;
       
   501 		}
       
   502 	}
       
   503 
       
   504 /**
       
   505 * Close an RTP Session.
       
   506 */
       
   507  void CRtpManager::CloseSession( TRtpId aSessionId )
       
   508 	{
       
   509 	LOG_FUNC_ENTRY("CRtpManager::CloseSession");
       
   510 	__RTP_LOG1("SessID %u",aSessionId)
       
   511 	TInt idx;
       
   512 	idx = FindSession(aSessionId);
       
   513 	if(KErrNotFound != idx)
       
   514 		{
       
   515 		/* This takes care of all cleaning up */
       
   516 		iRtpSessionArr[idx]->iRtpSession.Close();
       
   517 		/* There should be no more Pending requests on this session */
       
   518 		ASSERT(iRtpSessionArr[idx]->iPendingReqQue->IsEmpty());
       
   519 		delete iRtpSessionArr[idx]->iPendingReqQue;
       
   520 		CRtpSessionInfo *session = iRtpSessionArr[idx];
       
   521 		iRtpSessionArr.Remove(idx);
       
   522 		delete session;
       
   523 		}
       
   524 	else
       
   525 		{
       
   526 		__RTP_LOG("Session not found")
       
   527 	    //So already cleaned?	
       
   528 		}
       
   529 	LOG_FUNC_EXIT("CRtpManager::CloseSession");
       
   530 	}
       
   531 
       
   532 /**
       
   533 * Set remote IP address and port number to RTP Session.
       
   534 * Port number for RTP must be an even number and the corresponding
       
   535 * RTCP, if enabled, will be set to use the next higher (odd) port.
       
   536 */
       
   537  TInt CRtpManager::SetRemoteAddress( TRtpId aSessionId,const TInetAddr& aRemoteAddr )
       
   538 	{
       
   539 	LOG_FUNC_ENTRY("CRtpManager::SetRemoteAddress");
       
   540 	__RTP_LOG1("SessID %u",aSessionId)
       
   541 	__RTP_LOG_STMT(TBuf<50> buf; aRemoteAddr.Output(buf););
       
   542 	__RTP_LOG2("RemoteAddressAddress %S, Port %u", &buf, aRemoteAddr.Port());
       
   543 	TInt ret;
       
   544 	TInetAddr addr = aRemoteAddr;
       
   545 	if((ret =FindSession(aSessionId))!= KErrNotFound)
       
   546 		{
       
   547 		iRtpSessionArr[ret]->iRtpSession.SetRemoteAddress(addr);
       
   548 		iRtpSessionArr[ret]->iRemoteAddress = aRemoteAddr;
       
   549 		/* SET the RTCP address as well here */
       
   550 		iRtpSessionArr[ret]->iRemoteRTCPAddress = aRemoteAddr;
       
   551 		iRtpSessionArr[ret]->iRemoteRTCPAddress.SetPort(aRemoteAddr.Port()+1);
       
   552 
       
   553 		return KErrNone;
       
   554 		}
       
   555 	else
       
   556 		{
       
   557 		return KErrNotFound;
       
   558 		}
       
   559 	}
       
   560 
       
   561 /**
       
   562 * Set remote RTCP IP address and port number to RTP Session accoring to RFC 3605
       
   563 * i.e. this should be used if RTCP port is different than RTP port + 1
       
   564 */
       
   565 TInt CRtpManager::SetRemoteRtcpAddress( TRtpId aSessionId, const TInetAddr&  aRemoteAddr)
       
   566 	{
       
   567 	LOG_FUNC_ENTRY("CRtpManager::SetRemoteRtcpAddress");
       
   568 	__RTP_LOG1("SessID %u",aSessionId)
       
   569 	__RTP_LOG_STMT(TBuf<50> buf; aRemoteAddr.Output(buf););
       
   570 	__RTP_LOG2("RemoteAddressAddress %S, Port %u", &buf, aRemoteAddr.Port());
       
   571 	TInt ret;
       
   572 	TInt port = aRemoteAddr.Port();
       
   573 	if((ret =FindSession(aSessionId))!= KErrNotFound)
       
   574 		{
       
   575 		iRtpSessionArr[ret]->iRtpSession.SetRemoteRtcpPort(port);
       
   576 		iRtpSessionArr[ret]->iRemoteRTCPAddress = aRemoteAddr;
       
   577         
       
   578 		/*
       
   579 		//VS Experiment. Try sending Door opener here to Remote end
       
   580     	TRequestStatus 	stat;
       
   581 		__RTP_LOG("CRtpManager::SetRemoteAddress -- Sending DoorOpener --RTCP");
       
   582 		RSocket *sock = NULL;
       
   583 		sock = GetRtcpSocket(aSessionId);
       
   584 		sock->SendTo(_L8("OpenSesame"),iRtpSessionArr[ret]->iRemoteAddress,0,stat);
       
   585 		User::WaitForRequest(stat);
       
   586         __RTP_LOG1("DoorOpener --RTCP sent retCode %d", stat.Int());
       
   587 		LOG_FUNC_EXIT("CRtpManager::SetRemoteRtcpAddress");
       
   588 		*/
       
   589 		return KErrNone;
       
   590 		}
       
   591 	else
       
   592 		{
       
   593 		return KErrNotFound;
       
   594 		}
       
   595 	}
       
   596         
       
   597 /**
       
   598 * Create a Receive stream for an RTP Session and return the stream
       
   599 * ID which is unique for all RTP Sessions.
       
   600 */
       
   601  TRtpId CRtpManager::CreateReceiveStreamL( TRtpId aSessionId, const TRcvStreamParams& aParams )
       
   602 	{
       
   603 	LOG_FUNC_ENTRY("CRtpManager::CreateReceiveStreamL");
       
   604 	__RTP_LOG1("SessID %u",aSessionId)
       
   605 	/* Valide the session */
       
   606 	FindSessionL(aSessionId);
       
   607 	
       
   608 	/* Check for Post-Created Streams. If present use it */
       
   609 	for(TInt i=0; i < iRtpStreamsArr.Count(); i++)
       
   610 		{
       
   611 		if(iRtpStreamsArr[i].iSessionKey == aSessionId &&
       
   612 				iRtpStreamsArr[i].iState == TRtpStreamInfo::eStreamPostCreated && 
       
   613 				iRtpStreamsArr[i].iPayloadType == aParams.iPayloadType	)
       
   614 			{
       
   615 			__RTP_LOG1("Found Post Created Stream Key %u",iRtpStreamsArr[i].iKey)
       
   616 			/* Post created stream exists. Return it */
       
   617 			iRtpStreamsArr[i].iState = TRtpStreamInfo::eStreamReadyToUse;
       
   618 			return iRtpStreamsArr[i].iKey;
       
   619 			}
       
   620 		}
       
   621 	
       
   622 	/* OK found nothing. So create a Pre-Created stream and return its ID */
       
   623 	TRtpStreamInfo strmInfo;
       
   624 	strmInfo.iKey = Math::Random();
       
   625 	strmInfo.iSessionKey = aSessionId;
       
   626 	strmInfo.iState = TRtpStreamInfo::eStreamPreCreated;
       
   627 	strmInfo.iPayloadType = aParams.iPayloadType;
       
   628 	strmInfo.iRtpManager = this;
       
   629 	
       
   630 	iRtpStreamsArr.AppendL(strmInfo);
       
   631 	__RTP_LOG1("Created PreCreated Stream Key %u",strmInfo.iKey)
       
   632 	
       
   633 	LOG_FUNC_EXIT("CRtpManager::CreateReceiveStreamL");
       
   634 	return strmInfo.iKey;
       
   635 	}
       
   636 
       
   637  /**
       
   638   * Create a Transmit stream for an RTP Session and return the stream
       
   639   * ID which is unique for all RTP Sessions. SSRC value assigned for the
       
   640   * very first Transmit stream will be the same as the default SSRC
       
   641   * value reserved internally by CreateSession function. This function
       
   642   * is normally used to create a transmit stream where SSRC value is
       
   643   * randomly generated.
       
   644   */
       
   645    TRtpId CRtpManager::CreateTransmitStreamL( TRtpId aSessionId,
       
   646                       const TTranStreamParams& aParams,
       
   647                       TRtpSSRC& aSSRC )
       
   648 	   {
       
   649 	   LOG_FUNC_ENTRY("CRtpManager::CreateTransmitStreamL");
       
   650 	   __RTP_LOG1("SessID %u",aSessionId)
       
   651 	   TInt idx = FindSessionL(aSessionId);
       
   652 	   if(!iRtpSessionArr[idx]->iRtpSendSource.IsOpen())
       
   653 		   {
       
   654 		   iRtpSessionArr[idx]->iRtpSendSource = iRtpSessionArr[idx]->iRtpSession.NewSendSourceL();
       
   655 		   /* Now register for events in this session */
       
   656 		   iRtpSessionArr[idx]->iRtpSendSource.RegisterEventCallbackL(ERtpSendSucceeded,
       
   657 				                                          RtpSessionLevelCB,
       
   658 				                                          iRtpSessionArr[idx],
       
   659 				                                          ERtpNotOneShot);
       
   660 		   iRtpSessionArr[idx]->iRtpSendSource.RegisterEventCallbackL(ERtpSendFail,
       
   661 				                                          RtpSessionLevelCB,
       
   662 				                                          iRtpSessionArr[idx],
       
   663 				                                          ERtpNotOneShot);
       
   664 		   aSSRC = iRtpSessionArr[idx]->iRtpSendSource.GetLocalSSRC();
       
   665 		   
       
   666 		   iRtpSessionArr[idx]->iPayloadType = aParams.iPayloadType;
       
   667 		   
       
   668 		   iRtpSessionArr[idx]->iRtpSendSource.SetPayloadType(aParams.iPayloadType);
       
   669 		   
       
   670                
       
   671            //Note: The key is same as the SessionKey. We donot support
       
   672            //more than one Transmit Streams in one Session.
       
   673            LOG_FUNC_EXIT("CRtpManager::CreateTransmitStreamL");
       
   674                
       
   675            return iRtpSessionArr[idx]->iKey;
       
   676            }
       
   677 	   __RTP_LOG("A SendStream was already Opened!")
       
   678 	   //Already called still there might be Applications calling this
       
   679 	   //API twice
       
   680 	   //
       
   681 	   LOG_FUNC_EXIT("CRtpManager::CreateTransmitStreamL");
       
   682 	   return 0;
       
   683 	   }
       
   684 
       
   685   /**
       
   686   * Create a Transmit stream, with a given SSRC value, for an RTP Session
       
   687   * and return the stream ID which is unique for all RTP Sessions. This
       
   688   * extended function is used for a special case where a specific SSRC
       
   689   * value needs to be associated with the transmit stream being created,
       
   690   * e.g. for retransmission purpose.
       
   691   */
       
   692    TRtpId CRtpManager::CreateTransmitStreamExtL( TRtpId , const TTranStreamParams& ,
       
   693                       							const TRtpSSRC )
       
   694 	   {
       
   695 	   LOG_FUNC_ENTRY("CRtpManager::CreateTransmitStreamL");
       
   696 	   __RTP_LOG("NotSuppoted SSRC cannot be changed")
       
   697 	   //This is not supported as of now.
       
   698 	   //SSRC cannot be specified by Applications.
       
   699 	   return 0;
       
   700 	   }
       
   701 
       
   702 
       
   703    /**
       
   704     * Close a Transmit or Receive stream.
       
   705     */
       
   706 void CRtpManager::CloseStream( TRtpId aRtpID)
       
   707 	   {
       
   708 	   LOG_FUNC_ENTRY("CRtpManager::CloseStream");
       
   709 	   __RTP_LOG1("Stream ID %u",aRtpID)
       
   710        (void)aRtpID;
       
   711 	   //Streams are closed when session is closed.
       
   712 	   //so no requirement for an explicit close
       
   713 	   //TODO Verify Requirements
       
   714 	   return;
       
   715 	   }
       
   716 
       
   717 /**
       
   718  * Register a callback object for receiving RTP data packets from an RTP
       
   719  * Session. Only one receiver callback object is allowed to be
       
   720  * registered for one Session.
       
   721  */
       
   722 TInt CRtpManager::RegisterRtpObserver( TRtpId aSessionId, MRtpObserver& aRtpObserver )
       
   723 	{
       
   724 	LOG_FUNC_ENTRY("CRtpManager::RegisterRtpObserver");
       
   725 	__RTP_LOG1("SessID %u",aSessionId)
       
   726 	TInt ret = FindSession(aSessionId);
       
   727 	if(ret < 0)
       
   728 		return ret;
       
   729 	iRtpSessionArr[ret]->iRtpObserver = &aRtpObserver;
       
   730 	return KErrNone;
       
   731 	}
       
   732 
       
   733  /**
       
   734   * Unregister RTP observer callback object associated with an RTP
       
   735   * session.
       
   736   */
       
   737 void CRtpManager::UnregisterRtpObserver(TRtpId aSessionId)
       
   738 	{	
       
   739 	LOG_FUNC_ENTRY("CRtpManager::UnregisterRtpObserver");
       
   740 	__RTP_LOG1("SessID %u",aSessionId)
       
   741 
       
   742 	TInt ret = FindSession(aSessionId);
       
   743 	if(ret >= 0)
       
   744 		iRtpSessionArr[ret]->iRtpObserver = NULL;
       
   745 	}
       
   746 
       
   747 /**
       
   748 * Sets/resets the observer for the non-RTP data.
       
   749 * Only one receiver callback object is allowed to be
       
   750 * registered for one Session.
       
   751 * called when a non-RTP data packet is received.
       
   752 */
       
   753  TInt CRtpManager::SetNonRTPDataObserver( TRtpId aSessionId, MNonRTPDataObserver* aNonRtpObserver)
       
   754 	{
       
   755 	LOG_FUNC_ENTRY("CRtpManager::SetNonRTPDataObserver");
       
   756 	__RTP_LOG1("SessID %u",aSessionId);
       
   757 	
       
   758 	TInt ret = FindSession(aSessionId);
       
   759 	if(ret < 0)
       
   760 		return ret;
       
   761 	iRtpSessionArr[ret]->iNonRtpDataObserver = aNonRtpObserver;
       
   762 	
       
   763 	TRAPD(err,iRtpSessionArr[ret]->iRtpSession.RegisterEventCallbackL(ENonRtpDataReceived,
       
   764 			                                          RtpSessionLevelCB,
       
   765 			                                          iRtpSessionArr[ret],
       
   766 			                                          ERtpOneShot));
       
   767 	if(KErrNone != err)
       
   768 		{
       
   769 		__RTP_LOG1("err %d",err);
       
   770 		return err;
       
   771 		}
       
   772 
       
   773 	TRAP(err,iRtpSessionArr[ret]->iRtpSession.RegisterEventCallbackL(ENonRtcpDataReceived,
       
   774 				                                          RtpSessionLevelCB,
       
   775 				                                          iRtpSessionArr[ret],
       
   776 				                                          ERtpOneShot));
       
   777 	
       
   778 	if(KErrNone != err)
       
   779 		{
       
   780 		/* The already registered callback will be deleted when the first
       
   781 		 * NonRtp data comes
       
   782 		 */
       
   783 		iRtpSessionArr[ret]->iNonRtpDataObserver = 0;
       
   784 		}
       
   785 	return err;
       
   786 	}
       
   787 
       
   788 /**
       
   789 * Send an RTP data packet in a Transmit stream synchronously.
       
   790 */
       
   791  TInt CRtpManager::SendRtpPacket( TRtpId aTranStreamId,
       
   792                              const TRtpSendHeader& aHeaderInfo,
       
   793                              const TDesC8& aPayloadData )
       
   794 	{
       
   795 	LOG_FUNC_ENTRY("CRtpManager::SendRtpPacket");
       
   796 	__RTP_LOG1("aTranStreamId: %u",aTranStreamId)
       
   797 
       
   798 	/* The Transmit Id and Session ID are same. So
       
   799 	 * find the session */
       
   800 	TInt ret = FindSession(aTranStreamId);
       
   801 	if(ret<0)
       
   802 		return ret;
       
   803 	ASSERT(iRtpSessionArr[ret]->iRtpSendSource.IsOpen());
       
   804 	
       
   805 	RRtpSendPacket sendPkt;
       
   806 	TInt pktLen = 0;
       
   807     pktLen += aPayloadData.Length();
       
   808     __RTP_LOG1("pktLen: %d", pktLen );	
       
   809     if(iRtpSessionArr[ret]->iSRTPSession)
       
   810 		{
       
   811 		/* SRTP is enabled so allocate more bytes for MKI and AuthTag */
       
   812 		pktLen += ( KSrtpMaxAuthTagLength + KSrtpMaxMKILen );
       
   813 	    __RTP_LOG1("Added extra bytes for SRTP new pktLen: %d", pktLen );	
       
   814 		}	
       
   815 	TRAPD(err,sendPkt = iRtpSessionArr[ret]->iRtpSendSource.NewSendPacketL(pktLen, aHeaderInfo.iHeaderExtension?aHeaderInfo.iHeaderExtension->iLength:KRtpNoExtension));
       
   816 	if(err != KErrNone)
       
   817 		return err;
       
   818 	
       
   819 	__RTP_LOG2("TS: %u, PayloadType %d",aHeaderInfo.iTimestamp, aHeaderInfo.iPayloadType)
       
   820 	sendPkt.SetTimestamp(aHeaderInfo.iTimestamp);
       
   821 	sendPkt.SetMarker(aHeaderInfo.iMarker);
       
   822 	sendPkt.SetPayloadType(aHeaderInfo.iPayloadType);
       
   823 	
       
   824 	if(iRtpSessionArr[ret]->iFirstPacketSent == EFalse)
       
   825 	    {
       
   826 	    iRtpSessionArr[ret]->iRtpSession.SetRTPTimeConversion(aHeaderInfo.iTimestamp, iRtpSessionArr[ret]->iSamplingRate/1000);
       
   827 	    iRtpSessionArr[ret]->iFirstPacketSent = ETrue;
       
   828 	    }
       
   829 
       
   830 	TDes8 &wrtPayload = sendPkt.WritePayload();
       
   831 	wrtPayload = aPayloadData;
       
   832 	
       
   833 	ret = sendPkt.SendSync();
       
   834 	
       
   835 	//TODO pre allocate a Max Size
       
   836 	sendPkt.Close();
       
   837 	
       
   838 	LOG_FUNC_EXIT("CRtpManager::SendRtpPacket");	
       
   839 	return ret;
       
   840 	}
       
   841  
       
   842  
       
   843  /**
       
   844    * Send an RTP data packet in a Transmit stream asynchronously.
       
   845    */
       
   846  TInt CRtpManager::SendRtpPacket( TRtpId aTranStreamId,
       
   847                                 const TRtpSendHeader& aHeaderInfo,
       
   848                                 const TDesC8& aPayloadData,
       
   849                                 TRequestStatus& aStatus )
       
   850 	{
       
   851 	LOG_FUNC_ENTRY("CRtpManager::SendRtpPacket");
       
   852 	__RTP_LOG1("aTranStreamId: %u",aTranStreamId)
       
   853 	/* The Transmit Id and Session ID are same. So
       
   854 	 * find the session */
       
   855 	TInt ret = FindSession(aTranStreamId);
       
   856 	if(ret<0)
       
   857 		return ret;
       
   858 	ASSERT(iRtpSessionArr[ret]->iRtpSendSource.IsOpen());
       
   859 	
       
   860 	RRtpSendPacket sendPkt;
       
   861 	TInt pktLen = 0;
       
   862     pktLen += aPayloadData.Length();
       
   863     __RTP_LOG1("pktLen: %d", pktLen );	
       
   864     if(iRtpSessionArr[ret]->iSRTPSession)
       
   865 		{
       
   866 		/* SRTP is enabled so allocate more bytes for MKI and AuthTag */
       
   867 		pktLen += ( KSrtpMaxAuthTagLength + KSrtpMaxMKILen );
       
   868 	    __RTP_LOG1("Added extra bytes for SRTP new pktLen: %d", pktLen );	
       
   869 		}	
       
   870 	TRAPD(err,sendPkt = iRtpSessionArr[ret]->iRtpSendSource.NewSendPacketL(pktLen,aHeaderInfo.iHeaderExtension?aHeaderInfo.iHeaderExtension->iLength:KRtpNoExtension));
       
   871 	if(err != KErrNone)
       
   872 		return err;
       
   873 
       
   874     __RTP_LOG2("TS: %u, PayloadType %d",aHeaderInfo.iTimestamp, aHeaderInfo.iPayloadType);	
       
   875 	sendPkt.SetTimestamp(aHeaderInfo.iTimestamp);
       
   876 	sendPkt.SetMarker(aHeaderInfo.iMarker);
       
   877 	sendPkt.SetPayloadType(aHeaderInfo.iPayloadType);
       
   878 
       
   879 	
       
   880 	if(iRtpSessionArr[ret]->iFirstPacketSent == EFalse)
       
   881 		{
       
   882 		iRtpSessionArr[ret]->iRtpSession.SetRTPTimeConversion(aHeaderInfo.iTimestamp, 1000*1000/iRtpSessionArr[ret]->iSamplingRate);
       
   883 		iRtpSessionArr[ret]->iFirstPacketSent = ETrue;
       
   884 		}
       
   885 
       
   886 	
       
   887 	TDes8 &wrtPayload = sendPkt.WritePayload();
       
   888 	wrtPayload = aPayloadData;
       
   889 	
       
   890 	/* This is an Async Send. So insert this packet in to the 
       
   891 	 * the send queue.
       
   892 	 */
       
   893 	TRtpSendReqNode *sendReqNode = NULL;
       
   894 	sendReqNode = new TRtpSendReqNode();
       
   895 	if(!sendReqNode)
       
   896 		{
       
   897 		sendPkt.Close();
       
   898 		return KErrNoMemory;
       
   899 		}
       
   900 	
       
   901 	sendReqNode->iPktToSend = sendPkt;
       
   902 	sendReqNode->iStatus = &aStatus;
       
   903 	iRtpSessionArr[ret]->iPendingReqQue->AddFirst(*sendReqNode);
       
   904 	*sendReqNode->iStatus = KRequestPending;
       
   905 	/* If this is the only pending element in the queue schedule immediately */
       
   906 	if(iRtpSessionArr[ret]->iPendingReqQue->IsLast(sendReqNode))
       
   907 		{
       
   908 		__RTP_LOG("Async Send ..Sending Immediately!");
       
   909 	    return SendRtpDataFromPendingQueue(iRtpSessionArr[ret]);	
       
   910 		}
       
   911 	
       
   912 	__RTP_LOG("Async Send ..Packet Queued!");
       
   913 	//TODO pre allocate a Max Size
       
   914     // The packet will be closed when Send is completed
       
   915 	return KErrNone;
       
   916 	}
       
   917 
       
   918  /**
       
   919    * Send an RTP data packet asynchronously, with a given sequence number,
       
   920    * in a Transmit stream mainly for retransmission purpose.
       
   921  */
       
   922  TInt CRtpManager::SendRtpPacket( TRtpId aTranStreamId,
       
   923                                 TRtpSequence ,
       
   924                                 const TRtpSendHeader& aHeaderInfo,
       
   925                                 const TDesC8& aPayloadData,
       
   926                                 TRequestStatus& aStatus )
       
   927 	{
       
   928     LOG_FUNC_ENTRY("CRtpManager::SendRtpPacket - With Sequence Called!!");
       
   929     //TODO We SHOULD consider the Sequence number as well!	
       
   930 	return SendRtpPacket(aTranStreamId, aHeaderInfo, aPayloadData, aStatus) ;
       
   931 	}
       
   932 
       
   933 
       
   934 /**
       
   935   * Send a non-RTP (control) data packet asynchronously
       
   936 */
       
   937  void CRtpManager::SendDataL( TRtpId aSessionId, TBool aUseRTPSocket, 
       
   938 		                      const TDesC8& aData, TRequestStatus&  aStatus)
       
   939 	{
       
   940 	LOG_FUNC_ENTRY("CRtpManager::SendDataL");
       
   941 	__RTP_LOG1("aSessionId: %u",aSessionId)
       
   942 	TInt ret = FindSessionL(aSessionId);
       
   943 	RSocket *sock = NULL;
       
   944 	TInetAddr remAddr = iRtpSessionArr[ret]->iRemoteAddress;
       
   945 	if(aUseRTPSocket)
       
   946 		{
       
   947 		sock = GetRtpSocket(aSessionId);
       
   948 		}
       
   949 	else
       
   950 		{
       
   951 		if(!iRtpSessionArr[ret]->iRtcpEnabled)
       
   952 			User::Leave(KErrNotSupported);
       
   953 		sock = GetRtcpSocket(aSessionId);
       
   954 		remAddr = iRtpSessionArr[ret]->iRemoteRTCPAddress;
       
   955 		}
       
   956 	/* Send the data out through the Socket */
       
   957 	sock->SendTo(aData,remAddr,0,aStatus);
       
   958 	return;
       
   959 	}
       
   960 
       
   961  /**
       
   962   * Cancel an outstanding SendRtpPacket() operation.
       
   963   */
       
   964  void CRtpManager::CancelSend( TRtpId aSessId)
       
   965 	 {
       
   966 	 /* Its a Bit tricky here. 
       
   967 	  * We have two levels of Active Objects and the Symbian stack
       
   968 	  * do not provide any API to cancel the Send request. As a workarnd we accesses the
       
   969 	  * RTP Socket directly and cancels the send ( RSocket::CancelSend())
       
   970 	  * Internal statistics are not rolled back in this case, but surely we can
       
   971 	  * live with that.
       
   972 	  * 
       
   973 	  * The Active object who issued this call will do a User::WaitForRequest() 
       
   974 	  * immediatly after calling Cancel. (See CActive::Cancel() implementation).
       
   975 	  * This means we should complete the request with KErrCancel here itself or
       
   976 	  * thread will block (Because we are not exactly an Async Service provider).
       
   977 	  * Once the request is completed we can expect a ESendFail callback or an
       
   978 	  * ESendSuccess callback from stack ( Second one beacuse the request might have
       
   979 	  * been completed already).
       
   980 	  */
       
   981 	LOG_FUNC_ENTRY("CRtpManager::CancelSend");
       
   982 	__RTP_LOG1("SessId: %u",aSessId)
       
   983 
       
   984 	TInt ret = FindSession(aSessId);
       
   985 	if(ret < 0)
       
   986 		{
       
   987 		ASSERT(ret!=KErrNone);
       
   988 		return;
       
   989 		}
       
   990 	if(iRtpSessionArr[ret]->iPendingReqQue->IsEmpty())
       
   991 		{
       
   992 		/* There is no pending request. This probably means the request was
       
   993 		 * already completed but the App is yet to see it..
       
   994 		 */
       
   995 		__RTP_LOG("NO pending request .. Returning!")
       
   996 		return;
       
   997 		}
       
   998 	
       
   999 	TRtpSendReqNode *reqNode = iRtpSessionArr[ret]->iPendingReqQue->Last();
       
  1000     /* Once send is canceled complete Applications request. Also if the pending
       
  1001 	 * queue is not empty schedule a new transmission here itself */
       
  1002 	iRtpSessionArr[ret]->iRtpSendSource.Cancel();
       
  1003 	User::RequestComplete(reqNode->iStatus, KErrCancel);
       
  1004 	iRtpSessionArr[ret]->iPendingReqQue->Remove(*reqNode);
       
  1005 	reqNode->iPktToSend.Close();
       
  1006 	delete reqNode;
       
  1007 
       
  1008 	if(!iRtpSessionArr[ret]->iPendingReqQue->IsEmpty())
       
  1009 		{
       
  1010 		__RTP_LOG("Scheduling another send from PendingQueue")
       
  1011 		SendRtpDataFromPendingQueue(iRtpSessionArr[ret]);
       
  1012 		}
       
  1013 
       
  1014 	return;
       
  1015 	}
       
  1016 
       
  1017   /**
       
  1018   * Register a callback object for receiving RTCP packets associated with
       
  1019   * a given RTP Session. Only one observer callback object is allowed to
       
  1020   * be registered. One of aRtcpObserver object's callback functions is
       
  1021   * called when an RTCP packet of that type is received.
       
  1022   */
       
  1023  TInt CRtpManager::RegisterRtcpObserver( TRtpId aSessionId, MRtcpObserver& aRtcpObserver )
       
  1024 	 {
       
  1025 	LOG_FUNC_ENTRY("CRtpManager::RegisterRtcpObserver");
       
  1026 	__RTP_LOG1("SessId: %u",aSessionId)
       
  1027 
       
  1028 	 TInt ret = FindSession(aSessionId);
       
  1029 	 if(ret < 0)
       
  1030 	 	return ret;
       
  1031 	 iRtpSessionArr[ret]->iRtcpObserver = &aRtcpObserver;
       
  1032 	 return KErrNone;
       
  1033 	 }
       
  1034 
       
  1035   /**
       
  1036   * Unregister RTCP observer callback object associated with an RTP
       
  1037   * session.
       
  1038   */
       
  1039  void CRtpManager::UnregisterRtcpObserver( TRtpId aSessionId )
       
  1040 	 {
       
  1041 	 LOG_FUNC_ENTRY("CRtpManager::UnregisterRtcpObserver");
       
  1042 	 __RTP_LOG1("SessId: %u",aSessionId)
       
  1043 
       
  1044 	 TInt ret = FindSession(aSessionId);
       
  1045 	 if(ret >= 0)
       
  1046 		 iRtpSessionArr[ret]->iRtcpObserver = NULL; 
       
  1047 	 return;
       
  1048 	 }
       
  1049  /**
       
  1050  * Send an RTCP APP packet for a Transmit stream.
       
  1051  */
       
  1052  TInt CRtpManager::SendRtcpAppPacket( TRtpId aTranStreamId, const TRtcpApp& aApp )
       
  1053 	 {
       
  1054 	 LOG_FUNC_ENTRY("CRtpManager::SendRtcpAppPacket");
       
  1055 	 __RTP_LOG1("aTranStreamId: %u",aTranStreamId)
       
  1056 
       
  1057 	 /* A send stream should be open to send an RTCP Bye packet */
       
  1058 	 //Transmit Stream ID and Session Id are same
       
  1059 	 TInt ret = FindSession(aTranStreamId);
       
  1060 	 if(ret < 0)
       
  1061 	 	return ret;
       
  1062 	 ASSERT(iRtpSessionArr[ret]->iRtcpEnabled);
       
  1063 	 
       
  1064 	 TPtrC8 appName;
       
  1065 	 appName.Set(aApp.iName,4); //Name is 4 Characters RFC 3550 Sec 6.7
       
  1066 	 
       
  1067 	 TPtrC8 appData;
       
  1068 	 appData.Set(aApp.iAppData,aApp.iAppDataLen);
       
  1069 	 
       
  1070 	 TUint8 subType = aApp.iSubType;
       
  1071 	 
       
  1072 	 TRAPD(err,iRtpSessionArr[ret]->iRtpSession.SendAPPL(appName,appData, subType));
       
  1073 	 
       
  1074 	 return err;
       
  1075 	 }
       
  1076 
       
  1077  /**
       
  1078   * Send an RTCP BYE packet for a Transmit stream.
       
  1079  */
       
  1080  TInt CRtpManager::SendRtcpByePacket( TRtpId aTranStreamId, const TDesC8& aReason)
       
  1081 	 {
       
  1082 	 LOG_FUNC_ENTRY("CRtpManager::SendRtcpByePacket");
       
  1083 	 __RTP_LOG1("aTranStreamId: %u",aTranStreamId)
       
  1084 
       
  1085 	 /* A send stream should be open to send an RTCP Bye packet */
       
  1086 	 //Transmit Stream ID and Session Id are same
       
  1087 	 TInt ret = FindSession(aTranStreamId);
       
  1088 	 if(ret < 0)
       
  1089 	 	return ret;
       
  1090 	 ASSERT(iRtpSessionArr[ret]->iRtpSendSource.IsOpen());
       
  1091 	 TRAPD(err,iRtpSessionArr[ret]->iRtpSendSource.ByeL(const_cast<TDesC8&>(aReason)));
       
  1092 	 return err;
       
  1093 	 }
       
  1094 
       
  1095 /** 
       
  1096  * Send an RTCP RR packet for a Reception stream.
       
  1097 */
       
  1098 TInt CRtpManager::SendRtcpRrPacket( TRtpId aRcvStreamId )
       
  1099 	{
       
  1100 	 LOG_FUNC_ENTRY("CRtpManager::SendRtcpRrPacket");
       
  1101 	 __RTP_LOG1("aRcvStreamId: %u",aRcvStreamId)
       
  1102 
       
  1103     /* No specific way to Send an RR Report alone */
       
  1104 	//Do we need to?
       
  1105 	TInt ret = FindStream(aRcvStreamId);
       
  1106 	if(ret<0)
       
  1107 		{
       
  1108 		return ret;
       
  1109 		}
       
  1110 
       
  1111 	ret = FindSession(iRtpStreamsArr[ret].iSessionKey);
       
  1112 	TUint8 flg = 0x81;
       
  1113 	TBuf8<1> flags;
       
  1114 	flags.Copy(&flg,1);
       
  1115 	TRAP(ret, iRtpSessionArr[ret]->iRtpSession.SendRTCPPacketL(flags));
       
  1116 	return ret;
       
  1117 	}
       
  1118  
       
  1119  /** 
       
  1120  * Send an RTCP SR packet for a Transmit stream.
       
  1121  */
       
  1122  TInt CRtpManager::SendRtcpSrPacket( TRtpId aTranStreamId )
       
  1123  	{
       
  1124 	 LOG_FUNC_ENTRY("CRtpManager::SendRtcpSrPacket");
       
  1125 	 __RTP_LOG1("aTranStreamId: %u",aTranStreamId)
       
  1126 
       
  1127 	//NOTE: TransID same as SessionId
       
  1128 	TInt ret = FindSession(aTranStreamId);
       
  1129 	if(ret<0)
       
  1130 		return ret;
       
  1131 	
       
  1132 	TUint8 flg = 0x81;
       
  1133 	TBuf8<1> flags;
       
  1134 	flags.Copy(&flg,1);
       
  1135     TRAP(ret, iRtpSessionArr[ret]->iRtpSession.SendRTCPPacketL(flags));
       
  1136     return ret;  
       
  1137  	}
       
  1138 
       
  1139 /** 
       
  1140  * Suspend RTCP sending on/off, calculations will continue. 
       
  1141 */
       
  1142 TInt CRtpManager::SuspendRtcpSending( TRtpId aSessionId, TBool aAutoSending )
       
  1143 	{
       
  1144 	 LOG_FUNC_ENTRY("CRtpManager::SuspendRtcpSending");
       
  1145 	 __RTP_LOG2("aSessionId: %u aAutoSending %d",aSessionId,aAutoSending)
       
  1146 
       
  1147 	//NOTE: TransID same as SessionId
       
  1148 	TInt ret = FindSession(aSessionId);
       
  1149 	if(ret<0)
       
  1150 		return ret;
       
  1151 	if(iRtpSessionArr[ret]->iRtcpEnabled)
       
  1152 		{
       
  1153 		iRtpSessionArr[ret]->iRtpSession.SetRTCPAutoSend(aAutoSending);
       
  1154 		return KErrNone;
       
  1155 		}
       
  1156 	else
       
  1157 		{
       
  1158 		return KErrNotSupported;
       
  1159 		}
       
  1160 	}
       
  1161  
       
  1162 /** 
       
  1163  * Gets the status of automatic RTCP sending.
       
  1164  */
       
  1165 TInt CRtpManager::IsRtcpSendingSuspended( TRtpId aSessionId, TBool& aAutoSending )
       
  1166 	{
       
  1167 	LOG_FUNC_ENTRY("CRtpManager::IsRtcpSendingSuspended");
       
  1168 
       
  1169 	TInt ret = FindSession(aSessionId);
       
  1170 	if(ret<0)
       
  1171 		return ret;
       
  1172 	if(iRtpSessionArr[ret]->iRtcpEnabled)
       
  1173 		{
       
  1174 		aAutoSending = iRtpSessionArr[ret]->iRtpSession.RTCPAutoSend();
       
  1175 		return KErrNone;
       
  1176 		}
       
  1177 	else
       
  1178 		{
       
  1179 		return KErrNotSupported;
       
  1180 		}
       
  1181 	}
       
  1182 
       
  1183 /**
       
  1184 * Get the session ID of a stream, which belongs to that session.
       
  1185 */
       
  1186  TRtpId CRtpManager::GetSessionId( TRtpId aStreamId )
       
  1187 	 {
       
  1188 	 TInt ret = FindStream(aStreamId);
       
  1189 	 if(ret<0)
       
  1190 		{
       
  1191 		TInt idx = FindSession(aStreamId);
       
  1192 		if(idx < 0)
       
  1193 		    {
       
  1194 		    return idx;
       
  1195 		    }
       
  1196 		if(iRtpSessionArr[idx]->iRtpSendSource.IsOpen())
       
  1197 		    {
       
  1198 		    return iRtpSessionArr[idx]->iKey;
       
  1199 		    }
       
  1200 		return ret;
       
  1201 		}
       
  1202 	 return iRtpStreamsArr[ret].iSessionKey;
       
  1203 	 }
       
  1204 
       
  1205  
       
  1206 /**
       
  1207 * Get address of Socket object used by a given RTP Session
       
  1208 * to send/receive RTP data packets.
       
  1209 */
       
  1210  RSocket* CRtpManager::GetRtpSocket( TRtpId aSessionId )
       
  1211  	{
       
  1212  	LOG_FUNC_ENTRY("CRtpManager::GetRtpSocket");
       
  1213  	__RTP_LOG1("aSessId %u",aSessionId)
       
  1214  	
       
  1215 	TInt ret = FindSession(aSessionId);
       
  1216 	if( ret<0 )
       
  1217 		return NULL;
       
  1218  	return iRtpSessionArr[ret]->iRtpSession.RtpSocket();
       
  1219  	}
       
  1220 
       
  1221 /**
       
  1222 * Get address of Socket object used by a given RTP Session
       
  1223 * to send/receive RTCP control packets.
       
  1224 */
       
  1225  RSocket* CRtpManager::GetRtcpSocket( TRtpId  aSessionId)
       
  1226 	{
       
  1227 	LOG_FUNC_ENTRY("CRtpManager::GetRtcpSocket");
       
  1228  	__RTP_LOG1("aSessId %u",aSessionId)
       
  1229 	
       
  1230 	TInt ret = FindSession(aSessionId);
       
  1231 	if(ret<0 || !iRtpSessionArr[ret]->iRtcpEnabled)
       
  1232 		return NULL;
       
  1233  	return iRtpSessionArr[ret]->iRtpSession.RtcpSocket();
       
  1234 	}
       
  1235 
       
  1236  /**
       
  1237  * Retrieve statistical information for a stream
       
  1238  * based on the reports from RTCP SR & RR packets.
       
  1239  * @param aStreamId - [input] ID of stream
       
  1240  * @param aStat - [output] Statistical information
       
  1241  * @return KErrNone if successful; system wide error code otherwise
       
  1242  */
       
  1243  TInt CRtpManager::GetStreamStatistics( TRtpId aStreamId, TRtpPeerStat& aStat )
       
  1244 	 {
       
  1245 	 LOG_FUNC_ENTRY("CRtpManager::GetStreamStatistics");
       
  1246 	 /* Find the session and the stream */
       
  1247 	 TInt ret = FindStream(aStreamId);
       
  1248 	 if(ret<0)
       
  1249 		{
       
  1250 		return ret;
       
  1251 		}
       
  1252 	 
       
  1253 	 RRtcpSRPart srPart = iRtpStreamsArr[ret].iRecvSource.GetSR();
       
  1254 	 //Filling up the SR part first
       
  1255 	 aStat.iNumPacketsSent   = srPart.PacketCount();    
       
  1256 	 aStat.iCumNumOctetsSent = srPart.ByteCount();       
       
  1257 	 aStat.iRoundTripDelay   = 0; //TODO To be supported       
       
  1258 	 aStat.iTxBandwidth = 0; //TODO find the use cases
       
  1259 	 
       
  1260 	 return KErrNone;
       
  1261 	 }
       
  1262 
       
  1263  /**
       
  1264  * Get sampling rate setting for a payload type.
       
  1265  */
       
  1266  TUint32 CRtpManager::GetSamplingRate( TUint8 aPayloadType )
       
  1267 	  {
       
  1268 	  LOG_FUNC_ENTRY("CRtpManager::GetSamplingRate");
       
  1269 	  __RTP_LOG1("PayLoadType %d",aPayloadType);
       
  1270 	  /* Iterate through the sessions and return its sampling rate*/
       
  1271 	  for(int i=0; i< iRtpSessionArr.Count(); i++)
       
  1272 		  {
       
  1273 		  __RTP_LOG1("iPayloadtype -->> :%d", iRtpSessionArr[i]->iPayloadType);
       
  1274 		  __RTP_LOG1("aPayloadtype -->> :%d", aPayloadType);
       
  1275 		  if(iRtpSessionArr[i]->iPayloadType == aPayloadType)
       
  1276 			  {
       
  1277 			  return iRtpSessionArr[i]->iSamplingRate;
       
  1278 			  }
       
  1279 		  }
       
  1280 	  //Not found
       
  1281 	  return 0;
       
  1282 	  }
       
  1283 
       
  1284  /**
       
  1285  * Set sampling rate for a payload type.
       
  1286  */
       
  1287  TInt CRtpManager::SetSamplingRate( TUint8 aPayloadType, TUint32 aSamplingRate )
       
  1288 	 {
       
  1289 	 LOG_FUNC_ENTRY("CRtpManager::SetSamplingRate");
       
  1290 	 __RTP_LOG2("PayloadType %d SamplingRate %u",aPayloadType,aSamplingRate)
       
  1291 	  /* Iterate through the sessions and set its sampling rate*/
       
  1292 	  for(int i=0; i< iRtpSessionArr.Count(); i++)
       
  1293 		  {
       
  1294 		  if(iRtpSessionArr[i]->iPayloadType == aPayloadType || KRtpPayloadTypeUnspecified == iRtpSessionArr[i]->iPayloadType)
       
  1295 			  {
       
  1296 			  iRtpSessionArr[i]->iPayloadType = aPayloadType;
       
  1297 			  iRtpSessionArr[i]->iSamplingRate = aSamplingRate;
       
  1298 			  iRtpSessionArr[i]->iRtpSession.SetRTPTimeConversion(0,aSamplingRate/1000);
       
  1299 			  }
       
  1300 		  /* Also update the Sampling rates so that received streams are properly handled */
       
  1301 		  iRtpSessionArr[i]->iRtpSession.SetSamplingRate(aPayloadType,aSamplingRate);
       
  1302 		  }
       
  1303 	  return KErrNone;
       
  1304 	 }
       
  1305 
       
  1306  /**
       
  1307  * Set RTCP parameters for a given RTP Session.
       
  1308  * This function does nothing if RTCP was not enabled previously.
       
  1309  */
       
  1310  TInt CRtpManager::SetRtcpParameters( TRtpId aSessionId, const TRtcpParams& aRtcpParams )
       
  1311 	 {
       
  1312 	 TInt ret = FindSession(aSessionId);
       
  1313 	 if(ret<0)
       
  1314 	 	return ret;
       
  1315 	 ASSERT(iRtpSessionArr[ret]->iRtcpEnabled);
       
  1316 	 iRtpSessionArr[ret]->iRtpSession.SetRtcpInterval(const_cast<TTimeIntervalMicroSeconds32&>(aRtcpParams.iRtcpTimeOut));
       
  1317 	 iRtpSessionArr[ret]->iRtpSession.SetBandwidth(aRtcpParams.iSessionBWidth);
       
  1318 	 
       
  1319 	 return KErrNone;
       
  1320 	 }
       
  1321 
       
  1322 
       
  1323  /**
       
  1324   * Synchronous custom command interface for future extensions.
       
  1325   * Input/output data and return value are defined by each custom command
       
  1326   */
       
  1327    TInt CRtpManager::CustomCommandSync( TInt , const TDesC8& ,
       
  1328                            const TDesC8& , TDes8&  )
       
  1329 	   {
       
  1330 	   /* Not Supported. But is it ok to Fail? */
       
  1331 	   return KErrNotSupported;
       
  1332 	   }
       
  1333 
       
  1334   /**
       
  1335   * ASynchronous custom command interface for future extensions.
       
  1336   * Input/output data and return value are defined by each custom command
       
  1337   */
       
  1338    TInt CRtpManager::CustomCommandAsync( TInt , const TDesC8& ,  const TDesC8& ,
       
  1339                                     	 TDes8& ,TRequestStatus&  )
       
  1340 	   {
       
  1341 	   /* Not Supported. But is it ok to Fail? */
       
  1342 	   return KErrNotSupported;
       
  1343 	   }
       
  1344 
       
  1345 
       
  1346  TInt CRtpManager::FindSession(TRtpId aSessionId)
       
  1347 	{
       
  1348 	/* A simple iteration to find the session */
       
  1349 	for(TInt i=0; i < iRtpSessionArr.Count(); i++)
       
  1350 		{
       
  1351 		if(iRtpSessionArr[i]->iKey == aSessionId)
       
  1352 			{
       
  1353 			return i;
       
  1354 			}
       
  1355 		}
       
  1356 	__RTP_LOG("****FindSession Session Not Found!****")
       
  1357 	return KErrNotFound;
       
  1358 	}
       
  1359 
       
  1360 TInt CRtpManager::FindSessionL(TRtpId aSessionId)
       
  1361 	{
       
  1362 	TInt ret = FindSession(aSessionId);
       
  1363 	User::LeaveIfError(ret);
       
  1364 	return ret;
       
  1365 	}
       
  1366 
       
  1367 TInt CRtpManager::FindStream(TRtpId aStreamId)
       
  1368 	{
       
  1369 	/* A simple iteration to find the session */
       
  1370 	for(TInt i=0; i < iRtpStreamsArr.Count(); i++)
       
  1371 		{
       
  1372 		if(iRtpStreamsArr[i].iKey == aStreamId)
       
  1373 			{
       
  1374 			return i;
       
  1375 			}
       
  1376 		}
       
  1377 	__RTP_LOG("****FindStream Stream Not Found!****")
       
  1378 	return KErrNotFound;
       
  1379 	}
       
  1380 
       
  1381 TInt CRtpManager::FindStreamL(TRtpId aStreamId)
       
  1382 	{
       
  1383 	TInt ret = FindStream(aStreamId);
       
  1384 	User::LeaveIfError(ret);
       
  1385 	return ret;
       
  1386 	}
       
  1387 
       
  1388 TInt CRtpManager::GetDefaultIapIdL()
       
  1389 	{
       
  1390 	LOG_FUNC_ENTRY("CRtpManager::GetDefaultIapIdL");
       
  1391 	TInt apId;
       
  1392 	CCommsDatabase* db = CCommsDatabase::NewL(EDatabaseTypeIAP);
       
  1393 	CleanupStack::PushL(db);
       
  1394 	CCommsDbConnectionPrefTableView* view= db->OpenConnectionPrefTableInRankOrderLC(ECommDbConnectionDirectionOutgoing);
       
  1395 	CCommsDbConnectionPrefTableView::TCommDbIapConnectionPref Pref;
       
  1396 	view->GotoFirstRecord();
       
  1397 	view->ReadConnectionPreferenceL(Pref);
       
  1398 	apId = Pref.iBearer.iIapId;
       
  1399 	CleanupStack::PopAndDestroy(2);
       
  1400 	__RTP_LOG1("IapId %d",apId)
       
  1401 	LOG_FUNC_EXIT("CRtpManager::GetDefaultIapIdL");
       
  1402 	return apId;
       
  1403 	}
       
  1404 
       
  1405 /* Schedules RTP transmission from the Head of the pending queue
       
  1406  */
       
  1407 TInt CRtpManager::SendRtpDataFromPendingQueue(CRtpSessionInfo *aSessInfo)
       
  1408 	{
       
  1409 	ASSERT(!aSessInfo->iPendingReqQue->IsEmpty());
       
  1410 	TRtpSendReqNode *reqNode = aSessInfo->iPendingReqQue->Last();
       
  1411 	reqNode->iPktToSend.Send();
       
  1412 	return KErrNone;
       
  1413 	}
       
  1414 
       
  1415 void CRtpManager::RegisterEventsOnSessionL(CRtpSessionInfo *aSessionInfo)
       
  1416 	{
       
  1417 	RRtpSession session = aSessionInfo->iRtpSession;
       
  1418 	
       
  1419 	session.RegisterEventCallbackL(ERtpSessionFail,
       
  1420 			                       RtpSessionLevelCB,
       
  1421 			                       aSessionInfo,
       
  1422 			                       ERtpNotOneShot);	
       
  1423 	
       
  1424 	session.RegisterEventCallbackL(ERtpNewSource,
       
  1425 			                       RtpSessionLevelCB,
       
  1426 			                       aSessionInfo,
       
  1427 			                       ERtpNotOneShot);			                       
       
  1428 	
       
  1429 	session.RegisterEventCallbackL(ERtpNewRR,
       
  1430 			                       RtpSessionLevelCB,
       
  1431 			                       aSessionInfo,
       
  1432 			                       ERtpNotOneShot);			                       
       
  1433 	
       
  1434 	session.RegisterEventCallbackL(ERtpBufferOverflow,
       
  1435 			                       RtpSessionLevelCB,
       
  1436 			                       aSessionInfo,
       
  1437 			                       ERtpNotOneShot);			                       
       
  1438 	
       
  1439 	session.RegisterEventCallbackL(ERtpUndersizedPacket,
       
  1440 			                       RtpSessionLevelCB,
       
  1441 			                       aSessionInfo,
       
  1442 			                       ERtpNotOneShot);			                       	                       
       
  1443 	}
       
  1444 
       
  1445 
       
  1446 void CRtpManager::RegisterEventsOnRtpRcvSourceL(RRtpReceiveSource &aRcvSrc, TRtpStreamInfo *apStrmInfo)
       
  1447 	{
       
  1448         aRcvSrc.RegisterEventCallbackL(ERtpPacketReceived,
       
  1449 				                         CRtpManager::RtpStreamLevelCB,
       
  1450 				                         apStrmInfo,
       
  1451 				                         ERtpNotOneShot);		
       
  1452 		
       
  1453 		aRcvSrc.RegisterEventCallbackL(ERtpSourceFail,
       
  1454 				                         CRtpManager::RtpStreamLevelCB,
       
  1455 				                         apStrmInfo,
       
  1456 				                         ERtpNotOneShot);
       
  1457 		
       
  1458 		aRcvSrc.RegisterEventCallbackL(ERtpAPP,
       
  1459 				                         CRtpManager::RtpStreamLevelCB,
       
  1460 				                         apStrmInfo,
       
  1461 				                         ERtpNotOneShot);
       
  1462 
       
  1463 		
       
  1464 		aRcvSrc.RegisterEventCallbackL(ERtpBYE,
       
  1465 				                         CRtpManager::RtpStreamLevelCB,
       
  1466 				                         apStrmInfo,
       
  1467 				                         ERtpNotOneShot);
       
  1468 		
       
  1469 		aRcvSrc.RegisterEventCallbackL(ERtpSR,
       
  1470 				                         CRtpManager::RtpStreamLevelCB,
       
  1471 				                         apStrmInfo,
       
  1472 				                         ERtpNotOneShot);
       
  1473 		
       
  1474 		aRcvSrc.RegisterEventCallbackL(ERtpRR,
       
  1475 				                         CRtpManager::RtpStreamLevelCB,
       
  1476 				                         apStrmInfo,
       
  1477 				                         ERtpNotOneShot);
       
  1478 		
       
  1479 		aRcvSrc.RegisterEventCallbackL(ERtpSDES,
       
  1480 				                         CRtpManager::RtpStreamLevelCB,
       
  1481 				                         apStrmInfo,
       
  1482 				                         ERtpNotOneShot);                      	                       
       
  1483 	}
       
  1484 
       
  1485 void CRtpManager::HandleNonRtpDataL(CRtpSessionInfo *apSessionInfo)
       
  1486     {
       
  1487     apSessionInfo->iNonRtpDataObserver->NonRTPDataReceived(apSessionInfo->iPortNumber,
       
  1488                                                            ETrue,
       
  1489                                                            apSessionInfo->iRtpSession.NonRtpDataL());
       
  1490     apSessionInfo->iRtpSession.RegisterEventCallbackL(ENonRtpDataReceived,
       
  1491                                                        RtpSessionLevelCB,
       
  1492                                                        apSessionInfo,
       
  1493                                                        ERtpOneShot);
       
  1494     }
       
  1495 
       
  1496 void CRtpManager::HandleNonRtcpDataL(CRtpSessionInfo *apSessionInfo)
       
  1497     {
       
  1498      apSessionInfo->iNonRtpDataObserver->NonRTPDataReceived(apSessionInfo->iPortNumber+1,
       
  1499                                                              EFalse,
       
  1500                                                              apSessionInfo->iRtpSession.NonRtcpDataL());
       
  1501      apSessionInfo->iRtpSession.RegisterEventCallbackL(ENonRtcpDataReceived,
       
  1502                                                        RtpSessionLevelCB,
       
  1503                                                        apSessionInfo,
       
  1504                                                        ERtpOneShot);
       
  1505     }
       
  1506 
       
  1507 void CRtpManager::RtpSessionLevelCB(CRtpSessionInfo* apSessionInfo, const TRtpEvent& aEvent)
       
  1508 	{
       
  1509 	 LOG_FUNC_ENTRY("CRtpManager::RtpSessionLevelCB");
       
  1510 	 __RTP_LOG1("EventType %x",aEvent.Type())
       
  1511 	 CRtpManager *pSelf = apSessionInfo->iRtpManager;
       
  1512 
       
  1513 	/* Event Send succeded or Failed */
       
  1514 	if(ERtpSendSucceeded == aEvent.Type() || ERtpSendFail == aEvent.Type())
       
  1515 		{
       
  1516 		/* We are  here only if Async Send was initiated */
       
  1517 		TInt retCode = (aEvent.Type()==ERtpSendFail)?aEvent.Status():KErrNone;
       
  1518 		
       
  1519 		/* An Async send is Complete. Notify the Application and schedule for next
       
  1520 		 * transmission if send queue is not empty */
       
  1521 		ASSERT(!apSessionInfo->iPendingReqQue->IsEmpty());
       
  1522 		TRtpSendReqNode *reqNode = apSessionInfo->iPendingReqQue->First();
       
  1523 		reqNode->iPktToSend.Close();
       
  1524 			
       
  1525 		__RTP_LOG("Complete Async Request")
       
  1526 		/* Complete the Async Request */
       
  1527 		User::RequestComplete(reqNode->iStatus,retCode);
       
  1528 		apSessionInfo->iPendingReqQue->Remove(*reqNode);
       
  1529 		delete reqNode;
       
  1530 		
       
  1531 		if(!apSessionInfo->iPendingReqQue->IsEmpty())
       
  1532 			{
       
  1533 			//OK to ignore Send Errors ?
       
  1534 			apSessionInfo->iRtpManager->SendRtpDataFromPendingQueue(apSessionInfo);
       
  1535 			}
       
  1536 		}
       
  1537 	/* A new source was detected */
       
  1538 	if(ERtpNewSource == aEvent.Type())
       
  1539 		{
       
  1540 		/* Create a ReceiveSource for this stream. */
       
  1541 		RRtpReceiveSource rtpRcvSrc;
       
  1542 		TRAPD(err, rtpRcvSrc = apSessionInfo->iRtpSession.NewReceiveSourceL());
       
  1543 	    if(err)
       
  1544 	         {
       
  1545 	          __RTP_LOG1("Receive source could not be created %d Returning", err)
       
  1546 	          return;
       
  1547 	         }
       
  1548 		
       
  1549 		/* See if there is a Pre-Created stream that will accept this PayloadType.
       
  1550 		   If there are no Pre Created stream that accepts this PayloadType just
       
  1551 		   Blindly latch on to the First PreCreated Stream. This behaviour is not
       
  1552 		   really correct but is inline with the S60 RTP Stack behaviour. */
       
  1553 		TUint32 strmKey = 0;
       
  1554 		TInt tmpIdx = -1; //Used to remember the last index of a eStreamPreCreated stream
       
  1555 
       
  1556 		TUint payloadType = 0;
       
  1557 		TRAP(err, payloadType=rtpRcvSrc.PayLoadTypeL());
       
  1558 		if(err == KErrNotFound)
       
  1559 			{
       
  1560 			__RTP_LOG1("Payload type was not found", err)
       
  1561 			}
       
  1562 
       
  1563 		__RTP_LOG1("PayloadType %d",payloadType)
       
  1564 
       
  1565 		for(int i=0; i<pSelf->iRtpStreamsArr.Count();i++)
       
  1566 			{
       
  1567 			if(pSelf->iRtpStreamsArr[i].iState == TRtpStreamInfo::eStreamPreCreated)
       
  1568 				{
       
  1569 				/* To make later access easier */
       
  1570 				tmpIdx = i;
       
  1571 				}
       
  1572 
       
  1573 			/* Try to match the Payload type first */
       
  1574 			if(pSelf->iRtpStreamsArr[i].iPayloadType ==  payloadType
       
  1575 					&& pSelf->iRtpStreamsArr[i].iState == TRtpStreamInfo::eStreamPreCreated)
       
  1576 				{
       
  1577 				__RTP_LOG1("Found PreCreated Stream at %d",i);
       
  1578 				/* Ok so there is a PreCreated stream available */
       
  1579 				pSelf->iRtpStreamsArr[i].iIsRecvStream = ETrue;
       
  1580 				pSelf->iRtpStreamsArr[i].iRecvSource = rtpRcvSrc;
       
  1581 				pSelf->iRtpStreamsArr[i].iState = TRtpStreamInfo::eStreamReadyToUse;
       
  1582 				strmKey = pSelf->iRtpStreamsArr[i].iKey;
       
  1583 				break;
       
  1584 				}
       
  1585 			}
       
  1586 		
       
  1587 		if(!strmKey && tmpIdx>=0)
       
  1588 			{
       
  1589 			__RTP_LOG1("No PreCreated Stream : Using ID %d",tmpIdx)
       
  1590 			/* Latch on to the unspecified stream */
       
  1591 			pSelf->iRtpStreamsArr[tmpIdx].iIsRecvStream = ETrue;
       
  1592 			pSelf->iRtpStreamsArr[tmpIdx].iRecvSource = rtpRcvSrc;
       
  1593 			pSelf->iRtpStreamsArr[tmpIdx].iState = TRtpStreamInfo::eStreamReadyToUse;
       
  1594 			strmKey = pSelf->iRtpStreamsArr[tmpIdx].iKey;
       
  1595 			/* Because we ignored the original user selection */
       
  1596 			pSelf->iRtpStreamsArr[tmpIdx].iPayloadType = payloadType;
       
  1597 			}
       
  1598 		
       
  1599 		if(!strmKey)
       
  1600 			{
       
  1601 			__RTP_LOG("No PreCreated Stream : Creating a New Stream")
       
  1602 			/* Create a new stream */
       
  1603 			TRtpStreamInfo strmInfo;
       
  1604 			strmInfo.iKey = Math::Random();
       
  1605 			strmInfo.iSessionKey = apSessionInfo->iKey;
       
  1606 			strmInfo.iState = TRtpStreamInfo::eStreamPostCreated;
       
  1607 			strmInfo.iRecvSource  = rtpRcvSrc;
       
  1608 			TRAPD(error, strmInfo.iPayloadType = rtpRcvSrc.PayLoadTypeL());
       
  1609 			if(error == KErrNotFound)
       
  1610 			{
       
  1611 			__RTP_LOG1("Payload type was not found", error)
       
  1612 			}
       
  1613 			strmInfo.iRtpManager  = pSelf;
       
  1614 			/* Append to the Array */
       
  1615 			pSelf->iRtpStreamsArr.Append(strmInfo); //TODO handle append failures
       
  1616 			strmKey = strmInfo.iKey;
       
  1617 			__RTP_LOG1("Session Did not have a PreCreated Stream New StreamID %u",strmInfo.iKey)
       
  1618 			}
       
  1619 		/* Get a reference to the Strm from Array for Callback Registration */
       
  1620 		TInt idx = pSelf->FindStream(strmKey);
       
  1621 
       
  1622 	    TRAP_IGNORE(pSelf->RegisterEventsOnRtpRcvSourceL(rtpRcvSrc,  &(pSelf->iRtpStreamsArr[idx])));
       
  1623 		}
       
  1624 	if(ERtpNewRR == aEvent.Type())
       
  1625 		{
       
  1626 		/* Session Level RTCP RR . An Empty RR was received */
       
  1627 		if(apSessionInfo->iRtcpObserver)
       
  1628 			{
       
  1629 			apSessionInfo->iRtcpObserver->RrReceived(apSessionInfo->iKey,aEvent.Status());
       
  1630 			}
       
  1631 		}
       
  1632 
       
  1633 	if(ENonRtpDataReceived == aEvent.Type())
       
  1634 		{
       
  1635 		/* Session Level CB. A non rtp data was received */
       
  1636 		if(apSessionInfo->iNonRtpDataObserver)
       
  1637 			{
       
  1638 			TRAP_IGNORE(pSelf->HandleNonRtpDataL(apSessionInfo));
       
  1639 			}
       
  1640 		}
       
  1641 	if(ENonRtcpDataReceived == aEvent.Type())
       
  1642 		{
       
  1643 		/* Session Level CB. A non rtp data was received */
       
  1644 		if(apSessionInfo->iNonRtpDataObserver)
       
  1645 			{
       
  1646 			__RTP_LOG("CRtpManager::RtpSessionLevelCB");
       
  1647 			__RTP_LOG("Non rtcp data - issuing non rtp data received callback");
       
  1648 			TRAP_IGNORE(pSelf->HandleNonRtcpDataL(apSessionInfo));    
       
  1649 			}
       
  1650 		}
       
  1651 	}
       
  1652 
       
  1653 void CRtpManager::RtpStreamLevelCB(TRtpStreamInfo* apStrmInfo, const TRtpEvent& aEvent)
       
  1654 	{
       
  1655 	 LOG_FUNC_ENTRY("CRtpManager::RtpStreamLevelCB");
       
  1656 	 __RTP_LOG1("EventType %x",aEvent.Type())
       
  1657 
       
  1658 	TInt ret;
       
  1659 	if(ERtpPacketReceived == aEvent.Type())
       
  1660 		{
       
  1661 		/* New Packet Arrived. Issue callback */
       
  1662 		TRtpRecvHeader rcvHeader;
       
  1663 		RRtpReceivePacket pkt  = apStrmInfo->iRecvSource.Packet();
       
  1664 		rcvHeader.iMarker      = pkt.Marker();
       
  1665 		rcvHeader.iPadding     = 0; //TODO Pading bits are stripped by Stack? Verify
       
  1666 		rcvHeader.iPayloadType = pkt.PayloadType();
       
  1667 		rcvHeader.iSeqNum      = pkt.SequenceNumber();
       
  1668 		rcvHeader.iTimestamp   = pkt.Timestamp();
       
  1669 		
       
  1670 		ret = apStrmInfo->iRtpManager->FindSession(apStrmInfo->iSessionKey);
       
  1671 		ASSERT(ret>=0);
       
  1672 		if(apStrmInfo->iRtpManager->iRtpSessionArr[ret]->iRtpObserver)
       
  1673 			{
       
  1674 			__RTP_LOG("Issuing RtpReceived callback")
       
  1675 			apStrmInfo->iRtpManager->iRtpSessionArr[ret]->iRtpObserver->RtpPacketReceived(apStrmInfo->iKey,rcvHeader,pkt.Payload());
       
  1676 			}
       
  1677 		else
       
  1678 			{
       
  1679 			__RTP_LOG("Session Did not have RTP Observer Registered")
       
  1680 			}
       
  1681 		pkt.Close();
       
  1682 		}
       
  1683 	if(ERtpRR == aEvent.Type())
       
  1684 		{
       
  1685 		/* Fetch the information on the RR Received from specif SSRC */
       
  1686 		ret = apStrmInfo->iRtpManager->FindSession(apStrmInfo->iSessionKey);
       
  1687 		ASSERT(ret>=0);
       
  1688 		if(apStrmInfo->iRtpManager->iRtpSessionArr[ret]->iRtcpObserver)
       
  1689 			{
       
  1690 			__RTP_LOG("Issuing RtcpRrReceived callback")
       
  1691 			apStrmInfo->iRtpManager->iRtpSessionArr[ret]->iRtcpObserver->RrReceived(apStrmInfo->iKey, aEvent.Status());
       
  1692 			}
       
  1693 		else
       
  1694 			{
       
  1695 			__RTP_LOG("Session Did not have RCTP Observer Reqistered")
       
  1696 			}
       
  1697 		}	
       
  1698 	if(ERtpSDES == aEvent.Type())
       
  1699 		{
       
  1700 		/* Fetch the information on the SDES Received from specif SSRC */
       
  1701 		ret = apStrmInfo->iRtpManager->FindSession(apStrmInfo->iSessionKey);
       
  1702 		ASSERT(ret>=0);
       
  1703 		if(apStrmInfo->iRtpManager->iRtpSessionArr[ret]->iRtcpObserver)
       
  1704 			{
       
  1705 			TBuf8<100> cname;
       
  1706 			TBuf8<100> name;
       
  1707 			TBuf8<100> email;
       
  1708 			
       
  1709 			/* Extract the SDES information and pass it up */
       
  1710 			TRtpSdesParams sdesParams;
       
  1711 			if(KErrNotFound != apStrmInfo->iRecvSource.GetSDES(1,cname))
       
  1712 				{
       
  1713 				sdesParams.iCName.Set(cname);
       
  1714 				}
       
  1715 			if(KErrNotFound != apStrmInfo->iRecvSource.GetSDES(2,name))
       
  1716 				{
       
  1717 				sdesParams.iUserName.Set(name);
       
  1718 				}
       
  1719 			if(KErrNotFound != apStrmInfo->iRecvSource.GetSDES(3,email))
       
  1720 				{
       
  1721 				sdesParams.iEmail.Set(name);
       
  1722 				}
       
  1723 			__RTP_LOG("Issuing SdesReceived callback")
       
  1724 			apStrmInfo->iRtpManager->iRtpSessionArr[ret]->iRtcpObserver->SdesReceived(aEvent.Status(),sdesParams);
       
  1725 			}
       
  1726 		else
       
  1727 			{
       
  1728 			__RTP_LOG("RTCP Observer was not registered. Callback not issued")
       
  1729 			}
       
  1730 		}
       
  1731 	if(ERtpSR == aEvent.Type())
       
  1732 		{
       
  1733 		/* Fetch the information on the SR Received from specific SSRC */
       
  1734 		ret = apStrmInfo->iRtpManager->FindSession(apStrmInfo->iSessionKey);
       
  1735 		ASSERT(ret>=0);
       
  1736 		if(apStrmInfo->iRtpManager->iRtpSessionArr[ret]->iRtcpObserver)
       
  1737 			{
       
  1738 			RRtcpSRPart srPart(apStrmInfo->iRecvSource.GetSR());
       
  1739 			
       
  1740 			TTimeStamps timeStamps;
       
  1741 			srPart.NTPTimestamp(timeStamps.iNTPTimeStampSec, timeStamps.iNTPTimeStampFrac);
       
  1742 			timeStamps.iTimeStamp = srPart.RTPTimestamp();
       
  1743 			
       
  1744 			__RTP_LOG("Issuing SrReceived callback")
       
  1745 			apStrmInfo->iRtpManager->iRtpSessionArr[ret]->iRtcpObserver->SrReceived(apStrmInfo->iKey, apStrmInfo->iRecvSource.SSRC(), timeStamps);
       
  1746 			}
       
  1747 		else
       
  1748 			{
       
  1749 			__RTP_LOG("RTCP Observer was not registered. Callback not issued")
       
  1750 			}
       
  1751 		}	
       
  1752 	if(ERtpAPP == aEvent.Type())
       
  1753 		{
       
  1754 		/* Fetch the information on the RR Received from specif SSRC */
       
  1755 		ret = apStrmInfo->iRtpManager->FindSession(apStrmInfo->iSessionKey);
       
  1756 		ASSERT(ret>=0);
       
  1757 		if(apStrmInfo->iRtpManager->iRtpSessionArr[ret]->iRtcpObserver)
       
  1758 			{
       
  1759 			TRtcpApp app;
       
  1760 			TPtrC8 name;
       
  1761 			TPtrC8 appData;
       
  1762 			TUint  subType;
       
  1763 	
       
  1764 			apStrmInfo->iRecvSource.GetLastApp(name, appData, subType );
       
  1765 			
       
  1766 			//Create Tpr8 from TRtcpApp ..Duh!!
       
  1767 			TPtr8 name1(app.iName,4);
       
  1768 			TPtr8 appData1(app.iAppData,KMaxRtcpAppData);
       
  1769 			name1 = name;
       
  1770 			appData1 = appData;
       
  1771 			app.iAppDataLen = appData.Length();
       
  1772 			app.iSubType = subType;
       
  1773 			
       
  1774 			__RTP_LOG("Issuing SrReceived callback")
       
  1775 			apStrmInfo->iRtpManager->iRtpSessionArr[ret]->iRtcpObserver->AppReceived(apStrmInfo->iKey, aEvent.Status(),app );
       
  1776 			}
       
  1777 		else
       
  1778 			{
       
  1779 			__RTP_LOG("RTCP Observer was not registered. Callback not issued")
       
  1780 			}
       
  1781 		}	
       
  1782 	}
       
  1783 
       
  1784 
       
  1785 // Decrypting RTP Packet recieved from network
       
  1786 TInt CRtpSessionInfo::PreRtpProcessing(TDes8 &aRTPPacket)
       
  1787 	{
       
  1788 	__RTP_LOG("CRtpSessionInfo::PreRtpProcessing")
       
  1789 	//SSRC of recieved packet KRtpSSRCOffset (8)
       
  1790 	const TUint KRtpSSRCOffset = 8;
       
  1791     HBufC8 *rtpPacket = NULL;
       
  1792 	TUint8* packet = const_cast<TUint8*>(aRTPPacket.Ptr());
       
  1793 	TUint32 ssrc = (*(packet+KRtpSSRCOffset+3))+
       
  1794 						(*(packet+KRtpSSRCOffset+2)<<8)+
       
  1795 						(*(packet+KRtpSSRCOffset+1)<<16)+
       
  1796 						(*(packet+KRtpSSRCOffset)<<24);
       
  1797 	
       
  1798 	TRAPD(error, rtpPacket = iSRTPSession->UnprotectRTPL(ssrc, aRTPPacket));
       
  1799 	if(error == KErrNone)
       
  1800 		{
       
  1801 		__RTP_LOG("RTP Packet Decrypted sucessfully")
       
  1802 		aRTPPacket.Copy(rtpPacket->Des());
       
  1803 		}
       
  1804 	else
       
  1805 		{
       
  1806 		__RTP_LOG("RTP Packet Decrypted Failed")
       
  1807 		error = KErrCorrupt;
       
  1808 		}
       
  1809 	delete rtpPacket;
       
  1810 	return error;
       
  1811 	}
       
  1812 
       
  1813 // Encrypting RTP packet before sending
       
  1814 void CRtpSessionInfo::PostRtpProcessing(TDes8 &aRTPPacket)
       
  1815 	{
       
  1816 	__RTP_LOG("CRtpSessionInfo::PostRtpProcessing")
       
  1817 	//SSRC of recieved packet KRtpSSRCOffset (8)
       
  1818 	const TUint KRtpSSRCOffset = 8;
       
  1819     HBufC8 *rtpPacket = NULL;
       
  1820 	TUint8* packet = const_cast<TUint8*>(aRTPPacket.Ptr());
       
  1821 	TUint32 ssrc = (*(packet+KRtpSSRCOffset+3))+
       
  1822 						(*(packet+KRtpSSRCOffset+2)<<8)+
       
  1823 						(*(packet+KRtpSSRCOffset+1)<<16)+
       
  1824 						(*(packet+KRtpSSRCOffset)<<24);
       
  1825 	
       
  1826     TRAPD(error, rtpPacket = iSRTPSession->ProtectRTPL(ssrc, aRTPPacket));
       
  1827     if(error != KErrNone) 
       
  1828         { 
       
  1829         __RTP_LOG("RTP Packet was not encrypted") 
       
  1830         aRTPPacket.FillZ(); 
       
  1831         } 
       
  1832     else 
       
  1833         { 
       
  1834         __RTP_LOG("RTP Packet was encrypted successfully") 
       
  1835         aRTPPacket.Copy(rtpPacket->Des());   
       
  1836         delete rtpPacket;            
       
  1837         }
       
  1838 	}
       
  1839 
       
  1840 // DeCrypting RTCP Packet recieved from network
       
  1841 TInt CRtpSessionInfo::PreRtcpProcessing(TDes8 &aRTCPPacket) 
       
  1842 	{
       
  1843 	__RTP_LOG("CRtpSessionInfo::PreRtcpProcessing")
       
  1844 	//SSRC of recieved packet KRtcpSSRCOffset (4)
       
  1845 	const TUint KRtcpSSRCOffset = 4;
       
  1846 	HBufC8 *rtcpPacket = NULL;
       
  1847 	TUint8* packet = const_cast<TUint8*>(aRTCPPacket.Ptr());
       
  1848 	TUint32 ssrc = (*(packet+KRtcpSSRCOffset+3))+
       
  1849 						(*(packet+KRtcpSSRCOffset+2)<<8)+
       
  1850 						(*(packet+KRtcpSSRCOffset+1)<<16)+
       
  1851 						(*(packet+KRtcpSSRCOffset)<<24);
       
  1852 	
       
  1853 	TRAPD(error, rtcpPacket = iSRTPSession->UnprotectRTCPL(ssrc, aRTCPPacket));
       
  1854 	if(error == KErrNone)
       
  1855 		{
       
  1856 		__RTP_LOG("RTCP Packet Decrypted sucessfully")
       
  1857 		aRTCPPacket.Copy(rtcpPacket->Des());
       
  1858 		}
       
  1859 	else
       
  1860 		{
       
  1861 		__RTP_LOG("RTCP Packet Decrypted Failed")
       
  1862 		error = KErrCorrupt;
       
  1863 		}
       
  1864 	delete rtcpPacket;
       
  1865 	return error;
       
  1866 	}
       
  1867 
       
  1868 // Encrypting RTCP Packet before sending
       
  1869 void CRtpSessionInfo::PostRtcpProcessing(TDes8 &aRTCPPacket) 
       
  1870 	{
       
  1871 	__RTP_LOG("CRtpSessionInfo::PostRtcpProcessing")
       
  1872 	//SSRC of recieved packet KRtcpSSRCOffset (4)
       
  1873 	const TUint KRtcpSSRCOffset = 4;
       
  1874 	HBufC8 *rtcpPacket = NULL;
       
  1875 	// Assign a pointer to a packet
       
  1876 	TUint8* packet = const_cast<TUint8*>(aRTCPPacket.Ptr());
       
  1877 	TUint32 ssrc = (*(packet+KRtcpSSRCOffset+3))+
       
  1878 						(*(packet+KRtcpSSRCOffset+2)<<8)+
       
  1879 						(*(packet+KRtcpSSRCOffset+1)<<16)+
       
  1880 						(*(packet+KRtcpSSRCOffset)<<24);
       
  1881 	
       
  1882 	TRAPD(error, rtcpPacket = iSRTPSession->ProtectRTCPL(ssrc, aRTCPPacket)); 
       
  1883 	if(error != KErrNone) 
       
  1884         { 
       
  1885         __RTP_LOG("RCTP Packet was not encrypted") 
       
  1886         aRTCPPacket.FillZ(); 
       
  1887         } 
       
  1888 	else 
       
  1889         { 
       
  1890         __RTP_LOG("RCTP Packet was encrypted Successfully")
       
  1891         aRTCPPacket.Copy(rtcpPacket->Des());   
       
  1892         delete rtcpPacket;            
       
  1893         }
       
  1894 	}
       
  1895