/*
* Component Name: Headset Simulator
* Author: Comarch S.A.
* Version: 1.0
* Copyright (c) 2010 Comarch S.A.
*
* This Software is submitted by Comarch S.A. to Symbian Foundation Limited on
* the basis of the Member Contribution Agreement entered between Comarch S.A.
* and Symbian Foundation Limited on 5th June 2009 (“Agreement”) and may be
* used only in accordance with the terms and conditions of the Agreement.
* Any other usage, duplication or redistribution of this Software is not
* allowed without written permission of Comarch S.A.
*
*/
#include "hsclient.h"
#include "hsclientobservers.h"
#include "debug.h"
CHsClient* CHsClient::NewL( CBluetoothSocket *aClient,
MHsClientStateNotifier *aClientStateNotifier,
MHsClientObserver *aClientDisconnectNotifier )
{
User::LeaveIfNull( aClient );
CHsClient *self = CHsClient::NewLC( aClient, aClientStateNotifier,
aClientDisconnectNotifier );
CleanupStack::Pop( self );
return self;
}
CHsClient* CHsClient::NewLC( CBluetoothSocket *aClient,
MHsClientStateNotifier *aClientStateNotifier,
MHsClientObserver *aClientDisconnectNotifier )
{
User::LeaveIfNull( aClient );
CHsClient *self = new ( ELeave ) CHsClient( *aClient, aClientStateNotifier,
aClientDisconnectNotifier );
CleanupStack::PushL( self );
self->ConstructL();
return self;
}
CHsClient::~CHsClient()
{
TRACE_FUNC_ENTRY
if ( iSocket )
{
iSocket->CancelAll();
delete iSocket;
}
if ( iConnected )
{
if ( iStateNotifier )
{
TRAP_IGNORE( iStateNotifier->HandleClientDisconnectL(KErrNone) );
}
}
TRACE_FUNC_EXIT
}
void CHsClient::Send( const TDesC8 &aData )
{
TRACE_FUNC_ENTRY
if ( iSocket && iConnected )
{
TRAP_IGNORE( BufferedProcessL(aData) );
}
TRACE_FUNC_EXIT
}
void CHsClient::SetClientDisconnectNotfier( MHsClientObserver &aNotifier )
{
TRACE_FUNC_ENTRY
iClientObserver = &aNotifier;
TRACE_FUNC_EXIT
}
void CHsClient::SetClientStateNotfier( MHsClientStateNotifier &aNotifier )
{
TRACE_FUNC_ENTRY
iStateNotifier = &aNotifier;
TRACE_FUNC_EXIT
}
MHsClientStateNotifier* CHsClient::GetClientStateNotifer()
{
TRACE_FUNC_ENTRY
TRACE_FUNC_EXIT
return iStateNotifier;
}
CHsClient::CHsClient( CBluetoothSocket &aClient,
MHsClientStateNotifier *aClientStateNotifier,
MHsClientObserver *aClientDisconnectNotifier )
{
TRACE_FUNC_ENTRY
iSocket = &aClient;
iStateNotifier = aClientStateNotifier;
iState = CHsClient::EIdle;
iConnected = ETrue;
iClientObserver = aClientDisconnectNotifier;
iSocket->SetNotifier( *this );
TRACE_FUNC_EXIT
}
void CHsClient::ConstructL()
{
TRACE_FUNC_ENTRY
BufferedProcessL();
TRACE_FUNC_EXIT
}
void CHsClient::RawRecvL( TDes8 &aData )
{
TRACE_FUNC_ENTRY
User::LeaveIfNull( iSocket );
if ( !iConnected )
{
TRACE_INFO( _L(" Client is no longer connected" ) )
User::LeaveIfError( KErrDisconnected );
}
iState = CHsClient::EReceiving;
User::LeaveIfError( iSocket->RecvOneOrMore( aData, iReceiveFlag,
iReceiveMessageLength ) );
TRACE_FUNC_EXIT
}
void CHsClient::RawSendL( const TDesC8 &aData )
{
TRACE_FUNC_ENTRY
User::LeaveIfNull( iSocket );
if ( !iConnected )
{
User::LeaveIfError( KErrDisconnected );
}
if ( aData.Length() == 0 )
{
User::Leave( KErrWrite );
}
iState = CHsClient::ESending;
User::LeaveIfError( iSocket->Send( aData, iSendFlag ) );
TRACE_FUNC_EXIT
}
void CHsClient::BufferedProcessL( const TDesC8 &aData )
{
TRACE_FUNC_ENTRY
if ( iState != CHsClient::ESending )
{
iTempSendBuf.Append( aData );
SwapBuffers();
if ( iSendBuf.Length() > 0 )
{
iSocket->CancelRecv();
RawSendL( iSendBuf );
}
else if ( iState != CHsClient::ESending )
{
RawRecvL( iReceiveMessageBuffer );
}
}
else
{
iTempSendBuf.Append( aData );
}
TRACE_FUNC_EXIT
}
void CHsClient::SwapBuffers()
{
TRACE_FUNC_ENTRY
iSendBuf.Copy( iTempSendBuf );
iTempSendBuf.Zero();
TRACE_FUNC_EXIT
}
void CHsClient::HandleConnectCompleteL( TInt aErr )
{
TRACE_FUNC_ENTRY
TRACE_INFO( ( _L("aErr = %d"), aErr) )
TRACE_FUNC_EXIT
}
void CHsClient::HandleAcceptCompleteL( TInt aErr )
{
TRACE_FUNC_ENTRY
TRACE_INFO( ( _L("aErr = %d"), aErr) )
TRACE_FUNC_EXIT
}
void CHsClient::HandleShutdownCompleteL( TInt aErr )
{
TRACE_FUNC_ENTRY
TRACE_INFO( ( _L("aErr = %d"), aErr) )
TRACE_FUNC_EXIT
}
void CHsClient::HandleSendCompleteL( TInt aErr )
{
TRACE_FUNC_ENTRY
TRACE_INFO( ( _L("aErr = %d"), aErr) )
iState = CHsClient::EIdle;
iSendBuf.Zero();
if ( aErr != KErrDisconnected )
{
BufferedProcessL( KNullDesC8 );
}
if ( iStateNotifier )
{
if ( aErr != KErrDisconnected )
{
iStateNotifier->HandleClientSendCompleteL( aErr );
}
else
{
iConnected = EFalse;
iStateNotifier->HandleClientDisconnectL( aErr );
iClientObserver->HandleClientDisconnect( this, aErr );
}
}
TRACE_FUNC_EXIT
}
void CHsClient::HandleReceiveCompleteL( TInt aErr )
{
TRACE_FUNC_ENTRY
TRACE_INFO( ( _L("aErr = %d"), aErr) )
iState = CHsClient::EIdle;
if ( iStateNotifier )
{
if ( aErr == KErrNone )
{
TRAP_IGNORE( iStateNotifier->HandleClientReceiveCompleteL(
iReceiveMessageBuffer, aErr ) );
}
else
{
iConnected = EFalse;
iStateNotifier->HandleClientDisconnectL( aErr );
iClientObserver->HandleClientDisconnect( this, aErr );
}
}
if ( aErr == KErrNone )
{
BufferedProcessL( KNullDesC8 );
}
TRACE_FUNC_EXIT
}
void CHsClient::HandleIoctlCompleteL( TInt aErr )
{
TRACE_FUNC_ENTRY
TRACE_INFO( ( _L("aErr = %d"), aErr) );
TRACE_FUNC_EXIT
}
void CHsClient::HandleActivateBasebandEventNotifierCompleteL( TInt aErr,
TBTBasebandEventNotification& aEventNotification )
{
TRACE_FUNC_ENTRY
TRACE_INFO( ( _L("aErr = %d"), aErr) );
TRACE_FUNC_EXIT
}