diff -r e8e63152f320 -r 2a9601315dfc javaextensions/bluetooth/bluetoothplugins/btspppushplugin/src.s60/btrfcommserverconnection.cpp --- /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(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