ImagePrint/ImagePrintEngine/DeviceProtocols/btprotocol/src/cbtchannelbase.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:30:38 +0100
branchRCL_3
changeset 21 d59c248c9d36
parent 0 d11fb78c4374
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201031 Kit: 201035

/*
* Copyright (c) 2004-2007 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:  Defines the CBtChannelBase class.
*
*/


#include <obex.h>

#include "crsbtdevice.h"
#include "cbtchannelbase.h"
#include "cbtsoapcodec.h"
#include "clog.h"
#include "tbtmapper.h"
#include "cbtdiscover.h"
#include "printmessagecodes.h"
#include "rsutils.h"

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::CBtChannelBase
//
//--------------------------------------------------------------------------------------------
CBtChannelBase::CBtChannelBase(MBtPCObserver& aObs):
	CActive(CActive::EPriorityStandard),
	iObs( aObs ),
	iState( EStateNone ),
	iJobId( KErrNotFound ),
	iChannel( NULL ),
	iSoapCodec( NULL ),
	iObexBufObject( NULL ),
	iObexNullObject( NULL ),
	iObexBody( NULL ),
	iDevice( NULL ),
	iWait( NULL ),
	iResponseError(KErrNone),
	iStop(EFalse)
{
	LOG("[CBtChannelBase::CBtChannelBase]\t");
	CActiveScheduler::Add(this);
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::~CBtChannelBase
//
//--------------------------------------------------------------------------------------------
CBtChannelBase::~CBtChannelBase()
{
	LOG("[CBtChannelBase::~CBtChannelBase]\t");

	if(iWait)
	{
		StopWaiting();
		delete iWait;
	}

	ClearConnection();

	if(iSoapCodec)
		delete iSoapCodec;

	if(iObexNullObject)
		delete iObexNullObject;

	if(iObexBufObject)
		delete iObexBufObject;

	if(iObexBody)
		delete iObexBody;

	if(iChannel)
	{
		delete iChannel;
		iChannel = NULL;
	}
	if (iPasswordQuery)
	{
		delete iPasswordQuery;
		iPasswordQuery = NULL;
	}
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::ConstructL
//
//--------------------------------------------------------------------------------------------
void CBtChannelBase::ConstructL()
{
	LOG("[CBtChannelBase::ConstructL]\t begin");

	iWait = new (ELeave) CActiveSchedulerWait;

	LOG("[CBtChannelBase::ConstructL]\t iSoapCodec");
	iSoapCodec = CBtSoapCodec::NewL();

	// Create obex objects here: do not NEVER delete them but in destructor
	iObexBody = CBufFlat::NewL(8);
	iObexBufObject = CObexBufObject::NewL(iObexBody);
	iObexNullObject = CObexNullObject::NewL();
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::SetDevice
//
//--------------------------------------------------------------------------------------------
void CBtChannelBase::SetJobId( TInt aId )
{
	iJobId = aId;
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::Device
//
//--------------------------------------------------------------------------------------------
TInt CBtChannelBase::JobId() const
{
	return iJobId;
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::SetDevice
//
//--------------------------------------------------------------------------------------------
void CBtChannelBase::SetDevice( CRsBtDevice& aDevice )
{
	iDevice = &aDevice;
	LOG1("[CBtChannelBase::SetDevice]\t iDevice %d", iDevice);
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::Device
//
//--------------------------------------------------------------------------------------------
const CRsBtDevice& CBtChannelBase::Device() const
{
	return *iDevice;
}


//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::StartL
//
//--------------------------------------------------------------------------------------------
void CBtChannelBase::StartL( CRsBtDevice& aDevice )
{
	LOG1("[CBtChannelBase::StartL]\t state %d", iState);

	User::LeaveIfNull(&aDevice);
	
	Stop();

	iStop = EFalse;

	TBool btOn = RsUtils::IsBluetoothOn();
	LOG1("[CBtChannelBase::StartL]\t btOn: %d", btOn);
	if( !btOn )
		User::Leave( EObexConnectError );

	SetDevice( aDevice );
	iState = EStateNone;
	ConnectL();
	WaitL();

	LOG("[CBtChannelBase::StartL]\t out");
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::Stop
//
//--------------------------------------------------------------------------------------------
void CBtChannelBase::Stop()
{
	LOG("[CBtChannelBase::Stop]\t");

	iStop = ETrue;

	if( IsActive() )
	{
		Cancel();
	}
	else
		StopWaiting();
	
	ClearConnection();
	LOG("[CBtChannelBase::Stop]\t out");
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::DoCancel
//
//--------------------------------------------------------------------------------------------
void CBtChannelBase::DoCancel()
{
	LOG("[CBtChannelBase::DoCancel]\t");

	StopWaiting();
	
	LOG1("[CBtChannelBase::DoCancel]\t iChannel %d", iChannel);
	if(iChannel)
	{
		LOG1("[CBtChannelBase::DoCancel]\t iStatus.Int(): 0x%X", iStatus.Int());
		if(KRequestPending == iStatus.Int())
		{
			DeleteChannel();
		}
	}
	
	LOG1("[CBtChannelBase::DoCancel]\t out iStatus 0x%X", iStatus.Int());
}

//------------------------------
// InCalls
//------------------------------

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::IsConnected
//
//--------------------------------------------------------------------------------------------
TBool CBtChannelBase::IsConnected()
{
	TBool connected = EFalse;

	if(iChannel && iChannel->IsConnected())
	{
		connected = ETrue;
	}

	LOG2("[CBtChannelBase::IsConnected]\t iChannel: %d, connected: %d", iChannel, connected);

	return connected;
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::Disconnect
//
//--------------------------------------------------------------------------------------------
void CBtChannelBase::Disconnect()
{
	TBool conn = IsConnected();
	LOG1("[CBtChannelBase::Disconnect]\t IsConnected(): %d", conn);
	
	if( conn )
	{
		if(IsActive())
		{
			LOG("[CBtChannelBase::Disconnect]\t iChannel abort");
			iChannel->Abort();
		}
		else
		{
			LOG("[CBtChannelBase::Disconnect]\t iChannel disconnect");
			iState = EStateDisconnecting;
			iChannel->Disconnect(iStatus);
			Activate();
		}
		iStop = ETrue;
	}
	else
	{
		DeleteChannel();
		iState = EStateNone;
	}

	LOG1("[CBtChannelBase::Disconnect]\t out. iState: %d", iState);
	return;
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::FinishPrinting
//
//--------------------------------------------------------------------------------------------
void CBtChannelBase::FinishPrinting()
{
	LOG("[CBtChannelBase::FinishPrintingL]\t begin");

	// Already finishing
	if(EStateFinish == iState)
	{
		LOG("[CBtChannelBase::FinishPrintingL]\t already finishing");
		return;
	}

	iState = EStateDisconnecting;

	LOG1("[CBtChannelBase::FinishPrintingL]\t IsActive() %d", IsActive());
	if(IsActive())
	{
		//return: the iState causes disconnection printing when RunL called.
		return;
	}

	IsConnected();
		Disconnect();

	LOG("[CBtChannelBase::FinishPrintingL]\t end");
    return;
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::SendSoapRequestL
//
//--------------------------------------------------------------------------------------------
void CBtChannelBase::SendSoapRequestL(const TInt aRequest, const TInt aJobId)
{
	SendSoapRequestL(aRequest, iStatus, aJobId);
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::SendSoapRequestL
//
//--------------------------------------------------------------------------------------------
void CBtChannelBase::SendSoapRequestL(const TInt aRequest,
								  TRequestStatus& aStatus,
								  const TInt aJobId)
{
	LOG1("[CBtChannelBase::SendSoapRequestL]\t begin for %d", aRequest);
	User::LeaveIfNull(iChannel);
	User::LeaveIfNull(iObexBufObject); // panics if iObexBody == NULL

	/* Create soap from file */
	if(!iSoapCodec)
	{
		iSoapCodec = CBtSoapCodec::NewL();
	}
    TPtrC8 soap = iSoapCodec->CreateSoapL(aRequest, aJobId);

	LOG2("[CBtChannelBase::SendSoapRequestL]\t Soap created for %d. len: %d",aRequest, soap.Length());

	iObexBufObject->Reset();

	iObexBody->InsertL(0, soap);
	LOG1("[CBtChannelBase::SendSoapRequestL]\t data size %d", iObexBody->Size());

	iObexBufObject->SetTypeL(KBtMimeTypeSoap());

	LOG("[CBtChannelBase::SendSoapRequestL]\t Issuing get.");
	iChannel->Get(*iObexBufObject, aStatus);

	Activate();
	LOG("[CBtChannelBase::SendSoapRequestL]\t end");
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::GetSoapResponseL
//
//--------------------------------------------------------------------------------------------
TInt CBtChannelBase::GetSoapResponseL()
{
	LOG("[CBtChannelBase::GetSoapResponseL]\t");

	if( 0 >= iObexBody->Size() )
		User::Leave(KErrInvalidData);

	LOG("[CBtChannelBase::GetSoapResponseL]\t Data in obex body.");
	LOG1("[CBtChannelBase::GetSoapResponseL]\t iDevice: %d", iDevice);
	TInt action = EBtUnknownAction;

	//give obexbody to parser
	if(!iSoapCodec)
	{
		iSoapCodec = CBtSoapCodec::NewL();
	}

   	//read
	iSoapCodec->ReadSoapL(action, *iObexBody);
	LOG1("[CBtChannelBase::GetSoapResponseL]\t soap read. Action %d", action);

	// Reset object: data is stored in iSoapCodec.
	// NOTE: reset resets also iObexBody
	iObexBufObject->Reset();

	LOG("[CBtChannelBase::GetSoapResponseL]\t done");
	return action;
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::Activate
//
//--------------------------------------------------------------------------------------------
void CBtChannelBase::Activate()
{
	// If already active do not activate again
	LOG2("[CBtChannelBase::Activate]\t for %d, IsActive %d",iState, IsActive());
	if( IsActive() )
		return;

	SetActive();
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::CompleteRequest
//
//--------------------------------------------------------------------------------------------
void CBtChannelBase::CompleteRequest(TControlState aStateCompleted, TInt aError)
{
	LOG2("[CBtChannelBase::CompleteRequest]\t aStateCompleted %d, aError %d",aStateCompleted, aError);
	iState = aStateCompleted;

	LOG2("[CBtChannelBase::CompleteRequest]\t IsActive() %d, iStatus %d", IsActive(), iStatus.Int());
	if(IsActive() && KRequestPending == iStatus.Int())
	{
		TRequestStatus* statusPtr = &iStatus;
		User::RequestComplete(statusPtr, aError);
	}
	if(EStateNone != aStateCompleted)
	{
		Activate();
	}
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::StartWaiting
//
//--------------------------------------------------------------------------------------------
void CBtChannelBase::WaitL()
{
	if( !(iWait->IsStarted()) && KRequestPending == iStatus.Int())
	{
		LOG("[CBtChannelBase::WaitL]\t");
		iWait->Start();

		LOG2("[CBtChannelBase::WaitL]\t Continue, iStatus: %d at iState: %d", iStatus.Int(), iState);
		LOG1("[CBtChannelBase::WaitL]\t iStop: %d",iStop);
		if(KErrNone != iStatus.Int() && KRequestPending != iStatus.Int() && !iStop)
			User::Leave(iStatus.Int());
		LOG("[CBtChannelBase::WaitL]\t out");
	}
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::StopWaiting
//
//--------------------------------------------------------------------------------------------
void CBtChannelBase::StopWaiting()
{
	if( (iWait->IsStarted()) )
	{
		LOG("[CBtChannelBase::StopWaiting]\t");
		iWait->AsyncStop();
	}
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::ClearConnection
//
//--------------------------------------------------------------------------------------------
void CBtChannelBase::ClearConnection()
{
	LOG1("[CBtChannelBase::ClearConnection]\t iState %d", iState);

	Cancel();

	iObexBufObject->Reset();
	iObexNullObject->Reset();
	iDevice = NULL;

    if(iChannel)
    {
		LOG("[CBtChannelBase::ClearConnection]\t iChannel clear");
		//Sends the abort operation to receiver and completes request with KErrAbort
		Disconnect();	
    }
	LOG("[CBtChannelBase::ClearConnection]\t out");
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::DeleteChannel
//
//--------------------------------------------------------------------------------------------
void CBtChannelBase::DeleteChannel()
{
	LOG1("[CBtChannelBase::DeleteChannel]\t iChannel %d delete", iChannel);
    if(iChannel)
    {
		delete iChannel;
		iChannel = NULL;
    }
	iStop = EFalse;

	LOG1("[CBtChannelBase::DeleteChannel]\t iChannel %d out", iChannel);
}

//--------------------------------------------------------------------------------------------
//
// CBtChannelBase::GetUserPasswordL
//
//--------------------------------------------------------------------------------------------

void CBtChannelBase::GetUserPasswordL( const TDesC &aRealm )
{
    LOG("[CBtChannelBase::GetUserPasswordL begin]\t");

    iPasswordQuery = CBtPasswordQuery::NewL( *this );
    
    iPasswordQuery->StartActiveObjectL();
  
    LOG("[CBtChannelBase::GetUserPasswordL end]\t");
}

void CBtChannelBase::PasswordQueryCompleteL ( TObexPasskeyBuf aResultPckg )
	{     
	    iPckg = aResultPckg(); 
	    
	    TBuf<256> data;
	    data.Copy(iPckg);
	    
	    // Send user password
	    iChannel->UserPasswordL(data);
	}

//  End of File