Update contrib.
1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // Implements the Flogger server side data writing
23 #include "comsdbgwriter.h"
24 #include "comsdbgmessages.h"
27 const TInt KHeapBufSize = 50000; // Maximum that the file buffer can grow to limit its impact somewhat
30 // RDebug will truncate strings longer than the limit below
31 const TInt KRDebugLimit = 0x100;
34 // source strings, lengths and offsets
35 _LIT8(KLogStartedString, "#Logging started on dd/mm/yyyy. Output version 2\r\n"); ///< Format specifier for the very first line written. The output version is printed so tools processing the log output can determine the expected format of the output.
36 _LIT8(KDateChangedString,"# Date is now: dd/mm/yyyy.\r\n"); ///< Format specifier for subsequent date changes
37 const TInt KLogStartedStringLength = 50;
38 const TInt KLogStartedDayOffset = 20;
39 const TInt KLogStartedMonthOffset = 23;
40 const TInt KLogStartedYearOffset = 26;
42 _LIT8(KUnableToLog, "#Logs lost since log file couldn't be written to");
44 _LIT8(KClearLogString, "#Clear Log called by ");
45 const TInt KClearLogStringLength = 21;
47 _LIT8(KEolCharacters, "\r\n");
48 const TInt KEolCharactersLength = 2;
50 _LIT8(KLogPathTree,"\\");
51 _LIT8(KLogFileExt,".");
53 //Below const is... log string + 2 tags + 8 for the thread id + 3 tabs + EOL characters.
54 const TInt KMaxFinalLogStringLength = KLogBufferSize+2*KMaxTagLength+8+3+KEolCharactersLength;
56 _LIT8(KBadMediaString, "#Bad media setting in ini file.\r\n");
57 _LIT8(KUnableToUpdateMedia, "#Unable to update logging media. Err code: %d\r\n");
58 _LIT8(KUnableToLoadSerialDevices, "#Unable to load the LDD or PDD required for serial. Err code: %d\r\n");
59 _LIT8(KUnableToOpenSerial, "#Unable to open the serial port. Err code: %d\r\n");
60 _LIT8(KUnableToSetSerialConfig, "#Could not set serial port configuration after opening port. Err code: %d\r\n");
63 _LIT8(KTabCharacter, "\t");
64 _LIT8(KTypeIdentifierAscii, "a");
65 _LIT8(KTypeIdentifierBinary, "b");
68 const TBps KFloggerSerialRate = EBps115200;
69 const TInt KSerialRetryCount = 50;
70 const TInt KSerialTimeoutInMicroSecs = 100000;
73 const TInt KSerialPort1 = 0;
74 #if defined (__WINS__)
75 const TInt KSerialPort2OnEmulator = 1;
77 const TInt KSerialPort2OnTarget = 2;
80 #if defined (__WINS__)
81 #define PDD_NAME _L("ECDRV.PDD")
82 #define LDD_NAME _L("ECOMM.LDD")
84 #define PDD_NAME _L("EUART1")
85 #define LDD_NAME _L("ECOMM")
90 _LIT(KLogFileName, "log.txt");
91 _LIT(KLogDefaultFilePath, "C:\\logs\\");
94 const TUint KZeroDate = 0; ///< The day to count forward from when determining date roll.
95 const TUint KSecondsToWriteTimestampOnNoActivity = 5;
97 #if defined (__WINS__)
98 const TInt Win32DisplayStringLengthMax = 1024;
104 CLogManager* CLogManager::NewL(MLogArrayAccess& aArrayAccess)
106 CLogManager* self = new(ELeave) CLogManager(aArrayAccess);
107 CleanupStack::PushL(self);
109 CleanupStack::Pop(self);
114 CLogManager::CLogManager(MLogArrayAccess& aArrayAccess)
115 : iArrayAccess(aArrayAccess), iTimeString(KTimeFormat)
118 CLogManager::~CLogManager()
123 void CLogManager::ConstructL()
125 * Set the initial media to file and write there until the server has told us
126 * which media is in the ini file.
127 * Write the log started and date message.
130 iLogger = CFileWriter::NewL(); //File writer by default
131 iCurrentMediaSetting = KFileMedia;
132 iLoggingEnabled = EFalse;
135 TInt CLogManager::ThreadEntryPoint(TAny* aPtr)
137 MLogArrayAccess* arrayAccess = static_cast<MLogArrayAccess*> (aPtr);
139 CTrapCleanup* cleanupStack = CTrapCleanup::New();
140 if (cleanupStack==NULL)
145 TRAPD(err, CLogManager::DoRunThreadL(*arrayAccess));
152 void CLogManager::DoRunThreadL(MLogArrayAccess& aArrayAccess)
154 CLogManager* self = CLogManager::NewL(aArrayAccess);
159 void CLogManager::DoStart()
161 * Second/consumer/slave/draining/dequeuer thread main loop.
162 * @note Continuously takes the log queue top message and processes it. Blocks on the "Get" if no messages.
163 * @note Completes when a shutdown message is processed from the queue. This message sets "iShutDown".
166 CLogMessageBase * message = NULL;
169 RThread::Rendezvous(ret);
173 iArrayAccess.GetFirstMessageAndTakeOwnership(message);
174 __ASSERT_ALWAYS(message, User::Panic(KFloggerServerPanic, ENullMessageInArray));
175 message->Invoke(*this);
177 // GetFirstMessage waits on the request semaphore, so to balance these each
178 // time a message is processed we must then signal the completion semaphore
179 // when in synchronous mode
180 iArrayAccess.SignalCompletionSemaphore();
188 void CLogManager::WriteDateIntoLog(TBool firstTime)
190 * Write the date straight to the log output
191 * @param firstTime If ETrue then write a "log started" otherwise write a "date change" msg
194 if (!iLoggingEnabled)
198 //Put a date stamp for when we've started logging
199 //Can't use TTime::FormatL since it gives unicode and we want narrow.
201 TBuf8<KLogStartedStringLength> logDateString;
203 TDateTime dateTime(time.DateTime());
206 logDateString.Copy(KLogStartedString);
210 logDateString.Copy(KDateChangedString);
213 holdingBuf.NumFixedWidth(dateTime.Day()+1, EDecimal, 2);
214 logDateString.Replace(KLogStartedDayOffset,2,holdingBuf);
215 holdingBuf.NumFixedWidth(dateTime.Month()+1, EDecimal, 2);
216 logDateString.Replace(KLogStartedMonthOffset,2,holdingBuf);
217 TBuf8<4> holdingBuf2;
218 holdingBuf2.NumFixedWidth(dateTime.Year(), EDecimal, 4);
219 logDateString.Replace(KLogStartedYearOffset,4,holdingBuf2);
220 iLogger->LogString(logDateString);
223 void CLogManager::ClearLog(const TFullName& aName)
225 if (!iLoggingEnabled)
229 TRAP_IGNORE(iLogger->ClearLogL()); //if there is an error there is nothing we can do.
230 TBuf8<KMaxFullName+KClearLogStringLength+KEolCharactersLength> buf(KClearLogString);
232 buf.Append(KEolCharacters);
233 iLogger->LogString(buf);
234 WriteDateIntoLog(ETrue);
235 iTicksSinceLastLog=0;
238 void CLogManager::SetTimeL(const TTime& aTime)
240 if (!iLoggingEnabled)
244 //check whether date has rolled and write it to log if necessary
245 TTime currentMicrosecs;
246 TTimeIntervalDays newDate;
247 currentMicrosecs.HomeTime();
248 TTime zeroDate = TTime(TInt64(KZeroDate));
249 newDate = currentMicrosecs.DaysFrom(zeroDate);
250 if (newDate > iCurrentDate)
252 WriteDateIntoLog(EFalse);
253 iCurrentDate = newDate;
256 //Print the time to the log
257 //Have to do this stuff manually since TTime only provides Unicode formating
258 //which is not what we want.
259 // We format this each second regardless of whether it is used so that it is ready for use
260 // if a client logs since in normal use it would be rare for flogger not to log something each second.
261 TDateTime dateTime(aTime.DateTime());
263 holdingBuf.NumFixedWidth(dateTime.Hour(), EDecimal, 2);
264 iTimeString.Replace(KHourOffset,2,holdingBuf);
265 holdingBuf.NumFixedWidth(dateTime.Minute(), EDecimal, 2);
266 iTimeString.Replace(KMinuteOffset,2,holdingBuf);
267 holdingBuf.NumFixedWidth(dateTime.Second(), EDecimal, 2);
268 iTimeString.Replace(KSecondOffset,2,holdingBuf);
269 if (iTicksSinceLastLog++ < KSecondsToWriteTimestampOnNoActivity)
271 iLogger->LogString(iTimeString);
272 iLogger->FlushLogL();
277 void CLogManager::LogString(const TDesC8& aLogString, const TDesC8& aSubSystem, const TDesC8& aComponent, const TThreadId& aThreadId)
279 if (!iLoggingEnabled)
283 if (iTicksSinceLastLog > KSecondsToWriteTimestampOnNoActivity)
285 iLogger->LogString(iTimeString);
287 iTicksSinceLastLog=0;
289 TBuf8<KMaxFinalLogStringLength> buf;
290 buf.Append(aSubSystem);
291 buf.Append(KTabCharacter);
292 buf.Append(aComponent);
293 buf.Append(KTabCharacter);
294 buf.Append(KTypeIdentifierAscii);
295 buf.Append(KTabCharacter);
296 buf.AppendNum(aThreadId, EHex);
297 buf.Append(KTabCharacter);
298 buf.Append(aLogString);
299 // check whether last two bytes of string are eol chars, since some lines have cr/lf, some don't
300 TPtr8 ptr(&buf[buf.Length()-2], 2, 2);
301 if (ptr.Compare(KEolCharacters)!=0)
303 buf.Append(KEolCharacters);
305 iLogger->LogString(buf);
308 void CLogManager::LogBinaryDump(const TDesC8& aBinaryString, const TDesC8& aSubSystem, const TDesC8& aComponent)
310 iLogger->LogBinaryDump(aBinaryString, aSubSystem, aComponent);
313 void CLogManager::LogComment(const TDesC8& aComment)
315 if (iTicksSinceLastLog > KSecondsToWriteTimestampOnNoActivity)
317 iLogger->LogString(iTimeString);
319 iTicksSinceLastLog=0;
321 iLogger->LogString(aComment);
324 void CLogManager::MediaUpdate(const TDesC8& aMediaSetting, const TBool aForceFlush, const TDesC8& aLogPathSetting)
326 TRAPD(err, DoMediaUpdateL(aMediaSetting,aForceFlush, aLogPathSetting));
329 TBuf8<KMaxFinalLogStringLength> buf;
330 buf.Format(KUnableToUpdateMedia,err);
331 iLogger->LogString(buf);
335 void CLogManager::DoMediaUpdateL(const TDesC8& aMediaSetting,const TBool aForceFlush, const TDesC8& aLogPathSetting)
337 //We should NEVER have no media selected, media is set on construction
338 //and there should always be something set up.
339 __ASSERT_ALWAYS(iLogger, User::Panic(KFloggerServerPanic, ENoLoggingMediaSetUp));
341 if (aMediaSetting.Length() == 0)
346 // if the ini file has been opened, the media setting will be either the default
347 // or some other string so we can allow logging. If we are only opening media now, output extra info.
348 TTime currentMicrosecs;
349 currentMicrosecs.HomeTime();
350 iCurrentDate = currentMicrosecs.DaysFrom(TTime(TInt64(KZeroDate)));
352 if (!iLoggingEnabled)
354 iLoggingEnabled = ETrue;
355 WriteDateIntoLog(ETrue);
358 //Media update is a best effort, if it fails we keep
359 //logging to the old media
360 //If bad media in ini file, carry on with old media and post message in log
362 if (aMediaSetting.CompareF(iCurrentMediaSetting)==0 && aLogPathSetting.CompareF(iLogPath) == 0)
364 //Media hasn't changed, so update flush status only
365 // ForceFlushing as far as media is concerned only applies to file since
366 // serial has no such buffer which needs flushing.
367 iLogger->SetForceFlush(aForceFlush);
370 if (!aMediaSetting.CompareF(KFileMedia))
372 CLoggerMediaBase* media = CFileWriter::NewL();
375 // ForceFlushing only applies to file since serial has no such buffer
376 iLogger->SetForceFlush(aForceFlush);
377 if(aLogPathSetting.Length() != 0)
379 (static_cast<CFileWriter*>(iLogger))->SetLogPath(aLogPathSetting);
380 WriteDateIntoLog(ETrue);
383 else if (!aMediaSetting.CompareF(KSerial1Media))
385 // lots of things can go wrong when constructing the serial, so
386 // we set it up in stages, and log here if an error
387 // If we get an error in NewL - just let generic error given by
389 //CLoggerMediaBase* media = CSerialWriter::NewL();
390 CSerialWriter* serial = CSerialWriter::NewL();
392 TInt res = serial->LoadDevices();
395 TBuf8<KMaxFinalLogStringLength> buf;
396 buf.Format(KUnableToLoadSerialDevices,res);
397 iLogger->LogString(buf);
401 res = serial->OpenPort(KSerialPort1);
404 TBuf8<KMaxFinalLogStringLength> buf;
405 buf.Format(KUnableToOpenSerial,res);
406 iLogger->LogString(buf);
411 res = serial->SetPortConfig();
414 TBuf8<KMaxFinalLogStringLength> buf;
415 buf.Format(KUnableToSetSerialConfig,res);
416 iLogger->LogString(buf);
420 CLoggerMediaBase* media = serial;
423 WriteDateIntoLog(ETrue);
425 else if (!aMediaSetting.CompareF(KSerial2Media))
427 // lots of things can go wrong when constructing the serial, so
428 // we set it up in stages, and log here if an error.
429 // If we get an error in NewL - just let generic error given by
432 CSerialWriter* serial = CSerialWriter::NewL();
434 TInt res = serial->LoadDevices();
437 TBuf8<KMaxFinalLogStringLength> buf;
438 buf.Format(KUnableToLoadSerialDevices,res);
439 iLogger->LogString(buf);
444 #if defined (__WINS__)
445 res = serial->OpenPort(KSerialPort2OnEmulator);
447 res = serial->OpenPort(KSerialPort2OnTarget);
452 TBuf8<KMaxFinalLogStringLength> buf;
453 buf.Format(KUnableToOpenSerial,res);
454 iLogger->LogString(buf);
459 res = serial->SetPortConfig();
462 TBuf8<KMaxFinalLogStringLength> buf;
463 buf.Format(KUnableToSetSerialConfig,res);
464 iLogger->LogString(buf);
468 CLoggerMediaBase* media = serial;
471 WriteDateIntoLog(ETrue);
473 else if (!aMediaSetting.CompareF(KRDebugMedia))
475 CLoggerMediaBase* media = CRDebugWriter::NewL();;
478 WriteDateIntoLog(ETrue);
480 else if (!aMediaSetting.CompareF(KOSTv2Media))
482 CLoggerMediaBase* media = COstv2Writer::NewL();;
485 WriteDateIntoLog(ETrue);
487 else //Bad setting in the media file, leave media as is and return.
489 iLogger->LogString(KBadMediaString);
492 iCurrentMediaSetting = aMediaSetting;
493 iLogPath = aLogPathSetting;
496 void CLogManager::ShutDown()
501 //////////////////////////////////////////////////////////////////////////////
503 void CFileWriter::LogString(const TDesC8& aString)
505 TPtr8 ptr(iHBuf->Des());
506 if (ptr.Length()+aString.Length() <=KHeapBufSize)
512 TRAPD(err, DoFlushBufferToFileL());
521 ptr.Append(KUnableToLog);
525 if (iForceBufferFlushAlways)
527 TRAPD(err, DoFlushBufferToFileL());
531 ptr.Append(KUnableToLog);
537 void CFileWriter::LogBinaryDump(const TDesC8& aBinaryString, const TDesC8& aSubSystem, const TDesC8& aComponent)
539 TRAPD(err, DoLogBinaryDumpL(aBinaryString, aSubSystem, aComponent));
542 LogString(KUnableToLog);
546 void CFileWriter::DoLogBinaryDumpL(const TDesC8& aBinaryString, const TDesC8& aSubSystem, const TDesC8& aComponent)
548 * Place a chunk of raw binary into the log file
549 * @post Opens the output file, flushes the write buffer and then places some tags before writing
554 TInt err = logFile.Open(iFs, iLogFileName, EFileWrite|EFileShareAny);
555 if(err == KErrPathNotFound)
558 filePath.Copy(iLogPath);
559 User::LeaveIfError(iFs.MkDirAll(filePath));
561 if(err == KErrNotFound || err == KErrPathNotFound)
563 err = logFile.Create(iFs, iLogFileName, EFileWrite|EFileShareAny);
565 User::LeaveIfError(err);
567 CleanupClosePushL(logFile);
569 User::LeaveIfError(logFile.Seek(ESeekEnd,filePos));
570 User::LeaveIfError(logFile.Write(*iHBuf));
571 TPtr8 ptr(iHBuf->Des());
574 TUint32 length = static_cast<TUint32>(aBinaryString.Length());
575 TBuf8<sizeof(TUint32)> lengthString(4);
576 lengthString[0] = static_cast<TUint8>((length & 0x000000ff) >> 0);
577 lengthString[1] = static_cast<TUint8>((length & 0x0000ff00) >> 8);
578 lengthString[2] = static_cast<TUint8>((length & 0x00ff0000) >> 16);
579 lengthString[3] = static_cast<TUint8>((length & 0xff000000) >> 24);
581 User::LeaveIfError(logFile.Write(aSubSystem));
582 User::LeaveIfError(logFile.Write(KTabCharacter));
583 User::LeaveIfError(logFile.Write(aComponent));
584 User::LeaveIfError(logFile.Write(KTabCharacter));
585 User::LeaveIfError(logFile.Write(KTypeIdentifierBinary));
586 User::LeaveIfError(logFile.Write(KTabCharacter));
587 User::LeaveIfError(logFile.Write(lengthString));
588 User::LeaveIfError(logFile.Write(KTabCharacter));
589 User::LeaveIfError(logFile.Write(aBinaryString));
590 User::LeaveIfError(logFile.Write(KEolCharacters));
592 CleanupStack::PopAndDestroy(); //logFile
593 //LogString(KEolCharacters);
596 void CFileWriter::ClearLogL()
598 User::LeaveIfError(iFs.Delete(iLogFileName));
600 User::LeaveIfError(logFile.Create(iFs, iLogFileName, EFileWrite|EFileShareAny));
602 TPtr8 ptr(iHBuf->Des());
606 void CFileWriter::DoFlushBufferToFileL()
608 //Check that the log file exists, if not create a blank one.
610 TBool writePathErrorCode = KErrNone;
611 TInt err = logFile.Open(iFs, iLogFileName, EFileWrite|EFileShareAny);
612 if (err==KErrPathNotFound)
615 filePath.Copy(iLogPath);
616 User::LeaveIfError(iFs.MkDirAll(filePath));
618 else if (err == KErrBadName || err == KErrNotReady)
620 writePathErrorCode = err;
621 // duff pathspec in ini file
623 filePath.Copy(KLogDefaultFilePath);
624 err = iFs.MkDirAll(filePath);
625 iLogFileName.Copy(KLogDefaultFilePath);
626 iLogFileName.Append(KLogFileName);
627 if (err == KErrAlreadyExists)
629 err = logFile.Open(iFs, iLogFileName, EFileWrite|EFileShareAny);
633 if (err==KErrNotFound||err==KErrPathNotFound||err==KErrBadName||err == KErrNotReady)
635 err = logFile.Create(iFs, iLogFileName, EFileWrite|EFileShareAny);
637 User::LeaveIfError(err);
638 CleanupClosePushL(logFile);
640 User::LeaveIfError(logFile.Seek(ESeekEnd,filePos));
641 if (writePathErrorCode != KErrNone)
643 TBuf8<KMaxFinalLogStringLength> tmpBuf;
644 tmpBuf.Format(KUnableToUpdateMedia,writePathErrorCode);
645 User::LeaveIfError(logFile.Write(tmpBuf));
649 User::LeaveIfError(logFile.Write(*iHBuf));
651 CleanupStack::PopAndDestroy(); //logFile
654 void CFileWriter::FlushLogL()
656 DoFlushBufferToFileL();
659 TPtr8 ptr(iHBuf->Des());
664 void CFileWriter::SetForceFlush(TBool aOn)
666 iForceBufferFlushAlways = aOn;
669 void CFileWriter::SetLogPath(const TDesC8& aLogPathSetting)
671 iLogPath.Copy(aLogPathSetting);
673 //the path may be reconfigured, so check for '\'
674 //as its assumed to be at the end already
675 TPtr8 iTempStr = iLogPath.RightTPtr(1); //get last
676 TPtr8 iTempExt = iLogPath.RightTPtr(4); //get last 4
678 if( iTempStr == KLogPathTree)
680 //ends with '\', so ok to copy
681 iLogFileName.Copy(iLogPath);
682 iLogFileName.Append(KLogFileName);
684 else if(iTempExt.Find(KLogFileExt)==KErrNotFound)
686 //no file extension already set, so its just path
687 iLogPath.Append(KLogPathTree);
688 iLogFileName.Copy(iLogPath);
689 iLogFileName.Append(KLogFileName);
693 //already has all we need
694 iLogFileName.Copy(iLogPath);
698 CFileWriter* CFileWriter::NewL()
700 CFileWriter* self = new(ELeave) CFileWriter;
701 CleanupStack::PushL(self);
703 CleanupStack::Pop(self);
707 void CFileWriter::ConstructL()
709 User::LeaveIfError(iFs.Connect());
710 //Create our buffer for logging into, at zero length but specify a maximum.
711 iHBuf = HBufC8::NewL(KHeapBufSize);
712 iForceBufferFlushAlways = EFalse;
713 iLogPath.Copy(KLogDefaultFilePath);
714 iLogFileName.Copy(iLogPath);
715 iLogFileName.Append(KLogFileName);
718 CFileWriter::~CFileWriter()
720 // Don't attempt flushing when it's an OOM leave from NewL()
723 TRAP_IGNORE(CFileWriter::FlushLogL()); //Ignore error. Nothing we can do now.
729 ///////////////////////////////////////////////////////////////////////
731 CSerialWriter* CSerialWriter::NewL()
733 CSerialWriter* self = new(ELeave) CSerialWriter;
734 CleanupStack::PushL(self);
736 CleanupStack::Pop(self);
740 void CSerialWriter::ConstructL()
742 User::LeaveIfError(iTimeoutTimer.CreateLocal());
745 TInt CSerialWriter::LoadDevices()
747 // load the device drivers
748 TInt result = User::LoadPhysicalDevice(PDD_NAME);
749 if ((result != KErrNone) && (result != KErrAlreadyExists))
754 result = User::LoadLogicalDevice(LDD_NAME);
755 if ((result != KErrNone) && (result != KErrAlreadyExists))
764 TInt CSerialWriter::OpenPort(TInt aPort)
766 return iSerialPort.Open(aPort);
769 TInt CSerialWriter::SetPortConfig()
771 TCommConfig tComConfig;
772 TCommConfigV01 &tComConfigV = tComConfig();
773 iSerialPort.Config(tComConfig);
774 tComConfigV.iRate=KFloggerSerialRate;
775 tComConfigV.iDataBits=EData8;
776 tComConfigV.iStopBits=EStop1;
777 tComConfigV.iParity=EParityNone;
778 tComConfigV.iHandshake=0;
779 tComConfigV.iFifo = EFifoEnable;
780 return iSerialPort.SetConfig(tComConfig);
785 CSerialWriter::~CSerialWriter()
787 iTimeoutTimer.Close();
791 void CSerialWriter::ClearLogL()
793 * @note: Nothing to do for serial
797 void CSerialWriter::FlushLogL()
799 * @note: Nothing to do for serial
803 void CSerialWriter::SetForceFlush(TBool)
805 * @note: Nothing to do for serial.
811 void CSerialWriter::LogString(const TDesC8& aString)
813 //iInvalidcounter is used to dump packets if we fail to get a write through before the
814 //timer expires. It stops us getting backed up too much if there's a problem.
815 if (iInvalidCounter==0)
817 TRequestStatus writeStatus(KRequestPending);
818 TRequestStatus timeoutStatus(KRequestPending);
819 iSerialPort.Write(writeStatus, aString, aString.Length());
820 iTimeoutTimer.After(timeoutStatus,
821 TTimeIntervalMicroSeconds32(KSerialTimeoutInMicroSecs));
822 User::WaitForRequest(writeStatus, timeoutStatus);
823 if (writeStatus==KRequestPending)
824 {//OK, still not completed, better cancel send.
825 iSerialPort.WriteCancel();
826 iInvalidCounter=KSerialRetryCount;
830 iTimeoutTimer.Cancel();
832 User::WaitForAnyRequest();
838 void CSerialWriter::LogBinaryDump(const TDesC8& aBinaryString, const TDesC8& aSubSystem, const TDesC8& aComponent)
840 TUint32 length = static_cast<TUint32>(aBinaryString.Length());
841 TBuf8<sizeof(TUint32)> lengthString(4);
842 lengthString[0] = static_cast<TUint8>((length & 0x000000ff) >> 0);
843 lengthString[1] = static_cast<TUint8>((length & 0x0000ff00) >> 8);
844 lengthString[2] = static_cast<TUint8>((length & 0x00ff0000) >> 16);
845 lengthString[3] = static_cast<TUint8>((length & 0xff000000) >> 24);
847 LogString(aSubSystem);
848 LogString(KTabCharacter);
849 LogString(aComponent);
850 LogString(KTabCharacter);
851 LogString(KTypeIdentifierBinary);
852 LogString(KTabCharacter);
853 LogString(lengthString);
854 LogString(KTabCharacter);
855 LogString(aBinaryString);
856 LogString(KEolCharacters);
859 ///////////////////////////////////////////////////////////////////////////////////////////////////
861 //Don't strictly need a NewL. Doing it for consistency.
862 CRDebugWriter* CRDebugWriter::NewL()
864 return new(ELeave) CRDebugWriter;
867 CRDebugWriter::~CRDebugWriter()
871 void CRDebugWriter::ClearLogL()
873 * @note: Nothing to do for RDebug
877 void CRDebugWriter::FlushLogL()
879 * @note: Nothing to do for RDebug
883 void CRDebugWriter::SetForceFlush(TBool)
885 * @note: Nothing to do for RDebug.
891 void CRDebugWriter::LogString(const TDesC8& aString)
894 //RDebug truncates strings longer than a certain size
895 //To work around this we chop our string into palatable chunks
896 //and log those individually
898 const TUint8 *p = aString.Ptr();
900 TInt totalToSend = aString.Length();
905 bytesSent += KRDebugLimit;
906 if (bytesSent < totalToSend)
908 length = KRDebugLimit;
912 length = totalToSend - bytesSent + KRDebugLimit;
915 TPtrC8 ptr(p,length);
916 RDebug::RawPrint(ptr);
919 while(bytesSent < totalToSend);
923 void CRDebugWriter::LogBinaryDump(const TDesC8& aBinaryString, const TDesC8& aSubSystem, const TDesC8& aComponent)
925 TUint32 length = static_cast<TUint32>(aBinaryString.Length());
926 TBuf8<sizeof(TUint32)> lengthString(4);
927 lengthString[0] = static_cast<TUint8>((length & 0x000000ff) >> 0);
928 lengthString[1] = static_cast<TUint8>((length & 0x0000ff00) >> 8);
929 lengthString[2] = static_cast<TUint8>((length & 0x00ff0000) >> 16);
930 lengthString[3] = static_cast<TUint8>((length & 0xff000000) >> 24);
932 RDebug::RawPrint(aSubSystem);
933 RDebug::RawPrint(KTabCharacter);
934 RDebug::RawPrint(aComponent);
935 RDebug::RawPrint(KTabCharacter);
936 RDebug::RawPrint(KTypeIdentifierBinary);
937 RDebug::RawPrint(KTabCharacter);
938 RDebug::RawPrint(lengthString);
939 RDebug::RawPrint(KTabCharacter);
940 LogString(aBinaryString);
941 RDebug::RawPrint(KEolCharacters);
946 ///////////////////////////////////////////////////////////////////////
948 #if defined (__WINS__)
949 #include <emulator.h>
951 CDebugPortProtocol* CDebugPortProtocol::NewL()
953 CDebugPortProtocol* protocol = new(ELeave) CDebugPortProtocol;
954 CleanupStack::PushL(protocol);
955 protocol->ConstructL();
956 CleanupStack::Pop(protocol);
960 void CDebugPortProtocol::ConstructL()
962 iDebugWriter = CDebugPortWriter::NewL();
965 CDebugPortProtocol::~CDebugPortProtocol()
969 void CDebugPortProtocol::ClearLog(const TFullName& /*aName*/)
972 void CDebugPortProtocol::SetTimeL(const TTime& /*aTime*/)
975 void CDebugPortProtocol::LogString(const TDesC8& aLogString, const TDesC8& aSubSystem, const TDesC8& aComponent, const TThreadId& aThreadId)
977 TBuf8<KMaxFinalLogStringLength> buf;
978 buf.Append(aSubSystem);
979 buf.Append(KTabCharacter);
980 buf.Append(aComponent);
981 buf.Append(KTabCharacter);
982 buf.Append(KTypeIdentifierAscii);
983 buf.Append(KTabCharacter);
984 buf.AppendNum(aThreadId, EHex);
985 buf.Append(KTabCharacter);
986 buf.Append(aLogString);
987 // check whether last two bytes of string are eol chars, since some lines have cr/lf, some don't
988 TPtr8 ptr(&buf[buf.Length()-2], 2, 2);
989 if (ptr.Compare(KEolCharacters) !=0 )
991 buf.Append(KEolCharacters);
993 iDebugWriter->LogString(buf);
995 void CDebugPortProtocol::LogBinaryDump(const TDesC8& aBinaryString, const TDesC8& aSubSystem, const TDesC8& aComponent)
997 iDebugWriter->LogBinaryDump(aBinaryString, aSubSystem, aComponent);
999 void CDebugPortProtocol::LogComment(const TDesC8& aComment)
1001 iDebugWriter->LogString(aComment);
1003 void CDebugPortProtocol::MediaUpdate(const TDesC8& /*aMediaSetting*/, const TBool /*aForceFlushOn*/, const TDesC8& /*aLogPathSetting*/)
1006 void CDebugPortProtocol::ShutDown()
1010 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1012 CDebugPortWriter* CDebugPortWriter::NewL()
1014 return new(ELeave) CDebugPortWriter;
1018 void CDebugPortWriter::LogString(const TDesC8& aString)
1020 char str[Win32DisplayStringLengthMax];
1021 int len = Min(sizeof(str) - 1, aString.Length());
1022 Mem::Copy(str, aString.Ptr(), len);
1025 ::OutputDebugStringA(str);
1028 void CDebugPortWriter::ClearLogL()
1031 void CDebugPortWriter::FlushLogL()
1034 void CDebugPortWriter::LogBinaryDump(const TDesC8& /*aBinaryString*/, const TDesC8& /*aSubSystem*/, const TDesC8& /*aComponent*/)
1037 void CDebugPortWriter::SetForceFlush(const TBool /*aOn*/)