supl/locationomasuplprotocolhandler/waplistener/src/epos_comasuplwaplistener.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 11 May 2010 16:36:36 +0300
branchRCL_3
changeset 23 5944cae565c9
parent 0 667063e416a2
child 44 2b4ea9893b66
permissions -rw-r--r--
Revision: 201017 Kit: 201019

/*
* Copyright (c) 2005 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:   Implementation of OMA SUPL WAP Listener
*
*/



#include <utf.h>
#include <push/ccontenthandlerbase.h>
//#include <push/pushdispatcher.h> for header relocation error

#include "epos_comasuplwaplistener.h"

_LIT( KReserved, "Reserved" );
_LIT( KPushMsgNull, "NULL PUSH message" );
_LIT( KTraceFileName, "epos_suplwaplistener.cpp" );
_LIT( KSupportedContentType, "application/vnd.omaloc-supl-init");
_LIT( KSupportedBinaryContentType, "0x312");
_LIT( KSupportedBinaryContentType2, "0X312");

//const TUint8 KSupportedHEXContentType = 0x03020312;


// ======== MEMBER FUNCTIONS ========

// -----------------------------------------------------------------------------
// COMASuplWapListener::COMASuplWapListener()
// C++ default constructor.
// -----------------------------------------------------------------------------
//
COMASuplWapListener::COMASuplWapListener()
    : CPushHandlerBase()
    {
    iErrCode = KErrNone;
    CActiveScheduler::Add( this );
    }

// -----------------------------------------------------------------------------
// COMASuplWapListener::NewL
// COMASuplWapListener instantiation method.
// -----------------------------------------------------------------------------
//
COMASuplWapListener* COMASuplWapListener::NewL()
    {
    COMASuplWapListener* self = new (ELeave) COMASuplWapListener();
    self->ConstructL();
    return self;
    }

// -----------------------------------------------------------------------------
// COMASuplWapListener::ConstructL
// Symbian 2nd phase constructor.
// -----------------------------------------------------------------------------
//
void COMASuplWapListener::ConstructL()
    {
    iTrace = COMASuplTrace::NewL();
    }	

// -----------------------------------------------------------------------------
// COMASuplWapListener::~COMASuplWapListener
// Default destructor.
// -----------------------------------------------------------------------------
//
COMASuplWapListener::~COMASuplWapListener()
    {
    	if(iTrace)
    		iTrace->Trace( _L( "COMASuplWapListener::~COMASuplWapListener()" ), KTraceFileName, __LINE__ );    
    delete iMessage;
    delete iTrace;
    Deque();
    }	

// -----------------------------------------------------------------------------
// COMASuplWapListener::CPushHandlerBase_Reserved1
// Reserved for ECOM for future expansion.
// -----------------------------------------------------------------------------
//
void COMASuplWapListener::CPushHandlerBase_Reserved1()
    {
    User::Panic( KReserved, KErrNotSupported );
    }

// -----------------------------------------------------------------------------
// COMASuplWapListener::CPushHandlerBase_Reserved2
// Reserved for ECOM for future expansion.
// -----------------------------------------------------------------------------
//
void COMASuplWapListener::CPushHandlerBase_Reserved2()
    {
    User::Panic( KReserved, KErrNotSupported );
    }

// -----------------------------------------------------------------------------
// COMASuplWapListener::HandleMessageL
// Handles a push message asynchronously.
// -----------------------------------------------------------------------------
//
void COMASuplWapListener::HandleMessageL( CPushMessage* aPushMsg, TRequestStatus& aStatus )
    {
    __ASSERT_ALWAYS( aPushMsg, User::Panic( KPushMsgNull, KErrUnknown ) );    
    iTrace->Trace( _L("COMASuplWapListener::HandleMessageL() Async Start"), KTraceFileName, __LINE__ );
    iAsyncHandling = ETrue;
    SetConfirmationStatus(aStatus);
    HandleMessageL(aPushMsg);
    }

// -----------------------------------------------------------------------------
// COMASuplWapListener::HandleMessageL
// Handles a push message synchronously.
// -----------------------------------------------------------------------------
//
void COMASuplWapListener::HandleMessageL( CPushMessage* aPushMsg )
    {
    //TBuf<64> contentType;
    __ASSERT_ALWAYS( aPushMsg, User::Panic( KPushMsgNull, KErrUnknown ) );
    iTrace->Trace( _L( "COMASuplWapListener::HandleMessageL() Sync Start" ), KTraceFileName, __LINE__ );
    iMessage = aPushMsg;
    TPtrC receivedContentType;
    iTrace->Trace( _L("Retriving Content Type:" ), KTraceFileName, __LINE__ );
    iMessage->GetContentType(receivedContentType);
    iTrace->Trace( _L("Received Content Type for WAP ..." ), KTraceFileName, __LINE__ );
    iTrace->Trace(receivedContentType, KTraceFileName, __LINE__ );
    
    if(receivedContentType.Compare(KSupportedContentType) == 0 || 
       receivedContentType.Compare(KSupportedBinaryContentType) == 0 || 
       receivedContentType.Compare(KSupportedBinaryContentType2) == 0 ) //can be combined...
    	{
    	    iState = EProcess;
    	}
	else if (CheckBinaryContentType(aPushMsg))
    	{
    	    iState = EProcess;
    	}
    else
    	{
    	iTrace->Trace( _L("ERROR:Received Content Type is not supported..." ), KTraceFileName, __LINE__ );
			iState = EComplete;
			iErrCode = KErrNotSupported;
    	}	
    IdleComplete();
    }

// -----------------------------------------------------------------------------
// COMASuplWapListener::CancelHandleMessage
// Cancels an outstanding HandleMessageL() request.
// -----------------------------------------------------------------------------
//
void COMASuplWapListener::CancelHandleMessage()
    {
    Term( KErrCancel );
    }

// -----------------------------------------------------------------------------
// COMASuplWapListener::DoCancel
// Inherited from CActive - called to cancel outanding events.
// -----------------------------------------------------------------------------
//
void COMASuplWapListener::DoCancel()
    {
    Term( KErrCancel );
    }

// -----------------------------------------------------------------------------
// COMASuplWapListener::RunL
// Inherited from CActive - called when object is active.
// -----------------------------------------------------------------------------
//
void COMASuplWapListener::RunL()
    {
    iTrace->Trace( _L( "COMASuplWapListener::RunL() Start" ), KTraceFileName, __LINE__ );

    switch ( iState )
        {
        case EProcess:
            ProcessPushMsgL();
            break;
    
        case EComplete:
            Term( iErrCode );
            break;
    
        default:
            break;
        }
}

// -----------------------------------------------------------------------------
// COMASuplWapListener::RunError
// Handles the event of leave from the request completion event handler RunL()
// -----------------------------------------------------------------------------
//
TInt COMASuplWapListener::RunError( TInt aError ) 
    {
    iState = EComplete;
    Term( aError );
    return KErrNone;
    }

// -----------------------------------------------------------------------------
// COMASuplWapListener::ProcessPushMsgL
// Extracts the SUPL INIT request from the WAP Push message. 
// -----------------------------------------------------------------------------
//
void COMASuplWapListener::ProcessPushMsgL()
    {
    iTrace->Trace( _L( "COMASuplWapListener::ProcessPushMsgL() Start" ), KTraceFileName, __LINE__ );

    // Extract SUPL INIT request from the push message
    TPtrC8 msgPtr;
    iState = EComplete;
    TBool exist = iMessage->GetMessageBody( msgPtr );

    if (!exist)
        {
        iErrCode = KErrNotFound;
        IdleComplete();
        iTrace->Trace( _L( "Unable to extract SUPL payload" ), KTraceFileName, __LINE__ );
        return;
        }

    TRAP( iErrCode, SendL( msgPtr ) );
    IdleComplete();
    }

// -----------------------------------------------------------------------------
// COMASuplWapListener::SendL
// Creates an IPC connection with the SUPL gateway, forwards 
// the request and terminates the connection.
// -----------------------------------------------------------------------------
//	
void COMASuplWapListener::SendL( TPtrC8& aMessage )
    {
    iTrace->Trace( _L( "COMASuplWapListener::SendL() Start" ), KTraceFileName, __LINE__ );

    TInt err = KErrNone;
    
    // Create IPC session
    RSuplNetworkServer suplServ;
    err = suplServ.Connect();
    if ( KErrNone != err )
        {
        iTrace->Trace( _L( "Unable to create IPC session with SUPL server" ), KTraceFileName, __LINE__ );
        User::Leave(err);
        }

    // Forward SUPL payload to SUPL server
    err = suplServ.ForwardMessage( aMessage );
    suplServ.Close();
    if ( KErrNone != err )
        {
        iTrace->Trace( _L( "Error sending SUPL payload to server" ), KTraceFileName, __LINE__ );
        User::Leave( err );
        }	
    }

// -----------------------------------------------------------------------------
// COMASuplWapListener::Term
// Destroy self.
// -----------------------------------------------------------------------------
//
void COMASuplWapListener::Term( TInt aError )
    {
    iTrace->Trace( _L( "COMASuplWapListener::Term()" ), KTraceFileName, __LINE__ );
    if ( iAsyncHandling )
        {
        SignalConfirmationStatus( aError );
        }
    // Destroy self
    iPluginKiller->KillPushPlugin();
    }

// -----------------------------------------------------------------------------
// COMASuplWapListener::IdleComplete
// Completes the iRequestStatus with KErrNone.
// -----------------------------------------------------------------------------
//
void COMASuplWapListener::IdleComplete()
    {
    TRequestStatus* pS = &iStatus;
    User::RequestComplete( pS, KErrNone );
    if ( !IsActive() )
        {
        SetActive();
        }
    }

// -----------------------------------------------------------------------------
// COMASuplWapListener::CheckBinaryContentType
// 
// -----------------------------------------------------------------------------
//
TBool COMASuplWapListener::CheckBinaryContentType(CPushMessage* aPushMsg)
{
	TPtrC8 field;
	TBool isHeaderPresent = aPushMsg->GetBinaryHeaderField(EHttpContentType, field);

#ifdef _DEBUG
	//Log the received message
	iTrace->Trace( _L( "Received Binary Content Type is:" ), KTraceFileName, __LINE__ );
    PrintHex(field, __LINE__);
#endif

	if( isHeaderPresent )
	{
		    iTrace->Trace( _L( "Binary Content type present..." ), KTraceFileName, __LINE__ );
			TUint8 code = field[0];
			
			//if(code>0x7F && ((code&0x7F) == KSupportedHEXContentType) )                 //      Content-type-value =  Short-integer
            if (field[1] == 0x03 && field[2] == 0x12)
			{
				return ETrue;
			}	
	}
	else
	{
		iTrace->Trace( _L( "No Binary Content type present..." ), KTraceFileName, __LINE__ );
	}
	return EFalse;
}

// -----------------------------------------------------------------------------
// COMASuplWapListener::PrintHex
// 
// -----------------------------------------------------------------------------
//
void COMASuplWapListener::PrintHex(const TDesC8& aBuffer,TInt aLine)
	{
			TBuf<256> buffer;
			TBuf<2> buff;
			_LIT16(KFormat1,"%02x");
			TInt len = aBuffer.Length();
			
			//The buffer is usually larger than what can be logged in a single line in the log file.  As such this should only attempt
			// to log 27 hex blocks to each log line.
			const TInt KNumberOfBlocks = 27;
			TInt blockNumber = KNumberOfBlocks;
			
			for(TInt i = 0 ; i <len; i++)
				{
					//Check to see if the buffer should be logged and then emptied
                    if(i == blockNumber)
                        {
                        //Trace the buffer as it currently is
                        iTrace->Trace(buffer, KTraceFileName, aLine);
                        //Reset the buffer for the next log line
                        buffer.Zero();
                        blockNumber += KNumberOfBlocks;
                        }
					
					buff.Zero();
					buff.Format(KFormat1,aBuffer[i]);
					buffer.Append(buff);	
					buffer.Append(_L(" "));	
				}

				iTrace->Trace(buffer, KTraceFileName, aLine); 											
	}