First public contribution.
1 // Copyright (c) 1996-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 the License "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 // e32test\ethernet\etherpump.cpp
15 // Abbreviations - PSP (Professional Symbian Programming)
19 #define __USE_LDDPDD__
23 #include <e32base_private.h>
27 #include <d32ethernet.h>
31 #define LDD_NAME _L("Enet")
32 #if (!defined __WINS__)
33 #define PDD_NAME _L("Ethernet")
36 //#define PDD_NAME _L("EthernetWins")
37 #define PDD_NAME _L("Ethernet")
41 // changed from const to static
42 //const TUint8 DestMacAddr[] = {0x00,0x50,0xDA,0xE9,0x69,0xCA};
44 // MAC address with second bit 1
45 static TUint8 DestMacAddr[] = {0x02,0xB0,0xD0,0x64,0x98,0x02};
48 // for random functions
52 void StripeMem(TUint8 *aBuf, TInt aStartPos, TInt anEndPos, TUint aStartChar, TUint anEndChar, TInt aOffset)
54 // Mark a buffer with repeating byte pattern
57 TUint character=aStartChar+(aOffset%((anEndChar+1)-aStartChar));
59 for (TInt i=aStartPos;i<anEndPos;i++)
61 aBuf[i]=(TText8)character;
62 if(++character>anEndChar)
67 void StripeDes(TDes8 &aBuf, TInt aStartPos, TInt anEndPos, TUint aStartChar, TUint anEndChar, TInt aOffset)
69 StripeMem((TUint8 *)aBuf.Ptr(), aStartPos, anEndPos, aStartChar, anEndChar, aOffset);
72 TBool CheckMem(TUint8 *aBuf, TInt aStartPos, TInt anEndPos, TUint aStartChar, TUint anEndChar, TInt aOffset)
74 // Mark a buffer with repeating byte pattern
77 TUint character=aStartChar+(aOffset%((anEndChar+1)-aStartChar));
79 for (TInt i=aStartPos;i<anEndPos;i++)
81 if (aBuf[i]!=(TText8)character)
83 if(++character>anEndChar)
89 TBool CheckDes(TDes8 &aBuf, TInt aStartPos, TInt anEndPos, TUint aStartChar, TUint anEndChar, TInt aOffset)
91 return CheckMem((TUint8 *)aBuf.Ptr(), aStartPos, anEndPos, aStartChar, anEndChar, aOffset);
95 void StripeMem32(TUint *aBuf, TInt aStartPos, TInt aEndPos)
97 // Mark a buffer with repeating byte pattern
103 for (TInt i=aStartPos;i<aEndPos;i++)
109 void StripeDes32(TDes8 &aBuf, TInt aStartPos, TInt anEndPos)
111 StripeMem32((TUint*)aBuf.Ptr(), aStartPos, anEndPos);
114 // Standard Epoc32 Library Console class
115 static CConsoleBase* console;
118 // xxxLC means method can Leave and has pushed something on the Cleanup stack
119 // Caller is responsible for popping it.
120 CDemoControl* CDemoControl::NewLC()
122 CDemoControl* self = new (ELeave) CDemoControl(EPriorityNormal);
123 CleanupStack::PushL(self);
127 TInt CDemoControl::Callback(TAny* aControl)
128 // Callback function for timer expiry
129 // Just pump another packet at the server
130 // It's a static so call a class member to access private data
132 CIOBuffer* buf = ((CDemoControl*)aControl)->CreateSendPacketL();
134 ((CDemoControl*)aControl)->iWriteQueue.AddLast(*buf);
135 ((CDemoControl*)aControl)->iWriter->WriteL(buf->Ptr());
141 void CDemoControl::ConstructL()
142 // Second Phase construction
144 // Add us to the Active Scheduler for the thread
145 CActiveScheduler::Add(this);
146 // Create the Read and Write Active Objects
147 // The 'this' pointer is the MxxxNotify callback interface that CDemoControl is derived from
148 // Pass a reference to the Server session so they can make read and write requests
150 iWriter = CDemoWriter::NewL(*this,iCard);
151 iReader = CDemoReader::NewL(*this,iCard);
153 User::LoadPhysicalDevice(PDD_NAME);
154 User::LoadLogicalDevice(LDD_NAME);
156 #if (defined __USE_TIMER__)
158 iTimer = CPeriodic::NewL(EPriorityNormal);
161 iWriteQueue.SetOffset(CIOBuffer::LinkOffset());
167 void CDemoControl::EmptyWriteQueue()
169 TSglQueIter<CIOBuffer> iter(iWriteQueue);
171 while (buf = iter++, buf!=NULL)
173 iWriteQueue.Remove(*buf);
178 CDemoControl::~CDemoControl()
180 // Cancel this classes read request to the Console
182 if(iIfState != EIdle)
188 User::FreeLogicalDevice(LDD_NAME);
189 User::FreePhysicalDevice(PDD_NAME);
192 #if (defined __USE_TIMER__)
201 void CDemoControl::RequestCharacter()
202 // Request a character from the CConsoleBase class and set us to Active
204 // Read() will result in our iStatus being set to KRequestPending 0x80000001
205 console->Read(iStatus);
206 // SetActive sets our iActive to ETrue
210 void CDemoControl::RunL()
211 // Mandatory override of pure virtual called from active scheduler Start()
212 // Key method called when the Active Scheduler semaphore is
213 // signalled and the iStatus has been completed for this Active Object
215 ProcessKeyPress(TChar(console->KeyCode()));
217 // We now return control to the scheduler loop
220 void CDemoControl::DoCancel()
221 // Mandatory override of pure virtual, called from Cancel()
223 // Cancels an outstanding request to the console
224 console->ReadCancel();
227 static const TUint KEscChar = 0x1b;
228 void CDemoControl::ProcessKeyPress(TChar aChar)
229 // Process commands from the console
230 // Executes in the context of the class RunL()
233 if(aChar == KEscChar)
235 // Modifies loop control flag value so the scheduler loop exits
236 CActiveScheduler::Stop();
238 else if(aChar == 'h' || aChar == 'H')
244 // Add Command Handler Methods here
265 TRAP(err,SendAndCompareEchoL());
269 TRAP(err,ReadAndSetDestMacL());
273 ReadAndDisplaySettings();
285 _LIT(KMess,"State = %d\r\n");
286 console->ClearScreen();
287 console->SetPos(0,0);
288 console->Printf(KMess,iIfState);
293 void CDemoControl::HelpText() const
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");
296 console->ClearScreen();
297 console->SetPos(0,5);
298 console->Printf(KMess);
301 void CDemoControl::PrintError(TChar aChar)
303 //_LIT(KMess,"Command Error = %c State = %d\r\n1 = Idle\r\n2 = Echo\r\n3 = Read\r\n4 = Pump");
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");
305 console->ClearScreen();
306 console->SetPos(0,5);
307 console->Printf(KMess,(char)aChar,iIfState);
310 void CDemoControl::EchoL()
312 if(iIfState != EIdle)
314 User::Leave(KErrInUse);
318 iReadBuffer.SetMax();
320 iReader->ReadL(iReadBuffer);
325 void CDemoControl::PumpL()
327 console->ClearScreen();
329 if(iIfState != EIdle)
331 User::Leave(KErrInUse);
333 #if (defined __USE_TIMER__)
334 iTimer->Start(0,1,TCallBack(Callback,this));
338 iReadBuffer.SetMax();
340 iReader->ReadL(iReadBuffer);
342 #if (!defined __USE_TIMER__)
343 CIOBuffer* buf = CreateSendPacketL();
345 iWriteQueue.AddLast(*buf);
346 iWriter->WriteL(buf->Ptr());
352 void CDemoControl::ReadAndDisplaySettings()
354 // Read and display the current config
359 User::LeaveIfError(iCard.Open(0));
362 // MAC Address starts at the 4th byte
364 iCard.Config(config);
367 console->Printf(_L("\n\nEthernet Speed :"));
370 case KEthSpeedUnknown:
371 console->Printf(_L(" Unknown\n"));
374 console->Printf(_L(" Auto\n"));
376 case KEthSpeed10BaseT:
377 console->Printf(_L(" 10 MBit\n"));
379 case KEthSpeed100BaseTX:
380 console->Printf(_L(" 100 MBit\n"));
383 console->Printf(_L(" ERROR\n"));
386 console->Printf(_L("Duplex Setting :"));
389 case KEthDuplexUnknown:
390 console->Printf(_L(" Unknown\n"));
393 console->Printf(_L(" Auto\n"));
396 console->Printf(_L(" Full\n"));
399 console->Printf(_L(" Half\n"));
402 console->Printf(_L(" ERROR\n"));
405 console->Printf(_L("MAC :"));
406 console->Printf(_L(" %2x:%2x:%2x:%2x:%2x:%2x\n\n"),
407 config[2], config[3],
408 config[4], config[5],
409 config[6], config[7]);
411 console->Printf(_L("\nPress any key to continue..\n") );
419 CIOBuffer* CDemoControl::CreateSendPacketL()
421 CIOBuffer* buf = CIOBuffer::NewL(1500);
422 // Copy in the Destination mac address
423 buf->Ptr().SetLength(6);
424 buf->Ptr().Copy(DestMacAddr,6);
426 // Copy in the source mac address read from the driver
427 //buf->Ptr().Append(&iConfig[3],6);
428 buf->Ptr().Append(&iConfig[2],6);
431 buf->Ptr().Append(0x08);
432 buf->Ptr().Append(0x06);
434 StripeDes(buf->Ptr(), 14, buf->Ptr().Length(), '@', 'Z',0);
438 void CDemoControl::ReadL()
440 if(iIfState != EIdle)
442 User::Leave(KErrInUse);
447 iReadBuffer.SetMax();
449 iReader->ReadL(iReadBuffer);
457 CIOBuffer* CDemoControl::CreateRandomPacketL(TInt aOffset)
459 CIOBuffer* buf = CIOBuffer::NewL(1500);
460 // Copy in the Destination mac address
461 buf->Ptr().SetLength(6);
462 buf->Ptr().Copy(DestMacAddr,6);
463 #if (defined __USE_LDDPDD__)
464 // Copy in the source mac address read from the driver
465 //buf->Ptr().Append(&iConfig[3],6);
466 buf->Ptr().Append(&iConfig[2],6);
468 buf->Ptr().Append(DummyMac,6);
471 buf->Ptr().Append(0x08);
472 buf->Ptr().Append(0x06);
475 StripeDes(buf->Ptr(), 14, buf->Ptr().Length(), '@', 'Z',aOffset);
480 TInt CDemoControl::iSendAndEchoCmpCounter = 0;
482 void CDemoControl::CompareEcho()
485 CheckDes(iReadBuffer, 14, /*iReadBuffer.Length() - 4*/ 1500 - 4, '@', 'Z', iIntRandomOffset);
487 console->Printf(_L("\r\nSent & Received Random Packet no: %d \r\n"), iSendAndEchoCmpCounter );
489 if( iSendAndEchoSame )
490 console->Printf( _L("Echo Same: TRUE \r\n") );
492 console->Printf( _L("Echo Same: FALSE \r\n") );
497 void CDemoControl::SendAndCompareEchoL()
499 if(iIfState != EIdle)
501 User::Leave(KErrInUse);
504 iSendAndEchoSame = EFalse;
508 // empty write buffer before start - nothing else should write
509 // when iIfState = ESendAndCmpEcho
512 iIfState = ESendAndCmpEcho;
514 // time for generating seed for rand function
518 // change seed after 10 frames sent
519 if( 0 == (iSendAndEchoCmpCounter % 10) )
521 iIntSeed = time.Int64();
524 iIntRandomOffset = Math::Rand( iIntSeed );
526 CIOBuffer* buf = CreateRandomPacketL( iIntRandomOffset );
528 iWriteQueue.AddLast(*buf);
529 iWriter->WriteL(buf->Ptr());
532 void CDemoControl::HandleWriteCompleteSndCmpEchoModeL()
535 CIOBuffer* buf = iWriteQueue.First();
536 iWriteQueue.Remove(*buf);
539 iSendAndEchoCmpCounter = ++iSendAndEchoCmpCounter;
542 iReadBuffer.SetMax();
545 iReader->ReadL(iReadBuffer);
548 void CDemoControl::HandleReadCompleteSndCmpEchoModeL()
553 iReadBuffer.SetMax();
559 void CDemoControl::ReadAndSetDestMacL()
569 TBuf<20> validChars(_L("0123456789abcdef"));
571 TUint8 newDestMacAddr[] = {0x00,0x00,0x00,0x00,0x00,0x00};
573 _LIT(KMess,"Type new dest MAC (12 hexagonal digits):\r\n");
574 console->ClearScreen();
575 console->SetPos(0,0);
576 console->Printf(KMess,iIfState);
578 for(i = 0; i < 12; i++)
580 c = console->Getch();
582 if((pos = validChars.Locate(c))==KErrNotFound)
585 User::Leave(KErrNotFound);
588 console->SetPos(i, 1);
589 console->Printf(_L("%c"), (char)c);
592 upper = newDestMacAddr[i / 2];
594 //value = (TUint8)((upper<<4) | value);
595 newDestMacAddr[i / 2] = (TUint8)((upper<<4) | value);
598 newDestMacAddr[i / 2] = (TUint8)pos;
602 for(i = 0; i < 6; i++)
603 DestMacAddr[i] = newDestMacAddr[i];
605 console->Printf(_L("\nSetting MAC to %2x:%2x:%2x:%2x:%2x:%2x\n"),
606 DestMacAddr[0], DestMacAddr[1], DestMacAddr[2],
607 DestMacAddr[3], DestMacAddr[4], DestMacAddr[5]);
609 console->Printf(_L("\nPress any key to continue..\n") );
618 void CDemoControl::StopL()
620 if(iIfState == EIdle)
622 User::Leave(KErrInUse);
626 #if (defined __USE_TIMER__)
627 if(iIfState == EPump)
630 _LIT(KMess,"\r\nPackets Pumped = %d\r\n");
631 console->Printf(KMess,iPacketsWritten);
632 console->Printf(_L("\r\nPress any key to continue..\r\n") );
641 void CDemoControl::StartCardL()
643 // User::LeaveIfError(iCard.Open(iCard.VersionRequired(),0,NULL));
644 User::LeaveIfError(iCard.Open(0));
645 User::After(2000000);
646 // TBuf8<8> ioctlBuf;
647 // ioctlBuf.SetLength(1);
648 // ioctlBuf[0] = KIoControlGetStatus;
649 // TRequestStatus status;
650 // iCard.IOControl(iStatus,ioctlBuf);
651 // User::WaitForRequest(status);
652 // if(ioctlBuf[0] != KEventPCCardReady)
655 // User::Leave(KErrNotReady);
657 // MAC Address starts at the 2nd byte
659 iCard.Config(iConfig);
663 console->ClearScreen();
666 void CDemoControl::StopCard()
678 void CDemoControl::ReadCompleteL(const TInt aStatus)
679 // Read completed by the server
682 console->SetPos(0,1);
683 _LIT(KMess,"Read Complete Status = %d Packets Read = %d\r\n");
684 console->Printf(KMess,aStatus,iPacketsRead);
685 RDebug::Print(KMess,aStatus,iPacketsRead);
686 // Validate the received buffer with what we sent
691 HandleReadCompletePumpModeL();
695 HandleReadCompleteEchoModeL();
699 HandleReadCompleteReadModeL();
702 case ESendAndCmpEcho:
703 HandleReadCompleteSndCmpEchoModeL();
709 iReadBuffer.SetMax();
711 iReader->ReadL(iReadBuffer);
714 void CDemoControl::WriteCompleteL(const TInt aStatus)
715 // Write completed by the server
718 console->SetPos(0,0);
719 _LIT(KMess,"Write Complete Status = %d Packets Written = %d\r\n");
720 console->Printf(KMess,aStatus,iPacketsWritten);
725 HandleWriteCompletePumpModeL();
729 HandleWriteCompleteEchoModeL();
732 case ESendAndCmpEcho:
733 HandleWriteCompleteSndCmpEchoModeL();
741 void CDemoControl::HandleWriteCompleteEchoModeL()
743 CIOBuffer* buf = iWriteQueue.First();
744 iWriteQueue.Remove(*buf);
746 if(!iWriteQueue.IsEmpty())
748 buf = iWriteQueue.First();
749 iWriter->WriteL(buf->Ptr());
753 void CDemoControl::HandleReadCompleteEchoModeL()
754 // In echo mode we send out what we receive and there could potentialy be a write
756 // Get a new CIOBuffer copy the read data to the new write buffer
757 // Queue it but only WriteL() it if the queue was empty
759 TBool sendNow = EFalse;
760 (iWriteQueue.IsEmpty()) ? (sendNow = ETrue) : (sendNow = EFalse);
761 // Add it to the queue
762 CIOBuffer* buf = CIOBuffer::NewL(iReadBuffer.Length());
764 buf->Ptr() = iReadBuffer;
766 // Flip Mac Addresses in buf
767 FlipMacAddresses(buf->Ptr());
769 iWriteQueue.AddLast(*buf);
772 iWriter->WriteL(buf->Ptr());
776 void CDemoControl::FlipMacAddresses(TDes8& aBuf)
778 TUint32 length = aBuf.Length();
782 aBuf.Copy(&aBuf[6],6);
785 aBuf.SetLength(length);
788 void CDemoControl::HandleWriteCompletePumpModeL()
789 // In pump mode we never need to queue so just reuse the last buffer
791 #if (defined __USE_TIMER__)
792 CIOBuffer* buf = iWriteQueue.First();
793 iWriteQueue.Remove(*buf);
796 CIOBuffer* buf = iWriteQueue.First();
797 iWriter->WriteL(buf->Ptr());
801 void CDemoControl::HandleReadCompletePumpModeL()
805 void CDemoControl::HandleReadCompleteReadModeL()
811 CDemoWriter* CDemoWriter::NewL(MWriterNotify& aNotify,RBusDevEthernet& aCard)
812 // Standard CBase derived creation of the Writer object
814 CDemoWriter* self = new (ELeave) CDemoWriter(EPriorityNormal);
815 CleanupStack::PushL(self);
816 self->ConstructL(aNotify,aCard);
822 void CDemoWriter::WriteL(const TDesC8& aBuffer)
823 // Write data to the server
825 // Sanity check on the state of the active object
828 #if (defined __USE_TIMER__)
831 User::Leave(KErrNotReady);
834 RDebug::Print(_L("About to write\n"));
835 iCard->Write(iStatus,aBuffer);
840 CDemoWriter::~CDemoWriter()
842 // Just in case, does not hurt to call if object is not active
847 void CDemoWriter::ConstructL(MWriterNotify& aNotify,RBusDevEthernet& aCard)
848 // Second phase construction. Does not actually leave
850 CActiveScheduler::Add(this);
856 void CDemoWriter::RunL()
857 // Just call back into the parent to notify Write completion
860 iNotify->WriteCompleteL(iStatus.Int());
863 void CDemoWriter::DoCancel()
864 // Called by the CActive base class Cancel()
865 // Only called if our TRequestStatus is still active
872 CDemoReader* CDemoReader::NewL(MReaderNotify& aNotify,RBusDevEthernet& aCard)
873 // Standard CBase derived creation of the Reader object
875 CDemoReader* self = new (ELeave) CDemoReader(EPriorityNormal+1);
876 CleanupStack::PushL(self);
877 self->ConstructL(aNotify,aCard);
883 void CDemoReader::ReadL(TDes8& aBuffer)
888 User::Leave(KErrNotReady);
890 RDebug::Print(_L("About to read\n"));
891 iCard->Read(iStatus,aBuffer);
896 CDemoReader::~CDemoReader()
898 // Just in case, does not hurt to call if object is not active
903 void CDemoReader::ConstructL(MReaderNotify& aNotify,RBusDevEthernet& aCard)
904 // Second phase construction. Does not actually leave
906 CActiveScheduler::Add(this);
912 void CDemoReader::RunL()
913 // Just call back into the parent to notify read completion
916 iNotify->ReadCompleteL(iStatus.Int());
919 void CDemoReader::DoCancel()
920 // Called by the CActive base class Cancel()
921 // Only called if our TRequestStatus is still active
927 static void DriveEngineL()
929 // Create an Active Scheduler for the thread
930 // Only one Active Scheduler per thread
931 CActiveScheduler* myActiveScheduler = new(ELeave) CActiveScheduler;
932 CleanupStack::PushL(myActiveScheduler);
933 // Install the Active Scheduler
934 CActiveScheduler::Install(myActiveScheduler);
935 // Create of program control class derived from CActive
936 // The ConstructL() of CDemoControl adds itself to the Active Scheduler
937 RDebug::Print(_L("New demo Cntrol\n"));
938 CDemoControl* demo = CDemoControl::NewLC();
939 // Request a character from the the console to kick the
940 // Active scheduler into life. If this is not done then we will block on the
941 // Scheduler loop semaphore forever.
942 RDebug::Print(_L("demo Control request char\n"));
943 demo->RequestCharacter();
944 // Active scheduler now enters its control loop
945 // We can exit this loop and hence the program by calling CActiveScheduler::Stop()
948 // From now on all this thread's processing takes place from the RunL()'s of
949 // the Active objects that have been added to the Active Scheduler
950 RDebug::Print(_L("Start scheduler\n"));
951 myActiveScheduler->Start();
952 // Remove and delete demo and myActiveScheduler
953 CleanupStack::PopAndDestroy(2);
958 // String Literal MACRO initialises a Descriptor
959 //_LIT(KTitle,"EtherPump");
960 //console=Console::NewL(KTitle,TSize(KDefaultConsWidth,KDefaultConsHeight));
961 console=Console::NewL(_L("EtherPump"),TSize(KConsFullScreen,KConsFullScreen));
962 RDebug::Print(_L("Console created\n"));
963 CleanupStack::PushL(console);
964 RDebug::Print(_L("and put on cu stack\n"));
966 TRAPD(err,DriveEngineL());
969 _LIT(KErrText,"Function Leave Code = %d\r\n");
970 console->Printf(KErrText,err);
973 _LIT(KAnyKey,"Hit Any Key to Exit");
974 console->ClearScreen();
975 console->Printf(KAnyKey);
977 CleanupStack::PopAndDestroy(1);
980 // Entry point for all Epoc32 executables
981 // See PSP Chapter 2 Getting Started
982 GLDEF_C TInt E32Main()
984 // Heap balance checking
985 // See PSP Chapter 6 Error Handling
986 RDebug::Print(_L("create cu stack\n"));
988 CTrapCleanup* cleanup = CTrapCleanup::New();
993 RDebug::Print(_L("Run mainL\n"));
995 _LIT(KPanic,"Etherpump");
996 __ASSERT_ALWAYS(!err, User::Panic(KPanic,err));
1001 ///////////////////////
1003 // Generic Buffer class
1004 // Currently used for transmit buffers
1005 CIOBuffer::CIOBuffer() : iBufPtr(NULL,0)
1009 CIOBuffer::~CIOBuffer()
1010 // Free the HBuf if there is one
1015 TPtr8& CIOBuffer::Ptr()
1020 CIOBuffer* CIOBuffer::NewL(const TInt aSize)
1021 // Creation where we new the HBuf
1023 CIOBuffer * self = new (ELeave) CIOBuffer;
1024 CleanupStack::PushL(self);
1025 self->ConstructL(aSize);
1026 CleanupStack::Pop();
1030 void CIOBuffer::ConstructL(const TInt aSize)
1031 // Construction where we new the HBuf
1033 iBuf = HBufC8::NewL(aSize);
1034 TPtr8 temp=iBuf->Des();
1038 CIOBuffer* CIOBuffer::NewL(HBufC8* aBuf)
1041 CIOBuffer * self = new (ELeave) CIOBuffer;
1042 CleanupStack::PushL(self);
1043 self->ConstructL(aBuf);
1044 CleanupStack::Pop();
1048 void CIOBuffer::ConstructL(HBufC8* aBuffer)
1053 TInt CIOBuffer::LinkOffset()
1055 return _FOFF(CIOBuffer,iLink);
1058 void CIOBuffer::Assign(HBufC8* aBuffer)
1063 TPtr8 temp=iBuf->Des();
1068 HBufC8* CIOBuffer::Data() const
1073 void CIOBuffer::FreeData()