diff -r 000000000000 -r 094583676ce7 wvuing/wvuieng/EngSrc/CCAMessageHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wvuing/wvuieng/EngSrc/CCAMessageHandler.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,841 @@ +/* +* 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: Handler class for incoming and outgoing messages +* +*/ + + +#include "CCAMessageHandler.h" +#include "MCAChatInterface.h" +#include "MCAMessagesWriteInterface.h" +#include "MCAMessageUtils.h" +#include "MCAImpsImClient.h" +#include "MCASettings.h" +#include "MCAMessageErrorObserver.h" +#include "MCAImpsFactory.h" +#include "PublicEngineDefinitions.h" +#include "impsbuilddefinitions.h" +#include "mcabuffermemoryhandler.h" +#include "camessageutil.h" + +#include // KMaxDataTypeLength +#include // CnvUtfConverter + +#include "ChatDebugPrint.h" + +#include "ImpsCSPAllErrors.h" + +// "test character identity and accents, ignore case" +const TInt KCollationLevel = 1; +const TInt KMemorySafeValue = 1024; // One kbyte for safe memory allocation. + +//----------------------------------------------------------------------------- +// CCAMessageHandler::CCAMessageHandler +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +CCAMessageHandler::CCAMessageHandler( MCAChatInterface& aChatInterface, + MCAMessageUtils& aMessageUtils, + MCAImpsFactory* aIMPSFactory ) + : iMessageUtils( aMessageUtils ), + iChatInterface( aChatInterface ), + iImpsFactory( aIMPSFactory ) + { + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::~CCAMessageHandler +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +CCAMessageHandler::~CCAMessageHandler() + { + CHAT_DP_FUNC_ENTER( "CCAMessageHandler::~CCAMessageHandler" ); + delete iIdle; + if ( iSendBuffer ) + { + iSendBuffer->SetObserver( NULL ); + } + iErrorObservers.Close(); + iHoldingMessages.Close(); + CHAT_DP_FUNC_DONE( "CCAMessageHandler::~CCAMessageHandler" ); + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::NewL +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +CCAMessageHandler* CCAMessageHandler::NewL( + MCAChatInterface& aChatInterface, + MCAMessageUtils& aMessageUtils, + MCAImpsFactory* aIMPSFactory ) + { + CHAT_DP_FUNC_ENTER( "CCAMessageHandler::NewL" ); + CCAMessageHandler* self = CCAMessageHandler::NewLC( + aChatInterface, + aMessageUtils, + aIMPSFactory ); + CleanupStack::Pop( self ); + CHAT_DP_FUNC_DONE( "CCAMessageHandler::NewL" ); + return self; + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::NewLC +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +CCAMessageHandler* CCAMessageHandler::NewLC( + MCAChatInterface& aChatInterface, + MCAMessageUtils& aMessageUtils, + MCAImpsFactory* aIMPSFactory ) + { + CHAT_DP_FUNC_ENTER( "CCAMessageHandler::NewLC" ); + CCAMessageHandler* self = new ( ELeave ) CCAMessageHandler( + aChatInterface, + aMessageUtils, + aIMPSFactory ); + CleanupStack::PushL( self ); + self->ConstructL(); + CHAT_DP_FUNC_DONE( "CCAMessageHandler::NewLC" ); + return self; + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::ConstructL +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAMessageHandler::ConstructL() + { + CHAT_DP_FUNC_ENTER( "CCAMessageHandler::ConstructL" ); + + iImpsImClient = iImpsFactory->CreateImClientL(); + + iSendBuffer = &iChatInterface.MessageReadInterfaceL( KNullDesC, KNullDesC ); + iSendBuffer->SetObserver( this ); + iIdle = CIdle::NewL( CActive::EPriorityIdle ); + CHAT_DP_FUNC_DONE( "CCAMessageHandler::ConstructL" ); + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::HandleNewTextMessageL +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAMessageHandler::HandleNewTextMessageL( TInt aOpId, + const TDesC& /*aMessageId*/, + const TDesC& aSender, + const TDesC& aGroupId, + const MDesCArray& aRecipients, + const MDesCArray& aScreenNames, + const TDesC& aText, + TImpsCspIdentifier& aCspId ) + { + CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleNewTextMessageL" ); + + // Don't use memory handling if this is local echo message + MCAMessagesWriteInterface& messageContainer = + iChatInterface.MessageWriteInterfaceL( + aCspId.Sap(), + aCspId.UserId(), + ( aGroupId == KNullDesC ? aSender : aGroupId ) ); + + if ( !( aGroupId != KNullDesC && + iLocalEchoInGroup && + messageContainer.OwnScreenName().CompareC( aSender, KCollationLevel, NULL ) == 0 ) ) + { + if ( !iMessageUtils.MemoryHandler().FreeMemoryIfNeededL( KMemorySafeValue + aText.Size() ) ) + { + NotifyMessageError( KErrNoMemory, NULL ); + User::Leave( KErrNoMemory ); + } + } + + HBufC* sap = aCspId.Sap().AllocLC(); + HBufC* userId = aCspId.UserId().AllocLC(); + + MCAMessageCreator::SMessageData data = + { + KMessageDataVersion, + aOpId, + *sap, + *userId, + aSender, + ( aGroupId == KNullDesC ? aSender : aGroupId ), + &aRecipients, + &aScreenNames, + aText, + KNullDesC8, + KNullDesC8, + MCAMessage::EMessageReceived + }; + HandleNewMessageL( data ); + + CleanupStack::PopAndDestroy( 2, sap ); + CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleNewTextMessageL" ); + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::HandleNewContentMessageL +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAMessageHandler::HandleNewContentMessageL( + TInt aOpId, + const TDesC& /*aMessageId*/, + const TDesC& aSender, + const TDesC& aGroupId, + const MDesCArray& aRecipients, + const MDesCArray& aScreenNames, + const TDesC& aContentType, + const TDesC8& aContent, + TImpsCspIdentifier& aCspId ) + { + CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleNewContentMessageL" ); + + // Don't use memory handling if this is local echo message + MCAMessagesWriteInterface& messageContainer = + iChatInterface.MessageWriteInterfaceL( + aCspId.Sap(), + aCspId.UserId(), + ( aGroupId == KNullDesC ? aSender : aGroupId ) ); + + if ( !( aGroupId != KNullDesC && + iLocalEchoInGroup && + messageContainer.OwnScreenName().CompareC( aSender, KCollationLevel, NULL ) == 0 ) ) + { + if ( !iMessageUtils.MemoryHandler().FreeMemoryIfNeededL( KMemorySafeValue + aContent.Size() ) ) + { + NotifyMessageError( KErrNoMemory, NULL ); + User::Leave( KErrNoMemory ); + } + } + + HBufC* sap = aCspId.Sap().AllocLC(); + HBufC* userId = aCspId.UserId().AllocLC(); + + TBuf8< KMaxDataTypeLength > mimeType; + CnvUtfConverter::ConvertFromUnicodeToUtf8( mimeType, aContentType ); + + MCAMessageCreator::SMessageData data = + { + KMessageDataVersion, + aOpId, + *sap, + *userId, + aSender, + ( aGroupId == KNullDesC ? aSender : aGroupId ), + &aRecipients, + &aScreenNames, + KNullDesC, + mimeType, + aContent, + MCAMessage::EMessageReceived + }; + HandleNewMessageL( data ); + + CleanupStack::PopAndDestroy( 2, sap ); + CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleNewContentMessageL" ); + } + + +//----------------------------------------------------------------------------- +// CCAMessageHandler::HandleNewMessageL +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAMessageHandler::HandleNewMessageL( + MCAMessageCreator::SMessageData& aData ) + { + CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleNewMessageL" ); + if ( aData.iTargetId == KNullDesC ) + { + // Invalid message. + User::Leave( KErrArgument ); + } + MCAMessagesWriteInterface& messageContainer = + iChatInterface.MessageWriteInterfaceL( aData.iSapId, + aData.iUserId, + aData.iTargetId ); + + MCAMessage* message = iMessageUtils.MessageCreator().CreateMessageL( aData ); + + if ( iLocalEchoInGroup + && ( message->MessageType() == MCAMessage::EMessageGroup ) + && ( messageContainer.OwnScreenName().CompareC( aData.iSender, + KCollationLevel, NULL ) == 0 ) ) + { + // Do not show message because it is already shown with local echo. + CHAT_DP( D_CHAT_LIT( "Group message not shown, because local echo." ) ); + delete message; + return; + } + + // set iTargetId to ScreenName if current received message type is EMessageWhisper + if ( message->MessageType() == MCAMessage::EMessageWhisper || message->MessageType() == MCAMessage::EMessageGroup ) + { + TInt count = aData.iScreenNames->MdcaCount(); + MCAMessageCreator::SMessageData data2 = + { + aData.iVersion, + aData.iOpId, + aData.iSapId, + aData.iUserId, + aData.iSender, + ( count > 0 ) ? aData.iScreenNames->MdcaPoint( 0 ) : aData.iTargetId, + aData.iRecipients, + aData.iScreenNames, + aData.iText, + aData.iContentType, + aData.iContentData, + aData.iMessager + }; + + MCAMessage* message2 = iMessageUtils.MessageCreator().CreateMessageL( data2 ); + + delete message; + message = message2; + } + + // Message can get different process state during creation. For example + // EContentNotSupported + if ( message->ContentProcessState() == MCAMessage::EContentNotProcessed ) + { + message->SetProcessState( MCAMessage::EContentReady ); + } + + // Add message + CAMessageUtil::AppendMessageWithDateStampL( + *message, + messageContainer, + iMessageUtils.MessageCreator() ); + + CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleNewMessageL" ); + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::HandleSendCompleteL +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAMessageHandler::HandleSendCompleteL( TInt aOpId, + TBool aDeliveryReportOrdered, + TImpsCspIdentifier& /*aCspId*/ ) + { + CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleSendCompleteL" ); + + CHAT_DP( D_CHAT_LIT( "Operationcode %d. Delivery ordered %d" ), + aOpId, aDeliveryReportOrdered ); + HandleMessageSentL( KErrNone, aOpId, ETrue ); + CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleSendCompleteL" ); + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::HandleDeliveryReportL +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAMessageHandler::HandleDeliveryReportL( const TDesC& /*aMessageId*/, + TInt /*aResult*/, + const TDesC* /*aDescription*/, + TImpsCspIdentifier& /*aCspId*/ ) + { + CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleDeliveryReportL" ); + CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleDeliveryReportL" ); + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::HandleMessageEvent +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAMessageHandler::HandleMessageEvent( TMessageEventType aEvent, + TInt /*aIndex*/ ) + { + CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleMessageEvent" ); + switch ( aEvent ) + { + case ENewMessage: + { + if ( !iIdle->IsActive() ) + { + iIdle->Start( TCallBack( SendMessage, this ) ); + } + break; + } + case EChatDeleted: + { + // send buffer was deleted + iSendBuffer = NULL; + break; + } + default: + break; + } + CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleMessageEvent" ); + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::SendMessage +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +TInt CCAMessageHandler::SendMessage( TAny *aInstance ) + { + CCAMessageHandler* handler = static_cast< CCAMessageHandler* >( aInstance ); + handler->iSendLaunchLock = ETrue; + TInt retVal = handler->DoSendMessage(); + handler->iSendLaunchLock = EFalse; + return retVal; + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::DoSendMessage +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +TInt CCAMessageHandler::DoSendMessage() + { + CHAT_DP_FUNC_ENTER( "CCAMessageHandler::DoSendMessage" ); + + if ( !iSendBuffer ) + { + // send buffer was deleted, we're shutting down + CHAT_DP( D_CHAT_LIT( "There is no send buffer." ) ); + return EFalse; + } + + // 1. Check if there is message in holding. + MCAMessage* holdingMessage = NextHoldingMessage(); + if ( !holdingMessage && !iSendBuffer->UnreadCount() ) + { + CHAT_DP( D_CHAT_LIT( "There is not ready messages for sending." ) ); + return EFalse; + } + + // 2. Choose new message from sendbuffer or use holding message if exists. + MCAMessage& message = ( !holdingMessage ? iSendBuffer->ReadNextUnread() + : *holdingMessage ); + + // 3. Add message to holding if needed + TBool appendedToHolding( EFalse ); + TRAPD( error, appendedToHolding = AppendedToHoldingL( message ) ); +#ifndef RD_SEND_NOT_SUPPORTED_CONTENT + if ( error ) // Corrupted message, inform upstairs + { + NotifyMessageError( + error == KErrOverflow ? error : ECorruptedContent, &message ); + // Remove sent message from send buffer, because answer will not come. + TInt index = iSendBuffer->FindIndex( message ); + if ( index >= 0 ) + { + iSendBuffer->DeleteMessage( index ); + } + return ETrue; + } +#endif //RD_SEND_NOT_SUPPORTED + if ( appendedToHolding ) + { + return ETrue; + } + + // 4. Send message + TInt opCode( 0 ); + TRAP( error, opCode = SendMessageToServerL( message ) ); + CHAT_DP( D_CHAT_LIT( "Send retval ( %d )" ), error ); + + if ( error == KErrServerBusy ) + { + TRAPD( err, iHoldingMessages.AppendL( &message ) ); + if ( err ) + { + CActiveScheduler::Current()->Error( err ); + } + return ETrue; + } + // 5. Local echo message + TRAPD( error2, LocalEchoMessageL( message ) ); + if ( error2 != KErrNone ) + { + NotifyMessageError( error2, &message ); + } + + // 6. Handle error + if ( error != KErrNone ) + { + TRAP( error2, HandleMessageSentFailedL( message, error ) ); + if ( error2 ) + { + NotifyMessageError( error2, &message ); + } + // Remove sent message from send buffer, because answer will not come. + TInt index = iSendBuffer->FindIndex( message ); + if ( index >= 0 ) + { + iSendBuffer->DeleteMessage( index ); + } + } + else // Send succesfull. -> Local echo + { + CHAT_DP( D_CHAT_LIT( "Address: %s, UserId: %s, Recipient %s" ), + &message.ServerAddress(), + &message.UserId(), + &message.Recipient() ); + message.SetOperationCode( opCode ); + } + + // 7. Check need of + TInt unreadCount = iSendBuffer->UnreadCount(); + TInt holdingMessages( iHoldingMessages.Count() ); + CHAT_DP( D_CHAT_LIT( "Still %d messages to go. Send buffer has %d messages. \ + Holding %d messages" ), + unreadCount, iSendBuffer->MessageCount(), holdingMessages ); + + CHAT_DP_FUNC_DONE( "CCAMessageHandler::DoSendMessage" ); + return Max( unreadCount, holdingMessages ); + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::HandleMessageSentL +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAMessageHandler::HandleMessageSentL( TInt aStatus, TInt aOperationCode, + TBool aSuccess ) + { + CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleMessageSentL" ); + CHAT_DP( D_CHAT_LIT( "OpCode = %d, Success = %d" ), aOperationCode, aSuccess ); + + if ( !iSendBuffer ) + { + // send buffer was deleted, we're shutting down + CHAT_DP( D_CHAT_LIT( "There is no send buffer." ) ); + return; + } + + TInt index = User::LeaveIfError( iSendBuffer->FindIndex( aOperationCode ) ); + + if ( !aSuccess ) + { + MCAMessage& message = iSendBuffer->Message( index ); + + message.SetContainerInfo( NULL ); + + MCAMessage* failedMessage = + iMessageUtils.MessageCreator().CreateFailedMessageL( &message ); + CleanupDeletePushL( failedMessage ); + MCAMessagesWriteInterface& messageContainer = + iChatInterface.MessageWriteInterfaceL( message.ServerAddress(), + message.UserId(), + message.Recipient() ); + CleanupStack::Pop( failedMessage ); + messageContainer.AppendL( failedMessage ); + NotifyMessageError( aStatus, &message ); + } + iSendBuffer->DeleteMessage( index ); + CHAT_DP( D_CHAT_LIT( "Send buffer has %d messages." ), + iSendBuffer->MessageCount() ); + CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleMessageSentL" ); + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::SetLocalEchoInGroup +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAMessageHandler::SetLocalEchoInGroup( TBool aLocalEchoInGroup ) + { + iLocalEchoInGroup = aLocalEchoInGroup; + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::NotifyMessageError +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAMessageHandler::NotifyMessageError( TInt aStatus, MCAMessage* aMessage ) + { + TInt count( iErrorObservers.Count() ); + for ( TInt a( 0 ); a < count; ++a ) + { + iErrorObservers[ a ]->HandleMessageError( aStatus, aMessage ); + } + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::RegisterChatObserver +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAMessageHandler::RegisterObserver( MCAMessageErrorObserver* aObserver ) + { + TInt index = iErrorObservers.Find( aObserver ); + if ( index == KErrNotFound ) + { + iErrorObservers.Append( aObserver ); + } + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::RegisterChatObserver +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAMessageHandler::UnregisterObserver( MCAMessageErrorObserver* aObserver ) + { + TInt index = iErrorObservers.Find( aObserver ); + if ( index >= 0 ) + { + iErrorObservers.Remove( index ); + } + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::HandleProcessingComplete +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAMessageHandler::HandleProcessingComplete( + MCAContentProcessor& /*aProcessor*/, + MCAMessage& /*aMessage*/, + TInt aStatus ) + { + if ( !iIdle->IsActive() && aStatus == KErrNone && !iSendLaunchLock ) + { + iIdle->Start( TCallBack( SendMessage, this ) ); + } + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::NextHoldingMessage +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +MCAMessage* CCAMessageHandler::NextHoldingMessage() + { + TInt holdingMessages = iHoldingMessages.Count(); + MCAMessage* message = NULL; + TInt index( 0 ); + // Check if holding messages hold one ready message + for ( ; index < holdingMessages && !message; ++index ) + { + MCAMessage* msg = iHoldingMessages[ index ]; + if ( ( msg->ContentProcessState() >= MCAMessage::EContentReady ) || + ( msg->ContentType() == MCAMessage::EContentText ) ) + { + CHAT_DP( D_CHAT_LIT( "Ready holding message found. Index( %d )" ), + index ); + message = msg; + iHoldingMessages.Remove( index ); + } + } + return message; + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::NextHoldingMessage +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +TBool CCAMessageHandler::AppendedToHoldingL( MCAMessage& aMessage ) + { + switch ( aMessage.ContentType() ) + { + case MCAMessage::EContentPicture: // add scaler + { + if ( aMessage.ContentProcessState() < MCAMessage::EContentReady ) + { + CHAT_DP( D_CHAT_LIT( "Picture message not yet ready for \ + sending. Put to holding." ) ); + TInt added = User::LeaveIfError( aMessage.AddContentProcessor( + iMessageUtils.ImageScaler(), this ) ); + if ( added ) + { + iHoldingMessages.AppendL( &aMessage ); + return ETrue; + } + } + break; + } + default: // Flowthrough other types + { +#ifdef RD_SEND_NOT_SUPPORTED_CONTENT + if ( aMessage.ContentProcessState() < MCAMessage::EContentReady ) + { + CHAT_DP( D_CHAT_LIT( "Picture message not yet ready for \ + sending. Put to holding." ) ); + TInt added = User::LeaveIfError( aMessage.AddContentProcessor( + iMessageUtils.ImageScaler(), this ) ); + if ( added ) + { + iHoldingMessages.AppendL( &aMessage ); + return ETrue; + } + } +#endif //RD_SEND_NOT_SUPPORTED_CONTENT + break; + } + } + return EFalse; + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::SendMessageToServerL +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +TInt CCAMessageHandler::SendMessageToServerL( MCAMessage& aMessage ) + { + CHAT_DP_FUNC_ENTER( "CCAMessageHandler::SendMessageToServerL" ); + + TInt opCode( 0 ); + TBuf< KMaxDataTypeLength > mimeType; + CnvUtfConverter::ConvertToUnicodeFromUtf8( mimeType, aMessage.MimeType() ); + + // granularity of 1 because only one item appended to array + CDesCArrayFlat* tempArray = NULL; + const MDesCArray* recipients = NULL; + + const TDesC* sender = NULL; + const TDesC* groupId = NULL; + + if ( aMessage.ScreenNames() ) + { + groupId = &aMessage.Recipient(); + if ( aMessage.ScreenNames()->MdcaCount() > 0 ) + { + recipients = aMessage.ScreenNames(); + } + } + else + { + tempArray = new ( ELeave ) CDesCArrayFlat( 1 ); + CleanupStack::PushL( tempArray ); + tempArray->AppendL( aMessage.Recipient() ); + } + + if ( aMessage.ContentType() == MCAMessage::EContentText ) + { + CHAT_DP( D_CHAT_LIT( "Send text message" ) ); + opCode = iImpsImClient->SendTextMessageL( + sender, + tempArray, + groupId, + recipients, + aMessage.Text(), + EFalse ); + } + else + { + CHAT_DP( D_CHAT_LIT( "Send content message" ) ); + TInt size( aMessage.ContentData().Size() ); + TInt maxSize( iImpsImClient->MaxTransactionContentLengthL() ); + if ( size > maxSize ) + { + // content too big => can't send + CHAT_DP( D_CHAT_LIT( "content too big: %d/%d" ), size, maxSize ); + User::Leave( KErrOverflow ); + } + + opCode = iImpsImClient->SendContentMessageL( + sender, + tempArray, + groupId, + recipients, + mimeType, + aMessage.ContentData(), + EFalse ); + } + + if ( tempArray ) + { + CleanupStack::PopAndDestroy( tempArray ); + } + + CHAT_DP_FUNC_DONE( "CCAMessageHandler::SendMessageToServerL" ); + return opCode; + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::HandleMessageSentFailedL +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAMessageHandler::HandleMessageSentFailedL( MCAMessage& aMessage, + TInt aError ) + { + CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleMessageSentFailedL" ); + MCAMessage* failMessage = + iMessageUtils.MessageCreator().CreateFailedMessageL( &aMessage ); + CleanupDeletePushL( failMessage ); + MCAMessagesWriteInterface& messageContainer = + iChatInterface.MessageWriteInterfaceL( aMessage.ServerAddress(), + aMessage.UserId(), + aMessage.Recipient() ); + CleanupStack::Pop( failMessage ); + + // Notify observers for error. + NotifyMessageError( aError, &aMessage ); + messageContainer.AppendL( failMessage ); + CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleMessageSentFailedL" ); + } + +//----------------------------------------------------------------------------- +// CCAMessageHandler::LocalEchoMessageL +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAMessageHandler::LocalEchoMessageL( MCAMessage& aMessage ) + { + CHAT_DP_FUNC_ENTER( "CCAMessageHandler::LocalEchoMessageL" ); + + if ( aMessage.MessageType() == MCAMessage::EMessageGroup + && !iLocalEchoInGroup ) + { + // Local echo is not allowed in groups. + CHAT_DP( D_CHAT_LIT( " Message not shown because local echo is not \ + allowed." ) ); + return; + } + + MCAMessagesWriteInterface& messageContainer = + iChatInterface.MessageWriteInterfaceL( aMessage.ServerAddress(), + aMessage.UserId(), + aMessage.Recipient() ); + + if ( aMessage.MessageType() == MCAMessage::EMessageWhisper ) + { + // Local echo ones for all recipients + const MDesCArray* recipients = aMessage.ScreenNames(); + TInt count( recipients->MdcaCount() ); + for ( TInt a( 0 ); a < count; ++a ) + { + MCAMessageCreator::SMessageData data = + { + KMessageDataVersion, + aMessage.OperationCode(), + aMessage.ServerAddress(), + aMessage.UserId(), + aMessage.Sender(), + recipients->MdcaPoint( a ), + aMessage.Recipients(), + recipients, + aMessage.Text(), + aMessage.MimeType(), + aMessage.ContentData(), + aMessage.MessagerType() + }; + MCAMessage* message = + iMessageUtils.MessageCreator().CreateMessageL( data ); + message->SetProcessState( MCAMessage::EContentReady ); + + // Append message + CAMessageUtil::AppendMessageWithDateStampL( + *message, + messageContainer, + iMessageUtils.MessageCreator() ); + } + } + else + { + // Append message + CAMessageUtil::AppendMessageWithDateStampL( + aMessage, + messageContainer, + iMessageUtils.MessageCreator(), + ETrue ); + } + CHAT_DP_FUNC_DONE( "CCAMessageHandler::LocalEchoMessageL" ); + } + + +// end of file