📄 sipexsipengine.cpp
字号:
return *iServerTx;
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::SetClientTx
// Sets the current Client Transaction.
// -----------------------------------------------------------------------------
void CSIPExSIPEngine::SetClientTx( CSIPClientTransaction* aTx )
{
delete iClientTx;
iClientTx = aTx;
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::ClearClientTx
// Deletes the current Client Transaction.
// -----------------------------------------------------------------------------
void CSIPExSIPEngine::ClearClientTx()
{
delete iClientTx;
iClientTx = NULL;
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::ClientTx
// Returns the current Client Transaction.
// -----------------------------------------------------------------------------
CSIPClientTransaction& CSIPExSIPEngine::ClientTx()
{
return *iClientTx;
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::SetDialogAssoc
// Sets the current Invite Dialog Association.
// -----------------------------------------------------------------------------
void CSIPExSIPEngine::SetDialogAssoc( CSIPInviteDialogAssoc& aAssoc )
{
delete iDialogAssoc;
iDialogAssoc = &aAssoc;
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::DialogAssoc
// Returns the current Invite Dialog Association.
// -----------------------------------------------------------------------------
CSIPInviteDialogAssoc& CSIPExSIPEngine::DialogAssoc()
{
return *iDialogAssoc;
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::CreateToHeaderLC
// (other items were commented in a header).
// -----------------------------------------------------------------------------
CSIPToHeader* CSIPExSIPEngine::CreateToHeaderLC( const TDesC8& aSipUri )
{
CSIPAddress* addr = CSIPAddress::DecodeL( aSipUri );
CleanupStack::PushL( addr );
CSIPToHeader* to = CSIPToHeader::NewL( addr );
CleanupStack::Pop( addr );
CleanupStack::PushL( to );
return to;
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::CreateReqElementsLC
// (other items were commented in a header).
// -----------------------------------------------------------------------------
CSIPRequestElements* CSIPExSIPEngine::CreateReqElementsLC( const TDesC8& aSipUri )
{
CUri8* uri8 = ConvertToUri8LC( aSipUri );
CSIPRequestElements* req = CSIPRequestElements::NewL( uri8 );
CleanupStack::Pop( uri8 );
CleanupStack::PushL( req );
return req;
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::CreateMessageElementsLC
// Create a CSIPMEssageElements instance with the required information.
// -----------------------------------------------------------------------------
CSIPMessageElements* CSIPExSIPEngine::CreateMessageElementsLC()
{
_LIT8( KMediaType, "application" );
_LIT8( KMediaSubType, "sdp" );
CSIPMessageElements* msgElements = CSIPMessageElements::NewLC();
CSdpDocument* sdpDocument = SdpDocumentLC();
MediaFieldsL( sdpDocument );
HBufC8* content = SdpBodyL( sdpDocument );
CleanupStack::PushL( content );
CSIPContentTypeHeader* ct =
CSIPContentTypeHeader::NewLC( KMediaType, KMediaSubType );
msgElements->SetContentL( content, ct );
CleanupStack::Pop( ct );
CleanupStack::Pop( content );
CleanupStack::PopAndDestroy( sdpDocument );
return msgElements;
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::ConvertToUri8LC
// (other items were commented in a header).
// -----------------------------------------------------------------------------
CUri8* CSIPExSIPEngine::ConvertToUri8LC( const TDesC8& aSipUri )
{
TUriParser8 parser;
User::LeaveIfError( parser.Parse( aSipUri ) );
CUri8* uri8 = CUri8::NewLC( parser );
return uri8;
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::SessionId
// Set the session ID using a random number if not set before. Return ID.
// -----------------------------------------------------------------------------
TInt64 CSIPExSIPEngine::SessionId()
{
if ( iSessionId > 0 )
{
return iSessionId;
}
else
{
// Create a random number as the session ID
TTime now;
now.HomeTime();
TInt64 seed = now.Int64();
TInt random = Math::Rand( seed );
iSessionId = random;
return iSessionId;
}
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::SdpDocumentLC
// Create an instance of the SDP Document class, set the required fields, and
// leave it on the cleanup stack. Return pointer to the SDP Document instance.
// Ownership is transferred.
// -----------------------------------------------------------------------------
CSdpDocument* CSIPExSIPEngine::SdpDocumentLC()
{
_LIT8( KSessionName, "SIP Example Application" );
// Create SDP document
CSdpDocument* sdpDocument = CSdpDocument::NewL();
CleanupStack::PushL( sdpDocument );
CSdpOriginField* orgField = CSdpOriginField::NewL( KSdpNoInfoDesC8(),
SessionId(), 0,
iLocalAddr );
sdpDocument->SetOriginField( orgField );
// Set session name
sdpDocument->SetSessionNameL( KSessionName );
// Set connection data
CSdpConnectionField* connField = CSdpConnectionField::NewL( iLocalAddr );
sdpDocument->SetConnectionField( connField );
return sdpDocument;
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::MediaFieldsL()
// Insert the media line to the SDP document given as parameter.
// The format of the media line is:
// application 0 TCP SIPEx
// -----------------------------------------------------------------------------
void CSIPExSIPEngine::MediaFieldsL( CSdpDocument* aDocument )
{
_LIT8( KFormat, "SIPEx" );
// Set media field
// Set media type: application
RStringF media = StringPoolL().StringF( SdpCodecStringConstants::EMediaApplication,
SdpCodecStringPool::StringTableL() );
// Set media transport: TCP
RStringF prot = StringPoolL().StringF( SdpCodecStringConstants::EProtocolTcp,
SdpCodecStringPool::StringTableL() );
// Create the media line
CSdpMediaField* mediaDescription =
CSdpMediaField::NewL( media, 0, prot, KFormat );
aDocument->MediaFields().Append( mediaDescription );
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::SdpBodyL()
// Return SDP message body in textual form.
// Ownership is transferred.
// -----------------------------------------------------------------------------
HBufC8* CSIPExSIPEngine::SdpBodyL( CSdpDocument* aDocument )
{
HBufC8* sdpBuf = NULL;
// Build the message body using buffer writer
if ( aDocument->IsValid() )
{
CBufFlat* enBuf = CBufFlat::NewL( 1000 );
CleanupStack::PushL( enBuf );
RBufWriteStream writeStream;
writeStream.Open( *enBuf, 0 );
aDocument->EncodeL( writeStream );
writeStream.Close();
TPtr8 ptr = enBuf->Ptr( 0 );
sdpBuf = ptr.AllocL();
CleanupStack::PopAndDestroy( enBuf );
writeStream.Close();
}
return sdpBuf;
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::CurrentConnection
// (other items were commented in a header).
// -----------------------------------------------------------------------------
CSIPConnection* CSIPExSIPEngine::CurrentConnection()
{
if ( iConnection )
{
return iConnection;
}
return 0;
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::IPAddressFromResponseElementsL
// (other items were commented in a header).
// -----------------------------------------------------------------------------
const TInetAddr CSIPExSIPEngine::IPAddressFromResponseElementsL(
const CSIPResponseElements& aRespElem )
{
;
// First, retrieve remote party IP Address
// Get Message Elements from Response Elements
const CSIPMessageElements& msgElem = aRespElem.MessageElements();
// Get message content from Message Elements
const TDesC8& content = msgElem.Content();
// Get the SDP Document from the message content
CSdpDocument* SDPDoc = CSdpDocument::DecodeLC( content );
// Get the Connection Field from the SDP Document
CSdpConnectionField* connField = SDPDoc->ConnectionField();
// And, finally, get the IP Address from the Connection Field
const TInetAddr* addr = connField->InetAddress();
const TInetAddr inetAddr = *addr;
CleanupStack::PopAndDestroy( SDPDoc );
return inetAddr;
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::StringPoolL
// Get SDP codec string pool. Open string pool if not opened.
// -----------------------------------------------------------------------------
RStringPool CSIPExSIPEngine::StringPoolL()
{
TRAPD( error, SdpCodecStringPool::OpenL() );
if ( error == KErrAlreadyExists )
{
return SdpCodecStringPool::StringPoolL();
}
else if ( error == KErrNone )
{
//Add missing string to the pool then return it
return SdpCodecStringPool::StringPoolL();
}
else
{
User::Leave( error );
return SdpCodecStringPool::StringPoolL(); //Return here to omit warning
}
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::Observer
// Return pointer to the class registered as Engine Observer.
// -----------------------------------------------------------------------------
MSIPExSIPEngineObserver* CSIPExSIPEngine::Observer()
{
return iObserver;
}
//
// IMPLEMENTATION OF THE METHODS INHERITED FROM BASE CLASSES
//
// From MSIPObserver:
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::IncomingRequest
// Handle a request coming outside of a SIP dialog.
// We have to use TRAPs because this is a non-leaving method.
// We get the ownership to aTransaction.
// -----------------------------------------------------------------------------
void CSIPExSIPEngine::IncomingRequest(
TUint32 aIapId,
CSIPServerTransaction* aTransaction )
{
if ( !iProfile )
{
TRAPD( err, EnableProfileL() );
if ( err != KErrNone )
{
// A profile error occured.
// Delete aTransaction and inform the observer.
delete aTransaction;
aTransaction = NULL;
iObserver->ProfileError( err );
return;
}
}
if ( !CurrentConnection() )
{
// Create an instance of the SIP Connection object.
TRAPD( err2, iConnection = CSIPConnection::NewL( *iSIP, aIapId, *this ) );
if ( err2 != KErrNone )
{
// An error occured opening the connection.
// Delete aTransaction and inform the observer.
delete aTransaction;
aTransaction = NULL;
iObserver->EngineError( err2 );
return;
}
}
if ( aTransaction->Type() == SIPStrings::StringF( SipStrConsts::EInvite ) )
{
// An INVITE has been received.
// Save the pointer for later queries and eventual
// deletion.
SetServerTx(aTransaction);
// Let the current state handle the received INVITE.
// Ownership of aTransaction is transferred.
TRAPD( err2, iCurrentState->InviteReceivedL( *this, aTransaction ) );
if ( err2 != KErrNone )
{
// An error occured when handling invitation.
// Delete aTransaction and inform the observer.
delete aTransaction;
iServerTx = NULL;
iObserver->EngineError( err2 );
return;
}
}
else if ( aTransaction->Type() == SIPStrings::StringF( SipStrConsts::EMessage ) )
{
IMReceived( aTransaction );
}
}
// -----------------------------------------------------------------------------
// CSIPExSIPEngine::TimedOut - No implementation needed
// -----------------------------------------------------------------------------
void CSIPExSIPEngine::TimedOut(
CSIPServerTransaction& /* aSIPServerTransaction */ )
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -