bluetoothengine/bteng/src/btengsrvbbconnectionmgr.cpp
changeset 0 f63038272f30
child 12 b23265fb36da
equal deleted inserted replaced
-1:000000000000 0:f63038272f30
       
     1 /*
       
     2 * Copyright (c) 2006 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:  Helper class for handling Bluetooth Baseband-related 
       
    15 *                connection management.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 #include <wlaninternalpskeys.h>
       
    22 #include <featmgr.h>
       
    23 
       
    24 #include "btengsrvbbconnectionmgr.h"
       
    25 #include "debug.h"
       
    26 
       
    27 /**  ?description */
       
    28 const TInt KBTEngSrvBBConnId = 11;
       
    29 /**  ?description */
       
    30 const TInt KBTEngSrvWlanStatusId = 12;
       
    31 /**  ?description */
       
    32 const TInt KBTEngMaxAddrArraySize = 10;
       
    33 
       
    34 
       
    35 // ======== MEMBER FUNCTIONS ========
       
    36 
       
    37 // ---------------------------------------------------------------------------
       
    38 // C++ default constructor
       
    39 // ---------------------------------------------------------------------------
       
    40 //
       
    41 CBTEngSrvBBConnMgr::CBTEngSrvBBConnMgr(RSocketServ& aSockServ)
       
    42     : iSockServ(aSockServ)
       
    43     {
       
    44     }
       
    45 
       
    46 
       
    47 // ---------------------------------------------------------------------------
       
    48 // Symbian 2nd-phase constructor
       
    49 // ---------------------------------------------------------------------------
       
    50 //
       
    51 void CBTEngSrvBBConnMgr::ConstructL()
       
    52     {
       
    53     iLinkCountWatcher = CBTEngActive::NewL( *this, KBTEngSrvBBConnId, 
       
    54                                              CActive::EPriorityStandard );
       
    55         // Subscribe to the BT Baseband link count.
       
    56     User::LeaveIfError( iLinkCountProperty.Attach( KPropertyUidBluetoothCategory, 
       
    57                                                 KPropertyKeyBluetoothGetPHYCount ) );
       
    58     // Check if we need to monitor WLAN
       
    59     FeatureManager::InitializeLibL();
       
    60     iWlanSupported = FeatureManager::FeatureSupported( KFeatureIdProtocolWlan );
       
    61     FeatureManager::UnInitializeLib();
       
    62     if( iWlanSupported )
       
    63         {
       
    64         iWlanWatcher = CBTEngActive::NewL( *this, KBTEngSrvWlanStatusId, 
       
    65                                                   CActive::EPriorityStandard );
       
    66         User::LeaveIfError( iWlanStatusProperty.Attach( KPSUidWlan, 
       
    67                                                          KPSWlanIndicator ) );
       
    68         }
       
    69     }
       
    70 
       
    71 
       
    72 // ---------------------------------------------------------------------------
       
    73 // NewL
       
    74 // ---------------------------------------------------------------------------
       
    75 //
       
    76 CBTEngSrvBBConnMgr* CBTEngSrvBBConnMgr::NewL(RSocketServ& aSockServ)
       
    77     {
       
    78     CBTEngSrvBBConnMgr* self = new( ELeave ) CBTEngSrvBBConnMgr(aSockServ);
       
    79     CleanupStack::PushL( self );
       
    80     self->ConstructL();
       
    81     CleanupStack::Pop( self );
       
    82     return self;
       
    83     }
       
    84 
       
    85 
       
    86 // ---------------------------------------------------------------------------
       
    87 // Destructor
       
    88 // ---------------------------------------------------------------------------
       
    89 //
       
    90 CBTEngSrvBBConnMgr::~CBTEngSrvBBConnMgr()
       
    91     {
       
    92     Unsubscribe();
       
    93 	iLinkCountProperty.Close();
       
    94     iWlanStatusProperty.Close();
       
    95 	delete iLinkCountWatcher;
       
    96 	delete iWlanWatcher;
       
    97 	delete iPhyLinks;
       
    98     }
       
    99 
       
   100 
       
   101 // ---------------------------------------------------------------------------
       
   102 // Start listening to the relevant properties.
       
   103 // ---------------------------------------------------------------------------
       
   104 //
       
   105 void CBTEngSrvBBConnMgr::Subscribe()
       
   106     {
       
   107     if( !iLinkCountWatcher->IsActive() )
       
   108         {
       
   109         iLinkCountProperty.Subscribe( iLinkCountWatcher->RequestStatus() );
       
   110         iLinkCountWatcher->GoActive();
       
   111         }
       
   112     if( iWlanSupported && !iWlanWatcher->IsActive() )
       
   113         {
       
   114         iWlanStatusProperty.Subscribe( iWlanWatcher->RequestStatus() );
       
   115         iWlanWatcher->GoActive();
       
   116         }
       
   117     }
       
   118 
       
   119 
       
   120 // ---------------------------------------------------------------------------
       
   121 // Stop listening to the subscribed properties.
       
   122 // ---------------------------------------------------------------------------
       
   123 //
       
   124 void CBTEngSrvBBConnMgr::Unsubscribe()
       
   125     {
       
   126     if( iLinkCountWatcher->IsActive() )
       
   127         {
       
   128         iLinkCountProperty.Cancel();
       
   129         iLinkCountWatcher->CancelRequest();
       
   130         }
       
   131 	if( iWlanWatcher && iWlanWatcher->IsActive() )
       
   132 	    {
       
   133 	    iWlanStatusProperty.Cancel();
       
   134 	    iWlanWatcher->CancelRequest();
       
   135 	    }
       
   136     }
       
   137 
       
   138 
       
   139 // ---------------------------------------------------------------------------
       
   140 // ?implementation_description
       
   141 // ---------------------------------------------------------------------------
       
   142 //
       
   143 TInt CBTEngSrvBBConnMgr::ManageTopology( TBool aPrepDiscovery )
       
   144     {
       
   145     TInt linkCount = 0;
       
   146     TBool closeSock = ETrue;    // To check if we can close the handle again.
       
   147     TInt err = iLinkCountProperty.Get( linkCount );
       
   148     if( !err && !linkCount && iAutoSwitchOff )
       
   149         {
       
   150             // Inform server that there are no active connections anymore.
       
   151         iAutoSwitchOff = EFalse;
       
   152         iCallBack.CallBack();
       
   153         }
       
   154     RBTDevAddrArray addrArray;
       
   155     TInt minLinks = 1;  // We don't care about our role if we have only one link.
       
   156     if( aPrepDiscovery || GetWlanStatus() )
       
   157         {
       
   158             // If we are performing discovery shortly, or we have an active WLAN 
       
   159             // connection, then request master role on all links.
       
   160         minLinks = 0;
       
   161         }
       
   162     if( !err && linkCount > minLinks )
       
   163         {
       
   164         if( iPhyLinks )
       
   165             {
       
   166                 // If we have an open handle with the socket server (because we
       
   167                 // are disconnecting all links), then don't close the socket.
       
   168             closeSock = EFalse;
       
   169             }
       
   170             // There are existing links; get the addresses.
       
   171         TRAP( err, GetConnectedAddressesL( addrArray ) );
       
   172         }
       
   173     if( !err && addrArray.Count() > minLinks )
       
   174         {
       
   175             // Try to become master on all the links.
       
   176         RBTPhysicalLinkAdapter btLink;
       
   177         for( TInt i = 0; i < addrArray.Count(); i++ )
       
   178             {
       
   179                 // At this point, the results of the operations do not matter 
       
   180                 // too much. If an error is returned, then that only affects 
       
   181                 // further operations on the same link, and they should not be 
       
   182                 // passed back to the caller.
       
   183             TUint32 basebandState = 0;
       
   184             err = btLink.Open( iSockServ, addrArray[ i ] );
       
   185             if( !err )
       
   186                 {
       
   187                     // Mostly for logging purposes, check the current role (the 
       
   188                     // request will anyway be ignored if we're already master).
       
   189                 err = btLink.PhysicalLinkState( basebandState );
       
   190                 TRACE_INFO( ( 
       
   191                     _L( "[BTEng]\t ManageTopology: Current role: %d; status: %d" ), 
       
   192                     (TInt) ( basebandState & ENotifyAnyRole ), err ) )
       
   193                 }
       
   194             if( !err && ( basebandState & ENotifySlave ) )
       
   195                 {
       
   196                     // Try to become master of this link. This request could 
       
   197                     // be issued without checking the current role, and would 
       
   198                     // just be ignored if we are already master. The return 
       
   199                     // value is also ignored later on, at this stage it is 
       
   200                     // not important if the call succeeds.
       
   201                 err = btLink.RequestMasterRole();
       
   202                 TRACE_INFO( ( 
       
   203                     _L( "[BTEng]\t Requesting master role; result: %d" ),  err ) )
       
   204                 }
       
   205                 // Reset the result, so that it is not passed up 
       
   206                 // (in case this was the last one in the loop).
       
   207             err = KErrNone;
       
   208             btLink.Close();
       
   209             }
       
   210         }
       
   211     addrArray.Close();
       
   212     if( closeSock )
       
   213         {
       
   214         delete iPhyLinks;
       
   215         iPhyLinks = NULL;
       
   216         }
       
   217     return err;
       
   218     }
       
   219 
       
   220 
       
   221 // ---------------------------------------------------------------------------
       
   222 // Gets an array of addresses of remote devices for all Baseband connections.
       
   223 // ---------------------------------------------------------------------------
       
   224 //
       
   225 void CBTEngSrvBBConnMgr::GetConnectedAddressesL( RBTDevAddrArray& aAddrArray )
       
   226     {
       
   227     TInt err = KErrNone;
       
   228     if( !iPhyLinks )
       
   229         {
       
   230         iPhyLinks = CBluetoothPhysicalLinks::NewL( *this, iSockServ );
       
   231         }
       
   232     if( !err )
       
   233         {
       
   234         err = iPhyLinks->Enumerate( aAddrArray, KBTEngMaxAddrArraySize );
       
   235         }
       
   236     User::LeaveIfError( err );
       
   237     }
       
   238 
       
   239 
       
   240 // ---------------------------------------------------------------------------
       
   241 // Request to disconnect all Bluetooth baseband connections.
       
   242 // ---------------------------------------------------------------------------
       
   243 //
       
   244 void CBTEngSrvBBConnMgr::DisconnectAllLinksL( TCallBack& aCallBack )
       
   245     {
       
   246     TRACE_FUNC_ENTRY
       
   247     iCallBack = aCallBack;
       
   248     RBTDevAddrArray addrArray;
       
   249     GetConnectedAddressesL( addrArray );
       
   250     TInt err = KErrNone;
       
   251     if( addrArray.Count() > 0 )
       
   252         {
       
   253         err = iPhyLinks->DisconnectAll();
       
   254         }
       
   255     else
       
   256         {
       
   257         err = KErrNotFound;
       
   258         }
       
   259     addrArray.Close();
       
   260     if( err && err != KErrInUse )
       
   261         {
       
   262             // No connections, or something went wrong; just clean up 
       
   263             // and inform our client.
       
   264         HandleDisconnectAllCompleteL( err );
       
   265         }
       
   266     TRACE_FUNC_EXIT
       
   267     }
       
   268 
       
   269 
       
   270 // ---------------------------------------------------------------------------
       
   271 // Request to disconnect all Bluetooth baseband connections.
       
   272 // ---------------------------------------------------------------------------
       
   273 //
       
   274 void CBTEngSrvBBConnMgr::SetAutoSwitchOff( TBool aEnable, TCallBack& aCallBack )
       
   275     {
       
   276     iAutoSwitchOff = aEnable;
       
   277 	iCallBack = aCallBack;
       
   278     if( aEnable )
       
   279         {
       
   280         TInt linkCount = 0;
       
   281         TInt err = iLinkCountProperty.Get( linkCount );
       
   282         if( !err && !linkCount )
       
   283             {
       
   284             iCallBack.CallBack();
       
   285             }
       
   286         }
       
   287     }
       
   288 
       
   289 
       
   290 // ---------------------------------------------------------------------------
       
   291 // From class MBluetoothPhysicalLinksNotifier.
       
   292 // ?implementation_description
       
   293 // ---------------------------------------------------------------------------
       
   294 //
       
   295 void CBTEngSrvBBConnMgr::HandleCreateConnectionCompleteL( TInt aErr )
       
   296     {
       
   297     (void) aErr;
       
   298     }
       
   299 
       
   300 
       
   301 // ---------------------------------------------------------------------------
       
   302 // From class MBluetoothPhysicalLinksNotifier.
       
   303 // ?implementation_description
       
   304 // ---------------------------------------------------------------------------
       
   305 //
       
   306 void CBTEngSrvBBConnMgr::HandleDisconnectCompleteL( TInt aErr )
       
   307     {
       
   308     (void) aErr;
       
   309     }
       
   310 
       
   311 
       
   312 // ---------------------------------------------------------------------------
       
   313 // From class MBluetoothPhysicalLinksNotifier.
       
   314 // ?implementation_description
       
   315 // ---------------------------------------------------------------------------
       
   316 //
       
   317 void CBTEngSrvBBConnMgr::HandleDisconnectAllCompleteL( TInt aErr )
       
   318     {
       
   319     TRACE_FUNC_ARG( ( _L( "error: %d" ), aErr ) )
       
   320     delete iPhyLinks;
       
   321     iPhyLinks = NULL;
       
   322     iCallBack.CallBack();  // Inform our client.
       
   323     (void) aErr;    // There is no way to pass the error code; 
       
   324                     // anyway our client is not interested..
       
   325     }
       
   326 
       
   327 
       
   328 // ---------------------------------------------------------------------------
       
   329 // From class MBTEngActiveObserver.
       
   330 // ?implementation_description
       
   331 // ---------------------------------------------------------------------------
       
   332 //
       
   333 void CBTEngSrvBBConnMgr::RequestCompletedL( CBTEngActive* aActive, TInt aId, 
       
   334     TInt aStatus )
       
   335     {
       
   336     TRACE_FUNC_ARG( ( _L( "id: %d; status: %d" ), aId, aStatus ) )
       
   337     ASSERT( aId == KBTEngSrvBBConnId || aId == KBTEngSrvWlanStatusId );
       
   338     (void) aActive;
       
   339     (void) aId;
       
   340     if( aStatus != KErrPermissionDenied )
       
   341         {
       
   342             // Ignore any other errors.
       
   343             // First subscribe again, so that we don't miss any updates.
       
   344             Subscribe();
       
   345         }
       
   346     (void) ManageTopology( EFalse );    // Ignore result; nothing to do 
       
   347                                         // about it here.
       
   348     TRACE_FUNC_EXIT
       
   349     }
       
   350 
       
   351 
       
   352 // ---------------------------------------------------------------------------
       
   353 // From class MBTEngActiveObserver.
       
   354 // Handles an error in RunL( i.e. RequestCompletedL). Does nothing, since our
       
   355 // RunL cannot actually leave.
       
   356 // ---------------------------------------------------------------------------
       
   357 //
       
   358 void CBTEngSrvBBConnMgr::HandleError( CBTEngActive* aActive, TInt aId, 
       
   359     TInt aError )
       
   360     {
       
   361     TRACE_FUNC_ARG( ( _L( "id: %d; status: %d" ), aId, aError ) )
       
   362     (void) aActive;
       
   363     (void) aId;
       
   364     (void) aError;
       
   365     }
       
   366 
       
   367 
       
   368 // ---------------------------------------------------------------------------
       
   369 // ?implementation_description
       
   370 // ---------------------------------------------------------------------------
       
   371 //
       
   372 TBool CBTEngSrvBBConnMgr::GetWlanStatus()
       
   373     {
       
   374     TInt wlanStatus = 0;
       
   375     TBool connected = EFalse;
       
   376     if( iWlanSupported )
       
   377         {
       
   378         TInt err = iWlanStatusProperty.Get( wlanStatus );
       
   379         if( err )
       
   380             {
       
   381             wlanStatus = 0; // Reset just to be sure.
       
   382             }
       
   383         }
       
   384     if( wlanStatus == EPSWlanIndicatorActive || 
       
   385         wlanStatus == EPSWlanIndicatorActiveSecure )
       
   386         {
       
   387         connected = ETrue;
       
   388         }
       
   389     return connected;
       
   390     }