diff -r d3e8e7d462dd -r f92a4f87e424 usbmgmt/usbmgrtest/t_ncm/src/tcptest.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usbmgmt/usbmgrtest/t_ncm/src/tcptest.cpp Tue Aug 31 17:01:47 2010 +0300 @@ -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 +#include +#include +#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; + } + +