mmshplugins/mmshsipcrplugin/src/mussipcrplugin.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 31 Aug 2010 15:12:07 +0300
branchRCL_3
changeset 22 73a1feb507fb
parent 0 f0cf47e981f9
child 23 bc78a40cd63c
permissions -rw-r--r--
Revision: 201032 Kit: 201035

/*
* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  The Mus ECOM interface implementation of the SIP
*                stack client.
*
*/



#include "mussipcrplugin.h"
#include "muscommon.h"
#include "muslogger.h"
#include "musmanager.h"
#include "musuid.hrh"
#include "musunittesting.h"
#include "mussettings.h"

#include <mussettingskeys.h>
#include <sipstrings.h>
#include <sipstrconsts.h>
#include <sdpdocument.h>
#include <sdpmediafield.h>
#include <sdpcodecstringpool.h>
#include <sdpcodecstringconstants.h>
#include <sdpattributefield.h>

_LIT8( KSendRecv, "sendrecv");                  // For attribute checks
_LIT8( KRecvOnly, "recvonly");                  // For attribute checks
_LIT8( KSendOnly, "sendonly" );                 // For attribute checks

_LIT8(KCapabilities,
"<SIP_CLIENT ALLOW_STARTING=\"YES\">\
<SIP_HEADERS>\
<ACCEPT value=\"application/sdp\"/>\
<ACCEPT_CONTACT value=\"*;+g.3gpp.cs-voice\"/>\
</SIP_HEADERS>\
<SDP_LINES>\
<LINE name=\"m\" value=\"video 0 RTP/AVP 96\">\
<MEDIA_ATTRIBUTE value=\"application:com.nokia.rtvs\"/>\
<MEDIA_ATTRIBUTE value=\"X-application:com.nokia.rtvs\"/>\
</LINE>\
<LINE name=\"m\" value=\"audio 0 RTP/AVP 97\">\
</LINE>\
</SDP_LINES>\
</SIP_CLIENT>");


// -------------------------------------------------------------------------
// Two-phased constructor.
// -------------------------------------------------------------------------
//
CMusSipCrPlugin* CMusSipCrPlugin::NewL()
    {
    MUS_LOG( "mus: [MUSSCR]  -> CMusSipCrPlugin::NewL()" );
    CMusSipCrPlugin* self = new(ELeave) CMusSipCrPlugin;
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    MUS_LOG( "mus: [MUSSCR]  <- CMusSipCrPlugin::NewL()" );
    return self;
    }


// -------------------------------------------------------------------------
// C++ destructor.
// -------------------------------------------------------------------------
//
CMusSipCrPlugin::~CMusSipCrPlugin()
    {
    MUS_LOG( "mus: [MUSSCR]  -> CMusSipCrPlugin::~CMusSipCrPlugin()" );
    delete iManager;
    if ( iCloseStringPool )
        {
        SdpCodecStringPool::Close();
        }
    MUS_LOG( "mus: [MUSSCR]  <- CMusSipCrPlugin::~CMusSipCrPlugin()" );
    }


// -------------------------------------------------------------------------
// C++ constructor.
// -------------------------------------------------------------------------
//
CMusSipCrPlugin::CMusSipCrPlugin()
    {
    }


// -------------------------------------------------------------------------
// Symbian second-phase constructor.
// -------------------------------------------------------------------------
//
void CMusSipCrPlugin::ConstructL()
    {
    MUS_LOG( "mus: [MUSSCR]  -> CMusSipCrPlugin::ConstructL()" );
    iManager = CMusManager::NewL();
    
    TRAPD( err, SdpCodecStringPool::OpenL() );
    
    switch ( err )
        {
        case KErrNone:
            {
            //close pool at destructor, not opened by others
            iCloseStringPool = ETrue;
            break;
            }
        
        case KErrAlreadyExists:
            {
            //already opened, do not try to close at destructor
            iCloseStringPool = EFalse;
            break;
            }
        
        default:
            {
            User::Leave( err );
            }
        }
    
    MUS_LOG( "mus: [MUSSCR]  <- CMusSipCrPlugin::ConstructL()" );
    }


// -------------------------------------------------------------------------
// CMusSipCrPlugin::ChannelL
// -------------------------------------------------------------------------
//
TUid CMusSipCrPlugin::ChannelL( RStringF aMethod,
    const TDesC8& /*aRequestUri*/,
    const RPointerArray<CSIPHeaderBase>& /*aHeaders*/,
    const TDesC8& aContent,
    const CSIPContentTypeHeader* /*aContentType*/ )
    {
    MUS_LOG( "mus: [MUSSCR]  -> CMusSipCrPlugin::ChannelL()" );
    
    if ( aMethod == SIPStrings::StringF( SipStrConsts::EOptions ) )
        {
        TUid uid;
        uid.iUid = ( TInt ) CMusManager::ESipOptions;
        MUS_LOG1( "mus: [MUSSCR]     <- CMusSipCrPlugin::ChannelL(): KSipOptions %d",
                  uid.iUid );
        return uid;
        }
    else
        {
        MultimediaSharing::TMusAvailabilityStatus capability
            = iManager->AvailabilityL();

        if( capability < KErrNone || 
            capability >= MultimediaSharing::EErrServerShutDown )
            {
            TUid uid;
            uid.iUid = ( TInt ) CMusManager::ESipInviteNotDesired;
            MUS_LOG1( "mus: [MUSSCR]     <- CMusSipCrPlugin::ChannelL(): \
                      KNotAllowedSipInvite %d", uid.iUid );
            return uid;
            }
        else
            {
            TUid uid;
            uid.iUid = ( TInt ) CMusManager::ESipInviteDesired;
            TBool twoWaySupported = MultimediaSharingSettings::VideoDirectionL() == 
                                    MusSettingsKeys::ETwoWayVideo;
            
            if ( ( aContent.Length() > 0 ) && twoWaySupported )
                {
                MUS_LOG( "mus: [MUSSCR]  2 way supported, parsing SDP..." );
                CSdpDocument* sdpDocument = CSdpDocument::DecodeLC( aContent );
                TBool sendRecv = CheckForSendRecvAttributeL( sdpDocument->MediaFields() );
                if ( sendRecv )
                    {
                    uid.iUid = ( TInt ) CMusManager::ESipInviteDesired2WayVideo;
                    }
                    
                CleanupStack::PopAndDestroy( sdpDocument );
                }

            MUS_LOG1( "mus: [MUSSCR]     <- CMusSipCrPlugin::ChannelL(): \
                      KAllowedSipInvite %d", uid.iUid );
            return uid;
            }
        }
    }

// -------------------------------------------------------------------------
// CMusSipCrPlugin::CheckForSendRecvAttribute
// -------------------------------------------------------------------------
//
TBool CMusSipCrPlugin::CheckForSendRecvAttributeL(
    RPointerArray<CSdpMediaField>& aFields ) const
    {
    MUS_LOG( "mus: [MUSSCR]  -> CMusSipCrPlugin::CheckForSendRecvAttribute()" );
    
    TBool sendRecv = EFalse;
    TBool sendAttrFound = EFalse;
    TBool videoFound = EFalse;
    RStringF videoType = SdpCodecStringPool::StringPoolL().StringF(
                    SdpCodecStringConstants::EMediaVideo,
                    SdpCodecStringPool::StringTableL() );
    const TInt fieldcount = aFields.Count();
    
    for ( TInt i = 0; i < fieldcount && !videoFound; i++ )
        {
        CSdpMediaField* mField = aFields[i];
        
        //only check video fields
        videoFound = mField->Media() == videoType;
        
        if ( videoFound )
            {
            RPointerArray< CSdpAttributeField > attrList =
                mField->AttributeFields();
            
            TInt attrCount = attrList.Count();
            for (TInt j = 0; j < attrCount && !sendAttrFound; j++ )
                {
                CSdpAttributeField* attributeField = attrList[j];
                RStringF attribute = attributeField->Attribute();                
                
                if ( KErrNotFound != attribute.DesC().FindF( KSendRecv ) )
                    {
                    sendRecv = ETrue;
                    sendAttrFound = ETrue;
                    MUS_LOG( "mus: [MUSSCR]  <sendrecv> attribute found!" );
                    }
                else if ( ( KErrNotFound != attribute.DesC().FindF( KSendOnly ) ) ||
                          ( KErrNotFound != attribute.DesC().FindF( KRecvOnly ) ) )
                    {
                    MUS_LOG( "mus: [MUSSCR]  <sendonly>/<recvonly> attribute found!" );
                    sendAttrFound = ETrue;
                    }
                }
            
            if ( !sendAttrFound )
                {
                MUS_LOG( "mus: [MUSSCR]  no send/recv related attributes found!" );
                sendRecv = ETrue;
                }
            }
        }
    MUS_LOG1( "mus: [MUSSCR]  <- CMusSipCrPlugin::CheckForSendRecvAttribute(), \
            sendrecv: %d", sendRecv );
   
    return sendRecv;
    }

// -------------------------------------------------------------------------
// CMusSipCrPlugin::ConnectL
// -------------------------------------------------------------------------
//
void CMusSipCrPlugin::ConnectL( TUid aUid )
    {
    MUS_LOG1( "mus: [MUSSCR]     -> CMusSipCrPlugin::ConnectL( %d )", aUid.iUid );
    if ( aUid.iUid == CMusManager::ESipOptions ||
         aUid.iUid == CMusManager::ESipInviteDesired ||
         aUid.iUid == CMusManager::ESipInviteDesired2WayVideo ||
         aUid.iUid == CMusManager::ESipInviteNotDesired )
        {
        iManager->HandleSipRequestL(( CMusManager::TRequestType ) aUid.iUid );
        }
    else
        {
        MUS_LOG( "mus: [MUSSCR]  <- CMusSipCrPlugin::ChannelL()\
                       ( User::Leave KErrNotSupported )" );
        User::Leave( KErrNotSupported );
        }        
    MUS_LOG( "mus: [MUSSCR]  <- CMusSipCrPlugin::ConnectL()" );
    }


// -------------------------------------------------------------------------
// CMusSipCrPlugin::Capabilities()
// -------------------------------------------------------------------------
//
const TDesC8& CMusSipCrPlugin::Capabilities()
    {
    MUS_LOG( "mus: [MUSSCR]  -> CMusSipCrPlugin::Capabilities()" );
    MUS_LOG( "mus: [MUSSCR]  <- CMusSipCrPlugin::Capabilities()" );
    return KCapabilities;
    }