EXPORT_C CSIPInviteDialogAssoc* CSIPInviteDialogAssoc::NewLC( CSIPDialog& aDialog )
    {
    CSIPInviteDialogAssoc* self = new (ELeave) CSIPInviteDialogAssoc();
    CleanupStack::PushL( self );
    self->ConstructL( SIPStrings::StringF( SipStrConsts::EInvite ), &aDialog );
    return self;
    }
// -----------------------------------------------------------------------------
// CSIPExSIPIdleState::SendInviteL()
// Create and send an INVITE request to the recipient.
// -----------------------------------------------------------------------------
void CSIPExSIPIdleState::SendInviteL( 
    CSIPExSIPEngine& aEngine,
	const TDesC8& aSipUri )
	{
	// Retrieve the active profile and connection
	CSIPProfile& prof = aEngine.Profile();
	CSIPConnection& conn = aEngine.ConnectionL();

    // Create CUri8 from passed descriptor
    CUri8* uri8 = aEngine.ConvertToUri8LC( aSipUri );
    
	// Get dialog association, save for future use
	// The ownership of uri8 is transferred
	CSIPInviteDialogAssoc* dialogAssoc =
		CSIPInviteDialogAssoc::NewL( conn, uri8, prof );
	CleanupStack::Pop( uri8 );	
		
	aEngine.SetDialogAssoc( *dialogAssoc ); //Ownership is transferred!!

	// Create the necessary message elements
	CSIPMessageElements* msgElements = aEngine.CreateMessageElementsLC();

	// Send the INVITE in the dialog
	// The ownership of msgElements is transferred
	CSIPClientTransaction* tx = dialogAssoc->SendInviteL( msgElements );
	CleanupStack::Pop( msgElements );

	// Save the pointer to the transaction to the Engine
	aEngine.SetClientTx( tx );

	// Change machine state
	aEngine.SetCurrentState( iClientEstablishingState );
	}
/**
 * INPUT:
 *   Headers:		To*, From*, Contact*
 *   Parameters:	RemoteURI
 *   IDs:			ProfileId, RegistryId
 *
 * OUTPUT:
 *   Parameters:	-
 *   IDs:			TransactionId, InviteDialogId
 */
void TCmdSendInviteUsingProfile::ExecuteL()
	{
	// -- Setup ---------------------------------------------------------------

	// Extract required headers (From may be either mandatory or optional)
	CSIPToHeader* toHeader = ExtractToHeaderLC( EFalse );
	CSIPFromHeader* fromHeader = ExtractFromHeaderLC( EFalse );
    CSIPContactHeader* contactHeader = ExtractContactHeaderLC( EFalse );

	// Extract remote URI
	CUri8* uri = ExtractRemoteURILC( ETrue );

    // Get selected registry
    CTcSIPProfileContainer& container = SelectProfileL();

	// Get profile from the profile registry
	CSIPProfile& profile = GetProfileL( container );

	CSIPConnection* sipConnection = container.ProfileRegistry().ConnectionL( profile );
	
	// Ownership is not really transferred if SIPTester has opened already 
	// CSIPConnection for same IAP as profile is using!!
	if ( sipConnection != &(iContext.Connection().Connection()) )
		{
		// Have to store because needs longer lifetime than just current ExecuteL
		iContext.Registry().AddObjectL( sipConnection );	
		}		

    CSIPInviteDialogAssoc* inviteDialogAssoc = 
        CSIPInviteDialogAssoc::NewL( *sipConnection,
                                     uri,
                                     profile,
                                     fromHeader,
                                     toHeader,
                                     contactHeader );
                                                                    
    CleanupStack::Pop( iPushed ); // toHeader; fromheader, uri
    iPushed = 0;

    CleanupStack::PushL( inviteDialogAssoc );
    
    // Extract rest of headers (if provided)
    CSIPMessageElements* elements = ExtractHeadersAndContentLC();
    
     // -- Execution -----------------------------------------------------------
     
    // Start SIP Invite transaction.
	CSIPClientTransaction* transaction = inviteDialogAssoc->SendInviteL( elements );
    CleanupStack::Pop( elements );

	// -- Response creation ---------------------------------------------------

    AddIdResponseL( KTransactionId, transaction );
	AddIdResponseL( KInviteDialogId, inviteDialogAssoc );

    CleanupStack::Pop( inviteDialogAssoc );
	}
EXPORT_C CSIPInviteDialogAssoc*
        CSIPInviteDialogAssoc::NewLC(CSIPServerTransaction& aTransaction)
    {
    
    CSIPInviteDialogAssoc* self = new (ELeave) CSIPInviteDialogAssoc();
    CleanupStack::PushL( self );
    CSIPDialog* dlg = CSIPDialog::NewL();
    CleanupStack::PushL( dlg );
    self->ConstructL( SIPStrings::StringF( SipStrConsts::EInvite ), dlg, aTransaction );
    CleanupStack::Pop( dlg );
    return self;
    
    }
/**
 * INPUT:
 *   Headers:		Contact*, Content-Type*, Content-Encoding*, Route*
 *   Parameters:	Content*
 *   IDs:			InviteDialogId*, SubscribeDialogId*
 *
 * OUTPUT:
 *   Parameters:	-
 *   IDs:			TransactionId, InviteDialogId
 */
void TCmdSendInviteWithinDriver::ExecuteL()
{
    // -- Setup ---------------------------------------------------------------

    // Get SIP objects from registry
    CSIPSubscribeDialogAssoc* subscribeDialogAssoc =
        GetSubscribeDialogAssocL( EFalse );

    // If there was a SubscribeDialogId, use it to create a new InviteDialogAssoc
    // If not, try to use a InviteDialogId for an existing InviteDialogAssoc
    CSIPInviteDialogAssoc* inviteDialogAssocOrg;
    CSIPInviteDialogAssoc* inviteDialogAssoc;
    if( subscribeDialogAssoc )
    {
        // Create a new dialog association
        inviteDialogAssoc =
            CSIPInviteDialogAssoc::NewLC( subscribeDialogAssoc->Dialog() );
    }
    else
    {
        // Get invitedialog
        inviteDialogAssocOrg = GetInviteDialogAssocL();
        // Create a new dialog association
        inviteDialogAssoc =
            CSIPInviteDialogAssoc::NewLC( inviteDialogAssocOrg->Dialog() );
    }

    // Extract both headers (that are still left) and content.
    CSIPMessageElements* elements = ExtractHeadersAndContentLC();

    // -- Execution -----------------------------------------------------------

    // Start SIP Invite transaction.
    CSIPClientTransaction* transaction = inviteDialogAssoc->SendInviteL( elements );
    CleanupStack::Pop( elements );

    // -- Response creation ---------------------------------------------------

    AddIdResponseL( KTransactionId, transaction );
    // If subscribeDialogAssoc is valid, inviteDialogAssoc ptr is in CleanupStack
    if( subscribeDialogAssoc )
    {
        CleanupStack::Pop( inviteDialogAssoc );
    }
    AddIdResponseL( KInviteDialogId, inviteDialogAssoc );
}
CSIPInviteDialogAssoc* CSIPInviteDialogAssoc::NewLC(CSIPConnection& aConnection,
            								 CUri8* aRemoteUri,
            	                             CSIPFromHeader* aFrom,
            	                             CSIPToHeader* aTo,
            		                         CSIPContactHeader* aContact,
            		                         const MSIPRegistrationContext* aContext)
    {
    CSIPInviteDialogAssoc* self = new (ELeave) CSIPInviteDialogAssoc();
    CleanupStack::PushL( self );
    CSIPDialog* dlg = CSIPDialog::NewL( *aRemoteUri, *aFrom, *aTo );
    CleanupStack::PushL( dlg );
    self->ConstructL( SIPStrings::StringF( SipStrConsts::EInvite ), dlg );
    CleanupStack::Pop( dlg );
    self->iConnection = &aConnection;
    self->iRemoteUri = aRemoteUri;
    self->iFrom = aFrom;
    self->iTo = aTo;
    self->iContact = aContact;
    self->iContext = aContext;
    return self;
    }
/**
 * INPUT:
 *   Headers:		Contact*, Content-Type*, Content-Encoding*,
 *					Event*, Expires*
 *   Parameters:	Content*
 *   IDs:			InviteDialogId
 *
 * OUTPUT:
 *   Parameters:	-
 *   IDs:			TransactionId
 */
void TCmdUpdateInvite::ExecuteL()
	{
	// -- Setup ---------------------------------------------------------------

	// Get SIP objects from registry
	CSIPInviteDialogAssoc* dialogAssoc = GetInviteDialogAssocL();

	// Extract both headers (that are still left) and content.
	CSIPMessageElements* elements = ExtractHeadersAndContentLC();

	// -- Execution -----------------------------------------------------------

	// Start SIP Subscribe transaction.
	CSIPClientTransaction* transaction =
							dialogAssoc->SendInviteL( elements );
	CleanupStack::Pop( elements );

	// -- Response creation ---------------------------------------------------

	AddIdResponseL( KTransactionId, transaction );
	}
// -----------------------------------------------------------------------------
// CDialogConfirmed::SendAckL
// -----------------------------------------------------------------------------
//
void CDialogConfirmed::SendAckL(CSIPInviteDialogAssoc& aAssoc,
                                const CSIPClientTransaction& aTransaction,
			                    CSIPMessageElements* aElements) const
    {
    aAssoc.DoSendAckL(aTransaction, aElements);
    }
/**
 * INPUT:
 *   Headers:		From, To*, Contact*, Content-Type*
 *   Parameters:	Content*, RemoteURI*
 *   IDs:			RegistrationId*, InviteDialogId, ConnectionId*
 *
 * OUTPUT:
 *   Parameters:	-
 *   IDs:			TransactionId, InviteDialogId
 */
void TCmdSendInvite::ExecuteL()
{
    // -- Setup ---------------------------------------------------------------

    // Select connection; either default or user specified (and existing)
    CSIPConnection& connection = SelectConnectionL().Connection();

    // Get SIP objects from registry
    CSIPRegistrationBinding* registration = GetRegistrationL( EFalse );
    TBool fromHeaderMandatory( ETrue );
    if( registration )
    {
        fromHeaderMandatory = EFalse;
    }

    // Extract required headers (From may be either mandatory or optional)
    CSIPFromHeader* fromHeader = ExtractFromHeaderLC( fromHeaderMandatory );

    // Extract optional headers
    CSIPToHeader* toHeader = ExtractToHeaderLC( EFalse );
    CSIPContactHeader* contactHeader = ExtractContactHeaderLC( EFalse );

    // Conditionally create remote URI
    CUri8* remoteUri = ExtractRemoteURILC();

    // Construct the dialog association object
    CSIPInviteDialogAssoc* dialogAssoc;

    if( registration )
    {
        dialogAssoc = CSIPInviteDialogAssoc::NewL(
                          connection, remoteUri, *registration,
                          fromHeader, toHeader, contactHeader );
    }
    else
    {
        dialogAssoc = CSIPInviteDialogAssoc::NewL(
                          connection, fromHeader,
                          remoteUri, toHeader, contactHeader );
    }

    // Purge items from cleanup stack, now they are owned by CSIPInviteDialogAssoc
    // Some items are optional (i.e. NULL), so we've been tracking the number
    // of items in pushed to CleanupStack
    CleanupStack::Pop( iPushed );
    iPushed = 0;

    CleanupStack::PushL( dialogAssoc );

    // Extract both headers (that are still left) and content.
    CSIPMessageElements* elements = ExtractHeadersAndContentLC();

    // -- Execution -----------------------------------------------------------

    // Start SIP Invite transaction.
    CSIPClientTransaction* transaction = dialogAssoc->SendInviteL( elements );
    CleanupStack::Pop( elements );

    // -- Response creation ---------------------------------------------------

    AddIdResponseL( KTransactionId, transaction );
    CleanupStack::Pop( dialogAssoc );
    AddIdResponseL( KInviteDialogId, dialogAssoc );
}