messagingappbase/ncnlist/src/NcnMsvSessionObserver.cpp
changeset 0 72b543305e3a
child 12 caea42e26caa
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2004 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:   Methods for CNcnMsvSessionObserver class.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include    <AknUtils.h>                // Avkon Utilities
       
    22 #include    <AknGlobalNote.h>           // Avkon Global Note
       
    23 #include    <mtclreg.h>                 // Client MTM
       
    24 #include    <etel3rdparty.h>			// KMaxTelNumberSize
       
    25 #include    <SendUiConsts.h>            // For MTM Uids
       
    26 #include    <msvstd.hrh>                // For Message entry types
       
    27 #include    <centralrepository.h>
       
    28 
       
    29 #include 	<telremotepartyinformationpskeys.h>
       
    30 #include 	<telconfigcrkeys.h>
       
    31 #include    <settingsinternalcrkeys.h>  // For Autolock status
       
    32 
       
    33 #include    <smsclnt.h>                 // SMS Client MTM
       
    34 #include    <smuthdr.h>                 // Sms Header
       
    35 #include    <StringLoader.h>            // String Loader
       
    36 #include    <stringresourcereader.h>    // String Resource Reader
       
    37 #include    <mmsclient.h>
       
    38 
       
    39 #include    "NcnDebug.h"
       
    40 #include    "NcnHandlerAudio.h"
       
    41 #include    "CVoiceMailManager.h"
       
    42 #include    "NcnMsvSessionObserverBase.h"
       
    43 #include    "NcnMsvSessionObserver.h"
       
    44 #include    "NcnModel.h"
       
    45 #include    "CNcnNotifApiObserver.h"
       
    46 #include    "CNcnMsvSessionHandler.h"
       
    47 #include    <NcnListInternalCRKeys.h>
       
    48 #include    <Ncnlist.rsg>               // New Contacts Note resource
       
    49 
       
    50 #include	"MNcnMsgWaitingManager.h"
       
    51 
       
    52 // CONSTANTS
       
    53 _LIT( KEmptyChar, "" );
       
    54 _LIT( KSpaceChar, " " );
       
    55 
       
    56 const TInt KNcnStoreIndicator = 0x80;
       
    57 const TInt KNcnCphsAddressLength = 4;
       
    58 const TUint KNcnCphsConstantMask = 0x7E;
       
    59 const TUint KNcnCphsFirstChar = 2;
       
    60 const TUint KNcnCphsSecondChar = 3;
       
    61 const TUint KNcnCphsFirstInfo = 0x10;
       
    62 const TUint KNcnCphsSecondInfo = 0x00;
       
    63 const TUint KNcnCphsLineMask    = 0xf0;
       
    64 const TUint KNcnCphsVmiLine1    = 0x10; // bits 00010000
       
    65 const TUint KNcnCphsVmiLine2    = 0x90; // bits 10010000
       
    66 const TUint KNcnCphsSet         = 0x01; // bits 00000001
       
    67 
       
    68 const TInt KNcnMatchMin = 7;
       
    69 const TInt KNcnMatchMax = 11;
       
    70 const TInt KNcnMatchDefault = KNcnMatchMin;
       
    71 const TInt KNcnMaxTries = 10;
       
    72 const TInt KNcnTryInterval = 500000;
       
    73 
       
    74 // ================= LOCAL CONSTANTS =======================
       
    75 namespace
       
    76     {
       
    77     // default number of messages waiting to set, if any
       
    78     const TUint KNcnDefaultMessagesWaiting = 1;
       
    79         
       
    80     //Granularity for the unhandled message que
       
    81     const TUint KNcnUnhandledMessageQueGranularity = 5;
       
    82     }
       
    83 
       
    84 // ================= MEMBER FUNCTIONS =======================
       
    85 
       
    86 // ---------------------------------------------------------
       
    87 // CNcnMsvSessionObserverBase::NewL
       
    88 // Protocol specific class factory
       
    89 // ---------------------------------------------------------
       
    90 //
       
    91 CNcnMsvSessionObserverBase* CNcnMsvSessionObserverBase::NewL(
       
    92     CNcnModelBase* aModel, CVoiceMailManager& aVMManager)
       
    93     {
       
    94     CNcnMsvSessionObserverBase* self =
       
    95         CNcnMsvSessionObserver::NewL( aModel, aVMManager );
       
    96 
       
    97     CleanupStack::PushL( self );
       
    98     self->ConstructL();
       
    99     CleanupStack::Pop();
       
   100 
       
   101     return self;
       
   102     }
       
   103 
       
   104 // ================= MEMBER FUNCTIONS =======================
       
   105 
       
   106 // C++ default constructor can NOT contain any code that
       
   107 // might leave.
       
   108 //
       
   109 CNcnMsvSessionObserver::CNcnMsvSessionObserver(
       
   110     CNcnModelBase* aModel, CVoiceMailManager& aVMManager ) : 
       
   111     CNcnMsvSessionObserverBase( aModel ),
       
   112     iUnhandledMessages(NULL),
       
   113     iVMManager(aVMManager),
       
   114 	iUnreadMessages(NULL)
       
   115     {
       
   116     }
       
   117 
       
   118 // Two-phased constructor. NewL
       
   119 CNcnMsvSessionObserverBase* CNcnMsvSessionObserver::NewL(
       
   120     CNcnModelBase* aModel, CVoiceMailManager& aVMManager )
       
   121     {
       
   122     CNcnMsvSessionObserverBase* self = new (ELeave)
       
   123 		CNcnMsvSessionObserver ( aModel, aVMManager );
       
   124        
       
   125     return self;
       
   126     }
       
   127 
       
   128 // Two-phased constructor. ConstructL
       
   129 void CNcnMsvSessionObserver::ConstructL()
       
   130     {
       
   131     //Base classes constructor
       
   132     CNcnMsvSessionObserverBase::ConstructL();
       
   133    
       
   134     //Own constructions
       
   135 	iUnhandledMessages = new (ELeave)RArray<TInt>(KNcnUnhandledMessageQueGranularity);
       
   136 	iUnreadMessages = new (ELeave)RArray<TInt>(KNcnUnhandledMessageQueGranularity);
       
   137 	iUpdateNotifier = ETrue;
       
   138     }
       
   139     
       
   140 // Destructor
       
   141 CNcnMsvSessionObserver::~CNcnMsvSessionObserver()
       
   142     {
       
   143     if( iUnhandledMessages != NULL)
       
   144 	    {
       
   145 	    delete iUnhandledMessages;
       
   146 	    iUnhandledMessages = NULL;	
       
   147 	    }
       
   148     if( iUnreadMessages != NULL)
       
   149 	    {
       
   150 	    delete iUnreadMessages;
       
   151 	    iUnreadMessages = NULL;	
       
   152 	    }
       
   153     }         
       
   154     
       
   155 // ---------------------------------------------------------
       
   156 // CNcnMsvSessionObserver::HandleMsvSessionReadyL
       
   157 // ---------------------------------------------------------
       
   158 //
       
   159 void CNcnMsvSessionObserver::HandleMsvSessionReadyL( CMsvSession& aMsvSession )
       
   160 	{
       
   161 	NCN_RDEBUG_INT( _L( "CNcnMsvSessionObserver::HandleMsvSessionReadyL %d >> " ), iInitialized );
       
   162 	if ( !iInitialized )
       
   163 		{
       
   164 		//Most of this is in the base class
       
   165 		CNcnMsvSessionObserverBase::HandleMsvSessionReadyL(aMsvSession);
       
   166 			
       
   167 		// Add unread and visible entries in Inbox to iUnreadMessages
       
   168 		// Needed later on to determine which entries are truly new and unread
       
   169 		// and which are just old unread messages. 
       
   170 		InitUnreadMessagesArrayL();
       
   171 		
       
   172 		//Additional task is to update the message icon TSW ID: EXTW-6JDBWN
       
   173 	    UpdateInboxDataNotifiersL();
       
   174 	    iInitialized = ETrue;
       
   175 		}
       
   176 	else
       
   177 		{
       
   178 		iUnhandledMessages->Reset();
       
   179 		}
       
   180     NCN_RDEBUG( _L( "CNcnMsvSessionObserver::HandleMsvSessionReadyL <<" ) );
       
   181 	}
       
   182 	
       
   183 // ---------------------------------------------------------
       
   184 // CNcnMsvSessionObserver::HandleMsvSessionClosedL
       
   185 // ---------------------------------------------------------
       
   186 //
       
   187 void CNcnMsvSessionObserver::HandleMsvSessionClosedL()
       
   188 	{
       
   189 	NCN_RDEBUG(_L("CNcnMsvSessionObserver::HandleMsvSessionClosedL >>"));        
       
   190 
       
   191 	CNcnMsvSessionObserverBase::HandleMsvSessionClosedL();
       
   192     NCN_RDEBUG(_L("CNcnMsvSessionObserver::HandleMsvSessionClosedL >>"));        
       
   193 	}
       
   194 	
       
   195 // ---------------------------------------------------------
       
   196 // CNcnMsvSessionObserver::HandleEntryEventL
       
   197 // ---------------------------------------------------------
       
   198 //
       
   199 void CNcnMsvSessionObserver::HandleEntryEventL(
       
   200     TMsvEntryEvent  aEvent,
       
   201     TAny*           aArg1,
       
   202     TAny*           /*aArg2*/,
       
   203     TAny*           /*aArg3*/)
       
   204     {
       
   205     NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::HandleEntryEventL: aEvent: %d"), aEvent );        
       
   206 
       
   207     // handle event accordingly
       
   208     switch( aEvent )
       
   209         {
       
   210         case EMsvNewChildren:
       
   211             {
       
   212             NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleEntryEventL: EMsvNewChildren") );
       
   213             const CMsvEntrySelection* msvEntrySelection =
       
   214                 static_cast<CMsvEntrySelection*>( aArg1 );
       
   215             HandleNewChildrenL( *msvEntrySelection );
       
   216             break;
       
   217             }
       
   218         case EMsvChildrenChanged:
       
   219             {
       
   220             NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleEntryEventL: EMsvChildrenChanged") );
       
   221             const CMsvEntrySelection* msvEntrySelection =
       
   222                 static_cast<CMsvEntrySelection*>( aArg1 );
       
   223             HandleChangedChildrenL( *msvEntrySelection );
       
   224             break;
       
   225             }
       
   226         case EMsvDeletedChildren:
       
   227             {
       
   228             NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleEntryEventL: EMsvDeletedChildren") );
       
   229             const CMsvEntrySelection* msvEntrySelection =
       
   230                 static_cast<CMsvEntrySelection*>( aArg1 );
       
   231             HandleDeletedChildrenL( *msvEntrySelection );
       
   232             break;
       
   233             }
       
   234         default:
       
   235             {
       
   236             NCN_RDEBUG_INT( _L("CNcnMsvSessionObserver::HandleEntryEventL: default (%d)"), aEvent );
       
   237             break;
       
   238             }
       
   239         }        
       
   240     NCN_RDEBUG( _L( "CNcnMsvSessionObserver::HandleEntryEventL <<" ) );
       
   241     }
       
   242 
       
   243 // ---------------------------------------------------------
       
   244 // CNcnMsvSessionObserver::HandleNewChildrenL
       
   245 // ---------------------------------------------------------
       
   246 //    
       
   247 void CNcnMsvSessionObserver::HandleNewChildrenL(
       
   248     const CMsvEntrySelection& aMsvEntrySelection )
       
   249     {
       
   250     NCN_RDEBUG( _L( "CNcnMsvSessionObserver::HandleNewChildrenL" ) );
       
   251 
       
   252     // get session from session handler
       
   253     CMsvSession& msvSession = iModel->MsvSessionHandler().MsvSessionL();
       
   254     
       
   255 	//The received entrys type in ncn list's own definition
       
   256     TNcnInboxEntryType receivedEntryType = EUnknown;
       
   257     
       
   258     //Zero the phone number that is updated later
       
   259     iTelNumber.iTelNumber.Zero();
       
   260 
       
   261 	//The amount of new children
       
   262     const TInt newEntries = aMsvEntrySelection.Count();
       
   263     NCN_RDEBUG_INT( _L( "HandleNewChildrenL Count is %d" ), newEntries );
       
   264         
       
   265     // Go through all the new children
       
   266     for ( TInt index = 0; index < newEntries; index++ )
       
   267         {
       
   268         // Get the id of new entry and check if it is a sms message.
       
   269         // If so, then we have to do a detailed check.
       
   270         TMsvId id = aMsvEntrySelection.At( index );
       
   271         CMsvEntry* entryToHandlePtr = msvSession.GetEntryL( id );
       
   272         CleanupStack::PushL(entryToHandlePtr);
       
   273         
       
   274         TMsvEntry entryToHandle = entryToHandlePtr->Entry();
       
   275 		//Extensive debug information about the new entry
       
   276 		#ifdef _DEBUG
       
   277 		PrintEntryDebugInformation(entryToHandle);
       
   278 		#endif
       
   279 		
       
   280 		//Message is in preparation
       
   281         if( entryToHandle.InPreparation() && 
       
   282         	( entryToHandle.iMtm.iUid == KSenduiMtmSmsUidValue || 
       
   283         	  entryToHandle.iMtm.iUid == KSenduiMtmMmsUidValue ||
       
   284         	  entryToHandle.iMtm.iUid == KSenduiMtmBtUidValue ||
       
   285         	  entryToHandle.iMtm.iUid == KSenduiMtmIrUidValue ) )
       
   286             {
       
   287             switch( entryToHandle.iMtm.iUid )
       
   288 	            {
       
   289 	            case KSenduiMtmSmsUidValue:
       
   290 	            	{
       
   291 	            	NCN_RDEBUG_INT(_L("MsvEntry id: %d is an SMS that is still in preparation!"), entryToHandle.Id() );
       
   292 	            	break;
       
   293 	            	}
       
   294 	            case KSenduiMtmMmsUidValue:
       
   295 	            	{
       
   296 	            	NCN_RDEBUG_INT(_L("MsvEntry id: %d is an MMS that is still in preparation!"), entryToHandle.Id() );
       
   297 	            	break;
       
   298 	            	}
       
   299 	            default:
       
   300 	            	{
       
   301 	            	NCN_RDEBUG_INT(_L("MsvEntry id: %d is an IR/Bt message that is still in preparation!"), entryToHandle.Id() );
       
   302 	            	break;
       
   303 	            	}
       
   304 	            }
       
   305 	
       
   306 			//Append the message to unhandled que. We handle it when it changes to completed
       
   307 			iUnhandledMessages->AppendL( entryToHandle.Id() );
       
   308             }
       
   309         else if( entryToHandle.InPreparation() == EFalse && 
       
   310                  entryToHandle.Unread() )
       
   311             {
       
   312             switch ( entryToHandle.iMtm.iUid )
       
   313                 {
       
   314                 //Message is unread and complete SMS
       
   315                 case KSenduiMtmSmsUidValue:
       
   316                     {
       
   317                     NCN_RDEBUG_INT(_L("MsvEntry id: %d is an SMS that is complete!"), entryToHandle.Id() );            
       
   318 
       
   319         			// CheckAndHandleSmsEntryL takes ownership of the entryToHandlePtr
       
   320         			// and deletes it after completion
       
   321     		        CleanupStack::Pop(entryToHandlePtr);
       
   322                     // If the entry is an unread sms then call handling method...
       
   323                     // The method returns the entry type.		
       
   324                     TRAPD( err, receivedEntryType = CheckAndHandleSmsEntryL( entryToHandlePtr ) );
       
   325                     entryToHandlePtr = NULL;
       
   326         	        NCN_RDEBUG_INT(_L("New entry is of Ncn entry type: %d"), receivedEntryType );
       
   327         
       
   328                     // Check if message is deleted or message couldn't be
       
   329         			// recognized at all because of error
       
   330                     if( err != KErrNone )
       
   331                         {
       
   332                         // Don't react on messages that doesn't exist
       
   333         	        	NCN_RDEBUG(_L("Handling of the SMS failed. Changing it as NcnList entry type 'deleted'!") );
       
   334                         receivedEntryType = EDeletedMessage;
       
   335                         }
       
   336         			else                           
       
   337                         {
       
   338                         TInt err = iUnreadMessages->Append( entryToHandle.Id() );                   
       
   339                         if ( err )
       
   340                             {
       
   341                             NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::HandleNewChildrenL - APPEND ERROR %d!"), err );
       
   342                             }
       
   343                         }
       
   344                     break;
       
   345                     }
       
   346                 //Message is unread and complete MMS
       
   347                 case KSenduiMtmMmsUidValue:
       
   348                     {
       
   349         			NCN_RDEBUG_INT(_L("MsvEntry id: %d is an MMS that is complete!"), entryToHandle.Id() );
       
   350         
       
   351         			//This is the MMS entry's type. Notify about its arrival
       
   352         			receivedEntryType = EMMSMessage;
       
   353 			
       
   354                     TInt err = iUnreadMessages->Append( entryToHandle.Id() );
       
   355                     if ( err )
       
   356                         {
       
   357                         NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::HandleNewChildrenL - APPEND ERROR %d!"), err );
       
   358                         }
       
   359                     break;
       
   360                     }
       
   361                  
       
   362                  default:
       
   363                     {
       
   364                     NCN_RDEBUG_INT2(_L("MsvEntry id: %d with unknown MTM: 0x%x is complete!"), entryToHandle.Id(), entryToHandle.iMtm );
       
   365                     
       
   366                     //The exact type is not known
       
   367                    receivedEntryType = EUnknown;
       
   368                     
       
   369                     TInt err = iUnreadMessages->Append( entryToHandle.Id() );
       
   370                     if ( err )
       
   371                         {
       
   372                         NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::HandleNewChildrenL 2- APPEND ERROR %d!"), err );
       
   373                         }
       
   374                     break;
       
   375                     }
       
   376                 }
       
   377             // Common for all
       
   378             // notify about new child entry
       
   379             NotifyAboutNewChildEntryL( entryToHandle, receivedEntryType );
       
   380             }
       
   381          //Not an SMS/MMS, we don't do anything with it
       
   382          else
       
   383             {
       
   384             //Still in preparation
       
   385             
       
   386             // Do not add entry, if it is read. Message server sends all messages from
       
   387             // the store as changes messages, when changing message store.
       
   388             if ( entryToHandle.Unread() )
       
   389                 {
       
   390                 #ifdef _DEBUG
       
   391                 PrintEntryDebugInformation(entryToHandle);
       
   392                 #endif
       
   393                 NCN_RDEBUG_INT2(_L("MsvEntry id: %d with unknown MTM: 0x%x is still in preparation!"), entryToHandle.Id(), entryToHandle.iMtm );    
       
   394                     
       
   395                 TInt err = iUnreadMessages->Append( entryToHandle.Id() );
       
   396                 if ( err )
       
   397                     {
       
   398                     NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::HandleNewChildrenL 3 - APPEND ERROR %d!"), err );
       
   399                     }
       
   400                 }
       
   401             }
       
   402 
       
   403         if (entryToHandlePtr)
       
   404             {
       
   405             CleanupStack::PopAndDestroy(entryToHandlePtr);   
       
   406             entryToHandlePtr = NULL;
       
   407             }
       
   408         }
       
   409     }
       
   410     
       
   411 // ---------------------------------------------------------
       
   412 // CNcnMsvSessionObserver::HandleChangedChildrenL
       
   413 // ---------------------------------------------------------
       
   414 //        
       
   415 void CNcnMsvSessionObserver::HandleChangedChildrenL(
       
   416     const CMsvEntrySelection& aMsvEntrySelection )
       
   417     {
       
   418     NCN_RDEBUG( _L( "CNcnMsvSessionObserver::HandleChangedChildrenL >>" ) );
       
   419     
       
   420 	//Get session from session handler
       
   421     CMsvSession& msvSession = iModel->MsvSessionHandler().MsvSessionL();
       
   422         
       
   423   	//The amount of changed children
       
   424   	const TInt newEntries = aMsvEntrySelection.Count();
       
   425     NCN_RDEBUG_INT( _L( "HandleChangedChildrenL Count is %d" ), newEntries );
       
   426          	
       
   427   	 // Go through the changed children
       
   428     TBool completeHandling(EFalse);
       
   429 
       
   430     for ( TInt index = 0; index < newEntries; index++ )
       
   431 	    {
       
   432 	    //Get the id of the new entry and check if it has been processed
       
   433 	    //and also check if it can be notifed now
       
   434 		TMsvId id = aMsvEntrySelection.At( index );
       
   435 		CMsvEntry* entryToHandlePtr = msvSession.GetEntryL( id );
       
   436         CleanupStack::PushL(entryToHandlePtr);
       
   437         
       
   438         TMsvEntry entryToHandle = entryToHandlePtr->Entry();
       
   439         		
       
   440 		#ifdef _DEBUG
       
   441 		PrintEntryDebugInformation( entryToHandle );
       
   442 		#endif
       
   443 		
       
   444 		//Was this entry handled when it arrived or was it in preparation?
       
   445 		TInt indexInUnhandledArray = iUnhandledMessages->Find( entryToHandle.Id() );				
       
   446 		NCN_RDEBUG_INT(_L("HandleChangedChildrenL indexInUnhandledArray [%d]"), indexInUnhandledArray );
       
   447 				
       
   448         // Did the entry change to unread during preparation?
       
   449         if ( indexInUnhandledArray != KErrNotFound 
       
   450             && entryToHandle.Unread() ) 
       
   451             {
       
   452             TInt indexInUnreadArray = iUnreadMessages->Find( entryToHandle.Id() );				
       
   453             if ( indexInUnreadArray == KErrNotFound )
       
   454                 {
       
   455                 // This entry has changed to Unread(0->1) during preparation. Add it to unread messages cache.
       
   456                 TInt err = iUnreadMessages->Append( entryToHandle.Id() );
       
   457                 if ( err )
       
   458                     {
       
   459                     NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::HandleNewChildrenL - APPEND ERROR %d!"), err );
       
   460                     }
       
   461                 }
       
   462             }
       
   463 
       
   464 			
       
   465 		//Check if the entry is unhandled SMS and it can now be handled
       
   466 	    TBool entryUnhandled = 
       
   467 	        indexInUnhandledArray != KErrNotFound &&
       
   468 	    	entryToHandle.InPreparation() == EFalse &&
       
   469 	    	entryToHandle.Unread();
       
   470 
       
   471         TNcnInboxEntryType handledEntryType = EUnknown;  // default type
       
   472         completeHandling = EFalse;
       
   473 	    if( entryUnhandled )
       
   474             {
       
   475             switch( entryToHandle.iMtm.iUid )
       
   476             	{
       
   477            	
       
   478 	            case KSenduiMtmSmsUidValue:
       
   479 	    		    {
       
   480 	      			NCN_RDEBUG(_L("HandleChangedChildrenL Unhandled SMS found! Handling it now!") );
       
   481 	    			// CheckAndHandleSmsEntryL takes ownership of the entryToHandlePtr
       
   482 	    			// and deletes it after completion
       
   483 	    			CleanupStack::Pop(entryToHandlePtr);
       
   484 
       
   485 	      			// If the entry is an unread sms then call handling method...
       
   486 	    			// The method returns the entry type.
       
   487 	    			iUpdateNotifier = ETrue;
       
   488 	    			TRAPD( err, handledEntryType = CheckAndHandleSmsEntryL( entryToHandlePtr ) );
       
   489 	                entryToHandlePtr = NULL;
       
   490 	    	        NCN_RDEBUG_INT(_L("New entry is of Ncn entry type: %d"), handledEntryType );
       
   491 	    
       
   492 	    			// Check if message is deleted or message couldn't be
       
   493 	    			// recognized at all because of error
       
   494 	    			if( err != KErrNone )
       
   495 	    			    {
       
   496 	                    // Don't react on messages that doesn't exist
       
   497 	    	        	NCN_RDEBUG(_L("Handling of the SMS failed. Changing it as NcnList entry type 'deleted'!") );
       
   498 	                    handledEntryType = EDeletedMessage;
       
   499 	    			    }
       
   500 					break;
       
   501 	    		    }
       
   502             	case KSenduiMtmMmsUidValue: 	            	
       
   503 	    		    {
       
   504 	      			NCN_RDEBUG( _L("HandleChangedChildrenL Unhandled MMS found! Handling it now!") );
       
   505 	      			//This is the unhandled entry's type
       
   506 	    			handledEntryType = EMMSMessage;
       
   507 	    			break;
       
   508 	    		    }
       
   509             	
       
   510             	default:
       
   511             		{
       
   512             		NCN_RDEBUG( _L( "CNcnMsvSessionObserver::HandleChangedChildrenL: Completed something else than SMS or MMS. Smart message?" ) );
       
   513             		 // Eg. smart messages
       
   514             		break;
       
   515             		}
       
   516             	}
       
   517             // common for all messages
       
   518             completeHandling = ETrue; 
       
   519             }
       
   520 		 // It is required to update new message notifications after a message entry has been handled (by ncnlist) and
       
   521 		 // read (by user e.g. in MCE)
       
   522 		 
       
   523 		 // 2. If a read message is marked unread (e.g. in MCE), this condition is not true and notification is not displayed
       
   524 		 // about it. However if a new message arrives, all unread message (despite how they got that way) are treated as a new message.
       
   525 		 else if( indexInUnhandledArray == KErrNotFound && 
       
   526 		 		 !entryToHandle.Unread() &&
       
   527                  !entryToHandle.InPreparation() )
       
   528 			{
       
   529 			NCN_RDEBUG_INT( _L("HandleChangedChildrenL TMsvId %d changed - update message counts!"), entryToHandle.Id() );
       
   530 			TInt indexInUnreadArray = iUnreadMessages->Find( entryToHandle.Id() );				
       
   531 			NCN_RDEBUG_INT(_L("HandleChangedChildrenL indexInUnreadArray [%d]"), indexInUnreadArray );		
       
   532 			if ( indexInUnreadArray != KErrNotFound )
       
   533 				{
       
   534 				iUnreadMessages->Remove( indexInUnreadArray );
       
   535 				}
       
   536 			}
       
   537 		 //We dont do anything special with this message		 		  
       
   538 		 else
       
   539 		 	{
       
   540   			NCN_RDEBUG_INT( _L("HandleChangedChildrenL Unknown children has changed: TMsvId %d"), entryToHandle.Id() );
       
   541 		 	}
       
   542 		 	
       
   543         if ( completeHandling )
       
   544             {
       
   545             // notify about new child entry
       
   546             NotifyAboutNewChildEntryL( entryToHandle, handledEntryType );
       
   547             //Remove the notification from our unhandled list
       
   548             iUnhandledMessages->Remove( indexInUnhandledArray );
       
   549             }
       
   550         if ( entryToHandlePtr )
       
   551             {
       
   552             CleanupStack::PopAndDestroy(entryToHandlePtr);
       
   553             }
       
   554 	    }
       
   555 	    
       
   556 	 if(!iUpdateNotifier) 
       
   557 	 {
       
   558 	 	NCN_RDEBUG( _L( "CNcnMsvSessionObserver::HandleChangedChildrenL: iUpdateNotifier is set to False so No update of Notifiers" ) );
       
   559 	 	iUpdateNotifier = ETrue;
       
   560 	 	return;
       
   561 	 }
       
   562 
       
   563     UpdateInboxDataNotifiersL();
       
   564     NCN_RDEBUG( _L( "CNcnMsvSessionObserver::HandleChangedChildrenL <<" ) );
       
   565     }
       
   566 
       
   567 // ---------------------------------------------------------
       
   568 // CNcnMsvSessionObserver::HandleDeletedChildrenL
       
   569 // ---------------------------------------------------------
       
   570 //        
       
   571 void CNcnMsvSessionObserver::HandleDeletedChildrenL(
       
   572     const CMsvEntrySelection& aMsvEntrySelection )
       
   573     {
       
   574     NCN_RDEBUG( _L( "CNcnMsvSessionObserver::HandleDeletedChildrenL" ) );
       
   575     
       
   576     // get session from session handler
       
   577     CMsvSession& msvSession = iModel->MsvSessionHandler().MsvSessionL();
       
   578     const TInt deletedEntries = aMsvEntrySelection.Count();            
       
   579 
       
   580     NCN_RDEBUG_INT( _L( "CNcnMsvSessionObserver::HandleDeletedChildrenL: deleting %d messages" ), deletedEntries );
       
   581     NCN_RDEBUG_INT( _L( "CNcnMsvSessionObserver::HandleDeletedChildrenL: %d entries in iUnreadMessages" ), iUnreadMessages->Count() );
       
   582          		         	
       
   583   	 // Go through the deleted children
       
   584     for ( TInt index = 0; index < deletedEntries && iUnreadMessages->Count(); index++ )
       
   585 	    {	   
       
   586 	    NCN_RDEBUG( _L( "CNcnMsvSessionObserver::HandleDeletedChildrenL: for loop" ) ); 
       
   587 	    //Get the id of the new entry and check if it has been processed
       
   588 	    //and also check if it can be notifed now
       
   589 		TMsvId id = aMsvEntrySelection.At( index );
       
   590 
       
   591 		NCN_RDEBUG_INT( _L( "CNcnMsvSessionObserver::HandleDeletedChildrenL: Checking if msvid %d can found from unread array" ), id );
       
   592 
       
   593 		TInt idx = iUnreadMessages->Find( id );
       
   594 		if( idx != KErrNotFound )
       
   595 			{
       
   596 			NCN_RDEBUG_INT( _L( "CNcnMsvSessionObserver::HandleDeletedChildrenL: Removing msvid %d from unread array unread array" ), id );	
       
   597 			iUnreadMessages->Remove( idx );
       
   598 			}			
       
   599 	    }
       
   600 	    
       
   601 	NCN_RDEBUG( _L( "CNcnMsvSessionObserver::HandleDeletedChildrenL: Updating unread message count" ) );	    
       
   602     
       
   603     UpdateInboxDataNotifiersL();
       
   604      NCN_RDEBUG( _L( "CNcnMsvSessionObserver::HandleDeletedChildrenL <<" ) );
       
   605 
       
   606     }
       
   607 
       
   608 // ---------------------------------------------------------
       
   609 // CNcnMsvSessionObserver::NotifyAboutNewChildEntryL
       
   610 // ---------------------------------------------------------
       
   611 //    
       
   612 void CNcnMsvSessionObserver::NotifyAboutNewChildEntryL(
       
   613     const TMsvEntry& aEntry,
       
   614     TNcnInboxEntryType aEntryType )    
       
   615     {
       
   616     NCN_RDEBUG(_L("CNcnMsvSessionObserver::NotifyAboutNewChildEntryL >>"));    
       
   617     // Now we check what is the entry type and continue as required
       
   618     switch ( aEntryType )
       
   619         {
       
   620         // If the entry was a class 0 sms, then we set the lights on
       
   621         // and play the message received tone.
       
   622         case EClass0SmsMessage:
       
   623             {
       
   624             // set class0 notification
       
   625             iModel->NcnNotifier().SetNotification(
       
   626                     MNcnNotifier::ENcnClass0MessageNotification,
       
   627                     1 );
       
   628             }
       
   629             break;
       
   630 
       
   631         // If the new entry was a message of which the user
       
   632         // should be informed by the note then we set the lights on,
       
   633         // play the message received ringing tone and count the number
       
   634         // of unread messages in in-box. Then the model class is
       
   635         // informed about the new number of unread messages.
       
   636         case ESmsMessage:
       
   637         case EMMSMessage:
       
   638         case EMessageWaitingStoreMessage:
       
   639         case ESpecialMessage:
       
   640         case EUnknown:
       
   641             {
       
   642             // If the message is unread then the tone is played...
       
   643             if( IsUnread( aEntry ) )
       
   644                 {
       
   645                 UpdateInboxDataNotifiersL();
       
   646                 // Check if the message should be shown to user
       
   647                 if( iModel->IsSupported( KNcnSendFileInCall ) )
       
   648                     {
       
   649                     CheckAndLaunchMCEL( aEntry );
       
   650                     }
       
   651                 }
       
   652             break;
       
   653             }
       
   654         // If the new entry was a message waiting discard set message
       
   655         // then we set the lights on and play the tone.
       
   656         // Because it is a discard message (not containing text),
       
   657         // no note is required
       
   658         case EMessageWaitingDiscardSetMessage:
       
   659             {
       
   660             NCN_RDEBUG(_L("EMessageWaitingDiscardSetMessage:"));
       
   661             break;
       
   662             }
       
   663         // If the new entry was a delivery report or message waiting
       
   664         // discard clear message, just switch the lights on.
       
   665         case EDeliveryReport:
       
   666         case EMessageWaitingDiscardClearMessage:
       
   667             {
       
   668             NCN_RDEBUG(_L("EDeliveryReport:"));
       
   669             }
       
   670             break;
       
   671         // Delivery err report or deleted message, do nothing
       
   672         case EDeletedMessage:
       
   673         case EDeliveryErrReport:
       
   674             {
       
   675             // do nothing
       
   676             }
       
   677             break;
       
   678         default:
       
   679             break;
       
   680         }
       
   681     NCN_RDEBUG(_L("CNcnMsvSessionObserver::NotifyAboutNewChildEntryL <<")); 
       
   682     }
       
   683 
       
   684 // ---------------------------------------------------------
       
   685 // CNcnMsvSessionObserver::CheckAmountOfUnreadMessagesInInboxL
       
   686 // ---------------------------------------------------------
       
   687 //
       
   688 void CNcnMsvSessionObserver::CheckAmountOfUnreadMessagesInInboxL( TInt& aMsgCount, TInt& aAudioMsgCount )
       
   689     {
       
   690     aMsgCount = 0;
       
   691     aAudioMsgCount = 0;
       
   692     TBool audioMessagingSupported = iModel->IsSupported( KNcnAudioMessaging );
       
   693     // get session from session handler
       
   694     CMsvSession& msvSession = iModel->MsvSessionHandler().MsvSessionL();
       
   695         
       
   696     // Check how many unread messages there are in the In-box.
       
   697     const TInt itemCount = iInboxFolder->Count();
       
   698     NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::CheckAmountOfUnreadMessagesInInbox [%d]"), itemCount );
       
   699     
       
   700     for( TInt index = 0; index < itemCount; index++ )
       
   701         {
       
   702         const TMsvEntry entry = (*iInboxFolder)[index];
       
   703 
       
   704         if( entry.iType.iUid == KUidMsvMessageEntryValue && 
       
   705         	entry.Visible() &&
       
   706         	IsUnread( entry ) )
       
   707             {            
       
   708 			if( audioMessagingSupported && entry.iBioType == KUidMsgSubTypeMmsAudioMsg.iUid )
       
   709 			    {
       
   710                 aAudioMsgCount++;
       
   711                 }
       
   712             else 
       
   713                 {
       
   714                 aMsgCount++;
       
   715                 }
       
   716             }
       
   717         }
       
   718         
       
   719     NCN_RDEBUG_INT( _L( "CNcnMsvSessionObserver::CheckAmountOfUnreadMessagesInInbox \
       
   720         SetCRInt(KNcnNewMessageCountInInbox): %d" ), aMsgCount );
       
   721     
       
   722     TInt totalNewMsgCount = aMsgCount + aAudioMsgCount;
       
   723     User::LeaveIfError( iModel->SetCRInt( 
       
   724         KCRUidNcnList, KNcnNewMessageCountInInbox, totalNewMsgCount) );
       
   725         
       
   726     NCN_RDEBUG_INT( _L( "CNcnMsvSessionObserver::CheckAmountOfUnreadMessagesInInbox other\
       
   727         :%d" ), aMsgCount );
       
   728 
       
   729     if ( audioMessagingSupported )
       
   730         {
       
   731         NCN_RDEBUG_INT( _L("CNcnMsvSessionObserver::\
       
   732         CheckAmountOfNotListenedAudioMessagesInInboxL SetCRInt(KNcnNewAudioMessageCountInInbox) %d" ), aAudioMsgCount );
       
   733             
       
   734         User::LeaveIfError( iModel->SetCRInt( 
       
   735             KCRUidNcnList, KNcnNewAudioMessageCountInInbox, aAudioMsgCount ) );
       
   736         }
       
   737     }
       
   738 
       
   739 // ---------------------------------------------------------
       
   740 // CNcnMsvSessionObserver::CheckAndHandleSmsEntryL
       
   741 // ---------------------------------------------------------
       
   742 //
       
   743 CNcnMsvSessionObserver::TNcnInboxEntryType
       
   744     CNcnMsvSessionObserver::CheckAndHandleSmsEntryL(
       
   745         CMsvEntry* aEntryToHandlePtr )
       
   746     {
       
   747     NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckAndHandleSmsEntryL"));
       
   748     
       
   749     // Check that the pointer is valid
       
   750     TNcnInboxEntryType ncnEntryType = EUnknown;
       
   751     if( aEntryToHandlePtr == NULL )
       
   752         {
       
   753         return ncnEntryType;
       
   754         }
       
   755 
       
   756     //We take the ownership of the aEntryToHandlePtr
       
   757     CleanupStack::PushL(aEntryToHandlePtr);
       
   758     
       
   759     // get session from session handler
       
   760     CMsvSession& msvSession = iModel->MsvSessionHandler().MsvSessionL();
       
   761     
       
   762     // And get a copy of the TMsvEntry through the CMsvEntry
       
   763     TMsvEntry entryToHandle = aEntryToHandlePtr->Entry();
       
   764 			
       
   765     //This registry holds details of the all the Client-side MTMs
       
   766     CClientMtmRegistry* mtmReg = CClientMtmRegistry::NewL( msvSession );
       
   767 	CleanupStack::PushL(mtmReg);
       
   768 
       
   769     //Client-side MTM object for the MTM specified by aMtmTypeUid
       
   770     CBaseMtm* clientMtm = NULL;
       
   771 
       
   772 	// Wait for messaging objects to become available
       
   773 	TBool clientSet = EFalse;
       
   774 	TBool entrySet = EFalse;
       
   775     for (TInt tries = 0; tries < KNcnMaxTries; tries++ )
       
   776 		{
       
   777 		if ( !clientSet )
       
   778 			{
       
   779 			TRAPD( err0, clientMtm = mtmReg->NewMtmL( KUidMsgTypeSMS ));
       
   780 			if ( err0 == KErrNone )
       
   781 				{
       
   782 				CleanupStack::PushL( clientMtm );
       
   783 				clientSet = ETrue;
       
   784 				}
       
   785 			else if (( err0 == KErrInUse ) && ( tries < KNcnMaxTries - 1 ))
       
   786 				{
       
   787 				NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver: CheckAndHandleSmsEntryL mtmReg->NewMtmL() leave %d"), err0 );
       
   788 				User::After( KNcnTryInterval ); // CSI: 92 # We must use sleep here before we next try
       
   789 				}
       
   790 			else
       
   791 				{
       
   792 				NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver: CheckAndHandleSmsEntryL << mtmReg->NewMtmL() leave %d"), err0 );
       
   793 				User::Leave( err0 );
       
   794 				}
       
   795 			}
       
   796 		if ( clientSet && !entrySet )
       
   797 			{
       
   798 			// in the stack we now have clientMtm, mtmReg and aEntryToHandlePtr
       
   799 			// we need to remove aEntryToHandlePtr
       
   800 			CleanupStack::Pop(clientMtm);
       
   801 			CleanupStack::Pop(mtmReg);		
       
   802 			CleanupStack::Pop(aEntryToHandlePtr);
       
   803 				
       
   804 			//Transfer ownership of the aEntryToHandlePtr to the clientMtm
       
   805 			TRAPD( err1, clientMtm->SetCurrentEntryL( aEntryToHandlePtr ));
       
   806 			
       
   807 			//Push the mtmReg and clientMtm back to stack
       
   808 			CleanupStack::PushL(mtmReg);
       
   809 			CleanupStack::PushL(clientMtm); //clientMtm is now responsible for the aEntryToHandlePtr
       
   810 				
       
   811 			if ( err1 == KErrNone )
       
   812 				{
       
   813 				entrySet = ETrue;
       
   814 				}
       
   815 			else if ( err1 == KErrInUse )
       
   816 				{
       
   817 				NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver: CheckAndHandleSmsEntryL clientMtm->SetCurrentEntryL() leave %d"), err1 );
       
   818 				User::After( KNcnTryInterval ); // CSI: 92 # We must use sleep here before we next try
       
   819 				}
       
   820 			else
       
   821 				{
       
   822 				NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver: CheckAndHandleSmsEntryL clientMtm->SetCurrentEntryL() leave %d"), err1 );
       
   823 				delete aEntryToHandlePtr; //Ownership was not transferred
       
   824 				User::Leave( err1 );
       
   825 				}
       
   826 			}
       
   827 		if ( clientSet && entrySet )
       
   828 			{
       
   829 			TRAPD( err2, clientMtm->LoadMessageL() );
       
   830 
       
   831 			if ( err2 == KErrNone )
       
   832 				{
       
   833 				break;
       
   834 				}
       
   835 			else if ( err2 == KErrInUse )
       
   836 				{
       
   837 				NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver: CheckAndHandleSmsEntryL clientMtm->LoadMessageL() leave %d"), err2 );
       
   838 				User::After( KNcnTryInterval ); // CSI: 92 # We must use sleep here before we next try
       
   839 			    }
       
   840 			else
       
   841 				{
       
   842 				NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver: CheckAndHandleSmsEntryL clientMtm->LoadMessageL() leave %d"), err2 );
       
   843 				User::Leave( err2 );
       
   844 				}
       
   845 			}
       
   846 		}
       
   847 	//Always at this point the cleanupstack contains:
       
   848 	//1) clientMtm
       
   849 	//2) mtmReg
       
   850 	//clientMtm also has ownership to aEntryToHandlePtr
       
   851 	
       
   852     // check for special types of message
       
   853     CSmsHeader& header = static_cast<CSmsClientMtm*>(clientMtm)->SmsHeader();
       
   854     CSmsPDU& pdu = header.Message().SmsPDU();
       
   855 
       
   856     TSmsDataCodingScheme::TSmsClass smsClass;
       
   857 
       
   858     NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver:CheckAndHandleSmsEntryL Message's PDU type: %d"), pdu.Type());
       
   859 
       
   860     // First we check if the sms is a delivery report and if so, handle it.
       
   861     if( pdu.Type() == CSmsPDU::ESmsStatusReport ) //test for delivery note
       
   862         {
       
   863         CSmsStatusReport* statusReport = static_cast<CSmsStatusReport*>(&pdu);
       
   864 
       
   865         if( statusReport->Status() ==
       
   866                 TSmsStatus::ESmsShortMessageReceivedBySME ||
       
   867             statusReport->Status() ==
       
   868                 TSmsStatus::ESmsShortMessageForwardedBySCToSMEButUnconfirmedBySC ||
       
   869             statusReport->Status() ==
       
   870                 TSmsStatus::ESmsShortMessageReplacedBySC )
       
   871             {
       
   872             
       
   873             // Message is reached the recipient
       
   874             iModel->NcnUI().ShowDeliveryNoteL( entryToHandle );
       
   875             ncnEntryType = EDeliveryReport;
       
   876             }
       
   877         else
       
   878             {
       
   879             // This means that the SMS has not yet reached the recipient.
       
   880             // Some problems in delivering.
       
   881             ncnEntryType = EDeliveryErrReport;
       
   882             }
       
   883         }
       
   884     // Then we check if the sms is a class 0 sms. If so, then we
       
   885     // launch the viewer
       
   886     else if( pdu.Class( smsClass ) ) //test for class 0 sms
       
   887         {
       
   888         if( smsClass == TSmsDataCodingScheme::ESmsClass0 )
       
   889             {
       
   890             // Class 0 SMS should be set invisible at this point
       
   891             entryToHandle.SetVisible( EFalse );
       
   892             aEntryToHandlePtr->ChangeL( entryToHandle );
       
   893 
       
   894             // Class 0 message can contain CHPS type indication bits,
       
   895             // so they must be checked
       
   896             ncnEntryType =
       
   897                 CheckForMessageWaitingL( *aEntryToHandlePtr, header );
       
   898 
       
   899             if( ncnEntryType != EMessageWaitingDiscardSetMessage &&
       
   900                 ncnEntryType != EMessageWaitingDiscardClearMessage )
       
   901                 {
       
   902                 // show message
       
   903                 iModel->NcnUI().ShowMessageL( entryToHandle );
       
   904                 ncnEntryType = EClass0SmsMessage;
       
   905                 }
       
   906             }
       
   907         else
       
   908             {
       
   909             ncnEntryType =
       
   910                 CheckForMessageWaitingL( *aEntryToHandlePtr, header );
       
   911             }
       
   912         }
       
   913     // Then we check the status bits of the message
       
   914     // (message waiting, cphs etc...)
       
   915     else
       
   916         {
       
   917         ncnEntryType =
       
   918                 CheckForMessageWaitingL( *aEntryToHandlePtr, header );
       
   919         }
       
   920 
       
   921     // If the message is to be deleted, then we do it here.
       
   922     if( ncnEntryType == EMessageWaitingDiscardSetMessage ||
       
   923         ncnEntryType == EMessageWaitingDiscardClearMessage ||
       
   924         ncnEntryType == EDeliveryReport ||
       
   925         ncnEntryType == EDeliveryErrReport )
       
   926         {
       
   927         // Delete entry        
       
   928         TRAPD( err, iInboxFolder->DeleteL( entryToHandle.Id() ) );
       
   929         NCN_RDEBUG_INT(_L("HandleNewChildrenL:CheckAndHandleSmsEntryL Trap error Id is: %d "), err );
       
   930 		if(err == KErrInUse)
       
   931 		{
       
   932 			entryToHandle.SetVisible( EFalse );
       
   933 			entryToHandle.SetInPreparation(ETrue);
       
   934 			TRAPD(err1,aEntryToHandlePtr->ChangeL( entryToHandle ));
       
   935 			NCN_RDEBUG_INT(_L("HandleNewChildrenL:CheckAndHandleSmsEntryL ChangeL Trap error1 Id is: %d "), err1 );
       
   936 			iUpdateNotifier = EFalse;
       
   937 			NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckAndHandleSmsEntryL Discard message: Try deleting again "));
       
   938 			//Entry is not yet released.. try Remove Entry
       
   939 			msvSession.RemoveEntry(entryToHandle.Id());
       
   940 		}  
       
   941 
       
   942         }
       
   943     else
       
   944         {
       
   945         iTelNumber = GetTelNumber( header.Message() );
       
   946         }
       
   947 
       
   948     // Now we have got the SMS header of the message. Next delete mtmReq
       
   949     // and clientMtm. Destroying clientMtm destroys
       
   950     // also the current entryFocused to so we must not
       
   951     // delete the entryToHandlePtr after this...
       
   952     CleanupStack::PopAndDestroy(2); // mtmReq, clientMtm
       
   953     return ncnEntryType;
       
   954     }
       
   955     
       
   956 // ---------------------------------------------------------
       
   957 // CNcnMsvSessionObserver::CheckForMessageWaitingL
       
   958 // Check if the sms is a message waiting indicator and
       
   959 // notify the system agent if it is.
       
   960 // ---------------------------------------------------------
       
   961 //
       
   962 CNcnMsvSessionObserver::TNcnInboxEntryType
       
   963     CNcnMsvSessionObserver::CheckForMessageWaitingL(
       
   964         CMsvEntry&      aEntry,
       
   965         CSmsHeader&    aHeader )
       
   966     {
       
   967     NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL"));
       
   968 
       
   969     CSmsPDU &pdu = aHeader.Message().SmsPDU();
       
   970 
       
   971     // First check if the User Data contains Special message
       
   972     // indications coded as specified in GSM 03.40 V7.4.0
       
   973     if( pdu.UserDataPresent() )
       
   974         {
       
   975         // handle user data
       
   976         TNcnInboxEntryType entryType = HandleSmsUserDataL( pdu.UserData() );
       
   977         
       
   978         // use type could be identified from user data
       
   979         // return it now
       
   980         if( entryType != EUnknown )
       
   981             {
       
   982             NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL, not EUnknown 1 <<"));
       
   983             return entryType;
       
   984             }
       
   985         }
       
   986 
       
   987     // if IndicationType() is called on a normal sms there is a panic,
       
   988     // so have to filter out wrong type of smses with the following tests
       
   989 
       
   990     if(!pdu.DataCodingSchemePresent())
       
   991         {
       
   992         NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL, ESmsMessage 1<<"));
       
   993         return ESmsMessage;
       
   994         }
       
   995 
       
   996     TInt bits7to4 = pdu.Bits7To4();
       
   997     TSmsDataCodingScheme::TSmsIndicationState indicationState =
       
   998         TSmsDataCodingScheme::ESmsIndicationInactive;
       
   999 
       
  1000     switch (bits7to4)
       
  1001         {
       
  1002         case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndication7Bit:
       
  1003         case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationUCS2:
       
  1004         case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationDiscardMessage:
       
  1005 
       
  1006            indicationState = pdu.IndicationState();
       
  1007 
       
  1008            if( indicationState != TSmsDataCodingScheme::ESmsIndicationActive &&
       
  1009                indicationState != TSmsDataCodingScheme::ESmsIndicationInactive )
       
  1010                 {
       
  1011                 NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL, ESmsMessage 2<<"));
       
  1012                 return ESmsMessage;
       
  1013                 }
       
  1014            break;
       
  1015 
       
  1016         default:
       
  1017             // Check for CPHS message waiting bits. If they are not
       
  1018             // present, we are dealing with normal sms message
       
  1019             CNcnMsvSessionObserver::TNcnInboxEntryType type =
       
  1020                 CheckForCPHSIndicationBitsL( aEntry, aHeader );
       
  1021 
       
  1022             if( type != EUnknown )
       
  1023                 {
       
  1024                 NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL, not EUnknown 2<<"));
       
  1025                 return type;
       
  1026                 }
       
  1027             NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL, ESmsMessage 3<<"));
       
  1028 
       
  1029             return ESmsMessage;
       
  1030         }
       
  1031 
       
  1032     // handle dcs indication
       
  1033     TBool indicatorSetMessage = HandleDCSIndicationL(
       
  1034         pdu.IndicationType(),
       
  1035         pdu.IndicationState() );
       
  1036 
       
  1037     if( bits7to4 == TSmsDataCodingScheme::
       
  1038             ESmsDCSMessageWaitingIndicationDiscardMessage &&
       
  1039             aHeader.Message().Buffer().Length() < 2 )
       
  1040         {
       
  1041         if( indicatorSetMessage )
       
  1042             {
       
  1043             NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL, EMessageWaitingDiscardSetMessage <<"));
       
  1044             return EMessageWaitingDiscardSetMessage;
       
  1045             }
       
  1046         else
       
  1047             {
       
  1048             NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL, EMessageWaitingDiscardClearMessage <<"));
       
  1049             return EMessageWaitingDiscardClearMessage;
       
  1050             }
       
  1051         }
       
  1052     NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL, EMessageWaitingStoreMessage <<"));
       
  1053     return EMessageWaitingStoreMessage;
       
  1054     }
       
  1055 
       
  1056 // ---------------------------------------------------------
       
  1057 // CNcnMsvSessionObserver::HandleDCSIndicationL
       
  1058 // ---------------------------------------------------------
       
  1059 //    
       
  1060 TBool CNcnMsvSessionObserver::HandleDCSIndicationL(
       
  1061     TSmsDataCodingScheme::TSmsIndicationType aIndicationType,
       
  1062     TSmsDataCodingScheme::TSmsIndicationState aIndicationState )
       
  1063     {
       
  1064     NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL >>") );
       
  1065     // amount of messages waiting set
       
  1066     TUint amount = 0;
       
  1067     
       
  1068     // determine indication type
       
  1069     switch( aIndicationType )
       
  1070         {
       
  1071         case TSmsDataCodingScheme::ESmsVoicemailMessageWaiting:
       
  1072             {            
       
  1073             if( aIndicationState == TSmsDataCodingScheme::ESmsIndicationActive )
       
  1074                 {
       
  1075                 NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL: voice mail active") );
       
  1076                 amount = CVoiceMailManager::EVMExistsButCountNotKnown;
       
  1077                 }
       
  1078             else
       
  1079             	{
       
  1080                 NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL: voice mail inactive") );            	
       
  1081             	amount = CVoiceMailManager::ENoVoiceMails;	
       
  1082             	}    
       
  1083                 
       
  1084             //DCS indications don't seem to have alternative line support
       
  1085             iVMManager.VMMessageReceived( MNcnMsgWaitingManager::ENcnMessageTypeVMLine1 , amount );
       
  1086             break;
       
  1087             }
       
  1088         case TSmsDataCodingScheme::ESmsFaxMessageWaiting:
       
  1089             {            
       
  1090             if( aIndicationState == TSmsDataCodingScheme::ESmsIndicationActive )
       
  1091                 {
       
  1092                 NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL: fax message active") );                
       
  1093                 amount = KNcnDefaultMessagesWaiting;
       
  1094                 }
       
  1095 			else
       
  1096 				{
       
  1097 				NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL: fax message inactive") );						
       
  1098 				}                
       
  1099                 
       
  1100             SetFaxMessagesWaiting( amount );
       
  1101             break;
       
  1102             }
       
  1103         case TSmsDataCodingScheme::ESmsElectronicMailMessageWaiting:
       
  1104             {
       
  1105             if( aIndicationState == TSmsDataCodingScheme::ESmsIndicationActive )
       
  1106                 {
       
  1107 				NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL: email message active") );                
       
  1108                 amount = KNcnDefaultMessagesWaiting;
       
  1109                 }
       
  1110 			else
       
  1111 				{
       
  1112 				NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL: email message inactive") );	
       
  1113 				}                
       
  1114                 
       
  1115             SetEMailMessagesWaiting( amount );
       
  1116             break;
       
  1117             }
       
  1118         case TSmsDataCodingScheme::ESmsFaxOtherMessageWaiting:
       
  1119             {            
       
  1120             if( aIndicationState == TSmsDataCodingScheme::ESmsIndicationActive )
       
  1121                 {
       
  1122 				NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL: other message active") );                
       
  1123                 amount = KNcnDefaultMessagesWaiting;
       
  1124                 }
       
  1125 			else
       
  1126 				{
       
  1127 				NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL: other message inactive") ); 					
       
  1128 				}                
       
  1129                 
       
  1130             SetOtherMessagesWaiting( amount );
       
  1131             break;            
       
  1132             }
       
  1133         default:
       
  1134             break;
       
  1135         }
       
  1136         
       
  1137     // return the indication set status
       
  1138     // baes on number of messages waiting
       
  1139     NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL <<") );
       
  1140     return ( amount != 0 );
       
  1141     }
       
  1142 
       
  1143 // ---------------------------------------------------------
       
  1144 // CNcnMsvSessionObserver::HandleSmsUserDataL
       
  1145 // ---------------------------------------------------------
       
  1146 //
       
  1147 CNcnMsvSessionObserver::TNcnInboxEntryType CNcnMsvSessionObserver::HandleSmsUserDataL(
       
  1148     const CSmsUserData& aUserData )
       
  1149     {
       
  1150     NCN_RDEBUG(_L("CNcnMsvSessionObserver::HandleSmsUserDataL <<"));    
       
  1151     // default to unknown
       
  1152     TNcnInboxEntryType entryType = EUnknown;
       
  1153     
       
  1154     // count data elements
       
  1155     TInt count = aUserData.NumInformationElements();
       
  1156                
       
  1157     // process each element
       
  1158     while( count-- )
       
  1159         {
       
  1160         // extract information element
       
  1161         CSmsInformationElement& informationElement =
       
  1162             aUserData.InformationElement(count);
       
  1163             
       
  1164         // if element is message indication
       
  1165         if ( informationElement.Identifier() ==
       
  1166             CSmsInformationElement::ESmsIEISpecialSMSMessageIndication )
       
  1167             {
       
  1168             //Determine which resource ID to use
       
  1169             const TDesC8& data = informationElement.Data();
       
  1170             
       
  1171             // extract message type
       
  1172             TUint8 messageType = data[0];
       
  1173             
       
  1174             // extract number of messages waiting
       
  1175             TUint8 messagesWaiting = data[1];
       
  1176 
       
  1177             // handle the element
       
  1178             HandleSpecialSMSMessageIndicationL( messageType, messagesWaiting );
       
  1179             
       
  1180             // Check the store/discard -information from IE, so that we
       
  1181             // know, what to do to message itself
       
  1182             if( count == 0 )
       
  1183                 {
       
  1184                 if ( messageType & KNcnStoreIndicator )
       
  1185                     {
       
  1186                     entryType = EMessageWaitingStoreMessage;
       
  1187                     }
       
  1188                 else
       
  1189                     {
       
  1190                     if( messagesWaiting )
       
  1191                         {
       
  1192                         entryType = EMessageWaitingDiscardSetMessage;
       
  1193                         }
       
  1194                     else
       
  1195                         {
       
  1196                         entryType = EMessageWaitingDiscardClearMessage;
       
  1197                         }
       
  1198                     }
       
  1199                 }
       
  1200             }
       
  1201         }
       
  1202         
       
  1203     // return the entry type        
       
  1204     NCN_RDEBUG(_L("CNcnMsvSessionObserver::HandleSmsUserDataL <<"));    
       
  1205     return entryType;
       
  1206     }
       
  1207     
       
  1208 // ---------------------------------------------------------
       
  1209 // CNcnMsvSessionObserver::HandleSpecialSMSMessageIndicationL
       
  1210 // ---------------------------------------------------------
       
  1211 //
       
  1212 void CNcnMsvSessionObserver::HandleSpecialSMSMessageIndicationL(
       
  1213     TUint8 aMessageType,
       
  1214     TUint8 aMessagesWaiting )
       
  1215     {
       
  1216     NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleSpecialSMSMessageIndicationL") );
       
  1217     // Check from current message IEI, which type of indicator is provided
       
  1218     // message type is masked with 01111111
       
  1219     switch ( aMessageType & TSmsUtilities::ESpecialMessageTypeMask )
       
  1220         {
       
  1221         case TSmsUtilities::EVoiceMessageWaiting:
       
  1222             //Special SMS indications don't seem to have alternative line support
       
  1223             NCN_RDEBUG_INT( _L("CNcnMsvSessionObserver::HandleSpecialSMSMessageIndicationL: voice mails on line: %d"), aMessagesWaiting );
       
  1224        		iVMManager.VMMessageReceived( MNcnMsgWaitingManager::ENcnMessageTypeVMLine1, aMessagesWaiting );
       
  1225             break;
       
  1226 
       
  1227         case TSmsUtilities::EFaxMessageWaiting:
       
  1228             NCN_RDEBUG_INT( _L("CNcnMsvSessionObserver::HandleSpecialSMSMessageIndicationL: fax messages waiting: %d"), aMessagesWaiting );        
       
  1229             SetFaxMessagesWaiting( aMessagesWaiting );
       
  1230             break;
       
  1231             
       
  1232         case TSmsUtilities::EEmailMessageWaiting:
       
  1233             NCN_RDEBUG_INT( _L("CNcnMsvSessionObserver::HandleSpecialSMSMessageIndicationL: emails waiting: %d"), aMessagesWaiting );        
       
  1234             SetEMailMessagesWaiting( aMessagesWaiting );
       
  1235             break;
       
  1236             
       
  1237         default: // EOtherMessageWaiting
       
  1238             NCN_RDEBUG_INT( _L("CNcnMsvSessionObserver::HandleSpecialSMSMessageIndicationL: other messages waiting: %d"), aMessagesWaiting );        
       
  1239             SetOtherMessagesWaiting( aMessagesWaiting );
       
  1240             break;
       
  1241         }        
       
  1242     NCN_RDEBUG(_L("CNcnMsvSessionObserver::HandleSpecialSMSMessageIndicationL <<"));    
       
  1243     }
       
  1244     
       
  1245 // ---------------------------------------------------------
       
  1246 // CNcnMsvSessionObserver::CheckForCPHSIndicationBitsL
       
  1247 // Check if the sms is a CPHS message waiting indicator and
       
  1248 // notify the system agent if it is.
       
  1249 // ---------------------------------------------------------
       
  1250 //
       
  1251 CNcnMsvSessionObserver::TNcnInboxEntryType
       
  1252     CNcnMsvSessionObserver::CheckForCPHSIndicationBitsL(
       
  1253         CMsvEntry&      aEntry,
       
  1254         CSmsHeader&     aHeader )
       
  1255     {
       
  1256     NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForCPHSIndicationBitsL >>"));    
       
  1257     // CPHS Implementation of message waiting indicator (CPHS Phase 2)
       
  1258     CSmsPDU &pdu = aHeader.Message().SmsPDU();
       
  1259     TGsmSmsTelNumber address;
       
  1260     pdu.ParsedToFromAddress(address);
       
  1261 
       
  1262     // we can't get the npi from the address.
       
  1263     if( IsCphsMessage( address ) )// x000 000x constant value
       
  1264         {
       
  1265 		EmptyCphsMessageAddressL( aEntry, aHeader );
       
  1266 
       
  1267         // Check the bits on first character of telephone number
       
  1268         TInt indicatorSetMessage =
       
  1269             HandleCphsMessageL( address.iTelNumber[KNcnCphsFirstChar] );
       
  1270 
       
  1271         // Now check if the SMS is a store message or a
       
  1272         // discard message. The SMS is a store message
       
  1273         // if there is only one byte present and the byte
       
  1274         // has a value 01000000. Fetch the user data...
       
  1275         if( pdu.UserDataPresent() )
       
  1276             {
       
  1277             CSmsBufferBase &buffer = aHeader.Message().Buffer();
       
  1278             TBuf<1> oneChar(KEmptyChar);
       
  1279 
       
  1280             buffer.Extract(oneChar, 0, 1);
       
  1281             if( buffer.Length() == 1 && oneChar == KSpaceChar )
       
  1282                 {
       
  1283                 if( indicatorSetMessage )
       
  1284                     {
       
  1285                     return EMessageWaitingDiscardSetMessage;
       
  1286                     }
       
  1287                 else
       
  1288                     {
       
  1289                     return EMessageWaitingDiscardClearMessage;
       
  1290                     }
       
  1291                 }
       
  1292             else
       
  1293                 {
       
  1294                 return EMessageWaitingStoreMessage;
       
  1295                 }
       
  1296             }
       
  1297         else if( indicatorSetMessage )
       
  1298             {
       
  1299             return EMessageWaitingDiscardSetMessage;
       
  1300             }
       
  1301         else
       
  1302             {
       
  1303             return EMessageWaitingDiscardClearMessage;
       
  1304             }
       
  1305         }
       
  1306     NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForCPHSIndicationBitsL <<"));    
       
  1307     return EUnknown;
       
  1308     }
       
  1309 
       
  1310 // ---------------------------------------------------------
       
  1311 // CNcnMsvSessionObserver::EmptyCphsMessageAddress
       
  1312 // Empties the sender address from a Cphs message.
       
  1313 // ---------------------------------------------------------
       
  1314 //
       
  1315 void CNcnMsvSessionObserver::EmptyCphsMessageAddressL(
       
  1316         CMsvEntry&      aEntry,
       
  1317         CSmsHeader&     aHeader )
       
  1318 	{
       
  1319     NCN_RDEBUG(_L("CNcnMsvSessionObserver::EmptyCphsMessageAddressL >>"));
       
  1320     TMsvEntry tentry = aEntry.Entry();
       
  1321     TInt wasLocked = tentry.ReadOnly();
       
  1322 
       
  1323 	if( wasLocked )
       
  1324 		{
       
  1325 		tentry.SetReadOnly( EFalse ); // unlock the entry for writing
       
  1326 		}
       
  1327 
       
  1328     // Empty the iDetails data
       
  1329     tentry.iDetails.Set( KNullDesC );
       
  1330     // Commit the change
       
  1331     aEntry.ChangeL( tentry );
       
  1332     // Empty the real adress
       
  1333     aHeader.SetFromAddressL( KNullDesC );
       
  1334     // Store the header
       
  1335     CMsvStore* store = aEntry.EditStoreL();
       
  1336     CleanupStack::PushL(store);
       
  1337     aHeader.StoreL( *store );
       
  1338     store->CommitL();
       
  1339     CleanupStack::PopAndDestroy(store);
       
  1340 
       
  1341     // Setting the old state back
       
  1342     tentry.SetReadOnly( wasLocked );
       
  1343     NCN_RDEBUG(_L("CNcnMsvSessionObserver::EmptyCphsMessageAddressL <<"));
       
  1344     }
       
  1345 
       
  1346 // ---------------------------------------------------------
       
  1347 //  CNcnMsvSessionObserver::IsCphsMessage
       
  1348 //  Runs CPHS-checks for originator address field to determine
       
  1349 //  if message contains voicemail indication
       
  1350 // ---------------------------------------------------------
       
  1351 //
       
  1352 TBool CNcnMsvSessionObserver::IsCphsMessage(
       
  1353     const TGsmSmsTelNumber& aOrigAddress ) const
       
  1354     {
       
  1355     // Determine if the length of TP-OA is qualifies for CPHS indication
       
  1356     if( aOrigAddress.iTelNumber.Length() != KNcnCphsAddressLength )
       
  1357         {
       
  1358         // Address length is wrong, return immediately
       
  1359         return EFalse;
       
  1360         }
       
  1361 
       
  1362     // Get the Type of Address
       
  1363     TGsmSmsTypeOfNumber oaTON = aOrigAddress.iTypeOfAddress.TON();
       
  1364 
       
  1365     // Get first two digits of phonenumber
       
  1366     TUint oaDigits1 = aOrigAddress.iTelNumber[KNcnCphsFirstChar];
       
  1367 
       
  1368     // Get second two digits of phonenumber
       
  1369     TUint oaDigits2 = aOrigAddress.iTelNumber[KNcnCphsSecondChar];
       
  1370 
       
  1371     // Determine if Type of Address has the constant CPHS values (11010000)
       
  1372     TBool cphsTon = ( oaTON == EGsmSmsTONAlphaNumeric );
       
  1373 
       
  1374     // Determine if first two digits contains the voicemail
       
  1375     // indicator (bits 4..2) and in last two digits,
       
  1376     // bits 7 to 2 are all zeros
       
  1377     TBool cphsType = ( oaDigits1 & KNcnCphsConstantMask ) == KNcnCphsFirstInfo;
       
  1378     TBool cphsInd = ( oaDigits2 & KNcnCphsConstantMask ) == KNcnCphsSecondInfo;
       
  1379 
       
  1380     // Return the combined result of tests for final decision
       
  1381     return ( cphsTon && cphsType && cphsInd );
       
  1382     }
       
  1383 
       
  1384 // ---------------------------------------------------------
       
  1385 //  CNcnMsvSessionObserver::HandleCphsMessage
       
  1386 //  Handles CPHS-voicemail notifications
       
  1387 // ---------------------------------------------------------
       
  1388 //
       
  1389 TInt CNcnMsvSessionObserver::HandleCphsMessageL( const TUint aFirstOctet )
       
  1390     {
       
  1391     NCN_RDEBUG(_L("CNcnMsvSessionObserver::HandleCphsMessageL >>"));
       
  1392     // Get if set or clear message
       
  1393     TBool typeSetMessage = aFirstOctet & KNcnCphsSet;
       
  1394     TUint lineInfo = aFirstOctet & KNcnCphsLineMask;
       
  1395 
       
  1396     // Make sure the fields are correctly set
       
  1397     if( lineInfo == KNcnCphsVmiLine1 ||
       
  1398         lineInfo == KNcnCphsVmiLine2 )
       
  1399         {                  
       
  1400     	//The message is a SET message in line 1
       
  1401         if( typeSetMessage == 1 && lineInfo == KNcnCphsVmiLine1 )
       
  1402             {
       
  1403             iVMManager.VMMessageReceived( MNcnMsgWaitingManager::ENcnMessageTypeVMLine1, CVoiceMailManager::EVMExistsButCountNotKnown );
       
  1404             }
       
  1405             
       
  1406       	//The message is a CLEAR message in line 1
       
  1407         else if( typeSetMessage != 1 && lineInfo == KNcnCphsVmiLine1 )
       
  1408             {
       
  1409             iVMManager.VMMessageReceived( MNcnMsgWaitingManager::ENcnMessageTypeVMLine1, CVoiceMailManager::ENoVoiceMails );
       
  1410             }
       
  1411                        
       
  1412      	//The message is a SET message in line 2       
       
  1413         else if( typeSetMessage == 1 && lineInfo == KNcnCphsVmiLine2 )
       
  1414             {
       
  1415             iVMManager.VMMessageReceived( MNcnMsgWaitingManager::ENcnMessageTypeVMLine2, CVoiceMailManager::EVMExistsButCountNotKnown );
       
  1416             }
       
  1417             
       
  1418      	//The message is a CLEAR message in line 2       
       
  1419         else if( typeSetMessage != 1 && lineInfo == KNcnCphsVmiLine2 )
       
  1420             {
       
  1421             iVMManager.VMMessageReceived( MNcnMsgWaitingManager::ENcnMessageTypeVMLine2, CVoiceMailManager::ENoVoiceMails );
       
  1422             }   
       
  1423         }
       
  1424 
       
  1425     // Return EFalse, when clear message
       
  1426     NCN_RDEBUG(_L("CNcnMsvSessionObserver::HandleCphsMessageL <<"));
       
  1427     return typeSetMessage;
       
  1428     }
       
  1429 
       
  1430 // ---------------------------------------------------------
       
  1431 //  CNcnMsvSessionObserver::GetTelNumber
       
  1432 // ---------------------------------------------------------
       
  1433 //
       
  1434 TGsmSmsTelNumber CNcnMsvSessionObserver::GetTelNumber(
       
  1435     const CSmsMessage& aMessage ) const
       
  1436     {
       
  1437     // Get SMS PDU
       
  1438     const CSmsPDU &pdu = aMessage.SmsPDU();
       
  1439 
       
  1440     // Prepare address and get address from header
       
  1441     TGsmSmsTelNumber address;
       
  1442     pdu.ParsedToFromAddress( address );
       
  1443 
       
  1444     return address;
       
  1445     }
       
  1446 
       
  1447 // ---------------------------------------------------------
       
  1448 //  CNcnMsvSessionObserver::CheckAndLaunchMCEL
       
  1449 // ---------------------------------------------------------
       
  1450 //
       
  1451 void CNcnMsvSessionObserver::CheckAndLaunchMCEL(
       
  1452     const TMsvEntry& aEntry )
       
  1453     {
       
  1454     NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckAndLaunchMCEL >>"));
       
  1455     // get session from session handler
       
  1456     CMsvSession& msvSession = iModel->MsvSessionHandler().MsvSessionL();
       
  1457     
       
  1458     TBuf<CTelephony::KMaxTelNumberSize> number;
       
  1459 	TInt err = iModel->GetPSString(
       
  1460 		KPSUidTelRemotePartyInformation, KTelCLINumber, number );
       
  1461 
       
  1462     if( err == KErrNone )
       
  1463         {
       
  1464         NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::CheckAndLaunchMCEL: CLI number access successful, telnumber: %s"), number.PtrZ() );
       
  1465 
       
  1466         // Get match value from Shared Data
       
  1467         TInt sdMatchValue = KNcnMatchDefault;
       
  1468 		err = iModel->GetCRInteger(
       
  1469 			KCRUidTelConfiguration, KTelMatchDigits, sdMatchValue );
       
  1470 
       
  1471         if( err == KErrNone )
       
  1472             {
       
  1473             if ( sdMatchValue < KNcnMatchMin || sdMatchValue > KNcnMatchMax )
       
  1474                 {
       
  1475                 sdMatchValue = KNcnMatchDefault;
       
  1476                 }
       
  1477             }
       
  1478 
       
  1479         // Compare arrived message number/ender to the possible active phonenumber.
       
  1480         // Notice, that numbers can be on formats like 35840xxx and 040xxx,
       
  1481 		// so rightmost numbers have to be compared.
       
  1482 		if( number.Length() != 0 )
       
  1483 			{
       
  1484 			TBool match = EFalse;
       
  1485 			if( aEntry.iMtm == KUidMsgTypeMultimedia )
       
  1486 				{
       
  1487 				// Get MMS sender information
       
  1488 				CClientMtmRegistry* clientMtmRegistry =
       
  1489 				    CClientMtmRegistry::NewL( msvSession );
       
  1490 				CleanupStack::PushL( clientMtmRegistry );
       
  1491 				CMmsClientMtm* mMsClient = static_cast< CMmsClientMtm* >
       
  1492 				    ( clientMtmRegistry->NewMtmL( KUidMsgTypeMultimedia ) );
       
  1493 				CleanupStack::PushL( mMsClient );
       
  1494 				mMsClient->SwitchCurrentEntryL( aEntry.Id() );
       
  1495 				mMsClient->LoadMessageL();
       
  1496 				const TPtrC sender = mMsClient->Sender();
       
  1497 				NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::CheckAndLaunchMCEL: MMS sender: %s"), sender.Ptr() );
       
  1498 				match = ( sender.Right( sdMatchValue ) == number.Right( sdMatchValue ) );
       
  1499 				CleanupStack::PopAndDestroy( 2, clientMtmRegistry );    // mMsClient, clientMtmRegistry
       
  1500 				}
       
  1501 			else
       
  1502 				{
       
  1503 				// Get SMS sender information
       
  1504 				const TPtrC sender = iTelNumber.iTelNumber;
       
  1505 				NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::CheckAndLaunchMCEL: SMS number: %s"), iTelNumber.iTelNumber.PtrZ() );
       
  1506 				match = ( sender.Right( sdMatchValue ) == number.Right( sdMatchValue ) );
       
  1507 				}
       
  1508 			
       
  1509 			//Get the autolock status
       
  1510 			TInt autoLockStatus = CheckAutoLockStatus();
       
  1511 			
       
  1512 			NCN_RDEBUG_INT(_L("CheckAndLaunchMCEL: number match result = %d"), match );
       
  1513         	NCN_RDEBUG_INT(_L("CheckAndLaunchMCEL: autolockStatus = %d"), autoLockStatus );
       
  1514         
       
  1515 			if ( match && autoLockStatus != 1)
       
  1516 			    {
       
  1517 			    // open message
       
  1518 			    iModel->NcnUI().OpenMessageL( aEntry );
       
  1519 				}
       
  1520             }
       
  1521         }
       
  1522       NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckAndLaunchMCEL <<"));
       
  1523     }
       
  1524 
       
  1525 // ---------------------------------------------------------
       
  1526 //  CNcnMsvSessionObserver::SetFaxMessagesWaiting
       
  1527 // ---------------------------------------------------------
       
  1528 //         
       
  1529 void CNcnMsvSessionObserver::SetFaxMessagesWaiting( TUint aAmount )
       
  1530     {
       
  1531 	TBool enable = ( aAmount > 0 ) ? ETrue : EFalse;
       
  1532 	iModel->MsgWaitingManager().SetMessageCount( MNcnMsgWaitingManager::ENcnMessageTypeFax, aAmount, enable );				
       
  1533     }
       
  1534          
       
  1535 // ---------------------------------------------------------
       
  1536 //  CNcnMsvSessionObserver::SetEMailMessagesWaiting
       
  1537 // ---------------------------------------------------------
       
  1538 //
       
  1539 void CNcnMsvSessionObserver::SetEMailMessagesWaiting( TUint aAmount )
       
  1540     {
       
  1541 /*    
       
  1542     // default to messages waiting    
       
  1543     TUint value = KNcnNewEmail;
       
  1544                 
       
  1545     // change the default if there are now messages waiting
       
  1546     if( !aAmount )
       
  1547         {
       
  1548         value = KNcnNoNewEmail;
       
  1549         }
       
  1550 
       
  1551     // update key value
       
  1552 	iModel->NotifyPublishAndSubscribe(
       
  1553 			KNcnNewEmailCategory, KNcnNewEmailStatus, value );   
       
  1554 			
       
  1555 	// Store it as indicator
       
  1556 	iModel->StoreIndicatorStatus( KNcnNewEmailStatus, value );
       
  1557 */
       
  1558 
       
  1559 	TBool enable = ( aAmount > 0 ) ? ETrue : EFalse;
       
  1560 	iModel->MsgWaitingManager().SetMessageCount( MNcnMsgWaitingManager::ENcnMessageTypeEmail, aAmount, enable );	
       
  1561     }
       
  1562 
       
  1563 // ---------------------------------------------------------
       
  1564 //  CNcnMsvSessionObserver::SetOtherMessagesWaiting
       
  1565 // ---------------------------------------------------------
       
  1566 //         
       
  1567 void CNcnMsvSessionObserver::SetOtherMessagesWaiting( TUint aAmount )
       
  1568     {
       
  1569 	TBool enable = ( aAmount > 0 ) ? ETrue : EFalse;
       
  1570 	iModel->MsgWaitingManager().SetMessageCount( MNcnMsgWaitingManager::ENcnMessageTypeOther, aAmount, enable );		
       
  1571     }
       
  1572 
       
  1573 // ---------------------------------------------------------
       
  1574 //  CNcnMsvSessionObserver::CheckAutoLockStatus
       
  1575 // ---------------------------------------------------------
       
  1576 //               
       
  1577 TInt CNcnMsvSessionObserver::CheckAutoLockStatus()
       
  1578 	{
       
  1579 	//Get the lock status from Central Repository
       
  1580     TInt lockStatus(KErrNotFound);
       
  1581     NCN_RDEBUG(_L("CNcnMsvSessionObserver: CheckAutoLockStatus >>"));
       
  1582     CRepository* settingsRepository(NULL);
       
  1583     TRAPD(err, settingsRepository = CRepository::NewL(KCRUidSecuritySettings));
       
  1584     NCN_RDEBUG_INT(_L("CheckAndLaunchMCEL: CRepository::NewL err = %d"), err );
       
  1585     
       
  1586     if (err == KErrNone)
       
  1587         {
       
  1588         err = settingsRepository->Get(KSettingsAutolockStatus, lockStatus);
       
  1589         NCN_RDEBUG_INT(_L("CheckAndLaunchMCEL: lockStatus = %d"), lockStatus );
       
  1590         }
       
  1591                     
       
  1592     //Cleanup   
       
  1593     delete settingsRepository;
       
  1594     NCN_RDEBUG(_L("CNcnMsvSessionObserver: CheckAutoLockStatus <<"));
       
  1595     return lockStatus;		
       
  1596 	}
       
  1597 
       
  1598 // ---------------------------------------------------------
       
  1599 // CNcnMsvSessionObserver::IsUnread
       
  1600 // Check if entry is read or unread. Uses iUnreadMessages array.
       
  1601 // ---------------------------------------------------------
       
  1602 //	
       
  1603 TBool CNcnMsvSessionObserver::IsUnread(const TMsvEntry& aEntry)
       
  1604 	{
       
  1605 	if( iUnreadMessages->Find( aEntry.Id() ) != KErrNotFound )
       
  1606 		{
       
  1607 		//NCN_RDEBUG_INT( _L("CNcnMsvSessionObserver::CheckIfUnread: message (TMsvId %d) is unread"), aEntry.Id() );
       
  1608 		return ETrue;				
       
  1609 		}
       
  1610 	else
       
  1611 		{
       
  1612 		//NCN_RDEBUG_INT( _L("CNcnMsvSessionObserver::CheckIfUnread: message (TMsvId %d) is read"), aEntry.Id() );
       
  1613 		return EFalse;
       
  1614 		}			
       
  1615 
       
  1616 	}
       
  1617 	
       
  1618 // ---------------------------------------------------------
       
  1619 // CNcnMsvSessionObserver::InitUnreadMessagesArrayL
       
  1620 // This method is called only once during phone boot.
       
  1621 // Its purpose is to add all unread and visible messages
       
  1622 // in Inbox to iUnreadMessages array. This means that
       
  1623 // those entries are treated as new and unread eventhough
       
  1624 // message might have been read and marked again as unread
       
  1625 // before the boot. 
       
  1626 // ---------------------------------------------------------
       
  1627 //	
       
  1628 void CNcnMsvSessionObserver::InitUnreadMessagesArrayL()
       
  1629     {
       
  1630     // get session from session handler
       
  1631     CMsvSession& msvSession = iModel->MsvSessionHandler().MsvSessionL();
       
  1632     
       
  1633     NCN_RDEBUG( _L("CNcnMsvSessionObserver::InitUnreadMessagesArrayL") );
       
  1634     
       
  1635     // Check how many unread messages there are in the In-box.
       
  1636     const TInt itemCount = iInboxFolder->Count();
       
  1637     NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::InitUnreadMessagesArrayL [%d]"), itemCount );
       
  1638     TInt numberOfUnreadMessages = 0; // Note, This value only for logging purpose
       
  1639     
       
  1640     for( TInt index = 0; index < itemCount; index++ )
       
  1641         {
       
  1642         const TMsvEntry entry = (*iInboxFolder)[index];
       
  1643 
       
  1644         if( entry.iType.iUid == KUidMsvMessageEntryValue && 
       
  1645         	entry.Visible() &&
       
  1646         	entry.Unread() )
       
  1647             {
       
  1648             TInt err = iUnreadMessages->Append( entry.Id() );
       
  1649             if ( err )
       
  1650          	    {
       
  1651          	    NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::InitUnreadMessagesArrayL - APPEND ERROR %d!"), err );
       
  1652          	    }
       
  1653             ++numberOfUnreadMessages;
       
  1654             }
       
  1655         }
       
  1656     
       
  1657     NCN_RDEBUG_INT( _L( "CNcnMsvSessionObserver::InitUnreadMessagesArrayL \
       
  1658         :%d" ), numberOfUnreadMessages );
       
  1659         
       
  1660     NCN_RDEBUG( _L("CNcnMsvSessionObserver::InitUnreadMessagesArrayL <<") );
       
  1661     }
       
  1662 
       
  1663 // ---------------------------------------------------------
       
  1664 //  CNcnMsvSessionObserver::HandleMsvMediaChangedL
       
  1665 // ---------------------------------------------------------
       
  1666 //
       
  1667 void CNcnMsvSessionObserver::HandleMsvMediaChangedL( const TDriveNumber& /*aDriveNumber*/ )
       
  1668     {
       
  1669 	NCN_RDEBUG(_L("CNcnMsvSessionObserver::HandleMsvMediaChangedL >> <<" ));
       
  1670     }
       
  1671 
       
  1672 // ---------------------------------------------------------
       
  1673 //  CNcnMsvSessionObserver::UpdateInboxDataNotifiersL
       
  1674 // ---------------------------------------------------------
       
  1675 //
       
  1676 void CNcnMsvSessionObserver::UpdateInboxDataNotifiersL()
       
  1677     {
       
  1678     TInt unreadMessages = 0;
       
  1679     TInt notListenedAudioMessages = 0;
       
  1680     CheckAmountOfUnreadMessagesInInboxL( unreadMessages, notListenedAudioMessages);
       
  1681     
       
  1682     iModel->NcnNotifier().SetNotification(
       
  1683 		        MNcnNotifier::ENcnMessagesNotification,
       
  1684 		        unreadMessages );
       
  1685 		        
       
  1686 	if( iModel->IsSupported( KNcnAudioMessaging ) )
       
  1687 		{
       
  1688 		iModel->NcnNotifier().SetNotification( 
       
  1689     		MNcnNotifier::ENcnAudioMessagesNotification,
       
  1690     		notListenedAudioMessages );
       
  1691 		}
       
  1692     }
       
  1693              
       
  1694 // ---------------------------------------------------------
       
  1695 //  CNcnMsvSessionObserver::PrintEntryDebugInformation
       
  1696 // ---------------------------------------------------------
       
  1697 //
       
  1698 #ifdef _DEBUG
       
  1699 void CNcnMsvSessionObserver::PrintEntryDebugInformation(const TMsvEntry&  aEntryToHandle)
       
  1700 	{
       
  1701 	NCN_RDEBUG(_L(" *** MESSAGE ANALYZE START ***" ));
       
  1702 
       
  1703 	NCN_RDEBUG(_L(" * DATA *" ));
       
  1704     NCN_RDEBUG_INT(_L(" MSG: Service ID = %d"), aEntryToHandle.iServiceId );
       
  1705     NCN_RDEBUG_INT(_L(" MSG: Related ID = %d"), aEntryToHandle.iRelatedId );
       
  1706     NCN_RDEBUG_INT(_L(" MSG: Type = %d"), aEntryToHandle.iType );
       
  1707     NCN_RDEBUG_INT(_L(" MSG: MTM = %d"), aEntryToHandle.iMtm );
       
  1708     NCN_RDEBUG_INT(_L(" MSG: Date = %d"), aEntryToHandle.iDate.Int64() );
       
  1709     NCN_RDEBUG_INT(_L(" MSG: Size = %d"), aEntryToHandle.iSize );
       
  1710     NCN_RDEBUG_INT(_L(" MSG: Error = %d"), aEntryToHandle.iError );
       
  1711 	NCN_RDEBUG_INT(_L(" MSG: BioType = %d"), aEntryToHandle.iBioType );
       
  1712 	NCN_RDEBUG_INT(_L(" MSG: Data 1 = %d"), aEntryToHandle.iMtmData1 );
       
  1713 	NCN_RDEBUG_INT(_L(" MSG: Data 2 = %d"), aEntryToHandle.iMtmData2 );
       
  1714 	NCN_RDEBUG_INT(_L(" MSG: Data 3 = %d"), aEntryToHandle.iMtmData3 );
       
  1715 
       
  1716 	NCN_RDEBUG(_L(" * STATES *" ));
       
  1717 
       
  1718 	NCN_RDEBUG_INT(_L(" MSG: Owner( %d )"), aEntryToHandle.Owner() );
       
  1719 	NCN_RDEBUG_INT(_L(" MSG: Deleted( %d )"), aEntryToHandle.Deleted() );
       
  1720 	NCN_RDEBUG_INT(_L(" MSG: Complete( %d )"), aEntryToHandle.Complete() );
       
  1721 	NCN_RDEBUG_INT(_L(" MSG: New( %d )"), aEntryToHandle.New() );
       
  1722 	NCN_RDEBUG_INT(_L(" MSG: Unread( %d )"), aEntryToHandle.Unread() );
       
  1723 	NCN_RDEBUG_INT(_L(" MSG: Failed( %d )"), aEntryToHandle.Failed() );
       
  1724 	NCN_RDEBUG_INT(_L(" MSG: Operation( %d )"), aEntryToHandle.Operation() );
       
  1725 	NCN_RDEBUG_INT(_L(" MSG: Visible( %d )"), aEntryToHandle.Visible() );
       
  1726 	NCN_RDEBUG_INT(_L(" MSG: Multiple Recipients( %d )"), aEntryToHandle.MultipleRecipients() );
       
  1727 	NCN_RDEBUG_INT(_L(" MSG: ReadOnly( %d )"), aEntryToHandle.ReadOnly() );
       
  1728 	NCN_RDEBUG_INT(_L(" MSG: Standard Folder( %d )"), aEntryToHandle.StandardFolder() );
       
  1729 	NCN_RDEBUG_INT(_L(" MSG: Attachment( %d )"), aEntryToHandle.Attachment() );
       
  1730 	NCN_RDEBUG_INT(_L(" MSG: Connected( %d )"), aEntryToHandle.Connected() );
       
  1731 	NCN_RDEBUG_INT(_L(" MSG: In Preparation( %d )"), aEntryToHandle.InPreparation() );
       
  1732 	NCN_RDEBUG_INT(_L(" MSG: Off peak( %d )"), aEntryToHandle.OffPeak() );
       
  1733 	NCN_RDEBUG_INT(_L(" MSG: Scheduled( %d )"), aEntryToHandle.Scheduled() );
       
  1734 	NCN_RDEBUG_INT(_L(" MSG: Pending Delete( %d )"), aEntryToHandle.PendingDelete() );
       
  1735 
       
  1736 	NCN_RDEBUG(_L(" *** MESSAGE ANALYZE END ***" ));		
       
  1737 	}
       
  1738 #endif // _DEBUG
       
  1739 
       
  1740 // End of file