// Copyright (c) 1997-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:
// This file contains the implementation of the CSimNtRas class.
//
//
/**
@file
*/
#include "CSimNtras.h"
#include "Simlog.h"
_LIT8(KNtRasWriteText,"CLIENT"); // < Solicitation text, send to start the NTRas server
_LIT8(KNtRasReceiveText,"SERVER"); // < NTRas server response, indicating the PPP session can commence.
const TInt KNtRasServerResponseTimeout=5; // < Connection attempt time out value in seconds.
const TDataBits KDefaultDataBits=EData8; // < Default configuration is 8N1
const TParity KDefaultParity=EParityNone; // < Default configuration is 8N1
const TStopBits KDefaultStopBits=EStop1; // < Default configuration is 8N1
const TText8 KDefaultXon=17; // < Default XON character is <ctrl>Q
const TText8 KDefaultXoff=19; // < Default XOFF character is <ctrl>S
const TInt KTxMaxRetries=3; // < Maximum number of transmit retries before giving up
CSimNtRas* CSimNtRas::NewL(CSimPhone* aPhone)
/**
* Standard two phase constructor.
*/
{
CSimNtRas* self=new(ELeave) CSimNtRas(aPhone);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop();
return self;
}
CSimNtRas::CSimNtRas(CSimPhone* aPhone)
: iPhone(aPhone), iPortOpen(EFalse)
/**
* Trivial first phase constructor.
*/
{
}
void CSimNtRas::ConstructL()
/**
* Second phase constructor. Create heap-based objects, in this instance the timer
* and the Comm Port classes.
*/
{
iTimer=CSimTimer::NewL(iPhone);
CommConstructL(CActive::EPriorityStandard,CActive::EPriorityStandard);
}
CSimNtRas::~CSimNtRas()
/**
* Standard destructor. Close Comm Port and destroy heap-based objects.
*/
{
if(iPortOpen)
{
CommCancel();
CommClose();
}
delete iTimer;
}
TInt CSimNtRas::Connect(const TDesC& aCsyName, const TDesC& aPort,
const TCommConfigV01& aConfig, MNTRasCallBack* aCallback)
/**
* Attempt to connect to an NT Ras "Cable Connection" service.
* @param aCsyName The CSY to be used for the connection.
* @param aPort The Port to be used for the connection.
* @param aConfig The port configuration to be used for the connection.
* @param aCallback The callback class that must be signalled when the connection completes.
* @return TInt Standard error value.
*/
{
LOGDATA1("Starting to attempt a NT RAS Connection");
iReadBuf.Zero();
iInputBuf.Zero();
// Open and configuration the port
TInt ret=CommOpen(aCsyName,aPort,ECommShared);
if(ret!=KErrNone)
return ret;
iPortOpen=ETrue;
TCommConfig configPckg;
TCommConfigV01& config=configPckg();
iCommPort.Config(configPckg);
config.iDataBits=KDefaultDataBits;
config.iParity=KDefaultParity;
config.iStopBits=KDefaultStopBits;
config.iXonChar=KDefaultXon;
config.iXoffChar=KDefaultXoff;
config.iTerminatorCount=0;
config.iSpecialRate=0;
config.iRate=aConfig.iRate;
config.iHandshake=aConfig.iHandshake;
ret=iCommPort.SetConfig(configPckg);
if(ret!=KErrNone)
return ret;
// Power up the port ready for receives and transmits
CommReadReady();
CommWriteReady();
iAttemptCnt=0;
iCallback=aCallback;
CommReadOneOrMore(iReadBuf);
AttemptConnect();
return KErrNone;
}
void CSimNtRas::AttemptConnect()
/**
* Transmit "CLIENT" and attempt a connection
*/
{
LOGDATA1("NTRAS Writing CLIENT...");
iAttemptCnt++;
// Send the soliciting message, and await the NT Ras server's response.
CommWrite(KNtRasWriteText);
iTimer->Start(KNtRasServerResponseTimeout,this);
}
void CSimNtRas::Cancel()
/**
* Cancel any outstanding comm port reads, writes or timer requests.
*/
{
iTimer->Cancel();
CommCancel();
}
void CSimNtRas::Terminate()
/**
* Terminate the NTRas connection. If opened, cancel any outstanding requests and close
* the port. Also, cancel any outstanding timer request.
*/
{
if(iPortOpen)
{
CommCancel();
CommClose();
}
iTimer->Cancel();
}
void CSimNtRas::CommReadComplete(TInt aStatus)
/**
* Serial port read completion callback. If there's no read error, append the read
* data to the input buffer and scan for the server's response.
* If no match is found, re-post the read.
* @param aStatus Standard error value, indicating the result of the read request.
*/
{
LOGDATA2("NTRAS Rx Completion: %S",&iInputBuf);
if(aStatus!=KErrNone)
{
iTimer->Cancel();
iCallback->NTRasCallBack(aStatus);
return;
}
if((iInputBuf.Length()+iReadBuf.Length())>KInputBufferSize)
{
iTimer->Cancel();
iCallback->NTRasCallBack(KErrNotFound);
return;
}
iInputBuf.Append(iReadBuf);
TInt pos=iInputBuf.FindF(KNtRasReceiveText);
if(pos>=0)
{
iTimer->Cancel();
iCallback->NTRasCallBack(KErrNone);
LOGDATA1("NTRAS Received SERVER!");
return;
}
CommReadOneOrMore(iReadBuf);
}
void CSimNtRas::CommWriteComplete(TInt aStatus)
/**
* Serial port write completion callback. Terminate the connection attempt if an error
* has occurred.
*/
{
LOGDATA1("NTRAS Write Completion");
if(aStatus!=KErrNone)
{
iTimer->Cancel();
iCallback->NTRasCallBack(aStatus);
}
}
void CSimNtRas::TimerCallBack(TInt /*aId*/)
/**
* Timer expired callback. Give up the attempted connection with a time-out error.
*/
{
LOGDATA1("NTRAS Timeout Occurred");
CommWriteCancel();
if(iAttemptCnt<KTxMaxRetries)
AttemptConnect();
else
{
CommReadCancel();
iCallback->NTRasCallBack(KErrTimedOut);
}
}