wvuing/wvuieng/EngSrc/CCAMessageHandler.cpp
changeset 0 094583676ce7
equal deleted inserted replaced
-1:000000000000 0:094583676ce7
       
     1 /*
       
     2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Handler class for incoming and outgoing messages
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "CCAMessageHandler.h"
       
    20 #include "MCAChatInterface.h"
       
    21 #include "MCAMessagesWriteInterface.h"
       
    22 #include "MCAMessageUtils.h"
       
    23 #include "MCAImpsImClient.h"
       
    24 #include "MCASettings.h"
       
    25 #include "MCAMessageErrorObserver.h"
       
    26 #include "MCAImpsFactory.h"
       
    27 #include "PublicEngineDefinitions.h"
       
    28 #include "impsbuilddefinitions.h"
       
    29 #include "mcabuffermemoryhandler.h"
       
    30 #include "camessageutil.h"
       
    31 
       
    32 #include <apmstd.h> // KMaxDataTypeLength
       
    33 #include <utf.h>    // CnvUtfConverter
       
    34 
       
    35 #include "ChatDebugPrint.h"
       
    36 
       
    37 #include "ImpsCSPAllErrors.h"
       
    38 
       
    39 // "test character identity and accents, ignore case"
       
    40 const TInt KCollationLevel = 1;
       
    41 const TInt KMemorySafeValue = 1024; // One kbyte for safe memory allocation.
       
    42 
       
    43 //-----------------------------------------------------------------------------
       
    44 // CCAMessageHandler::CCAMessageHandler
       
    45 // ( Other items commented in header )
       
    46 //-----------------------------------------------------------------------------
       
    47 CCAMessageHandler::CCAMessageHandler( MCAChatInterface& aChatInterface,
       
    48                                       MCAMessageUtils& aMessageUtils,
       
    49                                       MCAImpsFactory* aIMPSFactory )
       
    50         : iMessageUtils( aMessageUtils ),
       
    51         iChatInterface( aChatInterface ),
       
    52         iImpsFactory( aIMPSFactory )
       
    53     {
       
    54     }
       
    55 
       
    56 //-----------------------------------------------------------------------------
       
    57 // CCAMessageHandler::~CCAMessageHandler
       
    58 // ( Other items commented in header )
       
    59 //-----------------------------------------------------------------------------
       
    60 CCAMessageHandler::~CCAMessageHandler()
       
    61     {
       
    62     CHAT_DP_FUNC_ENTER( "CCAMessageHandler::~CCAMessageHandler" );
       
    63     delete iIdle;
       
    64     if ( iSendBuffer )
       
    65         {
       
    66         iSendBuffer->SetObserver( NULL );
       
    67         }
       
    68     iErrorObservers.Close();
       
    69     iHoldingMessages.Close();
       
    70     CHAT_DP_FUNC_DONE( "CCAMessageHandler::~CCAMessageHandler" );
       
    71     }
       
    72 
       
    73 //-----------------------------------------------------------------------------
       
    74 // CCAMessageHandler::NewL
       
    75 // ( Other items commented in header )
       
    76 //-----------------------------------------------------------------------------
       
    77 CCAMessageHandler* CCAMessageHandler::NewL(
       
    78     MCAChatInterface& aChatInterface,
       
    79     MCAMessageUtils& aMessageUtils,
       
    80     MCAImpsFactory* aIMPSFactory )
       
    81     {
       
    82     CHAT_DP_FUNC_ENTER( "CCAMessageHandler::NewL" );
       
    83     CCAMessageHandler* self = CCAMessageHandler::NewLC(
       
    84                                   aChatInterface,
       
    85                                   aMessageUtils,
       
    86                                   aIMPSFactory );
       
    87     CleanupStack::Pop( self );
       
    88     CHAT_DP_FUNC_DONE( "CCAMessageHandler::NewL" );
       
    89     return self;
       
    90     }
       
    91 
       
    92 //-----------------------------------------------------------------------------
       
    93 // CCAMessageHandler::NewLC
       
    94 // ( Other items commented in header )
       
    95 //-----------------------------------------------------------------------------
       
    96 CCAMessageHandler* CCAMessageHandler::NewLC(
       
    97     MCAChatInterface& aChatInterface,
       
    98     MCAMessageUtils& aMessageUtils,
       
    99     MCAImpsFactory* aIMPSFactory )
       
   100     {
       
   101     CHAT_DP_FUNC_ENTER( "CCAMessageHandler::NewLC" );
       
   102     CCAMessageHandler* self = new ( ELeave ) CCAMessageHandler(
       
   103         aChatInterface,
       
   104         aMessageUtils,
       
   105         aIMPSFactory );
       
   106     CleanupStack::PushL( self );
       
   107     self->ConstructL();
       
   108     CHAT_DP_FUNC_DONE( "CCAMessageHandler::NewLC" );
       
   109     return self;
       
   110     }
       
   111 
       
   112 //-----------------------------------------------------------------------------
       
   113 // CCAMessageHandler::ConstructL
       
   114 // ( Other items commented in header )
       
   115 //-----------------------------------------------------------------------------
       
   116 void CCAMessageHandler::ConstructL()
       
   117     {
       
   118     CHAT_DP_FUNC_ENTER( "CCAMessageHandler::ConstructL" );
       
   119 
       
   120     iImpsImClient = iImpsFactory->CreateImClientL();
       
   121 
       
   122     iSendBuffer = &iChatInterface.MessageReadInterfaceL( KNullDesC, KNullDesC );
       
   123     iSendBuffer->SetObserver( this );
       
   124     iIdle = CIdle::NewL( CActive::EPriorityIdle );
       
   125     CHAT_DP_FUNC_DONE( "CCAMessageHandler::ConstructL" );
       
   126     }
       
   127 
       
   128 //-----------------------------------------------------------------------------
       
   129 // CCAMessageHandler::HandleNewTextMessageL
       
   130 // ( Other items commented in header )
       
   131 //-----------------------------------------------------------------------------
       
   132 void CCAMessageHandler::HandleNewTextMessageL(  TInt aOpId,
       
   133                                                 const TDesC& /*aMessageId*/,
       
   134                                                 const TDesC& aSender,
       
   135                                                 const TDesC& aGroupId,
       
   136                                                 const MDesCArray& aRecipients,
       
   137                                                 const MDesCArray& aScreenNames,
       
   138                                                 const TDesC& aText,
       
   139                                                 TImpsCspIdentifier& aCspId )
       
   140     {
       
   141     CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleNewTextMessageL" );
       
   142 
       
   143     // Don't use memory handling if this is local echo message
       
   144     MCAMessagesWriteInterface& messageContainer =
       
   145         iChatInterface.MessageWriteInterfaceL(
       
   146             aCspId.Sap(),
       
   147             aCspId.UserId(),
       
   148             ( aGroupId == KNullDesC ? aSender : aGroupId ) );
       
   149 
       
   150     if ( !( aGroupId != KNullDesC &&
       
   151             iLocalEchoInGroup &&
       
   152             messageContainer.OwnScreenName().CompareC( aSender, KCollationLevel, NULL ) == 0 ) )
       
   153         {
       
   154         if ( !iMessageUtils.MemoryHandler().FreeMemoryIfNeededL( KMemorySafeValue + aText.Size() ) )
       
   155             {
       
   156             NotifyMessageError( KErrNoMemory, NULL );
       
   157             User::Leave( KErrNoMemory );
       
   158             }
       
   159         }
       
   160 
       
   161     HBufC* sap = aCspId.Sap().AllocLC();
       
   162     HBufC* userId = aCspId.UserId().AllocLC();
       
   163 
       
   164     MCAMessageCreator::SMessageData data =
       
   165         {
       
   166         KMessageDataVersion,
       
   167         aOpId,
       
   168         *sap,
       
   169         *userId,
       
   170         aSender,
       
   171         ( aGroupId == KNullDesC ? aSender : aGroupId ),
       
   172         &aRecipients,
       
   173         &aScreenNames,
       
   174         aText,
       
   175         KNullDesC8,
       
   176         KNullDesC8,
       
   177         MCAMessage::EMessageReceived
       
   178         };
       
   179     HandleNewMessageL( data );
       
   180 
       
   181     CleanupStack::PopAndDestroy( 2, sap );
       
   182     CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleNewTextMessageL" );
       
   183     }
       
   184 
       
   185 //-----------------------------------------------------------------------------
       
   186 // CCAMessageHandler::HandleNewContentMessageL
       
   187 // ( Other items commented in header )
       
   188 //-----------------------------------------------------------------------------
       
   189 void CCAMessageHandler::HandleNewContentMessageL(
       
   190     TInt aOpId,
       
   191     const TDesC& /*aMessageId*/,
       
   192     const TDesC& aSender,
       
   193     const TDesC& aGroupId,
       
   194     const MDesCArray& aRecipients,
       
   195     const MDesCArray& aScreenNames,
       
   196     const TDesC& aContentType,
       
   197     const TDesC8& aContent,
       
   198     TImpsCspIdentifier& aCspId )
       
   199     {
       
   200     CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleNewContentMessageL" );
       
   201 
       
   202     // Don't use memory handling if this is local echo message
       
   203     MCAMessagesWriteInterface& messageContainer =
       
   204         iChatInterface.MessageWriteInterfaceL(
       
   205             aCspId.Sap(),
       
   206             aCspId.UserId(),
       
   207             ( aGroupId == KNullDesC ? aSender : aGroupId ) );
       
   208 
       
   209     if ( !( aGroupId != KNullDesC &&
       
   210             iLocalEchoInGroup &&
       
   211             messageContainer.OwnScreenName().CompareC( aSender, KCollationLevel, NULL ) == 0 ) )
       
   212         {
       
   213         if ( !iMessageUtils.MemoryHandler().FreeMemoryIfNeededL( KMemorySafeValue + aContent.Size() ) )
       
   214             {
       
   215             NotifyMessageError( KErrNoMemory, NULL );
       
   216             User::Leave( KErrNoMemory );
       
   217             }
       
   218         }
       
   219 
       
   220     HBufC* sap = aCspId.Sap().AllocLC();
       
   221     HBufC* userId = aCspId.UserId().AllocLC();
       
   222 
       
   223     TBuf8< KMaxDataTypeLength > mimeType;
       
   224     CnvUtfConverter::ConvertFromUnicodeToUtf8( mimeType, aContentType );
       
   225 
       
   226     MCAMessageCreator::SMessageData data =
       
   227         {
       
   228         KMessageDataVersion,
       
   229         aOpId,
       
   230         *sap,
       
   231         *userId,
       
   232         aSender,
       
   233         ( aGroupId == KNullDesC ? aSender : aGroupId ),
       
   234         &aRecipients,
       
   235         &aScreenNames,
       
   236         KNullDesC,
       
   237         mimeType,
       
   238         aContent,
       
   239         MCAMessage::EMessageReceived
       
   240         };
       
   241     HandleNewMessageL( data );
       
   242 
       
   243     CleanupStack::PopAndDestroy( 2, sap );
       
   244     CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleNewContentMessageL" );
       
   245     }
       
   246 
       
   247 
       
   248 //-----------------------------------------------------------------------------
       
   249 // CCAMessageHandler::HandleNewMessageL
       
   250 // ( Other items commented in header )
       
   251 //-----------------------------------------------------------------------------
       
   252 void CCAMessageHandler::HandleNewMessageL(
       
   253     MCAMessageCreator::SMessageData& aData )
       
   254     {
       
   255     CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleNewMessageL" );
       
   256     if ( aData.iTargetId == KNullDesC )
       
   257         {
       
   258         // Invalid message.
       
   259         User::Leave( KErrArgument );
       
   260         }
       
   261     MCAMessagesWriteInterface& messageContainer =
       
   262         iChatInterface.MessageWriteInterfaceL( aData.iSapId,
       
   263                                                aData.iUserId,
       
   264                                                aData.iTargetId );
       
   265 
       
   266     MCAMessage* message = iMessageUtils.MessageCreator().CreateMessageL( aData );
       
   267 
       
   268     if ( iLocalEchoInGroup
       
   269          && ( message->MessageType() == MCAMessage::EMessageGroup )
       
   270          && ( messageContainer.OwnScreenName().CompareC( aData.iSender,
       
   271                                                          KCollationLevel, NULL ) == 0 ) )
       
   272         {
       
   273         // Do not show message because it is already shown with local echo.
       
   274         CHAT_DP( D_CHAT_LIT( "Group message not shown, because local echo." ) );
       
   275         delete message;
       
   276         return;
       
   277         }
       
   278 
       
   279     // set iTargetId to ScreenName if current received message type is EMessageWhisper
       
   280     if ( message->MessageType() == MCAMessage::EMessageWhisper || message->MessageType() == MCAMessage::EMessageGroup )
       
   281         {
       
   282         TInt count = aData.iScreenNames->MdcaCount();
       
   283         MCAMessageCreator::SMessageData data2 =
       
   284             {
       
   285             aData.iVersion,
       
   286             aData.iOpId,
       
   287             aData.iSapId,
       
   288             aData.iUserId,
       
   289             aData.iSender,
       
   290             ( count > 0 ) ? aData.iScreenNames->MdcaPoint( 0 ) : aData.iTargetId,
       
   291             aData.iRecipients,
       
   292             aData.iScreenNames,
       
   293             aData.iText,
       
   294             aData.iContentType,
       
   295             aData.iContentData,
       
   296             aData.iMessager
       
   297             };
       
   298 
       
   299         MCAMessage* message2 = iMessageUtils.MessageCreator().CreateMessageL( data2 );
       
   300 
       
   301         delete message;
       
   302         message = message2;
       
   303         }
       
   304 
       
   305     // Message can get different process state during creation. For example
       
   306     // EContentNotSupported
       
   307     if ( message->ContentProcessState() == MCAMessage::EContentNotProcessed )
       
   308         {
       
   309         message->SetProcessState( MCAMessage::EContentReady );
       
   310         }
       
   311 
       
   312     // Add message
       
   313     CAMessageUtil::AppendMessageWithDateStampL(
       
   314         *message,
       
   315         messageContainer,
       
   316         iMessageUtils.MessageCreator() );
       
   317 
       
   318     CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleNewMessageL" );
       
   319     }
       
   320 
       
   321 //-----------------------------------------------------------------------------
       
   322 // CCAMessageHandler::HandleSendCompleteL
       
   323 // ( Other items commented in header )
       
   324 //-----------------------------------------------------------------------------
       
   325 void CCAMessageHandler::HandleSendCompleteL(	TInt aOpId,
       
   326                                              TBool aDeliveryReportOrdered,
       
   327                                              TImpsCspIdentifier& /*aCspId*/ )
       
   328     {
       
   329     CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleSendCompleteL" );
       
   330 
       
   331     CHAT_DP( D_CHAT_LIT( "Operationcode %d. Delivery ordered %d" ),
       
   332              aOpId, aDeliveryReportOrdered );
       
   333     HandleMessageSentL( KErrNone, aOpId, ETrue );
       
   334     CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleSendCompleteL" );
       
   335     }
       
   336 
       
   337 //-----------------------------------------------------------------------------
       
   338 // CCAMessageHandler::HandleDeliveryReportL
       
   339 // ( Other items commented in header )
       
   340 //-----------------------------------------------------------------------------
       
   341 void CCAMessageHandler::HandleDeliveryReportL(	const TDesC& /*aMessageId*/,
       
   342                                                TInt /*aResult*/,
       
   343                                                const TDesC* /*aDescription*/,
       
   344                                                TImpsCspIdentifier& /*aCspId*/ )
       
   345     {
       
   346     CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleDeliveryReportL" );
       
   347     CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleDeliveryReportL" );
       
   348     }
       
   349 
       
   350 //-----------------------------------------------------------------------------
       
   351 // CCAMessageHandler::HandleMessageEvent
       
   352 // ( Other items commented in header )
       
   353 //-----------------------------------------------------------------------------
       
   354 void CCAMessageHandler::HandleMessageEvent( TMessageEventType aEvent,
       
   355                                             TInt /*aIndex*/ )
       
   356     {
       
   357     CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleMessageEvent" );
       
   358     switch ( aEvent )
       
   359         {
       
   360         case ENewMessage:
       
   361             {
       
   362             if ( !iIdle->IsActive() )
       
   363                 {
       
   364                 iIdle->Start( TCallBack( SendMessage, this ) );
       
   365                 }
       
   366             break;
       
   367             }
       
   368         case EChatDeleted:
       
   369             {
       
   370             // send buffer was deleted
       
   371             iSendBuffer = NULL;
       
   372             break;
       
   373             }
       
   374         default:
       
   375             break;
       
   376         }
       
   377     CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleMessageEvent" );
       
   378     }
       
   379 
       
   380 //-----------------------------------------------------------------------------
       
   381 // CCAMessageHandler::SendMessage
       
   382 // ( Other items commented in header )
       
   383 //-----------------------------------------------------------------------------
       
   384 TInt CCAMessageHandler::SendMessage( TAny *aInstance )
       
   385     {
       
   386     CCAMessageHandler* handler = static_cast< CCAMessageHandler* >( aInstance );
       
   387     handler->iSendLaunchLock = ETrue;
       
   388     TInt retVal = handler->DoSendMessage();
       
   389     handler->iSendLaunchLock = EFalse;
       
   390     return retVal;
       
   391     }
       
   392 
       
   393 //-----------------------------------------------------------------------------
       
   394 // CCAMessageHandler::DoSendMessage
       
   395 // ( Other items commented in header )
       
   396 //-----------------------------------------------------------------------------
       
   397 TInt CCAMessageHandler::DoSendMessage()
       
   398     {
       
   399     CHAT_DP_FUNC_ENTER( "CCAMessageHandler::DoSendMessage" );
       
   400 
       
   401     if ( !iSendBuffer )
       
   402         {
       
   403         // send buffer was deleted, we're shutting down
       
   404         CHAT_DP( D_CHAT_LIT( "There is no send buffer." ) );
       
   405         return EFalse;
       
   406         }
       
   407 
       
   408     // 1. Check if there is message in holding.
       
   409     MCAMessage* holdingMessage = NextHoldingMessage();
       
   410     if ( !holdingMessage && !iSendBuffer->UnreadCount() )
       
   411         {
       
   412         CHAT_DP( D_CHAT_LIT( "There is not ready messages for sending." ) );
       
   413         return EFalse;
       
   414         }
       
   415 
       
   416     // 2. Choose new message from sendbuffer or use holding message if exists.
       
   417     MCAMessage& message = ( !holdingMessage ? iSendBuffer->ReadNextUnread()
       
   418                             : *holdingMessage );
       
   419 
       
   420     // 3. Add message to holding if needed
       
   421     TBool appendedToHolding( EFalse );
       
   422     TRAPD( error, appendedToHolding = AppendedToHoldingL( message ) );
       
   423 #ifndef RD_SEND_NOT_SUPPORTED_CONTENT
       
   424     if ( error ) // Corrupted message, inform upstairs
       
   425         {
       
   426         NotifyMessageError(
       
   427             error == KErrOverflow ? error : ECorruptedContent, &message );
       
   428         // Remove sent message from send buffer, because answer will not come.
       
   429         TInt index = iSendBuffer->FindIndex( message );
       
   430         if ( index >= 0 )
       
   431             {
       
   432             iSendBuffer->DeleteMessage( index );
       
   433             }
       
   434         return ETrue;
       
   435         }
       
   436 #endif //RD_SEND_NOT_SUPPORTED
       
   437     if ( appendedToHolding )
       
   438         {
       
   439         return ETrue;
       
   440         }
       
   441 
       
   442     // 4. Send message
       
   443     TInt opCode( 0 );
       
   444     TRAP( error, opCode = SendMessageToServerL( message ) );
       
   445     CHAT_DP( D_CHAT_LIT( "Send retval ( %d )" ), error );
       
   446 
       
   447     if ( error == KErrServerBusy )
       
   448         {
       
   449         TRAPD( err, iHoldingMessages.AppendL( &message ) );
       
   450         if ( err )
       
   451             {
       
   452             CActiveScheduler::Current()->Error( err );
       
   453             }
       
   454         return ETrue;
       
   455         }
       
   456     // 5. Local echo message
       
   457     TRAPD( error2, LocalEchoMessageL( message ) );
       
   458     if ( error2 != KErrNone )
       
   459         {
       
   460         NotifyMessageError( error2, &message );
       
   461         }
       
   462 
       
   463     // 6. Handle error
       
   464     if ( error != KErrNone )
       
   465         {
       
   466         TRAP( error2, HandleMessageSentFailedL( message, error ) );
       
   467         if ( error2 )
       
   468             {
       
   469             NotifyMessageError( error2, &message );
       
   470             }
       
   471         // Remove sent message from send buffer, because answer will not come.
       
   472         TInt index = iSendBuffer->FindIndex( message );
       
   473         if ( index >= 0 )
       
   474             {
       
   475             iSendBuffer->DeleteMessage( index );
       
   476             }
       
   477         }
       
   478     else // Send succesfull. -> Local echo
       
   479         {
       
   480         CHAT_DP( D_CHAT_LIT( "Address: %s, UserId: %s, Recipient %s" ),
       
   481                  &message.ServerAddress(),
       
   482                  &message.UserId(),
       
   483                  &message.Recipient() );
       
   484         message.SetOperationCode( opCode );
       
   485         }
       
   486 
       
   487     // 7. Check need of
       
   488     TInt unreadCount = iSendBuffer->UnreadCount();
       
   489     TInt holdingMessages( iHoldingMessages.Count() );
       
   490     CHAT_DP( D_CHAT_LIT( "Still %d messages to go. Send buffer has %d messages. \
       
   491                           Holding %d messages" ),
       
   492              unreadCount, iSendBuffer->MessageCount(), holdingMessages );
       
   493 
       
   494     CHAT_DP_FUNC_DONE( "CCAMessageHandler::DoSendMessage" );
       
   495     return Max( unreadCount, holdingMessages );
       
   496     }
       
   497 
       
   498 //-----------------------------------------------------------------------------
       
   499 // CCAMessageHandler::HandleMessageSentL
       
   500 // ( Other items commented in header )
       
   501 //-----------------------------------------------------------------------------
       
   502 void CCAMessageHandler::HandleMessageSentL( TInt aStatus, TInt aOperationCode,
       
   503                                             TBool aSuccess )
       
   504     {
       
   505     CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleMessageSentL" );
       
   506     CHAT_DP( D_CHAT_LIT( "OpCode = %d, Success = %d" ), aOperationCode, aSuccess );
       
   507 
       
   508     if ( !iSendBuffer )
       
   509         {
       
   510         // send buffer was deleted, we're shutting down
       
   511         CHAT_DP( D_CHAT_LIT( "There is no send buffer." ) );
       
   512         return;
       
   513         }
       
   514 
       
   515     TInt index = User::LeaveIfError( iSendBuffer->FindIndex( aOperationCode ) );
       
   516 
       
   517     if ( !aSuccess )
       
   518         {
       
   519         MCAMessage& message = iSendBuffer->Message( index );
       
   520 
       
   521         message.SetContainerInfo( NULL );
       
   522 
       
   523         MCAMessage* failedMessage =
       
   524             iMessageUtils.MessageCreator().CreateFailedMessageL( &message );
       
   525         CleanupDeletePushL( failedMessage );
       
   526         MCAMessagesWriteInterface& messageContainer =
       
   527             iChatInterface.MessageWriteInterfaceL( message.ServerAddress(),
       
   528                                                    message.UserId(),
       
   529                                                    message.Recipient() );
       
   530         CleanupStack::Pop( failedMessage );
       
   531         messageContainer.AppendL( failedMessage );
       
   532         NotifyMessageError( aStatus, &message );
       
   533         }
       
   534     iSendBuffer->DeleteMessage( index );
       
   535     CHAT_DP( D_CHAT_LIT( "Send buffer has %d messages." ),
       
   536              iSendBuffer->MessageCount() );
       
   537     CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleMessageSentL" );
       
   538     }
       
   539 
       
   540 //-----------------------------------------------------------------------------
       
   541 // CCAMessageHandler::SetLocalEchoInGroup
       
   542 // ( Other items commented in header )
       
   543 //-----------------------------------------------------------------------------
       
   544 void CCAMessageHandler::SetLocalEchoInGroup( TBool aLocalEchoInGroup )
       
   545     {
       
   546     iLocalEchoInGroup = aLocalEchoInGroup;
       
   547     }
       
   548 
       
   549 //-----------------------------------------------------------------------------
       
   550 // CCAMessageHandler::NotifyMessageError
       
   551 // ( Other items commented in header )
       
   552 //-----------------------------------------------------------------------------
       
   553 void CCAMessageHandler::NotifyMessageError( TInt aStatus, MCAMessage* aMessage )
       
   554     {
       
   555     TInt count( iErrorObservers.Count() );
       
   556     for ( TInt a( 0 ); a < count; ++a )
       
   557         {
       
   558         iErrorObservers[ a ]->HandleMessageError( aStatus, aMessage );
       
   559         }
       
   560     }
       
   561 
       
   562 //-----------------------------------------------------------------------------
       
   563 // CCAMessageHandler::RegisterChatObserver
       
   564 // ( Other items commented in header )
       
   565 //-----------------------------------------------------------------------------
       
   566 void CCAMessageHandler::RegisterObserver( MCAMessageErrorObserver* aObserver )
       
   567     {
       
   568     TInt index = iErrorObservers.Find( aObserver );
       
   569     if ( index == KErrNotFound )
       
   570         {
       
   571         iErrorObservers.Append( aObserver );
       
   572         }
       
   573     }
       
   574 
       
   575 //-----------------------------------------------------------------------------
       
   576 // CCAMessageHandler::RegisterChatObserver
       
   577 // ( Other items commented in header )
       
   578 //-----------------------------------------------------------------------------
       
   579 void CCAMessageHandler::UnregisterObserver( MCAMessageErrorObserver* aObserver )
       
   580     {
       
   581     TInt index = iErrorObservers.Find( aObserver );
       
   582     if ( index >= 0 )
       
   583         {
       
   584         iErrorObservers.Remove( index );
       
   585         }
       
   586     }
       
   587 
       
   588 //-----------------------------------------------------------------------------
       
   589 // CCAMessageHandler::HandleProcessingComplete
       
   590 // ( Other items commented in header )
       
   591 //-----------------------------------------------------------------------------
       
   592 void CCAMessageHandler::HandleProcessingComplete(
       
   593     MCAContentProcessor& /*aProcessor*/,
       
   594     MCAMessage& /*aMessage*/,
       
   595     TInt aStatus )
       
   596     {
       
   597     if ( !iIdle->IsActive() && aStatus == KErrNone && !iSendLaunchLock )
       
   598         {
       
   599         iIdle->Start( TCallBack( SendMessage, this ) );
       
   600         }
       
   601     }
       
   602 
       
   603 //-----------------------------------------------------------------------------
       
   604 // CCAMessageHandler::NextHoldingMessage
       
   605 // ( Other items commented in header )
       
   606 //-----------------------------------------------------------------------------
       
   607 MCAMessage* CCAMessageHandler::NextHoldingMessage()
       
   608     {
       
   609     TInt holdingMessages = iHoldingMessages.Count();
       
   610     MCAMessage* message = NULL;
       
   611     TInt index( 0 );
       
   612     // Check if holding messages hold one ready message
       
   613     for ( ; index < holdingMessages && !message; ++index )
       
   614         {
       
   615         MCAMessage* msg = iHoldingMessages[ index ];
       
   616         if ( ( msg->ContentProcessState() >= MCAMessage::EContentReady ) ||
       
   617              ( msg->ContentType() == MCAMessage::EContentText ) )
       
   618             {
       
   619             CHAT_DP( D_CHAT_LIT( "Ready holding message found. Index( %d )" ),
       
   620                      index );
       
   621             message = msg;
       
   622             iHoldingMessages.Remove( index );
       
   623             }
       
   624         }
       
   625     return message;
       
   626     }
       
   627 
       
   628 //-----------------------------------------------------------------------------
       
   629 // CCAMessageHandler::NextHoldingMessage
       
   630 // ( Other items commented in header )
       
   631 //-----------------------------------------------------------------------------
       
   632 TBool CCAMessageHandler::AppendedToHoldingL( MCAMessage& aMessage )
       
   633     {
       
   634     switch ( aMessage.ContentType() )
       
   635         {
       
   636         case MCAMessage::EContentPicture: // add scaler
       
   637             {
       
   638             if ( aMessage.ContentProcessState() < MCAMessage::EContentReady )
       
   639                 {
       
   640                 CHAT_DP( D_CHAT_LIT( "Picture message not yet ready for \
       
   641                                   sending. Put to holding." ) );
       
   642                 TInt added = User::LeaveIfError( aMessage.AddContentProcessor(
       
   643                                                      iMessageUtils.ImageScaler(), this ) );
       
   644                 if ( added )
       
   645                     {
       
   646                     iHoldingMessages.AppendL( &aMessage );
       
   647                     return ETrue;
       
   648                     }
       
   649                 }
       
   650             break;
       
   651             }
       
   652         default: // Flowthrough other types
       
   653             {
       
   654 #ifdef RD_SEND_NOT_SUPPORTED_CONTENT
       
   655             if ( aMessage.ContentProcessState() < MCAMessage::EContentReady )
       
   656                 {
       
   657                 CHAT_DP( D_CHAT_LIT( "Picture message not yet ready for \
       
   658                                   sending. Put to holding." ) );
       
   659                 TInt added = User::LeaveIfError( aMessage.AddContentProcessor(
       
   660                                                      iMessageUtils.ImageScaler(), this ) );
       
   661                 if ( added )
       
   662                     {
       
   663                     iHoldingMessages.AppendL( &aMessage );
       
   664                     return ETrue;
       
   665                     }
       
   666                 }
       
   667 #endif //RD_SEND_NOT_SUPPORTED_CONTENT            
       
   668             break;
       
   669             }
       
   670         }
       
   671     return EFalse;
       
   672     }
       
   673 
       
   674 //-----------------------------------------------------------------------------
       
   675 // CCAMessageHandler::SendMessageToServerL
       
   676 // ( Other items commented in header )
       
   677 //-----------------------------------------------------------------------------
       
   678 TInt CCAMessageHandler::SendMessageToServerL( MCAMessage& aMessage )
       
   679     {
       
   680     CHAT_DP_FUNC_ENTER( "CCAMessageHandler::SendMessageToServerL" );
       
   681 
       
   682     TInt opCode( 0 );
       
   683     TBuf< KMaxDataTypeLength > mimeType;
       
   684     CnvUtfConverter::ConvertToUnicodeFromUtf8( mimeType, aMessage.MimeType() );
       
   685 
       
   686     // granularity of 1 because only one item appended to array
       
   687     CDesCArrayFlat* tempArray = NULL;
       
   688     const MDesCArray* recipients = NULL;
       
   689 
       
   690     const TDesC* sender = NULL;
       
   691     const TDesC* groupId = NULL;
       
   692 
       
   693     if ( aMessage.ScreenNames() )
       
   694         {
       
   695         groupId = &aMessage.Recipient();
       
   696         if ( aMessage.ScreenNames()->MdcaCount() > 0 )
       
   697             {
       
   698             recipients = aMessage.ScreenNames();
       
   699             }
       
   700         }
       
   701     else
       
   702         {
       
   703         tempArray = new ( ELeave ) CDesCArrayFlat( 1 );
       
   704         CleanupStack::PushL( tempArray );
       
   705         tempArray->AppendL( aMessage.Recipient() );
       
   706         }
       
   707 
       
   708     if ( aMessage.ContentType() == MCAMessage::EContentText )
       
   709         {
       
   710         CHAT_DP( D_CHAT_LIT( "Send text message" ) );
       
   711         opCode = iImpsImClient->SendTextMessageL(
       
   712                      sender,
       
   713                      tempArray,
       
   714                      groupId,
       
   715                      recipients,
       
   716                      aMessage.Text(),
       
   717                      EFalse );
       
   718         }
       
   719     else
       
   720         {
       
   721         CHAT_DP( D_CHAT_LIT( "Send content message" ) );
       
   722         TInt size( aMessage.ContentData().Size() );
       
   723         TInt maxSize( iImpsImClient->MaxTransactionContentLengthL() );
       
   724         if ( size > maxSize )
       
   725             {
       
   726             // content too big => can't send
       
   727             CHAT_DP( D_CHAT_LIT( "content too big: %d/%d" ), size, maxSize );
       
   728             User::Leave( KErrOverflow );
       
   729             }
       
   730 
       
   731         opCode = iImpsImClient->SendContentMessageL(
       
   732                      sender,
       
   733                      tempArray,
       
   734                      groupId,
       
   735                      recipients,
       
   736                      mimeType,
       
   737                      aMessage.ContentData(),
       
   738                      EFalse );
       
   739         }
       
   740 
       
   741     if ( tempArray )
       
   742         {
       
   743         CleanupStack::PopAndDestroy( tempArray );
       
   744         }
       
   745 
       
   746     CHAT_DP_FUNC_DONE( "CCAMessageHandler::SendMessageToServerL" );
       
   747     return opCode;
       
   748     }
       
   749 
       
   750 //-----------------------------------------------------------------------------
       
   751 // CCAMessageHandler::HandleMessageSentFailedL
       
   752 // ( Other items commented in header )
       
   753 //-----------------------------------------------------------------------------
       
   754 void CCAMessageHandler::HandleMessageSentFailedL( MCAMessage& aMessage,
       
   755                                                   TInt aError )
       
   756     {
       
   757     CHAT_DP_FUNC_ENTER( "CCAMessageHandler::HandleMessageSentFailedL" );
       
   758     MCAMessage* failMessage =
       
   759         iMessageUtils.MessageCreator().CreateFailedMessageL( &aMessage );
       
   760     CleanupDeletePushL( failMessage );
       
   761     MCAMessagesWriteInterface& messageContainer =
       
   762         iChatInterface.MessageWriteInterfaceL( aMessage.ServerAddress(),
       
   763                                                aMessage.UserId(),
       
   764                                                aMessage.Recipient() );
       
   765     CleanupStack::Pop( failMessage );
       
   766 
       
   767     // Notify observers for error.
       
   768     NotifyMessageError( aError, &aMessage );
       
   769     messageContainer.AppendL( failMessage );
       
   770     CHAT_DP_FUNC_DONE( "CCAMessageHandler::HandleMessageSentFailedL" );
       
   771     }
       
   772 
       
   773 //-----------------------------------------------------------------------------
       
   774 // CCAMessageHandler::LocalEchoMessageL
       
   775 // ( Other items commented in header )
       
   776 //-----------------------------------------------------------------------------
       
   777 void CCAMessageHandler::LocalEchoMessageL( MCAMessage& aMessage )
       
   778     {
       
   779     CHAT_DP_FUNC_ENTER( "CCAMessageHandler::LocalEchoMessageL" );
       
   780 
       
   781     if ( aMessage.MessageType() == MCAMessage::EMessageGroup
       
   782          && !iLocalEchoInGroup )
       
   783         {
       
   784         // Local echo is not allowed in groups.
       
   785         CHAT_DP( D_CHAT_LIT( " Message not shown because local echo is not \
       
   786                     allowed." ) );
       
   787         return;
       
   788         }
       
   789 
       
   790     MCAMessagesWriteInterface& messageContainer =
       
   791         iChatInterface.MessageWriteInterfaceL( aMessage.ServerAddress(),
       
   792                                                aMessage.UserId(),
       
   793                                                aMessage.Recipient() );
       
   794 
       
   795     if ( aMessage.MessageType() == MCAMessage::EMessageWhisper )
       
   796         {
       
   797         // Local echo ones for all recipients
       
   798         const MDesCArray* recipients = aMessage.ScreenNames();
       
   799         TInt count( recipients->MdcaCount() );
       
   800         for ( TInt a( 0 ); a < count; ++a )
       
   801             {
       
   802             MCAMessageCreator::SMessageData data =
       
   803                 {
       
   804                 KMessageDataVersion,
       
   805                 aMessage.OperationCode(),
       
   806                 aMessage.ServerAddress(),
       
   807                 aMessage.UserId(),
       
   808                 aMessage.Sender(),
       
   809                 recipients->MdcaPoint( a ),
       
   810                 aMessage.Recipients(),
       
   811                 recipients,
       
   812                 aMessage.Text(),
       
   813                 aMessage.MimeType(),
       
   814                 aMessage.ContentData(),
       
   815                 aMessage.MessagerType()
       
   816                 };
       
   817             MCAMessage* message =
       
   818                 iMessageUtils.MessageCreator().CreateMessageL( data );
       
   819             message->SetProcessState( MCAMessage::EContentReady );
       
   820 
       
   821             // Append message
       
   822             CAMessageUtil::AppendMessageWithDateStampL(
       
   823                 *message,
       
   824                 messageContainer,
       
   825                 iMessageUtils.MessageCreator() );
       
   826             }
       
   827         }
       
   828     else
       
   829         {
       
   830         // Append message
       
   831         CAMessageUtil::AppendMessageWithDateStampL(
       
   832             aMessage,
       
   833             messageContainer,
       
   834             iMessageUtils.MessageCreator(),
       
   835             ETrue );
       
   836         }
       
   837     CHAT_DP_FUNC_DONE( "CCAMessageHandler::LocalEchoMessageL" );
       
   838     }
       
   839 
       
   840 
       
   841 // end of file