diff -r e8e63152f320 -r 2a9601315dfc javaextensions/bluetooth/bluetoothplugins/btspppushplugin/src/rfcommpushserverconnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaextensions/bluetooth/bluetoothplugins/btspppushplugin/src/rfcommpushserverconnection.cpp Mon May 03 12:27:20 2010 +0300 @@ -0,0 +1,333 @@ +/* +* 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 "btrfcommpushserverconnection.h" +#include "fs_methodcall.h" +#include "pushexception.h" +#include "pusherrorcodes.h" +#include "serviceclasshandler.h" +#include "bluetoothnamelookup.h" +#include "javacommonutils.h" + +using namespace std; +using namespace java::util; +using namespace java::push; + +namespace java +{ +namespace bluetooth +{ + +const wchar_t BT_GOEP_PROTOCOL[]=L"btgoep"; + +OS_EXPORT RFCOMMPushServerConnection::RFCOMMPushServerConnection( + const wstring aUri, const wstring aFilter,ServerConnectionFactoryBase* aFactory): + mAcceptMonitor(NULL), + mConnectionUri(aUri), + mConnectionFilter(aFilter), + mRFCOMMServer(NULL), + mConnectionFactory(aFactory), + mIsGOEP(false), + mPendingConnection(false), + mListening(false), + mCreatedByPush(false), + mClearServiceClassBitsFlag(true) +{ + JELOG2(EJavaBluetooth); + + // Create Bluetooth Parameters + mBtUrlParams = new BtUrlParams(mConnectionUri, mConnectionFilter); + mFunctionServer = new BluetoothFunctionServer(); + // Create a Server Object and store it as member. + mRFCOMMServer = new RFCOMMServerConnection(mFunctionServer); +} + +OS_EXPORT RFCOMMPushServerConnection::~RFCOMMPushServerConnection() +{ + JELOG2(EJavaBluetooth); + delete mBtUrlParams; + deleteServer(); + delete mFunctionServer; +} + +/** + * This method is called by Push framework to start listening. + * Steps to be followed to start listening. + * 1. Prompt user to switch in Bluetooth if it is switched off. + * 2. Create BtRFCOMMServer and ask it to start listening. + * + * + */ +OS_EXPORT void RFCOMMPushServerConnection::open(ConnectionListener* aListener) +{ + JELOG2(EJavaBluetooth); + mConnectionListener = aListener; + + bool authenticate = mBtUrlParams->getParamAuthenticate(); + bool authorize = mBtUrlParams->getParamAuthorize(); + bool encrypt = mBtUrlParams->getParamEncrypt(); + + int error = 0; + + // Open RFCOMM Server. + error = mRFCOMMServer->openServer(authorize, authenticate, encrypt); + if (error < 0) + { + std::string errTxt("ERROR!!! Unable to Open RFCOMM Server."); + throw PushException(COMMON_SRV_CONN_PLUGIN_ERROR, errTxt, __FILE__, + __FUNCTION__, __LINE__); + } + + int channel = mRFCOMMServer->GetRfListeningChannel(); + + std::wstring uuid = mBtUrlParams->getServiceUuid(); + std::wstring serviceName = mBtUrlParams->getParamName(); + + LOG1(EJavaBluetooth, EInfo, + " RFCOMMPushServerConnection::open Protocol:%S", + mBtUrlParams->getProtocol().c_str()); + if (0 == mBtUrlParams->getProtocol().compare(BT_GOEP_PROTOCOL)) + { + mIsGOEP = true; + } + // Initialize Services + error = mRFCOMMServer->initializeServiceRecord( + channel, uuid,serviceName, mIsGOEP); + + if (error < 0) + { + std::string errTxt("ERROR!!! Unable to Initialize channel Server."); + throw PushException(COMMON_SRV_CONN_PLUGIN_ERROR, errTxt, __FILE__, + __FUNCTION__, __LINE__); + } + + // Restore Persistent Record (if any) + mRFCOMMServer->restorePersistentRecord(); + + // Ask server to start + mRFCOMMServer->asyncAccept(this, mBtUrlParams); + + // We are listening now. + mListening = true; + + // Reset the flag + mClearServiceClassBitsFlag = true; +} + +/* + * When server is push registered, and manual launched server is closed, + * it is not required to clear the service class bits + * associated with this service. + */ +OS_EXPORT void RFCOMMPushServerConnection::unsetClearServiceClassBitsFlag() +{ + JELOG2(EJavaBluetooth); + mClearServiceClassBitsFlag = false; +} + +OS_EXPORT void RFCOMMPushServerConnection::close() +{ + JELOG2(EJavaBluetooth); + if (true == mClearServiceClassBitsFlag) + { + ServiceClassHandler::setDeviceServiceClass(0); + } + mPendingConnection = false; + mAcceptMonitor = NULL; + mListening = false; + mRFCOMMServer->CloseServer(); +} + +/* + * Gets the connection URI used to open this server connection. + */ +OS_EXPORT std::wstring RFCOMMPushServerConnection::getUri() const +{ + JELOG2(EJavaBluetooth); + return mConnectionUri; +} + +/* + * Gets the connection Filter string associate with this connection. + */ +OS_EXPORT std::wstring RFCOMMPushServerConnection::getFilter() const +{ + JELOG2(EJavaBluetooth); + return mConnectionFilter; +} + +OS_EXPORT void RFCOMMPushServerConnection::setFilter( + const std::wstring& aFilter) +{ + JELOG2(EJavaBluetooth); + mConnectionFilter = aFilter; +} + +void RFCOMMPushServerConnection::handleConnectionRequest( + BluetoothClientConnection* aClientConnection, TInt err) +{ + JELOG2(EJavaBluetooth); + //Here we handle checking of parameters and deciding to invoke push. + //Check all parameters + if (KErrNone != err) + { + if (NULL != mAcceptMonitor) + { + mAcceptMonitor->notify(); + } + mListening = false; + return; + } + mConnectionFactory->setPendingMsgFlag(mConnectionUri, true); + + std::wstring* remoteDeviceName = NULL; + + BluetoothNameLookup * nameLookup = NULL; + + long long remoteDevAddr = aClientConnection->getRemoteAddress(); + + TRAPD(lookupErr, + { + nameLookup = BluetoothNameLookup::NewL(); + remoteDeviceName = nameLookup->doDeviceNameLookupL(remoteDevAddr); + delete nameLookup; + } + ); + + if (KErrNone != lookupErr) + { + remoteDeviceName = new std::wstring( + JavaCommonUtils::longLongToWstring(remoteDevAddr)); + } + + mConnectionListener->msgArrived(*remoteDeviceName); + + delete remoteDeviceName; + + // This means that when jsr gets this object, it must complete + // acceptAndOpen immediately + mPendingConnection = true; + mListening = false; + + // Store this as member. We can later return this when queried from jsr. + mClientConnection = aClientConnection; + + if (NULL != mAcceptMonitor) + { + mAcceptMonitor->notify(); + } +} + +OS_EXPORT void RFCOMMPushServerConnection::setAcceptMonitor( + java::util::Monitor* aMonitor) +{ + mAcceptMonitor = aMonitor; + mRFCOMMServer->avoidFilter(); +} + +OS_EXPORT void RFCOMMPushServerConnection::unsetAcceptMonitor() +{ + mAcceptMonitor = NULL; +} + +OS_EXPORT bool RFCOMMPushServerConnection::isActive() +{ + JELOG2(EJavaBluetooth); + bool result = (mPendingConnection || mListening); + LOG1(EJavaBluetooth, EInfo, + "+ RFCOMMPushServerConnection::isActive: bool result: %d", result); + return result; +} + +OS_EXPORT bool RFCOMMPushServerConnection::isGOEPConnection() +{ + return mIsGOEP; +} + +OS_EXPORT bool RFCOMMPushServerConnection::isConnectionAccepted() +{ + return mPendingConnection; +} + +OS_EXPORT bool RFCOMMPushServerConnection::isListening() +{ + return mListening; +} + +OS_EXPORT bool RFCOMMPushServerConnection::isCreatedByPush() +{ + return mCreatedByPush; +} + +OS_EXPORT void RFCOMMPushServerConnection::setCreatedByPush() +{ + mCreatedByPush = true; +} + +OS_EXPORT +RFCOMMServerConnection* RFCOMMPushServerConnection::getServerObject() +{ + JELOG2(EJavaBluetooth); + if (mRFCOMMServer) + { + LOG(EJavaBluetooth,EInfo, + "- RFCOMMPushServerConnection::getServerObject Returning existing RFCOMM Server"); + return mRFCOMMServer; + } + else + { + mRFCOMMServer = new RFCOMMServerConnection(mFunctionServer); + LOG(EJavaBluetooth, EInfo, + "- RFCOMMPushServerConnection::getServerObject Returning new RFCOMM Server"); + return mRFCOMMServer; + } +} + +OS_EXPORT void RFCOMMPushServerConnection::deleteServer() +{ + JELOG2(EJavaBluetooth); + if (mRFCOMMServer) + { + delete mRFCOMMServer; + mRFCOMMServer = NULL; + return; + } +} + +OS_EXPORT +BluetoothClientConnection* RFCOMMPushServerConnection::getConnectedClient() +{ + JELOG2(EJavaBluetooth); + //NOTE: ISSUE: IS there a chance that there can be multiple clients + //connecting to the push midlet before launch of midlet? + //In that case we need to return clients in the order in which they were + //accepted. + //Code will be something like return acceptedConnections->deQueue() + //and in handleConnectionRequest we must + //have acceptedConnection->enQueue(client); + // + mConnectionFactory->setPendingMsgFlag(mConnectionUri, false); + + // Handed over the accepted connection. And hence, resetting the flag back + mPendingConnection = false; + + return mClientConnection; +} + +} //end namespace bluetooth +} //end namespace java