smsprotocols/smsstack/smsu/src/smsulog.cpp
changeset 0 3553901f7fa8
child 19 630d2f34d719
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smsprotocols/smsstack/smsu/src/smsulog.cpp	Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +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
+