messagingappbase/ncnlist/src/NcnMsvSessionObserver.cpp
branchRCL_3
changeset 60 7fdbb852d323
equal deleted inserted replaced
57:ebe688cedc25 60:7fdbb852d323
       
     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 #ifdef _DEBUG
       
   935 			TRAPD(TrapError,aEntryToHandlePtr->ChangeL( entryToHandle ));
       
   936 			NCN_RDEBUG_INT(_L("HandleNewChildrenL:CheckAndHandleSmsEntryL ChangeL Trap error1 Id is: %d "), TrapError );
       
   937 #else
       
   938 			TRAP_IGNORE(aEntryToHandlePtr->ChangeL( entryToHandle ));
       
   939 #endif			
       
   940 			iUpdateNotifier = EFalse;
       
   941 			NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckAndHandleSmsEntryL Discard message: Try deleting again "));
       
   942 			//Entry is not yet released.. try Remove Entry
       
   943 			msvSession.RemoveEntry(entryToHandle.Id());
       
   944 		}  
       
   945 
       
   946         }
       
   947     else
       
   948         {
       
   949         iTelNumber = GetTelNumber( header.Message() );
       
   950         }
       
   951 
       
   952     // Now we have got the SMS header of the message. Next delete mtmReq
       
   953     // and clientMtm. Destroying clientMtm destroys
       
   954     // also the current entryFocused to so we must not
       
   955     // delete the entryToHandlePtr after this...
       
   956     CleanupStack::PopAndDestroy(2); // mtmReq, clientMtm
       
   957     return ncnEntryType;
       
   958     }
       
   959     
       
   960 // ---------------------------------------------------------
       
   961 // CNcnMsvSessionObserver::CheckForMessageWaitingL
       
   962 // Check if the sms is a message waiting indicator and
       
   963 // notify the system agent if it is.
       
   964 // ---------------------------------------------------------
       
   965 //
       
   966 CNcnMsvSessionObserver::TNcnInboxEntryType
       
   967     CNcnMsvSessionObserver::CheckForMessageWaitingL(
       
   968         CMsvEntry&      aEntry,
       
   969         CSmsHeader&    aHeader )
       
   970     {
       
   971     NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL"));
       
   972 
       
   973     CSmsPDU &pdu = aHeader.Message().SmsPDU();
       
   974 
       
   975     // First check if the User Data contains Special message
       
   976     // indications coded as specified in GSM 03.40 V7.4.0
       
   977     if( pdu.UserDataPresent() )
       
   978         {
       
   979         // handle user data
       
   980         TNcnInboxEntryType entryType = HandleSmsUserDataL( pdu.UserData() );
       
   981         
       
   982         // use type could be identified from user data
       
   983         // return it now
       
   984         if( entryType != EUnknown )
       
   985             {
       
   986             NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL, not EUnknown 1 <<"));
       
   987             return entryType;
       
   988             }
       
   989         }
       
   990 
       
   991     // if IndicationType() is called on a normal sms there is a panic,
       
   992     // so have to filter out wrong type of smses with the following tests
       
   993 
       
   994     if(!pdu.DataCodingSchemePresent())
       
   995         {
       
   996         NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL, ESmsMessage 1<<"));
       
   997         return ESmsMessage;
       
   998         }
       
   999 
       
  1000     TInt bits7to4 = pdu.Bits7To4();
       
  1001     TSmsDataCodingScheme::TSmsIndicationState indicationState =
       
  1002         TSmsDataCodingScheme::ESmsIndicationInactive;
       
  1003 
       
  1004     switch (bits7to4)
       
  1005         {
       
  1006         case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndication7Bit:
       
  1007         case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationUCS2:
       
  1008         case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationDiscardMessage:
       
  1009 
       
  1010            indicationState = pdu.IndicationState();
       
  1011 
       
  1012            if( indicationState != TSmsDataCodingScheme::ESmsIndicationActive &&
       
  1013                indicationState != TSmsDataCodingScheme::ESmsIndicationInactive )
       
  1014                 {
       
  1015                 NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL, ESmsMessage 2<<"));
       
  1016                 return ESmsMessage;
       
  1017                 }
       
  1018            break;
       
  1019 
       
  1020         default:
       
  1021             // Check for CPHS message waiting bits. If they are not
       
  1022             // present, we are dealing with normal sms message
       
  1023             CNcnMsvSessionObserver::TNcnInboxEntryType type =
       
  1024                 CheckForCPHSIndicationBitsL( aEntry, aHeader );
       
  1025 
       
  1026             if( type != EUnknown )
       
  1027                 {
       
  1028                 NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL, not EUnknown 2<<"));
       
  1029                 return type;
       
  1030                 }
       
  1031             NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL, ESmsMessage 3<<"));
       
  1032 
       
  1033             return ESmsMessage;
       
  1034         }
       
  1035 
       
  1036     // handle dcs indication
       
  1037     TBool indicatorSetMessage = HandleDCSIndicationL(
       
  1038         pdu.IndicationType(),
       
  1039         pdu.IndicationState() );
       
  1040 
       
  1041     if( bits7to4 == TSmsDataCodingScheme::
       
  1042             ESmsDCSMessageWaitingIndicationDiscardMessage &&
       
  1043             aHeader.Message().Buffer().Length() < 2 )
       
  1044         {
       
  1045         if( indicatorSetMessage )
       
  1046             {
       
  1047             NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL, EMessageWaitingDiscardSetMessage <<"));
       
  1048             return EMessageWaitingDiscardSetMessage;
       
  1049             }
       
  1050         else
       
  1051             {
       
  1052             NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL, EMessageWaitingDiscardClearMessage <<"));
       
  1053             return EMessageWaitingDiscardClearMessage;
       
  1054             }
       
  1055         }
       
  1056     NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForMessageWaitingL, EMessageWaitingStoreMessage <<"));
       
  1057     return EMessageWaitingStoreMessage;
       
  1058     }
       
  1059 
       
  1060 // ---------------------------------------------------------
       
  1061 // CNcnMsvSessionObserver::HandleDCSIndicationL
       
  1062 // ---------------------------------------------------------
       
  1063 //    
       
  1064 TBool CNcnMsvSessionObserver::HandleDCSIndicationL(
       
  1065     TSmsDataCodingScheme::TSmsIndicationType aIndicationType,
       
  1066     TSmsDataCodingScheme::TSmsIndicationState aIndicationState )
       
  1067     {
       
  1068     NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL >>") );
       
  1069     // amount of messages waiting set
       
  1070     TUint amount = 0;
       
  1071     
       
  1072     // determine indication type
       
  1073     switch( aIndicationType )
       
  1074         {
       
  1075         case TSmsDataCodingScheme::ESmsVoicemailMessageWaiting:
       
  1076             {            
       
  1077             if( aIndicationState == TSmsDataCodingScheme::ESmsIndicationActive )
       
  1078                 {
       
  1079                 NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL: voice mail active") );
       
  1080                 amount = CVoiceMailManager::EVMExistsButCountNotKnown;
       
  1081                 }
       
  1082             else
       
  1083             	{
       
  1084                 NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL: voice mail inactive") );            	
       
  1085             	amount = CVoiceMailManager::ENoVoiceMails;	
       
  1086             	}    
       
  1087                 
       
  1088             //DCS indications don't seem to have alternative line support
       
  1089             iVMManager.VMMessageReceived( MNcnMsgWaitingManager::ENcnMessageTypeVMLine1 , amount );
       
  1090             break;
       
  1091             }
       
  1092         case TSmsDataCodingScheme::ESmsFaxMessageWaiting:
       
  1093             {            
       
  1094             if( aIndicationState == TSmsDataCodingScheme::ESmsIndicationActive )
       
  1095                 {
       
  1096                 NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL: fax message active") );                
       
  1097                 amount = KNcnDefaultMessagesWaiting;
       
  1098                 }
       
  1099 			else
       
  1100 				{
       
  1101 				NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL: fax message inactive") );						
       
  1102 				}                
       
  1103                 
       
  1104             SetFaxMessagesWaiting( amount );
       
  1105             break;
       
  1106             }
       
  1107         case TSmsDataCodingScheme::ESmsElectronicMailMessageWaiting:
       
  1108             {
       
  1109             if( aIndicationState == TSmsDataCodingScheme::ESmsIndicationActive )
       
  1110                 {
       
  1111 				NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL: email message active") );                
       
  1112                 amount = KNcnDefaultMessagesWaiting;
       
  1113                 }
       
  1114 			else
       
  1115 				{
       
  1116 				NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL: email message inactive") );	
       
  1117 				}                
       
  1118                 
       
  1119             SetEMailMessagesWaiting( amount );
       
  1120             break;
       
  1121             }
       
  1122         case TSmsDataCodingScheme::ESmsFaxOtherMessageWaiting:
       
  1123             {            
       
  1124             if( aIndicationState == TSmsDataCodingScheme::ESmsIndicationActive )
       
  1125                 {
       
  1126 				NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL: other message active") );                
       
  1127                 amount = KNcnDefaultMessagesWaiting;
       
  1128                 }
       
  1129 			else
       
  1130 				{
       
  1131 				NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL: other message inactive") ); 					
       
  1132 				}                
       
  1133                 
       
  1134             SetOtherMessagesWaiting( amount );
       
  1135             break;            
       
  1136             }
       
  1137         default:
       
  1138             break;
       
  1139         }
       
  1140         
       
  1141     // return the indication set status
       
  1142     // baes on number of messages waiting
       
  1143     NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleDCSIndicationL <<") );
       
  1144     return ( amount != 0 );
       
  1145     }
       
  1146 
       
  1147 // ---------------------------------------------------------
       
  1148 // CNcnMsvSessionObserver::HandleSmsUserDataL
       
  1149 // ---------------------------------------------------------
       
  1150 //
       
  1151 CNcnMsvSessionObserver::TNcnInboxEntryType CNcnMsvSessionObserver::HandleSmsUserDataL(
       
  1152     const CSmsUserData& aUserData )
       
  1153     {
       
  1154     NCN_RDEBUG(_L("CNcnMsvSessionObserver::HandleSmsUserDataL <<"));    
       
  1155     // default to unknown
       
  1156     TNcnInboxEntryType entryType = EUnknown;
       
  1157     
       
  1158     // count data elements
       
  1159     TInt count = aUserData.NumInformationElements();
       
  1160                
       
  1161     // process each element
       
  1162     while( count-- )
       
  1163         {
       
  1164         // extract information element
       
  1165         CSmsInformationElement& informationElement =
       
  1166             aUserData.InformationElement(count);
       
  1167             
       
  1168         // if element is message indication
       
  1169         if ( informationElement.Identifier() ==
       
  1170             CSmsInformationElement::ESmsIEISpecialSMSMessageIndication )
       
  1171             {
       
  1172             //Determine which resource ID to use
       
  1173             const TDesC8& data = informationElement.Data();
       
  1174             
       
  1175             // extract message type
       
  1176             TUint8 messageType = data[0];
       
  1177             
       
  1178             // extract number of messages waiting
       
  1179             TUint8 messagesWaiting = data[1];
       
  1180 
       
  1181             // handle the element
       
  1182             HandleSpecialSMSMessageIndicationL( messageType, messagesWaiting );
       
  1183             
       
  1184             // Check the store/discard -information from IE, so that we
       
  1185             // know, what to do to message itself
       
  1186             if( count == 0 )
       
  1187                 {
       
  1188                 if ( messageType & KNcnStoreIndicator )
       
  1189                     {
       
  1190                     entryType = EMessageWaitingStoreMessage;
       
  1191                     }
       
  1192                 else
       
  1193                     {
       
  1194                     if( messagesWaiting )
       
  1195                         {
       
  1196                         entryType = EMessageWaitingDiscardSetMessage;
       
  1197                         }
       
  1198                     else
       
  1199                         {
       
  1200                         entryType = EMessageWaitingDiscardClearMessage;
       
  1201                         }
       
  1202                     }
       
  1203                 }
       
  1204             }
       
  1205         }
       
  1206         
       
  1207     // return the entry type        
       
  1208     NCN_RDEBUG(_L("CNcnMsvSessionObserver::HandleSmsUserDataL <<"));    
       
  1209     return entryType;
       
  1210     }
       
  1211     
       
  1212 // ---------------------------------------------------------
       
  1213 // CNcnMsvSessionObserver::HandleSpecialSMSMessageIndicationL
       
  1214 // ---------------------------------------------------------
       
  1215 //
       
  1216 void CNcnMsvSessionObserver::HandleSpecialSMSMessageIndicationL(
       
  1217     TUint8 aMessageType,
       
  1218     TUint8 aMessagesWaiting )
       
  1219     {
       
  1220     NCN_RDEBUG( _L("CNcnMsvSessionObserver::HandleSpecialSMSMessageIndicationL") );
       
  1221     // Check from current message IEI, which type of indicator is provided
       
  1222     // message type is masked with 01111111
       
  1223     switch ( aMessageType & TSmsUtilities::ESpecialMessageTypeMask )
       
  1224         {
       
  1225         case TSmsUtilities::EVoiceMessageWaiting:
       
  1226             //Special SMS indications don't seem to have alternative line support
       
  1227             NCN_RDEBUG_INT( _L("CNcnMsvSessionObserver::HandleSpecialSMSMessageIndicationL: voice mails on line: %d"), aMessagesWaiting );
       
  1228        		iVMManager.VMMessageReceived( MNcnMsgWaitingManager::ENcnMessageTypeVMLine1, aMessagesWaiting );
       
  1229             break;
       
  1230 
       
  1231         case TSmsUtilities::EFaxMessageWaiting:
       
  1232             NCN_RDEBUG_INT( _L("CNcnMsvSessionObserver::HandleSpecialSMSMessageIndicationL: fax messages waiting: %d"), aMessagesWaiting );        
       
  1233             SetFaxMessagesWaiting( aMessagesWaiting );
       
  1234             break;
       
  1235             
       
  1236         case TSmsUtilities::EEmailMessageWaiting:
       
  1237             NCN_RDEBUG_INT( _L("CNcnMsvSessionObserver::HandleSpecialSMSMessageIndicationL: emails waiting: %d"), aMessagesWaiting );        
       
  1238             SetEMailMessagesWaiting( aMessagesWaiting );
       
  1239             break;
       
  1240             
       
  1241         default: // EOtherMessageWaiting
       
  1242             NCN_RDEBUG_INT( _L("CNcnMsvSessionObserver::HandleSpecialSMSMessageIndicationL: other messages waiting: %d"), aMessagesWaiting );        
       
  1243             SetOtherMessagesWaiting( aMessagesWaiting );
       
  1244             break;
       
  1245         }        
       
  1246     NCN_RDEBUG(_L("CNcnMsvSessionObserver::HandleSpecialSMSMessageIndicationL <<"));    
       
  1247     }
       
  1248     
       
  1249 // ---------------------------------------------------------
       
  1250 // CNcnMsvSessionObserver::CheckForCPHSIndicationBitsL
       
  1251 // Check if the sms is a CPHS message waiting indicator and
       
  1252 // notify the system agent if it is.
       
  1253 // ---------------------------------------------------------
       
  1254 //
       
  1255 CNcnMsvSessionObserver::TNcnInboxEntryType
       
  1256     CNcnMsvSessionObserver::CheckForCPHSIndicationBitsL(
       
  1257         CMsvEntry&      aEntry,
       
  1258         CSmsHeader&     aHeader )
       
  1259     {
       
  1260     NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForCPHSIndicationBitsL >>"));    
       
  1261     // CPHS Implementation of message waiting indicator (CPHS Phase 2)
       
  1262     CSmsPDU &pdu = aHeader.Message().SmsPDU();
       
  1263     TGsmSmsTelNumber address;
       
  1264     pdu.ParsedToFromAddress(address);
       
  1265 
       
  1266     // we can't get the npi from the address.
       
  1267     if( IsCphsMessage( address ) )// x000 000x constant value
       
  1268         {
       
  1269 		EmptyCphsMessageAddressL( aEntry, aHeader );
       
  1270 
       
  1271         // Check the bits on first character of telephone number
       
  1272         TInt indicatorSetMessage =
       
  1273             HandleCphsMessageL( address.iTelNumber[KNcnCphsFirstChar] );
       
  1274 
       
  1275         // Now check if the SMS is a store message or a
       
  1276         // discard message. The SMS is a store message
       
  1277         // if there is only one byte present and the byte
       
  1278         // has a value 01000000. Fetch the user data...
       
  1279         if( pdu.UserDataPresent() )
       
  1280             {
       
  1281             CSmsBufferBase &buffer = aHeader.Message().Buffer();
       
  1282             TBuf<1> oneChar(KEmptyChar);
       
  1283 
       
  1284             buffer.Extract(oneChar, 0, 1);
       
  1285             if( buffer.Length() == 1 && oneChar == KSpaceChar )
       
  1286                 {
       
  1287                 if( indicatorSetMessage )
       
  1288                     {
       
  1289                     return EMessageWaitingDiscardSetMessage;
       
  1290                     }
       
  1291                 else
       
  1292                     {
       
  1293                     return EMessageWaitingDiscardClearMessage;
       
  1294                     }
       
  1295                 }
       
  1296             else
       
  1297                 {
       
  1298                 return EMessageWaitingStoreMessage;
       
  1299                 }
       
  1300             }
       
  1301         else if( indicatorSetMessage )
       
  1302             {
       
  1303             return EMessageWaitingDiscardSetMessage;
       
  1304             }
       
  1305         else
       
  1306             {
       
  1307             return EMessageWaitingDiscardClearMessage;
       
  1308             }
       
  1309         }
       
  1310     NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckForCPHSIndicationBitsL <<"));    
       
  1311     return EUnknown;
       
  1312     }
       
  1313 
       
  1314 // ---------------------------------------------------------
       
  1315 // CNcnMsvSessionObserver::EmptyCphsMessageAddress
       
  1316 // Empties the sender address from a Cphs message.
       
  1317 // ---------------------------------------------------------
       
  1318 //
       
  1319 void CNcnMsvSessionObserver::EmptyCphsMessageAddressL(
       
  1320         CMsvEntry&      aEntry,
       
  1321         CSmsHeader&     aHeader )
       
  1322 	{
       
  1323     NCN_RDEBUG(_L("CNcnMsvSessionObserver::EmptyCphsMessageAddressL >>"));
       
  1324     TMsvEntry tentry = aEntry.Entry();
       
  1325     TInt wasLocked = tentry.ReadOnly();
       
  1326 
       
  1327 	if( wasLocked )
       
  1328 		{
       
  1329 		tentry.SetReadOnly( EFalse ); // unlock the entry for writing
       
  1330 		}
       
  1331 
       
  1332     // Empty the iDetails data
       
  1333     tentry.iDetails.Set( KNullDesC );
       
  1334     // Commit the change
       
  1335     aEntry.ChangeL( tentry );
       
  1336     // Empty the real adress
       
  1337     aHeader.SetFromAddressL( KNullDesC );
       
  1338     // Store the header
       
  1339     CMsvStore* store = aEntry.EditStoreL();
       
  1340     CleanupStack::PushL(store);
       
  1341     aHeader.StoreL( *store );
       
  1342     store->CommitL();
       
  1343     CleanupStack::PopAndDestroy(store);
       
  1344 
       
  1345     // Setting the old state back
       
  1346     tentry.SetReadOnly( wasLocked );
       
  1347     NCN_RDEBUG(_L("CNcnMsvSessionObserver::EmptyCphsMessageAddressL <<"));
       
  1348     }
       
  1349 
       
  1350 // ---------------------------------------------------------
       
  1351 //  CNcnMsvSessionObserver::IsCphsMessage
       
  1352 //  Runs CPHS-checks for originator address field to determine
       
  1353 //  if message contains voicemail indication
       
  1354 // ---------------------------------------------------------
       
  1355 //
       
  1356 TBool CNcnMsvSessionObserver::IsCphsMessage(
       
  1357     const TGsmSmsTelNumber& aOrigAddress ) const
       
  1358     {
       
  1359     // Determine if the length of TP-OA is qualifies for CPHS indication
       
  1360     if( aOrigAddress.iTelNumber.Length() != KNcnCphsAddressLength )
       
  1361         {
       
  1362         // Address length is wrong, return immediately
       
  1363         return EFalse;
       
  1364         }
       
  1365 
       
  1366     // Get the Type of Address
       
  1367     TGsmSmsTypeOfNumber oaTON = aOrigAddress.iTypeOfAddress.TON();
       
  1368 
       
  1369     // Get first two digits of phonenumber
       
  1370     TUint oaDigits1 = aOrigAddress.iTelNumber[KNcnCphsFirstChar];
       
  1371 
       
  1372     // Get second two digits of phonenumber
       
  1373     TUint oaDigits2 = aOrigAddress.iTelNumber[KNcnCphsSecondChar];
       
  1374 
       
  1375     // Determine if Type of Address has the constant CPHS values (11010000)
       
  1376     TBool cphsTon = ( oaTON == EGsmSmsTONAlphaNumeric );
       
  1377 
       
  1378     // Determine if first two digits contains the voicemail
       
  1379     // indicator (bits 4..2) and in last two digits,
       
  1380     // bits 7 to 2 are all zeros
       
  1381     TBool cphsType = ( oaDigits1 & KNcnCphsConstantMask ) == KNcnCphsFirstInfo;
       
  1382     TBool cphsInd = ( oaDigits2 & KNcnCphsConstantMask ) == KNcnCphsSecondInfo;
       
  1383 
       
  1384     // Return the combined result of tests for final decision
       
  1385     return ( cphsTon && cphsType && cphsInd );
       
  1386     }
       
  1387 
       
  1388 // ---------------------------------------------------------
       
  1389 //  CNcnMsvSessionObserver::HandleCphsMessage
       
  1390 //  Handles CPHS-voicemail notifications
       
  1391 // ---------------------------------------------------------
       
  1392 //
       
  1393 TInt CNcnMsvSessionObserver::HandleCphsMessageL( const TUint aFirstOctet )
       
  1394     {
       
  1395     NCN_RDEBUG(_L("CNcnMsvSessionObserver::HandleCphsMessageL >>"));
       
  1396     // Get if set or clear message
       
  1397     TBool typeSetMessage = aFirstOctet & KNcnCphsSet;
       
  1398     TUint lineInfo = aFirstOctet & KNcnCphsLineMask;
       
  1399 
       
  1400     // Make sure the fields are correctly set
       
  1401     if( lineInfo == KNcnCphsVmiLine1 ||
       
  1402         lineInfo == KNcnCphsVmiLine2 )
       
  1403         {                  
       
  1404     	//The message is a SET message in line 1
       
  1405         if( typeSetMessage == 1 && lineInfo == KNcnCphsVmiLine1 )
       
  1406             {
       
  1407             iVMManager.VMMessageReceived( MNcnMsgWaitingManager::ENcnMessageTypeVMLine1, CVoiceMailManager::EVMExistsButCountNotKnown );
       
  1408             }
       
  1409             
       
  1410       	//The message is a CLEAR message in line 1
       
  1411         else if( typeSetMessage != 1 && lineInfo == KNcnCphsVmiLine1 )
       
  1412             {
       
  1413             iVMManager.VMMessageReceived( MNcnMsgWaitingManager::ENcnMessageTypeVMLine1, CVoiceMailManager::ENoVoiceMails );
       
  1414             }
       
  1415                        
       
  1416      	//The message is a SET message in line 2       
       
  1417         else if( typeSetMessage == 1 && lineInfo == KNcnCphsVmiLine2 )
       
  1418             {
       
  1419             iVMManager.VMMessageReceived( MNcnMsgWaitingManager::ENcnMessageTypeVMLine2, CVoiceMailManager::EVMExistsButCountNotKnown );
       
  1420             }
       
  1421             
       
  1422      	//The message is a CLEAR message in line 2       
       
  1423         else if( typeSetMessage != 1 && lineInfo == KNcnCphsVmiLine2 )
       
  1424             {
       
  1425             iVMManager.VMMessageReceived( MNcnMsgWaitingManager::ENcnMessageTypeVMLine2, CVoiceMailManager::ENoVoiceMails );
       
  1426             }   
       
  1427         }
       
  1428 
       
  1429     // Return EFalse, when clear message
       
  1430     NCN_RDEBUG(_L("CNcnMsvSessionObserver::HandleCphsMessageL <<"));
       
  1431     return typeSetMessage;
       
  1432     }
       
  1433 
       
  1434 // ---------------------------------------------------------
       
  1435 //  CNcnMsvSessionObserver::GetTelNumber
       
  1436 // ---------------------------------------------------------
       
  1437 //
       
  1438 TGsmSmsTelNumber CNcnMsvSessionObserver::GetTelNumber(
       
  1439     const CSmsMessage& aMessage ) const
       
  1440     {
       
  1441     // Get SMS PDU
       
  1442     const CSmsPDU &pdu = aMessage.SmsPDU();
       
  1443 
       
  1444     // Prepare address and get address from header
       
  1445     TGsmSmsTelNumber address;
       
  1446     pdu.ParsedToFromAddress( address );
       
  1447 
       
  1448     return address;
       
  1449     }
       
  1450 
       
  1451 // ---------------------------------------------------------
       
  1452 //  CNcnMsvSessionObserver::CheckAndLaunchMCEL
       
  1453 // ---------------------------------------------------------
       
  1454 //
       
  1455 void CNcnMsvSessionObserver::CheckAndLaunchMCEL(
       
  1456     const TMsvEntry& aEntry )
       
  1457     {
       
  1458     NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckAndLaunchMCEL >>"));
       
  1459     // get session from session handler
       
  1460     CMsvSession& msvSession = iModel->MsvSessionHandler().MsvSessionL();
       
  1461     
       
  1462     TBuf<CTelephony::KMaxTelNumberSize> number;
       
  1463 	TInt err = iModel->GetPSString(
       
  1464 		KPSUidTelRemotePartyInformation, KTelCLINumber, number );
       
  1465 
       
  1466     if( err == KErrNone )
       
  1467         {
       
  1468         NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::CheckAndLaunchMCEL: CLI number access successful, telnumber: %s"), number.PtrZ() );
       
  1469 
       
  1470         // Get match value from Shared Data
       
  1471         TInt sdMatchValue = KNcnMatchDefault;
       
  1472 		err = iModel->GetCRInteger(
       
  1473 			KCRUidTelConfiguration, KTelMatchDigits, sdMatchValue );
       
  1474 
       
  1475         if( err == KErrNone )
       
  1476             {
       
  1477             if ( sdMatchValue < KNcnMatchMin || sdMatchValue > KNcnMatchMax )
       
  1478                 {
       
  1479                 sdMatchValue = KNcnMatchDefault;
       
  1480                 }
       
  1481             }
       
  1482 
       
  1483         // Compare arrived message number/ender to the possible active phonenumber.
       
  1484         // Notice, that numbers can be on formats like 35840xxx and 040xxx,
       
  1485 		// so rightmost numbers have to be compared.
       
  1486 		if( number.Length() != 0 )
       
  1487 			{
       
  1488 			TBool match = EFalse;
       
  1489 			if( aEntry.iMtm == KUidMsgTypeMultimedia )
       
  1490 				{
       
  1491 				// Get MMS sender information
       
  1492 				CClientMtmRegistry* clientMtmRegistry =
       
  1493 				    CClientMtmRegistry::NewL( msvSession );
       
  1494 				CleanupStack::PushL( clientMtmRegistry );
       
  1495 				CMmsClientMtm* mMsClient = static_cast< CMmsClientMtm* >
       
  1496 				    ( clientMtmRegistry->NewMtmL( KUidMsgTypeMultimedia ) );
       
  1497 				CleanupStack::PushL( mMsClient );
       
  1498 				mMsClient->SwitchCurrentEntryL( aEntry.Id() );
       
  1499 				mMsClient->LoadMessageL();
       
  1500 				const TPtrC sender = mMsClient->Sender();
       
  1501 				NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::CheckAndLaunchMCEL: MMS sender: %s"), sender.Ptr() );
       
  1502 				match = ( sender.Right( sdMatchValue ) == number.Right( sdMatchValue ) );
       
  1503 				CleanupStack::PopAndDestroy( 2, clientMtmRegistry );    // mMsClient, clientMtmRegistry
       
  1504 				}
       
  1505 			else
       
  1506 				{
       
  1507 				// Get SMS sender information
       
  1508 				const TPtrC sender = iTelNumber.iTelNumber;
       
  1509 				NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::CheckAndLaunchMCEL: SMS number: %s"), iTelNumber.iTelNumber.PtrZ() );
       
  1510 				match = ( sender.Right( sdMatchValue ) == number.Right( sdMatchValue ) );
       
  1511 				}
       
  1512 			
       
  1513 			//Get the autolock status
       
  1514 			TInt autoLockStatus = CheckAutoLockStatus();
       
  1515 			
       
  1516 			NCN_RDEBUG_INT(_L("CheckAndLaunchMCEL: number match result = %d"), match );
       
  1517         	NCN_RDEBUG_INT(_L("CheckAndLaunchMCEL: autolockStatus = %d"), autoLockStatus );
       
  1518         
       
  1519 			if ( match && autoLockStatus != 1)
       
  1520 			    {
       
  1521 			    // open message
       
  1522 			    iModel->NcnUI().OpenMessageL( aEntry );
       
  1523 				}
       
  1524             }
       
  1525         }
       
  1526       NCN_RDEBUG(_L("CNcnMsvSessionObserver::CheckAndLaunchMCEL <<"));
       
  1527     }
       
  1528 
       
  1529 // ---------------------------------------------------------
       
  1530 //  CNcnMsvSessionObserver::SetFaxMessagesWaiting
       
  1531 // ---------------------------------------------------------
       
  1532 //         
       
  1533 void CNcnMsvSessionObserver::SetFaxMessagesWaiting( TUint aAmount )
       
  1534     {
       
  1535 	TBool enable = ( aAmount > 0 ) ? ETrue : EFalse;
       
  1536 	iModel->MsgWaitingManager().SetMessageCount( MNcnMsgWaitingManager::ENcnMessageTypeFax, aAmount, enable );				
       
  1537     }
       
  1538          
       
  1539 // ---------------------------------------------------------
       
  1540 //  CNcnMsvSessionObserver::SetEMailMessagesWaiting
       
  1541 // ---------------------------------------------------------
       
  1542 //
       
  1543 void CNcnMsvSessionObserver::SetEMailMessagesWaiting( TUint aAmount )
       
  1544     {
       
  1545 /*    
       
  1546     // default to messages waiting    
       
  1547     TUint value = KNcnNewEmail;
       
  1548                 
       
  1549     // change the default if there are now messages waiting
       
  1550     if( !aAmount )
       
  1551         {
       
  1552         value = KNcnNoNewEmail;
       
  1553         }
       
  1554 
       
  1555     // update key value
       
  1556 	iModel->NotifyPublishAndSubscribe(
       
  1557 			KNcnNewEmailCategory, KNcnNewEmailStatus, value );   
       
  1558 			
       
  1559 	// Store it as indicator
       
  1560 	iModel->StoreIndicatorStatus( KNcnNewEmailStatus, value );
       
  1561 */
       
  1562 
       
  1563 	TBool enable = ( aAmount > 0 ) ? ETrue : EFalse;
       
  1564 	iModel->MsgWaitingManager().SetMessageCount( MNcnMsgWaitingManager::ENcnMessageTypeEmail, aAmount, enable );	
       
  1565     }
       
  1566 
       
  1567 // ---------------------------------------------------------
       
  1568 //  CNcnMsvSessionObserver::SetOtherMessagesWaiting
       
  1569 // ---------------------------------------------------------
       
  1570 //         
       
  1571 void CNcnMsvSessionObserver::SetOtherMessagesWaiting( TUint aAmount )
       
  1572     {
       
  1573 	TBool enable = ( aAmount > 0 ) ? ETrue : EFalse;
       
  1574 	iModel->MsgWaitingManager().SetMessageCount( MNcnMsgWaitingManager::ENcnMessageTypeOther, aAmount, enable );		
       
  1575     }
       
  1576 
       
  1577 // ---------------------------------------------------------
       
  1578 //  CNcnMsvSessionObserver::CheckAutoLockStatus
       
  1579 // ---------------------------------------------------------
       
  1580 //               
       
  1581 TInt CNcnMsvSessionObserver::CheckAutoLockStatus()
       
  1582 	{
       
  1583 	//Get the lock status from Central Repository
       
  1584     TInt lockStatus(KErrNotFound);
       
  1585     NCN_RDEBUG(_L("CNcnMsvSessionObserver: CheckAutoLockStatus >>"));
       
  1586     CRepository* settingsRepository(NULL);
       
  1587     TRAPD(err, settingsRepository = CRepository::NewL(KCRUidSecuritySettings));
       
  1588     NCN_RDEBUG_INT(_L("CheckAndLaunchMCEL: CRepository::NewL err = %d"), err );
       
  1589     
       
  1590     if (err == KErrNone)
       
  1591         {
       
  1592         err = settingsRepository->Get(KSettingsAutolockStatus, lockStatus);
       
  1593         NCN_RDEBUG_INT(_L("CheckAndLaunchMCEL: lockStatus = %d"), lockStatus );
       
  1594         }
       
  1595                     
       
  1596     //Cleanup   
       
  1597     delete settingsRepository;
       
  1598     NCN_RDEBUG(_L("CNcnMsvSessionObserver: CheckAutoLockStatus <<"));
       
  1599     return lockStatus;		
       
  1600 	}
       
  1601 
       
  1602 // ---------------------------------------------------------
       
  1603 // CNcnMsvSessionObserver::IsUnread
       
  1604 // Check if entry is read or unread. Uses iUnreadMessages array.
       
  1605 // ---------------------------------------------------------
       
  1606 //	
       
  1607 TBool CNcnMsvSessionObserver::IsUnread(const TMsvEntry& aEntry)
       
  1608 	{
       
  1609 	if( iUnreadMessages->Find( aEntry.Id() ) != KErrNotFound )
       
  1610 		{
       
  1611 		//NCN_RDEBUG_INT( _L("CNcnMsvSessionObserver::CheckIfUnread: message (TMsvId %d) is unread"), aEntry.Id() );
       
  1612 		return ETrue;				
       
  1613 		}
       
  1614 	else
       
  1615 		{
       
  1616 		//NCN_RDEBUG_INT( _L("CNcnMsvSessionObserver::CheckIfUnread: message (TMsvId %d) is read"), aEntry.Id() );
       
  1617 		return EFalse;
       
  1618 		}			
       
  1619 
       
  1620 	}
       
  1621 	
       
  1622 // ---------------------------------------------------------
       
  1623 // CNcnMsvSessionObserver::InitUnreadMessagesArrayL
       
  1624 // This method is called only once during phone boot.
       
  1625 // Its purpose is to add all unread and visible messages
       
  1626 // in Inbox to iUnreadMessages array. This means that
       
  1627 // those entries are treated as new and unread eventhough
       
  1628 // message might have been read and marked again as unread
       
  1629 // before the boot. 
       
  1630 // ---------------------------------------------------------
       
  1631 //	
       
  1632 void CNcnMsvSessionObserver::InitUnreadMessagesArrayL()
       
  1633     {
       
  1634     // get session from session handler
       
  1635     CMsvSession& msvSession = iModel->MsvSessionHandler().MsvSessionL();
       
  1636     
       
  1637     NCN_RDEBUG( _L("CNcnMsvSessionObserver::InitUnreadMessagesArrayL") );
       
  1638     
       
  1639     // Check how many unread messages there are in the In-box.
       
  1640     const TInt itemCount = iInboxFolder->Count();
       
  1641     NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::InitUnreadMessagesArrayL [%d]"), itemCount );
       
  1642     TInt numberOfUnreadMessages = 0; // Note, This value only for logging purpose
       
  1643     
       
  1644     for( TInt index = 0; index < itemCount; index++ )
       
  1645         {
       
  1646         const TMsvEntry entry = (*iInboxFolder)[index];
       
  1647 
       
  1648         if( entry.iType.iUid == KUidMsvMessageEntryValue && 
       
  1649         	entry.Visible() &&
       
  1650         	entry.Unread() )
       
  1651             {
       
  1652             TInt err = iUnreadMessages->Append( entry.Id() );
       
  1653             if ( err )
       
  1654          	    {
       
  1655          	    NCN_RDEBUG_INT(_L("CNcnMsvSessionObserver::InitUnreadMessagesArrayL - APPEND ERROR %d!"), err );
       
  1656          	    }
       
  1657             ++numberOfUnreadMessages;
       
  1658             }
       
  1659         }
       
  1660     
       
  1661     NCN_RDEBUG_INT( _L( "CNcnMsvSessionObserver::InitUnreadMessagesArrayL \
       
  1662         :%d" ), numberOfUnreadMessages );
       
  1663         
       
  1664     NCN_RDEBUG( _L("CNcnMsvSessionObserver::InitUnreadMessagesArrayL <<") );
       
  1665     }
       
  1666 
       
  1667 // ---------------------------------------------------------
       
  1668 //  CNcnMsvSessionObserver::HandleMsvMediaChangedL
       
  1669 // ---------------------------------------------------------
       
  1670 //
       
  1671 void CNcnMsvSessionObserver::HandleMsvMediaChangedL( const TDriveNumber& /*aDriveNumber*/ )
       
  1672     {
       
  1673 	NCN_RDEBUG(_L("CNcnMsvSessionObserver::HandleMsvMediaChangedL >> <<" ));
       
  1674     }
       
  1675 
       
  1676 // ---------------------------------------------------------
       
  1677 //  CNcnMsvSessionObserver::UpdateInboxDataNotifiersL
       
  1678 // ---------------------------------------------------------
       
  1679 //
       
  1680 void CNcnMsvSessionObserver::UpdateInboxDataNotifiersL()
       
  1681     {
       
  1682     TInt unreadMessages = 0;
       
  1683     TInt notListenedAudioMessages = 0;
       
  1684     CheckAmountOfUnreadMessagesInInboxL( unreadMessages, notListenedAudioMessages);
       
  1685     
       
  1686     iModel->NcnNotifier().SetNotification(
       
  1687 		        MNcnNotifier::ENcnMessagesNotification,
       
  1688 		        unreadMessages );
       
  1689 		        
       
  1690 	if( iModel->IsSupported( KNcnAudioMessaging ) )
       
  1691 		{
       
  1692 		iModel->NcnNotifier().SetNotification( 
       
  1693     		MNcnNotifier::ENcnAudioMessagesNotification,
       
  1694     		notListenedAudioMessages );
       
  1695 		}
       
  1696     }
       
  1697              
       
  1698 // ---------------------------------------------------------
       
  1699 //  CNcnMsvSessionObserver::PrintEntryDebugInformation
       
  1700 // ---------------------------------------------------------
       
  1701 //
       
  1702 #ifdef _DEBUG
       
  1703 void CNcnMsvSessionObserver::PrintEntryDebugInformation(const TMsvEntry&  aEntryToHandle)
       
  1704 	{
       
  1705 	NCN_RDEBUG(_L(" *** MESSAGE ANALYZE START ***" ));
       
  1706 
       
  1707 	NCN_RDEBUG(_L(" * DATA *" ));
       
  1708     NCN_RDEBUG_INT(_L(" MSG: Service ID = %d"), aEntryToHandle.iServiceId );
       
  1709     NCN_RDEBUG_INT(_L(" MSG: Related ID = %d"), aEntryToHandle.iRelatedId );
       
  1710     NCN_RDEBUG_INT(_L(" MSG: Type = %d"), aEntryToHandle.iType );
       
  1711     NCN_RDEBUG_INT(_L(" MSG: MTM = %d"), aEntryToHandle.iMtm );
       
  1712     NCN_RDEBUG_INT(_L(" MSG: Date = %d"), aEntryToHandle.iDate.Int64() );
       
  1713     NCN_RDEBUG_INT(_L(" MSG: Size = %d"), aEntryToHandle.iSize );
       
  1714     NCN_RDEBUG_INT(_L(" MSG: Error = %d"), aEntryToHandle.iError );
       
  1715 	NCN_RDEBUG_INT(_L(" MSG: BioType = %d"), aEntryToHandle.iBioType );
       
  1716 	NCN_RDEBUG_INT(_L(" MSG: Data 1 = %d"), aEntryToHandle.iMtmData1 );
       
  1717 	NCN_RDEBUG_INT(_L(" MSG: Data 2 = %d"), aEntryToHandle.iMtmData2 );
       
  1718 	NCN_RDEBUG_INT(_L(" MSG: Data 3 = %d"), aEntryToHandle.iMtmData3 );
       
  1719 
       
  1720 	NCN_RDEBUG(_L(" * STATES *" ));
       
  1721 
       
  1722 	NCN_RDEBUG_INT(_L(" MSG: Owner( %d )"), aEntryToHandle.Owner() );
       
  1723 	NCN_RDEBUG_INT(_L(" MSG: Deleted( %d )"), aEntryToHandle.Deleted() );
       
  1724 	NCN_RDEBUG_INT(_L(" MSG: Complete( %d )"), aEntryToHandle.Complete() );
       
  1725 	NCN_RDEBUG_INT(_L(" MSG: New( %d )"), aEntryToHandle.New() );
       
  1726 	NCN_RDEBUG_INT(_L(" MSG: Unread( %d )"), aEntryToHandle.Unread() );
       
  1727 	NCN_RDEBUG_INT(_L(" MSG: Failed( %d )"), aEntryToHandle.Failed() );
       
  1728 	NCN_RDEBUG_INT(_L(" MSG: Operation( %d )"), aEntryToHandle.Operation() );
       
  1729 	NCN_RDEBUG_INT(_L(" MSG: Visible( %d )"), aEntryToHandle.Visible() );
       
  1730 	NCN_RDEBUG_INT(_L(" MSG: Multiple Recipients( %d )"), aEntryToHandle.MultipleRecipients() );
       
  1731 	NCN_RDEBUG_INT(_L(" MSG: ReadOnly( %d )"), aEntryToHandle.ReadOnly() );
       
  1732 	NCN_RDEBUG_INT(_L(" MSG: Standard Folder( %d )"), aEntryToHandle.StandardFolder() );
       
  1733 	NCN_RDEBUG_INT(_L(" MSG: Attachment( %d )"), aEntryToHandle.Attachment() );
       
  1734 	NCN_RDEBUG_INT(_L(" MSG: Connected( %d )"), aEntryToHandle.Connected() );
       
  1735 	NCN_RDEBUG_INT(_L(" MSG: In Preparation( %d )"), aEntryToHandle.InPreparation() );
       
  1736 	NCN_RDEBUG_INT(_L(" MSG: Off peak( %d )"), aEntryToHandle.OffPeak() );
       
  1737 	NCN_RDEBUG_INT(_L(" MSG: Scheduled( %d )"), aEntryToHandle.Scheduled() );
       
  1738 	NCN_RDEBUG_INT(_L(" MSG: Pending Delete( %d )"), aEntryToHandle.PendingDelete() );
       
  1739 
       
  1740 	NCN_RDEBUG(_L(" *** MESSAGE ANALYZE END ***" ));		
       
  1741 	}
       
  1742 #endif // _DEBUG
       
  1743 
       
  1744 // End of file