// rsocket.cpp
//
// Copyright (c) 2009 - 2010 Accenture. All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the "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:
// Accenture - Initial contribution
//
#include <fshell/ioutils.h>
#include <es_sock.h>
#include <es_enum.h>
#include <in_sock.h>
#include <nifvar.h>
#include <commdbconnpref.h>
using namespace IoUtils;
class CCmdRsocket : public CCommandBase
{
public:
static CCommandBase* NewLC();
~CCmdRsocket();
private:
CCmdRsocket();
void StartConnectionL();
void TcpConnectL();
void TcpDisconnect();
private: // From CCommandBase.
virtual const TDesC& Name() const;
virtual void DoRunL();
virtual void ArgumentsL(RCommandArgumentList& aArguments);
virtual void OptionsL(RCommandOptionList& aOptions);
private:
RSocketServ iSocketSession;
RConnection iConnection;
RSocket iSocket;
enum
{
EConnect, EListen
} iOperation;
HBufC* iHost;
TUint iPort;
TUint iIapId;
TUint iNetworkId;
TBool iVerbose;
};
CCommandBase* CCmdRsocket::NewLC()
{
CCmdRsocket* self = new(ELeave) CCmdRsocket();
CleanupStack::PushL(self);
self->BaseConstructL();
return self;
}
CCmdRsocket::~CCmdRsocket()
{
delete iHost;
iSocket.Close();
iConnection.Close();
iSocketSession.Close();
}
CCmdRsocket::CCmdRsocket()
{
}
const TDesC& CCmdRsocket::Name() const
{
_LIT(KName, "rsocket");
return KName;
}
void CCmdRsocket::DoRunL()
{
LeaveIfErr(iSocketSession.Connect(), _L("Couldn't open socket server session"));
LeaveIfErr(iConnection.Open(iSocketSession), _L("Couldn't open connection handle"));
switch (iOperation)
{
case EConnect:
TcpConnectL();
break;
case EListen:
LeaveIfErr(KErrNotSupported, _L("Listen operation not yet implemented"));
break;
};
}
void CCmdRsocket::StartConnectionL()
{
if (iVerbose)
{
Write(_L("Starting RConnection...\r\n"));
}
TCommDbConnPref prefs;
if (iIapId > 0)
{
prefs.SetIapId(iIapId);
prefs.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
}
if (iNetworkId > 0)
{
prefs.SetNetId(iNetworkId);
}
LeaveIfErr(iConnection.Start(prefs), _L("Failed to start connection"));
}
void CCmdRsocket::TcpConnectL()
{
StartConnectionL();
TInetAddr addr(iPort);
TInt err = addr.Input(*iHost);
if (err)
{
if (iVerbose)
{
Write(_L("Resolving name...\r\n"));
}
RHostResolver resolver;
LeaveIfErr(resolver.Open(iSocketSession, KAfInet, KProtocolInetTcp, iConnection), _L("Unable to open host resolver"));
CleanupClosePushL(resolver);
TNameEntry nameEntry;
LeaveIfErr(resolver.GetByName(*iHost, nameEntry), _L("Unable to resolve name \"%S\""), iHost);
addr.SetAddress(TInetAddr::Cast(nameEntry().iAddr).Address());
CleanupStack::PopAndDestroy(&resolver);
}
if (iVerbose)
{
Write(_L("Opening socket...\r\n"));
}
LeaveIfErr(iSocket.Open(iSocketSession, KAfInet, KSockStream, KProtocolInetTcp, iConnection), _L("Unable to open TCP socket"));
if (iVerbose)
{
Write(_L("Connecting socket...\r\n"));
}
TRequestStatus status;
iSocket.Connect(addr, status);
User::WaitForRequest(status);
LeaveIfErr(status.Int(), _L("Unable to connect to %S : %u"), iHost, iPort);
TcpDisconnect();
}
void CCmdRsocket::TcpDisconnect()
{
if (iVerbose)
{
Write(_L("Shutting down socket...\r\n"));
}
TRequestStatus status;
iSocket.Shutdown(RSocket::ENormal, status);
User::WaitForRequest(status);
}
void CCmdRsocket::ArgumentsL(RCommandArgumentList& aArguments)
{
_LIT(KArgOperation, "operation");
aArguments.AppendEnumL((TInt&)iOperation, KArgOperation);
_LIT(KOptHost, "host");
aArguments.AppendStringL(iHost, KOptHost);
_LIT(KOptPort, "port");
aArguments.AppendUintL(iPort, KOptPort);
}
void CCmdRsocket::OptionsL(RCommandOptionList& aOptions)
{
_LIT(KOptVerbose, "verbose");
aOptions.AppendBoolL(iVerbose, KOptVerbose);
_LIT(KOptIapId, "iap");
aOptions.AppendUintL(iIapId, KOptIapId);
_LIT(KOptNetworkId, "network");
aOptions.AppendUintL(iNetworkId, KOptNetworkId);
}
EXE_BOILER_PLATE(CCmdRsocket)