pushmtm/plugins/PushContentHandler/CSLContentHandler.cpp
branchRCL_3
changeset 69 4455192101e4
equal deleted inserted replaced
65:8e6fa1719340 69:4455192101e4
       
     1 /*
       
     2 * Copyright (c) 2002 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 the License "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:  Implementation of CSLContentHandler.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 
       
    22 #include "CSLContentHandler.h"
       
    23 #include "PushMtmUtil.h"
       
    24 #include "PushMtmSettings.h"
       
    25 #include "PushAuthenticationUtilities.h"
       
    26 #include "PushMtmLog.h"
       
    27 #include "PushContentHandlerPanic.h"
       
    28 #include "PushMtmAutoFetchOperation.h"
       
    29 #include "PushMtmUiDef.h"
       
    30 #include "StringResourceReader.h"
       
    31 #include "sl_dict.h"
       
    32 #include "PushContentHandlerUtils.h"
       
    33 #include <push/cslpushmsgentry.h>
       
    34 #include <msvids.h>
       
    35 #include <apgtask.h>
       
    36 #include <apgcli.h>
       
    37 #include <w32std.h>
       
    38 #include <PushMtmUi.rsg>
       
    39 #include <nw_dom_node.h>
       
    40 #include <nw_dom_document.h>
       
    41 #include <nw_dom_element.h>
       
    42 #include <nw_dom_text.h>
       
    43 #include <nw_wbxml_dictionary.h>
       
    44 #include <nw_string_char.h>
       
    45 #include "PushMtmPrivateCRKeys.h"
       
    46 #include <centralrepository.h> 
       
    47 
       
    48 // CONSTANTS
       
    49 
       
    50 // sl attributes / elements
       
    51 _LIT8( KSl,      "sl" );
       
    52 _LIT8( KHref,    "href" );
       
    53 _LIT8( KAction,  "action" );
       
    54 
       
    55 // action attribute literals
       
    56 _LIT8( KExecHigh,"execute-high" );  
       
    57 _LIT8( KExecLow, "execute-low" );
       
    58 _LIT8( KCache,   "cache" );
       
    59 
       
    60 // Text SL MIME type
       
    61 _LIT( KSlTextContentType, "text/vnd.wap.sl" );
       
    62 
       
    63 // Browser command to fetch an URL. See Browser API Specification!
       
    64 _LIT( KBrowserCmdFetchUrl, "4 " );
       
    65 const TUid KBrowserAppUid = { 0x10008D39 };
       
    66 
       
    67 const TInt KNoOfDictArrays = 1;
       
    68 
       
    69 /// Autofetch time delay in seconds.
       
    70 const TInt KAutofetchDelayInSec = 5;
       
    71 
       
    72 // file monitored by browser
       
    73 _LIT( KPushMtmUrl, "c:\\system\\temp\\PushMtmUrl.txt" );
       
    74 
       
    75 // ================= MEMBER FUNCTIONS =======================
       
    76 
       
    77 // ---------------------------------------------------------
       
    78 // CSLContentHandler::NewL
       
    79 // ---------------------------------------------------------
       
    80 //
       
    81 CSLContentHandler* CSLContentHandler::NewL()
       
    82 	{
       
    83 	CSLContentHandler* self = new (ELeave) CSLContentHandler;
       
    84 	CleanupStack::PushL( self );
       
    85 	self->ConstructL();
       
    86 	CleanupStack::Pop( self );
       
    87 	return self;
       
    88 	}
       
    89 
       
    90 // ---------------------------------------------------------
       
    91 // CSLContentHandler::~CSLContentHandler
       
    92 // ---------------------------------------------------------
       
    93 //
       
    94 CSLContentHandler::~CSLContentHandler()
       
    95 	{
       
    96     PUSHLOG_ENTERFN("CSLContentHandler::~CSLContentHandler")
       
    97 
       
    98     Cancel();
       
    99     delete iFetchOp;
       
   100     delete iHrefBuf;
       
   101 
       
   102     PUSHLOG_LEAVEFN("CSLContentHandler::~CSLContentHandler")
       
   103     }
       
   104 
       
   105 // ---------------------------------------------------------
       
   106 // CSLContentHandler::CSLContentHandler
       
   107 // ---------------------------------------------------------
       
   108 //
       
   109 CSLContentHandler::CSLContentHandler()
       
   110 :   CPushContentHandlerBase(), 
       
   111     iSavedMsgId( KMsvNullIndexEntryId ), 
       
   112     iPushMsgAction( KErrNotFound ), 
       
   113     iSaveAsRead( EFalse )
       
   114 	{
       
   115 	}
       
   116 
       
   117 // ---------------------------------------------------------
       
   118 // CSLContentHandler::ConstructL
       
   119 // ---------------------------------------------------------
       
   120 //
       
   121 void CSLContentHandler::ConstructL()
       
   122 	{
       
   123     PUSHLOG_ENTERFN("CSLContentHandler::ConstructL")
       
   124     
       
   125     CRepository* PushSL = CRepository::NewL( KCRUidPushMtm );
       
   126     CleanupStack::PushL( PushSL );
       
   127     User::LeaveIfError( PushSL->Get( KPushMtmServiceEnabled , iPushSLEnabled ) );
       
   128     CleanupStack::PopAndDestroy( PushSL ); 
       
   129     
       
   130     CPushContentHandlerBase::ConstructL();
       
   131     // Added to Active Scheduler.
       
   132     PUSHLOG_LEAVEFN("CSLContentHandler::ConstructL")
       
   133     }
       
   134 
       
   135 // ---------------------------------------------------------
       
   136 // CSLContentHandler::CollectGarbageL
       
   137 // ---------------------------------------------------------
       
   138 //
       
   139 void CSLContentHandler::CollectGarbageL()
       
   140 	{
       
   141     PUSHLOG_ENTERFN("CSLContentHandler::CollectGarbageL")
       
   142 
       
   143     DoCollectGarbageL();
       
   144 
       
   145 	if(iPushSLEnabled)
       
   146 	    iState = EFilteringAndParsing;
       
   147 	else
       
   148 	    iState = EDone;
       
   149 	
       
   150 	IdleComplete();
       
   151 
       
   152     PUSHLOG_LEAVEFN("CSLContentHandler::CollectGarbageL")
       
   153     }
       
   154 
       
   155 
       
   156 // ---------------------------------------------------------
       
   157 // CSLContentHandler::ParsePushMsgL
       
   158 // Note that cXML parser dosn't do any validation!
       
   159 // ---------------------------------------------------------
       
   160 //
       
   161 void CSLContentHandler::ParsePushMsgL()
       
   162 	{
       
   163     PUSHLOG_ENTERFN("CSLContentHandler::ParsePushMsgL")
       
   164 
       
   165     TPtrC8 bodyPtr;
       
   166     iMessage->GetMessageBody( bodyPtr );
       
   167     // If there is no body in the message leave with an error
       
   168     if ( bodyPtr.Size() == 0 )
       
   169         {
       
   170         PUSHLOG_WRITE("CSLContentHandler::ParsePushMsgL: Empty body")
       
   171         User::Leave( KErrCorrupt );
       
   172         }
       
   173 
       
   174     TPtrC contentType;
       
   175     iMessage->GetContentType( contentType );
       
   176     PUSHLOG_WRITE_FORMAT(" Content type <%S>",&contentType)
       
   177 
       
   178     // Add SL dictionary.
       
   179     NW_WBXML_Dictionary_t* dictArray[ KNoOfDictArrays ] = 
       
   180         { (NW_WBXML_Dictionary_t*)&NW_SL_WBXMLDictionary };
       
   181 
       
   182     NW_Status_t stat = NW_STAT_SUCCESS;
       
   183 
       
   184     RWbxmlDictionary wbxmlDict;
       
   185     wbxmlDict.InitializeL( KNoOfDictArrays, dictArray );
       
   186     CleanupClosePushL<RWbxmlDictionary>( wbxmlDict );
       
   187 
       
   188     NW_TinyDom_Handle_t domHandle;
       
   189     NW_Byte* buffer = (NW_Byte*)bodyPtr.Ptr();
       
   190     NW_Int32 length = (NW_Int32)bodyPtr.Size();
       
   191     NW_Bool encoded = ( contentType.CompareF( KSlTextContentType ) == 0 ) ? 
       
   192                                                          NW_FALSE : NW_TRUE;
       
   193     NW_Uint32 publicID = NW_SL_PublicId;
       
   194     NW_Bool extTNotStringTable = NW_FALSE; // What is this?
       
   195     NW_DOM_NodeType_t type = 0;
       
   196     /**********************************
       
   197     *   Root of DOM
       
   198     ***********************************/
       
   199     CDocumentTreeOwner* docTreeOwner = new (ELeave) CDocumentTreeOwner;
       
   200     CleanupStack::PushL( docTreeOwner );
       
   201     NW_DOM_DocumentNode_t* domNode = NW_DOM_DocumentNode_BuildTree
       
   202         ( 
       
   203                             &domHandle, 
       
   204                             buffer, 
       
   205                             length, 
       
   206                             encoded, 
       
   207                             publicID, 
       
   208                             extTNotStringTable 
       
   209         );
       
   210 	if (!domNode)
       
   211 		{
       
   212 		PUSHLOG_WRITE("CSLContentHandler::ParsePushMsgL: domNode is Null")
       
   213 		}
       
   214     User::LeaveIfNull( domNode );
       
   215     docTreeOwner->SetDocTree( domNode );
       
   216 
       
   217     type = NW_DOM_Node_getNodeType( domNode );
       
   218     if ( type != NW_DOM_DOCUMENT_NODE )
       
   219         {
       
   220         PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: Not Document node <%d>",type)
       
   221         User::Leave( KErrArgument );
       
   222         }
       
   223 
       
   224     iCharEncoding = NW_DOM_DocumentNode_getCharacterEncoding( domNode );
       
   225     PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: Doc char encoding <%x>",iCharEncoding)
       
   226 
       
   227     /**********************************
       
   228     *   ELEMENT sl
       
   229     ***********************************/
       
   230 	// first make sure if there any children in the dom tree, otherwise we will PANIC(in NW_DOM_DocumentNode_getDocumentElement) and crash WatcherMainThread.
       
   231 	TBool domNodeHasChildNodes = EFalse;
       
   232 	domNodeHasChildNodes = NW_DOM_Node_hasChildNodes( domNode );
       
   233 	PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: check if Dom tree has <SI> node <%d>", domNodeHasChildNodes)
       
   234 	if (!domNodeHasChildNodes)
       
   235         {
       
   236         PUSHLOG_WRITE("CSLContentHandler::ParsePushMsgL: No SL element present in the dom tree. Message corrupted.")
       
   237         User::Leave( KErrCorrupt );
       
   238         }
       
   239 
       
   240 	PUSHLOG_WRITE("CSLContentHandler::ParsePushMsgL: before calling getDocumentElement")
       
   241     NW_DOM_ElementNode_t* slElement = 
       
   242         NW_DOM_DocumentNode_getDocumentElement( domNode );
       
   243 	if (!slElement)
       
   244 		{
       
   245 		PUSHLOG_WRITE("CSLContentHandler::ParsePushMsgL: slElement is Null")
       
   246 		}
       
   247     User::LeaveIfNull( slElement );
       
   248 
       
   249     type = NW_DOM_Node_getNodeType( slElement );
       
   250 
       
   251     CStringOwner* stringOwner = new (ELeave) CStringOwner;
       
   252     CleanupStack::PushL( stringOwner );
       
   253 
       
   254     NW_String_t* name = NW_String_new();
       
   255     User::LeaveIfNull( name );
       
   256     stringOwner->SetString( name );
       
   257     stat = NW_DOM_Node_getNodeName( slElement, name );
       
   258 	PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: getNodeName ErrCode: %d", NwxStatusToErrCode( stat ))
       
   259     User::LeaveIfError( NwxStatusToErrCode( stat ) );
       
   260     NW_Byte*  nameBuf = NW_String_getStorage( name );
       
   261     NW_Uint16 nameLen = NW_String_getCharCount( name, iCharEncoding );
       
   262     TPtrC8 namePtr( nameBuf, nameLen );
       
   263 
       
   264     if ( type != NW_DOM_ELEMENT_NODE || namePtr.CompareF( KSl ) != 0 )
       
   265         {
       
   266         PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: Not sl element node <%d>",type)
       
   267         User::Leave( KErrArgument );
       
   268         }
       
   269 
       
   270     CleanupStack::PopAndDestroy( stringOwner ); // stringOwner
       
   271 
       
   272     /**********************************
       
   273     *   Attributes of ELEMENT sl
       
   274     ***********************************/
       
   275     if ( NW_DOM_ElementNode_hasAttributes( slElement ) )
       
   276         {
       
   277         NW_DOM_AttributeListIterator_t attrIter;
       
   278         stat = NW_DOM_ElementNode_getAttributeListIterator
       
   279                              ( slElement, &attrIter );
       
   280 		PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: getAttribListIter ErrCode: %d", NwxStatusToErrCode( stat ))
       
   281         User::LeaveIfError( NwxStatusToErrCode( stat ) );
       
   282 
       
   283         NW_DOM_AttributeHandle_t attrHandle;
       
   284         while( NW_DOM_AttributeListIterator_getNextAttribute
       
   285                ( &attrIter, &attrHandle ) == NW_STAT_WBXML_ITERATE_MORE )
       
   286             {
       
   287             ParseSlAttributeL( attrHandle );
       
   288             }
       
   289         }
       
   290 
       
   291     // Cleanup.
       
   292     CleanupStack::PopAndDestroy( 2, &wbxmlDict ); // docTreeOwner, wbxmlDict
       
   293 
       
   294     // if 'action' attribute not specified, the value 'execute-low' is used.
       
   295 	if ( !ActionFlag() )
       
   296         {
       
   297 		iPushMsgAction = CSLPushMsgEntry::ESLPushMsgExecuteLow;
       
   298         SetActionFlag( ETrue );
       
   299         PUSHLOG_WRITE_FORMAT(" Defaulting to ActionFlag: %d",iPushMsgAction)
       
   300         }
       
   301 
       
   302     iState = EProcessing;
       
   303     IdleComplete();
       
   304 
       
   305     PUSHLOG_LEAVEFN("CSLContentHandler::ParsePushMsgL")
       
   306 	}
       
   307 
       
   308 // ---------------------------------------------------------
       
   309 // CSLContentHandler::ParseSlAttributeL
       
   310 // ---------------------------------------------------------
       
   311 //
       
   312 void CSLContentHandler::ParseSlAttributeL
       
   313                         ( NW_DOM_AttributeHandle_t& aAttrHandle )
       
   314 	{
       
   315     PUSHLOG_ENTERFN("CSLContentHandler::ParseSlAttributeL")
       
   316 
       
   317     NW_Status_t stat = NW_STAT_SUCCESS;
       
   318 
       
   319     CStringOwner* attrNameOwner = new (ELeave) CStringOwner;
       
   320     CleanupStack::PushL( attrNameOwner );
       
   321 
       
   322     NW_String_t* attrName = NW_String_new();
       
   323     User::LeaveIfNull( attrName );
       
   324     attrNameOwner->SetString( attrName );
       
   325 
       
   326     // Get the name of the attribute.
       
   327     stat = NW_DOM_AttributeHandle_getName( &aAttrHandle, attrName );
       
   328     User::LeaveIfError( NwxStatusToErrCode( stat ) );
       
   329     NW_Byte*  attrNameBuf = NW_String_getStorage( attrName );
       
   330     NW_Uint16 attrNameLen = NW_String_getCharCount( attrName, iCharEncoding );
       
   331     TPtrC8 attrNamePtr( attrNameBuf, attrNameLen );
       
   332 
       
   333     if ( attrNamePtr.CompareF( KHref ) == 0 )
       
   334         {
       
   335         if ( !HrefFlag() )
       
   336             {
       
   337             HBufC* tempHrefBuf = NULL;
       
   338 
       
   339             CStringOwner* valOwner = new (ELeave) CStringOwner;
       
   340             CleanupStack::PushL( valOwner );
       
   341 
       
   342             NW_String_t* val = NW_String_new();
       
   343             User::LeaveIfNull( val );
       
   344             valOwner->SetString( val );
       
   345             stat = NW_DOM_AttributeHandle_getValue( &aAttrHandle, val );
       
   346             if ( stat != NW_STAT_DOM_NO_STRING_RETURNED )
       
   347                 {
       
   348                 User::LeaveIfError( NwxStatusToErrCode( stat ) );
       
   349                 NW_Byte* storage = NW_String_getStorage( val );
       
   350                 NW_Uint16 length = NW_String_getCharCount( val, iCharEncoding );
       
   351                 TPtrC8 prefixPtr( storage, length );
       
   352                 tempHrefBuf = HBufC::NewMaxL( length );
       
   353                 // No leavable after it!!! until...
       
   354                 tempHrefBuf->Des().Copy( prefixPtr );
       
   355                 }
       
   356 
       
   357             CleanupStack::PopAndDestroy( valOwner ); // valOwner
       
   358 
       
   359             if ( tempHrefBuf )
       
   360                 {
       
   361                 if ( tempHrefBuf->Length() == 0 )
       
   362                     {
       
   363                     // Zero length Href is considered as nothing.
       
   364                     PUSHLOG_WRITE(" Zero length HrefFlag");
       
   365                     }
       
   366                 else
       
   367                     {
       
   368                     iHrefBuf = tempHrefBuf; // ...until here.
       
   369                     SetHrefFlag( ETrue );
       
   370                     PUSHLOG_WRITE_FORMAT(" HrefFlag set <%S>",iHrefBuf);
       
   371                     }
       
   372                 }
       
   373             }
       
   374         }
       
   375     else if ( attrNamePtr.CompareF( KAction ) == 0 )
       
   376         {
       
   377         if ( !ActionFlag() )
       
   378             {
       
   379             CStringOwner* stringOwner = new (ELeave) CStringOwner;
       
   380             CleanupStack::PushL( stringOwner );
       
   381 
       
   382             NW_String_t* val = NW_String_new();
       
   383             User::LeaveIfNull( val );
       
   384             stringOwner->SetString( val );
       
   385             stat = NW_DOM_AttributeHandle_getValue( &aAttrHandle, val ); 
       
   386             User::LeaveIfError( NwxStatusToErrCode( stat ) );
       
   387             NW_Byte* storage = NW_String_getStorage( val );
       
   388             NW_Uint16 length = NW_String_getCharCount( val, iCharEncoding );
       
   389             TPtrC8 actionPtr( storage, length );
       
   390 
       
   391             iPushMsgAction = ConvertActionString( actionPtr );
       
   392             SetActionFlag( ETrue );
       
   393             PUSHLOG_WRITE_FORMAT(" ActionFlag: %d",iPushMsgAction)
       
   394 
       
   395             CleanupStack::PopAndDestroy( stringOwner );
       
   396             }
       
   397         }
       
   398     else
       
   399         {
       
   400         __ASSERT_DEBUG( EFalse, 
       
   401             ContHandPanic( EPushContHandPanUnexpSlToken ) );
       
   402         }
       
   403 
       
   404     CleanupStack::PopAndDestroy( attrNameOwner ); // attrNameOwner
       
   405 
       
   406     PUSHLOG_LEAVEFN("CSLContentHandler::ParseSlAttributeL")
       
   407     }
       
   408 
       
   409 // ---------------------------------------------------------
       
   410 // CSLContentHandler::ConvertActionString
       
   411 // ---------------------------------------------------------
       
   412 //
       
   413 TUint CSLContentHandler::ConvertActionString
       
   414                          ( const TDesC8& aActionString ) const
       
   415 	{
       
   416 	const TInt KMatchFound = 0;
       
   417 
       
   418 	// if 'action' attribute not specified, the value 'execute-low' is used.
       
   419 	TUint actionValue = CSLPushMsgEntry::ESLPushMsgExecuteLow;
       
   420 
       
   421 	if ( aActionString.Compare( KExecHigh ) == KMatchFound )
       
   422         {
       
   423 		actionValue = CSLPushMsgEntry::ESLPushMsgExecuteHigh;
       
   424         }
       
   425 	else if ( aActionString.Compare( KExecLow ) == KMatchFound )
       
   426         {
       
   427 		actionValue = CSLPushMsgEntry::ESLPushMsgExecuteLow;
       
   428         }
       
   429 	else if ( aActionString.Compare( KCache ) == KMatchFound )
       
   430         {
       
   431 		actionValue = CSLPushMsgEntry::ESLPushMsgExecuteCache;
       
   432         }
       
   433 
       
   434 	return actionValue;
       
   435 	}
       
   436 
       
   437 // ---------------------------------------------------------
       
   438 // CSLContentHandler::SetSlPushMsgEntryFieldsL
       
   439 // ---------------------------------------------------------
       
   440 //
       
   441 void CSLContentHandler::SetSlPushMsgEntryFieldsL( CSLPushMsgEntry& 
       
   442                                                   aSlPushMsgEntry ) const
       
   443 	{
       
   444     PUSHLOG_ENTERFN("CSLContentHandler::SetSlPushMsgEntryFieldsL")
       
   445 
       
   446 	// Set URL and Action fields.
       
   447     if ( HrefFlag() )
       
   448         {
       
   449 	    aSlPushMsgEntry.SetUrlL( *iHrefBuf );
       
   450         }
       
   451 
       
   452     __ASSERT_DEBUG( ActionFlag(), 
       
   453                     ContHandPanic( EPushContHandPanUnspecSlAction ) );
       
   454     if ( ActionFlag() )
       
   455         {
       
   456 	    aSlPushMsgEntry.SetAction( iPushMsgAction );
       
   457         }
       
   458     else // if not specified, the value 'execute-low' is used.
       
   459         {
       
   460         aSlPushMsgEntry.SetAction( CSLPushMsgEntry::ESLPushMsgExecuteLow );
       
   461         }
       
   462 
       
   463 	// Set all the relevant header fields.
       
   464 	TPtrC8 msgHeaderPtr;
       
   465 	iMessage->GetHeader( msgHeaderPtr );
       
   466 	aSlPushMsgEntry.SetHeaderL( msgHeaderPtr );
       
   467 
       
   468     // Get server address.
       
   469     TPtrC8 srvAddress;
       
   470     if ( iMessage->GetServerAddress( srvAddress ) )
       
   471         {
       
   472 	    aSlPushMsgEntry.SetFromL( srvAddress );
       
   473         }
       
   474 
       
   475     // First line in Inbox: TMsvEntry::iDetails.
       
   476     if ( srvAddress.Length() == 0 )
       
   477         {
       
   478         // Read from resource.
       
   479         HBufC* details = 
       
   480             iStrRscReader->AllocReadResourceLC( R_PUSHMISC_UNK_SENDER );
       
   481         aSlPushMsgEntry.SetMsgDetailsL( *details );
       
   482         CleanupStack::PopAndDestroy( details );
       
   483         }
       
   484     else
       
   485         {
       
   486         // Convert the "From" information to the format required by the UI 
       
   487         // spec and then decode it.
       
   488         HBufC* details = iWapPushUtils->ConvertDetailsL( srvAddress );
       
   489         CleanupStack::PushL( details );
       
   490         HBufC* convertedFrom = 
       
   491             CPushMtmUtil::ConvertUriToDisplayFormL( *details );
       
   492         CleanupStack::PushL( convertedFrom );
       
   493         //
       
   494         aSlPushMsgEntry.SetMsgDetailsL( *convertedFrom );
       
   495         //
       
   496         CleanupStack::PopAndDestroy( 2, details ); // convertedFrom, details
       
   497         }
       
   498 
       
   499     // Second line in Inbox: TMsvEntry::iDescription.
       
   500     // Read from resource.
       
   501     HBufC* description = 
       
   502         iStrRscReader->AllocReadResourceLC( R_PUSHMISC_INBOX_SERV_MSG );
       
   503     aSlPushMsgEntry.SetMsgDescriptionL( *description );
       
   504     CleanupStack::PopAndDestroy( description );
       
   505 
       
   506     // ******** Push MTM specific processing *********
       
   507 
       
   508     /*
       
   509     * Unfortunately in CPushMsgEntryBase there is no such functionality 
       
   510     * with which we can reach TMsvEntry as non-const, but we have to 
       
   511     * modify the entry's iMtmData2 member somehow. We can do it 
       
   512     * with either casting or with modifying and saving the entry 
       
   513     * manually after it has been saved by CSLPushMsgEntry. The latter 
       
   514     * solution is more expensive so we choose the first.
       
   515     */
       
   516     TMsvEntry& tEntry = CONST_CAST( TMsvEntry&, aSlPushMsgEntry.Entry() );
       
   517     if ( HrefFlag() )
       
   518         {
       
   519         CPushMtmUtil::SetAttrs( tEntry, EPushMtmAttrHasHref );
       
   520         }
       
   521     else
       
   522         {
       
   523         CPushMtmUtil::ResetAttrs( tEntry, EPushMtmAttrHasHref );
       
   524         }
       
   525 
       
   526     // Indication is required if the entry is saved as 'read' (delete & 
       
   527     // replacement notification). It can happen only in case of SL message.
       
   528     // Otherwise the flag has to be cleared!
       
   529     if ( !iSaveAsRead )
       
   530         {
       
   531         // Saving as unread & new.
       
   532         tEntry.SetNew( ETrue );
       
   533         tEntry.SetUnread( ETrue );
       
   534         CPushMtmUtil::ResetAttrs( tEntry, EPushMtmReadButContentChanged );
       
   535         }
       
   536     else
       
   537         {
       
   538         // Saving as read.
       
   539         tEntry.SetNew( EFalse );
       
   540         tEntry.SetUnread( EFalse );
       
   541         CPushMtmUtil::SetAttrs( tEntry, EPushMtmReadButContentChanged );
       
   542         }
       
   543 
       
   544     PUSHLOG_LEAVEFN("CSLContentHandler::SetSlPushMsgEntryFieldsL")
       
   545     }
       
   546 
       
   547 // ---------------------------------------------------------
       
   548 // CSLContentHandler::ProcessingPushMsgEntryL
       
   549 // ---------------------------------------------------------
       
   550 //
       
   551 void CSLContentHandler::ProcessingPushMsgEntryL()
       
   552 	{
       
   553     PUSHLOG_ENTERFN("CSLContentHandler::ProcessingPushMsgEntryL")
       
   554 
       
   555     TBool discardPushMsg( EFalse );
       
   556 
       
   557     __ASSERT_DEBUG( ActionFlag(), 
       
   558                     ContHandPanic( EPushContHandPanUnspecSlAction ) );
       
   559 
       
   560     // S60 requirement: if the href is empty then delete (discard) the msg.
       
   561     if ( HrefFlag() == EFalse )
       
   562         {
       
   563         PUSHLOG_WRITE(" No SL Href.")
       
   564         discardPushMsg = ETrue;
       
   565         }
       
   566     else
       
   567         {
       
   568         __ASSERT_DEBUG( HrefFlag() && iHrefBuf, 
       
   569                         ContHandPanic( EPushContHandPanUnspecSlHref ) );
       
   570 
       
   571         // The message will not be discarded
       
   572         discardPushMsg = EFalse;
       
   573 
       
   574         CMsvEntrySelection* matchingUrlList = iWapPushUtils->FindUrlLC
       
   575                                               ( *iHrefBuf, KUidWapPushMsgSL );
       
   576         TInt matchingListCount = matchingUrlList->Count();
       
   577         PUSHLOG_WRITE_FORMAT(" matchingListCount: %d",matchingListCount)
       
   578 
       
   579         // Only one SL is allowed with the same Url, so leave the first and 
       
   580         // delete the others.
       
   581         if ( 1 < matchingListCount )
       
   582             {
       
   583             for ( TInt count = 1; count < matchingListCount; ++count )
       
   584                 {
       
   585                 iWapPushUtils->DeleteEntryL( matchingUrlList->At(count) );
       
   586                 }
       
   587             matchingListCount = 1; // Only one remains.
       
   588             }
       
   589 
       
   590 	    if ( 0 < matchingListCount )
       
   591 		    {
       
   592 		    // Find msg of the same href and discard it if it has a lower or 
       
   593             // the same action value.
       
   594             CSLPushMsgEntry* matchingSl = CSLPushMsgEntry::NewL();
       
   595 	        CleanupStack::PushL( matchingSl );
       
   596 
       
   597             const TMsvId matchingId = matchingUrlList->At(0);
       
   598             matchingSl->RetrieveL( *iMsvSession, matchingId );
       
   599 
       
   600             if ( iPushMsgAction <= matchingSl->Action() ) 
       
   601 			    {
       
   602                 PUSHLOG_WRITE(" SL: not higher action")
       
   603                 discardPushMsg = ETrue;
       
   604                 }
       
   605 
       
   606             CleanupStack::PopAndDestroy( matchingSl ); // matchingSl, 
       
   607             }
       
   608 
       
   609 	    CleanupStack::PopAndDestroy( matchingUrlList ); // matchingUrlList
       
   610         }
       
   611 
       
   612     if ( discardPushMsg )
       
   613         {
       
   614         // Nothing to do.
       
   615         PUSHLOG_WRITE(" SL discarded.")
       
   616         iState = EDone;
       
   617         IdleComplete();
       
   618         }
       
   619     else
       
   620         {
       
   621         iState = HandleServiceInvocationL();
       
   622         IdleComplete();
       
   623         }
       
   624 
       
   625     __ASSERT_DEBUG( iSavedMsgId == KMsvNullIndexEntryId, 
       
   626                     ContHandPanic( EPushContHandPanSlMsgIdSet ) );
       
   627 
       
   628     PUSHLOG_LEAVEFN("CSLContentHandler::ProcessingPushMsgEntryL")
       
   629 	}
       
   630 
       
   631 // ---------------------------------------------------------
       
   632 // CSLContentHandler::HandleServiceInvocationL
       
   633 // ---------------------------------------------------------
       
   634 //
       
   635 TInt CSLContentHandler::HandleServiceInvocationL() const
       
   636     {
       
   637     PUSHLOG_ENTERFN("CSLContentHandler::HandleServiceInvocationL")
       
   638 
       
   639     TInt nextState = ESavePushMsgEntry;
       
   640 
       
   641     if ( iPushMsgAction == CSLPushMsgEntry::ESLPushMsgExecuteCache )
       
   642         {
       
   643         PUSHLOG_WRITE(" SL cache");
       
   644         TBool isAuthenticated = TPushAuthenticationUtil::
       
   645             AuthenticateMsgL( *iMtmSettings, *iMessage );
       
   646 		if ( !isAuthenticated )
       
   647             {
       
   648             PUSHLOG_WRITE(" Not authenticated");
       
   649             // The message is placed to Inbox.
       
   650             nextState = ESavePushMsgEntry;
       
   651             }
       
   652         else
       
   653             {
       
   654             // Authenticated. Fetch SL-cache.
       
   655             nextState = EFetching;
       
   656             }
       
   657         }
       
   658 
       
   659     else if ( iPushMsgAction == CSLPushMsgEntry::ESLPushMsgExecuteLow )
       
   660         {
       
   661         PUSHLOG_WRITE(" SL execute-low")
       
   662         // It is independent from Automatic/Manual setting and WL 
       
   663         // authentication is not applied. The message is placed to Inbox 
       
   664         // for manual downloading.
       
   665         nextState = ESavePushMsgEntry;
       
   666         }
       
   667 
       
   668     else // ESLPushMsgExecuteHigh
       
   669         {
       
   670         PUSHLOG_WRITE(" SL execute-high");
       
   671         // If the settings is Manual or it does not pass the WL authentication 
       
   672 		// then it is placed to Inbox for manual downloading.
       
   673         // If the setting is Automatic and it passes the WL authentication, 
       
   674         // the Browser is started standalone to download the URL without any 
       
   675 		// user interaction.
       
   676         if ( iMtmSettings->ServiceLoadingType() == 
       
   677 			               CPushMtmSettings::EManual )
       
   678             {
       
   679             PUSHLOG_WRITE(" Manual setting")
       
   680             // The message is placed to Inbox.
       
   681             nextState = ESavePushMsgEntry;
       
   682             }
       
   683         else // Automatic loading
       
   684             {
       
   685             PUSHLOG_WRITE(" Automatic setting");
       
   686             // Authenticate the message.
       
   687             TBool isAuthenticated = TPushAuthenticationUtil::
       
   688                 AuthenticateMsgL( *iMtmSettings, *iMessage );
       
   689             if ( !isAuthenticated )
       
   690 	            {
       
   691                 PUSHLOG_WRITE(" Not authenticated");
       
   692 	            // The message is placed to Inbox.
       
   693 	            nextState = ESavePushMsgEntry;
       
   694 	            }
       
   695             else
       
   696 	            {
       
   697 	            // Authenticated - start downloading.
       
   698 	            nextState = EFetching;
       
   699 	            }
       
   700             }
       
   701         }
       
   702 
       
   703     PUSHLOG_LEAVEFN("CSLContentHandler::HandleServiceInvocationL")
       
   704     return nextState;
       
   705     }
       
   706 
       
   707 // ---------------------------------------------------------
       
   708 // CSLContentHandler::FetchPushMsgEntryL
       
   709 // ---------------------------------------------------------
       
   710 //
       
   711 void CSLContentHandler::FetchPushMsgEntryL()
       
   712 	{
       
   713     PUSHLOG_ENTERFN("CSLContentHandler::FetchPushMsgEntryL")
       
   714 
       
   715     __ASSERT_DEBUG( iSavedMsgId == KMsvNullIndexEntryId, 
       
   716                     ContHandPanic( EPushContHandPanAlreadyInitialized ) );
       
   717     __ASSERT_DEBUG( HrefFlag() && iHrefBuf, 
       
   718                     ContHandPanic( EPushContHandPanUnspecSlHref ) );
       
   719 
       
   720     /* 
       
   721     * In case of execute-high use the Browser to download the service.
       
   722     * In case of cache use the fetch operation to download the service 
       
   723     * silently. 
       
   724     */
       
   725 
       
   726     if ( iPushMsgAction == CSLPushMsgEntry::ESLPushMsgExecuteHigh )
       
   727         {
       
   728         PUSHLOG_WRITE(" Start Browser")
       
   729         // Launch the Browser with the URI, then save the message.
       
   730         // Trap errors. If Browser's launching fails, then save the 
       
   731         // message as 'unread'. In case of an error, it is not forwarded.
       
   732         TRAPD( err, StartBrowserL() );
       
   733         iState = ESavePushMsgEntry;
       
   734         // Mark it 'read' after succesfull Browser startup.
       
   735         iSaveAsRead = err ? EFalse : ETrue;
       
   736         IdleComplete();
       
   737         }
       
   738     else if ( iPushMsgAction == CSLPushMsgEntry::ESLPushMsgExecuteCache )
       
   739         {
       
   740         // Fetch the service inside the content handler.
       
   741         iStatus = KRequestPending;
       
   742         SetActive();
       
   743         __ASSERT_DEBUG( !iFetchOp, 
       
   744                         ContHandPanic( EPushContHandPanFetchAlreadyInit ) );
       
   745 
       
   746         iFetchOp = CPushMtmAutoFetchOperation::NewL( *iHrefBuf, 
       
   747                                                      KAutofetchDelayInSec, 
       
   748                                                      iStatus );
       
   749         iFetchOp->StartL();
       
   750         PUSHLOG_WRITE(" Fetch op started")
       
   751         iState = EFetchCompleted; // Next state.
       
   752         // Fetch completes it.
       
   753         }
       
   754     else
       
   755         {
       
   756         __ASSERT_DEBUG( EFalse, 
       
   757                         ContHandPanic( EPushContHandPanBadActionValue ) );
       
   758         User::Leave( KErrNotSupported );
       
   759         }
       
   760 
       
   761     PUSHLOG_LEAVEFN("CSLContentHandler::FetchPushMsgEntryL")
       
   762     }
       
   763 
       
   764 // ---------------------------------------------------------
       
   765 // CSLContentHandler::StartBrowserL
       
   766 // ---------------------------------------------------------
       
   767 //
       
   768 void CSLContentHandler::StartBrowserL()
       
   769     {
       
   770     PUSHLOG_ENTERFN("CSLContentHandler::StartBrowserL")
       
   771 
       
   772     // Parameters are separated by space
       
   773     // 1st parameter: type of the further parameters
       
   774     // 2nd parameter: URL
       
   775     //
       
   776     HBufC* param = HBufC::NewLC( KBrowserCmdFetchUrl().Length() + 
       
   777                                  iHrefBuf->Length() );
       
   778     TPtr paramPtr = param->Des();
       
   779     paramPtr.Copy( KBrowserCmdFetchUrl );
       
   780     paramPtr.Append( *iHrefBuf );
       
   781 
       
   782     RWsSession wsSession;
       
   783     User::LeaveIfError( wsSession.Connect() );
       
   784     CleanupClosePushL<RWsSession>( wsSession );
       
   785     TApaTaskList taskList( wsSession );
       
   786     TApaTask task = taskList.FindApp( KBrowserAppUid );
       
   787 
       
   788     if ( task.Exists() )
       
   789         {
       
   790         PUSHLOG_WRITE("CSLContentHandler Browser::SendMessage")
       
   791 
       
   792         RFs             rfs;
       
   793         RFile           file;
       
   794         TPtrC8          param8Ptr;
       
   795         // 8-bit buffer is required.
       
   796         HBufC8* param8 = HBufC8::NewLC( param->Length() );
       
   797         param8->Des().Copy( *param );
       
   798         param8Ptr.Set(param8->Des());
       
   799 
       
   800         // Open the file.
       
   801         User::LeaveIfError(rfs.Connect());
       
   802         CleanupClosePushL(rfs);
       
   803 
       
   804         // Replace file if exists or Create file if not exist yet
       
   805         User::LeaveIfError( file.Replace( rfs, KPushMtmUrl, EFileWrite | EFileShareExclusive ) );
       
   806         CleanupClosePushL(file);
       
   807 
       
   808         // Write to file      
       
   809         User::LeaveIfError( file.Write( param8Ptr ) );
       
   810         
       
   811         // Clean up.
       
   812         CleanupStack::PopAndDestroy(/*file*/);
       
   813         CleanupStack::PopAndDestroy(/*rfs*/);
       
   814         CleanupStack::PopAndDestroy( /*param8*/ );
       
   815         }
       
   816     else 
       
   817         {
       
   818         PUSHLOG_WRITE("CSLContentHandler Browser::StartDocument")
       
   819         RApaLsSession appArcSession;
       
   820         User::LeaveIfError( appArcSession.Connect() );
       
   821         CleanupClosePushL<RApaLsSession>( appArcSession );
       
   822         TThreadId id;
       
   823         User::LeaveIfError
       
   824             (
       
   825                 appArcSession.StartDocument( *param, KBrowserAppUid, id )
       
   826             );
       
   827         CleanupStack::PopAndDestroy( &appArcSession );
       
   828         }
       
   829 
       
   830     CleanupStack::PopAndDestroy( &wsSession );
       
   831     CleanupStack::PopAndDestroy( param );
       
   832 
       
   833     PUSHLOG_LEAVEFN("CSLContentHandler::StartBrowserL")
       
   834     }
       
   835 
       
   836 // ---------------------------------------------------------
       
   837 // CSLContentHandler::FetchCompletedL
       
   838 // ---------------------------------------------------------
       
   839 //
       
   840 void CSLContentHandler::FetchCompletedL()
       
   841 	{
       
   842     PUSHLOG_ENTERFN("CSLContentHandler::FetchCompletedL")
       
   843 
       
   844     __ASSERT_DEBUG( iPushMsgAction == CSLPushMsgEntry::ESLPushMsgExecuteCache, 
       
   845                     ContHandPanic( EPushContHandPanBadActionValue ) );
       
   846     __ASSERT_DEBUG( iSavedMsgId == KMsvNullIndexEntryId, 
       
   847                     ContHandPanic( EPushContHandPanAlreadyInitialized ) );
       
   848     __ASSERT_DEBUG( iFetchOp, ContHandPanic( EPushContHandPanNoFetchOp ) );
       
   849 
       
   850     const TInt fetchRes = iStatus.Int();
       
   851     PUSHLOG_WRITE_FORMAT(" fetchRes <%d>",fetchRes)
       
   852 
       
   853     if ( fetchRes != KErrNone )
       
   854         {
       
   855         // Downloading failed. Save the message.
       
   856         iState = ESavePushMsgEntry;
       
   857         }
       
   858     else
       
   859         {
       
   860         // Silent fetching has completed successfully.
       
   861         // The message should not be saved.
       
   862         iState = EDone;
       
   863         }
       
   864 
       
   865     // Next state set. Complete.
       
   866     IdleComplete();
       
   867 
       
   868     PUSHLOG_LEAVEFN("CSLContentHandler::FetchCompletedL")
       
   869     }
       
   870 
       
   871 // ---------------------------------------------------------
       
   872 // CSLContentHandler::SavePushMsgEntryL
       
   873 // ---------------------------------------------------------
       
   874 //
       
   875 void CSLContentHandler::SavePushMsgEntryL()
       
   876     {
       
   877     PUSHLOG_ENTERFN("CSLContentHandler::SavePushMsgEntryL")
       
   878 
       
   879     __ASSERT_DEBUG( ActionFlag(), 
       
   880                     ContHandPanic( EPushContHandPanUnspecSlAction ) );
       
   881     __ASSERT_DEBUG( HrefFlag() && iHrefBuf, 
       
   882                     ContHandPanic( EPushContHandPanUnspecSlHref ) );
       
   883     __ASSERT_DEBUG( iSavedMsgId == KMsvNullIndexEntryId, 
       
   884                     ContHandPanic( EPushContHandPanAlreadyInitialized ) );
       
   885 
       
   886     CMsvEntrySelection* matchingUrlList = iWapPushUtils->FindUrlLC
       
   887                                           ( *iHrefBuf, KUidWapPushMsgSL );
       
   888     TInt matchingListCount = matchingUrlList->Count();
       
   889     PUSHLOG_WRITE_FORMAT(" matchingListCount: %d",matchingListCount)
       
   890 
       
   891     // Only one SL is allowed with the same Url, so leave the first and 
       
   892     // delete the others.
       
   893     __ASSERT_DEBUG( matchingListCount <= 1, 
       
   894                     ContHandPanic( EPushContHandPanTooManySl ) );
       
   895     if ( 1 < matchingListCount )
       
   896         {
       
   897         for ( TInt count = 1; count < matchingListCount; ++count )
       
   898             {
       
   899             iWapPushUtils->DeleteEntryL( matchingUrlList->At(count) );
       
   900             }
       
   901         matchingListCount = 1; // Only one remains.
       
   902         }
       
   903 
       
   904     TBool saveNewMsg = ETrue; // Save by default.
       
   905     TMsvId matchingEntryId = KMsvNullIndexEntryId;
       
   906 
       
   907     // Apply reception rules.
       
   908     if ( matchingListCount == 0 )
       
   909         {
       
   910         // Nothing to do.
       
   911         saveNewMsg = ETrue;
       
   912         }
       
   913     else
       
   914         {
       
   915         CSLPushMsgEntry* matchingSl = CSLPushMsgEntry::NewL();
       
   916         CleanupStack::PushL( matchingSl );
       
   917 
       
   918         matchingEntryId = matchingUrlList->At(0);
       
   919         matchingSl->RetrieveL( *iMsvSession, matchingEntryId );
       
   920 
       
   921         if ( iPushMsgAction <= matchingSl->Action() ) 
       
   922             {
       
   923             // Discard the new SL: it does not have higher 
       
   924             // action value as the existing.
       
   925             PUSHLOG_WRITE(" SL not higher action - discarded")
       
   926             saveNewMsg = EFalse;
       
   927             }
       
   928         else
       
   929             {
       
   930             // The new has greater action attribute. 
       
   931             // Update the old SL with the new data.
       
   932             saveNewMsg = ETrue;
       
   933             }
       
   934 
       
   935         CleanupStack::PopAndDestroy( matchingSl ); // matchingSl
       
   936         }
       
   937 
       
   938     CleanupStack::PopAndDestroy( matchingUrlList ); // matchingUrlList
       
   939 
       
   940     // Store message if not marked for deletion.
       
   941     if ( saveNewMsg )
       
   942         {
       
   943 		StoreSLMessageL( matchingEntryId );
       
   944 		}
       
   945 
       
   946     iState = EDone;
       
   947     IdleComplete();
       
   948 
       
   949     PUSHLOG_LEAVEFN("CSLContentHandler::SavePushMsgEntryL")
       
   950     }
       
   951 
       
   952 // ---------------------------------------------------------
       
   953 // CSLContentHandler::StoreSLMessageL
       
   954 // ---------------------------------------------------------
       
   955 //
       
   956 void CSLContentHandler::StoreSLMessageL( TMsvId aMatchingEntryId )
       
   957 	{
       
   958     PUSHLOG_ENTERFN("CSLContentHandler::StoreSLMessageL")
       
   959 
       
   960 	CSLPushMsgEntry* slEntry = CSLPushMsgEntry::NewL();
       
   961 	CleanupStack::PushL( slEntry );
       
   962 
       
   963     if ( aMatchingEntryId == KMsvNullIndexEntryId )
       
   964         {
       
   965         PUSHLOG_WRITE(" No matching SL")
       
   966         // Save new to Inbox.
       
   967         SetSlPushMsgEntryFieldsL( *slEntry );
       
   968 	    iSavedMsgId = 
       
   969             slEntry->SaveL( *iMsvSession, KMsvGlobalInBoxIndexEntryId );
       
   970         // Set the entry to read and *not* new state depending on iSaveAsRead.
       
   971         if ( !iSaveAsRead )
       
   972             {
       
   973             // Do nothing SaveL saves it as unread.
       
   974             }
       
   975         else
       
   976             {
       
   977             // SaveL owerrides the read settings (iEntry.SetUnread(ETrue);) 
       
   978             // that we set in SetSlPushMsgEntryFieldsL, thus the read status 
       
   979             // has to be reset manually here:
       
   980             iWapPushUtils->MarkServiceUnreadL( iSavedMsgId, EFalse );
       
   981             }
       
   982         }
       
   983     else
       
   984         {
       
   985         PUSHLOG_WRITE(" Matching SL")
       
   986         slEntry->RetrieveL( *iMsvSession, aMatchingEntryId );
       
   987         SetSlPushMsgEntryFieldsL( *slEntry );
       
   988 
       
   989         slEntry->UpdateL( *iMsvSession );
       
   990         iSavedMsgId = aMatchingEntryId;
       
   991         // Note that UpdateL does not change the read/unread status.
       
   992 
       
   993         // Move the updated msg back to Inbox.
       
   994         TMsvId parentId = slEntry->Entry().Parent();
       
   995         if ( parentId != KMsvGlobalInBoxIndexEntryId )
       
   996 	        {
       
   997             PUSHLOG_WRITE(" Moving back to Inbox")
       
   998             CMsvEntry* cParent = iMsvSession->GetEntryL( parentId );
       
   999             CleanupStack::PushL( cParent );
       
  1000 	        cParent->MoveL( iSavedMsgId, KMsvGlobalInBoxIndexEntryId );
       
  1001             CleanupStack::PopAndDestroy( cParent ); // cParent
       
  1002 	        }
       
  1003         }
       
  1004 
       
  1005 #ifdef __TEST_LOG__
       
  1006         _LIT( KDateFormat, "%E%D%X%N%Y %1 %2 %3" );
       
  1007         _LIT( KTimeFormat, "%-B%:0%J%:1%T%:2%S%:3%+B" );
       
  1008         TBuf<32> dateHolder;
       
  1009         TBuf<32> timeHolder;
       
  1010         TTime recDateTime = slEntry->ReceivedDate();
       
  1011         recDateTime.FormatL( dateHolder, KDateFormat );
       
  1012         recDateTime.FormatL( timeHolder, KTimeFormat );
       
  1013         PUSHLOG_WRITE_FORMAT(" rec date: <%S>",&dateHolder)
       
  1014         PUSHLOG_WRITE_FORMAT(" rec time: <%S>",&timeHolder)
       
  1015 #endif // __TEST_LOG__
       
  1016 
       
  1017 	CleanupStack::PopAndDestroy( slEntry ); // slEntry
       
  1018 
       
  1019     PUSHLOG_LEAVEFN("CSLContentHandler::StoreSLMessageL")
       
  1020 	}
       
  1021 
       
  1022 
       
  1023 // ---------------------------------------------------------
       
  1024 // CSLContentHandler::HandleMessageL
       
  1025 // ---------------------------------------------------------
       
  1026 //
       
  1027 void CSLContentHandler::HandleMessageL( CPushMessage* aPushMsg, 
       
  1028                                         TRequestStatus& aStatus )
       
  1029 	{
       
  1030     PUSHLOG_ENTERFN("CSLContentHandler::HandleMessageL 2")
       
  1031 
       
  1032     __ASSERT_DEBUG( aPushMsg != NULL, 
       
  1033                     ContHandPanic( EPushContHandPanMsgNull ) );
       
  1034 
       
  1035 #ifdef __TEST_LOG__
       
  1036     TPtrC8 bodyPtr;
       
  1037     aPushMsg->GetMessageBody( bodyPtr );
       
  1038     PUSHLOG_HEXDUMP( bodyPtr )
       
  1039 #endif // __TEST_LOG__
       
  1040 
       
  1041 	iMessage = aPushMsg;
       
  1042 	iAcknowledge = ETrue;
       
  1043 	SetConfirmationStatus( aStatus );
       
  1044 
       
  1045 	iState = EGarbageCollecting;
       
  1046 	IdleComplete();
       
  1047 
       
  1048     PUSHLOG_LEAVEFN("CSLContentHandler::HandleMessageL 2")
       
  1049     }
       
  1050 
       
  1051 // ---------------------------------------------------------
       
  1052 // CSLContentHandler::HandleMessageL
       
  1053 // ---------------------------------------------------------
       
  1054 //
       
  1055 void CSLContentHandler::HandleMessageL( CPushMessage* aPushMsg )
       
  1056 	{
       
  1057     PUSHLOG_ENTERFN("CSLContentHandler::HandleMessageL 1")
       
  1058 
       
  1059     __ASSERT_DEBUG( aPushMsg != NULL, 
       
  1060                     ContHandPanic( EPushContHandPanMsgNull ) );
       
  1061 	
       
  1062 #ifdef __TEST_LOG__
       
  1063     TPtrC8 bodyPtr;
       
  1064     aPushMsg->GetMessageBody( bodyPtr );
       
  1065     PUSHLOG_HEXDUMP( bodyPtr )
       
  1066 #endif // __TEST_LOG__
       
  1067 
       
  1068 	iAcknowledge = EFalse;
       
  1069 	iMessage = aPushMsg;
       
  1070 
       
  1071 	iState = EGarbageCollecting;
       
  1072 	IdleComplete();
       
  1073 
       
  1074     PUSHLOG_LEAVEFN("CSLContentHandler::HandleMessageL 1")
       
  1075     }
       
  1076 
       
  1077 // ---------------------------------------------------------
       
  1078 // CSLContentHandler::CancelHandleMessage
       
  1079 // ---------------------------------------------------------
       
  1080 //
       
  1081 void CSLContentHandler::CancelHandleMessage()
       
  1082 	{
       
  1083     Cancel();
       
  1084 	}
       
  1085 
       
  1086 // ---------------------------------------------------------
       
  1087 // CSLContentHandler::CPushHandlerBase_Reserved1
       
  1088 // ---------------------------------------------------------
       
  1089 //
       
  1090 void CSLContentHandler::CPushHandlerBase_Reserved1()
       
  1091 	{
       
  1092 	}
       
  1093 
       
  1094 // ---------------------------------------------------------
       
  1095 // CSLContentHandler::CPushHandlerBase_Reserved1
       
  1096 // ---------------------------------------------------------
       
  1097 //
       
  1098 void CSLContentHandler::CPushHandlerBase_Reserved2()
       
  1099 	{
       
  1100 	}
       
  1101 
       
  1102 // ---------------------------------------------------------
       
  1103 // CSLContentHandler::DoCancel
       
  1104 // ---------------------------------------------------------
       
  1105 //
       
  1106 void CSLContentHandler::DoCancel()
       
  1107 	{
       
  1108     PUSHLOG_ENTERFN("CSLContentHandler::DoCancel")
       
  1109     // TODO Cancel outstanding requests!
       
  1110 	Complete( KErrCancel );
       
  1111     PUSHLOG_LEAVEFN("CSLContentHandler::DoCancel")
       
  1112 	}
       
  1113 
       
  1114 // ---------------------------------------------------------
       
  1115 // CSLContentHandler::RunL
       
  1116 // ---------------------------------------------------------
       
  1117 //
       
  1118 void CSLContentHandler::RunL()
       
  1119 	{
       
  1120     PUSHLOG_ENTERFN("CSLContentHandler::RunL")
       
  1121 
       
  1122     // Handle errors in RunError().
       
  1123     PUSHLOG_WRITE_FORMAT(" iStatus.Int(): %d",iStatus.Int())
       
  1124 
       
  1125 	switch ( iState )
       
  1126 		{
       
  1127 	    case EGarbageCollecting:
       
  1128             {
       
  1129 		    CollectGarbageL();
       
  1130 		    break;
       
  1131             }
       
  1132 
       
  1133 
       
  1134         case EFilteringAndParsing:
       
  1135             {
       
  1136             if(iPushSLEnabled)
       
  1137                 {
       
  1138                 if ( !FilterPushMsgL() )
       
  1139                     {
       
  1140                     // It did not pass the filter. Done.
       
  1141                     iState = EDone;
       
  1142                     IdleComplete();
       
  1143                     }
       
  1144                 else
       
  1145                     {
       
  1146                     // Continue.
       
  1147                     TInt ret = KErrNone;
       
  1148                     PUSHLOG_WRITE("CSLContentHandler::RunL : before trapping parsing.")
       
  1149                     TRAP(ret, ParsePushMsgL());
       
  1150                     PUSHLOG_WRITE_FORMAT("CSLContentHandler::RunL : after trapping parsing. ret = %d", ret)
       
  1151                     if ( ret != KErrNone)
       
  1152                         {
       
  1153                         PUSHLOG_WRITE("CSLContentHandler::RunL : Parsing failed. discarding message.")
       
  1154                         iState = EDone;
       
  1155                         IdleComplete();
       
  1156                         }
       
  1157                     }
       
  1158                 }
       
  1159 			break;
       
  1160             }
       
  1161 
       
  1162         case EProcessing:
       
  1163             {
       
  1164             if(iPushSLEnabled)
       
  1165 			ProcessingPushMsgEntryL();
       
  1166 			break;
       
  1167             }
       
  1168 
       
  1169 		case EFetching:
       
  1170             {
       
  1171             if(iPushSLEnabled)
       
  1172 			FetchPushMsgEntryL();
       
  1173 			break;
       
  1174             }
       
  1175 
       
  1176 		case EFetchCompleted:
       
  1177             {
       
  1178             if(iPushSLEnabled)
       
  1179 			FetchCompletedL();
       
  1180 			break;
       
  1181             }
       
  1182 
       
  1183 		case ESavePushMsgEntry:
       
  1184             {
       
  1185             if(iPushSLEnabled)
       
  1186 			SavePushMsgEntryL();
       
  1187 			break;
       
  1188             }
       
  1189 
       
  1190 
       
  1191         case EDone:
       
  1192             {
       
  1193             PUSHLOG_WRITE("CSLContentHandler EDone")
       
  1194 			Complete( KErrNone );
       
  1195 			break;
       
  1196             }
       
  1197 		default:
       
  1198             {
       
  1199             // JIC.
       
  1200             PUSHLOG_WRITE("CSLContentHandler default EDone")
       
  1201 			Complete( KErrNone );
       
  1202 			break;
       
  1203             }
       
  1204 		}
       
  1205 
       
  1206     PUSHLOG_LEAVEFN("CSLContentHandler::RunL")
       
  1207     }
       
  1208 
       
  1209 // ---------------------------------------------------------
       
  1210 // CSLContentHandler::RunError
       
  1211 // ---------------------------------------------------------
       
  1212 //
       
  1213 TInt CSLContentHandler::RunError( TInt aError )
       
  1214 	{
       
  1215     PUSHLOG_WRITE_FORMAT("CSLContentHandler::RunError: %d",aError)
       
  1216 
       
  1217 	iState = EDone;
       
  1218 	Complete( aError );
       
  1219 	return KErrNone;
       
  1220 	}
       
  1221