sl@0: /* sl@0: * Copyright (c) 2006-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: Contained libc logger class implementation. sl@0: * sl@0: */ sl@0: sl@0: sl@0: // INCLUDE FILES sl@0: #include sl@0: sl@0: #ifdef SYMBIAN_FILE_LOGGER sl@0: #include sl@0: #endif sl@0: sl@0: #include "libloggerhandler.h" sl@0: sl@0: // CONSTANTS sl@0: #define LOG_MESSAGE_TYPE_INFO "INFO" sl@0: #define LOG_MESSAGE_TYPE_MINOR "MINOR" sl@0: #define LOG_MESSAGE_TYPE_MAJOR "MAJOR" sl@0: #define LOG_MESSAGE_TYPE_CRITICAL "CRITICAL" sl@0: sl@0: sl@0: #define MAX_LOG_STR_LEN 512 /* Overall size of any logging string size, including timestamp and others */ sl@0: #define MAX_DATE_TIME_LEN 32 sl@0: sl@0: #define DUMP_STR_LENGTH 16 sl@0: sl@0: #ifdef SYMBIAN_FILE_LOGGER sl@0: _LIT(KLogFileLocation,"libc"); // c:\logs\libc sl@0: #else sl@0: _LIT(KLogFileLocation,"c:\\logs\\libc\\"); sl@0: _LIT8(KDumpSpace," %04x "); sl@0: #endif sl@0: sl@0: const char KMsgType[4][16] = sl@0: { sl@0: LOG_MESSAGE_TYPE_INFO, sl@0: LOG_MESSAGE_TYPE_MINOR, sl@0: LOG_MESSAGE_TYPE_MAJOR, sl@0: LOG_MESSAGE_TYPE_CRITICAL sl@0: }; sl@0: sl@0: // ============================ LOCAL FUNCTIONS =============================== sl@0: sl@0: // strlen is implemented over here, just to remove the dependancy from libc/estdlib sl@0: sl@0: // ----------------------------------------------------------------------------- sl@0: // _lstrlen sl@0: // find the string length. sl@0: // ----------------------------------------------------------------------------- sl@0: // sl@0: LOCAL_C TInt _lstrlen(const char *str) sl@0: sl@0: { sl@0: const char *s; sl@0: for (s = str; *s; ++s) sl@0: { sl@0: } sl@0: return(s - str); sl@0: } sl@0: // ----------------------------------------------------------------------------- sl@0: // BitPosition sl@0: // Find the bit position within the number sl@0: // ----------------------------------------------------------------------------- sl@0: // sl@0: LOCAL_C TInt BitPosition(TInt aNumber) sl@0: { sl@0: TInt pos = 0; sl@0: while(!(aNumber & 1)) sl@0: { sl@0: aNumber = (aNumber >> 1); sl@0: pos++; sl@0: } sl@0: // only first 4 bits are used. sl@0: if ( pos < 0 || pos >= 4) sl@0: { sl@0: // crosses the boundary. sl@0: pos = 0; sl@0: } sl@0: return pos; sl@0: } sl@0: sl@0: sl@0: // ----------------------------------------------------------------------------- sl@0: // CLibLogger::GetLogFilename sl@0: // Get the log file name. sl@0: // ----------------------------------------------------------------------------- sl@0: // sl@0: void CLibLogger::GetLogFilename(TDes& aFileName) sl@0: { sl@0: _LIT(KFileNameFormat, "Mrt_%S.txt"); sl@0: RProcess currentProcess; sl@0: TName processName = currentProcess.Name(); sl@0: #ifdef SYMBIAN_FILE_LOGGER sl@0: aFileName.Format(KFileNameFormat, &processName); sl@0: #else sl@0: aFileName.Copy(KLogFileLocation); sl@0: aFileName.AppendFormat(KFileNameFormat, &processName); sl@0: #endif sl@0: currentProcess.Close(); sl@0: } sl@0: sl@0: // ----------------------------------------------------------------------------- sl@0: // CLibLogger::WriteMessage sl@0: // Write message to the log file sl@0: // ----------------------------------------------------------------------------- sl@0: // sl@0: TInt CLibLogger::WriteMessage(const TDesC8& aMessage) sl@0: { sl@0: TFileName logFileName; sl@0: GetLogFilename(logFileName); sl@0: TInt err = KErrNone; sl@0: #ifdef SYMBIAN_FILE_LOGGER sl@0: RFileLogger::Write(KLogFileLocation, logFileName, EFileLoggingModeAppend, aMessage); sl@0: #else sl@0: RFs fsSession; /* file server */ sl@0: RFile iFile; sl@0: err = CLibLogger::CreateFileSession(fsSession, iFile); sl@0: if(KErrNone != err) sl@0: { sl@0: /* Error : Unable to initialize the file session */ sl@0: return err; sl@0: } sl@0: sl@0: /* write the buffer to the file */ sl@0: err = iFile.Write(aMessage); sl@0: if(KErrNone != err) sl@0: { sl@0: /* Error : Unable to initialize the file session */ sl@0: iFile.Close(); sl@0: fsSession.Close(); sl@0: return err; sl@0: } sl@0: sl@0: /* flush the buffer */ sl@0: iFile.Flush(); /* commit the write. */ sl@0: sl@0: /* close the session and resources */ sl@0: iFile.Close(); sl@0: fsSession.Close(); sl@0: #endif sl@0: return err; sl@0: } sl@0: sl@0: // ----------------------------------------------------------------------------- sl@0: // CLibLogger::LogMessage sl@0: // Logging the internal messages. sl@0: // ----------------------------------------------------------------------------- sl@0: // sl@0: int CLibLogger::LogMessage(TLibTraceMessageType aLogMessageType, sl@0: char *aFileName, sl@0: int aLine, sl@0: char *aFormat, sl@0: VA_LIST& aMarkerList) sl@0: { sl@0: /* checking for error inputs */ sl@0: if(NULL == aFormat) sl@0: { sl@0: /* Error : Check the input parameter. */ sl@0: return -1; sl@0: } sl@0: sl@0: /* trying to fetch the local time */ sl@0: TBuf8 lBuf; sl@0: lBuf.FillZ(); sl@0: lBuf.SetLength(0); sl@0: sl@0: #ifdef SYMBIAN_FILE_LOGGER sl@0: /* formulate the time stamp with log type */ sl@0: _LIT8(KFormat, "(%s : %d) [%s] - "); sl@0: lBuf.Format(KFormat, sl@0: aFileName, sl@0: aLine, sl@0: KMsgType[BitPosition(aLogMessageType)] sl@0: ); sl@0: #else sl@0: TTime lCurTime; sl@0: lCurTime.HomeTime(); sl@0: TDateTime lTimeStamp = lCurTime.DateTime(); sl@0: sl@0: /* formulate the time stamp with log type */ sl@0: _LIT8(KFormat, "%2d/%2d/%d-%2d:%2d:%2d.%3d - (%s : %d) [%s] - "); sl@0: lBuf.Format(KFormat, sl@0: lTimeStamp.Day(), sl@0: (int)(lTimeStamp.Month() + 1), sl@0: lTimeStamp.Year(), sl@0: lTimeStamp.Hour(), sl@0: lTimeStamp.Minute(), sl@0: lTimeStamp.Second(), sl@0: (int)((lTimeStamp.MicroSecond())/1000), sl@0: aFileName, sl@0: aLine, sl@0: KMsgType[BitPosition(aLogMessageType)] sl@0: ); sl@0: #endif // SYMBIAN_FILE_LOGGER sl@0: sl@0: TPtrC8 lPtr((TUint8*)aFormat, _lstrlen(aFormat)); sl@0: lBuf.AppendFormatList(lPtr, aMarkerList); sl@0: sl@0: /* new line */ sl@0: _LIT8(KNewLine, "\r\n"); sl@0: lBuf.Append(KNewLine); sl@0: WriteMessage(lBuf); sl@0: return lBuf.Length(); sl@0: } sl@0: sl@0: // ----------------------------------------------------------------------------- sl@0: // CLibLogger::LogMessage sl@0: // Logging the internal messages. sl@0: // ----------------------------------------------------------------------------- sl@0: // sl@0: int CLibLogger::LogMessage(char *aFileName, int aLine) sl@0: { sl@0: /* trying to fetch the local time */ sl@0: TBuf8 lBuf; sl@0: lBuf.FillZ(); sl@0: lBuf.SetLength(0); sl@0: sl@0: #ifdef SYMBIAN_FILE_LOGGER sl@0: /* formulate the time stamp with log type */ sl@0: _LIT8(KFormat, "(%s : %d) "); sl@0: lBuf.Format(KFormat, sl@0: aFileName, sl@0: aLine); sl@0: #else sl@0: TTime lCurTime; sl@0: lCurTime.HomeTime(); sl@0: TDateTime lTimeStamp = lCurTime.DateTime(); sl@0: sl@0: /* formulate the time stamp with log type */ sl@0: _LIT8(KFormat, "%2d/%2d/%d-%2d:%2d:%2d.%3d - (%s : %d) "); sl@0: lBuf.Format(KFormat, sl@0: lTimeStamp.Day(), sl@0: (int)(lTimeStamp.Month() + 1), sl@0: lTimeStamp.Year(), sl@0: lTimeStamp.Hour(), sl@0: lTimeStamp.Minute(), sl@0: lTimeStamp.Second(), sl@0: (int)((lTimeStamp.MicroSecond())/1000), sl@0: aFileName, sl@0: aLine); sl@0: #endif // SYMBIAN_FILE_LOGGER sl@0: WriteMessage(lBuf); sl@0: return lBuf.Length(); sl@0: } sl@0: sl@0: sl@0: // ----------------------------------------------------------------------------- sl@0: // CLibLogger::LogMessage sl@0: // Logging the internal messages. sl@0: // ----------------------------------------------------------------------------- sl@0: // sl@0: int CLibLogger::LogMessage(TLibTraceMessageType aLogMessageType, sl@0: char *aFormat, sl@0: VA_LIST& aMarkerList) sl@0: { sl@0: /* checking for error inputs */ sl@0: if(NULL == aFormat) sl@0: { sl@0: /* Error : Check the input parameter. */ sl@0: return -1; sl@0: } sl@0: sl@0: /* trying to fetch the local time */ sl@0: TBuf8 lBuf; sl@0: lBuf.FillZ(); sl@0: lBuf.SetLength(0); sl@0: sl@0: /* formulate the time stamp with log type */ sl@0: _LIT8(KFormat, "[%s] - "); sl@0: lBuf.Format(KFormat, sl@0: KMsgType[BitPosition(aLogMessageType)] sl@0: ); sl@0: sl@0: TPtrC8 lPtr((TUint8*)aFormat, _lstrlen(aFormat)); sl@0: lBuf.AppendFormatList(lPtr, aMarkerList); sl@0: sl@0: /* new line */ sl@0: _LIT8(KNewLine, "\r\n"); sl@0: lBuf.Append(KNewLine); sl@0: WriteMessage(lBuf); sl@0: return lBuf.Length(); sl@0: } sl@0: sl@0: sl@0: // ----------------------------------------------------------------------------- sl@0: // CLibLogger::DumpFormatMessage sl@0: // Dump the internal message in hex format. sl@0: // ----------------------------------------------------------------------------- sl@0: // sl@0: int CLibLogger::DumpFormatMessage(TLibTraceMessageType aLogMessageType, sl@0: char *aFileName, sl@0: int aLine, sl@0: char *aMessage, sl@0: char *aFormat, sl@0: VA_LIST& aMarkerList) sl@0: { sl@0: if(NULL == aFormat) sl@0: { sl@0: /* Error : Check your input value. */ sl@0: return 0; sl@0: } sl@0: TBuf8 lBuf; sl@0: lBuf.FillZ(); sl@0: lBuf.SetLength(0); sl@0: TPtrC8 lPtr((TUint8*)aFormat, _lstrlen(aFormat)); sl@0: lBuf.AppendFormatList(lPtr, aMarkerList); sl@0: sl@0: return DumpMessage(aLogMessageType, aFileName, aLine, aMessage, (char *)lBuf.PtrZ(), lBuf.Length()); sl@0: } sl@0: sl@0: // ----------------------------------------------------------------------------- sl@0: // CLibLogger::DumpMessage sl@0: // Dump the internal message in hex format. sl@0: // ----------------------------------------------------------------------------- sl@0: // sl@0: int CLibLogger::DumpMessage(TLibTraceMessageType aLogMessageType, sl@0: char *aFileName, sl@0: int aLine, sl@0: char *aMessage, sl@0: char *aStr, sl@0: int aStrLen) sl@0: { sl@0: int istrLen = (aStrLen == -1) ? _lstrlen(aStr) : aStrLen; sl@0: if((NULL == aStr) sl@0: || (istrLen <= 0)) sl@0: { sl@0: /* Error : Check your input value. */ sl@0: return 0; sl@0: } sl@0: /* log the timestamp */ sl@0: sl@0: return LibTracer(aLogMessageType, aFileName, aLine, aMessage) + DumpMessage(aStr, istrLen); sl@0: } sl@0: sl@0: // ----------------------------------------------------------------------------- sl@0: // CLibLogger::DumpFormatMessage sl@0: // Dump the internal message in hex format. sl@0: // ----------------------------------------------------------------------------- sl@0: // sl@0: int CLibLogger::DumpFormatMessage(TLibTraceMessageType aLogMessageType, sl@0: char *aMessage, sl@0: char *aFormat, sl@0: VA_LIST& aMarkerList) sl@0: { sl@0: if(NULL == aFormat) sl@0: { sl@0: /* Error : Check your input value. */ sl@0: return 0; sl@0: } sl@0: sl@0: sl@0: /* trying to fetch the local time */ sl@0: TBuf8 lBuf; sl@0: lBuf.FillZ(); sl@0: lBuf.SetLength(0); sl@0: sl@0: /* formulate the time stamp with log type */ sl@0: _LIT8(KFormat, "[%s] - %s"); sl@0: lBuf.Format(KFormat, sl@0: KMsgType[BitPosition(aLogMessageType)], aMessage); sl@0: sl@0: sl@0: _LIT8(KNewLine, "\r\n"); sl@0: lBuf.Append(KNewLine); sl@0: WriteMessage(lBuf); sl@0: int len = lBuf.Length(); sl@0: lBuf.FillZ(); sl@0: lBuf.SetLength(0); sl@0: TPtrC8 lPtr((TUint8*)aFormat, _lstrlen(aFormat)); sl@0: lBuf.AppendFormatList(lPtr, aMarkerList); sl@0: sl@0: return len + DumpMessage((char *)lBuf.PtrZ(), lBuf.Length()); sl@0: } sl@0: sl@0: sl@0: sl@0: #ifdef SYMBIAN_FILE_LOGGER sl@0: // ----------------------------------------------------------------------------- sl@0: // CLibLogger::DumpMessage sl@0: // Dump the internal message in hex format. sl@0: // ----------------------------------------------------------------------------- sl@0: // sl@0: int CLibLogger::DumpMessage(char *aStr, int aStrLen) sl@0: { sl@0: /* check the inputs */ sl@0: if((NULL == aStr) sl@0: || (aStrLen <= 0)) sl@0: { sl@0: /* Error : Check your input value. */ sl@0: return 0; sl@0: } sl@0: sl@0: /* Input parameter is okey */ sl@0: sl@0: TFileName logFileName; sl@0: GetLogFilename(logFileName); sl@0: RFileLogger::HexDump(KLogFileLocation, logFileName, EFileLoggingModeAppend, NULL, NULL, (TUint8*)aStr, aStrLen); sl@0: return aStrLen; sl@0: } sl@0: sl@0: sl@0: #else sl@0: sl@0: // ----------------------------------------------------------------------------- sl@0: // CLibLogger::CreateFileSession sl@0: // Create a file session for the logger. sl@0: // ----------------------------------------------------------------------------- sl@0: // sl@0: int CLibLogger::CreateFileSession(RFs &aFsSession, RFile &aFile) sl@0: { sl@0: int lErr; sl@0: /* register with the file service session. */ sl@0: sl@0: lErr = aFsSession.Connect(); sl@0: if(lErr != KErrNone) sl@0: { sl@0: /* Error : unable to create a session with file server */ sl@0: return lErr; sl@0: } sl@0: sl@0: /* Success : application is connected with the file server */ sl@0: sl@0: TFileName logFileName; sl@0: GetLogFilename(logFileName); sl@0: sl@0: aFsSession.MkDirAll(logFileName); sl@0: CDir* fileList; sl@0: CDir* dirList; sl@0: sl@0: //coverity[alloc_fn] sl@0: lErr = aFsSession.GetDir(logFileName,KEntryAttNormal, sl@0: ESortByName,fileList,dirList); sl@0: if(lErr != KErrNone) sl@0: { sl@0: /* Error : unable to retrieve the directory list */ sl@0: aFsSession.Close(); /* close the session with file server */ sl@0: return lErr; sl@0: } sl@0: sl@0: if(0 >= fileList->Count()) sl@0: { sl@0: /* File doesn't exist. create a new file. */ sl@0: lErr = aFile.Replace(aFsSession, sl@0: logFileName, sl@0: EFileWrite|EFileStreamText); sl@0: if(lErr != KErrNone) sl@0: { sl@0: /* Error : unable to create the new file. */ sl@0: delete fileList; sl@0: delete dirList; sl@0: aFsSession.Close(); /* close the session with file server */ sl@0: return lErr; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: /* Shared access for reading and writing. */ sl@0: lErr = aFile.Open(aFsSession, sl@0: logFileName, sl@0: EFileWrite | EFileStreamText); sl@0: if(lErr != KErrNone) sl@0: { sl@0: /* Error : unable to open the file. */ sl@0: delete fileList; sl@0: delete dirList; sl@0: aFsSession.Close(); /* close the session with file server */ sl@0: return lErr; sl@0: } sl@0: int pos = 0; /* since we have pass the 2nd parameter as reference. */ sl@0: lErr = aFile.Seek(ESeekEnd, pos); sl@0: if(lErr != KErrNone) sl@0: { sl@0: /* Error : unable to move the file pointer. */ sl@0: //coverity[leave_without_push] sl@0: aFile.Close(); /* close the file */ sl@0: //coverity[leave_without_push] sl@0: aFsSession.Close(); /* close the session with file server */ sl@0: delete fileList; sl@0: delete dirList; sl@0: return lErr; sl@0: } sl@0: } sl@0: /* delete the resources */ sl@0: sl@0: delete fileList; sl@0: delete dirList; sl@0: return lErr; sl@0: } sl@0: sl@0: sl@0: // ----------------------------------------------------------------------------- sl@0: // CLibLogger::DumpMessage sl@0: // Dump the internal message in hex format. sl@0: // ----------------------------------------------------------------------------- sl@0: // sl@0: int CLibLogger::DumpMessage(char *aStr, int aStrLen) sl@0: { sl@0: /* check the inputs */ sl@0: if((NULL == aStr) sl@0: || (aStrLen <= 0)) sl@0: { sl@0: /* Error : Check your input value. */ sl@0: return 0; sl@0: } sl@0: sl@0: /* Input parameter is okey */ sl@0: sl@0: /* local variables */ sl@0: int counter = 0; sl@0: sl@0: /* store the input string to a local pointer */ sl@0: TPtrC8 istrMesg((TUint8* )aStr, aStrLen); sl@0: sl@0: /* local log buffer */ sl@0: TBuf8 lstrLogMesgString; sl@0: TBuf8 ptempStr; sl@0: sl@0: /* few literals */ sl@0: _LIT8(KSpace, " "); sl@0: _LIT8(KDblSpace, " "); sl@0: _LIT8(KFormat, "%2x "); /* hex format */ sl@0: _LIT8(KNewLine, "\r\n"); sl@0: RFs fsSession; /* file server */ sl@0: RFile file; sl@0: int lErr = CLibLogger::CreateFileSession(fsSession, file); sl@0: if(KErrNone != lErr) sl@0: { sl@0: /* Error : Unable to initialize the file session */ sl@0: return lErr; sl@0: } sl@0: // since these method can be called in from thread context and sl@0: // thread may not call this method within TRAPD sl@0: //CleanupClosePushL(fsSession); sl@0: //CleanupClosePushL(file); sl@0: sl@0: for(counter = 0; counter < aStrLen; counter++) sl@0: { sl@0: if((counter != 0) && ((counter % DUMP_STR_LENGTH) == 0)) sl@0: { sl@0: /* sring reaches with the multiple to 16 (DUMP_STR_LENGTH) */ sl@0: lstrLogMesgString.UpperCase(); sl@0: lstrLogMesgString.Append(KSpace); sl@0: /* append 16 (DUMP_STR_LENGTH) characters */ sl@0: lstrLogMesgString.Append(istrMesg.Mid(((counter / DUMP_STR_LENGTH) - 1) * DUMP_STR_LENGTH, DUMP_STR_LENGTH)); sl@0: sl@0: /* dump the buffer */ sl@0: ptempStr.Format(KDumpSpace, counter - DUMP_STR_LENGTH); sl@0: lstrLogMesgString.Insert(0, ptempStr); sl@0: file.Write(lstrLogMesgString); sl@0: file.Write(KNewLine); sl@0: file.Flush(); sl@0: /* free the buffer, set the length to zero */ sl@0: lstrLogMesgString.FillZ(); sl@0: lstrLogMesgString.SetLength(0); sl@0: } /* end of if */ sl@0: ptempStr.Format(KFormat,(int)istrMesg[counter]); sl@0: lstrLogMesgString.Append(ptempStr); sl@0: } /* end of for */ sl@0: sl@0: if(0 < lstrLogMesgString.Length()) sl@0: { sl@0: /* few character remains */ sl@0: /* it's not multiple of 16 (DUMP_STR_LENGTH) */ sl@0: /* adjust the dump and the character portion */ sl@0: if (aStrLen % DUMP_STR_LENGTH != 0) sl@0: { sl@0: for(int lliCounter = 0; lliCounter < DUMP_STR_LENGTH - (aStrLen % DUMP_STR_LENGTH); lliCounter++) sl@0: { sl@0: lstrLogMesgString.Append(KDblSpace); /* filling the blanks */ sl@0: } /* end of for */ sl@0: } sl@0: lstrLogMesgString.UpperCase(); sl@0: /* fill the string */ sl@0: lstrLogMesgString.Append(KSpace); sl@0: /* append the string */ sl@0: if (aStrLen % DUMP_STR_LENGTH != 0) sl@0: { sl@0: lstrLogMesgString.Append(istrMesg.Mid(((counter / DUMP_STR_LENGTH)) * DUMP_STR_LENGTH, (aStrLen - ((counter / DUMP_STR_LENGTH)) * DUMP_STR_LENGTH))); sl@0: } sl@0: else sl@0: { sl@0: lstrLogMesgString.Append(istrMesg.Mid(((counter / DUMP_STR_LENGTH) - 1) * DUMP_STR_LENGTH, (aStrLen - ((counter / DUMP_STR_LENGTH) -1) * DUMP_STR_LENGTH))); sl@0: } sl@0: ptempStr.Format(KDumpSpace, ((aStrLen / DUMP_STR_LENGTH) * DUMP_STR_LENGTH)); sl@0: lstrLogMesgString.Insert(0, ptempStr); sl@0: file.Write(lstrLogMesgString); sl@0: file.Write(KNewLine); sl@0: file.Flush(); sl@0: } /* end of if */ sl@0: //CleanupStack::PopAndDestroy(2); // file, fsFession sl@0: file.Close(); sl@0: fsSession.Close(); sl@0: return aStrLen; /* return the total dump message length */ sl@0: } sl@0: sl@0: #endif // SYMBIAN_FILE_LOGGER sl@0: sl@0: #ifndef EKA2 sl@0: sl@0: GLDEF_C TInt E32Dll(TDllReason aReason) sl@0: { sl@0: switch (aReason) sl@0: { sl@0: default: sl@0: break; sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: #endif sl@0: sl@0: // End of file