realtimenetprots/rtp/cfrtp/src/rtpflow.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2008-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 // RTPFlow Implementation
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21 */
       
    22 
       
    23 #include <comms-infras/ss_log.h>
       
    24 
       
    25 #include "rtpflow.h"
       
    26 #include "rtppint.h"
       
    27 #include "rtp_cfmessages.h"
       
    28 
       
    29 
       
    30 #if defined(ESOCK_LOGGING_ACTIVE)
       
    31 _LIT8(KRtpFlowSubTag, "RtpFlow");
       
    32 #endif
       
    33 
       
    34 									
       
    35 CRtpFlow::CRtpFlow(ESock::CSubConnectionFlowFactoryBase& aFactory, const Messages::TNodeId& aSubConnId, ESock::CProtocolIntfBase* aProtocolIntf)
       
    36 :CRtpBaseFlow(aFactory, aSubConnId, aProtocolIntf)
       
    37 {
       
    38 	LOG_NODE_CREATE(KESockFlowTag, CRtpFlow);
       
    39 }
       
    40 
       
    41 CRtpFlow* CRtpFlow::NewL(CSubConnectionFlowFactoryBase& aFactory, const Messages::TNodeId& aSubConn, CProtocolIntfBase* aProtocolIntf)
       
    42 	{
       
    43 	CRtpFlow *pRtpFlow = new (ELeave) CRtpFlow(aFactory, aSubConn, aProtocolIntf);
       
    44 	
       
    45 	CleanupStack::PushL(pRtpFlow);
       
    46 	pRtpFlow->ConstructL();
       
    47 	/* Register the flow with Rtp Pint */
       
    48 	((CRtpProtocolIntf*)aProtocolIntf)->RegisterSubConnProvIDL(pRtpFlow,aSubConn);
       
    49 	CleanupStack::Pop();
       
    50 
       
    51 	return pRtpFlow;
       
    52 	}
       
    53 
       
    54 void CRtpFlow::ConstructL()
       
    55 	{
       
    56 	TSockAddr addr;
       
    57 	/* Create the RTP Handler */
       
    58 	iRtpHandler = CCFRtpHandler::NewL(this,EPriorityNormal);
       
    59 	iRtpSession = CRtpController::NewL(*iRtpHandler,EPriorityNormal,addr, _L8(""));
       
    60 	iRtpBuffer.ReAllocL(KRtpDefBufSz);
       
    61 	}
       
    62 
       
    63 
       
    64 CRtpFlow::~CRtpFlow()
       
    65 	{
       
    66 	delete iRtpSession;
       
    67 	iRtpBuffer.Close();
       
    68 	LOG_NODE_DESTROY(KESockFlowTag, CRtpFlow);
       
    69 	}
       
    70 	
       
    71 void CRtpFlow::CanSend()
       
    72 	{
       
    73 	__ASSERT_DEBUG(iSessionDataNotify,User::Panic(KRtpFlowPanic, RtpFlowPanics::KPanicNoControlProvider));
       
    74 	CRtpBaseFlow::CanSend();
       
    75 	}
       
    76 
       
    77 TInt CRtpFlow::Write(RMBufChain& aData, TUint aOptions, TSockAddr* anAddr )
       
    78 	{
       
    79 
       
    80 	TInt nwr = -1;
       
    81 	TInt ret = KErrNone;
       
    82 	/* Findout the amount of Data contained in the RMbuf Chain */
       
    83 	TInt rmbuflen = aData.Length();
       
    84 	TPtr8 rtpBufPtr(NULL, 0);
       
    85 	
       
    86 	LOG( ESockLogExternal::Printf(KESockFlowTag,KRtpFlowSubTag,_L8("CRtpFlow %08x:\tWrite() Len=%d"), this, rmbuflen));
       
    87 	
       
    88 	if(!(aData.First()->Next()))
       
    89 		{
       
    90 		RMBuf *buffer = aData.First();
       
    91 		__ASSERT_DEBUG(rmbuflen == buffer->Length() ,User::Panic(KRtpFlowPanic, RtpFlowPanics::KPanicIncompleteBuffer));
       
    92 		rtpBufPtr.Set(buffer->Ptr(), rmbuflen, rmbuflen);
       
    93 		}
       
    94 	else
       
    95 		{
       
    96 		if(iRtpBuffer.MaxLength() < rmbuflen)
       
    97 			{
       
    98 			iRtpBuffer.SetLength(0);
       
    99 			ret = iRtpBuffer.ReAlloc(rmbuflen);
       
   100 		
       
   101 			if(KErrNone != ret)
       
   102 				{
       
   103 				LOG( ESockLogExternal::Printf(KESockFlowTag,KRtpFlowSubTag,_L8("CRtpFlow %08x:\tWrite() -ALLOC Failed!"), this));
       
   104 				/* In case of error a protocol is supposed to Error and then return 0 */
       
   105 				iSessionControlNotify->Error(ret,MSessionControlNotify::EErrorSend);
       
   106 				return 0;
       
   107 				}
       
   108 			}
       
   109 
       
   110 		/* Copy the Data from RMbuf to Descriptor. Then Pass it to the RtpStack*/
       
   111 		iRtpBuffer.SetLength(rmbuflen);
       
   112 		aData.CopyOut(iRtpBuffer);
       
   113 		rtpBufPtr.Set(&iRtpBuffer[0], rmbuflen, iRtpBuffer.MaxLength());
       
   114 		}
       
   115 	
       
   116 	if(!NonRtpSendData())
       
   117 		{
       
   118 		iRtpSession->PacketBeingSent(rtpBufPtr, ERtp); 
       
   119 		}
       
   120 	//It is assumed that a Properly Created packet is passed down here.
       
   121 	//Maybe we should handle a return code for PacketbeingSent function.
       
   122 	if(aData.First()->Next())
       
   123 		{
       
   124 		aData.CopyIn(iRtpBuffer);
       
   125 		}
       
   126 		 
       
   127 	__ASSERT_DEBUG(iSSPData,User::Panic(KRtpFlowPanic, RtpFlowPanics::KPanicNoServiceProvider));
       
   128 	nwr = iSSPData->Write(aData, aOptions, anAddr);
       
   129 
       
   130 	LOG( ESockLogExternal::Printf(KESockFlowTag,KRtpFlowSubTag,_L8("CRtpFlow %08x:\tWrite() Done nwr=%d"), this,nwr));	
       
   131 
       
   132 	return nwr;
       
   133 	
       
   134 	}
       
   135  
       
   136  
       
   137 void CRtpFlow::ReceivedL(const Messages::TRuntimeCtxId& aSender, const Messages::TNodeId& aRecipient, Messages::TSignatureBase& aMessage)
       
   138     {
       
   139 	CRtpBaseFlow::ReceivedL(aSender,aRecipient,aMessage);
       
   140 
       
   141     LOG( ESockLogExternal::Printf(KESockFlowTag,KRtpFlowSubTag,_L8("CRtpFlow %08x:\tReceivedL() Msg %d"), this, aMessage.MessageId().MessageId()));
       
   142 
       
   143 	if ( aMessage.IsMessage<Messages::TEBase::TError>() )
       
   144 		{
       
   145         LOG( ESockLogExternal::Printf(KESockFlowTag,KRtpFlowSubTag,_L8("CRtpFlow %08x:\tGot TError from Sunconn"), this));
       
   146         HandleError(static_cast<Messages::TEBase::TError&>(aMessage).iValue);
       
   147 		}	
       
   148     else if (Messages::TEChild::ERealmId == aMessage.MessageId().Realm())
       
   149         {
       
   150     	switch (aMessage.MessageId().MessageId())
       
   151         	{
       
   152    		case Messages::TEChild::TDestroy::EId :
       
   153     			{
       
   154             	Destroy();
       
   155             	break;
       
   156     			}
       
   157         	}
       
   158 		}
       
   159 	else if (TCFDataClient::ERealmId == aMessage.MessageId().Realm())
       
   160 		{
       
   161 	    switch (aMessage.MessageId().MessageId())
       
   162         	{
       
   163         	case TCFDataClient::TProvisionConfig::EId:
       
   164          		{	
       
   165     			TCFDataClient::TProvisionConfig& aMess = Messages::message_cast<TCFDataClient::TProvisionConfig>(aMessage);
       
   166 				
       
   167 				iAccessPointConfig.Close();
       
   168 				iAccessPointConfig.Open(aMess.iConfig);
       
   169 				
       
   170 				const CRtpProvisionConfig& rtpProv = static_cast<const CRtpProvisionConfig&>(AccessPointConfig().FindExtensionL(STypeId::CreateSTypeId(KRtpProvisionUid, KRtpProvisionConfigType)));
       
   171 				DoProvisionL(&rtpProv);
       
   172 			
       
   173 				/* Deafult Processing */
       
   174 				HandleProvisionMessage(aMessage);				
       
   175         		break;
       
   176          		}
       
   177  
       
   178 	        case TCFDataClient::TStart::EId :
       
   179         		{
       
   180 	        	/* Check if we Have a Bearer. If we donot Have
       
   181 	        	   complete when we Have one */
       
   182         		User::LeaveIfError(iStartRequest.Open(iSubConnectionProvider,aSender));
       
   183 	        	if(iSSPData)
       
   184 	        		{
       
   185 	        		CompleteStart(KErrNone);
       
   186 	        		}
       
   187 	        	else
       
   188 	        		{
       
   189 	        		LOG( ESockLogExternal::Printf(KESockFlowTag,KRtpFlowSubTag,_L8("CRtpFlow %08x:\tGot TDataClientStart no SP iIsStarting=>ETrue"), this));
       
   190 	        		iIsStarting = ETrue;		
       
   191 	        		}
       
   192 	        	}
       
   193 	            break;
       
   194 
       
   195 	         case TCFDataClient::TStop::EId :
       
   196 	         	{
       
   197 	        	StopFlow(static_cast<TCFDataClient::TStop&>(aMessage));
       
   198 	            break;
       
   199 	         	}
       
   200 	         
       
   201 	         case TCFDataClient::TBindTo::EId :
       
   202 				{
       
   203 				TCFDataClient::TBindTo& bindToMsg(static_cast<TCFDataClient::TBindTo&>(aMessage));
       
   204                 TRAPD(err,BindToL(bindToMsg));
       
   205                 
       
   206                 if(err)
       
   207                     {
       
   208                     Messages::RClientInterface::OpenPostMessageClose(Id(), aSender, Messages::TEBase::TError(TCFDataClient::TBindTo::Id(), err).CRef());
       
   209                     }
       
   210                 else
       
   211                     {
       
   212                     Messages::RClientInterface::OpenPostMessageClose(Id(), aSender, TCFDataClient::TBindToComplete().CRef());
       
   213                     }
       
   214                 
       
   215 				//If we have received TDataClientStart before (when we did not yet have a bearer),
       
   216 				//we complete the start here as well
       
   217 				if (iIsStarting)
       
   218 					{
       
   219 					CompleteStart(err);
       
   220 					}
       
   221 				
       
   222 				HandleBindToMessage(aMessage,err);	
       
   223                 break;			
       
   224 				}
       
   225  
       
   226         	}
       
   227 		}
       
   228 	else if (TCFControlProvider::ERealmId == aMessage.MessageId().Realm())
       
   229 		{
       
   230 		/* VRAMY : LOG Here!!! */
       
   231 		}
       
   232 	}
       
   233 
       
   234 
       
   235 void CRtpFlow::DoProvisionL(const CRtpProvisionConfig *apRtpProv)    
       
   236 	{
       
   237 	iRtpSession->SetSessionBandwidth(apRtpProv->BandWidth());
       
   238 	iRtpSession->SetRTPTimeConversion(apRtpProv->RtpTimeNow(),apRtpProv->RtptimeConversion());
       
   239 	iRtpSession->SetRtpStreamParameters(apRtpProv->MaxDropOut(),
       
   240 										apRtpProv->MaxMisorder(),
       
   241 										apRtpProv->MinSequential());
       
   242 	}
       
   243 
       
   244 TInt CRtpFlow::GetData(RMBufChain& aData, TUint aLength, TUint aOptions, TSockAddr* anAddr)
       
   245 	{
       
   246 	ASSERT(iSSPData);
       
   247 	TInt ret;
       
   248 
       
   249 	LOG( ESockLogExternal::Printf(KESockFlowTag,KRtpFlowSubTag,_L8("CRtpFlow %08x:\tGetData "), this ));
       
   250 
       
   251 	ret = iSSPData->GetData(aData, aLength, aOptions, anAddr);
       
   252 	if(ret < 0)
       
   253 		{
       
   254 		/* The Read failed. Just pass the error up */
       
   255 		LOG( ESockLogExternal::Printf(KESockFlowTag,KRtpFlowSubTag,_L8("CRtpFlow %08x:\tGetData failed (ret =%d)"), this));
       
   256 		return ret;
       
   257 		}
       
   258 	
       
   259 	/* Findout the amount of Data contained in the RMbuf Chain */
       
   260 	TInt rmbuflen = aData.Length();
       
   261 	TPtr8 rtpBufPtr(NULL, 0);
       
   262 	
       
   263 	if(!(aData.First()->Next()))
       
   264 		{
       
   265 		RMBuf *buffer = aData.First();
       
   266 		__ASSERT_DEBUG(rmbuflen == buffer->Length() ,User::Panic(KRtpFlowPanic, RtpFlowPanics::KPanicIncompleteBuffer));
       
   267 		rtpBufPtr.Set(buffer->Ptr(), rmbuflen, rmbuflen);
       
   268 		}
       
   269 	else
       
   270 		{
       
   271 		if(iRtpBuffer.MaxLength() < rmbuflen)
       
   272 			{
       
   273 			iRtpBuffer.SetLength(0);
       
   274 			ret = iRtpBuffer.ReAlloc(rmbuflen);
       
   275 			if(KErrNone != ret)
       
   276 				{
       
   277 				return ret;
       
   278 				}	
       
   279 			}
       
   280 	
       
   281 		iRtpBuffer.SetLength(rmbuflen);
       
   282 		aData.CopyOut(iRtpBuffer);
       
   283 		rtpBufPtr.Set(&iRtpBuffer[0], rmbuflen, iRtpBuffer.MaxLength());
       
   284 		}
       
   285 	
       
   286 	if(anAddr)
       
   287 		{
       
   288 		iRtpHandler->SetRecvAddress(*anAddr);
       
   289 		}
       
   290 	else
       
   291 		{
       
   292 		/* Connected Socket */
       
   293 		__ASSERT_DEBUG(iConnected,User::Panic(KRtpFlowPanic, RtpFlowPanics::KPanicIncorrectState));
       
   294 		iRtpHandler->SetRecvAddress(iDestAddr);
       
   295 		}
       
   296 		
       
   297 	TRAP(ret,iRtpSession->DoReceiveL(rtpBufPtr,ERtp));
       
   298 	
       
   299 	if((KErrNone == ret) && (aData.First()->Next()))
       
   300 		{
       
   301 		aData.CopyIn(iRtpBuffer);
       
   302 		}
       
   303 
       
   304 	LOG( ESockLogExternal::Printf(KESockFlowTag,KRtpFlowSubTag,_L8("CRtpFlow %08x:\tGetData()) done ret=%d"), this,ret));
       
   305 
       
   306 	return ret;
       
   307 	}
       
   308 
       
   309 
       
   310 void CRtpFlow::SendData(TDes8& , TSockAddr &, TInt , TRequestStatus  &aStatus)
       
   311 	{
       
   312 		
       
   313 		TRequestStatus *stat = &aStatus;
       
   314 		User::RequestComplete(stat,KErrNone);
       
   315 	}
       
   316 	
       
   317 
       
   318 void CRtpFlow::NewData(TUint aCount)
       
   319 	{
       
   320 	__ASSERT_DEBUG(iSessionDataNotify,User::Panic(KRtpFlowPanic, RtpFlowPanics::KPanicNoControlProvider));
       
   321 
       
   322 	LOG( ESockLogExternal::Printf(KESockFlowTag,KRtpFlowSubTag,_L8("CRtpFlow %08x:\tNewData()"), this));
       
   323 
       
   324 	CRtpBaseFlow::NewData(aCount);
       
   325 	}
       
   326 	
       
   327 
       
   328 /* When an RTCP flow is created call this function to enable RTCP in
       
   329    RtpSession. The function will return a Pointer to RTPSession which
       
   330    can be passed on to RTCP Flow */
       
   331 CRtpController* CRtpFlow::GetRtpSession() const
       
   332 	{
       
   333 	return 	iRtpSession;
       
   334 	}
       
   335 
       
   336 void CRtpFlow::DoCanClose(MSessionControlNotify::TDelete )
       
   337 /**
       
   338 Called from protocol to indicate that a graceful close has completed
       
   339 */
       
   340 	{
       
   341 	/* RTP Session is no longer Valid and Can be Closed now */
       
   342 	/* OOPS no API to close the RtpSession :(*/
       
   343 	}
       
   344 
       
   345 
       
   346 void CRtpFlow::DoUpdateLocalAddress(const TSockAddr& anAddr)
       
   347 /* Called by BaseFlow to notify that Local address has been 
       
   348    Updated. Ideally called only once */
       
   349 	{
       
   350 	iRtpSession->SetLocalAddress(anAddr);
       
   351 	}
       
   352 
       
   353 TInt CRtpFlow::DoGetOption(TUint level, TUint name, TDes8 &aOption) const
       
   354 	{
       
   355 	/* Socket option for RTP */
       
   356 	if(KSolRtp == level)
       
   357 		{
       
   358 		switch(name)
       
   359 			{
       
   360 			case KSoLocalSSRC:
       
   361 				{
       
   362 				TUint locSSRC = iRtpSession->GetLocalSSRC();
       
   363 				CopyOptionToDesc(aOption,locSSRC);
       
   364 				break;
       
   365 				}
       
   366 			default:
       
   367 				{
       
   368 				return KErrNotSupported;
       
   369 				}
       
   370 			}
       
   371 		return KErrNone;
       
   372 		}
       
   373 
       
   374 	if(iSSP)
       
   375 	 return iSSP->GetOption(level,name,aOption);
       
   376 	return KErrNone;
       
   377 	}
       
   378 
       
   379 TInt CRtpFlow::DoSetOption(TUint level, TUint name, const TDesC8 &aOption)
       
   380 	{
       
   381 	
       
   382 	/* Socket option for RTP */
       
   383 	if(KSolRtp == level)
       
   384 		{
       
   385 		TInt ret = KErrNone;
       
   386 		switch(name)
       
   387 			{
       
   388 			case KSoRtpBandwidth:
       
   389 				{
       
   390 				TInt optInt=0;
       
   391 				GETOPTION_OR_RETURN(aOption,optInt);
       
   392 				iRtpSession->SetSessionBandwidth(optInt);
       
   393 				break;
       
   394 				}
       
   395 			case KSoStreamParams:
       
   396 				{
       
   397 				TRtpStreamParams strmParams;
       
   398 				GETOPTION_OR_RETURN(aOption,strmParams);
       
   399 				iRtpSession->SetRtpStreamParameters(strmParams.iMaxDropout,
       
   400 						                            strmParams.iMaxMisorder,
       
   401 						                            strmParams.iMinSequential);
       
   402 				break;
       
   403 				}
       
   404 
       
   405 			case KSoRtpTimeConvertion:
       
   406 				{
       
   407 				TRtpTimeConversion rtpTimeConv;
       
   408 				GETOPTION_OR_RETURN(aOption,rtpTimeConv);
       
   409 				iRtpSession->SetRTPTimeConversion(rtpTimeConv.iRtpTimeNow,
       
   410 												  rtpTimeConv.iConversion);
       
   411 				break;
       
   412 				}
       
   413 			
       
   414 			case KSoSendNonRtpData:
       
   415 				{
       
   416 				TInt nonRtpData = 0;
       
   417 				GETOPTION_OR_RETURN(aOption,nonRtpData);
       
   418 				SetNonRtpSendData(nonRtpData);
       
   419 				break;	
       
   420 				}
       
   421 				
       
   422 			case KSoReceiveNonRtpData:
       
   423 				{
       
   424 				TInt nonRtpData = 0;
       
   425 				GETOPTION_OR_RETURN(aOption,nonRtpData);
       
   426 				iRtpSession->SetNonRtpData(nonRtpData);
       
   427 				break;	
       
   428 				}
       
   429 			case KSoSamplingRate:
       
   430 				{
       
   431 				TSamplingRateInfo sampRateInfo;
       
   432 				GETOPTION_OR_RETURN(aOption,sampRateInfo);
       
   433 				ret = iRtpSession->SetSamplingRate(sampRateInfo.iPayloadType,
       
   434 											 sampRateInfo.iSamplingRate);
       
   435 				break;
       
   436 				}
       
   437 
       
   438 			default:
       
   439 				{
       
   440 				return KErrNotSupported;
       
   441 				}
       
   442 			}
       
   443 		return ret;
       
   444 		}
       
   445 	if(iSSP)
       
   446 		return iSSP->SetOption(level,name,aOption);
       
   447 	return KErrNone;
       
   448 	}
       
   449 	
       
   450 void CRtpFlow::SetNonRtpSendData(TInt aNonRtpData)
       
   451 	{
       
   452 	iNonRtpSendData = aNonRtpData;
       
   453 	}
       
   454 	
       
   455 TInt CRtpFlow::NonRtpSendData()
       
   456 	{
       
   457 	return iNonRtpSendData;
       
   458 	}
       
   459 
       
   460