sl@0: // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "logservcli.h" sl@0: sl@0: // System includes sl@0: #include sl@0: #include sl@0: sl@0: // User includes sl@0: #include "LogServShared.h" sl@0: sl@0: static TInt StartServer() sl@0: // sl@0: // Start the server process/thread which lives in an EPOCEXE object sl@0: // sl@0: { sl@0: const TUidType serverUid(KNullUid,KNullUid,KServerUid3); sl@0: sl@0: // sl@0: // EPOC is easy, we just create a new server process. Simultaneous launching sl@0: // of two such processes should be detected when the second one attempts to sl@0: // create the server object, failing with KErrAlreadyExists. sl@0: // sl@0: RProcess server; sl@0: TInt r=server.Create(KLogServerName,KNullDesC,serverUid); sl@0: if (r == KErrNone) sl@0: server.SetPriority(EPriorityForeground); sl@0: sl@0: if (r!=KErrNone) sl@0: return r; sl@0: sl@0: TRequestStatus stat; sl@0: server.Rendezvous(stat); sl@0: if (stat!=KRequestPending) sl@0: server.Kill(0); // abort startup sl@0: else sl@0: server.Resume(); // logon OK - start the server sl@0: User::WaitForRequest(stat); // wait for start or death sl@0: // we can't use the 'exit reason' if the server panicked as this sl@0: // is the panic 'reason' and may be '0' which cannot be distinguished sl@0: // from KErrNone sl@0: r=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int(); sl@0: server.Close(); sl@0: return r; sl@0: sl@0: } sl@0: sl@0: // Initialise the operation and view ids sl@0: RLogSession::RLogSession() sl@0: : iOperationId(KLogNullOperationId + 1), iViewId(KLogNullViewId + 1) sl@0: { sl@0: } sl@0: sl@0: TInt RLogSession::Connect() sl@0: // sl@0: // Connect to the server, attempting to start it if necessary sl@0: // sl@0: { sl@0: TInt retry=2; sl@0: for (;;) sl@0: { sl@0: TInt r=CreateSession(KLogServerFullName,TVersion(0,0,0)); sl@0: if (r!=KErrNotFound && r!=KErrServerTerminated) sl@0: return r; sl@0: if (--retry==0) sl@0: return r; sl@0: r=StartServer(); sl@0: if (r!=KErrNone && r!=KErrAlreadyExists) sl@0: return r; sl@0: } sl@0: } sl@0: sl@0: sl@0: void RLogSession::Send(TInt aType, const TIpcArgs& aArgs, TRequestStatus& aStatus) const sl@0: { sl@0: SendWithRetryAsync(aType, aArgs, aStatus); sl@0: } sl@0: sl@0: TInt RLogSession::Send(TInt aType, const TIpcArgs& aArgs) const sl@0: { sl@0: return SendWithRetry(aType, aArgs); sl@0: } sl@0: sl@0: TInt RLogSession::SendWithRetry(TInt aType, const TIpcArgs& aParam) const sl@0: { sl@0: TInt ret = SendReceive(aType, aParam); sl@0: if (ret < KErrNone) sl@0: { sl@0: if(ret == KErrServerTerminated || ret == KErrNotFound) sl@0: { sl@0: // Try to reconnect sl@0: const_cast(*this).Close(); sl@0: ret = const_cast(*this).Connect(); sl@0: if(ret == KErrNone) sl@0: { sl@0: // Try to resend sl@0: ret = SendReceive(aType, aParam); sl@0: } sl@0: } sl@0: } sl@0: return ret; sl@0: } sl@0: sl@0: sl@0: void RLogSession::SendWithRetryAsync(TInt aType, const TIpcArgs& aParam, TRequestStatus& aStatus) const sl@0: { sl@0: SendReceive(aType, aParam, aStatus); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: #ifdef LOGGING_ENABLED sl@0: sl@0: const TInt KLogEngLogBufferSize = 256; sl@0: sl@0: void Log::New() sl@0: { sl@0: _LIT(KNewLogText, "===== NEW LOG ====="); sl@0: // sl@0: RFileLogger logger; sl@0: TInt ret=logger.Connect(); sl@0: if (ret==KErrNone) sl@0: { sl@0: logger.CreateLog(KLogFolder, KLogFileName, EFileLoggingModeOverwrite); sl@0: logger.Write(KNewLogText); sl@0: } sl@0: logger.Close(); sl@0: } sl@0: sl@0: void Log::Write(const TDesC& aText) sl@0: { sl@0: PruneLogFile(); sl@0: sl@0: RFileLogger logger; sl@0: TInt ret=logger.Connect(); sl@0: if (ret==KErrNone) sl@0: { sl@0: logger.SetDateAndTime(EFalse,EFalse); sl@0: logger.CreateLog(KLogFolder, KLogFileName,EFileLoggingModeAppend); sl@0: TBuf buf; sl@0: sl@0: // The debug log uses hometime rather than UTC for its timestamps. This is sl@0: // purely a debugging aid. sl@0: TTime now; sl@0: now.HomeTime(); sl@0: sl@0: TDateTime dateTime; sl@0: dateTime = now.DateTime(); sl@0: buf.Format(KTimeFormat,dateTime.Hour(),dateTime.Minute(),dateTime.Second(),dateTime.MicroSecond()); sl@0: buf.AppendFormat(KTextFormat,&aText); sl@0: sl@0: logger.Write(buf); sl@0: } sl@0: sl@0: logger.Close(); sl@0: } sl@0: sl@0: void Log::WriteFormat(TRefByValue aFmt,...) sl@0: { sl@0: VA_LIST list; sl@0: VA_START(list,aFmt); sl@0: sl@0: PruneLogFile(); sl@0: sl@0: TBuf<2*KLogEngLogBufferSize> buf; sl@0: buf.SetMax(); sl@0: buf.FillZ(); sl@0: sl@0: // The debug log uses hometime rather than UTC for its timestamps. This is sl@0: // purely a debugging aid. sl@0: TTime now; sl@0: now.HomeTime(); sl@0: sl@0: TDateTime dateTime; sl@0: dateTime = now.DateTime(); sl@0: buf.Format(KTimeFormat,dateTime.Hour(),dateTime.Minute(),dateTime.Second(),dateTime.MicroSecond()); sl@0: buf.AppendFormatList(aFmt, list ); sl@0: sl@0: RFileLogger logger; sl@0: TInt ret=logger.Connect(); sl@0: if (ret==KErrNone) sl@0: { sl@0: logger.SetDateAndTime(EFalse,EFalse); sl@0: logger.CreateLog(KLogFolder, KLogFileName,EFileLoggingModeAppend); sl@0: logger.Write(buf); sl@0: } sl@0: sl@0: logger.Close(); sl@0: } sl@0: sl@0: void Log::PruneLogFile() sl@0: { sl@0: const TInt KMaxLogSize = 1024 * 500; sl@0: // sl@0: _LIT(KBaseFolder, "_:\\Logs\\"); sl@0: TFileName fileName(KBaseFolder); sl@0: fileName[0] = 'A' + static_cast(RFs::GetSystemDrive()); sl@0: fileName.Append(KLogFolder); sl@0: fileName.Append(KPathDelimiter); sl@0: fileName.Append(KLogFileName); sl@0: // sl@0: RFs fsSession; sl@0: if (fsSession.Connect() == KErrNone) sl@0: { sl@0: TEntry entry; sl@0: if (fsSession.Entry(fileName, entry) == KErrNone) sl@0: { sl@0: // Check size and delete if its too big sl@0: if (entry.iSize >= KMaxLogSize) sl@0: { sl@0: TInt fileDeleteErr=fsSession.Delete(fileName); sl@0: sl@0: // If a debug build - record error sl@0: #ifdef _DEBUG sl@0: if (fileDeleteErr != KErrNone) sl@0: { sl@0: RDebug::Print(_L("Log::PruneLogFile - Failed to delete file. Error = %d"), fileDeleteErr); sl@0: } sl@0: #else sl@0: (void)fileDeleteErr; sl@0: #endif sl@0: } sl@0: } sl@0: } sl@0: fsSession.Close(); sl@0: } sl@0: sl@0: #endif sl@0: