localconnectivityservice/dun/plugins/src/bt/DunBtListen.cpp
branchRCL_3
changeset 20 4a793f564d72
parent 19 0aa8cc770c8a
child 21 74aa6861c87d
--- a/localconnectivityservice/dun/plugins/src/bt/DunBtListen.cpp	Tue Aug 31 16:03:15 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" ) ));
-    }