bluetoothengine/btsap/src/BTSapPlugin.cpp
changeset 0 f63038272f30
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/btsap/src/BTSapPlugin.cpp	Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,527 @@
+/*
+* Copyright (c) 2004-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: 
+*     BT SAP Plugin header definition
+*
+*
+*/
+
+
+// INCLUDE FILES
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include <btmanclient.h>
+#include <bt_sock.h>
+#include "BTSapPlugin.h"
+#include "BTSapServerState.h"
+#include "debug.h"
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CBTSapStatusObserver::CBTSapStatusObserver()
+//----------------------------------------------------------
+//
+CBTSapAsyncHelper::CBTSapAsyncHelper(): CActive(CActive::EPriorityStandard)
+    {                                
+    CActiveScheduler::Add( this );
+    }
+
+// ---------------------------------------------------------
+// CBTSapStatusObserver::NewL()
+//----------------------------------------------------------
+// 
+CBTSapAsyncHelper* CBTSapAsyncHelper::NewL(CBTSapServerState* aServerState, MSapAsyncObserver* aObserver) 
+    {
+    CBTSapAsyncHelper* self = new(ELeave) CBTSapAsyncHelper();
+    CleanupStack::PushL( self );
+    self->ConstructL(aServerState, aObserver);
+    CleanupStack::Pop();
+    return self;
+    }
+ 
+// ---------------------------------------------------------
+// CBTSapAsyncHelper::ConstructL()
+//----------------------------------------------------------
+//   
+void CBTSapAsyncHelper::ConstructL(CBTSapServerState* aServerState, MSapAsyncObserver* aObserver)
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap]  CBTSapAsyncHelper::ConstructL")));
+    
+    iServerState = aServerState;
+    iObserver = aObserver;
+    iOperation = MSapAsyncObserver::EConnect;
+    iDiscType = EDisconnectImmediate;
+    }
+
+// ---------------------------------------------------------
+// CBTSapAsyncHelper::~CBTSapAsyncHelper
+//----------------------------------------------------------
+//
+CBTSapAsyncHelper::~CBTSapAsyncHelper()
+    {
+    Cancel();
+    }
+    
+// ---------------------------------------------------------
+// CBTSapAsyncHelper::AsyncConnect()
+//----------------------------------------------------------
+//
+/*
+void CBTSapAsyncHelper::AsyncConnect(const TBTDevAddr& aAddr)
+    {
+    // Not supported at the moment
+    }
+*/
+  
+// ---------------------------------------------------------
+// CBTSapAsyncHelper::AsyncCancelConnect()
+//----------------------------------------------------------
+//
+/*
+void CBTSapAsyncHelper::AsyncCancelConnect(const TBTDevAddr& aAddr)
+    {
+    // Not supported at the moment
+    }
+*/
+
+// ---------------------------------------------------------
+// CBTSapAsyncHelper::AsyncDissconnect()
+//----------------------------------------------------------
+//    
+void CBTSapAsyncHelper::AsyncDisconnect(const TBTDevAddr& /*aAddr*/, TBTSapDisconnectType aDiscType)
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap]  CBTSapAsyncHelper::AsyncDisconnect")));
+    
+    if (IsActive())
+        {
+        return;
+        }
+    iOperation = MSapAsyncObserver::EDisconnect;
+    iDiscType = aDiscType;
+    TRequestStatus* ownStatus;
+    ownStatus = &iStatus;
+    *ownStatus = KRequestPending;
+    SetActive();
+    User::RequestComplete(ownStatus, KErrNone);;
+    }
+    
+
+// ---------------------------------------------------------
+// CBTSapAsyncHelper::DoCancel()
+// ---------------------------------------------------------
+//
+void CBTSapAsyncHelper::DoCancel()
+    {
+    }
+
+// ---------------------------------------------------------
+// CBTSapAsyncHelper::RunL()
+// ---------------------------------------------------------
+//
+void CBTSapAsyncHelper::RunL()
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap]  CBTSapAsyncHelper::RunL")));
+    
+    TInt r = KErrNone;
+    
+    switch(iOperation)
+        {
+        case MSapAsyncObserver::EDisconnect:
+            {
+            r = iServerState->DisconnectSapConnection(iDiscType);
+            return; // Disconnect callback will happen after a socket is closed, not yet here
+            }
+        default:
+            {
+            // Nothing
+            }
+        }
+    iObserver->OperationCompletedL(iOperation, r);
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::CBTSapPlugin()
+// ---------------------------------------------------------
+//
+CBTSapPlugin::CBTSapPlugin()
+    : iServiceState(EServiceOff)
+    {
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::~CBTSapPlugin()
+// ---------------------------------------------------------
+//
+CBTSapPlugin::~CBTSapPlugin()
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap]  ~CBTSapPlugin")));
+    
+    if(iBTSapServerState)
+        {
+        iBTSapServerState->DisconnectSapConnection(EDisconnectImmediate);
+        }
+
+    if(iAsyncHelper)
+        {
+        iAsyncHelper->Cancel();
+        delete iAsyncHelper;
+        }
+    
+    delete iBTSapServerState;
+    iBTSapServerState = NULL;
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::NewL
+// ---------------------------------------------------------
+//
+CBTSapPlugin* CBTSapPlugin::NewL()
+    {
+    CBTSapPlugin* self=new(ELeave) CBTSapPlugin();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::ConstructL
+// ---------------------------------------------------------
+//
+void CBTSapPlugin::ConstructL()
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::ConstructL")));
+    iBTSapServerState = CBTSapServerState::NewL(*this);
+    iAsyncHelper = CBTSapAsyncHelper::NewL(iBTSapServerState, this);
+    StartBTSapServiceL(); // Creates iBTSapServerState
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::SetObserver, from CBTEngPlugin
+// ---------------------------------------------------------
+//
+void CBTSapPlugin::SetObserver( MBTEngPluginObserver* aObserver )
+    {
+    iObserver = aObserver;
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::GetSupportedProfiles, from CBTEngPlugin
+// ---------------------------------------------------------
+//
+void CBTSapPlugin::GetSupportedProfiles( RProfileArray& aProfiles )
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::GetSupportedProfiles")));
+    
+    aProfiles.Append(EBTProfileSAP);
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::IsProfileSupported, from CBTEngPlugin
+// ---------------------------------------------------------
+//
+TBool CBTSapPlugin::IsProfileSupported( const TBTProfile aProfile ) const
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::IsProfileSupported")));
+    
+    return (aProfile == EBTProfileSAP) ? ETrue : EFalse;
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::Connect, from CBTEngPlugin
+// ---------------------------------------------------------
+//
+TInt CBTSapPlugin::Connect( const TBTDevAddr& /*aAddr*/ )
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::Connect")));
+    
+    // A SAP connection can only be created by a remote device
+    return KErrNotSupported;
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::CancelConnect, from CBTEngPlugin
+// ---------------------------------------------------------
+//
+void CBTSapPlugin::CancelConnect( const TBTDevAddr& /*aAddr*/ )
+    {
+    // A SAP connection can only be created by a remote device
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::Disconnect, from CBTEngPlugin
+// ---------------------------------------------------------
+//
+TInt CBTSapPlugin::Disconnect( const TBTDevAddr& aAddr, TBTDisconnectType aDiscType )
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::Disconnect")));
+    
+    TInt r = KErrNotSupported;
+    TBTDevAddr btDevAddr;
+    iAddr = aAddr;
+
+    r = GetRemoteBTAddress(btDevAddr);
+
+    if (!r)
+        {
+        if (btDevAddr != aAddr)
+            {
+            return KErrNone;
+            }
+        }
+    else
+        {
+        return r;
+        }
+    
+    if (aDiscType == EBTDiscImmediate)
+        {
+        r = DisconnectSapConnection(EDisconnectImmediate);
+        }
+    else if (aDiscType == EBTDiscGraceful)
+        {
+        r = DisconnectSapConnection(EDisconnectGraceful);
+        }
+    return r;
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::GetConnections, from CBTEngPlugin
+// ---------------------------------------------------------
+//    
+void CBTSapPlugin::GetConnections( RBTDevAddrArray& aAddrArray, TBTProfile aConnectedProfile )
+    {
+    TBTDevAddr btDevAddr;
+    
+    if(aConnectedProfile == EBTProfileSAP)
+        {
+        if (GetRemoteBTAddress(btDevAddr) == KErrNone)
+            {
+            aAddrArray.Append(btDevAddr);
+            }
+        }
+    }
+    
+// ---------------------------------------------------------
+// CBTSapPlugin::IsConnected, from CBTEngPlugin
+// ---------------------------------------------------------
+//
+TBTEngConnectionStatus CBTSapPlugin::IsConnected( const TBTDevAddr& aAddr )
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::IsConnected")));
+    
+    TBTDevAddr addr;
+    TInt r = KErrNotSupported;
+    
+    if(iServiceState)
+        {
+        // Only check connection state if the service is enabled
+        if (iBTSapServerState->IsSapConnected())
+            {
+            r = GetRemoteBTAddress( addr );
+            if( !r && addr == aAddr )
+                {
+                return EBTEngConnected;
+                }
+            }
+        }
+        
+    // Otherwise there is no connection, for sure
+    return EBTEngNotConnected;
+    }
+
+
+// ---------------------------------------------------------
+// CBTSapPlugin::StartBTSapServiceL
+// ---------------------------------------------------------
+//
+void CBTSapPlugin::StartBTSapServiceL()
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::StartBTSapServiceL")));
+    
+    if(iServiceState == EServiceOff)
+        {
+        iBTSapServerState->StartL();
+        iServiceState = EServiceOn;
+        }
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::AcceptSapConnection
+// ---------------------------------------------------------
+//
+TInt CBTSapPlugin::AcceptSapConnection()
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::AcceptSapConnection")));
+    
+    if(iServiceState)
+        {
+        // Only accept connection if the service is enabled
+        return iBTSapServerState->AcceptSapConnection();
+        }
+    else
+        {
+        // Otherwise the state-machine is not ready yet
+        BTSAP_TRACE_OPT(KBTSAP_TRACE_ERROR,
+                        BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::AcceptSapConnection: Can't accept when service is disabled")));
+        return KErrNotReady;
+        }
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::RejectSapConnection
+// ---------------------------------------------------------
+//
+TInt CBTSapPlugin::RejectSapConnection(TBTSapRejectReason aReason)
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::RejectSapConnection")));
+    
+    if(iServiceState)
+        {
+        // Only reject connection if the service is enabled
+        return iBTSapServerState->RejectSapConnection(aReason);
+        }
+    else
+        {
+        // Otherwise the state-machine is not ready yet
+        BTSAP_TRACE_OPT(KBTSAP_TRACE_ERROR,
+                        BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::RejectSapConnection: Can't reject when service is disabled")));
+        return KErrNotReady;
+        }
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::DisconnectSapConnection
+// ---------------------------------------------------------
+//
+TInt CBTSapPlugin::DisconnectSapConnection(TBTSapDisconnectType aType)
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::DisconnectSapConnection")));
+    
+    if(iServiceState)
+        {
+        TBTDevAddr addr;
+        // Only disconnect SAP if the service is enabled
+        iAsyncHelper->AsyncDisconnect(addr, aType);
+        return KErrNone;
+        }
+    else
+        {
+        BTSAP_TRACE_OPT(KBTSAP_TRACE_ERROR,
+                        BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::DisconnectSapConnection: Can't disconnect when service is disabled")));
+        // Otherwise the state-machine is not ready yet
+        return KErrNotReady;
+        }
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::IsSapConnected
+// ---------------------------------------------------------
+//
+TBool CBTSapPlugin::IsSapConnected()
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::IsSapConnected")));
+    
+    if(iServiceState)
+        {
+        // Only check connection state if the service is enabled
+        return iBTSapServerState->IsSapConnected();
+        }
+        
+    // Otherwise there is no connection, for sure
+    return EFalse;
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::GetRemoteBTAddress
+// ---------------------------------------------------------
+//
+TInt CBTSapPlugin::GetRemoteBTAddress(TBTDevAddr& aBTDevAddr)
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::GetRemoteBTAddress")));
+    
+    if(iServiceState)
+        {
+        // Only get remote address if the service is enabled
+        return iBTSapServerState->GetRemoteBTAddress(aBTDevAddr);
+        }
+    else
+        {
+        BTSAP_TRACE_OPT(KBTSAP_TRACE_ERROR,
+                        BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::GetRemoteBTAddress: Can't get remote address when service is disabled")));
+        // Otherwise the state-machine is not ready yet
+        return KErrNotReady;
+        }
+    }
+
+// ---------------------------------------------------------
+// CBTSapPlugin::OperationCompletedL
+// ---------------------------------------------------------
+//    
+void CBTSapPlugin::OperationCompletedL(MSapAsyncObserver::TOperation aOperation, TInt aError)
+    {
+    BTSAP_TRACE_OPT(KBTSAP_TRACE_STM, BTSapPrintTrace(_L("[BTSap]  CBTSapPlugin::OperationCompletedL")));
+    
+    TBTProfile profile = EBTProfileSAP;
+    
+    switch (aOperation)
+        {
+        case MSapAsyncObserver::EDisconnect:
+            {
+            iObserver->DisconnectComplete(iAddr, profile, aError);
+            }
+        }
+    }
+    
+// ---------------------------------------------------------
+// CBTSapPlugin::ConnectComplete
+// ---------------------------------------------------------
+//    
+void CBTSapPlugin::ConnectComplete()
+    {
+    // Used just for incoming SAP connectios, outgoing SAP connections are not supported.
+    // And used only when connection is created successully.
+    if ( iObserver )
+        {
+        TBTDevAddr addr;
+        if ( !GetRemoteBTAddress( addr ) )
+            {
+            iObserver->ConnectComplete( addr, EBTProfileSAP, KErrNone );
+            }
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// Implementation table is required by ECom. Allows alternative
+// New methods to be specified.
+// -----------------------------------------------------------------------------
+//
+const TImplementationProxy ImplementationTable[] =
+	{
+    IMPLEMENTATION_PROXY_ENTRY(0x101FFE46,CBTSapPlugin::NewL)
+	}; 
+    
+// -----------------------------------------------------------------------------
+// ImplementationGroupProxy: Lookup method required by ECom
+// Returns the ImplementationTable to the  ECom framework
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+	{
+	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+	return ImplementationTable;
+	}
+
+// End of file