javaextensions/bluetooth/bluetoothplugins/btspppushplugin/src/rfcommpushserverconnection.cpp
changeset 21 2a9601315dfc
child 72 1f0034e370aa
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "btrfcommpushserverconnection.h"
       
    20 #include "fs_methodcall.h"
       
    21 #include "pushexception.h"
       
    22 #include "pusherrorcodes.h"
       
    23 #include "serviceclasshandler.h"
       
    24 #include "bluetoothnamelookup.h"
       
    25 #include "javacommonutils.h"
       
    26 
       
    27 using namespace std;
       
    28 using namespace java::util;
       
    29 using namespace java::push;
       
    30 
       
    31 namespace java
       
    32 {
       
    33 namespace bluetooth
       
    34 {
       
    35 
       
    36 const wchar_t BT_GOEP_PROTOCOL[]=L"btgoep";
       
    37 
       
    38 OS_EXPORT RFCOMMPushServerConnection::RFCOMMPushServerConnection(
       
    39     const wstring aUri, const wstring aFilter,ServerConnectionFactoryBase* aFactory):
       
    40         mAcceptMonitor(NULL),
       
    41         mConnectionUri(aUri),
       
    42         mConnectionFilter(aFilter),
       
    43         mRFCOMMServer(NULL),
       
    44         mConnectionFactory(aFactory),
       
    45         mIsGOEP(false),
       
    46         mPendingConnection(false),
       
    47         mListening(false),
       
    48         mCreatedByPush(false),
       
    49         mClearServiceClassBitsFlag(true)
       
    50 {
       
    51     JELOG2(EJavaBluetooth);
       
    52 
       
    53     // Create Bluetooth Parameters
       
    54     mBtUrlParams = new BtUrlParams(mConnectionUri, mConnectionFilter);
       
    55     mFunctionServer = new BluetoothFunctionServer();
       
    56     // Create a Server Object and store it as member.
       
    57     mRFCOMMServer = new RFCOMMServerConnection(mFunctionServer);
       
    58 }
       
    59 
       
    60 OS_EXPORT RFCOMMPushServerConnection::~RFCOMMPushServerConnection()
       
    61 {
       
    62     JELOG2(EJavaBluetooth);
       
    63     delete mBtUrlParams;
       
    64     deleteServer();
       
    65     delete mFunctionServer;
       
    66 }
       
    67 
       
    68 /**
       
    69  * This method is called by Push framework to start listening.
       
    70  * Steps to be followed to start listening.
       
    71  * 1. Prompt user to switch in Bluetooth if it is switched off.
       
    72  * 2. Create BtRFCOMMServer and ask it to start listening.
       
    73  *
       
    74  *
       
    75  */
       
    76 OS_EXPORT void RFCOMMPushServerConnection::open(ConnectionListener* aListener)
       
    77 {
       
    78     JELOG2(EJavaBluetooth);
       
    79     mConnectionListener = aListener;
       
    80 
       
    81     bool authenticate = mBtUrlParams->getParamAuthenticate();
       
    82     bool authorize = mBtUrlParams->getParamAuthorize();
       
    83     bool encrypt = mBtUrlParams->getParamEncrypt();
       
    84 
       
    85     int error = 0;
       
    86 
       
    87     // Open RFCOMM Server.
       
    88     error = mRFCOMMServer->openServer(authorize, authenticate, encrypt);
       
    89     if (error < 0)
       
    90     {
       
    91         std::string errTxt("ERROR!!! Unable to Open RFCOMM Server.");
       
    92         throw PushException(COMMON_SRV_CONN_PLUGIN_ERROR, errTxt, __FILE__,
       
    93                             __FUNCTION__, __LINE__);
       
    94     }
       
    95 
       
    96     int channel = mRFCOMMServer->GetRfListeningChannel();
       
    97 
       
    98     std::wstring uuid = mBtUrlParams->getServiceUuid();
       
    99     std::wstring serviceName = mBtUrlParams->getParamName();
       
   100 
       
   101     LOG1(EJavaBluetooth, EInfo,
       
   102          "  RFCOMMPushServerConnection::open Protocol:%S",
       
   103          mBtUrlParams->getProtocol().c_str());
       
   104     if (0 == mBtUrlParams->getProtocol().compare(BT_GOEP_PROTOCOL))
       
   105     {
       
   106         mIsGOEP = true;
       
   107     }
       
   108     // Initialize Services
       
   109     error = mRFCOMMServer->initializeServiceRecord(
       
   110                 channel, uuid,serviceName, mIsGOEP);
       
   111 
       
   112     if (error < 0)
       
   113     {
       
   114         std::string errTxt("ERROR!!! Unable to Initialize channel Server.");
       
   115         throw PushException(COMMON_SRV_CONN_PLUGIN_ERROR, errTxt, __FILE__,
       
   116                             __FUNCTION__, __LINE__);
       
   117     }
       
   118 
       
   119     // Restore Persistent Record (if any)
       
   120     mRFCOMMServer->restorePersistentRecord();
       
   121 
       
   122     // Ask server to start
       
   123     mRFCOMMServer->asyncAccept(this, mBtUrlParams);
       
   124 
       
   125     // We are listening now.
       
   126     mListening = true;
       
   127 
       
   128     // Reset the flag
       
   129     mClearServiceClassBitsFlag = true;
       
   130 }
       
   131 
       
   132 /*
       
   133  * When server is push registered, and manual launched server is closed,
       
   134  * it is not required to clear the service class bits
       
   135  * associated with this service.
       
   136  */
       
   137 OS_EXPORT void RFCOMMPushServerConnection::unsetClearServiceClassBitsFlag()
       
   138 {
       
   139     JELOG2(EJavaBluetooth);
       
   140     mClearServiceClassBitsFlag = false;
       
   141 }
       
   142 
       
   143 OS_EXPORT void RFCOMMPushServerConnection::close()
       
   144 {
       
   145     JELOG2(EJavaBluetooth);
       
   146     if (true == mClearServiceClassBitsFlag)
       
   147     {
       
   148         ServiceClassHandler::setDeviceServiceClass(0);
       
   149     }
       
   150     mPendingConnection = false;
       
   151     mAcceptMonitor = NULL;
       
   152     mListening = false;
       
   153     mRFCOMMServer->CloseServer();
       
   154 }
       
   155 
       
   156 /*
       
   157  * Gets the connection URI used to open this server connection.
       
   158  */
       
   159 OS_EXPORT std::wstring RFCOMMPushServerConnection::getUri() const
       
   160 {
       
   161     JELOG2(EJavaBluetooth);
       
   162     return mConnectionUri;
       
   163 }
       
   164 
       
   165 /*
       
   166  * Gets the connection Filter string associate with this connection.
       
   167  */
       
   168 OS_EXPORT std::wstring RFCOMMPushServerConnection::getFilter() const
       
   169 {
       
   170     JELOG2(EJavaBluetooth);
       
   171     return mConnectionFilter;
       
   172 }
       
   173 
       
   174 OS_EXPORT void RFCOMMPushServerConnection::setFilter(
       
   175     const std::wstring& aFilter)
       
   176 {
       
   177     JELOG2(EJavaBluetooth);
       
   178     mConnectionFilter = aFilter;
       
   179 }
       
   180 
       
   181 void RFCOMMPushServerConnection::handleConnectionRequest(
       
   182     BluetoothClientConnection* aClientConnection, TInt err)
       
   183 {
       
   184     JELOG2(EJavaBluetooth);
       
   185     //Here we handle checking of parameters and deciding to invoke push.
       
   186     //Check all parameters
       
   187     if (KErrNone != err)
       
   188     {
       
   189         if (NULL != mAcceptMonitor)
       
   190         {
       
   191             mAcceptMonitor->notify();
       
   192         }
       
   193         mListening = false;
       
   194         return;
       
   195     }
       
   196     mConnectionFactory->setPendingMsgFlag(mConnectionUri, true);
       
   197 
       
   198     std::wstring* remoteDeviceName = NULL;
       
   199 
       
   200     BluetoothNameLookup * nameLookup = NULL;
       
   201 
       
   202     long long remoteDevAddr = aClientConnection->getRemoteAddress();
       
   203 
       
   204     TRAPD(lookupErr,
       
   205     {
       
   206         nameLookup = BluetoothNameLookup::NewL();
       
   207         remoteDeviceName = nameLookup->doDeviceNameLookupL(remoteDevAddr);
       
   208         delete nameLookup;
       
   209     }
       
   210          );
       
   211 
       
   212     if (KErrNone != lookupErr)
       
   213     {
       
   214         remoteDeviceName = new std::wstring(
       
   215             JavaCommonUtils::longLongToWstring(remoteDevAddr));
       
   216     }
       
   217 
       
   218     mConnectionListener->msgArrived(*remoteDeviceName);
       
   219 
       
   220     delete remoteDeviceName;
       
   221 
       
   222     // This means that when jsr gets this object, it must complete
       
   223     // acceptAndOpen immediately
       
   224     mPendingConnection = true;
       
   225     mListening = false;
       
   226 
       
   227     // Store this as member. We can later return this when queried from jsr.
       
   228     mClientConnection = aClientConnection;
       
   229 
       
   230     if (NULL != mAcceptMonitor)
       
   231     {
       
   232         mAcceptMonitor->notify();
       
   233     }
       
   234 }
       
   235 
       
   236 OS_EXPORT void RFCOMMPushServerConnection::setAcceptMonitor(
       
   237     java::util::Monitor* aMonitor)
       
   238 {
       
   239     mAcceptMonitor = aMonitor;
       
   240     mRFCOMMServer->avoidFilter();
       
   241 }
       
   242 
       
   243 OS_EXPORT void RFCOMMPushServerConnection::unsetAcceptMonitor()
       
   244 {
       
   245     mAcceptMonitor = NULL;
       
   246 }
       
   247 
       
   248 OS_EXPORT bool RFCOMMPushServerConnection::isActive()
       
   249 {
       
   250     JELOG2(EJavaBluetooth);
       
   251     bool result = (mPendingConnection || mListening);
       
   252     LOG1(EJavaBluetooth, EInfo,
       
   253          "+ RFCOMMPushServerConnection::isActive: bool result: %d", result);
       
   254     return result;
       
   255 }
       
   256 
       
   257 OS_EXPORT bool RFCOMMPushServerConnection::isGOEPConnection()
       
   258 {
       
   259     return mIsGOEP;
       
   260 }
       
   261 
       
   262 OS_EXPORT bool RFCOMMPushServerConnection::isConnectionAccepted()
       
   263 {
       
   264     return mPendingConnection;
       
   265 }
       
   266 
       
   267 OS_EXPORT bool RFCOMMPushServerConnection::isListening()
       
   268 {
       
   269     return mListening;
       
   270 }
       
   271 
       
   272 OS_EXPORT bool RFCOMMPushServerConnection::isCreatedByPush()
       
   273 {
       
   274     return mCreatedByPush;
       
   275 }
       
   276 
       
   277 OS_EXPORT void RFCOMMPushServerConnection::setCreatedByPush()
       
   278 {
       
   279     mCreatedByPush = true;
       
   280 }
       
   281 
       
   282 OS_EXPORT
       
   283 RFCOMMServerConnection* RFCOMMPushServerConnection::getServerObject()
       
   284 {
       
   285     JELOG2(EJavaBluetooth);
       
   286     if (mRFCOMMServer)
       
   287     {
       
   288         LOG(EJavaBluetooth,EInfo,
       
   289             "-  RFCOMMPushServerConnection::getServerObject Returning existing RFCOMM Server");
       
   290         return mRFCOMMServer;
       
   291     }
       
   292     else
       
   293     {
       
   294         mRFCOMMServer = new RFCOMMServerConnection(mFunctionServer);
       
   295         LOG(EJavaBluetooth, EInfo,
       
   296             "-  RFCOMMPushServerConnection::getServerObject Returning new RFCOMM Server");
       
   297         return mRFCOMMServer;
       
   298     }
       
   299 }
       
   300 
       
   301 OS_EXPORT void RFCOMMPushServerConnection::deleteServer()
       
   302 {
       
   303     JELOG2(EJavaBluetooth);
       
   304     if (mRFCOMMServer)
       
   305     {
       
   306         delete mRFCOMMServer;
       
   307         mRFCOMMServer = NULL;
       
   308         return;
       
   309     }
       
   310 }
       
   311 
       
   312 OS_EXPORT
       
   313 BluetoothClientConnection* RFCOMMPushServerConnection::getConnectedClient()
       
   314 {
       
   315     JELOG2(EJavaBluetooth);
       
   316     //NOTE: ISSUE: IS there a chance that there can be multiple clients
       
   317     //connecting to the push midlet before launch of midlet?
       
   318     //In that case we need to return clients in the order in which they were
       
   319     //accepted.
       
   320     //Code will be something like return acceptedConnections->deQueue()
       
   321     //and in handleConnectionRequest we must
       
   322     //have acceptedConnection->enQueue(client);
       
   323     //
       
   324     mConnectionFactory->setPendingMsgFlag(mConnectionUri, false);
       
   325 
       
   326     // Handed over the accepted connection. And hence, resetting the flag  back
       
   327     mPendingConnection = false;
       
   328 
       
   329     return mClientConnection;
       
   330 }
       
   331 
       
   332 } //end namespace bluetooth
       
   333 } //end namespace java