os/kernelhwsrv/kerneltest/e32test/ethernet/pump/etherpump.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1996-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 the License "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
// e32test\ethernet\etherpump.cpp
sl@0
    15
// Abbreviations - PSP (Professional Symbian Programming)
sl@0
    16
// 
sl@0
    17
//
sl@0
    18
sl@0
    19
#define __USE_LDDPDD__
sl@0
    20
#define __USE_TIMER__
sl@0
    21
sl@0
    22
#include <e32base.h>
sl@0
    23
#include <e32base_private.h>
sl@0
    24
#include <e32cons.h>
sl@0
    25
#include <e32svr.h>
sl@0
    26
sl@0
    27
#include <d32ethernet.h>
sl@0
    28
sl@0
    29
#include "activeio.h"
sl@0
    30
sl@0
    31
#define LDD_NAME _L("Enet")
sl@0
    32
#if (!defined __WINS__)
sl@0
    33
#define PDD_NAME _L("Ethernet")
sl@0
    34
#else
sl@0
    35
sl@0
    36
//#define PDD_NAME _L("EthernetWins")
sl@0
    37
#define PDD_NAME _L("Ethernet")
sl@0
    38
#endif
sl@0
    39
sl@0
    40
sl@0
    41
// changed from const to static
sl@0
    42
//const TUint8 DestMacAddr[] = {0x00,0x50,0xDA,0xE9,0x69,0xCA};
sl@0
    43
sl@0
    44
// MAC address with second bit 1
sl@0
    45
static TUint8 DestMacAddr[] = {0x02,0xB0,0xD0,0x64,0x98,0x02};
sl@0
    46
sl@0
    47
sl@0
    48
// for random functions
sl@0
    49
#include <e32math.h>
sl@0
    50
sl@0
    51
sl@0
    52
void StripeMem(TUint8 *aBuf, TInt aStartPos, TInt anEndPos, TUint aStartChar, TUint anEndChar, TInt aOffset)
sl@0
    53
//
sl@0
    54
// Mark a buffer with repeating byte pattern
sl@0
    55
//
sl@0
    56
    {
sl@0
    57
    TUint character=aStartChar+(aOffset%((anEndChar+1)-aStartChar));
sl@0
    58
sl@0
    59
    for (TInt i=aStartPos;i<anEndPos;i++)
sl@0
    60
	{
sl@0
    61
	aBuf[i]=(TText8)character;
sl@0
    62
	if(++character>anEndChar)
sl@0
    63
	    character=aStartChar;
sl@0
    64
	}
sl@0
    65
    }
sl@0
    66
sl@0
    67
void StripeDes(TDes8 &aBuf, TInt aStartPos, TInt anEndPos, TUint aStartChar, TUint anEndChar, TInt aOffset)
sl@0
    68
    {
sl@0
    69
    StripeMem((TUint8 *)aBuf.Ptr(), aStartPos, anEndPos, aStartChar, anEndChar, aOffset);
sl@0
    70
    }
sl@0
    71
sl@0
    72
TBool CheckMem(TUint8 *aBuf, TInt aStartPos, TInt anEndPos, TUint aStartChar, TUint anEndChar, TInt aOffset)
sl@0
    73
//
sl@0
    74
// Mark a buffer with repeating byte pattern
sl@0
    75
//
sl@0
    76
    {
sl@0
    77
    TUint character=aStartChar+(aOffset%((anEndChar+1)-aStartChar));
sl@0
    78
sl@0
    79
    for (TInt i=aStartPos;i<anEndPos;i++)
sl@0
    80
	{
sl@0
    81
	if (aBuf[i]!=(TText8)character)
sl@0
    82
	    return EFalse;
sl@0
    83
	if(++character>anEndChar)
sl@0
    84
	    character=aStartChar;
sl@0
    85
	}
sl@0
    86
    return ETrue;
sl@0
    87
    }
sl@0
    88
sl@0
    89
TBool CheckDes(TDes8 &aBuf, TInt aStartPos, TInt anEndPos, TUint aStartChar, TUint anEndChar, TInt aOffset)
sl@0
    90
    {
sl@0
    91
    return CheckMem((TUint8 *)aBuf.Ptr(), aStartPos, anEndPos, aStartChar, anEndChar, aOffset);
sl@0
    92
    }
sl@0
    93
sl@0
    94
sl@0
    95
void StripeMem32(TUint *aBuf, TInt aStartPos, TInt aEndPos)
sl@0
    96
//
sl@0
    97
// Mark a buffer with repeating byte pattern
sl@0
    98
//
sl@0
    99
    {
sl@0
   100
    aStartPos >>= 2;
sl@0
   101
    aEndPos >>= 2;
sl@0
   102
	
sl@0
   103
    for (TInt i=aStartPos;i<aEndPos;i++)
sl@0
   104
	{
sl@0
   105
	aBuf[i]=i<<2;
sl@0
   106
	}
sl@0
   107
    }
sl@0
   108
sl@0
   109
void StripeDes32(TDes8 &aBuf, TInt aStartPos, TInt anEndPos)
sl@0
   110
    {
sl@0
   111
    StripeMem32((TUint*)aBuf.Ptr(), aStartPos, anEndPos);
sl@0
   112
    }
sl@0
   113
sl@0
   114
// Standard Epoc32 Library Console class
sl@0
   115
static CConsoleBase* console;
sl@0
   116
sl@0
   117
sl@0
   118
// xxxLC means method can Leave and has pushed something on the Cleanup stack
sl@0
   119
// Caller is responsible for popping it.
sl@0
   120
CDemoControl* CDemoControl::NewLC()
sl@0
   121
    {
sl@0
   122
    CDemoControl* self = new (ELeave) CDemoControl(EPriorityNormal);
sl@0
   123
    CleanupStack::PushL(self);
sl@0
   124
    self->ConstructL();
sl@0
   125
    return self;
sl@0
   126
    }
sl@0
   127
TInt CDemoControl::Callback(TAny* aControl)
sl@0
   128
// Callback function for timer expiry
sl@0
   129
// Just pump another packet at the server
sl@0
   130
// It's a static so call a class member to access private data
sl@0
   131
    {
sl@0
   132
    CIOBuffer* buf = ((CDemoControl*)aControl)->CreateSendPacketL();
sl@0
   133
sl@0
   134
    ((CDemoControl*)aControl)->iWriteQueue.AddLast(*buf);
sl@0
   135
    ((CDemoControl*)aControl)->iWriter->WriteL(buf->Ptr());
sl@0
   136
sl@0
   137
    return KErrNone;
sl@0
   138
    }
sl@0
   139
sl@0
   140
sl@0
   141
void CDemoControl::ConstructL()
sl@0
   142
// Second Phase construction
sl@0
   143
    {
sl@0
   144
    // Add us to the Active Scheduler for the thread
sl@0
   145
    CActiveScheduler::Add(this);
sl@0
   146
    // Create the Read and Write Active Objects
sl@0
   147
    // The 'this' pointer is the MxxxNotify callback interface that CDemoControl is derived from
sl@0
   148
    // Pass a reference to the Server session so they can make read and write requests
sl@0
   149
sl@0
   150
    iWriter = CDemoWriter::NewL(*this,iCard);
sl@0
   151
    iReader = CDemoReader::NewL(*this,iCard);
sl@0
   152
sl@0
   153
    User::LoadPhysicalDevice(PDD_NAME);
sl@0
   154
    User::LoadLogicalDevice(LDD_NAME);
sl@0
   155
sl@0
   156
#if (defined __USE_TIMER__)
sl@0
   157
    iIfState = EIdle;
sl@0
   158
    iTimer = CPeriodic::NewL(EPriorityNormal);
sl@0
   159
#endif
sl@0
   160
sl@0
   161
    iWriteQueue.SetOffset(CIOBuffer::LinkOffset());
sl@0
   162
sl@0
   163
    HelpText();
sl@0
   164
sl@0
   165
    }
sl@0
   166
sl@0
   167
void CDemoControl::EmptyWriteQueue()
sl@0
   168
    {
sl@0
   169
    TSglQueIter<CIOBuffer> iter(iWriteQueue);
sl@0
   170
    CIOBuffer* buf;
sl@0
   171
    while (buf = iter++, buf!=NULL)
sl@0
   172
	{
sl@0
   173
	iWriteQueue.Remove(*buf);
sl@0
   174
	delete buf;
sl@0
   175
	}
sl@0
   176
    }
sl@0
   177
sl@0
   178
CDemoControl::~CDemoControl()
sl@0
   179
    {
sl@0
   180
    // Cancel this classes read request to the Console
sl@0
   181
    Cancel();
sl@0
   182
    if(iIfState != EIdle)
sl@0
   183
	{
sl@0
   184
	EmptyWriteQueue();
sl@0
   185
	StopCard();
sl@0
   186
	}
sl@0
   187
sl@0
   188
    User::FreeLogicalDevice(LDD_NAME);
sl@0
   189
    User::FreePhysicalDevice(PDD_NAME);
sl@0
   190
sl@0
   191
sl@0
   192
#if (defined __USE_TIMER__)
sl@0
   193
    iTimer->Cancel();
sl@0
   194
    delete iTimer;
sl@0
   195
#endif
sl@0
   196
sl@0
   197
    delete iWriter;
sl@0
   198
    delete iReader;
sl@0
   199
    }
sl@0
   200
sl@0
   201
void CDemoControl::RequestCharacter()
sl@0
   202
// Request a character from the CConsoleBase class and set us to Active
sl@0
   203
    {
sl@0
   204
    // Read() will result in our iStatus being set to KRequestPending 0x80000001
sl@0
   205
    console->Read(iStatus);
sl@0
   206
    // SetActive sets our iActive to ETrue
sl@0
   207
    SetActive();
sl@0
   208
    }
sl@0
   209
sl@0
   210
void CDemoControl::RunL()
sl@0
   211
// Mandatory override of pure virtual called from active scheduler Start()
sl@0
   212
// Key method called when the Active Scheduler semaphore is
sl@0
   213
// signalled and the iStatus has been completed for this Active Object
sl@0
   214
    {
sl@0
   215
    ProcessKeyPress(TChar(console->KeyCode()));
sl@0
   216
    RequestCharacter();
sl@0
   217
    // We now return control to the scheduler loop
sl@0
   218
    }
sl@0
   219
sl@0
   220
void CDemoControl::DoCancel()
sl@0
   221
// Mandatory override of pure virtual, called from Cancel()
sl@0
   222
    {
sl@0
   223
    // Cancels an outstanding request to the console
sl@0
   224
    console->ReadCancel();
sl@0
   225
    }
sl@0
   226
sl@0
   227
static const TUint KEscChar = 0x1b;
sl@0
   228
void CDemoControl::ProcessKeyPress(TChar aChar)
sl@0
   229
// Process commands from the console
sl@0
   230
// Executes in the context of the class RunL()
sl@0
   231
    {
sl@0
   232
    TInt err = KErrNone;
sl@0
   233
    if(aChar == KEscChar)
sl@0
   234
	{
sl@0
   235
	// Modifies loop control flag value so the scheduler loop exits
sl@0
   236
	CActiveScheduler::Stop();
sl@0
   237
	}
sl@0
   238
    else if(aChar == 'h' || aChar == 'H')
sl@0
   239
	{
sl@0
   240
	HelpText();
sl@0
   241
	}
sl@0
   242
    else
sl@0
   243
	{
sl@0
   244
	// Add Command Handler Methods here
sl@0
   245
	switch(aChar)
sl@0
   246
	    {
sl@0
   247
	    case 'p'	:
sl@0
   248
	    case 'P'	:
sl@0
   249
		TRAP(err,PumpL());
sl@0
   250
		break;
sl@0
   251
	    case 'e'	:
sl@0
   252
	    case 'E'	:
sl@0
   253
		TRAP(err,EchoL());
sl@0
   254
		break;
sl@0
   255
	    case 'r'	:
sl@0
   256
	    case 'R'	:
sl@0
   257
		TRAP(err,ReadL());
sl@0
   258
		break;
sl@0
   259
	    case 's'	:
sl@0
   260
	    case 'S'	:
sl@0
   261
		TRAP(err,StopL());
sl@0
   262
		break;
sl@0
   263
		case 'c'	:
sl@0
   264
		case 'C'	:
sl@0
   265
		TRAP(err,SendAndCompareEchoL());
sl@0
   266
		break;
sl@0
   267
		case 'd'	:
sl@0
   268
		case 'D'	:
sl@0
   269
		TRAP(err,ReadAndSetDestMacL());
sl@0
   270
		break;
sl@0
   271
		case 'm'	:
sl@0
   272
		case 'M'	:
sl@0
   273
			ReadAndDisplaySettings();
sl@0
   274
		break;				
sl@0
   275
	    default		:
sl@0
   276
		break;
sl@0
   277
	    }
sl@0
   278
sl@0
   279
	if(err != KErrNone)
sl@0
   280
	    {
sl@0
   281
	    PrintError(aChar);
sl@0
   282
	    }
sl@0
   283
	else
sl@0
   284
	    {
sl@0
   285
	    _LIT(KMess,"State = %d\r\n");
sl@0
   286
	    console->ClearScreen();
sl@0
   287
	    console->SetPos(0,0);
sl@0
   288
	    console->Printf(KMess,iIfState);
sl@0
   289
	    }
sl@0
   290
	}
sl@0
   291
    }
sl@0
   292
sl@0
   293
void CDemoControl::HelpText() const
sl@0
   294
    {
sl@0
   295
	_LIT(KMess,"Press 'Esc' to exit \r\nPress 'H' for Help \r\nPress 'P' for Data Pump \r\nPress 'E' for Echo \r\nPress 'R' for Read \r\nPress 'C' for send and Compare echo \r\nPress 'D' to set dest MAC\r\nPress 'M' to display Settings\r\nPress 'S' to Stop");
sl@0
   296
	console->ClearScreen();
sl@0
   297
    console->SetPos(0,5);
sl@0
   298
    console->Printf(KMess);
sl@0
   299
    }
sl@0
   300
sl@0
   301
void CDemoControl::PrintError(TChar aChar)
sl@0
   302
    {
sl@0
   303
    //_LIT(KMess,"Command Error = %c State = %d\r\n1 = Idle\r\n2 = Echo\r\n3 = Read\r\n4 = Pump");
sl@0
   304
	_LIT(KMess,"Command Error = %c State = %d\r\n0 = Idle\r\n1 = Echo\r\n2 = Read\r\n3 = Pump\r\n4 = send & Compare echo");
sl@0
   305
	console->ClearScreen();
sl@0
   306
    console->SetPos(0,5);
sl@0
   307
    console->Printf(KMess,(char)aChar,iIfState);	
sl@0
   308
    }
sl@0
   309
sl@0
   310
void CDemoControl::EchoL()
sl@0
   311
    {
sl@0
   312
    if(iIfState != EIdle)
sl@0
   313
	{
sl@0
   314
	User::Leave(KErrInUse);
sl@0
   315
	}
sl@0
   316
    StartCardL();
sl@0
   317
sl@0
   318
    iReadBuffer.SetMax();
sl@0
   319
    iReadBuffer.FillZ();
sl@0
   320
    iReader->ReadL(iReadBuffer);
sl@0
   321
sl@0
   322
    iIfState = EEcho;
sl@0
   323
    }
sl@0
   324
sl@0
   325
void CDemoControl::PumpL()
sl@0
   326
    {
sl@0
   327
    console->ClearScreen();
sl@0
   328
sl@0
   329
    if(iIfState != EIdle)
sl@0
   330
	{
sl@0
   331
	User::Leave(KErrInUse);
sl@0
   332
	}
sl@0
   333
#if (defined __USE_TIMER__)
sl@0
   334
    iTimer->Start(0,1,TCallBack(Callback,this));
sl@0
   335
#endif
sl@0
   336
    StartCardL();
sl@0
   337
	
sl@0
   338
    iReadBuffer.SetMax();
sl@0
   339
    iReadBuffer.FillZ();
sl@0
   340
    iReader->ReadL(iReadBuffer);
sl@0
   341
sl@0
   342
#if (!defined __USE_TIMER__)
sl@0
   343
    CIOBuffer* buf = CreateSendPacketL();
sl@0
   344
sl@0
   345
    iWriteQueue.AddLast(*buf);
sl@0
   346
    iWriter->WriteL(buf->Ptr());
sl@0
   347
#endif
sl@0
   348
sl@0
   349
    iIfState = EPump;
sl@0
   350
    }
sl@0
   351
sl@0
   352
void CDemoControl::ReadAndDisplaySettings()
sl@0
   353
//
sl@0
   354
// Read and display the current config
sl@0
   355
//
sl@0
   356
    {
sl@0
   357
    TBuf8<32> config;
sl@0
   358
sl@0
   359
    User::LeaveIfError(iCard.Open(0));
sl@0
   360
    User::After(2000);
sl@0
   361
sl@0
   362
    // MAC Address starts at the 4th byte
sl@0
   363
    config.SetMax();
sl@0
   364
    iCard.Config(config);
sl@0
   365
sl@0
   366
sl@0
   367
    console->Printf(_L("\n\nEthernet Speed :"));
sl@0
   368
    switch (config[0])
sl@0
   369
	{
sl@0
   370
	case KEthSpeedUnknown:
sl@0
   371
	    console->Printf(_L(" Unknown\n"));
sl@0
   372
	    break;
sl@0
   373
	case KEthSpeedAuto:
sl@0
   374
	    console->Printf(_L(" Auto\n"));
sl@0
   375
	    break;
sl@0
   376
	case KEthSpeed10BaseT:
sl@0
   377
	    console->Printf(_L(" 10 MBit\n"));
sl@0
   378
	    break;
sl@0
   379
	case KEthSpeed100BaseTX:
sl@0
   380
	    console->Printf(_L(" 100 MBit\n"));
sl@0
   381
	    break;
sl@0
   382
	default:
sl@0
   383
	    console->Printf(_L(" ERROR\n"));
sl@0
   384
	}
sl@0
   385
sl@0
   386
    console->Printf(_L("Duplex Setting :"));
sl@0
   387
    switch (config[1])
sl@0
   388
	{
sl@0
   389
	case KEthDuplexUnknown:
sl@0
   390
	    console->Printf(_L(" Unknown\n"));
sl@0
   391
	    break;
sl@0
   392
	case KEthDuplexAuto:
sl@0
   393
	    console->Printf(_L(" Auto\n"));
sl@0
   394
	    break;
sl@0
   395
	case KEthDuplexFull:
sl@0
   396
	    console->Printf(_L(" Full\n"));
sl@0
   397
	    break;
sl@0
   398
	case KEthDuplexHalf:
sl@0
   399
	    console->Printf(_L(" Half\n"));
sl@0
   400
	    break;
sl@0
   401
	default:
sl@0
   402
	    console->Printf(_L(" ERROR\n"));
sl@0
   403
	}
sl@0
   404
sl@0
   405
    console->Printf(_L("MAC :"));
sl@0
   406
    console->Printf(_L(" %2x:%2x:%2x:%2x:%2x:%2x\n\n"),
sl@0
   407
		 config[2], config[3],
sl@0
   408
		 config[4], config[5],
sl@0
   409
		 config[6], config[7]);
sl@0
   410
sl@0
   411
	console->Printf(_L("\nPress any key to continue..\n") );
sl@0
   412
sl@0
   413
	console->Getch();
sl@0
   414
sl@0
   415
	iCard.Close();
sl@0
   416
    }
sl@0
   417
sl@0
   418
sl@0
   419
CIOBuffer* CDemoControl::CreateSendPacketL()
sl@0
   420
    {
sl@0
   421
    CIOBuffer* buf = CIOBuffer::NewL(1500);
sl@0
   422
    // Copy in the Destination mac address
sl@0
   423
    buf->Ptr().SetLength(6);
sl@0
   424
    buf->Ptr().Copy(DestMacAddr,6);
sl@0
   425
sl@0
   426
    // Copy in the source mac address read from the driver
sl@0
   427
    //buf->Ptr().Append(&iConfig[3],6);
sl@0
   428
	buf->Ptr().Append(&iConfig[2],6);
sl@0
   429
	
sl@0
   430
    // EtherII framing
sl@0
   431
    buf->Ptr().Append(0x08);
sl@0
   432
    buf->Ptr().Append(0x06);
sl@0
   433
    buf->Ptr().SetMax();
sl@0
   434
    StripeDes(buf->Ptr(), 14, buf->Ptr().Length(), '@', 'Z',0);
sl@0
   435
    return buf;
sl@0
   436
    }
sl@0
   437
sl@0
   438
void CDemoControl::ReadL()
sl@0
   439
    {
sl@0
   440
    if(iIfState != EIdle)
sl@0
   441
	{
sl@0
   442
	User::Leave(KErrInUse);
sl@0
   443
	}
sl@0
   444
	
sl@0
   445
    StartCardL();
sl@0
   446
	
sl@0
   447
    iReadBuffer.SetMax();
sl@0
   448
    iReadBuffer.FillZ();
sl@0
   449
    iReader->ReadL(iReadBuffer);
sl@0
   450
sl@0
   451
    iIfState = ERead;
sl@0
   452
    }
sl@0
   453
sl@0
   454
sl@0
   455
sl@0
   456
sl@0
   457
CIOBuffer* CDemoControl::CreateRandomPacketL(TInt aOffset)
sl@0
   458
	{
sl@0
   459
	CIOBuffer* buf = CIOBuffer::NewL(1500);
sl@0
   460
	// Copy in the Destination mac address
sl@0
   461
	buf->Ptr().SetLength(6);
sl@0
   462
	buf->Ptr().Copy(DestMacAddr,6);
sl@0
   463
#if (defined __USE_LDDPDD__)
sl@0
   464
	// Copy in the source mac address read from the driver
sl@0
   465
	//buf->Ptr().Append(&iConfig[3],6);
sl@0
   466
	buf->Ptr().Append(&iConfig[2],6);
sl@0
   467
#else
sl@0
   468
	buf->Ptr().Append(DummyMac,6);
sl@0
   469
#endif
sl@0
   470
	// EtherII framing
sl@0
   471
	buf->Ptr().Append(0x08);
sl@0
   472
	buf->Ptr().Append(0x06);
sl@0
   473
	buf->Ptr().SetMax();
sl@0
   474
	
sl@0
   475
	StripeDes(buf->Ptr(), 14, buf->Ptr().Length(), '@', 'Z',aOffset);
sl@0
   476
	return buf;
sl@0
   477
}
sl@0
   478
sl@0
   479
sl@0
   480
TInt CDemoControl::iSendAndEchoCmpCounter = 0;
sl@0
   481
sl@0
   482
void CDemoControl::CompareEcho()
sl@0
   483
{
sl@0
   484
	iSendAndEchoSame = 
sl@0
   485
		CheckDes(iReadBuffer, 14, /*iReadBuffer.Length() - 4*/ 1500 - 4, '@', 'Z', iIntRandomOffset);
sl@0
   486
										// - 4 for trailer
sl@0
   487
	console->Printf(_L("\r\nSent & Received Random Packet no: %d \r\n"), iSendAndEchoCmpCounter );
sl@0
   488
	
sl@0
   489
	if( iSendAndEchoSame )
sl@0
   490
		console->Printf( _L("Echo Same: TRUE \r\n") );
sl@0
   491
	else
sl@0
   492
		console->Printf( _L("Echo Same: FALSE \r\n") );
sl@0
   493
	
sl@0
   494
sl@0
   495
}
sl@0
   496
sl@0
   497
void CDemoControl::SendAndCompareEchoL()
sl@0
   498
{
sl@0
   499
	if(iIfState != EIdle)
sl@0
   500
		{
sl@0
   501
		User::Leave(KErrInUse);
sl@0
   502
		}
sl@0
   503
sl@0
   504
	iSendAndEchoSame = EFalse;
sl@0
   505
sl@0
   506
	StartCardL();
sl@0
   507
	
sl@0
   508
	// empty write buffer before start - nothing else should write 
sl@0
   509
	// when iIfState = ESendAndCmpEcho
sl@0
   510
	EmptyWriteQueue();
sl@0
   511
	
sl@0
   512
	iIfState = ESendAndCmpEcho;
sl@0
   513
sl@0
   514
	// time for generating seed for rand function
sl@0
   515
	TTime time;
sl@0
   516
	time.HomeTime(); 
sl@0
   517
sl@0
   518
	// change seed after 10 frames sent
sl@0
   519
	if( 0 == (iSendAndEchoCmpCounter % 10) )
sl@0
   520
	{
sl@0
   521
		iIntSeed = time.Int64();
sl@0
   522
	}
sl@0
   523
sl@0
   524
	iIntRandomOffset = Math::Rand( iIntSeed );
sl@0
   525
sl@0
   526
	CIOBuffer* buf = CreateRandomPacketL( iIntRandomOffset );
sl@0
   527
	
sl@0
   528
	iWriteQueue.AddLast(*buf);
sl@0
   529
	iWriter->WriteL(buf->Ptr());
sl@0
   530
}
sl@0
   531
sl@0
   532
void CDemoControl::HandleWriteCompleteSndCmpEchoModeL()
sl@0
   533
{
sl@0
   534
	
sl@0
   535
	CIOBuffer* buf = iWriteQueue.First();
sl@0
   536
	iWriteQueue.Remove(*buf);
sl@0
   537
	delete buf;
sl@0
   538
sl@0
   539
	iSendAndEchoCmpCounter = ++iSendAndEchoCmpCounter;
sl@0
   540
		
sl@0
   541
	// empty read buffer
sl@0
   542
	iReadBuffer.SetMax();
sl@0
   543
	iReadBuffer.FillZ();	
sl@0
   544
	// read echo
sl@0
   545
	iReader->ReadL(iReadBuffer);
sl@0
   546
}
sl@0
   547
sl@0
   548
void CDemoControl::HandleReadCompleteSndCmpEchoModeL()
sl@0
   549
{
sl@0
   550
	CompareEcho();
sl@0
   551
sl@0
   552
	// empty read buffer
sl@0
   553
	iReadBuffer.SetMax();
sl@0
   554
    iReadBuffer.FillZ();
sl@0
   555
sl@0
   556
//	iIfState = EIdle;
sl@0
   557
}
sl@0
   558
sl@0
   559
void CDemoControl::ReadAndSetDestMacL()
sl@0
   560
{
sl@0
   561
	
sl@0
   562
	TUint8 upper=0;
sl@0
   563
	TInt i =0;
sl@0
   564
	//TInt consPos = 0;
sl@0
   565
	TChar c;
sl@0
   566
	TInt pos; 
sl@0
   567
	TUint8 value;
sl@0
   568
sl@0
   569
	TBuf<20> validChars(_L("0123456789abcdef"));
sl@0
   570
sl@0
   571
	TUint8 newDestMacAddr[] = {0x00,0x00,0x00,0x00,0x00,0x00};
sl@0
   572
sl@0
   573
	_LIT(KMess,"Type new dest MAC (12 hexagonal digits):\r\n");
sl@0
   574
	console->ClearScreen();
sl@0
   575
	console->SetPos(0,0);
sl@0
   576
	console->Printf(KMess,iIfState);
sl@0
   577
sl@0
   578
	for(i = 0; i < 12; i++)
sl@0
   579
	{
sl@0
   580
		c = console->Getch();
sl@0
   581
		c.LowerCase();
sl@0
   582
		if((pos = validChars.Locate(c))==KErrNotFound)
sl@0
   583
		    {
sl@0
   584
		    //pos = upper;
sl@0
   585
			User::Leave(KErrNotFound); 
sl@0
   586
		    //break;
sl@0
   587
		    }
sl@0
   588
		console->SetPos(i, 1);
sl@0
   589
		console->Printf(_L("%c"), (char)c);
sl@0
   590
		if(i%2)
sl@0
   591
		{
sl@0
   592
			upper = newDestMacAddr[i / 2];
sl@0
   593
			value = (TUint8)pos;
sl@0
   594
			//value = (TUint8)((upper<<4) | value);
sl@0
   595
			newDestMacAddr[i / 2] = (TUint8)((upper<<4) | value);
sl@0
   596
		}
sl@0
   597
		else
sl@0
   598
			newDestMacAddr[i / 2] = (TUint8)pos;
sl@0
   599
		
sl@0
   600
	}
sl@0
   601
sl@0
   602
	for(i = 0; i < 6; i++)
sl@0
   603
		DestMacAddr[i] = newDestMacAddr[i];
sl@0
   604
sl@0
   605
	console->Printf(_L("\nSetting MAC to %2x:%2x:%2x:%2x:%2x:%2x\n"),
sl@0
   606
			 DestMacAddr[0], DestMacAddr[1], DestMacAddr[2],
sl@0
   607
			 DestMacAddr[3], DestMacAddr[4], DestMacAddr[5]);
sl@0
   608
sl@0
   609
	console->Printf(_L("\nPress any key to continue..\n") );
sl@0
   610
sl@0
   611
	console->Getch();
sl@0
   612
sl@0
   613
   return; 
sl@0
   614
}
sl@0
   615
sl@0
   616
//-jk
sl@0
   617
sl@0
   618
void CDemoControl::StopL()
sl@0
   619
    {
sl@0
   620
    if(iIfState == EIdle)
sl@0
   621
		{
sl@0
   622
		User::Leave(KErrInUse);
sl@0
   623
		}
sl@0
   624
sl@0
   625
    EmptyWriteQueue();
sl@0
   626
#if (defined __USE_TIMER__)
sl@0
   627
    if(iIfState == EPump)
sl@0
   628
	{
sl@0
   629
		iTimer->Cancel();
sl@0
   630
		_LIT(KMess,"\r\nPackets Pumped = %d\r\n");
sl@0
   631
		console->Printf(KMess,iPacketsWritten);
sl@0
   632
		console->Printf(_L("\r\nPress any key to continue..\r\n") );
sl@0
   633
		console->Getch();
sl@0
   634
	}
sl@0
   635
#endif
sl@0
   636
    StopCard();
sl@0
   637
sl@0
   638
    iIfState = EIdle;
sl@0
   639
    }
sl@0
   640
sl@0
   641
void CDemoControl::StartCardL()
sl@0
   642
    {
sl@0
   643
//	User::LeaveIfError(iCard.Open(iCard.VersionRequired(),0,NULL));
sl@0
   644
    User::LeaveIfError(iCard.Open(0));
sl@0
   645
    User::After(2000000);
sl@0
   646
//	TBuf8<8> ioctlBuf;
sl@0
   647
//	ioctlBuf.SetLength(1);
sl@0
   648
//	ioctlBuf[0] = KIoControlGetStatus;
sl@0
   649
//	TRequestStatus status;
sl@0
   650
//	iCard.IOControl(iStatus,ioctlBuf);
sl@0
   651
//	User::WaitForRequest(status);
sl@0
   652
//	if(ioctlBuf[0] != KEventPCCardReady)
sl@0
   653
//		{
sl@0
   654
//		iCard.Close();
sl@0
   655
//		User::Leave(KErrNotReady);
sl@0
   656
//		}
sl@0
   657
    // MAC Address starts at the 2nd byte
sl@0
   658
    iConfig.SetMax();
sl@0
   659
    iCard.Config(iConfig);
sl@0
   660
sl@0
   661
    iPacketsRead = 0;
sl@0
   662
    iPacketsWritten = 0;
sl@0
   663
    console->ClearScreen();
sl@0
   664
    }
sl@0
   665
sl@0
   666
void CDemoControl::StopCard()
sl@0
   667
    {
sl@0
   668
	
sl@0
   669
    iCard.ReadCancel();
sl@0
   670
    iCard.WriteCancel();
sl@0
   671
    iWriter->Cancel();
sl@0
   672
    iReader->Cancel();
sl@0
   673
	
sl@0
   674
    iCard.Close();
sl@0
   675
		
sl@0
   676
    }
sl@0
   677
sl@0
   678
void CDemoControl::ReadCompleteL(const TInt aStatus)
sl@0
   679
// Read completed by the server
sl@0
   680
    {
sl@0
   681
    iPacketsRead++;
sl@0
   682
    console->SetPos(0,1);
sl@0
   683
    _LIT(KMess,"Read  Complete Status = %d Packets Read    = %d\r\n");
sl@0
   684
    console->Printf(KMess,aStatus,iPacketsRead);
sl@0
   685
	RDebug::Print(KMess,aStatus,iPacketsRead);
sl@0
   686
    // Validate the received buffer with what we sent
sl@0
   687
sl@0
   688
    switch(iIfState)
sl@0
   689
	{
sl@0
   690
	case EPump:
sl@0
   691
	    HandleReadCompletePumpModeL();
sl@0
   692
	    break;
sl@0
   693
sl@0
   694
	case EEcho:
sl@0
   695
	    HandleReadCompleteEchoModeL();
sl@0
   696
	    break;
sl@0
   697
		
sl@0
   698
	case ERead:
sl@0
   699
	    HandleReadCompleteReadModeL();
sl@0
   700
	    break;
sl@0
   701
sl@0
   702
	case ESendAndCmpEcho:
sl@0
   703
		HandleReadCompleteSndCmpEchoModeL();
sl@0
   704
		break;
sl@0
   705
		
sl@0
   706
	default:
sl@0
   707
	    break;
sl@0
   708
	}
sl@0
   709
    iReadBuffer.SetMax();
sl@0
   710
    iReadBuffer.FillZ();
sl@0
   711
    iReader->ReadL(iReadBuffer);
sl@0
   712
    }
sl@0
   713
sl@0
   714
void CDemoControl::WriteCompleteL(const TInt aStatus)
sl@0
   715
// Write completed by the server
sl@0
   716
    {
sl@0
   717
    iPacketsWritten++;
sl@0
   718
    console->SetPos(0,0);
sl@0
   719
    _LIT(KMess,"Write Complete Status = %d Packets Written = %d\r\n");
sl@0
   720
    console->Printf(KMess,aStatus,iPacketsWritten);
sl@0
   721
sl@0
   722
    switch(iIfState)
sl@0
   723
	{
sl@0
   724
	case EPump:
sl@0
   725
	    HandleWriteCompletePumpModeL();
sl@0
   726
	    break;
sl@0
   727
sl@0
   728
	case EEcho:
sl@0
   729
	    HandleWriteCompleteEchoModeL();
sl@0
   730
	    break;
sl@0
   731
sl@0
   732
	case ESendAndCmpEcho:
sl@0
   733
			HandleWriteCompleteSndCmpEchoModeL();
sl@0
   734
			break;
sl@0
   735
	
sl@0
   736
	default:
sl@0
   737
	    break;
sl@0
   738
	}
sl@0
   739
    }
sl@0
   740
sl@0
   741
void CDemoControl::HandleWriteCompleteEchoModeL()
sl@0
   742
    {
sl@0
   743
    CIOBuffer* buf = iWriteQueue.First();
sl@0
   744
    iWriteQueue.Remove(*buf);
sl@0
   745
    delete buf;
sl@0
   746
    if(!iWriteQueue.IsEmpty())
sl@0
   747
	{
sl@0
   748
	buf = iWriteQueue.First();
sl@0
   749
	iWriter->WriteL(buf->Ptr());
sl@0
   750
	}
sl@0
   751
    }
sl@0
   752
sl@0
   753
void CDemoControl::HandleReadCompleteEchoModeL()
sl@0
   754
    // In echo mode we send out what we receive and there could potentialy be a write
sl@0
   755
    // outstanding.
sl@0
   756
    // Get a new CIOBuffer copy the read data to the new write buffer
sl@0
   757
    // Queue it but only WriteL() it if the queue was empty
sl@0
   758
    {
sl@0
   759
    TBool sendNow = EFalse;
sl@0
   760
    (iWriteQueue.IsEmpty()) ? (sendNow = ETrue) : (sendNow = EFalse);
sl@0
   761
    // Add it to the queue
sl@0
   762
    CIOBuffer* buf = CIOBuffer::NewL(iReadBuffer.Length());
sl@0
   763
	
sl@0
   764
    buf->Ptr() = iReadBuffer;
sl@0
   765
sl@0
   766
    // Flip Mac Addresses in buf
sl@0
   767
    FlipMacAddresses(buf->Ptr());
sl@0
   768
sl@0
   769
    iWriteQueue.AddLast(*buf);
sl@0
   770
    if(sendNow)
sl@0
   771
	{
sl@0
   772
	iWriter->WriteL(buf->Ptr());
sl@0
   773
	}
sl@0
   774
    }
sl@0
   775
sl@0
   776
void CDemoControl::FlipMacAddresses(TDes8& aBuf)
sl@0
   777
    {
sl@0
   778
    TUint32 length = aBuf.Length();
sl@0
   779
    aBuf.SetLength(6);
sl@0
   780
    TBuf8<6> dest(aBuf);
sl@0
   781
    aBuf.SetLength(12);
sl@0
   782
    aBuf.Copy(&aBuf[6],6);
sl@0
   783
    aBuf.SetLength(6);
sl@0
   784
    aBuf.Append(dest);
sl@0
   785
    aBuf.SetLength(length);
sl@0
   786
    }
sl@0
   787
sl@0
   788
void CDemoControl::HandleWriteCompletePumpModeL()
sl@0
   789
    // In pump mode we never need to queue so just reuse the last buffer
sl@0
   790
    {
sl@0
   791
#if (defined __USE_TIMER__)
sl@0
   792
    CIOBuffer* buf = iWriteQueue.First();
sl@0
   793
    iWriteQueue.Remove(*buf);
sl@0
   794
    delete buf;
sl@0
   795
#else
sl@0
   796
    CIOBuffer* buf = iWriteQueue.First();
sl@0
   797
    iWriter->WriteL(buf->Ptr());
sl@0
   798
#endif
sl@0
   799
    }
sl@0
   800
sl@0
   801
void CDemoControl::HandleReadCompletePumpModeL()
sl@0
   802
    {
sl@0
   803
    }
sl@0
   804
sl@0
   805
void CDemoControl::HandleReadCompleteReadModeL()
sl@0
   806
    {
sl@0
   807
    }
sl@0
   808
sl@0
   809
//////////////
sl@0
   810
sl@0
   811
CDemoWriter* CDemoWriter::NewL(MWriterNotify& aNotify,RBusDevEthernet& aCard)
sl@0
   812
// Standard CBase derived creation of the Writer object
sl@0
   813
    {
sl@0
   814
    CDemoWriter* self = new (ELeave) CDemoWriter(EPriorityNormal);
sl@0
   815
    CleanupStack::PushL(self);
sl@0
   816
    self->ConstructL(aNotify,aCard);
sl@0
   817
    CleanupStack::Pop();
sl@0
   818
    return self;
sl@0
   819
    }
sl@0
   820
sl@0
   821
sl@0
   822
void CDemoWriter::WriteL(const TDesC8& aBuffer)
sl@0
   823
// Write data to the server
sl@0
   824
    {
sl@0
   825
    // Sanity check on the state of the active object
sl@0
   826
    if(IsActive())
sl@0
   827
	{
sl@0
   828
#if (defined __USE_TIMER__)
sl@0
   829
	return;
sl@0
   830
#else
sl@0
   831
	User::Leave(KErrNotReady);
sl@0
   832
#endif
sl@0
   833
	}
sl@0
   834
    RDebug::Print(_L("About to write\n"));
sl@0
   835
    iCard->Write(iStatus,aBuffer);
sl@0
   836
sl@0
   837
    SetActive();
sl@0
   838
    }
sl@0
   839
sl@0
   840
CDemoWriter::~CDemoWriter()
sl@0
   841
    {
sl@0
   842
    // Just in case, does not hurt to call if object is not active
sl@0
   843
    Cancel();
sl@0
   844
    }
sl@0
   845
sl@0
   846
sl@0
   847
void CDemoWriter::ConstructL(MWriterNotify& aNotify,RBusDevEthernet& aCard)
sl@0
   848
// Second phase construction. Does not actually leave 
sl@0
   849
    {
sl@0
   850
    CActiveScheduler::Add(this);
sl@0
   851
    iNotify = &aNotify;
sl@0
   852
    iCard = &aCard;
sl@0
   853
    }
sl@0
   854
sl@0
   855
sl@0
   856
void CDemoWriter::RunL()
sl@0
   857
// Just call back into the parent to notify Write completion
sl@0
   858
    {
sl@0
   859
    // Pass the status
sl@0
   860
    iNotify->WriteCompleteL(iStatus.Int());
sl@0
   861
    }
sl@0
   862
sl@0
   863
void CDemoWriter::DoCancel()
sl@0
   864
// Called by the CActive base class Cancel()
sl@0
   865
// Only called if our TRequestStatus is still active 
sl@0
   866
    {
sl@0
   867
    }
sl@0
   868
sl@0
   869
///////
sl@0
   870
sl@0
   871
sl@0
   872
CDemoReader* CDemoReader::NewL(MReaderNotify& aNotify,RBusDevEthernet& aCard)
sl@0
   873
// Standard CBase derived creation of the Reader object
sl@0
   874
    {
sl@0
   875
    CDemoReader* self = new (ELeave) CDemoReader(EPriorityNormal+1);
sl@0
   876
    CleanupStack::PushL(self);
sl@0
   877
    self->ConstructL(aNotify,aCard);
sl@0
   878
    CleanupStack::Pop();
sl@0
   879
    return self;
sl@0
   880
    }
sl@0
   881
sl@0
   882
sl@0
   883
void CDemoReader::ReadL(TDes8& aBuffer)
sl@0
   884
    {
sl@0
   885
    // Sanity Check
sl@0
   886
    if(IsActive())
sl@0
   887
	{
sl@0
   888
	User::Leave(KErrNotReady);
sl@0
   889
	}
sl@0
   890
    RDebug::Print(_L("About to read\n"));
sl@0
   891
    iCard->Read(iStatus,aBuffer);
sl@0
   892
sl@0
   893
    SetActive();
sl@0
   894
    }
sl@0
   895
sl@0
   896
CDemoReader::~CDemoReader()
sl@0
   897
    {
sl@0
   898
    // Just in case, does not hurt to call if object is not active
sl@0
   899
    Cancel();
sl@0
   900
    }
sl@0
   901
sl@0
   902
sl@0
   903
void CDemoReader::ConstructL(MReaderNotify& aNotify,RBusDevEthernet& aCard)
sl@0
   904
// Second phase construction. Does not actually leave 
sl@0
   905
    {
sl@0
   906
    CActiveScheduler::Add(this);
sl@0
   907
    iNotify = &aNotify;
sl@0
   908
    iCard = &aCard;
sl@0
   909
    }
sl@0
   910
sl@0
   911
sl@0
   912
void CDemoReader::RunL()
sl@0
   913
// Just call back into the parent to notify read completion
sl@0
   914
    {
sl@0
   915
    // Pass the status
sl@0
   916
    iNotify->ReadCompleteL(iStatus.Int());
sl@0
   917
    }
sl@0
   918
sl@0
   919
void CDemoReader::DoCancel()
sl@0
   920
// Called by the CActive base class Cancel()
sl@0
   921
// Only called if our TRequestStatus is still active 
sl@0
   922
    {
sl@0
   923
    }
sl@0
   924
sl@0
   925
///////
sl@0
   926
sl@0
   927
static void DriveEngineL()
sl@0
   928
    {
sl@0
   929
    // Create an Active Scheduler for the thread
sl@0
   930
    // Only one Active Scheduler per thread
sl@0
   931
    CActiveScheduler* myActiveScheduler = new(ELeave) CActiveScheduler;
sl@0
   932
    CleanupStack::PushL(myActiveScheduler);
sl@0
   933
    // Install the Active Scheduler
sl@0
   934
    CActiveScheduler::Install(myActiveScheduler);
sl@0
   935
    // Create of program control class derived from CActive
sl@0
   936
    // The ConstructL() of CDemoControl adds itself to the Active Scheduler
sl@0
   937
    RDebug::Print(_L("New demo Cntrol\n"));
sl@0
   938
    CDemoControl* demo = CDemoControl::NewLC();
sl@0
   939
    // Request a character from the the console to kick the
sl@0
   940
    // Active scheduler into life. If this is not done then we will block on the
sl@0
   941
    // Scheduler loop semaphore forever.
sl@0
   942
    RDebug::Print(_L("demo Control request char\n"));
sl@0
   943
    demo->RequestCharacter();
sl@0
   944
    // Active scheduler now enters its control loop
sl@0
   945
    // We can exit this loop and hence the program by calling CActiveScheduler::Stop()
sl@0
   946
    // from a RunL().
sl@0
   947
    // IMPORTANT :-
sl@0
   948
    // From now on all this thread's processing takes place from the RunL()'s of
sl@0
   949
    // the Active objects that have been added to the Active Scheduler
sl@0
   950
    RDebug::Print(_L("Start scheduler\n"));
sl@0
   951
    myActiveScheduler->Start();
sl@0
   952
    // Remove and delete demo and myActiveScheduler
sl@0
   953
    CleanupStack::PopAndDestroy(2);	
sl@0
   954
    }
sl@0
   955
sl@0
   956
static void MainL()
sl@0
   957
    {
sl@0
   958
    // String Literal MACRO initialises a Descriptor
sl@0
   959
    //_LIT(KTitle,"EtherPump");
sl@0
   960
    //console=Console::NewL(KTitle,TSize(KDefaultConsWidth,KDefaultConsHeight));
sl@0
   961
    console=Console::NewL(_L("EtherPump"),TSize(KConsFullScreen,KConsFullScreen));
sl@0
   962
    RDebug::Print(_L("Console created\n"));
sl@0
   963
    CleanupStack::PushL(console);
sl@0
   964
    RDebug::Print(_L("and put on cu stack\n"));
sl@0
   965
    // TRAP
sl@0
   966
    TRAPD(err,DriveEngineL());
sl@0
   967
    if(err != KErrNone)
sl@0
   968
	{
sl@0
   969
	_LIT(KErrText,"Function Leave Code = %d\r\n");
sl@0
   970
	console->Printf(KErrText,err);
sl@0
   971
	}
sl@0
   972
sl@0
   973
    _LIT(KAnyKey,"Hit Any Key to Exit");
sl@0
   974
    console->ClearScreen();
sl@0
   975
    console->Printf(KAnyKey);
sl@0
   976
    console->Getch();
sl@0
   977
    CleanupStack::PopAndDestroy(1);
sl@0
   978
    }
sl@0
   979
sl@0
   980
// Entry point for all Epoc32 executables
sl@0
   981
// See PSP Chapter 2 Getting Started
sl@0
   982
GLDEF_C TInt E32Main()
sl@0
   983
    {
sl@0
   984
    // Heap balance checking
sl@0
   985
    // See PSP Chapter 6 Error Handling
sl@0
   986
    RDebug::Print(_L("create cu stack\n"));
sl@0
   987
    __UHEAP_MARK;
sl@0
   988
    CTrapCleanup* cleanup = CTrapCleanup::New();
sl@0
   989
    if(cleanup == NULL)
sl@0
   990
	{
sl@0
   991
	return KErrNoMemory;
sl@0
   992
	}
sl@0
   993
    RDebug::Print(_L("Run mainL\n"));
sl@0
   994
    TRAPD(err,MainL());
sl@0
   995
    _LIT(KPanic,"Etherpump");
sl@0
   996
    __ASSERT_ALWAYS(!err, User::Panic(KPanic,err));
sl@0
   997
    delete cleanup;
sl@0
   998
    __UHEAP_MARKEND;
sl@0
   999
    return KErrNone;
sl@0
  1000
    }
sl@0
  1001
///////////////////////
sl@0
  1002
sl@0
  1003
// Generic Buffer class
sl@0
  1004
// Currently used for transmit buffers
sl@0
  1005
CIOBuffer::CIOBuffer() : iBufPtr(NULL,0)
sl@0
  1006
    {
sl@0
  1007
    }
sl@0
  1008
sl@0
  1009
CIOBuffer::~CIOBuffer()
sl@0
  1010
// Free the HBuf if there is one
sl@0
  1011
    {
sl@0
  1012
    FreeData();
sl@0
  1013
    }
sl@0
  1014
sl@0
  1015
TPtr8& CIOBuffer::Ptr()
sl@0
  1016
    {
sl@0
  1017
    return iBufPtr;
sl@0
  1018
    }
sl@0
  1019
sl@0
  1020
CIOBuffer* CIOBuffer::NewL(const TInt aSize)
sl@0
  1021
// Creation where we new the HBuf
sl@0
  1022
    {
sl@0
  1023
    CIOBuffer * self = new (ELeave) CIOBuffer;
sl@0
  1024
    CleanupStack::PushL(self);
sl@0
  1025
    self->ConstructL(aSize);
sl@0
  1026
    CleanupStack::Pop();
sl@0
  1027
    return self;
sl@0
  1028
    }
sl@0
  1029
sl@0
  1030
void CIOBuffer::ConstructL(const TInt aSize)
sl@0
  1031
// Construction where we new the HBuf
sl@0
  1032
    {
sl@0
  1033
    iBuf = HBufC8::NewL(aSize);
sl@0
  1034
    TPtr8 temp=iBuf->Des();
sl@0
  1035
    iBufPtr.Set(temp);
sl@0
  1036
    }
sl@0
  1037
sl@0
  1038
CIOBuffer* CIOBuffer::NewL(HBufC8* aBuf)
sl@0
  1039
// HBuf provided
sl@0
  1040
    {
sl@0
  1041
    CIOBuffer * self = new (ELeave) CIOBuffer;
sl@0
  1042
    CleanupStack::PushL(self);
sl@0
  1043
    self->ConstructL(aBuf);
sl@0
  1044
    CleanupStack::Pop();
sl@0
  1045
    return self;
sl@0
  1046
    }
sl@0
  1047
sl@0
  1048
void CIOBuffer::ConstructL(HBufC8* aBuffer)
sl@0
  1049
    {
sl@0
  1050
    Assign(aBuffer);
sl@0
  1051
    }
sl@0
  1052
sl@0
  1053
TInt CIOBuffer::LinkOffset()
sl@0
  1054
    {
sl@0
  1055
    return _FOFF(CIOBuffer,iLink);	
sl@0
  1056
    }
sl@0
  1057
sl@0
  1058
void CIOBuffer::Assign(HBufC8* aBuffer)
sl@0
  1059
    {
sl@0
  1060
    iBuf = aBuffer;
sl@0
  1061
    if(aBuffer)
sl@0
  1062
	{
sl@0
  1063
	TPtr8 temp=iBuf->Des();
sl@0
  1064
	iBufPtr.Set(temp);
sl@0
  1065
	}
sl@0
  1066
    }
sl@0
  1067
sl@0
  1068
HBufC8*	CIOBuffer::Data() const
sl@0
  1069
    {
sl@0
  1070
    return iBuf;
sl@0
  1071
    }
sl@0
  1072
sl@0
  1073
void CIOBuffer::FreeData()
sl@0
  1074
    {
sl@0
  1075
    if(iBuf)
sl@0
  1076
	{
sl@0
  1077
	delete iBuf;
sl@0
  1078
	iBuf = NULL;
sl@0
  1079
	}
sl@0
  1080
    }