javaextensions/bluetooth/bluetoothplugins/btspppushplugin/src.s60/btrfcommserverconnection.cpp
changeset 21 2a9601315dfc
child 57 59b3b4473dc8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javaextensions/bluetooth/bluetoothplugins/btspppushplugin/src.s60/btrfcommserverconnection.cpp	Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,553 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+
+#include "logger.h"
+#include "functionserver.h"
+#include "bluetoothfunctionserver.h"
+#include "bluetoothremotedevice.h"
+#include "fs_methodcall.h"
+#include "bluetoothclientconnection.h"
+#include "btrfcommserverconnection.h"
+#include "bluetoothpusheventlistener.h"
+#include "javasymbianoslayer.h"
+
+using namespace std;
+using namespace java::util;
+
+namespace java
+{
+namespace bluetooth
+{
+
+const TInt KSizeOfListenQueue = 7;
+#define SERVICE_AVAILABLE 0xFF
+#define SERVICE_NOTAVAILABLE 0x00
+_LIT(KRfComm, "RFCOMM");
+
+OS_EXPORT RFCOMMServerConnection::RFCOMMServerConnection(
+    java::bluetooth::BluetoothFunctionServer* server):
+        mAcceptMonitor(NULL),
+        mAsyncAccept(false),
+        mBtUrlParams(NULL),
+        mBtClientConn(NULL),
+        mServer(server),
+        mIsConnected(EFalse),
+        mServRec(NULL),
+        mState(ENone)
+{
+    JELOG2(EJavaBluetooth);
+}
+
+OS_EXPORT RFCOMMServerConnection::~RFCOMMServerConnection()
+{
+    JELOG2(EJavaBluetooth);
+    CloseServer();
+    delete mAcceptMonitor;
+}
+
+OS_EXPORT int RFCOMMServerConnection::openServer(bool authorize,
+        bool authenticate, bool encrypt)
+{
+    JELOG2(EJavaBluetooth);
+    return ServerOpen(authorize, authenticate, encrypt);
+}
+
+OS_EXPORT int RFCOMMServerConnection::ServerOpen(TBool authorize,
+        TBool authenticate, TBool encrypt)
+{
+    JELOG2(EJavaBluetooth);
+    int result = 0;
+    TRAP(result, CallMethodL(this, &RFCOMMServerConnection::ServerOpenL,
+                             authorize, authenticate, encrypt, mServer));
+    return result;
+}
+
+OS_EXPORT ServiceRecord *RFCOMMServerConnection::getServiceRecordHandle()
+{
+    return mServRec;
+}
+
+void RFCOMMServerConnection::ServerOpenL(TBool authorize, TBool authenticate,
+        TBool encrypt)
+{
+    JELOG2(EJavaBluetooth);
+
+    if (mState != ENone)
+    {
+        User::Leave(KErrInUse);
+    }
+
+    User::LeaveIfError(mSocketServ.Connect());
+    User::LeaveIfError(mSocketServ.ShareAuto());
+
+    TRAPD(err,
+    {
+        // Set this active object to connecting state
+        mState = EConnecting;
+
+        // Set a Bluetooth socket address
+        BindL(authorize, authenticate, encrypt);
+
+        // Set a socket to listen for incoming connections
+        ListenL();
+    }
+         );
+
+    if (KErrNone != err)
+    {
+        ELOG(EJavaBluetooth,
+             "- RFCOMMServerConnection::ServerOpenL: Exception caught ");
+        mState = ENone;
+        mSocketServ.Close();
+        User::LeaveIfError(err);
+    }
+
+}
+
+void RFCOMMServerConnection::BindL(TBool authorize, TBool authenticate,
+                                   TBool encrypt)
+{
+    JELOG2(EJavaBluetooth);
+    // Load protocol, RFCOMM
+    TProtocolDesc protocolDesc;
+    User::LeaveIfError(mSocketServ.FindProtocol(KRfComm(), protocolDesc));
+
+    LOG(EJavaBluetooth, EInfo,
+        "  RFCOMMServerConnection::Bind: Opening A Listener Socket ");
+
+    // Open a socket
+    mListenSock = CBluetoothSocket::NewL(*this, mSocketServ,
+                                         protocolDesc.iSockType, KRFCOMM);
+
+    mListenSock->SetNotifier(*this);
+
+    TInt Channel = 0;
+    // Get listening channel
+    User::LeaveIfError(mListenSock->GetOpt(KRFCOMMGetAvailableServerChannel,
+                                           KSolBtRFCOMM, Channel));
+
+    // Set security
+    TBTServiceSecurity secSettings;
+
+    secSettings.SetAuthentication(authenticate);
+    secSettings.SetAuthorisation(authorize);
+    secSettings.SetEncryption(encrypt);
+
+    LOG(EJavaBluetooth, EInfo,
+        "  RFCOMMServerConnection::Accept: setting The Security Settings ");
+    // Attach the security settings.
+    mBtSockAddr.SetSecurity(secSettings);
+
+    LOG1(EJavaBluetooth, EInfo,
+         "  RFCOMMServerConnection::Bind: setting port to: %d", Channel);
+    // Setting Rfcom Port
+    mBtSockAddr.SetPort(Channel);
+
+    LOG(EJavaBluetooth, EInfo,
+        "  RFCOMMServerConnection::Bind: Binding Bluetooth Socket ");
+    // Bind bluetooth socket
+    User::LeaveIfError(mListenSock->Bind(mBtSockAddr));
+}
+
+OS_EXPORT int RFCOMMServerConnection::GetRfListeningChannel()
+{
+    JELOG2(EJavaBluetooth);
+    int result = 0;
+    TRAPD(err, CallMethodL(result, this,
+                           &RFCOMMServerConnection::GetRfListeningChannelFs, mServer));
+
+    if (err != KErrNone)
+    {
+        return err;
+    }
+
+    return result;
+}
+
+int RFCOMMServerConnection::GetRfListeningChannelFs()
+{
+    JELOG2(EJavaBluetooth);
+    TInt channel = 0;
+    if (mState != EConnecting)
+    {
+        return -1;
+    }
+
+    channel = mListenSock->LocalPort();
+    LOG1(EJavaBluetooth, EInfo,
+         "  RFCOMMServerConnection::GetRfListeningChannelFs: %d", channel);
+    return channel;
+
+}
+
+void RFCOMMServerConnection::ListenL()
+{
+    JELOG2(EJavaBluetooth);
+    // Listen on port
+    User::LeaveIfError(mListenSock->Listen(KSizeOfListenQueue));
+}
+
+OS_EXPORT int RFCOMMServerConnection::asyncAccept(
+    java::bluetooth::BluetoothPushEventListener* aEventListener,
+    BtUrlParams *aBtUrlParams)
+{
+    JELOG2(EJavaBluetooth);
+    //Store event listener and notify it when client is accepted.
+    //Make a call to accept and do not wait.
+    mAsyncAccept = true;
+    mPushEventListener = aEventListener;
+    mBtUrlParams = aBtUrlParams;
+    int result = 0;
+    TRAPD(err, CallMethodL(result, this, &RFCOMMServerConnection::AcceptL,
+                           mServer));
+    return err;
+}
+
+OS_EXPORT long RFCOMMServerConnection::Accept()
+{
+    JELOG2(EJavaBluetooth);
+    long result = 0;
+    mBtClientConn = NULL;
+
+    TRAPD(err, CallMethodL(result, this, &RFCOMMServerConnection::AcceptL,
+                           mServer));
+
+    if (err != KErrNone)
+    {
+        return err;
+    }
+
+    mAcceptMonitor->wait();
+
+    if (mAcceptStatus != KErrNone)
+    {
+        return mAcceptStatus;
+    }
+
+    mAcceptedSocket = NULL;
+
+    return reinterpret_cast<long>(mBtClientConn);
+}
+
+long RFCOMMServerConnection::AcceptL()
+{
+    JELOG2(EJavaBluetooth);
+
+    // Open blank socket and pass it to accept to be assigned a proper
+    // socket upon completion of Accept()
+    mAcceptedSocket = CBluetoothSocket::NewL(*this, mSocketServ);
+    LOG(EJavaBluetooth, EInfo,
+        "  RFCOMMServerConnection::Accept: Set To Accept Incoming Connections ");
+
+    if (NULL == mAcceptMonitor)
+    {
+        mAcceptMonitor = java::util::Monitor::createMonitor();
+    }
+
+    mAcceptStatus = 0;
+
+    // Enabling the advertising flag
+    if (NULL != mServRec)
+    {
+        mServRec -> setAdvertiseFs(ETrue);
+    }
+    int err = mListenSock->Accept((*mAcceptedSocket));
+    LOG1(EJavaBluetooth,EInfo,
+         "  RFCOMMServerConnection::Accept: accept return: %d", err);
+
+    return err;
+}
+
+OS_EXPORT int RFCOMMServerConnection::initializeServiceRecord(
+    TInt aChannel, TUUID &aServiceUUID, TDesC8 &aServiceName, bool aIsGOEP)
+{
+    JELOG2(EJavaBluetooth);
+    int result = 0;
+
+    if (NULL == mServRec)
+    {
+        TRAP(result, CallMethodL(mServRec, this,
+                                 &RFCOMMServerConnection::createServiceRecordL, mServer));
+
+        if (KErrNone == result)
+        {
+            TInt protocol = (true == aIsGOEP)?PROTOCOL_GOEP : PROTOCOL_RFCOMM;
+
+            TRAP(result, mServRec->initializeRecordL(protocol,
+                    aChannel, aServiceUUID, aServiceName));
+        }
+    }
+    return result;
+}
+
+OS_EXPORT int RFCOMMServerConnection::initializeServiceRecord(
+    int aChannel, wstring aServiceUUID, wstring aServiceName, bool aIsGOEP)
+{
+    JELOG2(EJavaBluetooth);
+    int result = 0;
+
+    if (NULL == mServRec)
+    {
+        TRAP(result, CallMethodL(mServRec, this,
+                                 &RFCOMMServerConnection::createServiceRecordL, mServer));
+
+        if (KErrNone == result)
+        {
+            TInt protocol = (true == aIsGOEP)?PROTOCOL_GOEP : PROTOCOL_RFCOMM;
+
+            result = mServRec->initializeRecord(protocol,
+                                                aChannel, aServiceUUID, aServiceName);
+        }
+    }
+    return result;
+}
+
+OS_EXPORT int RFCOMMServerConnection::restorePersistentRecord()
+{
+    JELOG2(EJavaBluetooth);
+    int result = 0;
+    if (NULL != mServRec)
+    {
+        result = mServRec->restorePersistentRecord();
+    }
+    return result;
+}
+
+ServiceRecord *RFCOMMServerConnection::createServiceRecordL()
+{
+    return ServiceRecord::NewL(mServer);
+}
+
+int RFCOMMServerConnection::CloseServer()
+{
+    JELOG2(EJavaBluetooth);
+    int result = 0;
+    mIsConnected = EFalse;
+    mAsyncAccept = false;
+    CallMethod(this, &RFCOMMServerConnection::Close, mServer);
+    return result;
+}
+
+void RFCOMMServerConnection::Close()
+{
+    JELOG2(EJavaBluetooth);
+
+    // Deleting service record.
+    ServiceRecord::cleanup(mServRec);
+
+    if (mState != ENone)
+    {
+        mListenSock->CancelAll();
+        mListenSock->Shutdown(RSocket::EImmediate);
+        delete mListenSock; //Destructor closes the socket
+        mListenSock = NULL;
+        mState = ENone;
+        mAcceptStatus = KErrCancel;
+        if (mAcceptMonitor)
+            mAcceptMonitor->notify();
+    }
+}
+
+void RFCOMMServerConnection::DoCancel()
+{
+    JELOG2(EJavaBluetooth);
+}
+
+bool RFCOMMServerConnection::isConnectionAllowed(TBTSockAddr aBtAddr)
+{
+    JELOG2(EJavaBluetooth);
+    if (NULL == mBtUrlParams)
+    {
+        return true;
+    }
+
+    bool authorize = false;
+    bool authenticate = false;
+
+    HBufC* devAddr = HBufC::New(aBtAddr.Length());
+    TPtr ptr = devAddr->Des();
+    TBTDevAddr btDeviceAddress = aBtAddr.BTAddr();
+    btDeviceAddress.GetReadable((TDes&)ptr);
+    if (true == mBtUrlParams->isBlockedSender(*devAddr))
+    {
+        delete devAddr;
+        return false;
+    }
+    if (true == mBtUrlParams->isAllowedSender(*devAddr, authorize, authenticate))
+    {
+        LOG(EJavaBluetooth, EInfo,
+            "  RFCOMMServerConnection::isConnectionAllowed AllowedSender");
+        bool flag = true;
+        TInt64 longBtAddr = 0;
+        TLex16 toParse(*devAddr);
+        toParse.Val(longBtAddr, EHex);
+        LOG1(EJavaBluetooth, EInfo,
+             " RFCOMMServerConnection::isConnectionAllowed Long BTRemote address %llx",longBtAddr);
+        if (true == authorize)
+        {
+            flag = BluetoothRemoteDevice::getSecurityProperty(
+                       REMOTE_AUTHORIZED, longBtAddr);
+        }
+        if (true == flag && true == authenticate)
+        {
+            flag = BluetoothRemoteDevice::getSecurityProperty(
+                       REMOTE_AUTHENTICATED, longBtAddr);
+        }
+        delete devAddr;
+        return flag;
+    }
+    delete devAddr;
+    LOG(EJavaBluetooth, EInfo, "- RFCOMMServerConnection::isConnectionAllowed");
+    return false;
+}
+
+void RFCOMMServerConnection::avoidFilter()
+{
+    JELOG2(EJavaBluetooth);
+    mAvoidFilter = true;
+}
+//------------------------------------------------------------------------------
+//  Methods from MBluetoothSocketNotifier to handle Bluetooth Events
+//------------------------------------------------------------------------------
+
+//Notification of an accept complete event
+void RFCOMMServerConnection::HandleAcceptCompleteL(TInt err)
+{
+    TBTSockAddr btRemoteAddr;
+
+    mAcceptStatus = err;
+
+    LOG1(EJavaBluetooth, EInfo, "+  RFCOMMServerConnection::HandleAcceptCompleteL Err:%d", err);
+
+    if (KErrNone == err)
+    {
+        mAcceptedSocket->RemoteName(btRemoteAddr);
+        if (mAsyncAccept && (!mAvoidFilter) && (false == isConnectionAllowed(btRemoteAddr)))
+        {
+            mAcceptedSocket->CancelAll();
+            mAcceptedSocket->Shutdown(RSocket::EImmediate);
+            delete mAcceptedSocket;
+            mAcceptedSocket = NULL;
+            ELOG(EJavaBluetooth,
+                 "RFCOMMServerConnection::HandleAcceptCompleteL Connection Rejected");
+            AcceptL();
+            return;
+        }
+        TBuf<20> addr;
+        TInt64 longBtAddr = 0;
+        TBTDevAddr btDeviceAddress = btRemoteAddr.BTAddr();
+        btDeviceAddress.GetReadable(addr);
+        TLex16 toParse(addr);
+        toParse.Val(longBtAddr, EHex);
+        LOG1(EJavaBluetooth, EInfo, "RFCOMMServerConnection::HandleAcceptCompleteL: Address: %ld", longBtAddr);
+        mBtClientConn = new BluetoothClientConnection(mAcceptedSocket, mServer);
+        mBtClientConn->initialize(PROTOCOL_RFCOMM, longBtAddr, 0, 0);
+        if (mAsyncAccept)
+        {
+            mPushEventListener->handleConnectionRequest(mBtClientConn, err);
+        }
+        else
+        {
+            mAcceptMonitor->notify();
+        }
+    }
+    else
+    {
+        if (mAsyncAccept)
+        {
+            // If Pushframework cancels the listening then return otherwise
+            // continue listening.
+            if (KErrCancel == err)
+            {
+                mPushEventListener->handleConnectionRequest(NULL, err);
+            }
+            else
+            {
+                ELOG(EJavaBluetooth,
+                     "  RFCOMMServerConnection::HandleAcceptCompleteL: Error while accept. Listening again.");
+                AcceptL();
+            }
+            return;
+        }
+        else
+        {
+            mAcceptMonitor->notify();
+        }
+    }
+
+    // If connection is accepted, then it should
+    // disable the advertising flag
+    if (NULL != mServRec)
+    {
+        mServRec -> setAdvertiseFs(EFalse);
+    }
+
+    LOG(EJavaBluetooth, EInfo, "-  RFCOMMServerConnection::HandleAcceptCompleteL");
+}
+
+// Notification of a baseband event
+void RFCOMMServerConnection::HandleActivateBasebandEventNotifierCompleteL(
+    TInt /*aErr*/, TBTBasebandEventNotification& /*aEventNotification*/)
+{
+    LOG1(EJavaBluetooth,EInfo,
+         "+  RFCOMMServerConnection::HandleActivateBasebandEventNotifierCompleteL %s",
+         "WARNING: Nothing to handle in this event !!");
+}
+
+//Notification of a connection complete event
+void RFCOMMServerConnection::HandleConnectCompleteL(TInt /*aErr*/)
+{
+    LOG1(EJavaBluetooth,EInfo,
+         "+  RFCOMMServerConnection::HandleConnectCompleteL %s",
+         "WARNING: Nothing to handle in this event !!");
+}
+
+//Notification of a ioctl complete event
+void RFCOMMServerConnection::HandleIoctlCompleteL(TInt /*aErr*/)
+{
+    LOG1(EJavaBluetooth,EInfo,
+         "+  RFCOMMServerConnection::HandleIoctlCompleteL %s",
+         "WARNING: Nothing to handle in this event !!");
+}
+
+//Notification of a receive complete event
+void RFCOMMServerConnection::HandleReceiveCompleteL(TInt /*aErr*/)
+{
+    LOG1(EJavaBluetooth,EInfo,
+         "+  RFCOMMServerConnection::HandleReceiveCompleteL %s",
+         "WARNING: Nothing to handle in this event !!");
+}
+
+//Notification of a send complete event
+void RFCOMMServerConnection::HandleSendCompleteL(TInt /*aErr*/)
+{
+    LOG1(EJavaBluetooth,EInfo,
+         "+  RFCOMMServerConnection::HandleSendCompleteL %s",
+         "WARNING: Nothing to handle in this event !!");
+}
+
+//Notification of a shutdown complete event
+void RFCOMMServerConnection::HandleShutdownCompleteL(TInt /*aErr*/)
+{
+    LOG1(EJavaBluetooth,EInfo,
+         "+  RFCOMMServerConnection::HandleShutdownCompleteL %s",
+         "WARNING: Nothing to handle in this event !!");
+}
+
+} //end namespace bluetooth
+} //end namespace java