usbmgmt/usbmgrtest/t_ncm/src/tcptest.cpp
changeset 28 f1fd07aa74c9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_ncm/src/tcptest.cpp	Wed Jul 07 14:16:40 2010 +0800
@@ -0,0 +1,612 @@
+/*
+* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+/** @file
+ @internalComponent
+ @test
+ */
+
+#include "tcptest.h"
+#include <in_sock.h>
+#include <commdbconnpref.h>
+#include <es_enum.h>
+#include "tcpcommand.h"
+#include "ncmtestconsole.h"
+
+_LIT8(KSendData, "TCP-Packet::HelloWorld\n");
+
+static const TInt KMaxNumOfChars = 255;
+
+//The title of TCP test console
+_LIT(KTcpServerMode, "Tcp Server");
+_LIT(KTcpClientMode, "Tcp Client");
+
+//The default value of data size
+static const TInt KDefaultDataSize = 30;
+
+CTcpProcess* CTcpProcess::NewL(CConsoleBase& aConsole, TInetAddr& aAddr, TInt aPort, TInt aSize, TBool aMode)
+	{
+	CTcpProcess* self = new(ELeave) CTcpProcess(aConsole, aAddr, aPort, aSize, aMode);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CTcpProcess::~CTcpProcess()
+	{
+	Cancel();
+	iRecvBuf.Close();
+    iSendBuf.Close();
+    iSocket.Close();
+    iListenSocket.Close();
+    iSockServ.Close();
+	}
+
+CTcpProcess::CTcpProcess(CConsoleBase& aConsole, TInetAddr& aAddr, TInt aPort, TInt aSize, TBool aMode) 
+		:  CActive(EPriorityStandard), iConsole(aConsole), iAddr(aAddr), iPort(aPort), iSize(aSize), iMode(aMode)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CTcpProcess::ConstructL()
+	{
+	//Create the data buffer
+	User::LeaveIfError(iSendBuf.Create(iSize));
+	User::LeaveIfError(iRecvBuf.Create(iSize));
+	iRecvSize = iSize;
+	
+	iProcessState = ECreateConnection;
+	
+	User::LeaveIfError(iSockServ.Connect());
+	if(iMode)
+		{
+		//Listen at specified port
+		TBuf<5>		 protocol = _L("tcp");
+		User::LeaveIfError(iListenSocket.Open(iSockServ, protocol));
+		User::LeaveIfError(iListenSocket.SetOpt(KSoReuseAddr, KProtocolInetIp, 1));
+		User::LeaveIfError(iListenSocket.SetLocalPort(iPort));
+		User::LeaveIfError(iListenSocket.Listen(5));
+		User::LeaveIfError(iSocket.Open(iSockServ));
+		iListenSocket.Accept(iSocket, iStatus);
+		iConsole.Printf(_L("\nWait for a connection at port[%d].\n"), iPort);
+		}
+	else
+		{
+        RConnection conn;  
+        User::LeaveIfError(conn.Open(iSockServ));
+        TCommDbConnPref pref;
+        pref.SetIapId(13);
+        pref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
+        User::LeaveIfError(conn.Start(pref));
+        
+		//Connect to specified server
+		User::LeaveIfError(iSocket.Open(iSockServ, KAfInet, KSockStream, KProtocolInetTcp, conn));
+		iSocket.Connect(iAddr, iStatus);
+
+		iConsole.Printf(_L("\nConnecting....\n"));
+		}
+	SetActive();
+	}
+
+
+void CTcpProcess::RunL()
+	{
+	switch(iProcessState)
+		{
+		case ECreateConnection:
+			//Get result of connect
+			if(iStatus.Int() != KErrNone)
+				{
+				iConsole.Printf(_L("Connect err[%d].\nPress any key to quit."), iStatus.Int());
+				return;
+				}
+			else
+				{
+				//A TCP connection is created.
+				if(iMode)
+					{
+					iConsole.Printf(_L("Get a connection.\n"));
+					}
+				else
+					{
+					iConsole.Printf(_L("\nConnected.\n"));					
+					}
+				iProcessState = EDataTransfer;
+
+				//Ready for read data
+				iSocket.RecvOneOrMore(iRecvBuf, 0, iStatus, iRecvSize);
+				__FLOG_STATIC1(KSubSys, KLogComponent , _L8("Ready for read data"), iRecvSize);
+				SetActive();
+				if(!iMode)
+					{
+					//As a client, send data first.
+					iSendBuf.SetLength(iSize);
+					iSendBuf.Repeat(KSendData());
+
+					iConsole.Printf(_L("Send data."));
+					PrintData(iSendBuf);
+					TInt sendLen = SendDataL(iSendBuf, iSize);
+					if(sendLen != iSize)
+						{
+						iConsole.Printf(_L("The length of data sent is not equal to requested! requested[%d], sent[%d]"),
+											iSize, sendLen);
+						}
+					}
+				}
+			break;
+
+		case EDataTransfer:
+			//In data transfer, some data is received
+			iConsole.Printf(_L("recv Package, size[%d], status[%d]\n"), iRecvSize(), iStatus.Int());
+			if((KErrEof == iStatus.Int()) || (KErrDisconnected == iStatus.Int()))
+				{
+				iConsole.Printf(_L("Connection closed!"));
+				return;
+				}
+			else if(KErrNone == iStatus.Int())
+				{
+				iConsole.Printf(_L("Receive data."));
+				PrintData(iRecvBuf);
+
+				if(iMode)
+					{
+					//As a server, send back the data received
+					TInt len = SendDataL(iRecvBuf, iRecvSize());
+					iConsole.Printf(_L("Send back the data. len[%d]"), len);
+					}
+				}	
+			iRecvBuf.SetLength(0);
+			iRecvSize = iSize;
+			iSocket.RecvOneOrMore(iRecvBuf, 0, iStatus, iRecvSize);
+			SetActive();	
+			
+			break;
+		}
+	}
+
+void CTcpProcess::DoCancel()
+	{
+	switch(iProcessState)
+		{
+		case ECreateConnection:
+			if(iMode)
+				{
+				iListenSocket.CancelAccept();
+				}
+			else
+				{
+				iSocket.CancelConnect();
+				}
+			break;
+		case EDataTransfer:
+			iSocket.CancelRecv();
+			break;
+		}
+	}
+
+TInt CTcpProcess::RunError(TInt aError)
+	{
+	User::Panic(_L("CTcpProcess"), aError);
+	return aError;
+	}
+
+TInt CTcpProcess::SendDataL(TDes8& aData, TInt aSize)
+/**
+Send data.
+  @return the size of data sent
+ */
+	{
+	TRequestStatus status;
+	TSockXfrLength sendSize = aSize;
+	iSocket.Send(aData, 0, status, sendSize);
+	User::WaitForRequest(status);
+	
+	switch(status.Int())
+		{
+		case KErrEof:
+			iConsole.Printf(_L("Connection closed!"));
+			return 0;		
+		case KErrNone:
+			iConsole.Printf(_L("Send successfully."));
+			break;
+		default:
+			User::LeaveIfError(status.Int());
+			break;
+		}
+	return sendSize();
+	}
+
+void CTcpProcess::PrintData(TDes8& aData)
+	{
+	iConsole.Printf(_L("The data is: \n"));
+	for(TInt i=0; i< aData.Length();i++)
+		{
+		iConsole.Printf(_L("%c"), aData[i]);
+		}
+	iConsole.Printf(_L("\n"));
+	}
+
+CUdpProcess* CUdpProcess::NewL(CConsoleBase& aConsole, TInetAddr& aAddr,
+        TInt aPort, TInt aSize, TBool aMode)
+    {
+    CUdpProcess* self = new (ELeave) CUdpProcess(aConsole, aAddr, aPort,
+            aSize, aMode);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+CUdpProcess::~CUdpProcess()
+    {
+    Cancel();
+    iRecvBuf.Close();
+    iSendBuf.Close();
+    iSocket.Close();
+    iListenSocket.Close();
+    iSockServ.Close();
+    }
+
+CUdpProcess::CUdpProcess(CConsoleBase& aConsole, TInetAddr& aAddr,
+        TInt aPort, TInt aSize, TBool aMode) :
+    CActive(EPriorityStandard), iConsole(aConsole), iAddr(aAddr),
+            iPort(aPort), iSize(aSize), iMode(aMode)
+    {
+    CActiveScheduler::Add(this);
+    }
+
+void CUdpProcess::ConstructL()
+    {
+    //Create the data buffer
+    User::LeaveIfError(iSendBuf.Create(iSize));
+    User::LeaveIfError(iRecvBuf.Create(iSize));
+    iRecvSize = iSize;
+
+    User::LeaveIfError(iSockServ.Connect());
+
+    // Start NCM IAP
+    RConnection conn;
+    User::LeaveIfError(conn.Open(iSockServ));
+    TCommDbConnPref pref;
+    pref.SetIapId(13);
+    pref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
+    User::LeaveIfError(conn.Start(pref));
+    
+    User::LeaveIfError(iSocket.Open(iSockServ, KAfInet, KSockDatagram,
+            KProtocolInetUdp, conn));
+    
+    iConsole.Printf(_L("In constructL, port=%d"), iAddr.Port());
+    
+    if (iMode)
+        {
+        iProcessState = EDataTransfer;
+       
+        User::LeaveIfError(iSocket.SetLocalPort(iPort));
+        iSocket.RecvFrom(iRecvBuf, iPeerAddr, 0, iStatus);
+        iConsole.Printf(_L("\nWait for UDP incoming data at port[%d]...\n"),iPort);
+        SetActive();
+        }
+    else 
+        {
+        iProcessState = EDataSending;
+        SetActive();
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete(status, KErrNone);
+        }
+    }
+
+
+void CUdpProcess::RunL()
+    {
+    __FLOG_STATIC0(KSubSys, KLogComponent , _L8("CUdpProcess::RunL"));
+    switch (iProcessState)
+        {
+        case EDataSending:
+            //As a client, send data first.
+            iSendBuf.SetLength(iSize);
+            iSendBuf.Repeat(KSendData());
+            iConsole.Printf(_L("Send data.."));
+            PrintData(iSendBuf);
+            iConsole.Printf(_L("In RunL, port=%d"), iAddr.Port());
+            TInt sendLen = SendDataL(iSendBuf, iAddr, iSize);
+            
+            if (sendLen != iSize)
+                {
+                iConsole.Printf(
+                        _L("The length of data sent is not equal to requested! requested[%d], sent[%d]"),
+                        iSize, sendLen);
+                }
+            break;
+
+        case EDataTransfer:
+            //In data transfer, some data is received
+            iConsole.Printf(_L("recv Package, size[%d], status[%d]\n"),
+                    iRecvSize(), iStatus.Int());
+            if (KErrNone == iStatus.Int())
+                {
+                iConsole.Printf(_L("Receive data."));
+                PrintData(iRecvBuf);
+
+                if (iMode)
+                    {
+                    //As a server, send back the data received
+                    TInt len = SendDataL(iRecvBuf, iPeerAddr, iRecvBuf.Length());
+                    iConsole.Printf(_L("Send back the data. len[%d]"), len);
+                    }
+                }
+            else
+                {
+                iConsole.Printf(_L("Something is wrong..."));
+                return;
+                }
+
+            iRecvBuf.SetLength(0);
+            iRecvSize = iSize;
+            //iListenSocket.RecvFrom(iRecvBuf, iPeerAddr, 0, iStatus);
+            iSocket.RecvFrom(iRecvBuf, iPeerAddr, 0, iStatus);
+            SetActive();
+            iConsole.Printf(_L("\nWait for UDP incoming data at port[%d]...\n"),iPort);
+            break;
+        }
+    }
+
+void CUdpProcess::DoCancel()
+{
+    switch(iProcessState)
+    {
+    case EDataTransfer:
+        //iListenSocket.CancelRecv();
+        iSocket.CancelRecv();
+        break;
+    }
+}
+
+TInt CUdpProcess::RunError(TInt aError)
+{
+    User::Panic(_L("CUdpProcess"), aError);
+    return aError;
+}
+
+TInt CUdpProcess::SendDataL(TDes8& aData, TInetAddr& aAddr, TInt aSize)
+    /**
+      Send data.
+      @return the size of data sent
+      */
+{
+    TRequestStatus status;
+    
+    TInt port = aAddr.Port();
+    iConsole.Printf(_L("Before sending, size = %d, port=%d\n"), aSize, port);
+    TSockXfrLength sendSize = 0; //aSize;
+    iSocket.SendTo(aData, aAddr, 0, status, sendSize);
+    User::WaitForRequest(status);
+    iConsole.Printf(_L("Sending result = %d, and sent=%d\n"), status.Int(), sendSize());
+
+    switch(status.Int())
+    {
+    case KErrEof:
+        iConsole.Printf(_L("Connection closed!"));
+        return 0;       
+    case KErrNone:
+        iConsole.Printf(_L("Send successfully.\n"));
+        break;
+    default:
+        User::LeaveIfError(status.Int());
+        break;
+    }
+    return sendSize();
+}
+
+void CUdpProcess::PrintData(TDes8& aData)
+{
+    iConsole.Printf(_L("The data is: \n"));
+    for(TInt i=0; i< aData.Length();i++)
+    {
+    iConsole.Printf(_L("%c"), aData[i]);
+    }
+    iConsole.Printf(_L("\n"));
+}
+
+
+
+CTcpTestConsole* CTcpTestConsole::NewL(TBool aIsTcp, TBool aMode, TDesC& aDefautAddr, TInt aIndex, CTcpCommand& aOwner)
+	{
+	CTcpTestConsole* self = new(ELeave) CTcpTestConsole(aIsTcp, aMode, aDefautAddr, aIndex, aOwner);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	
+	}
+
+CTcpTestConsole::CTcpTestConsole(TBool aIsTcp, TBool aMode, TDesC& aDefautAddr, TInt aIndex, CTcpCommand& aOwner) 
+	: CActive(EPriorityStandard),iCommandMode(ECommandInit),  iIsTcp(aIsTcp), iMode(aMode), 
+	  iDefaultAddr(aDefautAddr), iIndex(aIndex), iOwner(aOwner)
+	{	
+	CActiveScheduler::Add(this);
+	}
+
+CTcpTestConsole::~CTcpTestConsole()
+	{
+	Cancel();
+	delete iTcp;
+	delete iUdp;
+    delete iConsole;
+    iChars.Close();
+	}
+
+
+void CTcpTestConsole::ConstructL()
+	{
+	if(iMode)
+		{
+		iConsole = Console::NewL(KTcpServerMode(),TSize(KConsFullScreen,KConsFullScreen));
+		}
+	else
+		{
+		iConsole = Console::NewL(KTcpClientMode(),TSize(KConsFullScreen,KConsFullScreen));
+		}	
+	User::LeaveIfError(iChars.Create(KMaxNumOfChars));
+	//Generate the default value and display on screen, user can modify it if they want to use other value.
+	iChars.AppendFormat(_L("%S %d"), &iDefaultAddr, KDefaultDataSize);
+	Help();
+	//wait user input
+	iConsole->Read(iStatus);
+	SetActive();
+	}
+
+void CTcpTestConsole::Help()
+	{
+	iConsole->Printf(_L("Please change the parameters, then press enter\n"));
+	if(iMode)
+		{
+		iConsole->Printf(_L("   The parameters are port size \n"));
+		iConsole->Printf(_L("   port - The port of the Tcp/udp Server listen to \n"));
+		iConsole->Printf(_L("   size - the max package size \n"));
+		}
+	else
+		{
+		iConsole->Printf(_L("   The parameters are destAddr port size \n"));
+		iConsole->Printf(_L("   destAddr - The ip address of Tcp/udp Client connect to.\n"));
+		iConsole->Printf(_L("   port - The port of Tcp Client connect to \n"));
+		iConsole->Printf(_L("   size - the package size \n"));
+		}
+	//Display the default value
+	iConsole->Printf(_L("%S"), &iChars);
+		
+	}
+TBool CTcpTestConsole::StartL()
+	{
+	TLex args(iChars);
+	// args are separated by spaces
+	args.SkipSpace(); 
+	
+	TInetAddr addr;
+	TInt size;
+
+	if(!iMode)
+		{
+		//Get ip addr
+		TPtrC cmdAddr = args.NextToken();
+		if(!args.Eos())
+			{
+			if(KErrNone == addr.Input(cmdAddr))
+				{
+				args.Inc();
+				}
+			else
+				{
+				return EFalse;
+				}
+			}
+		else
+			{
+			return EFalse;
+			}
+		}
+	
+	//Get port
+	TInt port;
+	if(KErrNone != args.Val(port))
+		{
+		return EFalse;
+		}
+	addr.SetPort(port);
+
+	//Get pkg size
+	args.Inc();
+	if(KErrNone != args.Val(size))
+		{
+		return EFalse;
+		}
+	
+	iCommandMode = ECommandRunning;
+    if (iIsTcp)
+        {
+        iConsole->Printf(_L("Test for TCP...\n"));
+        iTcp = CTcpProcess::NewL(*iConsole, addr, port, size, iMode);
+        }
+    else
+        {
+        iConsole->Printf(_L("Test for UDP...\n"));
+        iUdp = CUdpProcess::NewL(*iConsole, addr, port, size, iMode);
+        }
+		
+	return ETrue;
+
+	}
+
+void CTcpTestConsole::DoCancel()
+	{
+	iConsole->ReadCancel();
+	}
+
+void CTcpTestConsole::RunL()
+	{
+	User::LeaveIfError(iStatus.Int());
+	switch(iCommandMode)
+		{
+		case ECommandInit:
+			{
+			TKeyCode code = iConsole->KeyCode();
+			switch(code)
+				{
+				case EKeyEnter:
+					{
+					//User input ok
+					if(!StartL())
+						{
+						Help();
+						}
+					}
+					break;
+				case EKeyEscape:
+					//connection has not been created. User want to cancel and quit
+					iOwner.CloseTcpTest(iIndex);
+					return;
+				case EKeyBackspace:
+					if(iChars.Length() > 0)
+						{
+						iConsole->SetCursorPosRel(TPoint(-1, 0));
+						iConsole->ClearToEndOfLine();
+						iChars.SetLength(iChars.Length()-1);
+						}
+					break;
+				default:
+					iChars.Append(code);
+					iConsole->Printf(_L("%c"), code);
+					break;
+				}
+			iConsole->Read(iStatus);
+			SetActive();
+			}
+			break;
+		case ECommandRunning:
+			//Connection has been created. User quit by press any key.
+			iOwner.CloseTcpTest(iIndex);
+			break;
+		}
+	}
+
+TInt CTcpTestConsole::RunError(TInt aError)
+	{
+	User::Panic(_L("CTcpTestConsole"), aError);
+	return aError;
+	}
+
+