diff -r 000000000000 -r 3553901f7fa8 smsprotocols/smsstack/smsu/src/smsulog.cpp --- /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 +#include + + +/** + * 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 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 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 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 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 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 +