--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingfw/wappushfw/SISLContentHandlers/src/CSIContentHandler.cpp Mon Jan 18 20:36:02 2010 +0200
@@ -0,0 +1,861 @@
+// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+// Local includes
+//
+#include "CSIContentHandler.h"
+
+// System includes
+//
+#include <push/sislpushmsgutils.h>
+#include <push/csipushmsgentry.h>
+#include <escapeutils.h>
+#include <msvids.h>
+#include <inetprottextutils.h>
+
+// SI string tables.
+#include "sitagstable.h"
+#include "siattributetable.h"
+#include "siattributevaluetable.h"
+
+
+const TInt KValidUTCLength = 20;
+
+
+#if defined(_DEBUG)
+_LIT(KErrPushMsgNull, "NULL CPushMessage");
+#endif
+
+// Constants
+_LIT(KReserved, "Reserved");
+
+void CSIContentHandler::CPushHandlerBase_Reserved1()
+ {
+ User::Panic(KReserved, KErrNotSupported);
+ }
+
+void CSIContentHandler::CPushHandlerBase_Reserved2()
+ {
+ User::Panic(KReserved, KErrNotSupported);
+ }
+
+/**
+ * The SL Content handler private constructor.
+ * Index number : ESIContentHandlerIndex
+ */
+CSIContentHandler::CSIContentHandler()
+: CContentHandlerBase(), iPushMsgAction(KErrNotFound), iExpiresTime(Time::NullTTime()), iCreatedTime(Time::NullTTime()), iValidDate(ETrue)
+ {
+ }
+
+/**
+ * This will complete initialization of the object
+ */
+void CSIContentHandler::ConstructL()
+ {
+ iWapPushUtils = CSISLPushMsgUtils::NewL();
+ CActiveScheduler::Add(this);
+ }
+
+/**
+ * Static Factory Construction
+ *
+ * Version of NewL which leaves nothing
+ * on the cleanup stack
+ */
+CSIContentHandler* CSIContentHandler::NewL()
+ {
+ CSIContentHandler* self = new(ELeave) CSIContentHandler;
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/**
+ * Default d'tor
+ */
+CSIContentHandler::~CSIContentHandler()
+ {
+ __LOG_PTR_DEBUG("CSIContentHandler:: Destructor Called");
+ delete iHrefBuf;
+ delete iSiIdBuf;
+ delete iData;
+ delete iWapPushUtils;
+ }
+
+/**
+ * HandleMessage Async. Version
+ * Takes ownership of Push Message and sets self active to continue
+ * processing message.
+ * @param aPushMsg
+ * CPushMessage to process
+ * @param aStatus
+ * request status variable for use in asynchronous operations
+ */
+void CSIContentHandler::HandleMessageL(CPushMessage* aPushMsg, TRequestStatus& aStatus)
+ {
+ __LOG_PTR_DEBUG("CSIContentHandler:: HandleMessage Async Func. Called");
+ __ASSERT_DEBUG( aPushMsg != NULL, User::Panic(KErrPushMsgNull, KErrNone));
+
+ iMessage = aPushMsg;
+ iAcknowledge = ETrue;
+ SetConfirmationStatus(aStatus);
+
+ iState= EParsing;
+ IdleComplete();
+ }
+
+/**
+ * HandleMessage Sync. Version
+ * Takes ownership of Push Message and sets self active to continue
+ * processing message.
+ *
+ * Initial State: Set data members then go to the next state
+ * @param aPushMsg
+ * CPushMessage to process
+ */
+void CSIContentHandler::HandleMessageL(CPushMessage* aPushMsg)
+ {
+ __LOG_PTR_DEBUG("CSIContentHandler:: HandleMessage Sync Func. Called");
+ __ASSERT_DEBUG( aPushMsg != NULL, User::Panic(KErrPushMsgNull, KErrNone));
+
+ iAcknowledge = EFalse;
+ iMessage = aPushMsg;
+
+ iState =EParsing;
+ IdleComplete();
+ }
+
+/**
+ * Parse the SI message from XML to its component parts which are held
+ * in the document tree. This tree is then examined and the attributes
+ * read and recorded for later reference. Once parsed the parser and tree
+ * are deleted as no longer required.
+ * @leave KErrNotFound
+ * indicates general processing error and to abandon processing
+ * @leave KErrCorrupt
+ * there is no body in the message
+ * @leave TDesC::AllocL
+
+ */
+void CSIContentHandler::ParsePushMsgL()
+ {
+ __LOG_PTR_DEBUG("CSIContentHandler:: ParsePushMsgL. Called");
+
+ CMessageParser* myParser = CMessageParser::NewL ( *iMessage,
+ *this,
+ &sitagstable::Table,
+ &siattributetable::Table,
+ &siattributevaluetable::Table );
+ CleanupStack::PushL ( myParser );
+
+ myParser->ParseMessageL ();
+
+ User::LeaveIfError ( myParser->LastError() );
+
+ CleanupStack::PopAndDestroy ( myParser );
+
+ if (iData)
+ {
+ ( iData->Des() ).TrimLeft ();
+ ( iData->Des() ).TrimRight ();
+ }
+ iState = EProcessing;
+ IdleComplete();
+ }
+
+ // Return value NULL indicates failed conversion!
+ // Ownership of the resulting string is passed up to caller.
+ HBufC16* CSIContentHandler::FormatDateStringL(const TDesC& aData)
+ {
+ const TInt KDateTimePart = 7;
+ enum TDateTimeParts {EYearTop, EYearBot, EMon, EDay, EHour, EMin, ESec};
+ TInt dateData[KDateTimePart];
+
+ for (TInt i = 0; i < KDateTimePart; i++)
+ dateData[i] = 0;
+
+ TInt offSet = 0;
+ TInt dataLen = aData.Length();
+
+
+ while (offSet < KDateTimePart && dataLen > 0)
+ {
+ dateData[offSet] = aData[offSet];
+ offSet++;
+ dataLen--;
+ }
+
+ _LIT(KDateFormat,"%2x%02x-%02x-%02xT%02x:%02x:%02xZ");
+ const TInt KDateFormatLen = 20;
+
+ TBuf16<KDateFormatLen> dateBuf;
+ dateBuf.Format(KDateFormat, dateData[EYearTop],
+ dateData[EYearBot],
+ dateData[EMon],
+ dateData[EDay],
+ dateData[EHour],
+ dateData[EMin],
+ dateData[ESec]);
+ return( dateBuf.AllocL() );
+}
+
+
+/**
+ * Convert UTC date time into native TTime format. Method can not leave
+ * and traps any leaves from ValidateUTCTimeL.
+ * @param aDateTime
+ * the UTC string representing the date and time
+ * @param aConvertedDate
+ * member date variable passed in to accept converted UTC date as TTime varaible
+ * @return TBool
+ * indicates if conversion successful (ETrue) or conversion failed (EFalse)
+ */
+TBool CSIContentHandler::ConvertDateTimeL(const TDesC& aDateTime, TTime &aConvertedDate)
+ {
+ TTime convertedTime = Time::NullTTime();
+ TBool convertedOK = EFalse;
+
+ HBufC* dateTime = NULL;
+ if (aDateTime.Length() == KValidUTCLength) //check supplied descriptor is the correct length
+ {
+ dateTime = aDateTime.AllocLC ();
+ }
+ else
+ {
+ // Convert to UTC string
+ dateTime = FormatDateStringL ( aDateTime );
+ CleanupStack::PushL ( dateTime );
+ }
+
+ TBuf<20> str = dateTime->Des();
+ if (IsValidUTCTime(str))
+ {
+ // adjust UTC time to zero offset TTime
+ const TInt KFirstMonthChar = 4;
+ const TInt KSecondMonthChar = KFirstMonthChar + 1;
+ const TInt KFirstDayChar = 6;
+ const TInt KSecondDayChar = KFirstDayChar + 1;
+ // check for special case of month = 10 which becomes 09
+ if (str[KFirstMonthChar]=='1' && str[KSecondMonthChar] == '0')
+ {
+ str[KFirstMonthChar]='0';
+ str[KSecondMonthChar]='9';
+ }
+ else
+ // month value is either 11, 12 or less than 10, ie 1 - 9.
+ // reduce day by one, eg 11 becomes 10, 12 becomes 11, 09 becomes 08
+ str[KSecondMonthChar]-- ;
+
+ // check for special cases 10, 20, 30
+ if (str[KSecondDayChar] == '0')
+ {
+ // reduce day by 1, ie 10 becomes 09, 20 becomes 19 ...
+ str[KSecondDayChar] = '9';
+ str[KFirstDayChar]--;
+ }
+ else
+ // day value is between 1 and 9 so reduce day by one
+ // eg 29 becomes 28, 11 bcomes 10, 31 becomes 30
+ str[KSecondDayChar]--;
+
+ // string is now syntaxically correct and year will be not be negative
+ // so no errors will occur here and will now have a valid TTime
+ convertedTime.Set(str);
+ convertedOK = ETrue;
+ }
+
+ aConvertedDate = convertedTime;
+ CleanupStack::PopAndDestroy ( dateTime );
+ if(!convertedOK)
+ {
+ iValidDate = EFalse;
+ }
+ return convertedOK;
+ }
+
+/**
+ * Check given UTC time string conforms to expected format:
+ * YYYY-MM-DDTHH:MM:SSZ and strip out formatting characters
+ * then validate the remaining characters are all digits.
+ * If validated then add TTime formating character so final
+ * string returned will be of the format YYYYMMDD:HHMMSS.
+ * @param aDateTime
+ * UTC string which is validated and returned
+ * @return boolean
+ * indicates if given date is valid (ETrue)
+ * or not (EFalse)
+ */
+TBool CSIContentHandler::IsValidUTCTime(TDes& aDateTime)
+ {
+ // strip out formatting characters
+ TInt formatCharPos = 4;
+ aDateTime.Delete(formatCharPos, 1);
+ // now move through two characters at a time and remove other chars
+ // to just leave digits
+ TInt KRemainingFormatChars = 5;
+ for (TInt i = 0 ; i < KRemainingFormatChars; i++)
+ {
+ formatCharPos += 2;
+ aDateTime.Delete(formatCharPos, 1);
+ }
+
+ // check string now the right TTime length
+ const TInt KValidTTimeLength = 14;
+ if (aDateTime.Length() != KValidTTimeLength)
+ return EFalse;
+
+ // now have UTC string stripped of format characters - check remaining characters are
+ // all digits - YYYYMMDDHHMMSS
+ TChar ch;
+ for (TInt x = 0; x < KValidTTimeLength; x++)
+ {
+ ch = aDateTime[x];
+ if (ch.IsDigit() == EFalse)
+ return EFalse;
+ }
+
+ TInt err = ValidateDateTime( aDateTime );
+ if(!err)
+ return EFalse;
+
+ // insert colon seperating date from time
+ _LIT(colon, ":");
+ const TInt KColonPosition = 8;
+ aDateTime.Insert(KColonPosition, colon);
+ return ETrue;
+ }
+
+/**
+ * Validate date and time to check whether date and time values lie
+ * within the valid range
+ * @param aDateTime
+ * UTC string which is validated
+ * @return boolean
+ * indicates if given date and time is valid (ETrue)
+ * or not (EFalse)
+ */
+TBool CSIContentHandler::ValidateDateTime(TDes& aDateTime)
+ {
+ TPtrC ptr(aDateTime);
+ TPtrC yr;
+ yr.Set(ptr.Left(4));
+ TInt yearInt;
+ InetProtTextUtils::ConvertDescriptorToInt(yr,yearInt);
+
+ TPtrC month;
+ month.Set(ptr.Mid(4));
+ TPtrC mon;
+ mon.Set(month.Left(2));
+ TInt monthInt;
+ InetProtTextUtils::ConvertDescriptorToInt(mon,monthInt);
+
+ TPtrC day;
+ day.Set(month.Mid(2));
+ TPtrC dy;
+ dy.Set(day.Left(2));
+ TInt dayInt;
+ InetProtTextUtils::ConvertDescriptorToInt(dy,dayInt);
+
+ TPtrC hour;
+ hour.Set(day.Mid(2));
+ TPtrC hr;
+ hr.Set(hour.Left(2));
+ TInt hourInt;
+ InetProtTextUtils::ConvertDescriptorToInt(hr,hourInt);
+
+ TPtrC minute;
+ minute.Set(hour.Mid(2));
+ TPtrC min;
+ min.Set(minute.Left(2));
+ TInt minInt;
+ InetProtTextUtils::ConvertDescriptorToInt(min,minInt);
+
+ TPtrC second;
+ second.Set(minute.Mid(2));
+ TPtrC sec;
+ sec.Set(second.Left(2));
+ TInt secInt;
+ InetProtTextUtils::ConvertDescriptorToInt(sec,secInt);
+
+
+ if ( monthInt == 1 || monthInt == 3 || monthInt == 5 || monthInt == 7
+ || monthInt == 8 || monthInt == 10 || monthInt == 12)
+ {
+ if (!(dayInt <= 31))
+ return EFalse;
+ }
+ else if (monthInt == 04 || monthInt == 06 || monthInt == 9 || monthInt == 11)
+ {
+ if (!(dayInt <= 30))
+ return EFalse;
+ }
+ else if (monthInt == 02)
+ {
+ if (Time::IsLeapYear(yearInt))
+ {
+ if (!(dayInt <= 29))
+ return EFalse;
+ }
+ else if (!(dayInt <= 28))
+ return EFalse;
+ }
+ else
+ {
+ return EFalse;
+ }
+
+ if ( !(hourInt <= 23 && minInt <= 59 && secInt <= 59))
+ return EFalse;
+
+ return ETrue;
+ }
+
+/**
+ * Convert the action string to a representative numeric value to facilitate
+ * storing the message in the wap push utils.
+ * @param aActionString
+ * the attribute value indicating the action level eg 'signal-high'
+ * @return TUint
+ * a value representing the action type (as defined in PushEntry.h)
+ */
+TUint CSIContentHandler::ConvertActionString(const RString& aActionString)
+ {
+ // set to default signal value (to rid ourselves of build warning)
+ TUint actionValue = CSIPushMsgEntry::ESIPushMsgSignalMedium;
+ switch ( aActionString.Index ( siattributevaluetable::Table ) )
+ {
+ case siattributevaluetable::EAction1:
+ actionValue = CSIPushMsgEntry::ESIPushMsgSignalNone;
+ break;
+ case siattributevaluetable::EAction2:
+ actionValue = CSIPushMsgEntry::ESIPushMsgSignalLow;
+ break;
+ case siattributevaluetable::EAction3:
+ actionValue = CSIPushMsgEntry::ESIPushMsgSignalMedium;
+ break;
+ case siattributevaluetable::EAction4:
+ actionValue = CSIPushMsgEntry::ESIPushMsgSignalHigh;
+ break;
+ case siattributevaluetable::EAction5:
+ actionValue = CSIPushMsgEntry::ESIPushMsgDelete;
+ break;
+ default:
+ User::Invariant ();
+ }
+ return actionValue;
+ }
+
+/**
+ * Handles message reception and processes the received message following
+ * the flow of actions detailed in 7.2 Reception
+ * [WAP Service Indication 08-Nov-1999]
+ * 1. check if received message is expired
+ * 2. if received message is an older version of stored SI,
+ * or is the same age - discard received message
+ * 3. if message is more recent version than stored SI - delete stored SI
+ * 4. if message actioned to delete, and has Si Id set, then delete it
+ * and any stored messages with same id
+ * finally if received message not set to deleted or discarded - store it
+ */
+void CSIContentHandler::ProcessingPushMsgEntryL()
+ {
+ __LOG_PTR_DEBUG("CSIContentHandler:: ProcessingPushMsgEntryL. called");
+ TBool deletePushMsg = EFalse;
+
+ // 1. Expiration
+ TTime today;
+ today.UniversalTime();
+ // check if message has expiry date before today's date
+ if (ExpiresFlag() && iExpiresTime < today)
+ {
+ deletePushMsg = ETrue;
+ __LOG_PTR_DEBUG("CSIContentHandler: ProcessingPushMsgEntryL: Expired msg (1)");
+ }
+
+ // 2. handling out of order delivery &
+ // 3. replacement
+ else if (SiIdFlag() || HrefFlag())
+ deletePushMsg = HandleMsgOrderReceptionL();
+
+ // 4. deletion
+ if (!deletePushMsg && ActionFlag())
+ {
+ // check if action = delete and SiId value is set before can delete
+ if ((iPushMsgAction == CSIPushMsgEntry::ESIPushMsgDelete) && (SiIdFlag()))
+ {
+ __LOG_PTR_DEBUG("CSIContentHandler: ProcessingPushMsgEntryL: delete msg (4)");
+
+ // delete msg and any matching messages (with same si-id)
+ __LOG_PTR_DEBUG("CWapPushMsgUtils: FindSiIdLC called");
+ CMsvEntrySelection* matchingIdList = iWapPushUtils->FindSiIdLC(*iSiIdBuf);
+ TInt matchingListCount = matchingIdList->Count();
+ for (TInt count = 0; count < matchingListCount; count++)
+ {
+ TMsvId matchingSiMsgEntryId = matchingIdList->At(count);
+ if (matchingSiMsgEntryId)
+ {
+ __LOG_PTR_DEBUG("CWapPushMsgUtils: DeleteEntryNowL called");
+ iWapPushUtils->DeleteEntryNowL(matchingSiMsgEntryId);
+ }
+ }
+ CleanupStack::PopAndDestroy(); // matchingIdList
+ deletePushMsg = ETrue;
+ }
+ }
+
+ // store message if not marked for deletion and date/time is valid
+ if (!deletePushMsg && iValidDate)
+ StoreSIMessageL();
+ // Reset the flag to ETrue for next message
+ iValidDate = ETrue;
+
+ iState = EDone;
+ IdleComplete();
+ }
+
+/**
+ * Check received SI message against existing stored messages
+ * with the same si-id and update the message(s) according to
+ * the creation date (if specified).
+ * @return TBool
+ * ETrue - Received SI message older than stored match(es)
+ * and should be marked for deletion
+ * EFalse - Receieved SI message to be retained as newer
+ * therefore do not delete it
+ */
+TBool CSIContentHandler::HandleMsgOrderReceptionL()
+ {
+ CMsvEntrySelection* matchingIdList;
+ TBool discardPushMsg = EFalse;
+
+ __LOG_PTR_DEBUG("CSISLPushMsgUtils: FindSiIdLC called");
+ // get list of matching stored SI messages
+ if (SiIdFlag())
+ matchingIdList = iWapPushUtils->FindSiIdLC(*iSiIdBuf);
+ else
+ matchingIdList = iWapPushUtils->FindSiIdLC(*iHrefBuf);
+
+ // check we have a creation date specified before checking against list of matches
+ if (matchingIdList->Count() && CreatedFlag())
+ {
+ CSIPushMsgEntry* siEntry=GetSiEntryL();
+ CleanupStack::PushL(siEntry);
+
+ // delete older stored messages and/or mark current message for deletion
+ // if same date or older than stored messages
+ TInt matchingListCount = matchingIdList->Count();
+ for (TInt count = 0; count < matchingListCount; count++)
+ {
+ TMsvId matchingSiMsgEntryId = matchingIdList->At(count);
+
+ __LOG_PTR_DEBUG("CSIPushMsgEntry: RetrieveL called");
+ siEntry->RetrieveL(iWapPushUtils->Session(), matchingSiMsgEntryId);
+
+ // skip date comparisons if creation date not valid
+ TTime existingSiCreatedTime = siEntry->Created();
+ if (existingSiCreatedTime == Time::NullTTime())
+ continue;
+ //check if received SI is newer than existing stored Si (out of order)
+ if (iCreatedTime > existingSiCreatedTime)
+ {
+ __LOG_PTR_DEBUG("CWapPushMsgUtils: DeleteEntryNowL called");
+ iWapPushUtils->DeleteEntryNowL(matchingSiMsgEntryId);
+ __LOG_PTR_DEBUG("CSIContentHandler: ProcessingPushMsgEntryL: delete stored msg (3)");
+ }
+ else if (iCreatedTime <= existingSiCreatedTime)
+ // received SI older than existing stored Si (replacement)
+ discardPushMsg = ETrue;
+ }
+ CleanupStack::PopAndDestroy(siEntry);
+ }
+
+ CleanupStack::PopAndDestroy(matchingIdList);
+
+ if (discardPushMsg)
+ {
+ __LOG_PTR_DEBUG("CSIContentHandler: ProcessingPushMsgEntryL: discard msg (2)");
+ }
+ return discardPushMsg;
+ }
+
+
+/**
+ * Save push message in message store.
+ * Creates link to message service provided by wap push utils
+ * and uses this and the associated push entry class to save
+ * the push message.
+ */
+void CSIContentHandler::StoreSIMessageL()
+ {
+ __LOG_PTR_DEBUG("CSIContentHandler:: StoreSiMessageL. called");
+
+ CSIPushMsgEntry* siEntry=GetSiEntryL();
+ CleanupStack::PushL(siEntry);
+ SetSIPushMsgEntryFieldsL(*siEntry);
+
+ TMsvId folderId;
+ iWapPushUtils->GetPushMsgFolderIdL(folderId);
+
+ __LOG_PTR_DEBUG("CSIPushMsgEntry::SaveL called");
+ siEntry->SaveL(iWapPushUtils->Session(), folderId);
+
+ CleanupStack::PopAndDestroy(siEntry);
+ }
+
+
+CSIPushMsgEntry* CSIContentHandler::GetSiEntryL()
+ {
+ TBool isInt;
+ TPtrC8 appURI;
+ TInt appID=0;
+ iMessage->GetAppIdL(appURI, appID, isInt);
+ CSIPushMsgEntry* siEntry=NULL;
+ if (isInt)
+ {
+ siEntry = CSIPushMsgEntry::NewL(appID);
+ }
+ else
+ {
+ siEntry = CSIPushMsgEntry::NewL(appURI);
+ }
+ return siEntry;
+ }
+
+/**
+ * Create SI entry fields prior to storing message. The saving of
+ * certain push message attributes will be set to defaults if
+ * information missing to facilitate message searching, storing
+ * and retrieval.
+ * @param siEntry
+ * entry represents message format to use when storing it
+ */
+void CSIContentHandler::SetSIPushMsgEntryFieldsL(CSIPushMsgEntry& aSIPushMsgEntry)
+ {
+ // if message has no si-id but does have a href - use href as si-id and
+ // if message has a si-id but no href use si-id for href
+
+ if (SiIdFlag() || HrefFlag())
+ {
+ if (SiIdFlag() && (HrefFlag() == EFalse))
+ {
+ aSIPushMsgEntry.SetIdL(*iSiIdBuf);
+ aSIPushMsgEntry.SetUrlL(*iSiIdBuf);
+ }
+ else if (HrefFlag() && (SiIdFlag() == EFalse))
+ {
+ aSIPushMsgEntry.SetIdL(*iHrefBuf);
+ aSIPushMsgEntry.SetUrlL(*iHrefBuf);
+ }
+ else
+ {
+ aSIPushMsgEntry.SetIdL(*iSiIdBuf);
+ aSIPushMsgEntry.SetUrlL(*iHrefBuf);
+ }
+ }
+
+ if (ActionFlag())
+ aSIPushMsgEntry.SetAction(iPushMsgAction);
+ else // default if no action explicitly stated
+ aSIPushMsgEntry.SetAction(CSIPushMsgEntry::ESIPushMsgSignalMedium);
+
+ // uses default null time value if no explicit date set in message
+ aSIPushMsgEntry.SetCreated(iCreatedTime);
+ aSIPushMsgEntry.SetExpires(iExpiresTime);
+
+ // PCDATA (text) from message
+ if (DataFlag())
+ aSIPushMsgEntry.SetTextL(*iData);
+
+ TPtrC8 msgHeaderPtr;
+ iMessage->GetHeader(msgHeaderPtr);
+ aSIPushMsgEntry.SetHeaderL(msgHeaderPtr);
+
+ TPtrC8 from;
+ if (!iMessage->GetBinaryHeaderField(EHttpFrom, from) &&
+ !iMessage->GetBinaryHeaderField(EHttpXWapInitiatorURI, from) &&
+ !iMessage->GetBinaryHeaderField(EHttpContentLocation, from) )
+ {
+ from.Set(KNullDesC8);
+ }
+ aSIPushMsgEntry.SetFromL(from);
+
+ if(iMessage->MessageAllowed())
+ {
+ aSIPushMsgEntry.SetTrusted(ETrue);
+ }
+ else
+ {
+ aSIPushMsgEntry.SetTrusted(EFalse);
+ }
+
+ TPtrC8 serverAddress8;
+ iMessage->GetServerAddress(serverAddress8);
+ aSIPushMsgEntry.SetMsgOriginUriL(serverAddress8);
+ }
+
+/**
+ * Same functionality as DoCancel()
+ */
+void CSIContentHandler::CancelHandleMessage()
+ {
+ __LOG_PTR_DEBUG("CSIContentHandler:: CancelHandleMessage called");
+ Complete(KErrCancel);
+ }
+
+/**
+ * Cancels the handling of the message and revokes the active status
+ * of the handler
+ */
+void CSIContentHandler::DoCancel()
+ {
+ __LOG_PTR_DEBUG("CSIContentHandler:: DoCancel Called");
+ Complete(KErrCancel);
+ }
+
+/**
+ * Step through the various representative states for handling a message
+ * 1. validate the message by parsing it against the relevant DTD
+ * 2. process the message in accordance with the Reception rules
+ * 3. finish up
+ */
+void CSIContentHandler::RunL()
+ {
+ __LOG_PTR_DEBUG("CSIContentHandler:: RunL Called");
+ // use active state machine routine to manage activites:
+ switch (iState)
+ {
+ case EParsing :
+ ParsePushMsgL();
+ break;
+ case EProcessing:
+ ProcessingPushMsgEntryL();
+ break;
+ case EDone:
+ Complete(KErrNone);
+ break;
+ default:
+ break;
+ }
+ }
+
+/**
+ * CPluginActiveBase methods
+ */
+TInt CSIContentHandler::RunError(TInt aError)
+ {
+ __LOG_PTR_DEBUG("CSIContentHandler:: RunError Called");
+ iState=EDone;
+ Complete(aError);
+ return KErrNone;
+ }
+
+void CSIContentHandler::HandleElementL ( const RString& aTag, const RString& aAttributeName, const RString& aAttributeValue )
+ {
+ __LOG_PTR_DEBUG( "CSIContentHandler:: HandleElementL Called" );
+
+ const TDesC8& tag = aTag.DesC();
+ iIndicationTagFound = EFalse;
+
+ if ( aTag.Index ( sitagstable::Table ) == sitagstable::EIndication )
+ {
+ iIndicationTagFound = ETrue;
+ }
+
+ TBool gotDate = EFalse;
+ HBufC* des16 = EscapeUtils::ConvertToUnicodeFromUtf8L ( aAttributeValue.DesC() );
+ CleanupStack::PushL ( des16 );
+
+ switch ( aAttributeName.Index ( siattributetable::Table ) )
+ {
+ case siattributetable::EAction1:
+ case siattributetable::EAction2:
+ case siattributetable::EAction3:
+ case siattributetable::EAction4:
+ case siattributetable::EAction5:
+ iPushMsgAction = ConvertActionString( aAttributeValue );
+ SetActionFlag(ETrue);
+ break;
+
+ case siattributetable::ECreated:
+ gotDate = ConvertDateTimeL ( *des16, iCreatedTime );
+ SetCreatedFlag(gotDate);
+ break;
+
+ case siattributetable::EHref:
+ delete iHrefBuf;
+ iHrefBuf = NULL;
+
+ iHrefBuf = ( des16->Des() ).AllocL ();
+ SetHrefFlag(ETrue);
+ break;
+
+ case siattributetable::ESiExpires:
+ gotDate = ConvertDateTimeL ( *des16, iExpiresTime );
+ SetExpiresFlag(gotDate);
+ break;
+
+ case siattributetable::ESiId:
+ delete iSiIdBuf;
+ iSiIdBuf = NULL;
+
+ iSiIdBuf = ( des16->Des() ).AllocL ();
+ SetSiIdFlag(ETrue);
+ break;
+
+ case siattributetable::EClass:
+ break;
+
+ default:
+ // Shouldn't come here.
+ User::Invariant ();
+ }
+
+ CleanupStack::PopAndDestroy ( des16 );
+ }
+
+void CSIContentHandler::HandleContentL ( const TDesC8& aBytes )
+ {
+ // We do handle content only if it is in indication tag.
+ // else we reject the content.
+ if ( !iIndicationTagFound )
+ {
+ return;
+ }
+ if ( iData )
+ {
+ HBufC* des16 = EscapeUtils::ConvertToUnicodeFromUtf8L ( aBytes );
+ CleanupStack::PushL ( des16 );
+
+ TInt newDataLength = des16->Length ();
+ TInt existingDataLength = iData->Length ();
+
+ if ( ( newDataLength + existingDataLength ) > existingDataLength )
+ {
+ iData = iData->ReAllocL ( newDataLength + existingDataLength );
+ }
+
+ (iData->Des()).Append( *des16 );
+
+ CleanupStack::PopAndDestroy ( des16 );
+ }
+ else
+ {
+ iData = EscapeUtils::ConvertToUnicodeFromUtf8L ( aBytes );
+ }
+ SetDataFlag ( ETrue );
+ }
+