--- a/localconnectivityservice/dun/plugins/src/bt/DunBtListen.cpp Thu Aug 19 10:46:39 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,464 +0,0 @@
-/*
-* Copyright (c) 2006-2008 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: DUN Bluetooth plugin's listener
-*
-*/
-
-
-#include <btsdp.h>
-#include <e32std.h>
-#include <bt_sock.h>
-#include <btengdiscovery.h>
-#include "DunPlugin.h"
-#include "DunBtListen.h"
-#include "DunBtPlugin.h"
-#include "DunDebug.h"
-
-const TInt KListenQueSize = 1;
-const TInt KDunFixedChannel = 22; // Hack/kludge for Apple Bug ID 6527598
-
-//Service Class Bits supported by DUN
-static const TUint16 KCoDDunServiceClass = EMajorServiceTelephony | EMajorServiceNetworking;
-
-// ======== MEMBER FUNCTIONS ========
-
-// ---------------------------------------------------------------------------
-// Two-phased constructor.
-// ---------------------------------------------------------------------------
-//
-CDunBtListen* CDunBtListen::NewL( MDunServerCallback* aServer,
- MDunListenCallback* aParent,
- CDunTransporter* aTransporter,
- TBtPortEntity& aEntity )
- {
- CDunBtListen* self = new (ELeave) CDunBtListen( aServer,
- aParent,
- aTransporter,
- aEntity );
- CleanupStack::PushL( self );
- self->ConstructL();
- CleanupStack::Pop( self );
- return self;
- }
-
-// ---------------------------------------------------------------------------
-// Destructor.
-// ---------------------------------------------------------------------------
-//
-CDunBtListen::~CDunBtListen()
- {
- FTRACE(FPrint( _L("CDunBtListen::~CDunBtListen()") ));
- ResetData();
- FTRACE(FPrint( _L("CDunBtListen::~CDunBtListen() complete") ));
- }
-
-// ---------------------------------------------------------------------------
-// Resets data to initial values
-// ---------------------------------------------------------------------------
-//
-void CDunBtListen::ResetData()
- {
- // APIs affecting this:
- // IssueRequestL()
- Stop();
- StopServiceAdvertisement();
- // NewL()
- iTransporter->FreeAdvertisementMonitor( KDunBtPluginUid, this );
- delete iDiscovery;
- iDiscovery = NULL;
- if ( iSockServer.Handle() != KNullHandle )
- {
- iSockServer.Close();
- }
- // Internal
- Initialize();
- }
-
-// ---------------------------------------------------------------------------
-// Registers itself to SDP and BT manager, opens a socket
-// and starts to listen it.
-// ---------------------------------------------------------------------------
-//
-void CDunBtListen::IssueRequestL()
- {
- FTRACE(FPrint( _L( "CDunBtListen::IssueRequestL()" ) ));
-
- if ( iListenState == EBtListenStateListening )
- {
- FTRACE(FPrint( _L( "CDunBtListen::IssueRequestL() (already active) complete" ) ));
- User::Leave( KErrNotReady );
- }
-
- TBool advertise = iTransporter->AdvertisementStatus();
- if ( !advertise )
- {
- // Return silently here as CDunTransporter will notify later
- return;
- }
-
- TBool inUse = EFalse;
- TInt numOfChans = 0;
- TInt retTemp = StartServiceAdvertisement( inUse );
- if ( retTemp != KErrNone )
- {
- if ( inUse )
- {
- numOfChans = iTransporter->GetNumberOfAllocatedChannelsByUid(
- KDunBtPluginUid );
- if ( numOfChans == 0)
- {
- // No channels so parent can't reissue requests of this object
- // This is fatal case -> leave.
- // NOTE: To add full support for this case a poller (timer) is
- // needed that polls for free RFCOMM channel by given interval.
- User::Leave( retTemp );
- }
- // If in use and parent has channels then just fail silently.
- // Let this object to wait until parent finds new resources.
- FTRACE(FPrint( _L( "CDunBtListen::IssueRequestL() complete" ) ));
- return;
- }
- FTRACE(FPrint( _L( "CDunBtListen::IssueRequestL() (failed!) complete" ) ));
- User::Leave( retTemp );
- }
-
- // Not already active here so start listening
- // First open blank data socket
- retTemp = iEntity.iBTPort.Open( iSockServer );
- if ( retTemp != KErrNone )
- {
- FTRACE(FPrint( _L( "CDunBtListen::IssueRequestL() (ERROR) complete (%d)" ), retTemp));
- User::Leave( retTemp );
- }
- iStatus = KRequestPending;
- iListenSocket.Accept( iEntity.iBTPort, iStatus );
- SetActive();
- iListenState = EBtListenStateListening;
-
- FTRACE(FPrint( _L( "CDunBtListen::IssueRequestL() complete") ));
- }
-
-// ---------------------------------------------------------------------------
-// Stops listening
-// ---------------------------------------------------------------------------
-//
-TInt CDunBtListen::Stop()
- {
- FTRACE(FPrint( _L( "CDunBtListen::Stop()") ));
- if ( iListenState != EBtListenStateListening )
- {
- FTRACE(FPrint( _L("CDunBtListen::Stop() (not ready) complete" )));
- return KErrNotReady;
- }
- iListenSocket.CancelAccept();
- Cancel();
- iListenState = EBtListenStateIdle;
- FTRACE(FPrint( _L( "CDunBtListen::Stop() complete") ));
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CDunBtListen::CDunBtListen
-// ---------------------------------------------------------------------------
-//
-CDunBtListen::CDunBtListen( MDunServerCallback* aServer,
- MDunListenCallback* aParent,
- CDunTransporter* aTransporter,
- TBtPortEntity& aEntity ) :
- CActive( EPriorityStandard ),
- iServer( aServer ),
- iParent( aParent ),
- iTransporter( aTransporter ),
- iEntity( aEntity )
- {
- Initialize();
- }
-
-// ---------------------------------------------------------------------------
-// CDunBtListen::ConstructL
-// ---------------------------------------------------------------------------
-//
-void CDunBtListen::ConstructL()
- {
- FTRACE(FPrint(_L("CDunBtListen::ConstructL()")));
- if ( !iServer || !iParent || !iTransporter )
- {
- User::Leave( KErrGeneral );
- }
-
- CBTEngDiscovery* discovery = CBTEngDiscovery::NewLC();
- FTRACE(FPrint(_L("CDunBtListen::ConstructL: iSockServer.Connect")));
- User::LeaveIfError( iSockServer.Connect() );
-
- // Set advertisement monitor
- iTransporter->SetAdvertisementMonitorL( KDunBtPluginUid, this );
-
- // Then we are ready to start listening and accepting incoming connection
- // requests.
- CleanupStack::Pop( discovery );
- iDiscovery = discovery;
- CActiveScheduler::Add( this );
- FTRACE(FPrint(_L("CDunBtListen::ConstructL() complete")));
- }
-
-// ---------------------------------------------------------------------------
-// Initializes this class
-// ---------------------------------------------------------------------------
-//
-void CDunBtListen::Initialize()
- {
- // Don't initialize iServer here (it is set through NewL)
- // Don't initialize iParent here (it is set through NewL)
- // Don't initialize iTransporter here (it is set through NewL)
- // Don't initialize iEntity here (it is set through NewL)
- iListenState = EBtListenStateIdle;
- iDiscovery = NULL;
- iChannelNum = 0;
- iSDPHandleDun = 0;
- }
-
-// ---------------------------------------------------------------------------
-// Starts dialup service advertisement
-// ---------------------------------------------------------------------------
-//
-TInt CDunBtListen::StartServiceAdvertisement( TBool& aInUse )
- {
- FTRACE(FPrint( _L( "CDunBtListen::StartServiceAdvertisement()" ) ));
-
- TInt retTemp = ReserveLocalChannel( iSockServer,
- iListenSocket,
- iChannelNum,
- aInUse );
- if ( retTemp != KErrNone )
- {
- FTRACE(FPrint( _L( "CDunBtListen::StartServiceAdvertisement() (ERROR) complete" ) ));
- return retTemp;
- }
-
- // Now RFCOMM channel number of the next data socket must be the same as
- // the current listener's RFCOMM channel number. Set that now.
- iEntity.iChannelNum = iChannelNum;
-
- // Register SDP record
- iSDPHandleDun = 0;
- retTemp = iDiscovery->RegisterSdpRecord( KDialUpNetworkingUUID,
- iChannelNum,
- iSDPHandleDun );
- if ( retTemp != KErrNone )
- {
- FTRACE(FPrint( _L( "CDunBtListen::StartServiceAdvertisement() (failed!) complete (%d)" ), retTemp));
- return retTemp;
- }
- FTRACE(FPrint( _L( "CDunBtListen::StartServiceAdvertisement() complete" ) ));
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// Stops dialup service advertisement
-// ---------------------------------------------------------------------------
-//
-TInt CDunBtListen::StopServiceAdvertisement()
- {
- FTRACE(FPrint( _L( "CDunBtListen::StopServiceAdvertisement()" ) ));
- if ( !iDiscovery )
- {
- FTRACE(FPrint( _L( "CDunBtListen::StopServiceAdvertisement() (iDiscovery) not initialized!" ) ));
- return KErrGeneral;
- }
- if ( iSDPHandleDun != 0 )
- {
- TInt retTemp = iDiscovery->DeleteSdpRecord( iSDPHandleDun );
- FTRACE(FPrint( _L( "CDunBtListen::StopServiceAdvertisement() record closed (%d)" ), retTemp ));
- iSDPHandleDun = 0;
- }
- if ( iListenSocket.SubSessionHandle() )
- {
- iListenSocket.Close();
- }
- FTRACE(FPrint( _L( "CDunBtListen::StopServiceAdvertisement() complete" ) ));
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// Method which reserves local RFCOMM channel (from possible channels 1-30)
-// and returns it to client.
-// ---------------------------------------------------------------------------
-//
-TInt CDunBtListen::ReserveLocalChannel( RSocketServ& aSocketServ,
- RSocket& aListenSocket,
- TUint& aChannelNum,
- TBool& aInUse )
- {
- FTRACE(FPrint(_L("CDunBtListen::ReserveLocalChannel()")));
- aInUse = EFalse;
- if ( aListenSocket.SubSessionHandle() )
- {
- FTRACE(FPrint(_L("CDunBtListen::ReserveLocalChannel() (open socket!) complete")));
- return KErrArgument;
- }
- TInt retTemp;
- TProtocolDesc pInfo;
- retTemp = aSocketServ.FindProtocol( TProtocolName(KRFCOMMDesC), pInfo );
- if ( retTemp != KErrNone )
- {
- FTRACE(FPrint(_L("CDunBtListen::ReserveLocalChannel() (FindProtocol failed) complete (%d)"), retTemp));
- return retTemp;
- }
- retTemp = aListenSocket.Open( aSocketServ,
- pInfo.iAddrFamily,
- pInfo.iSockType,
- pInfo.iProtocol );
- if ( retTemp != KErrNone )
- {
- FTRACE(FPrint(_L("CDunBtListen::ReserveLocalChannel() (Open failed) complete (%d)"), retTemp));
- return retTemp;
- }
- TRfcommSockAddr addr;
- TBTServiceSecurity sec;
- sec.SetAuthentication( ETrue );
- sec.SetAuthorisation( ETrue );
- sec.SetEncryption( ETrue );
- sec.SetPasskeyMinLength( 0 );
- addr.SetSecurity( sec );
- addr.SetPort( KRfcommPassiveAutoBind );
- // When fix from Apple, replace the following with
- // "retTemp = aListenSocket.Bind( addr );"
- retTemp = DoExtendedBind( aListenSocket, addr );
- if ( retTemp != KErrNone )
- {
- aListenSocket.Close();
- aInUse = ETrue;
- FTRACE(FPrint(_L("CDunBtListen::ReserveLocalChannel() Bind() complete (%d)"), retTemp));
- return KErrInUse;
- }
- aChannelNum = aListenSocket.LocalPort();
-
- // We try to set the Telephony and Networking bits in our service class. If this fails we
- // ignore it, as it's better to carry on without it than to fail to start listening.
- aListenSocket.SetOpt(KBTRegisterCodService, KSolBtRFCOMM, KCoDDunServiceClass);
-
- retTemp = aListenSocket.Listen( KListenQueSize );
- if ( retTemp != KErrNone )
- {
- aListenSocket.Close();
- FTRACE(FPrint(_L("CDunBtListen::ReserveLocalChannel() Listen() complete (%d)"), retTemp));
- return retTemp;
- }
- FTRACE(FPrint(_L("CDunBtListen::ReserveLocalChannel() complete (%d)"), aChannelNum));
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// Tries to bind to a fixed port and if that fails with KRfcommPassiveAutoBind.
-// This is for spec breaking solutions like the OSX Leopard.
-// ---------------------------------------------------------------------------
-//
-TInt CDunBtListen::DoExtendedBind( RSocket& aListenSocket,
- TRfcommSockAddr& aSockAddr )
- {
- FTRACE(FPrint(_L("CDunBtListen::DoExtendedBind()")));
- if ( !aListenSocket.SubSessionHandle() )
- {
- FTRACE(FPrint(_L("CDunBtListen::DoExtendedBind() (closed socket!) complete")));
- return KErrGeneral;
- }
- TRfcommSockAddr fixedAddr = aSockAddr;
- fixedAddr.SetPort( KDunFixedChannel );
- TInt retTemp = aListenSocket.Bind( fixedAddr );
- if ( retTemp == KErrNone )
- {
- FTRACE(FPrint(_L("CDunBtListen::DoExtendedBind() complete")));
- return KErrNone;
- }
- TInt retVal = aListenSocket.Bind( aSockAddr );
- FTRACE(FPrint(_L("CDunBtListen::DoExtendedBind() complete")));
- return retVal;
- }
-
-// ---------------------------------------------------------------------------
-// From class CActive.
-// Called when a service is requested via BT.
-// ---------------------------------------------------------------------------
-//
-void CDunBtListen::RunL()
- {
- FTRACE(FPrint( _L( "CDunBtListen::RunL()" ) ));
- iListenState = EBtListenStateIdle;
-
- StopServiceAdvertisement();
-
- TInt retTemp = iStatus.Int();
- if ( retTemp != KErrNone )
- {
- FTRACE(FPrint( _L( "CDunBtListen::RunL() (ERROR) complete (%d)" ), retTemp));
- iServer->NotifyPluginCloseRequest( KDunBtPluginUid, ETrue );
- return;
- }
- // Notify new connection
- TBool noFreeChans = EFalse;
- retTemp = iParent->NotifyChannelAllocate( noFreeChans );
- if ( retTemp != KErrNone )
- {
- FTRACE(FPrint( _L( "CDunBtListen::RunL() channel allocation failed! (%d)" ), retTemp));
- // Other error than no free channels, close plugin now
- if ( !noFreeChans )
- {
- iServer->NotifyPluginCloseRequest( KDunBtPluginUid, ETrue );
- }
- return;
- }
-
- // Don't restart listening here. Request is issued via
- // NotifyAdvertisementStart()
-
- FTRACE(FPrint( _L( "CDunBtListen::RunL() complete" ) ));
- }
-
-// ---------------------------------------------------------------------------
-// From class CActive.
-// Cancel current activity.
-// ---------------------------------------------------------------------------
-//
-void CDunBtListen::DoCancel()
- {
- }
-
-// ---------------------------------------------------------------------------
-// From class MDunServAdvMon.
-// Gets called when advertisement status changes to start.
-// ---------------------------------------------------------------------------
-//
-void CDunBtListen::NotifyAdvertisementStart( TBool aCreation )
- {
- FTRACE(FPrint( _L( "CDunBtListen::NotifyAdvertisementStart()" ) ));
- // Remove the "if" below when fix comes from Apple
- if ( !aCreation )
- {
- TRAP_IGNORE( IssueRequestL() );
- }
- FTRACE(FPrint( _L( "CDunBtListen::NotifyAdvertisementStart() complete" ) ));
- }
-
-// ---------------------------------------------------------------------------
-// From class MDunServAdvMon.
-// Gets called when advertisement status changes to end.
-// ---------------------------------------------------------------------------
-//
-void CDunBtListen::NotifyAdvertisementEnd()
- {
- FTRACE(FPrint( _L( "CDunBtListen::NotifyAdvertisementEnd()" ) ));
- Stop();
- StopServiceAdvertisement();
- FTRACE(FPrint( _L( "CDunBtListen::NotifyAdvertisementEnd() complete" ) ));
- }