smsprotocols/smsstack/smsu/src/smsulog.cpp
branchopencode
changeset 24 6638e7f4bd8f
parent 0 3553901f7fa8
--- a/smsprotocols/smsstack/smsu/src/smsulog.cpp	Mon May 03 13:37:20 2010 +0300
+++ b/smsprotocols/smsstack/smsu/src/smsulog.cpp	Thu May 06 15:10:38 2010 +0100
@@ -1,524 +1,524 @@
-// Copyright (c) 1999-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:
-// Implements the CSmsEventLogerClass
-// 
-//
-
-/**
- @file
-*/
-
-#include "smsulog.h"
-#include "smsumain.h"
-#include "smsstacklog.h"
-#include "gsmubuf.h"
-#include "Gsmumsg.h"
-#include "Gsmuelem.h"
-#include <logwrap.h>
-#include <logwraplimits.h>
-
-
-/**
- *  Allocates and creates a logger.
- *  
- *  @param aFs File server handle
- *  @param aPriority Active object priority
- *  @return New CSmsEventLogger object
- *  @capability None
- */
-EXPORT_C CSmsEventLogger* CSmsEventLogger::NewL(RFs& aFs,TInt aPriority)
-	{
-	LOGSMSU1("CSmsEventLogger::NewL()");
-
-	CSmsEventLogger* smseventlogger = new(ELeave) CSmsEventLogger(aPriority);
-	CleanupStack::PushL(smseventlogger);
-	smseventlogger->ConstructL(aFs);
-	CleanupStack::Pop();
-	return smseventlogger;
-	} // CSmsEventLogger::NewL
-
-
-/**
- *  Destructor.
- *  @capability None
- */
-EXPORT_C CSmsEventLogger::~CSmsEventLogger()
-	{
-	Cancel();
-	delete iLogEvent;
-	delete iLogWrapper;
-	} // CSmsEventLogger::~CSmsEventLogger
-
-
-/**
- *  Adds an event to the log database.
- *  
- *  @param aStatus Asynchronous status word to signal when the operation is complete
- *  @param aSmsMessage The SMS message that the event concerns
- *  @param aData SMS PDU information for the event
- *  @param aStatusId Optional string to include in the log message, specified by
- *  resource ID
- *  @capability WriteUserData
- */
-EXPORT_C void CSmsEventLogger::AddEvent(TRequestStatus& aStatus,const CSmsMessage& aSmsMessage,const TLogSmsPduData& aData,TInt* aStatusId)
-	{
-    LOGSMSU1("CSmsEventLogger::AddEvent");
-
-	__ASSERT_DEBUG(iState==ESmsEventLoggerIdle,SmsuPanic(KSmsuPanicUnexpectedState));
-	
-	iState=ESmsEventLoggerAddingEvent;
-
-	Queue(aStatus);
-
-	iSmsPDUData=aData;
-	iSmsPDUData.iType=aSmsMessage.Type();
-
-	TRAPD(ret,DoAddEventL(aSmsMessage,aStatusId));
-	if (ret!=KErrNone)
-		{
-		CompleteMyself(ret);
-		}
-	else
-		{
-		iLogWrapper->Log().AddEvent(*iLogEvent,iStatus);
-		SetActive();
-		}
-	} // CSmsEventLogger::AddEvent
-
-
-/**
- *  Gets the specified event from the log.
- *  
- *  The event itself can be obtained using a subsequent call to Event().
- *  
- *  @param aStatus Asynchronous status word to signal when the operation is complete
- *  @param aId Log event ID for the event
- *  @capability ReadUserData
- */
-EXPORT_C void CSmsEventLogger::GetEvent(TRequestStatus& aStatus,TLogId aId)
-	{
-    LOGSMSU1("CSmsEventLogger::GetEvent");
-
-	__ASSERT_DEBUG(iState==ESmsEventLoggerIdle,SmsuPanic(KSmsuPanicUnexpectedState));
-	iState=ESmsEventLoggerGettingEvent;
-	Queue(aStatus);
-	iLogEvent->SetId(aId);
-	iLogWrapper->Log().GetEvent(*iLogEvent,iStatus);
-	SetActive();
-	} // CSmsEventLogger::GetEvent
-
-/** Changes the details of an existing event.
- 
-    Use GetEvent() to specify the event.
- 
-    @param aStatus       Asynchronous status word to signal when the operation is complete
-    @param aSmsMessage   The SMS message that the event concerns
-    @param aTime SMS delivery time
-    @param aData SMS PDU information for the event
-    @param aStatusId Optional string to include in the log message, specified by
-    resource ID
-    @capability WriteUserData
-*/
-EXPORT_C void CSmsEventLogger::ChangeEvent(TRequestStatus& aStatus,const CSmsMessage& aSmsMessage, const TTime* aTime, const TLogSmsPduData& aData, TInt* aStatusId)
-    {
-    LOGSMSU1("CSmsEventLogger::ChangeEvent");
-    
-    __ASSERT_DEBUG(iState==ESmsEventLoggerIdle,SmsuPanic(KSmsuPanicUnexpectedState));
-    __ASSERT_DEBUG(aSmsMessage.LogServerId()==iLogEvent->Id(),SmsuPanic(KSmsuPanicWrongLogServerId));
-    __ASSERT_DEBUG(iSmsPDUData.iType==aSmsMessage.Type(),SmsuPanic(ESmsuUnexpectedSmsPDUType));
-    iState=ESmsEventLoggerChangingEvent;
-    Queue(aStatus);
-    iSmsPDUData=aData;
-    iSmsPDUData.iType=aSmsMessage.Type();        
-
-    TRAPD(ret,SetDataL(aSmsMessage,aStatusId, aTime));
-    if (ret!=KErrNone)
-        {
-        Complete(ret);
-        }
-    else
-        {
-        iLogWrapper->Log().ChangeEvent(*iLogEvent,iStatus);
-        SetActive();
-        }
-    }
-
-/**
- *  Changes the details of an existing event.
- *  
- *  Use GetEvent() to specify the event.
- *  
- *  @param aStatus Asynchronous status word to signal when the operation is complete
- *  @param aSmsMessage The SMS message that the event concerns
- *  @param aData SMS PDU information for the event
- *  @param aStatusId Optional string to include in the log message, specified by
- *  resource ID
- *  @capability WriteUserData
- */
-EXPORT_C void CSmsEventLogger::ChangeEvent(TRequestStatus& aStatus, const CSmsMessage& aSmsMessage, const TLogSmsPduData& aData, TInt* aStatusId)
-	{
-	ChangeEvent(aStatus, aSmsMessage, NULL, aData, aStatusId);
-	} // CSmsEventLogger::ChangeEvent
-
-/**
- *  Deletes an event.
- *  
- *  Use GetEvent() to specify the event.
- *  
- *  @param aStatus Asynchronous status word to signal when the operation is complete
- *  @capability WriteUserData
- */
-EXPORT_C void CSmsEventLogger::DeleteEvent(TRequestStatus& aStatus)
-    {
-    // Ignore in code coverage - not used within the SMS stack.
-    BULLSEYE_OFF
-    LOGSMSU1("CSmsEventLogger::DeleteEvent");
-    
-    __ASSERT_DEBUG(iState==ESmsEventLoggerIdle,SmsuPanic(KSmsuPanicUnexpectedState));
-    
-    iState=ESmsEventLoggerDeletingEvent;
-    
-    Queue(aStatus);
-    
-    iLogWrapper->Log().DeleteEvent(iLogEvent->Id(),iStatus);
-    SetActive();
-    BULLSEYE_RESTORE
-    }
-
-void CSmsEventLogger::DoCancel()
-    {
-    // Ignore in code coverage - in order to test would need to cancel
-    // event logger request; as these called when receiving/sending SMS
-    // message would need to cancel these activities during event the 
-    // logger request - too difficult to test. Need to add unit test.
-    BULLSEYE_OFF
-    LOGSMSU3("CSmsEventLogger::DoCancel [iStatus=%d, iState=%d]", iStatus.Int(), iState);
-    
-    switch( iState )
-        {
-        case ESmsEventLoggerGettingEvent:
-        case ESmsEventLoggerAddingEvent:
-        case ESmsEventLoggerChangingEvent:
-        case ESmsEventLoggerDeletingEvent:
-            {
-            iLogWrapper->Log().Cancel();
-            } break;
-        default:
-            {
-            SmsuPanic(KSmsuPanicUnexpectedState);
-            } break;
-        }
-    // Handle completion of this Active Object. Note that the object
-    // may well still be active at this point...
-    if( TimedOut() )
-        {
-        Complete(KErrTimedOut);
-        }
-    else
-        {
-        Complete(KErrCancel);
-        }
-    BULLSEYE_RESTORE
-    }
-
-CSmsEventLogger::CSmsEventLogger(TInt aPriority):
-	CSmsuActiveBase(aPriority),
-	iState(ESmsEventLoggerIdle)
-	{
-	// NOP
-	}
-
-
-void CSmsEventLogger::ConstructL(RFs& aFs)
-	{
-	LOGSMSU1("CSmsEventLogger::ConstructL()");
-
-	iLogWrapper=CLogWrapper::NewL(aFs);
-	iLogEvent=CLogEvent::NewL();
-	} // CSmsEventLogger::ConstructL
-
-
-void CSmsEventLogger::DoRunL()
-	{
-    LOGSMSU2("CSmsEventLogger::DoRunL [iStatus=%d]", iStatus.Int() );
-
-	switch (iState)
-		{
-		case ESmsEventLoggerGettingEvent:
-			{
-			if (iStatus.Int() == KErrNone)
-				{
-				TPckg<TLogSmsPduData> packeddata(iSmsPDUData);
-				packeddata.Copy(iLogEvent->Data());
-				}
-			}
-            break;
-
-		case ESmsEventLoggerAddingEvent:
-		case ESmsEventLoggerChangingEvent:
-		case ESmsEventLoggerDeletingEvent:
-			{
-			// NOP
-			}
-			break;
-
-		default:
-			{
-            User::Leave(KErrGeneral);
-            //SmsuPanic(KSmsuPanicUnexpectedState);
-            }
-            break;
-		}
-
-	//
-	// DoRunL() will now return to CSmsuActiveBase which if the object
-	// is not active, will call Complete().
-	//
-	} // CSmsEventLogger::DoRunL
-
-
-void CSmsEventLogger::DoAddEventL(const CSmsMessage& aSmsMessage,TInt* aStatusId)
-	{
-    LOGSMSU2("CSmsEventLogger::DoAddEventL [statusID*=%d]", aStatusId);
-
-	 //  Reset event
-	CLogEvent* logevent=CLogEvent::NewL();
-	delete iLogEvent;
-	iLogEvent=logevent;
-	TBuf<KLogMaxDirectionLength> direction;
-	switch (aSmsMessage.Type())
-		{
-		//  Incoming SMS
-		case CSmsPDU::ESmsDeliver:
-			{
-			LOGSMSU1("DoAddEventL ESmsDeliver");
-			GetStringL(direction,R_LOG_DIR_IN);
-			break;
-			}
-		case CSmsPDU::ESmsStatusReport:
-			{
-			LOGSMSU1("DoAddEventL ESmsStatusReport");
-			GetStringL(direction,R_LOG_DIR_IN);
-			break;
-			}
-		//  Outgoing SMS
-		case CSmsPDU::ESmsSubmit:
-			{
-			LOGSMSU1("DoAddEventL ESmsSubmit");
-			GetStringL(direction,R_LOG_DIR_OUT);
-			break;
-			}
-		case CSmsPDU::ESmsCommand:
-			{
-			LOGSMSU1("DoAddEventL ESmsCommand");
-			GetStringL(direction,R_LOG_DIR_OUT);
-			break;
-			}
-		default:
-			{
-			LOGSMSU1("DoAddEventL ESmsuUnexpectedSmsPDUType");
-			SmsuPanic(ESmsuUnexpectedSmsPDUType);
-			}
-		}
-
-	Event().SetDirection(direction);
-	Event().SetEventType(KLogShortMessageEventTypeUid);
-
-	TGsmSmsTelNumber address;
-	aSmsMessage.ParsedToFromAddress(address);
-
-	if (address.IsInstanceOf(TGsmSmsTelNumber::EVoiceMessageWaitingIndicator))
-    	{
-	    Event().SetNumber(_L("CPHS"));
-	    }
-	    else
-	    {
-	    Event().SetNumber(aSmsMessage.ToFromAddress());
-	    }
-
-	SetDataL(aSmsMessage,aStatusId, NULL);
-	} // CSmsEventLogger::DoAddEventL
-
-
-void CSmsEventLogger::SetDataL(const CSmsMessage& aSmsMessage,TInt* aStatusId, const TTime* aDischargeTime)
-	{
-
-	__ASSERT_DEBUG(iSmsPDUData.iType==aSmsMessage.Type(),SmsuPanic(ESmsuUnexpectedSmsPDUType));
-	TBuf<KLogMaxStatusLength> status;
-#ifdef _DEBUG
-	if (aStatusId!=NULL)
-		LOGSMSU2("CSmsEventLogger::SetDataL StatusID = %d", *aStatusId);
-#endif
-	if (aStatusId==NULL)
-		{
-		CSmsPDU::TSmsPDUType type=aSmsMessage.Type();
-		switch (type)
-			{
-			//  Incoming SMS
-			case CSmsPDU::ESmsDeliver:
-				{
-				if (iSmsPDUData.iTotal==iSmsPDUData.iReceived)
-					{
-					LOGSMSU1("SetDataL ESmsDeliver R_LOG_DEL_DONE");
-					GetStringL(status,R_LOG_DEL_DONE);
-					}
-				else if (iSmsPDUData.iTotal>iSmsPDUData.iReceived)
-					{
-					LOGSMSU1("SetDataL ESmsDeliver R_LOG_DEL_PENDING");
-					GetStringL(status,R_LOG_DEL_PENDING);
-					}
-				break;
-				}
-			case CSmsPDU::ESmsStatusReport:
-				{
-				if (iSmsPDUData.iTotal==iSmsPDUData.iReceived)
-					{
-					LOGSMSU1("SetDataL ESmsStatusReport R_LOG_DEL_DONE");
-					GetStringL(status,R_LOG_DEL_DONE);
-					}
-				else if (iSmsPDUData.iTotal>iSmsPDUData.iReceived)
-					{
-					LOGSMSU1("SetDataL ESmsStatusReport R_LOG_DEL_PENDING");
-					GetStringL(status,R_LOG_DEL_PENDING);
-					}
-				break;
-				}
-			//  Outgoing SMS
-			case CSmsPDU::ESmsSubmit:
-			case CSmsPDU::ESmsCommand:
-				{
-				TBool statusreportrequest=EFalse;
-				if (type==CSmsPDU::ESmsSubmit)
-					{
-					CSmsSubmit& submit=(CSmsSubmit&) aSmsMessage.SmsPDU();
-					statusreportrequest=submit.StatusReportRequest();
-					}
-				else
-					{
-					CSmsCommand& command=(CSmsCommand&) aSmsMessage.SmsPDU();
-					statusreportrequest=command.StatusReportRequest();
-					}
-				if (statusreportrequest)
-					{
-					if (iSmsPDUData.iSent==0)
-						{
-						// None sent yet
-						GetStringL(status,R_LOG_DEL_NOT_SENT);
-						LOGSMSU1("SetDataL ESmsSubmit R_LOG_DEL_NOT_SENT SR");
-						}
-					else if (iSmsPDUData.iTotal==iSmsPDUData.iDelivered)
-						{
-						// All have been delivered
-						LOGSMSU2("SetDataL ESmsSubmit R_LOG_DEL_DONE SR iSmsPDUData.iDelivered=%d", iSmsPDUData.iDelivered);
-						GetStringL(status,R_LOG_DEL_DONE);
-						}
-					else if (iSmsPDUData.iSent<=iSmsPDUData.iTotal && iSmsPDUData.iFailed==0)
-						{
-						// One or more sent but not all, no failures
-						LOGSMSU3("SetDataL ESmsSubmit R_LOG_DEL_PENDING SR iSmsPDUData.iSent==%d, iSmsPDUData.iTotal==%d, iFailed==0", iSmsPDUData.iSent, iSmsPDUData.iTotal);
-						GetStringL(status,R_LOG_DEL_PENDING);
-						}
-					else
-						{
-						// One or more failures or corruption of iSmsPDUData values
-						LOGSMSU1("SetDataL ESmsSubmit R_LOG_DEL_FAILED SR");
-						LOGSMSU3("	Total:  %d, Sent: %d",iSmsPDUData.iTotal, iSmsPDUData.iSent );
-						LOGSMSU3("	Failed: %d, Delivered: %d",iSmsPDUData.iFailed, iSmsPDUData.iDelivered );
-						GetStringL(status,R_LOG_DEL_FAILED);
-						}
-                    if (aDischargeTime != NULL)
-                        {
-                        iLogEvent->SetTime(*aDischargeTime);
-                        }					
-					}
-				else
-					{
-					if (iSmsPDUData.iSent<iSmsPDUData.iTotal)
-						{
-						// IF not all PDUs sent, state is "NOT SENT".
-						LOGSMSU1("SetDataL ESmsSubmit R_LOG_DEL_NOT_SENT NOSR");
-						LOGSMSU3("	Total:  %d, Sent: %d", iSmsPDUData.iTotal, iSmsPDUData.iSent );
-						GetStringL(status,R_LOG_DEL_NOT_SENT);
-						}
-					else if (iSmsPDUData.iTotal==iSmsPDUData.iSent)
-						{
-						// All sent
-						LOGSMSU1("SetDataL ESmsSubmit R_LOG_DEL_SENT NOSR");
-						GetStringL(status,R_LOG_DEL_SENT);
-						}
-					else
-						{
-						// The iSmsPDUData values have become corrupt
-						LOGSMSU1("SetDataL ESmsSubmit R_LOG_DEL_FAILED NOSR");
-						LOGSMSU3("	Total:  %d, Sent: %d",iSmsPDUData.iTotal, iSmsPDUData.iSent );
-						LOGSMSU3("	Failed: %d, Delivered: %d",iSmsPDUData.iFailed, iSmsPDUData.iDelivered );
-						GetStringL(status,R_LOG_DEL_FAILED);
-						}
-				    }
-				LOGSMSU2("SetDataL [status string=%S]",&status);
-				break;
-				}
-			default:
-				{
-				LOGSMSU1("SetDataL ESmsuUnexpectedSmsPDUType");
-				SmsuPanic(ESmsuUnexpectedSmsPDUType);
-				}
-			}
-		}
-	else
-		GetStringL(status,*aStatusId);
-
- 	TBuf<KLogMaxSubjectLength> subject;
-	//
-	// EDNAVSA-4VA9FQ Incoming SMSes with special chars are entered in the log as "data messages"
-	// only 8 bit messages are displayed as data message in the log viewer
-	//
- 	if (aSmsMessage.SmsPDU().DataCodingSchemePresent() && aSmsMessage.SmsPDU().Alphabet() == TSmsDataCodingScheme::ESmsAlphabet8Bit)
- 		{
- 		GetStringL(subject, R_LOG_SUBJECT_DATA_MESSAGE);
- 		}
- 	else if (aSmsMessage.TextPresent())
-   		{
-   		const TInt length= Min(KLogMaxSubjectLength, aSmsMessage.Buffer().Length());
- 		aSmsMessage.Buffer().Extract(subject, 0, length);
- 		subject.Trim();
- 		}
- 	if (subject.Length() == 0)
- 		{
- 		GetStringL(subject, R_LOG_SUBJECT_NONE);
-   		}
- 	iLogEvent->SetSubject(subject);
-
-	iLogEvent->SetStatus(status);
-	TPckg<TLogSmsPduData> packeddata(iSmsPDUData);
-	iLogEvent->SetDataL(packeddata);
-	} // CSmsEventLogger::SetDataL
-
-
-void CSmsEventLogger::DoComplete(TInt& aStatus)
-	{
-    LOGSMSU3("CSmsEventLogger::DoComplete(): aStatus=%d, iState=%d", aStatus, iState);
-
-	//
-	// Check the state is valid and finish up...
-	//
-	__ASSERT_DEBUG(iState == ESmsEventLoggerGettingEvent  ||
-				   iState == ESmsEventLoggerAddingEvent  ||
-				   iState == ESmsEventLoggerChangingEvent  ||
-				   iState == ESmsEventLoggerDeletingEvent, SmsuPanic(KSmsuPanicUnexpectedState));
-
-	aStatus = -aStatus;
-	iState  = ESmsEventLoggerIdle;
-	} // CSmsEventLogger::Complete
-
+// Copyright (c) 1999-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:
+// Implements the CSmsEventLogerClass
+// 
+//
+
+/**
+ @file
+*/
+
+#include "smsulog.h"
+#include "smsumain.h"
+#include "smsstacklog.h"
+#include "gsmubuf.h"
+#include "Gsmumsg.h"
+#include "Gsmuelem.h"
+#include <logwrap.h>
+#include <logwraplimits.h>
+
+
+/**
+ *  Allocates and creates a logger.
+ *  
+ *  @param aFs File server handle
+ *  @param aPriority Active object priority
+ *  @return New CSmsEventLogger object
+ *  @capability None
+ */
+EXPORT_C CSmsEventLogger* CSmsEventLogger::NewL(RFs& aFs,TInt aPriority)
+	{
+	LOGSMSU1("CSmsEventLogger::NewL()");
+
+	CSmsEventLogger* smseventlogger = new(ELeave) CSmsEventLogger(aPriority);
+	CleanupStack::PushL(smseventlogger);
+	smseventlogger->ConstructL(aFs);
+	CleanupStack::Pop();
+	return smseventlogger;
+	} // CSmsEventLogger::NewL
+
+
+/**
+ *  Destructor.
+ *  @capability None
+ */
+EXPORT_C CSmsEventLogger::~CSmsEventLogger()
+	{
+	Cancel();
+	delete iLogEvent;
+	delete iLogWrapper;
+	} // CSmsEventLogger::~CSmsEventLogger
+
+
+/**
+ *  Adds an event to the log database.
+ *  
+ *  @param aStatus Asynchronous status word to signal when the operation is complete
+ *  @param aSmsMessage The SMS message that the event concerns
+ *  @param aData SMS PDU information for the event
+ *  @param aStatusId Optional string to include in the log message, specified by
+ *  resource ID
+ *  @capability WriteUserData
+ */
+EXPORT_C void CSmsEventLogger::AddEvent(TRequestStatus& aStatus,const CSmsMessage& aSmsMessage,const TLogSmsPduData& aData,TInt* aStatusId)
+	{
+    LOGSMSU1("CSmsEventLogger::AddEvent");
+
+	__ASSERT_DEBUG(iState==ESmsEventLoggerIdle,SmsuPanic(KSmsuPanicUnexpectedState));
+	
+	iState=ESmsEventLoggerAddingEvent;
+
+	Queue(aStatus);
+
+	iSmsPDUData=aData;
+	iSmsPDUData.iType=aSmsMessage.Type();
+
+	TRAPD(ret,DoAddEventL(aSmsMessage,aStatusId));
+	if (ret!=KErrNone)
+		{
+		CompleteMyself(ret);
+		}
+	else
+		{
+		iLogWrapper->Log().AddEvent(*iLogEvent,iStatus);
+		SetActive();
+		}
+	} // CSmsEventLogger::AddEvent
+
+
+/**
+ *  Gets the specified event from the log.
+ *  
+ *  The event itself can be obtained using a subsequent call to Event().
+ *  
+ *  @param aStatus Asynchronous status word to signal when the operation is complete
+ *  @param aId Log event ID for the event
+ *  @capability ReadUserData
+ */
+EXPORT_C void CSmsEventLogger::GetEvent(TRequestStatus& aStatus,TLogId aId)
+	{
+    LOGSMSU1("CSmsEventLogger::GetEvent");
+
+	__ASSERT_DEBUG(iState==ESmsEventLoggerIdle,SmsuPanic(KSmsuPanicUnexpectedState));
+	iState=ESmsEventLoggerGettingEvent;
+	Queue(aStatus);
+	iLogEvent->SetId(aId);
+	iLogWrapper->Log().GetEvent(*iLogEvent,iStatus);
+	SetActive();
+	} // CSmsEventLogger::GetEvent
+
+/** Changes the details of an existing event.
+ 
+    Use GetEvent() to specify the event.
+ 
+    @param aStatus       Asynchronous status word to signal when the operation is complete
+    @param aSmsMessage   The SMS message that the event concerns
+    @param aTime SMS delivery time
+    @param aData SMS PDU information for the event
+    @param aStatusId Optional string to include in the log message, specified by
+    resource ID
+    @capability WriteUserData
+*/
+EXPORT_C void CSmsEventLogger::ChangeEvent(TRequestStatus& aStatus,const CSmsMessage& aSmsMessage, const TTime* aTime, const TLogSmsPduData& aData, TInt* aStatusId)
+    {
+    LOGSMSU1("CSmsEventLogger::ChangeEvent");
+    
+    __ASSERT_DEBUG(iState==ESmsEventLoggerIdle,SmsuPanic(KSmsuPanicUnexpectedState));
+    __ASSERT_DEBUG(aSmsMessage.LogServerId()==iLogEvent->Id(),SmsuPanic(KSmsuPanicWrongLogServerId));
+    __ASSERT_DEBUG(iSmsPDUData.iType==aSmsMessage.Type(),SmsuPanic(ESmsuUnexpectedSmsPDUType));
+    iState=ESmsEventLoggerChangingEvent;
+    Queue(aStatus);
+    iSmsPDUData=aData;
+    iSmsPDUData.iType=aSmsMessage.Type();        
+
+    TRAPD(ret,SetDataL(aSmsMessage,aStatusId, aTime));
+    if (ret!=KErrNone)
+        {
+        Complete(ret);
+        }
+    else
+        {
+        iLogWrapper->Log().ChangeEvent(*iLogEvent,iStatus);
+        SetActive();
+        }
+    }
+
+/**
+ *  Changes the details of an existing event.
+ *  
+ *  Use GetEvent() to specify the event.
+ *  
+ *  @param aStatus Asynchronous status word to signal when the operation is complete
+ *  @param aSmsMessage The SMS message that the event concerns
+ *  @param aData SMS PDU information for the event
+ *  @param aStatusId Optional string to include in the log message, specified by
+ *  resource ID
+ *  @capability WriteUserData
+ */
+EXPORT_C void CSmsEventLogger::ChangeEvent(TRequestStatus& aStatus, const CSmsMessage& aSmsMessage, const TLogSmsPduData& aData, TInt* aStatusId)
+	{
+	ChangeEvent(aStatus, aSmsMessage, NULL, aData, aStatusId);
+	} // CSmsEventLogger::ChangeEvent
+
+/**
+ *  Deletes an event.
+ *  
+ *  Use GetEvent() to specify the event.
+ *  
+ *  @param aStatus Asynchronous status word to signal when the operation is complete
+ *  @capability WriteUserData
+ */
+EXPORT_C void CSmsEventLogger::DeleteEvent(TRequestStatus& aStatus)
+    {
+    // Ignore in code coverage - not used within the SMS stack.
+    BULLSEYE_OFF
+    LOGSMSU1("CSmsEventLogger::DeleteEvent");
+    
+    __ASSERT_DEBUG(iState==ESmsEventLoggerIdle,SmsuPanic(KSmsuPanicUnexpectedState));
+    
+    iState=ESmsEventLoggerDeletingEvent;
+    
+    Queue(aStatus);
+    
+    iLogWrapper->Log().DeleteEvent(iLogEvent->Id(),iStatus);
+    SetActive();
+    BULLSEYE_RESTORE
+    }
+
+void CSmsEventLogger::DoCancel()
+    {
+    // Ignore in code coverage - in order to test would need to cancel
+    // event logger request; as these called when receiving/sending SMS
+    // message would need to cancel these activities during event the 
+    // logger request - too difficult to test. Need to add unit test.
+    BULLSEYE_OFF
+    LOGSMSU3("CSmsEventLogger::DoCancel [iStatus=%d, iState=%d]", iStatus.Int(), iState);
+    
+    switch( iState )
+        {
+        case ESmsEventLoggerGettingEvent:
+        case ESmsEventLoggerAddingEvent:
+        case ESmsEventLoggerChangingEvent:
+        case ESmsEventLoggerDeletingEvent:
+            {
+            iLogWrapper->Log().Cancel();
+            } break;
+        default:
+            {
+            SmsuPanic(KSmsuPanicUnexpectedState);
+            } break;
+        }
+    // Handle completion of this Active Object. Note that the object
+    // may well still be active at this point...
+    if( TimedOut() )
+        {
+        Complete(KErrTimedOut);
+        }
+    else
+        {
+        Complete(KErrCancel);
+        }
+    BULLSEYE_RESTORE
+    }
+
+CSmsEventLogger::CSmsEventLogger(TInt aPriority):
+	CSmsuActiveBase(aPriority),
+	iState(ESmsEventLoggerIdle)
+	{
+	// NOP
+	}
+
+
+void CSmsEventLogger::ConstructL(RFs& aFs)
+	{
+	LOGSMSU1("CSmsEventLogger::ConstructL()");
+
+	iLogWrapper=CLogWrapper::NewL(aFs);
+	iLogEvent=CLogEvent::NewL();
+	} // CSmsEventLogger::ConstructL
+
+
+void CSmsEventLogger::DoRunL()
+	{
+    LOGSMSU2("CSmsEventLogger::DoRunL [iStatus=%d]", iStatus.Int() );
+
+	switch (iState)
+		{
+		case ESmsEventLoggerGettingEvent:
+			{
+			if (iStatus.Int() == KErrNone)
+				{
+				TPckg<TLogSmsPduData> packeddata(iSmsPDUData);
+				packeddata.Copy(iLogEvent->Data());
+				}
+			}
+            break;
+
+		case ESmsEventLoggerAddingEvent:
+		case ESmsEventLoggerChangingEvent:
+		case ESmsEventLoggerDeletingEvent:
+			{
+			// NOP
+			}
+			break;
+
+		default:
+			{
+            User::Leave(KErrGeneral);
+            //SmsuPanic(KSmsuPanicUnexpectedState);
+            }
+            break;
+		}
+
+	//
+	// DoRunL() will now return to CSmsuActiveBase which if the object
+	// is not active, will call Complete().
+	//
+	} // CSmsEventLogger::DoRunL
+
+
+void CSmsEventLogger::DoAddEventL(const CSmsMessage& aSmsMessage,TInt* aStatusId)
+	{
+    LOGSMSU2("CSmsEventLogger::DoAddEventL [statusID*=%d]", aStatusId);
+
+	 //  Reset event
+	CLogEvent* logevent=CLogEvent::NewL();
+	delete iLogEvent;
+	iLogEvent=logevent;
+	TBuf<KLogMaxDirectionLength> direction;
+	switch (aSmsMessage.Type())
+		{
+		//  Incoming SMS
+		case CSmsPDU::ESmsDeliver:
+			{
+			LOGSMSU1("DoAddEventL ESmsDeliver");
+			GetStringL(direction,R_LOG_DIR_IN);
+			break;
+			}
+		case CSmsPDU::ESmsStatusReport:
+			{
+			LOGSMSU1("DoAddEventL ESmsStatusReport");
+			GetStringL(direction,R_LOG_DIR_IN);
+			break;
+			}
+		//  Outgoing SMS
+		case CSmsPDU::ESmsSubmit:
+			{
+			LOGSMSU1("DoAddEventL ESmsSubmit");
+			GetStringL(direction,R_LOG_DIR_OUT);
+			break;
+			}
+		case CSmsPDU::ESmsCommand:
+			{
+			LOGSMSU1("DoAddEventL ESmsCommand");
+			GetStringL(direction,R_LOG_DIR_OUT);
+			break;
+			}
+		default:
+			{
+			LOGSMSU1("DoAddEventL ESmsuUnexpectedSmsPDUType");
+			SmsuPanic(ESmsuUnexpectedSmsPDUType);
+			}
+		}
+
+	Event().SetDirection(direction);
+	Event().SetEventType(KLogShortMessageEventTypeUid);
+
+	TGsmSmsTelNumber address;
+	aSmsMessage.ParsedToFromAddress(address);
+
+	if (address.IsInstanceOf(TGsmSmsTelNumber::EVoiceMessageWaitingIndicator))
+    	{
+	    Event().SetNumber(_L("CPHS"));
+	    }
+	    else
+	    {
+	    Event().SetNumber(aSmsMessage.ToFromAddress());
+	    }
+
+	SetDataL(aSmsMessage,aStatusId, NULL);
+	} // CSmsEventLogger::DoAddEventL
+
+
+void CSmsEventLogger::SetDataL(const CSmsMessage& aSmsMessage,TInt* aStatusId, const TTime* aDischargeTime)
+	{
+
+	__ASSERT_DEBUG(iSmsPDUData.iType==aSmsMessage.Type(),SmsuPanic(ESmsuUnexpectedSmsPDUType));
+	TBuf<KLogMaxStatusLength> status;
+#ifdef _DEBUG
+	if (aStatusId!=NULL)
+		LOGSMSU2("CSmsEventLogger::SetDataL StatusID = %d", *aStatusId);
+#endif
+	if (aStatusId==NULL)
+		{
+		CSmsPDU::TSmsPDUType type=aSmsMessage.Type();
+		switch (type)
+			{
+			//  Incoming SMS
+			case CSmsPDU::ESmsDeliver:
+				{
+				if (iSmsPDUData.iTotal==iSmsPDUData.iReceived)
+					{
+					LOGSMSU1("SetDataL ESmsDeliver R_LOG_DEL_DONE");
+					GetStringL(status,R_LOG_DEL_DONE);
+					}
+				else if (iSmsPDUData.iTotal>iSmsPDUData.iReceived)
+					{
+					LOGSMSU1("SetDataL ESmsDeliver R_LOG_DEL_PENDING");
+					GetStringL(status,R_LOG_DEL_PENDING);
+					}
+				break;
+				}
+			case CSmsPDU::ESmsStatusReport:
+				{
+				if (iSmsPDUData.iTotal==iSmsPDUData.iReceived)
+					{
+					LOGSMSU1("SetDataL ESmsStatusReport R_LOG_DEL_DONE");
+					GetStringL(status,R_LOG_DEL_DONE);
+					}
+				else if (iSmsPDUData.iTotal>iSmsPDUData.iReceived)
+					{
+					LOGSMSU1("SetDataL ESmsStatusReport R_LOG_DEL_PENDING");
+					GetStringL(status,R_LOG_DEL_PENDING);
+					}
+				break;
+				}
+			//  Outgoing SMS
+			case CSmsPDU::ESmsSubmit:
+			case CSmsPDU::ESmsCommand:
+				{
+				TBool statusreportrequest=EFalse;
+				if (type==CSmsPDU::ESmsSubmit)
+					{
+					CSmsSubmit& submit=(CSmsSubmit&) aSmsMessage.SmsPDU();
+					statusreportrequest=submit.StatusReportRequest();
+					}
+				else
+					{
+					CSmsCommand& command=(CSmsCommand&) aSmsMessage.SmsPDU();
+					statusreportrequest=command.StatusReportRequest();
+					}
+				if (statusreportrequest)
+					{
+					if (iSmsPDUData.iSent==0)
+						{
+						// None sent yet
+						GetStringL(status,R_LOG_DEL_NOT_SENT);
+						LOGSMSU1("SetDataL ESmsSubmit R_LOG_DEL_NOT_SENT SR");
+						}
+					else if (iSmsPDUData.iTotal==iSmsPDUData.iDelivered)
+						{
+						// All have been delivered
+						LOGSMSU2("SetDataL ESmsSubmit R_LOG_DEL_DONE SR iSmsPDUData.iDelivered=%d", iSmsPDUData.iDelivered);
+						GetStringL(status,R_LOG_DEL_DONE);
+						}
+					else if (iSmsPDUData.iSent<=iSmsPDUData.iTotal && iSmsPDUData.iFailed==0)
+						{
+						// One or more sent but not all, no failures
+						LOGSMSU3("SetDataL ESmsSubmit R_LOG_DEL_PENDING SR iSmsPDUData.iSent==%d, iSmsPDUData.iTotal==%d, iFailed==0", iSmsPDUData.iSent, iSmsPDUData.iTotal);
+						GetStringL(status,R_LOG_DEL_PENDING);
+						}
+					else
+						{
+						// One or more failures or corruption of iSmsPDUData values
+						LOGSMSU1("SetDataL ESmsSubmit R_LOG_DEL_FAILED SR");
+						LOGSMSU3("	Total:  %d, Sent: %d",iSmsPDUData.iTotal, iSmsPDUData.iSent );
+						LOGSMSU3("	Failed: %d, Delivered: %d",iSmsPDUData.iFailed, iSmsPDUData.iDelivered );
+						GetStringL(status,R_LOG_DEL_FAILED);
+						}
+                    if (aDischargeTime != NULL)
+                        {
+                        iLogEvent->SetTime(*aDischargeTime);
+                        }					
+					}
+				else
+					{
+					if (iSmsPDUData.iSent<iSmsPDUData.iTotal)
+						{
+						// IF not all PDUs sent, state is "NOT SENT".
+						LOGSMSU1("SetDataL ESmsSubmit R_LOG_DEL_NOT_SENT NOSR");
+						LOGSMSU3("	Total:  %d, Sent: %d", iSmsPDUData.iTotal, iSmsPDUData.iSent );
+						GetStringL(status,R_LOG_DEL_NOT_SENT);
+						}
+					else if (iSmsPDUData.iTotal==iSmsPDUData.iSent)
+						{
+						// All sent
+						LOGSMSU1("SetDataL ESmsSubmit R_LOG_DEL_SENT NOSR");
+						GetStringL(status,R_LOG_DEL_SENT);
+						}
+					else
+						{
+						// The iSmsPDUData values have become corrupt
+						LOGSMSU1("SetDataL ESmsSubmit R_LOG_DEL_FAILED NOSR");
+						LOGSMSU3("	Total:  %d, Sent: %d",iSmsPDUData.iTotal, iSmsPDUData.iSent );
+						LOGSMSU3("	Failed: %d, Delivered: %d",iSmsPDUData.iFailed, iSmsPDUData.iDelivered );
+						GetStringL(status,R_LOG_DEL_FAILED);
+						}
+				    }
+				LOGSMSU2("SetDataL [status string=%S]",&status);
+				break;
+				}
+			default:
+				{
+				LOGSMSU1("SetDataL ESmsuUnexpectedSmsPDUType");
+				SmsuPanic(ESmsuUnexpectedSmsPDUType);
+				}
+			}
+		}
+	else
+		GetStringL(status,*aStatusId);
+
+ 	TBuf<KLogMaxSubjectLength> subject;
+	//
+	// EDNAVSA-4VA9FQ Incoming SMSes with special chars are entered in the log as "data messages"
+	// only 8 bit messages are displayed as data message in the log viewer
+	//
+ 	if (aSmsMessage.SmsPDU().DataCodingSchemePresent() && aSmsMessage.SmsPDU().Alphabet() == TSmsDataCodingScheme::ESmsAlphabet8Bit)
+ 		{
+ 		GetStringL(subject, R_LOG_SUBJECT_DATA_MESSAGE);
+ 		}
+ 	else if (aSmsMessage.TextPresent())
+   		{
+   		const TInt length= Min(KLogMaxSubjectLength, aSmsMessage.Buffer().Length());
+ 		aSmsMessage.Buffer().Extract(subject, 0, length);
+ 		subject.Trim();
+ 		}
+ 	if (subject.Length() == 0)
+ 		{
+ 		GetStringL(subject, R_LOG_SUBJECT_NONE);
+   		}
+ 	iLogEvent->SetSubject(subject);
+
+	iLogEvent->SetStatus(status);
+	TPckg<TLogSmsPduData> packeddata(iSmsPDUData);
+	iLogEvent->SetDataL(packeddata);
+	} // CSmsEventLogger::SetDataL
+
+
+void CSmsEventLogger::DoComplete(TInt& aStatus)
+	{
+    LOGSMSU3("CSmsEventLogger::DoComplete(): aStatus=%d, iState=%d", aStatus, iState);
+
+	//
+	// Check the state is valid and finish up...
+	//
+	__ASSERT_DEBUG(iState == ESmsEventLoggerGettingEvent  ||
+				   iState == ESmsEventLoggerAddingEvent  ||
+				   iState == ESmsEventLoggerChangingEvent  ||
+				   iState == ESmsEventLoggerDeletingEvent, SmsuPanic(KSmsuPanicUnexpectedState));
+
+	aStatus = -aStatus;
+	iState  = ESmsEventLoggerIdle;
+	} // CSmsEventLogger::Complete
+