diff -r 000000000000 -r b497e44ab2fc syncmlfw/common/alertqueue/src/NSmlAlertHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/syncmlfw/common/alertqueue/src/NSmlAlertHandler.cpp Thu Dec 17 09:07:52 2009 +0200 @@ -0,0 +1,488 @@ +/* +* Copyright (c) 2002-2004 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: Alert queue and handler +* +*/ + +#include + +#include "NSmlAlertQueue.h" +#include "nsmlsosserverdefs.h" + +//Fix to Remove the Bad Compiler Warnings +#ifndef __WINS__ +// This lowers the unnecessary compiler warning (armv5) to remark. +// "Warning: #174-D: expression has no effect..." is caused by +// DBG_ARGS8 macro in no-debug builds. +#pragma diag_remark 174 +#endif + +// ============================ MEMBER FUNCTIONS =============================== + +// --------------------------------------------------------- +// CNSmlAlertHandler::NewL(MNSmlMessageHandler* aMsgHandler) +// Two phase constructor +// --------------------------------------------------------- +// +CNSmlAlertHandler* CNSmlAlertHandler::NewL( MNSmlMessageHandler* aMsgHandler ) + { + CNSmlAlertHandler* self = new (ELeave) CNSmlAlertHandler; + CleanupStack::PushL( self ); + self->ConstructL( aMsgHandler ); + CleanupStack::Pop(); + return self; + } + +// --------------------------------------------------------- +// CNSmlAlertHandler::CNSmlAlertHandler() +// Constructor +// --------------------------------------------------------- +CNSmlAlertHandler::CNSmlAlertHandler() +: CActive(0), iNewEntry( EFalse ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------- +// CNSmlAlertHandler::~CNSmlAlertHandler() +// Destructor +// --------------------------------------------------------- +CNSmlAlertHandler::~CNSmlAlertHandler() + { + + Cancel(); + if( !iHistoryArray ) + { + iHistoryArray->SetOwnerShip( ETrue ); + delete iHistoryArray; + } + delete iAlertParser; + + if ( ! iNewEntry ) + { + delete iAlertInfo; + delete iHistoryInfo; + } + } + +// --------------------------------------------------------- +// CNSmlAlertHandler::DoCancel() +// Method from base class +// --------------------------------------------------------- +void CNSmlAlertHandler::DoCancel() + { + + } + +// --------------------------------------------------------- +// CNSmlAlertHandler::ProcessAlert() +// Activates alert handler +// --------------------------------------------------------- +void CNSmlAlertHandler::ProcessAlert() + { + if ( IsActive() ) + { + return; + } + SetActive(); + TRequestStatus* pStatus = &iStatus; + User::RequestComplete(pStatus, KErrNone); + } + +// --------------------------------------------------------- +// CNSmlAlertHandler::ConstructL( MNSmlMessageHandler* aMsgHandler ) +// Second phase constructor +// --------------------------------------------------------- +void CNSmlAlertHandler::ConstructL( MNSmlMessageHandler* aMsgHandler ) + { + User::LeaveIfNull(aMsgHandler); + iMsgHandler = aMsgHandler; + + iHistoryInfo = CSyncMLHistoryPushMsg::NewL(); + + iAlertInfo = new ( ELeave ) CSmlAlertInfo; + + iHistoryArray = CNSmlHistoryArray::NewL(); + iHistoryArray->SetOwnerShip( EFalse ); // move ownership to history array + } + +// --------------------------------------------------------- +// CNSmlAlertHandler::RunL() +// Method from base class +// --------------------------------------------------------- +void CNSmlAlertHandler::RunL() + { + TRAP_IGNORE( DoRunL() ); + }; + +// --------------------------------------------------------- +// CNSmlAlertHandler::DoRunL() +// Method from base class +// --------------------------------------------------------- +void CNSmlAlertHandler::DoRunL() + { + + // Delete member variables + iHistoryArray->SetOwnerShip( ETrue ); + delete iHistoryArray; + iHistoryArray = NULL; + delete iAlertParser; + iAlertParser = NULL; + + // These are deleted by iHistoryArray + iAlertInfo = NULL; + iHistoryInfo = NULL; + + // Create member variables + iHistoryInfo = CSyncMLHistoryPushMsg::NewL(); + iAlertInfo = new ( ELeave ) CSmlAlertInfo; + iHistoryArray = CNSmlHistoryArray::NewL(); + iHistoryArray->SetOwnerShip( EFalse ); // move ownership to history array + + + // Continue DoRunL method + TBool message( EFalse ); + TBool quit( ETrue ); + TBool doPop( EFalse ); + + TPtrC8 pPackage; + TSmlUsageType type; + TSmlProtocolVersion version; + TSmlTransportId bearerType; + + //check message + iMsgHandler->CheckMessage( message, type, version, bearerType ); + iAlertInfo->SetJobControl( CSmlAlertInfo::EDoNotCreateJob ); + iAlertInfo->SetTransportId( bearerType ); + #ifdef __NSML_DEBUG__ + DBG_ARGS(_S("CNSmlAlertHandler::RunL(): TransportId : '%d'"), bearerType ); + #endif // __NSML_DEBUG__ + + TInt err( KErrNone ); + + if ( message ) + { + + iAlertParser = NSmlParserFactory::CreateAlertParserL( type, version, *iAlertInfo, *iHistoryInfo ); + iAlertParser->CreateBufferL( iMsgHandler->MessageSize() ); + iMsgHandler->AlertMessage( iAlertParser->Message() ); + + TRAP(err, iAlertParser->ParseMessageL()); + DBG_FILE_CODE(err, _S8("CNSmlAlertHandler::RunL() : Alert result")); + iAlertInfo->SetErrorCode( err ); + + iNewEntry = ETrue; + + if ( err != KErrNone) + { + iNewEntry = EFalse; + iAlertInfo->SetJobControl( CSmlAlertInfo::EDoNotCreateJob ); + + // Close local connection + if ( bearerType != KUidNSmlMediumTypeInternet.iUid ) + { + iMsgHandler->DoDisconnect(); + } + + if ( err == KErrCorrupt ) + { + return; + } + } + else + { + CheckDigestL( iAlertInfo->Profile(), iHistoryInfo->MsgDigest() ); + + CheckProtocolAndChangeL( version ); + + if ( ( type == ESmlDataSync ) && ( version == ESmlVersion1_1_2 ) ) + { + iAlertInfo->SetConfirmation( ETrue ); + pPackage.Set( iAlertParser->DoMessageCopyLC() ); + doPop = ETrue; + } + } + + delete iAlertParser; + iAlertParser = NULL; + } + + iAlertInfo->SetConfirmation( FinalizeBeforeJobCreationL() ); + iMsgHandler->CreateJobL( *iAlertInfo, quit, pPackage); + + if ( doPop ) + { + CleanupStack::PopAndDestroy(); // DoMessageCopyLC() + } + + + if (! quit) + { + ProcessAlert(); + } + + } + + +// --------------------------------------------------------- +// CNSmlAlertHandler::FinalizeBeforeJobCreationL() +// Connects to notifier plug in to show confirmation note and +// waits for the response. +// --------------------------------------------------------- +TBool CNSmlAlertHandler::FinalizeBeforeJobCreationL() + { + + if ( iAlertInfo->Profile() < KMaxDataSyncID ) + { + CNSmlDSSettings* settings = CNSmlDSSettings::NewLC(); + + CNSmlDSProfile* profile = settings->ProfileL( iAlertInfo->Profile() ); + + if ( !profile ) + { + CleanupStack::PopAndDestroy(); //settings + return EFalse; + } + + CleanupStack::PushL( profile ); + + iAlertInfo->SetTransportId( profile->IntValue( EDSProfileTransportId) ); + iAlertInfo->SetConnectionId( profile->IntValue( EDSProfileTransportId) ); + + CleanupStack::PopAndDestroy(2); //profile, settings + } + else + { + CNSmlDMSettings* settings = CNSmlDMSettings::NewLC(); + + CNSmlDMProfile* profile = settings->ProfileL( iAlertInfo->Profile() ); + + if ( !profile ) + { + CleanupStack::PopAndDestroy(); //settings + return EFalse; + } + + CleanupStack::PushL( profile ); + profile->SetIntValue( EDMProfileSessionId, iAlertInfo->SessionId() ); + profile->SaveL(); + + iAlertInfo->SetTransportId( profile->IntValue( EDMProfileTransportId) ); + iAlertInfo->SetConnectionId( profile->IntValue( EDMProfileTransportId) ); + + CleanupStack::PopAndDestroy(2); //profile, settings + } + + SaveAlertInfoL(); + + if ( ! iAlertInfo->CreateSession() ) + { + return ETrue; + } + + return ETrue; + } + +// --------------------------------------------------------- +// CheckDigestL( const TInt aProfileId, const TDesC8& aDigest ) +// Checks whether alert has already been handled. Receive count +// is updated if handled before. +// --------------------------------------------------------- +void CNSmlAlertHandler::CheckDigestL( const TInt aProfileId, const TDesC8& aDigest ) + { + + if ( aProfileId < KMaxDataSyncID ) + { + CNSmlDSSettings* settings = CNSmlDSSettings::NewLC(); + + CNSmlDSProfile* profile = settings->ProfileL(aProfileId); + CleanupStack::PushL(profile); + + if ( ! profile->HasLogL() ) + { + CleanupStack::PopAndDestroy(2); //profile, settings + return; + } + + RReadStream& readStream = profile->LogReadStreamL(); + CleanupClosePushL( readStream ); + + iHistoryArray->InternalizeL(readStream); + + CleanupStack::PopAndDestroy(); //readStream + + for (TInt i = 0; i < iHistoryArray->Count(); i++) + { + CSyncMLHistoryEntry& hEntry = iHistoryArray->Entry(i); + CSyncMLHistoryPushMsg * pushMsg = CSyncMLHistoryPushMsg::DynamicCast(&hEntry); + + if (pushMsg == NULL) + continue; + + if ( aDigest.Compare( pushMsg->MsgDigest() ) == 0) + { + pushMsg->IncReceivedCount(); + iNewEntry = EFalse; + iAlertInfo->SetConfirmation( iNewEntry ); + } + } + + CleanupStack::PopAndDestroy(2); //profile, settings + } + else + { + CNSmlDMSettings* settings = CNSmlDMSettings::NewLC(); + + CNSmlDMProfile* profile = settings->ProfileL(aProfileId); + CleanupStack::PushL(profile); + + if ( ! profile->HasLogL() ) + { + CleanupStack::PopAndDestroy(2); //profile, settings + return; + } + + RReadStream& readStream = profile->LogReadStreamL(); + CleanupClosePushL( readStream ); + + iHistoryArray->InternalizeL( readStream ); + + CleanupStack::PopAndDestroy(); //readStream + + for (TInt i = 0; i < iHistoryArray->Count(); i++) + { + CSyncMLHistoryEntry& hEntry = iHistoryArray->Entry(i); + CSyncMLHistoryPushMsg * pushMsg = CSyncMLHistoryPushMsg::DynamicCast(&hEntry); + + if (pushMsg == NULL) + continue; + + if ( aDigest.Compare( pushMsg->MsgDigest() ) == 0) + { + pushMsg->IncReceivedCount(); + iNewEntry = EFalse; + iAlertInfo->SetConfirmation( iNewEntry ); + } + } + CleanupStack::PopAndDestroy(2); //profile, settings + } + } + +// --------------------------------------------------------- +// CNSmlAlertHandler::SaveAlertInfoL( ) +// Saves the result to profile history log and adds new entry +// --------------------------------------------------------- +void CNSmlAlertHandler::SaveAlertInfoL( ) + { + + TInt profileId( iAlertInfo->Profile() ); + + if ( profileId == KNSmlNullId ) + { + return; + } + + if ( profileId < KMaxDataSyncID ) + { + CNSmlDSSettings* settings = CNSmlDSSettings::NewLC(); + + CNSmlDSProfile* profile = settings->ProfileL( profileId ); + CleanupStack::PushL( profile ); + RWriteStream& stream = profile->LogWriteStreamL(); + CleanupClosePushL( stream ); + + if ( iNewEntry ) + { + RPointerArray alertInfoArray; + CleanupClosePushL( alertInfoArray ); + + alertInfoArray.AppendL( iAlertInfo ); + + iHistoryInfo->AddAlertsL( alertInfoArray ); + iHistoryArray->AppendEntryL( iHistoryInfo ); + CleanupStack::PopAndDestroy(); //alertInfoArray + } + + iHistoryArray->ExternalizeL(stream); + + CleanupStack::PopAndDestroy(); //stream + + profile->WriteStreamCommitL(); + + CleanupStack::PopAndDestroy(2); // profile, settings + } + else + { + CNSmlDMSettings* settings = CNSmlDMSettings::NewLC(); + + CNSmlDMProfile* profile = settings->ProfileL( profileId ); + CleanupStack::PushL( profile ); + + RWriteStream& stream = profile->LogWriteStreamL(); + CleanupClosePushL( stream ); + + if ( iNewEntry ) + { + RPointerArray alertInfoArray; + CleanupClosePushL( alertInfoArray ); + + alertInfoArray.AppendL( iAlertInfo ); + + iHistoryInfo->AddAlertsL( alertInfoArray ); + iHistoryArray->AppendEntryL( iHistoryInfo ); + + CleanupStack::PopAndDestroy(); //alertInfoArray + } + + iHistoryArray->ExternalizeL( stream ); + CleanupStack::PopAndDestroy(); //stream + + profile->WriteStreamCommitL(); + + CleanupStack::PopAndDestroy(2); // profile, settings + } + } + + +// --------------------------------------------------------- +// CheckProtocolAndChange(TSmlProtocolVersion& aVersion) +// Checks if profile has different version and chages to alert's +// version if different. +// --------------------------------------------------------- +void CNSmlAlertHandler::CheckProtocolAndChangeL( TSmlProtocolVersion& aVersion ) const + { + TInt profileId( iAlertInfo->Profile() ); + + if ( profileId == KNSmlNullId ) + { + return; + } + + if ( profileId < KMaxDataSyncID ) + { + CNSmlDSSettings* settings = CNSmlDSSettings::NewLC(); + CNSmlDSProfile* profile = settings->ProfileL( profileId ); + CleanupStack::PushL( profile ); + + if ( profile->IntValue( EDSProfileProtocolVersion ) != aVersion ) + { + profile->SetIntValue( EDSProfileProtocolVersion, (TInt) aVersion ); + profile->SaveL(); + } + + CleanupStack::PopAndDestroy(2); // profile, settings + } + } + +//End of File