os/persistentdata/traceservices/commsdebugutility/SSVR/comsdbgwriter.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// Implements the Flogger server side data writing
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
/**
sl@0
    19
 @file
sl@0
    20
 @internalComponent
sl@0
    21
*/
sl@0
    22
sl@0
    23
#include "comsdbgwriter.h"
sl@0
    24
#include "comsdbgmessages.h"
sl@0
    25
sl@0
    26
sl@0
    27
const TInt KHeapBufSize = 50000;   // Maximum that the file buffer can grow to limit its impact somewhat
sl@0
    28
sl@0
    29
sl@0
    30
// RDebug will truncate strings longer than the limit below
sl@0
    31
const TInt KRDebugLimit = 0x100;
sl@0
    32
sl@0
    33
sl@0
    34
// source strings, lengths and offsets
sl@0
    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.
sl@0
    36
_LIT8(KDateChangedString,"#      Date is now: dd/mm/yyyy.\r\n");	///< Format specifier for subsequent date changes
sl@0
    37
const TInt KLogStartedStringLength = 50;
sl@0
    38
const TInt KLogStartedDayOffset = 20;
sl@0
    39
const TInt KLogStartedMonthOffset = 23;
sl@0
    40
const TInt KLogStartedYearOffset = 26;
sl@0
    41
sl@0
    42
_LIT8(KUnableToLog, "#Logs lost since log file couldn't be written to");
sl@0
    43
sl@0
    44
_LIT8(KClearLogString, "#Clear Log called by ");
sl@0
    45
const TInt KClearLogStringLength = 21;
sl@0
    46
sl@0
    47
_LIT8(KEolCharacters, "\r\n");
sl@0
    48
const TInt KEolCharactersLength = 2;
sl@0
    49
sl@0
    50
_LIT8(KLogPathTree,"\\");	
sl@0
    51
_LIT8(KLogFileExt,".");
sl@0
    52
sl@0
    53
//Below const is... log string + 2 tags + 8 for the thread id + 3 tabs + EOL characters.
sl@0
    54
const TInt KMaxFinalLogStringLength = KLogBufferSize+2*KMaxTagLength+8+3+KEolCharactersLength;
sl@0
    55
sl@0
    56
_LIT8(KBadMediaString, "#Bad media setting in ini file.\r\n");
sl@0
    57
_LIT8(KUnableToUpdateMedia, "#Unable to update logging media. Err code: %d\r\n");
sl@0
    58
_LIT8(KUnableToLoadSerialDevices, "#Unable to load the LDD or PDD required for serial. Err code: %d\r\n");
sl@0
    59
_LIT8(KUnableToOpenSerial, "#Unable to open the serial port. Err code: %d\r\n");
sl@0
    60
_LIT8(KUnableToSetSerialConfig, "#Could not set serial port configuration after opening port. Err code: %d\r\n");
sl@0
    61
sl@0
    62
// source characters
sl@0
    63
_LIT8(KTabCharacter, "\t");
sl@0
    64
_LIT8(KTypeIdentifierAscii, "a");
sl@0
    65
_LIT8(KTypeIdentifierBinary, "b");
sl@0
    66
sl@0
    67
// serial specs
sl@0
    68
const TBps KFloggerSerialRate = EBps115200;
sl@0
    69
const TInt KSerialRetryCount = 50;
sl@0
    70
const TInt KSerialTimeoutInMicroSecs = 100000;
sl@0
    71
sl@0
    72
// serial ports
sl@0
    73
const TInt KSerialPort1 = 0;
sl@0
    74
#if defined (__WINS__)
sl@0
    75
const TInt KSerialPort2OnEmulator = 1;
sl@0
    76
#else
sl@0
    77
const TInt KSerialPort2OnTarget = 2;
sl@0
    78
#endif
sl@0
    79
sl@0
    80
#if defined (__WINS__)
sl@0
    81
#define PDD_NAME _L("ECDRV.PDD")
sl@0
    82
#define LDD_NAME _L("ECOMM.LDD")
sl@0
    83
#else
sl@0
    84
#define PDD_NAME _L("EUART1")
sl@0
    85
#define LDD_NAME _L("ECOMM")
sl@0
    86
#endif
sl@0
    87
sl@0
    88
sl@0
    89
// log file specs
sl@0
    90
_LIT(KLogFileName, "log.txt");
sl@0
    91
_LIT(KLogDefaultFilePath, "C:\\logs\\");
sl@0
    92
sl@0
    93
sl@0
    94
const TUint KZeroDate = 0;  ///< The day to count forward from when determining date roll.
sl@0
    95
const TUint KSecondsToWriteTimestampOnNoActivity = 5;
sl@0
    96
sl@0
    97
#if defined (__WINS__)
sl@0
    98
const TInt Win32DisplayStringLengthMax = 1024; 
sl@0
    99
#endif
sl@0
   100
sl@0
   101
sl@0
   102
sl@0
   103
sl@0
   104
CLogManager* CLogManager::NewL(MLogArrayAccess& aArrayAccess)
sl@0
   105
	{
sl@0
   106
	CLogManager* self = new(ELeave) CLogManager(aArrayAccess);
sl@0
   107
	CleanupStack::PushL(self);
sl@0
   108
	self->ConstructL();
sl@0
   109
	CleanupStack::Pop(self);
sl@0
   110
	return self;
sl@0
   111
	}
sl@0
   112
sl@0
   113
sl@0
   114
CLogManager::CLogManager(MLogArrayAccess& aArrayAccess)
sl@0
   115
: iArrayAccess(aArrayAccess), iTimeString(KTimeFormat)
sl@0
   116
{}
sl@0
   117
sl@0
   118
CLogManager::~CLogManager()
sl@0
   119
	{
sl@0
   120
	delete iLogger;
sl@0
   121
	}
sl@0
   122
sl@0
   123
void CLogManager::ConstructL()
sl@0
   124
/*
sl@0
   125
 * Set the initial media to file and write there until the server has told us
sl@0
   126
 * which media is in the ini file.
sl@0
   127
 * Write the log started and date message. 
sl@0
   128
 */
sl@0
   129
	{
sl@0
   130
	iLogger = CFileWriter::NewL();	//File writer by default
sl@0
   131
	iCurrentMediaSetting = KFileMedia;
sl@0
   132
	iLoggingEnabled = EFalse;
sl@0
   133
	}
sl@0
   134
sl@0
   135
TInt CLogManager::ThreadEntryPoint(TAny* aPtr)
sl@0
   136
	{
sl@0
   137
	MLogArrayAccess* arrayAccess = static_cast<MLogArrayAccess*> (aPtr);
sl@0
   138
sl@0
   139
	CTrapCleanup* cleanupStack = CTrapCleanup::New();
sl@0
   140
	if (cleanupStack==NULL)
sl@0
   141
		{
sl@0
   142
		return KErrNoMemory;
sl@0
   143
		}
sl@0
   144
sl@0
   145
	TRAPD(err, CLogManager::DoRunThreadL(*arrayAccess));
sl@0
   146
sl@0
   147
	delete cleanupStack;
sl@0
   148
sl@0
   149
	return err;
sl@0
   150
	}
sl@0
   151
sl@0
   152
void CLogManager::DoRunThreadL(MLogArrayAccess& aArrayAccess)
sl@0
   153
	{
sl@0
   154
	CLogManager* self = CLogManager::NewL(aArrayAccess);
sl@0
   155
	self->DoStart();
sl@0
   156
	delete self;
sl@0
   157
	}
sl@0
   158
sl@0
   159
void CLogManager::DoStart()
sl@0
   160
/**
sl@0
   161
 * Second/consumer/slave/draining/dequeuer thread main loop.
sl@0
   162
 * @note Continuously takes the log queue top message and processes it. Blocks on the "Get" if no messages.
sl@0
   163
 * @note Completes when a shutdown message is processed from the queue. This message sets "iShutDown".
sl@0
   164
 */
sl@0
   165
	{
sl@0
   166
	CLogMessageBase * message = NULL;
sl@0
   167
sl@0
   168
	TInt ret = KErrNone;
sl@0
   169
	RThread::Rendezvous(ret);
sl@0
   170
sl@0
   171
	FOREVER
sl@0
   172
		{
sl@0
   173
		iArrayAccess.GetFirstMessageAndTakeOwnership(message);
sl@0
   174
		__ASSERT_ALWAYS(message, User::Panic(KFloggerServerPanic, ENullMessageInArray));
sl@0
   175
		message->Invoke(*this);
sl@0
   176
		delete message;
sl@0
   177
        // GetFirstMessage waits on the request semaphore, so to balance these each 
sl@0
   178
		// time a message is processed we must then signal the completion semaphore
sl@0
   179
		// when in synchronous mode
sl@0
   180
		iArrayAccess.SignalCompletionSemaphore();
sl@0
   181
		if (iShutDown)
sl@0
   182
			{
sl@0
   183
			break;
sl@0
   184
			}
sl@0
   185
		}
sl@0
   186
	}
sl@0
   187
sl@0
   188
void CLogManager::WriteDateIntoLog(TBool firstTime)
sl@0
   189
/**
sl@0
   190
 * Write the date straight to the log output
sl@0
   191
 * @param firstTime If ETrue then write a "log started" otherwise write a "date change" msg
sl@0
   192
 */
sl@0
   193
	{
sl@0
   194
	if (!iLoggingEnabled) 
sl@0
   195
	   {
sl@0
   196
	   return;
sl@0
   197
	   }
sl@0
   198
	//Put a date stamp for when we've started logging
sl@0
   199
	//Can't use TTime::FormatL since it gives unicode and we want narrow.
sl@0
   200
	TTime time;
sl@0
   201
	TBuf8<KLogStartedStringLength> logDateString;
sl@0
   202
	time.HomeTime();
sl@0
   203
	TDateTime dateTime(time.DateTime());
sl@0
   204
	if (firstTime)
sl@0
   205
		{
sl@0
   206
		logDateString.Copy(KLogStartedString);
sl@0
   207
		}
sl@0
   208
	else
sl@0
   209
		{
sl@0
   210
		logDateString.Copy(KDateChangedString);
sl@0
   211
		}
sl@0
   212
	TBuf8<2> holdingBuf;
sl@0
   213
	holdingBuf.NumFixedWidth(dateTime.Day()+1, EDecimal, 2);
sl@0
   214
	logDateString.Replace(KLogStartedDayOffset,2,holdingBuf);
sl@0
   215
	holdingBuf.NumFixedWidth(dateTime.Month()+1, EDecimal, 2);
sl@0
   216
	logDateString.Replace(KLogStartedMonthOffset,2,holdingBuf);
sl@0
   217
	TBuf8<4> holdingBuf2;
sl@0
   218
	holdingBuf2.NumFixedWidth(dateTime.Year(), EDecimal, 4);
sl@0
   219
	logDateString.Replace(KLogStartedYearOffset,4,holdingBuf2);
sl@0
   220
	iLogger->LogString(logDateString);
sl@0
   221
	}
sl@0
   222
sl@0
   223
void CLogManager::ClearLog(const TFullName& aName)
sl@0
   224
	{
sl@0
   225
	if (!iLoggingEnabled) 
sl@0
   226
	   {
sl@0
   227
	   return;
sl@0
   228
	   }
sl@0
   229
	TRAP_IGNORE(iLogger->ClearLogL());	//if there is an error there is nothing we can do.
sl@0
   230
	TBuf8<KMaxFullName+KClearLogStringLength+KEolCharactersLength> buf(KClearLogString);
sl@0
   231
	buf.Append(aName);
sl@0
   232
	buf.Append(KEolCharacters);
sl@0
   233
	iLogger->LogString(buf);
sl@0
   234
	WriteDateIntoLog(ETrue);
sl@0
   235
	iTicksSinceLastLog=0;
sl@0
   236
	}
sl@0
   237
sl@0
   238
void CLogManager::SetTimeL(const TTime& aTime)
sl@0
   239
	{
sl@0
   240
	if (!iLoggingEnabled) 
sl@0
   241
	   {
sl@0
   242
	   return;
sl@0
   243
	   }
sl@0
   244
	//check whether date has rolled and write it to log if necessary
sl@0
   245
	TTime currentMicrosecs;
sl@0
   246
	TTimeIntervalDays newDate;
sl@0
   247
	currentMicrosecs.HomeTime();
sl@0
   248
	TTime zeroDate = TTime(TInt64(KZeroDate));
sl@0
   249
	newDate = currentMicrosecs.DaysFrom(zeroDate);
sl@0
   250
	if (newDate > iCurrentDate)
sl@0
   251
		{
sl@0
   252
		WriteDateIntoLog(EFalse);
sl@0
   253
		iCurrentDate = newDate;
sl@0
   254
		}
sl@0
   255
	
sl@0
   256
	//Print the time to the log
sl@0
   257
	//Have to do this stuff manually since TTime only provides Unicode formating
sl@0
   258
	//which is not what we want.
sl@0
   259
	// We format this each second regardless of whether it is used so that it is ready for use
sl@0
   260
	// if a client logs since in normal use it would be rare for flogger not to log something each second.
sl@0
   261
	TDateTime dateTime(aTime.DateTime());
sl@0
   262
	TBuf8<2> holdingBuf;
sl@0
   263
	holdingBuf.NumFixedWidth(dateTime.Hour(), EDecimal, 2);
sl@0
   264
	iTimeString.Replace(KHourOffset,2,holdingBuf);
sl@0
   265
	holdingBuf.NumFixedWidth(dateTime.Minute(), EDecimal, 2);
sl@0
   266
	iTimeString.Replace(KMinuteOffset,2,holdingBuf);
sl@0
   267
	holdingBuf.NumFixedWidth(dateTime.Second(), EDecimal, 2);
sl@0
   268
	iTimeString.Replace(KSecondOffset,2,holdingBuf);
sl@0
   269
	if (iTicksSinceLastLog++ < KSecondsToWriteTimestampOnNoActivity)
sl@0
   270
		{
sl@0
   271
		iLogger->LogString(iTimeString);
sl@0
   272
		iLogger->FlushLogL();
sl@0
   273
		}
sl@0
   274
		
sl@0
   275
	}
sl@0
   276
sl@0
   277
void CLogManager::LogString(const TDesC8& aLogString, const TDesC8& aSubSystem, const TDesC8& aComponent, const TThreadId& aThreadId)
sl@0
   278
	{
sl@0
   279
	if (!iLoggingEnabled) 
sl@0
   280
	   {
sl@0
   281
	   return;
sl@0
   282
	   }
sl@0
   283
	if (iTicksSinceLastLog > KSecondsToWriteTimestampOnNoActivity)
sl@0
   284
		{
sl@0
   285
		iLogger->LogString(iTimeString);
sl@0
   286
		}
sl@0
   287
	iTicksSinceLastLog=0;
sl@0
   288
sl@0
   289
	TBuf8<KMaxFinalLogStringLength> buf;
sl@0
   290
	buf.Append(aSubSystem);
sl@0
   291
	buf.Append(KTabCharacter);
sl@0
   292
	buf.Append(aComponent);
sl@0
   293
	buf.Append(KTabCharacter);
sl@0
   294
	buf.Append(KTypeIdentifierAscii);
sl@0
   295
	buf.Append(KTabCharacter);
sl@0
   296
	buf.AppendNum(aThreadId, EHex);
sl@0
   297
	buf.Append(KTabCharacter);
sl@0
   298
	buf.Append(aLogString);
sl@0
   299
	// check whether last two bytes of string are eol chars, since some lines have cr/lf, some don't
sl@0
   300
	TPtr8 ptr(&buf[buf.Length()-2], 2, 2);
sl@0
   301
	if (ptr.Compare(KEolCharacters)!=0)
sl@0
   302
		{
sl@0
   303
		buf.Append(KEolCharacters);
sl@0
   304
		}
sl@0
   305
	iLogger->LogString(buf);
sl@0
   306
	}
sl@0
   307
sl@0
   308
void CLogManager::LogBinaryDump(const TDesC8& aBinaryString, const TDesC8& aSubSystem, const TDesC8& aComponent)
sl@0
   309
	{
sl@0
   310
	iLogger->LogBinaryDump(aBinaryString, aSubSystem, aComponent);
sl@0
   311
	}
sl@0
   312
sl@0
   313
void CLogManager::LogComment(const TDesC8& aComment)
sl@0
   314
	{
sl@0
   315
	if (iTicksSinceLastLog > KSecondsToWriteTimestampOnNoActivity)
sl@0
   316
		{
sl@0
   317
		iLogger->LogString(iTimeString);
sl@0
   318
		}
sl@0
   319
	iTicksSinceLastLog=0;
sl@0
   320
sl@0
   321
	iLogger->LogString(aComment);
sl@0
   322
	}
sl@0
   323
sl@0
   324
void CLogManager::MediaUpdate(const TDesC8& aMediaSetting, const TBool aForceFlush, const TDesC8& aLogPathSetting)
sl@0
   325
	{
sl@0
   326
	TRAPD(err, DoMediaUpdateL(aMediaSetting,aForceFlush, aLogPathSetting));
sl@0
   327
	if (err!=KErrNone)
sl@0
   328
		{
sl@0
   329
		TBuf8<KMaxFinalLogStringLength> buf;
sl@0
   330
		buf.Format(KUnableToUpdateMedia,err);
sl@0
   331
		iLogger->LogString(buf);
sl@0
   332
		}
sl@0
   333
	}
sl@0
   334
sl@0
   335
void CLogManager::DoMediaUpdateL(const TDesC8& aMediaSetting,const TBool aForceFlush, const TDesC8& aLogPathSetting)
sl@0
   336
	{
sl@0
   337
	//We should NEVER have no media selected, media is set on construction
sl@0
   338
	//and there should always be something set up.
sl@0
   339
	__ASSERT_ALWAYS(iLogger, User::Panic(KFloggerServerPanic, ENoLoggingMediaSetUp));
sl@0
   340
sl@0
   341
	if (aMediaSetting.Length() == 0)
sl@0
   342
		{
sl@0
   343
		return;
sl@0
   344
		}
sl@0
   345
		
sl@0
   346
	// if the ini file has been opened, the media setting will be either the default
sl@0
   347
	// or some other string so we can allow logging. If we are only opening media now, output extra info.
sl@0
   348
	TTime currentMicrosecs;
sl@0
   349
	currentMicrosecs.HomeTime();
sl@0
   350
	iCurrentDate = currentMicrosecs.DaysFrom(TTime(TInt64(KZeroDate)));
sl@0
   351
	
sl@0
   352
	if (!iLoggingEnabled)
sl@0
   353
		{
sl@0
   354
		iLoggingEnabled = ETrue;
sl@0
   355
		WriteDateIntoLog(ETrue);
sl@0
   356
		}
sl@0
   357
	
sl@0
   358
	//Media update is a best effort, if it fails we keep
sl@0
   359
	//logging to the old media
sl@0
   360
	//If bad media in ini file, carry on with old media and post message in log
sl@0
   361
sl@0
   362
	if (aMediaSetting.CompareF(iCurrentMediaSetting)==0 && aLogPathSetting.CompareF(iLogPath) == 0)
sl@0
   363
		{
sl@0
   364
		//Media hasn't changed, so update flush status only
sl@0
   365
		// ForceFlushing as far as media is concerned only applies to file since 
sl@0
   366
		// serial has no such buffer which needs flushing.
sl@0
   367
		iLogger->SetForceFlush(aForceFlush);
sl@0
   368
		return;
sl@0
   369
		}
sl@0
   370
	if (!aMediaSetting.CompareF(KFileMedia))
sl@0
   371
		{
sl@0
   372
		CLoggerMediaBase* media = CFileWriter::NewL();
sl@0
   373
		delete iLogger;
sl@0
   374
		iLogger = media;
sl@0
   375
		// ForceFlushing only applies to file since serial has no such buffer
sl@0
   376
		iLogger->SetForceFlush(aForceFlush);
sl@0
   377
		if(aLogPathSetting.Length() != 0)
sl@0
   378
			{
sl@0
   379
			(static_cast<CFileWriter*>(iLogger))->SetLogPath(aLogPathSetting);
sl@0
   380
			WriteDateIntoLog(ETrue);
sl@0
   381
			}
sl@0
   382
		}
sl@0
   383
	else if (!aMediaSetting.CompareF(KSerial1Media))
sl@0
   384
		{
sl@0
   385
		// lots of things can go wrong when constructing the serial, so
sl@0
   386
		// we set it up in stages, and log here if an error
sl@0
   387
		// If we get an error in NewL - just let generic error given by
sl@0
   388
		// SetMedia cover it
sl@0
   389
		//CLoggerMediaBase* media = CSerialWriter::NewL();
sl@0
   390
		CSerialWriter* serial = CSerialWriter::NewL();
sl@0
   391
sl@0
   392
		TInt res = serial->LoadDevices();
sl@0
   393
		if (res != KErrNone)
sl@0
   394
			{
sl@0
   395
			TBuf8<KMaxFinalLogStringLength> buf;
sl@0
   396
			buf.Format(KUnableToLoadSerialDevices,res);
sl@0
   397
			iLogger->LogString(buf);
sl@0
   398
			delete serial;
sl@0
   399
			User::Leave(res);
sl@0
   400
			}
sl@0
   401
		res = serial->OpenPort(KSerialPort1);
sl@0
   402
		if (res != KErrNone)
sl@0
   403
			{
sl@0
   404
			TBuf8<KMaxFinalLogStringLength> buf;
sl@0
   405
			buf.Format(KUnableToOpenSerial,res);
sl@0
   406
			iLogger->LogString(buf);
sl@0
   407
			delete serial;
sl@0
   408
			User::Leave(res);
sl@0
   409
			}
sl@0
   410
sl@0
   411
		res = serial->SetPortConfig();
sl@0
   412
		if (res != KErrNone)
sl@0
   413
			{
sl@0
   414
			TBuf8<KMaxFinalLogStringLength> buf;
sl@0
   415
			buf.Format(KUnableToSetSerialConfig,res);
sl@0
   416
			iLogger->LogString(buf);
sl@0
   417
			delete serial;
sl@0
   418
			User::Leave(res);
sl@0
   419
			}
sl@0
   420
		CLoggerMediaBase* media = serial;
sl@0
   421
		delete iLogger;
sl@0
   422
		iLogger = media;
sl@0
   423
		WriteDateIntoLog(ETrue);
sl@0
   424
		}
sl@0
   425
	else if (!aMediaSetting.CompareF(KSerial2Media))
sl@0
   426
		{
sl@0
   427
		// lots of things can go wrong when constructing the serial, so
sl@0
   428
		// we set it up in stages, and log here if an error.
sl@0
   429
		// If we get an error in NewL - just let generic error given by
sl@0
   430
		// SetMedia cover it
sl@0
   431
sl@0
   432
		CSerialWriter* serial = CSerialWriter::NewL();
sl@0
   433
sl@0
   434
		TInt res = serial->LoadDevices();
sl@0
   435
		if (res != KErrNone)
sl@0
   436
			{
sl@0
   437
			TBuf8<KMaxFinalLogStringLength> buf;
sl@0
   438
			buf.Format(KUnableToLoadSerialDevices,res);
sl@0
   439
			iLogger->LogString(buf);
sl@0
   440
			delete serial;
sl@0
   441
			User::Leave(res);
sl@0
   442
			}
sl@0
   443
sl@0
   444
		#if defined (__WINS__)
sl@0
   445
		res = serial->OpenPort(KSerialPort2OnEmulator);
sl@0
   446
		#else
sl@0
   447
		res = serial->OpenPort(KSerialPort2OnTarget);
sl@0
   448
		#endif
sl@0
   449
sl@0
   450
		if (res != KErrNone)
sl@0
   451
			{
sl@0
   452
			TBuf8<KMaxFinalLogStringLength> buf;
sl@0
   453
			buf.Format(KUnableToOpenSerial,res);
sl@0
   454
			iLogger->LogString(buf);
sl@0
   455
			delete serial;
sl@0
   456
			User::Leave(res);
sl@0
   457
			}
sl@0
   458
sl@0
   459
		res = serial->SetPortConfig();
sl@0
   460
		if (res != KErrNone)
sl@0
   461
			{
sl@0
   462
			TBuf8<KMaxFinalLogStringLength> buf;
sl@0
   463
			buf.Format(KUnableToSetSerialConfig,res);
sl@0
   464
			iLogger->LogString(buf);
sl@0
   465
			delete serial;
sl@0
   466
			User::Leave(res);
sl@0
   467
			}
sl@0
   468
		CLoggerMediaBase* media = serial;
sl@0
   469
		delete iLogger;
sl@0
   470
		iLogger = media;
sl@0
   471
		WriteDateIntoLog(ETrue);
sl@0
   472
		}
sl@0
   473
	else if (!aMediaSetting.CompareF(KRDebugMedia))
sl@0
   474
		{
sl@0
   475
		CLoggerMediaBase* media = CRDebugWriter::NewL();;
sl@0
   476
		delete iLogger;
sl@0
   477
		iLogger = media;
sl@0
   478
		WriteDateIntoLog(ETrue);
sl@0
   479
		}
sl@0
   480
	else if (!aMediaSetting.CompareF(KOSTv2Media))
sl@0
   481
		{
sl@0
   482
		CLoggerMediaBase* media = COstv2Writer::NewL();;
sl@0
   483
		delete iLogger;
sl@0
   484
		iLogger = media;
sl@0
   485
		WriteDateIntoLog(ETrue);
sl@0
   486
		}
sl@0
   487
	else	//Bad setting in the media file, leave media as is and return.
sl@0
   488
		{
sl@0
   489
		iLogger->LogString(KBadMediaString);
sl@0
   490
		return;	
sl@0
   491
		}
sl@0
   492
	iCurrentMediaSetting = aMediaSetting;
sl@0
   493
	iLogPath = aLogPathSetting;
sl@0
   494
	}
sl@0
   495
sl@0
   496
void CLogManager::ShutDown()
sl@0
   497
	{
sl@0
   498
	iShutDown = ETrue;
sl@0
   499
	}
sl@0
   500
sl@0
   501
//////////////////////////////////////////////////////////////////////////////
sl@0
   502
sl@0
   503
void CFileWriter::LogString(const TDesC8& aString)
sl@0
   504
	{
sl@0
   505
	TPtr8 ptr(iHBuf->Des());
sl@0
   506
	if (ptr.Length()+aString.Length() <=KHeapBufSize)
sl@0
   507
		{
sl@0
   508
		ptr.Append(aString);
sl@0
   509
		}
sl@0
   510
	else
sl@0
   511
		{
sl@0
   512
		TRAPD(err, DoFlushBufferToFileL());
sl@0
   513
		if (err==KErrNone)
sl@0
   514
			{
sl@0
   515
			ptr.Zero();
sl@0
   516
			ptr.Append(aString);
sl@0
   517
			}
sl@0
   518
		else
sl@0
   519
			{
sl@0
   520
			ptr.Zero();
sl@0
   521
			ptr.Append(KUnableToLog);
sl@0
   522
			ptr.Append(aString);
sl@0
   523
			}
sl@0
   524
		}
sl@0
   525
	if (iForceBufferFlushAlways)
sl@0
   526
		{
sl@0
   527
		TRAPD(err, DoFlushBufferToFileL());
sl@0
   528
		ptr.Zero();
sl@0
   529
		if (err!=KErrNone)
sl@0
   530
			{
sl@0
   531
			ptr.Append(KUnableToLog);
sl@0
   532
			}
sl@0
   533
		}
sl@0
   534
sl@0
   535
	}
sl@0
   536
sl@0
   537
void CFileWriter::LogBinaryDump(const TDesC8& aBinaryString, const TDesC8& aSubSystem, const TDesC8& aComponent)
sl@0
   538
	{
sl@0
   539
	TRAPD(err, DoLogBinaryDumpL(aBinaryString, aSubSystem, aComponent));
sl@0
   540
	if (err!=KErrNone)
sl@0
   541
		{
sl@0
   542
		LogString(KUnableToLog);
sl@0
   543
		}
sl@0
   544
	}
sl@0
   545
sl@0
   546
void CFileWriter::DoLogBinaryDumpL(const TDesC8& aBinaryString, const TDesC8& aSubSystem, const TDesC8& aComponent)
sl@0
   547
/**
sl@0
   548
 * Place a chunk of raw binary into the log file
sl@0
   549
 * @post Opens the output file, flushes the write buffer and then places some tags before writing
sl@0
   550
 *   the binary data.
sl@0
   551
 */
sl@0
   552
	{
sl@0
   553
	RFile logFile;
sl@0
   554
	TInt err = logFile.Open(iFs, iLogFileName, EFileWrite|EFileShareAny);
sl@0
   555
	if(err == KErrPathNotFound)
sl@0
   556
		{
sl@0
   557
		TName filePath;
sl@0
   558
		filePath.Copy(iLogPath);
sl@0
   559
		User::LeaveIfError(iFs.MkDirAll(filePath));
sl@0
   560
		}
sl@0
   561
	if(err == KErrNotFound || err == KErrPathNotFound)
sl@0
   562
		{
sl@0
   563
		err = logFile.Create(iFs, iLogFileName, EFileWrite|EFileShareAny);
sl@0
   564
		}
sl@0
   565
	User::LeaveIfError(err);
sl@0
   566
	
sl@0
   567
	CleanupClosePushL(logFile);
sl@0
   568
	TInt filePos = 0;
sl@0
   569
	User::LeaveIfError(logFile.Seek(ESeekEnd,filePos));
sl@0
   570
	User::LeaveIfError(logFile.Write(*iHBuf));
sl@0
   571
	TPtr8 ptr(iHBuf->Des());
sl@0
   572
	ptr.Zero();
sl@0
   573
sl@0
   574
	TUint32 length = static_cast<TUint32>(aBinaryString.Length());
sl@0
   575
	TBuf8<sizeof(TUint32)> lengthString(4);
sl@0
   576
	lengthString[0] = static_cast<TUint8>((length & 0x000000ff) >> 0);
sl@0
   577
	lengthString[1] = static_cast<TUint8>((length & 0x0000ff00) >> 8);
sl@0
   578
	lengthString[2] = static_cast<TUint8>((length & 0x00ff0000) >> 16);
sl@0
   579
	lengthString[3] = static_cast<TUint8>((length & 0xff000000) >> 24);
sl@0
   580
sl@0
   581
	User::LeaveIfError(logFile.Write(aSubSystem));
sl@0
   582
	User::LeaveIfError(logFile.Write(KTabCharacter));
sl@0
   583
	User::LeaveIfError(logFile.Write(aComponent));
sl@0
   584
	User::LeaveIfError(logFile.Write(KTabCharacter));
sl@0
   585
	User::LeaveIfError(logFile.Write(KTypeIdentifierBinary));
sl@0
   586
	User::LeaveIfError(logFile.Write(KTabCharacter));
sl@0
   587
	User::LeaveIfError(logFile.Write(lengthString));
sl@0
   588
	User::LeaveIfError(logFile.Write(KTabCharacter));
sl@0
   589
	User::LeaveIfError(logFile.Write(aBinaryString));
sl@0
   590
	User::LeaveIfError(logFile.Write(KEolCharacters));
sl@0
   591
	
sl@0
   592
	CleanupStack::PopAndDestroy();	//logFile
sl@0
   593
	//LogString(KEolCharacters);
sl@0
   594
	}
sl@0
   595
sl@0
   596
void CFileWriter::ClearLogL()
sl@0
   597
	{
sl@0
   598
	User::LeaveIfError(iFs.Delete(iLogFileName));
sl@0
   599
	RFile logFile;
sl@0
   600
	User::LeaveIfError(logFile.Create(iFs, iLogFileName, EFileWrite|EFileShareAny));
sl@0
   601
	logFile.Close();
sl@0
   602
	TPtr8 ptr(iHBuf->Des());
sl@0
   603
	ptr.Zero();
sl@0
   604
	}
sl@0
   605
sl@0
   606
void CFileWriter::DoFlushBufferToFileL()
sl@0
   607
	{
sl@0
   608
	//Check that the log file exists, if not create a blank one.
sl@0
   609
	RFile logFile;
sl@0
   610
	TBool writePathErrorCode = KErrNone;
sl@0
   611
	TInt err = logFile.Open(iFs, iLogFileName, EFileWrite|EFileShareAny);
sl@0
   612
	if (err==KErrPathNotFound)
sl@0
   613
		{
sl@0
   614
		TName filePath;
sl@0
   615
		filePath.Copy(iLogPath);
sl@0
   616
		User::LeaveIfError(iFs.MkDirAll(filePath));
sl@0
   617
		}
sl@0
   618
	else if (err == KErrBadName || err == KErrNotReady)
sl@0
   619
		{
sl@0
   620
		writePathErrorCode = err;			
sl@0
   621
		// duff pathspec in ini file
sl@0
   622
		TName filePath;
sl@0
   623
		filePath.Copy(KLogDefaultFilePath);
sl@0
   624
		err = iFs.MkDirAll(filePath);
sl@0
   625
		iLogFileName.Copy(KLogDefaultFilePath);
sl@0
   626
		iLogFileName.Append(KLogFileName);			
sl@0
   627
		if (err == KErrAlreadyExists)
sl@0
   628
			{
sl@0
   629
			err = logFile.Open(iFs, iLogFileName, EFileWrite|EFileShareAny);
sl@0
   630
			}
sl@0
   631
		}
sl@0
   632
		
sl@0
   633
	if (err==KErrNotFound||err==KErrPathNotFound||err==KErrBadName||err == KErrNotReady)
sl@0
   634
		{
sl@0
   635
		err = logFile.Create(iFs, iLogFileName, EFileWrite|EFileShareAny);
sl@0
   636
		}
sl@0
   637
	User::LeaveIfError(err);
sl@0
   638
	CleanupClosePushL(logFile);
sl@0
   639
	TInt filePos = 0;
sl@0
   640
	User::LeaveIfError(logFile.Seek(ESeekEnd,filePos));
sl@0
   641
	if (writePathErrorCode != KErrNone)
sl@0
   642
		{
sl@0
   643
		TBuf8<KMaxFinalLogStringLength> tmpBuf;
sl@0
   644
		tmpBuf.Format(KUnableToUpdateMedia,writePathErrorCode);
sl@0
   645
		User::LeaveIfError(logFile.Write(tmpBuf));
sl@0
   646
		}
sl@0
   647
	if (iHBuf)
sl@0
   648
		{
sl@0
   649
		User::LeaveIfError(logFile.Write(*iHBuf));
sl@0
   650
		}
sl@0
   651
	CleanupStack::PopAndDestroy();	//logFile
sl@0
   652
	}
sl@0
   653
sl@0
   654
void CFileWriter::FlushLogL()
sl@0
   655
	{
sl@0
   656
	DoFlushBufferToFileL();
sl@0
   657
	if (iHBuf)
sl@0
   658
		{
sl@0
   659
		TPtr8 ptr(iHBuf->Des());
sl@0
   660
		ptr.Zero();
sl@0
   661
		}
sl@0
   662
	}
sl@0
   663
sl@0
   664
void CFileWriter::SetForceFlush(TBool aOn)
sl@0
   665
	{
sl@0
   666
	iForceBufferFlushAlways = aOn;
sl@0
   667
	}
sl@0
   668
sl@0
   669
void CFileWriter::SetLogPath(const TDesC8& aLogPathSetting)
sl@0
   670
	{
sl@0
   671
	iLogPath.Copy(aLogPathSetting);
sl@0
   672
	
sl@0
   673
	//the path may be reconfigured, so check for '\' 
sl@0
   674
	//as its assumed to be at the end already
sl@0
   675
	TPtr8 iTempStr = iLogPath.RightTPtr(1);	//get last
sl@0
   676
	TPtr8 iTempExt = iLogPath.RightTPtr(4);	//get last 4
sl@0
   677
sl@0
   678
	if( iTempStr == KLogPathTree)
sl@0
   679
		{
sl@0
   680
			//ends with '\', so ok to copy
sl@0
   681
			iLogFileName.Copy(iLogPath);
sl@0
   682
			iLogFileName.Append(KLogFileName);
sl@0
   683
		}	
sl@0
   684
	else if(iTempExt.Find(KLogFileExt)==KErrNotFound)
sl@0
   685
		{
sl@0
   686
			//no file extension already set, so its just path
sl@0
   687
			iLogPath.Append(KLogPathTree);
sl@0
   688
			iLogFileName.Copy(iLogPath);
sl@0
   689
			iLogFileName.Append(KLogFileName);
sl@0
   690
		}
sl@0
   691
	else
sl@0
   692
		{
sl@0
   693
			//already has all we need
sl@0
   694
			iLogFileName.Copy(iLogPath);
sl@0
   695
		}
sl@0
   696
	}
sl@0
   697
sl@0
   698
CFileWriter* CFileWriter::NewL()
sl@0
   699
	{
sl@0
   700
	CFileWriter* self = new(ELeave) CFileWriter;
sl@0
   701
	CleanupStack::PushL(self);
sl@0
   702
	self->ConstructL();
sl@0
   703
	CleanupStack::Pop(self);
sl@0
   704
	return self;
sl@0
   705
	}
sl@0
   706
sl@0
   707
void CFileWriter::ConstructL()
sl@0
   708
	{
sl@0
   709
	User::LeaveIfError(iFs.Connect());
sl@0
   710
	//Create our buffer for logging into, at zero length but specify a maximum.
sl@0
   711
	iHBuf = HBufC8::NewL(KHeapBufSize);
sl@0
   712
	iForceBufferFlushAlways = EFalse;
sl@0
   713
	iLogPath.Copy(KLogDefaultFilePath);
sl@0
   714
	iLogFileName.Copy(iLogPath);
sl@0
   715
	iLogFileName.Append(KLogFileName);
sl@0
   716
	}
sl@0
   717
sl@0
   718
CFileWriter::~CFileWriter()
sl@0
   719
	{
sl@0
   720
	// Don't attempt flushing when it's an OOM leave from NewL()
sl@0
   721
	if (iHBuf)
sl@0
   722
		{
sl@0
   723
		TRAP_IGNORE(CFileWriter::FlushLogL());	//Ignore error. Nothing we can do now.
sl@0
   724
		delete iHBuf;
sl@0
   725
		}
sl@0
   726
	iFs.Close();
sl@0
   727
	}
sl@0
   728
sl@0
   729
///////////////////////////////////////////////////////////////////////
sl@0
   730
sl@0
   731
CSerialWriter* CSerialWriter::NewL()
sl@0
   732
	{
sl@0
   733
	CSerialWriter* self = new(ELeave) CSerialWriter;
sl@0
   734
	CleanupStack::PushL(self);
sl@0
   735
	self->ConstructL();
sl@0
   736
	CleanupStack::Pop(self);
sl@0
   737
	return self;
sl@0
   738
	}
sl@0
   739
sl@0
   740
void CSerialWriter::ConstructL()
sl@0
   741
	{
sl@0
   742
	User::LeaveIfError(iTimeoutTimer.CreateLocal());
sl@0
   743
	}
sl@0
   744
sl@0
   745
TInt CSerialWriter::LoadDevices()
sl@0
   746
	{
sl@0
   747
	// load the device drivers
sl@0
   748
	TInt result = User::LoadPhysicalDevice(PDD_NAME);
sl@0
   749
	if ((result != KErrNone) && (result != KErrAlreadyExists))
sl@0
   750
		{
sl@0
   751
		 return result;
sl@0
   752
		}
sl@0
   753
sl@0
   754
	result = User::LoadLogicalDevice(LDD_NAME);
sl@0
   755
	if ((result != KErrNone) && (result != KErrAlreadyExists))
sl@0
   756
		{
sl@0
   757
		return result;
sl@0
   758
		}
sl@0
   759
sl@0
   760
	return KErrNone;
sl@0
   761
	}
sl@0
   762
sl@0
   763
sl@0
   764
TInt CSerialWriter::OpenPort(TInt aPort)
sl@0
   765
	{
sl@0
   766
	return iSerialPort.Open(aPort);
sl@0
   767
	}
sl@0
   768
sl@0
   769
TInt CSerialWriter::SetPortConfig()
sl@0
   770
	{
sl@0
   771
	TCommConfig tComConfig;
sl@0
   772
	TCommConfigV01 &tComConfigV = tComConfig();
sl@0
   773
	iSerialPort.Config(tComConfig);
sl@0
   774
	tComConfigV.iRate=KFloggerSerialRate;
sl@0
   775
	tComConfigV.iDataBits=EData8;
sl@0
   776
	tComConfigV.iStopBits=EStop1;
sl@0
   777
	tComConfigV.iParity=EParityNone;
sl@0
   778
	tComConfigV.iHandshake=0;
sl@0
   779
	tComConfigV.iFifo = EFifoEnable;
sl@0
   780
	return iSerialPort.SetConfig(tComConfig);
sl@0
   781
	}
sl@0
   782
sl@0
   783
sl@0
   784
sl@0
   785
CSerialWriter::~CSerialWriter()
sl@0
   786
	{
sl@0
   787
	iTimeoutTimer.Close();
sl@0
   788
	iSerialPort.Close();
sl@0
   789
	}
sl@0
   790
sl@0
   791
void CSerialWriter::ClearLogL()
sl@0
   792
/**
sl@0
   793
 * @note: Nothing to do for serial
sl@0
   794
 */
sl@0
   795
	{}
sl@0
   796
sl@0
   797
void CSerialWriter::FlushLogL()
sl@0
   798
/**
sl@0
   799
 * @note: Nothing to do for serial
sl@0
   800
 */
sl@0
   801
	{}
sl@0
   802
sl@0
   803
void CSerialWriter::SetForceFlush(TBool)
sl@0
   804
/**
sl@0
   805
 * @note: Nothing to do for serial.
sl@0
   806
 */
sl@0
   807
	{
sl@0
   808
	}
sl@0
   809
sl@0
   810
sl@0
   811
void CSerialWriter::LogString(const TDesC8& aString)
sl@0
   812
	{
sl@0
   813
	//iInvalidcounter is used to dump packets if we fail to get a write through before the
sl@0
   814
	//timer expires. It stops us getting backed up too much if there's a problem.
sl@0
   815
	if (iInvalidCounter==0)
sl@0
   816
		{
sl@0
   817
		TRequestStatus writeStatus(KRequestPending);
sl@0
   818
		TRequestStatus timeoutStatus(KRequestPending);
sl@0
   819
		iSerialPort.Write(writeStatus, aString, aString.Length());
sl@0
   820
		iTimeoutTimer.After(timeoutStatus, 
sl@0
   821
			TTimeIntervalMicroSeconds32(KSerialTimeoutInMicroSecs));
sl@0
   822
		User::WaitForRequest(writeStatus, timeoutStatus);
sl@0
   823
		if (writeStatus==KRequestPending)
sl@0
   824
			{//OK, still not completed, better cancel send.
sl@0
   825
			iSerialPort.WriteCancel();
sl@0
   826
			iInvalidCounter=KSerialRetryCount;
sl@0
   827
			}
sl@0
   828
		else
sl@0
   829
			{
sl@0
   830
			iTimeoutTimer.Cancel();
sl@0
   831
			}
sl@0
   832
		User::WaitForAnyRequest();
sl@0
   833
		}
sl@0
   834
	else
sl@0
   835
		--iInvalidCounter;
sl@0
   836
	}
sl@0
   837
sl@0
   838
void CSerialWriter::LogBinaryDump(const TDesC8& aBinaryString, const TDesC8& aSubSystem, const TDesC8& aComponent)
sl@0
   839
	{
sl@0
   840
	TUint32 length = static_cast<TUint32>(aBinaryString.Length());
sl@0
   841
	TBuf8<sizeof(TUint32)> lengthString(4);
sl@0
   842
	lengthString[0] = static_cast<TUint8>((length & 0x000000ff) >> 0);
sl@0
   843
	lengthString[1] = static_cast<TUint8>((length & 0x0000ff00) >> 8);
sl@0
   844
	lengthString[2] = static_cast<TUint8>((length & 0x00ff0000) >> 16);
sl@0
   845
	lengthString[3] = static_cast<TUint8>((length & 0xff000000) >> 24);
sl@0
   846
sl@0
   847
	LogString(aSubSystem);
sl@0
   848
	LogString(KTabCharacter);
sl@0
   849
	LogString(aComponent);
sl@0
   850
	LogString(KTabCharacter);
sl@0
   851
	LogString(KTypeIdentifierBinary);
sl@0
   852
	LogString(KTabCharacter);
sl@0
   853
	LogString(lengthString);
sl@0
   854
	LogString(KTabCharacter);
sl@0
   855
	LogString(aBinaryString);
sl@0
   856
	LogString(KEolCharacters);
sl@0
   857
	}
sl@0
   858
sl@0
   859
///////////////////////////////////////////////////////////////////////////////////////////////////
sl@0
   860
sl@0
   861
//Don't strictly need a NewL. Doing it for consistency.
sl@0
   862
CRDebugWriter* CRDebugWriter::NewL()
sl@0
   863
	{
sl@0
   864
	return new(ELeave) CRDebugWriter;
sl@0
   865
	}
sl@0
   866
sl@0
   867
CRDebugWriter::~CRDebugWriter()
sl@0
   868
	{
sl@0
   869
	}
sl@0
   870
sl@0
   871
void CRDebugWriter::ClearLogL()
sl@0
   872
/**
sl@0
   873
 * @note: Nothing to do for RDebug
sl@0
   874
 */
sl@0
   875
	{}
sl@0
   876
sl@0
   877
void CRDebugWriter::FlushLogL()
sl@0
   878
/**
sl@0
   879
 * @note: Nothing to do for RDebug
sl@0
   880
 */
sl@0
   881
	{}
sl@0
   882
sl@0
   883
void CRDebugWriter::SetForceFlush(TBool)
sl@0
   884
/**
sl@0
   885
 * @note: Nothing to do for RDebug.
sl@0
   886
 */
sl@0
   887
	{
sl@0
   888
	}
sl@0
   889
sl@0
   890
sl@0
   891
void CRDebugWriter::LogString(const TDesC8& aString)
sl@0
   892
	{
sl@0
   893
	
sl@0
   894
	//RDebug truncates strings longer than a certain size
sl@0
   895
	//To work around this we chop our string into palatable chunks
sl@0
   896
	//and log those individually
sl@0
   897
	
sl@0
   898
	const TUint8 *p = aString.Ptr();
sl@0
   899
	TInt bytesSent(0);
sl@0
   900
	TInt totalToSend = aString.Length();
sl@0
   901
	TInt length(0);
sl@0
   902
	
sl@0
   903
	do
sl@0
   904
		{
sl@0
   905
		bytesSent += KRDebugLimit;
sl@0
   906
		if (bytesSent < totalToSend)
sl@0
   907
			{
sl@0
   908
			length = KRDebugLimit;
sl@0
   909
			}
sl@0
   910
		else
sl@0
   911
			{
sl@0
   912
			length = totalToSend - bytesSent + KRDebugLimit;
sl@0
   913
			}
sl@0
   914
		
sl@0
   915
		TPtrC8 ptr(p,length);
sl@0
   916
		RDebug::RawPrint(ptr);		
sl@0
   917
		p += KRDebugLimit;
sl@0
   918
		}
sl@0
   919
	while(bytesSent < totalToSend);
sl@0
   920
	}
sl@0
   921
sl@0
   922
sl@0
   923
void CRDebugWriter::LogBinaryDump(const TDesC8& aBinaryString, const TDesC8& aSubSystem, const TDesC8& aComponent)
sl@0
   924
	{
sl@0
   925
	TUint32 length = static_cast<TUint32>(aBinaryString.Length());
sl@0
   926
	TBuf8<sizeof(TUint32)> lengthString(4);
sl@0
   927
	lengthString[0] = static_cast<TUint8>((length & 0x000000ff) >> 0);
sl@0
   928
	lengthString[1] = static_cast<TUint8>((length & 0x0000ff00) >> 8);
sl@0
   929
	lengthString[2] = static_cast<TUint8>((length & 0x00ff0000) >> 16);
sl@0
   930
	lengthString[3] = static_cast<TUint8>((length & 0xff000000) >> 24);
sl@0
   931
sl@0
   932
	RDebug::RawPrint(aSubSystem);
sl@0
   933
	RDebug::RawPrint(KTabCharacter);
sl@0
   934
	RDebug::RawPrint(aComponent);
sl@0
   935
	RDebug::RawPrint(KTabCharacter);
sl@0
   936
	RDebug::RawPrint(KTypeIdentifierBinary);
sl@0
   937
	RDebug::RawPrint(KTabCharacter);
sl@0
   938
	RDebug::RawPrint(lengthString);
sl@0
   939
	RDebug::RawPrint(KTabCharacter);
sl@0
   940
	LogString(aBinaryString);	
sl@0
   941
	RDebug::RawPrint(KEolCharacters);
sl@0
   942
sl@0
   943
	}
sl@0
   944
sl@0
   945
sl@0
   946
///////////////////////////////////////////////////////////////////////
sl@0
   947
sl@0
   948
#if defined (__WINS__)
sl@0
   949
#include <emulator.h>
sl@0
   950
sl@0
   951
CDebugPortProtocol* CDebugPortProtocol::NewL()
sl@0
   952
	{
sl@0
   953
	CDebugPortProtocol* protocol = new(ELeave) CDebugPortProtocol;
sl@0
   954
	CleanupStack::PushL(protocol);
sl@0
   955
	protocol->ConstructL();
sl@0
   956
	CleanupStack::Pop(protocol);
sl@0
   957
	return protocol;
sl@0
   958
	}
sl@0
   959
	
sl@0
   960
void CDebugPortProtocol::ConstructL()
sl@0
   961
	{
sl@0
   962
	iDebugWriter = CDebugPortWriter::NewL();
sl@0
   963
	}
sl@0
   964
	
sl@0
   965
CDebugPortProtocol::~CDebugPortProtocol()
sl@0
   966
	{
sl@0
   967
	delete iDebugWriter;
sl@0
   968
	}
sl@0
   969
void CDebugPortProtocol::ClearLog(const TFullName& /*aName*/)
sl@0
   970
	{
sl@0
   971
	}
sl@0
   972
void CDebugPortProtocol::SetTimeL(const TTime& /*aTime*/)
sl@0
   973
	{
sl@0
   974
	}
sl@0
   975
void CDebugPortProtocol::LogString(const TDesC8& aLogString, const TDesC8& aSubSystem, const TDesC8& aComponent, const TThreadId& aThreadId)
sl@0
   976
	{
sl@0
   977
	TBuf8<KMaxFinalLogStringLength> buf;
sl@0
   978
	buf.Append(aSubSystem);
sl@0
   979
	buf.Append(KTabCharacter);
sl@0
   980
	buf.Append(aComponent);
sl@0
   981
	buf.Append(KTabCharacter);
sl@0
   982
	buf.Append(KTypeIdentifierAscii);
sl@0
   983
	buf.Append(KTabCharacter);
sl@0
   984
	buf.AppendNum(aThreadId, EHex);
sl@0
   985
	buf.Append(KTabCharacter);
sl@0
   986
	buf.Append(aLogString);
sl@0
   987
	// check whether last two bytes of string are eol chars, since some lines have cr/lf, some don't
sl@0
   988
	TPtr8 ptr(&buf[buf.Length()-2], 2, 2);
sl@0
   989
	if (ptr.Compare(KEolCharacters) !=0 )
sl@0
   990
		{
sl@0
   991
		buf.Append(KEolCharacters);
sl@0
   992
		}
sl@0
   993
	iDebugWriter->LogString(buf);
sl@0
   994
	}
sl@0
   995
void CDebugPortProtocol::LogBinaryDump(const TDesC8& aBinaryString, const TDesC8& aSubSystem, const TDesC8& aComponent)
sl@0
   996
	{
sl@0
   997
	iDebugWriter->LogBinaryDump(aBinaryString, aSubSystem, aComponent);
sl@0
   998
	}
sl@0
   999
void CDebugPortProtocol::LogComment(const TDesC8& aComment)
sl@0
  1000
	{
sl@0
  1001
	iDebugWriter->LogString(aComment);
sl@0
  1002
	}
sl@0
  1003
void CDebugPortProtocol::MediaUpdate(const TDesC8& /*aMediaSetting*/, const TBool /*aForceFlushOn*/, const TDesC8& /*aLogPathSetting*/)
sl@0
  1004
	{
sl@0
  1005
	}
sl@0
  1006
void CDebugPortProtocol::ShutDown()
sl@0
  1007
	{
sl@0
  1008
	}
sl@0
  1009
sl@0
  1010
///////////////////////////////////////////////////////////////////////////////////////////////////////
sl@0
  1011
sl@0
  1012
CDebugPortWriter* CDebugPortWriter::NewL()
sl@0
  1013
	{
sl@0
  1014
	return new(ELeave) CDebugPortWriter;
sl@0
  1015
	}
sl@0
  1016
	
sl@0
  1017
sl@0
  1018
void CDebugPortWriter::LogString(const TDesC8& aString)
sl@0
  1019
	{
sl@0
  1020
	char str[Win32DisplayStringLengthMax];
sl@0
  1021
	int len = Min(sizeof(str) - 1, aString.Length());
sl@0
  1022
	Mem::Copy(str, aString.Ptr(), len);
sl@0
  1023
	str[len] = '\0';
sl@0
  1024
	Emulator::Lock();
sl@0
  1025
	::OutputDebugStringA(str);
sl@0
  1026
	Emulator::Unlock();
sl@0
  1027
	}
sl@0
  1028
void CDebugPortWriter::ClearLogL()
sl@0
  1029
	{
sl@0
  1030
	}
sl@0
  1031
void CDebugPortWriter::FlushLogL()
sl@0
  1032
	{
sl@0
  1033
	}
sl@0
  1034
void CDebugPortWriter::LogBinaryDump(const TDesC8& /*aBinaryString*/, const TDesC8& /*aSubSystem*/, const TDesC8& /*aComponent*/)
sl@0
  1035
	{
sl@0
  1036
	}
sl@0
  1037
void CDebugPortWriter::SetForceFlush(const TBool /*aOn*/)
sl@0
  1038
	{
sl@0
  1039
	}
sl@0
  1040
sl@0
  1041
#endif  //(__WINS__)