bluetoothengine/bteng/src/btengsrvpluginmgr.cpp
changeset 0 f63038272f30
child 10 0707dd69d236
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 BTEng server to manage and interface with
       
    15 *                the profile plug-ins the profile plug-ins.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 #include <ecom/ecom.h>
       
    22 #include <btsdp.h>
       
    23 #include <centralrepository.h>
       
    24 #include <featmgr.h>
       
    25 
       
    26 #include "btengsrvpluginmgr.h"
       
    27 #include "btengserver.h"
       
    28 #include "btengsrvsession.h"
       
    29 #include "btengsrvbbconnectionmgr.h"
       
    30 #include "btengprivatecrkeys.h"
       
    31 #include "debug.h"
       
    32 #include <btfeaturescfg.h>
       
    33 
       
    34 /**  UID for BTEng plug-ins */
       
    35 const TUid KBTEngPluginUid = { 0x2000277B };
       
    36 /**  ECOM registration info for BTSAP plugin */
       
    37 _LIT8( KEComBTSapPlugin, "112D" );
       
    38 /**  The message argument which holds the Bluetooth address. */
       
    39 const TInt KBTEngAddrSlot = 0;
       
    40 /**  The message argument which holds the connection status parameter. */
       
    41 const TInt KBTEngParamSlot = 1;
       
    42 
       
    43 // ======== MEMBER FUNCTIONS ========
       
    44 
       
    45 // ---------------------------------------------------------------------------
       
    46 // C++ default constructor
       
    47 // ---------------------------------------------------------------------------
       
    48 //
       
    49 CBTEngSrvPluginMgr::CBTEngSrvPluginMgr( CBTEngServer* aServer )
       
    50 :    iServer( aServer )
       
    51     {
       
    52     }
       
    53 
       
    54 
       
    55 // ---------------------------------------------------------------------------
       
    56 // Symbian 2nd-phase constructor
       
    57 // ---------------------------------------------------------------------------
       
    58 //
       
    59 void CBTEngSrvPluginMgr::ConstructL()
       
    60     {
       
    61     }
       
    62 
       
    63 
       
    64 // ---------------------------------------------------------------------------
       
    65 // NewL
       
    66 // ---------------------------------------------------------------------------
       
    67 //
       
    68 CBTEngSrvPluginMgr* CBTEngSrvPluginMgr::NewL( CBTEngServer* aServer )
       
    69     {
       
    70     CBTEngSrvPluginMgr* self = new( ELeave ) CBTEngSrvPluginMgr( aServer );
       
    71     CleanupStack::PushL( self );
       
    72     self->ConstructL();
       
    73     CleanupStack::Pop( self );
       
    74     return self;
       
    75     }
       
    76 
       
    77 
       
    78 // ---------------------------------------------------------------------------
       
    79 // Destructor
       
    80 // ---------------------------------------------------------------------------
       
    81 //
       
    82 CBTEngSrvPluginMgr::~CBTEngSrvPluginMgr()
       
    83     {
       
    84     iPluginInfoArray.Close();
       
    85     iPluginArray.ResetAndDestroy();
       
    86     }
       
    87 
       
    88 
       
    89 // ---------------------------------------------------------------------------
       
    90 // ?implementation_description
       
    91 // ---------------------------------------------------------------------------
       
    92 //
       
    93 void CBTEngSrvPluginMgr::ProcessCommandL( const RMessage2& aMessage )
       
    94     {
       
    95     TRACE_FUNC_ENTRY
       
    96     TInt opcode = aMessage.Function();
       
    97     TInt err = KErrNone;
       
    98     TBTDevAddrPckgBuf addr;
       
    99     switch( opcode )
       
   100         {
       
   101         case EBTEngConnectDevice:
       
   102             {
       
   103             aMessage.ReadL( KBTEngAddrSlot, addr );
       
   104             TBTEngDevClassPkg cod;
       
   105             aMessage.ReadL( KBTEngParamSlot, cod );
       
   106             err = Connect( addr(), TBTDeviceClass( cod() ) );
       
   107             }
       
   108             break;
       
   109         case EBTEngCancelConnectDevice:
       
   110             {
       
   111             aMessage.ReadL( KBTEngAddrSlot, addr );
       
   112             err = CancelConnect( addr() );
       
   113             }
       
   114             break;
       
   115         case EBTEngDisconnectDevice:
       
   116             {
       
   117             aMessage.ReadL( KBTEngAddrSlot, addr );
       
   118             TPckgBuf<TUint> discType;
       
   119             aMessage.ReadL( KBTEngParamSlot, discType );
       
   120             err = Disconnect( addr(), (TBTDisconnectType) discType() );
       
   121             }
       
   122             break;
       
   123         case EBTEngIsDeviceConnected:
       
   124             {
       
   125             aMessage.ReadL( KBTEngAddrSlot, addr );
       
   126             TBTEngConnectionStatus connectStatus = EBTEngNotConnected;
       
   127             connectStatus = IsDeviceConnected( addr() );
       
   128             TBTEngParamPkg statusPkg( connectStatus );
       
   129             aMessage.WriteL( KBTEngParamSlot, statusPkg );
       
   130             }
       
   131             break;
       
   132         case EBTEngIsDeviceConnectable:
       
   133             {
       
   134             aMessage.ReadL( KBTEngAddrSlot, addr );
       
   135             TBTEngDevClassPkg cod;
       
   136             aMessage.ReadL( KBTEngParamSlot, cod );
       
   137             TBool connectable = ( GetConnectablePluginIndex(cod(), addr() ) != KErrNotFound ) ;
       
   138             TPckgBuf<TBool> connPkg( connectable );
       
   139             aMessage.WriteL( 2, connPkg );
       
   140             }
       
   141             break;
       
   142         case EBTEngGetConnectedAddresses:
       
   143             {
       
   144             TPckgBuf<TBTProfile> profile;
       
   145             aMessage.ReadL( KBTEngParamSlot, profile );
       
   146             RBTDevAddrArray addrArray;
       
   147             if( profile() == EBTProfileUndefined )
       
   148                 {
       
   149                     // Get all baseband connections
       
   150                 iServer->iBBConnMgr->GetConnectedAddressesL( addrArray );
       
   151                 }
       
   152             else
       
   153                 {
       
   154                 err = GetConnectedAddresses( addrArray, profile() );
       
   155                 }
       
   156             HBufC8* buf = HBufC8::NewLC( aMessage.GetDesMaxLengthL( KBTEngAddrSlot ) );
       
   157             TPtr8 ptr = buf->Des();
       
   158             aMessage.ReadL( KBTEngAddrSlot, ptr );
       
   159             ptr.Zero();
       
   160             for( TInt i = 0; i < addrArray.Count(); i++ )
       
   161                 {
       
   162                 addr = addrArray[ i ];
       
   163                 ptr.Append( addr );
       
   164                 }
       
   165             aMessage.WriteL( KBTEngAddrSlot, ptr );
       
   166             CleanupStack::PopAndDestroy( buf );
       
   167             }
       
   168             break;
       
   169         default:
       
   170             {
       
   171             TRACE_INFO( ( _L( "ProcessCommandL: bad request (%d)" ), 
       
   172                            aMessage.Function() ) )
       
   173             err = KErrArgument;
       
   174             }
       
   175             break;
       
   176         }
       
   177     User::LeaveIfError( err );
       
   178     TRACE_FUNC_EXIT
       
   179     }
       
   180 
       
   181 
       
   182 // ---------------------------------------------------------------------------
       
   183 // ?implementation_description
       
   184 // ---------------------------------------------------------------------------
       
   185 //
       
   186 void CBTEngSrvPluginMgr::DisconnectAllPlugins()
       
   187     {
       
   188     TRACE_FUNC_ENTRY
       
   189     TBTDevAddr nullAddr;
       
   190     for( TInt i = 0; i < iPluginArray.Count(); i++ )
       
   191         {
       
   192         (void) iPluginArray[ i ]->Disconnect( nullAddr, EBTDiscImmediate );
       
   193         }
       
   194     }
       
   195 
       
   196 
       
   197 // ---------------------------------------------------------------------------
       
   198 // ?implementation_description
       
   199 // ---------------------------------------------------------------------------
       
   200 //
       
   201 void CBTEngSrvPluginMgr::LoadProfilePluginsL( const TEComResolverParams aParams )
       
   202     {
       
   203     TRACE_FUNC_ENTRY
       
   204     if( aParams.DataType().Length() )
       
   205         {
       
   206             // This is a request to enable a specific service, e.g. BT SAP.
       
   207         REComSession::ListImplementationsL( KBTEngPluginUid, aParams, 
       
   208                                              iPluginInfoArray );
       
   209         }
       
   210     else
       
   211         {
       
   212         if( iPluginArray.Count() > 0 || iPluginInfoArray.Count() > 0 )
       
   213             {
       
   214                 // Could be the case if we received a command to turn BT on 
       
   215                 // halfway through a power down sequence. Just ignore.
       
   216             return;
       
   217             }
       
   218         iPluginInfoArray.Reset();
       
   219         iPluginArray.Reset();
       
   220         REComSession::ListImplementationsL( KBTEngPluginUid, iPluginInfoArray );
       
   221         }
       
   222         // Ignore the number of plug-ins left to load; the server state machine 
       
   223         // will handle this at a later stage.
       
   224     (void) LoadPluginL();
       
   225     TRACE_FUNC_EXIT
       
   226     }
       
   227 
       
   228 TBool CBTEngSrvPluginMgr::FilterByEnterpriseDisablementModeL(TUid aUid) const
       
   229 	{
       
   230 	TRACE_FUNC_ENTRY
       
   231 	TBool want = EFalse;
       
   232 	switch ( iServer->EnterpriseEnablementMode() )
       
   233 		{
       
   234 	case BluetoothFeatures::EDisabled:
       
   235 		// In Disabled mode all plugins are filtered out.
       
   236 		break;
       
   237 	case BluetoothFeatures::EDataProfilesDisabled:
       
   238 		// In 'privileged profiles only' mode we only allow the following.
       
   239 		if ( 		aUid == TUid::Uid(0x1020897B) // audio (i.e. allow HSP, HFP and A2DP)
       
   240 				||	aUid == TUid::Uid(0x10208979) // remote control (i.e. allow AVRCP) )
       
   241 				||	aUid == TUid::Uid(0x2001E309) // HID
       
   242 			)
       
   243 			{
       
   244 			want = ETrue;
       
   245 			}
       
   246 		break;
       
   247 	case BluetoothFeatures::EEnabled:
       
   248 		// In Enabled mode we do not filter plugins.
       
   249 		want = ETrue;
       
   250 		break;
       
   251 	default:
       
   252 		__ASSERT_DEBUG( NULL, PanicServer( EBTEngPanicCorruptSettings ) );
       
   253 		break;
       
   254 		}
       
   255 	TRACE_INFO( ( _L( "[BTENG]\t returning want = %d" ), want ) )
       
   256 	TRACE_FUNC_EXIT
       
   257 	return want;
       
   258 	}
       
   259 
       
   260 // ---------------------------------------------------------------------------
       
   261 // ?implementation_description
       
   262 // ---------------------------------------------------------------------------
       
   263 //
       
   264 TInt CBTEngSrvPluginMgr::LoadPluginL()
       
   265     {
       
   266     TRACE_FUNC_ENTRY
       
   267     if( !iPluginInfoArray.Count() )
       
   268         {
       
   269             // All plug-ins have been loaded.
       
   270         return KErrNotFound;
       
   271         }
       
   272 
       
   273         // Simply pop the first info object, process it, and delete it.
       
   274         // There is no need to keep it after the plug-in has been constructed.
       
   275     CImplementationInformation* implInfo = iPluginInfoArray[ 0 ];
       
   276     iPluginInfoArray.Remove( 0 );
       
   277     CleanupStack::PushL( implInfo );
       
   278     TLex8 lex( implInfo->DataType() );
       
   279     TUint profile = (TInt) EBTProfileUndefined;
       
   280     TInt err = lex.Val( profile, EHex );
       
   281         // Check if the feature is allowed to be loaded
       
   282     if( !err && CheckFeatureEnabledL( profile ) && FilterByEnterpriseDisablementModeL(implInfo->ImplementationUid()) )
       
   283         {
       
   284         TRACE_INFO( ( _L( "[BTENG]\t loading profile 0x%04x" ), profile ) )
       
   285         TUid implUid = implInfo->ImplementationUid();
       
   286         CBTEngPlugin* plugin = CBTEngPlugin::NewL( implUid );
       
   287         CleanupStack::PushL( plugin );
       
   288         plugin->SetObserver( ( MBTEngPluginObserver* ) this );
       
   289         User::LeaveIfError( iPluginArray.Append( plugin ) );
       
   290         CleanupStack::Pop( plugin );
       
   291         }
       
   292     CleanupStack::PopAndDestroy( implInfo ); 
       
   293     TRACE_FUNC_RES( ( _L( "%d plug-ins left to load" ), iPluginInfoArray.Count() ) )
       
   294     return iPluginInfoArray.Count();
       
   295     }
       
   296 
       
   297 
       
   298 // ---------------------------------------------------------------------------
       
   299 // ?implementation_description
       
   300 // ---------------------------------------------------------------------------
       
   301 //
       
   302 void CBTEngSrvPluginMgr::UnloadProfilePlugins()
       
   303     {
       
   304     TRACE_FUNC_ARG( ( _L( "[BTENG]\t unloading %d plug-ins" ), iPluginArray.Count() ) )
       
   305 
       
   306     // All plug-ins need to be unloaded at once. Otherwise it gets too
       
   307     // difficult to keep track in case of a power-on command during a 
       
   308     // power-off sequence.
       
   309     iPluginArray.ResetAndDestroy();
       
   310 
       
   311     REComSession::FinalClose();
       
   312     TRACE_FUNC_EXIT
       
   313     }
       
   314 
       
   315 
       
   316 // ---------------------------------------------------------------------------
       
   317 // ?implementation_description
       
   318 // ---------------------------------------------------------------------------
       
   319 //
       
   320 void CBTEngSrvPluginMgr::LoadBTSapPluginL()
       
   321     {
       
   322     TRACE_FUNC_ENTRY
       
   323 
       
   324 	// SAP is supported in neither Data Profiles Disabled nor Disabled mode.
       
   325     if ( iServer->EnterpriseEnablementMode() != BluetoothFeatures::EEnabled )
       
   326         {
       
   327         TRACE_INFO( ( _L( "\tno we're not... Bluetooth is enterprise-IT-disabled" ) ) )
       
   328         User::Leave(KErrNotSupported);
       
   329         }
       
   330     
       
   331     if( CheckFeatureEnabledL( EBTProfileSAP ) )
       
   332         {
       
   333         TEComResolverParams params;
       
   334         TPtrC8 ptr( KEComBTSapPlugin );
       
   335         params.SetDataType( ptr );
       
   336         LoadProfilePluginsL( params );
       
   337         }
       
   338     TRACE_FUNC_EXIT
       
   339     }
       
   340 
       
   341 
       
   342 // ---------------------------------------------------------------------------
       
   343 // ?implementation_description
       
   344 // ---------------------------------------------------------------------------
       
   345 //
       
   346 void CBTEngSrvPluginMgr::UnloadBTSapPlugin()
       
   347     {
       
   348     TRACE_FUNC_ENTRY
       
   349     TInt ret = GetFirstPluginOfProfileSupported( EBTProfileSAP );
       
   350     if( ret != KErrNotFound )
       
   351         {
       
   352         CBTEngPlugin* plugin = iPluginArray[ ret ];
       
   353         iPluginArray.Remove( ret );
       
   354         delete plugin;
       
   355         }
       
   356     
       
   357     TRACE_FUNC_EXIT
       
   358     }
       
   359     
       
   360 // ---------------------------------------------------------------------------
       
   361 // ?implementation_description
       
   362 // ---------------------------------------------------------------------------
       
   363 //
       
   364 void CBTEngSrvPluginMgr::DisconnectProfile( TBTProfile aProfile )
       
   365     {
       
   366     TRACE_FUNC_ENTRY
       
   367     RBTDevAddrArray addrArray;
       
   368     TInt count = iPluginArray.Count();
       
   369     while( count )
       
   370         {
       
   371         count--;
       
   372         if( iPluginArray[ count ]->IsProfileSupported( aProfile ) )
       
   373             {
       
   374             iPluginArray[ count ]->GetConnections( addrArray, aProfile );
       
   375             for ( TInt i = 0;  i < addrArray.Count(); i++ )
       
   376                 {
       
   377                 iPluginArray[ count ]->Disconnect( addrArray[i], EBTDiscImmediate );
       
   378                 }
       
   379             break;
       
   380             }
       
   381         }
       
   382     TRACE_FUNC_EXIT
       
   383     }
       
   384 
       
   385 
       
   386 // ---------------------------------------------------------------------------
       
   387 // From class MBTEngPluginObserver.
       
   388 // ?implementation_description
       
   389 // ---------------------------------------------------------------------------
       
   390 //
       
   391 void CBTEngSrvPluginMgr::ConnectComplete( const TBTDevAddr& aAddr, 
       
   392     TBTProfile aProfile, TInt aErr, RBTDevAddrArray* aConflicts )
       
   393     {
       
   394     TRACE_FUNC_ENTRY
       
   395         // Inform listeners of this event.
       
   396     (void) aProfile;
       
   397     iServer->iSessionIter.SetToFirst();
       
   398     CBTEngSrvSession* session = (CBTEngSrvSession*) iServer->iSessionIter++;
       
   399     while( session )
       
   400         {
       
   401         TRACE_INFO( ( _L( "[BTEng]\t Notifying session %d" ), (TInt) session ) )
       
   402         session->NotifyConnectionEvent( aAddr, EBTEngConnected, aConflicts, aErr );
       
   403         session = (CBTEngSrvSession*) iServer->iSessionIter++;
       
   404         }
       
   405     TRACE_FUNC_EXIT
       
   406     }
       
   407 
       
   408 
       
   409 // ---------------------------------------------------------------------------
       
   410 // From class MBTEngPluginObserver.
       
   411 // ?implementation_description
       
   412 // ---------------------------------------------------------------------------
       
   413 //
       
   414 void CBTEngSrvPluginMgr::DisconnectComplete( const TBTDevAddr& aAddr, 
       
   415     TBTProfile aProfile, TInt aErr )
       
   416     {
       
   417     TRACE_FUNC_ENTRY
       
   418         // Inform listeners of this event.
       
   419     (void) aProfile;
       
   420     iServer->iSessionIter.SetToFirst();
       
   421     CBTEngSrvSession* session = (CBTEngSrvSession*) iServer->iSessionIter++;
       
   422     while( session )
       
   423         {
       
   424         TRACE_INFO( ( _L( "[BTEng]\t Notifying session %d" ), (TInt) session ) )
       
   425         session->NotifyConnectionEvent( aAddr, EBTEngNotConnected, NULL, aErr );
       
   426         session = (CBTEngSrvSession*) iServer->iSessionIter++;
       
   427         }
       
   428     TRACE_FUNC_EXIT
       
   429     }
       
   430 
       
   431 // ---------------------------------------------------------------------------
       
   432 // ?implementation_description
       
   433 // ---------------------------------------------------------------------------
       
   434 //
       
   435 TInt CBTEngSrvPluginMgr::Connect( const TBTDevAddr& aAddr, 
       
   436     const TBTDeviceClass& aDeviceClass )
       
   437     {
       
   438     TRACE_FUNC_ENTRY
       
   439     TRACE_BDADDR ( aAddr )
       
   440     TInt pindex = GetConnectablePluginIndex( aDeviceClass );    
       
   441     TRACE_INFO( ( _L( "[BTEng]\t The %dth of plugin in plugarray to connect" ), pindex ) )
       
   442     TInt err (KErrNotFound);
       
   443     if( pindex != KErrNotFound && iPluginArray.Count())
       
   444         {
       
   445         err = iPluginArray[ pindex ]->Connect( aAddr );
       
   446         }
       
   447     TRACE_FUNC_RES( ( _L( "result: %d" ), err ) )
       
   448     return err;
       
   449     }
       
   450 
       
   451 
       
   452 // ---------------------------------------------------------------------------
       
   453 // ?implementation_description
       
   454 // ---------------------------------------------------------------------------
       
   455 //
       
   456 TInt CBTEngSrvPluginMgr::CancelConnect( const TBTDevAddr& aAddr )
       
   457     {
       
   458     TRACE_FUNC_ENTRY
       
   459     TInt err = KErrNotFound;
       
   460     TRACE_BDADDR(aAddr);
       
   461     for( TInt i = 0; i < iPluginArray.Count(); i++ )
       
   462         {
       
   463         TBTEngConnectionStatus status = iPluginArray[ i ]->IsConnected( aAddr );
       
   464         if( status == EBTEngConnecting || status == EBTEngConnected )
       
   465             {
       
   466             (void) iPluginArray[ i ]->CancelConnect( aAddr );
       
   467             err = KErrNone;
       
   468             break;
       
   469             }
       
   470         }
       
   471     TRACE_FUNC_RES( ( _L( "result: %d" ), err ) )
       
   472     return err;
       
   473     }
       
   474 
       
   475 
       
   476 // ---------------------------------------------------------------------------
       
   477 // ?implementation_description
       
   478 // ---------------------------------------------------------------------------
       
   479 //
       
   480 TInt CBTEngSrvPluginMgr::Disconnect( const TBTDevAddr& aAddr, 
       
   481     TBTDisconnectType aDiscType )
       
   482     {
       
   483     TRACE_FUNC_ENTRY
       
   484     TRACE_BDADDR(aAddr);
       
   485     TInt err = KErrNotFound;
       
   486     for( TInt i = 0; i < iPluginArray.Count(); i++ )
       
   487         {
       
   488             // Should be ignored if the plug-in does not have 
       
   489             // a connection to the address.
       
   490         err = iPluginArray[ i ]->Disconnect( aAddr, aDiscType );
       
   491         }
       
   492     TRACE_FUNC_RES( ( _L( "result: %d" ), err ) )
       
   493     return err;
       
   494     }
       
   495 
       
   496 
       
   497 // ---------------------------------------------------------------------------
       
   498 // ?implementation_description
       
   499 // ---------------------------------------------------------------------------
       
   500 //
       
   501 TBTEngConnectionStatus CBTEngSrvPluginMgr::IsDeviceConnected( const TBTDevAddr& aAddr )
       
   502     {
       
   503     TRACE_FUNC_ENTRY
       
   504     TRACE_BDADDR(aAddr);
       
   505     TBTEngConnectionStatus status = EBTEngNotConnected;
       
   506     for( TInt i = 0; i < iPluginArray.Count(); i++ )
       
   507         {
       
   508         status = iPluginArray[ i ]->IsConnected( aAddr );
       
   509         if( status == EBTEngConnecting || status == EBTEngConnected )
       
   510             {
       
   511             break;  // Just exit the loop here, we have a connection status.
       
   512             }
       
   513         }
       
   514     TRACE_FUNC_RES( ( _L( "result: %d" ), (TInt) status ) )
       
   515     return status;
       
   516     }
       
   517 
       
   518 
       
   519 // ---------------------------------------------------------------------------
       
   520 // ?implementation_description
       
   521 // ---------------------------------------------------------------------------
       
   522 //
       
   523 TInt CBTEngSrvPluginMgr::GetConnectablePluginIndex( const TBTDeviceClass& aDeviceClass, const TBTDevAddr& aAddr )
       
   524     {
       
   525     TRACE_FUNC_ENTRY
       
   526     TInt plugindex( KErrNotFound );
       
   527     TRACE_BDADDR(aAddr);
       
   528     TRACE_INFO ( (_L("[BTENG] cod %b"), aDeviceClass.DeviceClass()))
       
   529     if( aAddr != TBTDevAddr() )
       
   530         {
       
   531         DoGetEirData( aAddr );
       
   532         }
       
   533     
       
   534     if( iUuidContainter.UUIDs().Count() > 0)
       
   535         {
       
   536         plugindex = GetConnectablePluginIndexByEir();
       
   537         }
       
   538     
       
   539     if ( plugindex == KErrNotFound )
       
   540         {
       
   541         TBTProfile profile = MapDeviceClassToProfile( aDeviceClass );
       
   542         if( profile == EBTProfileUndefined )
       
   543             {
       
   544             return plugindex;
       
   545             }
       
   546         
       
   547         plugindex = GetFirstPluginOfProfileSupported( profile );
       
   548         
       
   549         if ( !iPluginArray.Count() )
       
   550             {
       
   551             // In case BT is off and plugins are not loaded
       
   552             if ( profile == EBTProfileHFP || profile == EBTProfileA2DP )
       
   553                 {
       
   554                 plugindex = KErrNone; 
       
   555                 }
       
   556             }
       
   557         }
       
   558     
       
   559     TRACE_FUNC_RES( ( _L( "result: %d" ), plugindex ) )
       
   560     return plugindex;
       
   561     }
       
   562 
       
   563 // ---------------------------------------------------------------------------
       
   564 // ?implementation_description
       
   565 // ---------------------------------------------------------------------------
       
   566 //
       
   567 TInt CBTEngSrvPluginMgr::GetConnectedAddresses( RBTDevAddrArray& aAddrArray, 
       
   568     TBTProfile aProfile )
       
   569     {
       
   570     TRACE_FUNC_ENTRY    
       
   571     TInt ret = GetFirstPluginOfProfileSupported( aProfile );
       
   572     if( ret != KErrNotFound )
       
   573         {
       
   574         iPluginArray[ ret ]->GetConnections( aAddrArray, aProfile );
       
   575         ret = KErrNone;
       
   576         }
       
   577     TRACE_FUNC_RES( ( _L( "result: %d" ), ret ) )
       
   578     return ret;
       
   579     }
       
   580 
       
   581 // ---------------------------------------------------------------------------
       
   582 // ?implementation_description
       
   583 // ---------------------------------------------------------------------------
       
   584 //
       
   585 TBool CBTEngSrvPluginMgr::CheckFeatureEnabledL( TInt aProfile )
       
   586     {
       
   587     TRACE_FUNC_ARG( ( _L( "requested feature: 0x%04x" ), aProfile ) )
       
   588         // By default, a feature is supported. This allowd features that do not
       
   589         // have a related feature flag to be loaded too.
       
   590     TBool supported = ETrue;
       
   591     if( aProfile == EBTProfileSAP )
       
   592         {
       
   593             // First check from central repository.
       
   594         CRepository* cenrep = CRepository::NewL( KCRUidBTEngPrivateSettings );
       
   595         TInt enabled = 0;
       
   596         TInt err = cenrep->Get( KBTSapEnabled, enabled );
       
   597         delete cenrep;
       
   598         if( err || !enabled )
       
   599             {
       
   600             return EFalse;
       
   601             }
       
   602         }
       
   603 
       
   604     TInt feature = MapProfileToFeature( aProfile );
       
   605     if( feature )
       
   606         {
       
   607             // Check from feature manager if this phone enables this feature.
       
   608         FeatureManager::InitializeLibL();
       
   609         supported = FeatureManager::FeatureSupported( feature );
       
   610         FeatureManager::UnInitializeLib();
       
   611         }
       
   612     TRACE_FUNC_RES( ( _L ( "result: %d" ), supported ) )
       
   613     return supported;
       
   614     }
       
   615 
       
   616 
       
   617 // ---------------------------------------------------------------------------
       
   618 // ?implementation_description
       
   619 // ---------------------------------------------------------------------------
       
   620 //
       
   621 TBTProfile CBTEngSrvPluginMgr::MapDeviceClassToProfile( 
       
   622     const TBTDeviceClass& aDeviceClass )
       
   623     {
       
   624     TRACE_FUNC_ARG( ( _L( "Mapping CoD %b ..." ), aDeviceClass.DeviceClass() ) )
       
   625     // Could (should?) be done more dynamically or with some header file definition.
       
   626     // Right now these are the only known/possible ECOM plug-ins.
       
   627     TBTProfile profile = EBTProfileUndefined;
       
   628     if( aDeviceClass.MajorServiceClass() & EMajorServiceAudio )
       
   629         {
       
   630         profile = EBTProfileHFP;
       
   631         }
       
   632     else if( aDeviceClass.MajorServiceClass() & EMajorServiceRendering &&
       
   633             ( aDeviceClass.MajorDeviceClass() != EMajorDeviceImaging ) )
       
   634         // Printer or camera or other imaging device may set EMajorServiceRendering bit
       
   635         // as well as stereo audio device, so check EMajorDeviceImaging too.
       
   636         {
       
   637         profile = EBTProfileA2DP;
       
   638         }
       
   639     else if( aDeviceClass.MajorDeviceClass() == EMajorDevicePeripheral &&
       
   640             ( (aDeviceClass.MinorDeviceClass() & EMinorDevicePeripheralKeyboard) ||
       
   641               (aDeviceClass.MinorDeviceClass() & EMinorDevicePeripheralPointer) ) )
       
   642         {
       
   643         profile = EBTProfileHID;
       
   644         }
       
   645     else if( aDeviceClass.MajorDeviceClass() == EMajorDeviceLanAccessPoint )
       
   646         {
       
   647             // Mainly for testing now; PAN profile is a personal favorite.
       
   648         profile = EBTProfilePANU;
       
   649         }
       
   650     
       
   651     TRACE_FUNC_RES( ( _L( "... to profile 0x%04x." ), profile ) )
       
   652     return profile;
       
   653     }
       
   654 
       
   655 
       
   656 // ---------------------------------------------------------------------------
       
   657 // Maps a profile UUID to any Bluetooth-related pflatfom feature flag.
       
   658 // ---------------------------------------------------------------------------
       
   659 //
       
   660 TInt CBTEngSrvPluginMgr::MapProfileToFeature( TInt aProfile )
       
   661     {
       
   662     TInt feature = 0;
       
   663     switch( aProfile )
       
   664         {
       
   665         case EBTProfileHSP:
       
   666         case EBTProfileHFP:
       
   667             {
       
   668             feature = KFeatureIdBtAudio;
       
   669             }
       
   670             break;
       
   671         case EBTProfileA2DP:
       
   672             {
       
   673             feature = KFeatureIdBtStereoAudio;
       
   674             }
       
   675             break;
       
   676         case EBTProfileSAP:
       
   677             {
       
   678             feature = KFeatureIdBtSap;
       
   679             }
       
   680             break;
       
   681         case EBTProfileDUN:
       
   682             {
       
   683             feature = KFeatureIdDialupNetworking;
       
   684             }
       
   685             break;
       
   686         case EBTProfileFAX:
       
   687             {
       
   688             feature = KFeatureIdBtFaxProfile;
       
   689             }
       
   690             break;
       
   691         case EBTProfilePANU:
       
   692         case EBTProfileNAP:
       
   693         case EBTProfileGN:
       
   694             {
       
   695             //feature = KFeatureIdBtPanProfile;
       
   696             feature = 0;// Testin'
       
   697             }
       
   698             break;
       
   699         case EBTProfileBIP:
       
   700             {
       
   701             feature = KFeatureIdBtImagingProfile;
       
   702             }
       
   703             break;
       
   704         case EBTProfileBPP:
       
   705             {
       
   706             feature = KFeatureIdBtPrintingProfile;
       
   707             }
       
   708             break;
       
   709         default:
       
   710             break;
       
   711         }
       
   712     TRACE_FUNC_RES( ( _L( "selected feature %d" ), feature ) )
       
   713     return feature;
       
   714     }
       
   715 
       
   716 // ---------------------------------------------------------------------------
       
   717 // Get Eir Data by hostResolver in Cache
       
   718 // ---------------------------------------------------------------------------
       
   719 //
       
   720 TInt CBTEngSrvPluginMgr::DoGetEirData( const TBTDevAddr& aAddr )
       
   721     {
       
   722     TRACE_FUNC_ENTRY
       
   723     TInt err = KErrNone;
       
   724     iUuidContainter.Close();
       
   725     
       
   726     if( !iServer->iSocketServ.Handle() )
       
   727         {
       
   728         err = iServer->iSocketServ.Connect();
       
   729         }
       
   730     
       
   731     TProtocolDesc pInfo;
       
   732     if(err == KErrNone)
       
   733         {
       
   734         _LIT(KBTLinkManagerProtocol, "BTLinkManager");
       
   735         err = iServer->iSocketServ.FindProtocol( KBTLinkManagerProtocol(), pInfo );
       
   736         }
       
   737     if (err == KErrNone)
       
   738         {
       
   739         err = iHostResolver.Open(iServer->iSocketServ, pInfo.iAddrFamily, pInfo.iProtocol);
       
   740         }
       
   741     if(err == KErrNone)
       
   742         {
       
   743         iInquirySockAddr = TInquirySockAddr();
       
   744         iInquirySockAddr.SetBTAddr(aAddr);
       
   745         iInquirySockAddr.SetAction(KHostResCache | KHostResEir);
       
   746         
       
   747         TRequestStatus status;
       
   748         iHostResolver.GetByAddress(iInquirySockAddr, iNameEntry, status);
       
   749         User::WaitForRequest(status);
       
   750         err = status.Int();
       
   751         TRACE_FUNC_RES(( _L( "HostResolver GetByAddress status: %d" ), err))
       
   752         iHostResolver.Close();
       
   753         }
       
   754     if(err == KErrNone)
       
   755         {
       
   756         TBluetoothNameRecordWrapper eirWrapper( iNameEntry() );
       
   757         err = eirWrapper.GetServiceClassUuids( iUuidContainter );
       
   758         }
       
   759     
       
   760     TRACE_FUNC_EXIT
       
   761     return err;
       
   762     }
       
   763 
       
   764 // ---------------------------------------------------------------------------
       
   765 // Check if Service UUID is supported by some plugin.
       
   766 // ---------------------------------------------------------------------------
       
   767 //
       
   768 TInt CBTEngSrvPluginMgr::GetConnectablePluginIndexByEir()
       
   769     {
       
   770     CBTEngPlugin::RProfileArray profiles;
       
   771     TInt count = iUuidContainter.UUIDs().Count();
       
   772     
       
   773     for( TInt u = 0; u < count; u++)
       
   774         {
       
   775         for( TInt i = 0; i < iPluginArray.Count(); i++ )
       
   776             {
       
   777             profiles.Reset();
       
   778             iPluginArray[ i ]->GetSupportedProfiles( profiles );
       
   779             for (TInt x = 0; x < profiles.Count(); x++)
       
   780                 {
       
   781                 if (iUuidContainter.UUIDs().At(u) == TUUID(profiles[x]))
       
   782                     {
       
   783                     profiles.Close();
       
   784     				TRACE_INFO( ( _L( "connectable plugin index %d" ), i ) )
       
   785                     return i;
       
   786                     }
       
   787                 }
       
   788             }
       
   789         }
       
   790     profiles.Close();
       
   791     return KErrNotFound;
       
   792     }
       
   793 
       
   794 // ---------------------------------------------------------------------------
       
   795 // Internal utility function 
       
   796 // ---------------------------------------------------------------------------
       
   797 //
       
   798 TInt CBTEngSrvPluginMgr::GetFirstPluginOfProfileSupported(TBTProfile aProfile )
       
   799     {
       
   800     TRACE_FUNC_ENTRY
       
   801     for( TInt i = 0; i < iPluginArray.Count(); i++ )
       
   802         {
       
   803         if( iPluginArray[ i ]->IsProfileSupported( aProfile ) )
       
   804             {
       
   805             return i;
       
   806             }
       
   807         }
       
   808     return KErrNotFound;
       
   809     }
       
   810 
       
   811 // ---------------------------------------------------------------------------
       
   812 //  Check if any audio connection exists. 
       
   813 // ---------------------------------------------------------------------------
       
   814 //
       
   815 	
       
   816 TBool CBTEngSrvPluginMgr::CheckAudioConnectionsL()
       
   817     {
       
   818     TRACE_FUNC_ENTRY
       
   819     TBool result = EFalse;
       
   820     RArray <TBTProfile> profiles;
       
   821 	CleanupClosePushL( profiles );
       
   822     profiles.AppendL( EBTProfileHSP );
       
   823     profiles.AppendL( EBTProfileHFP );
       
   824     profiles.AppendL( EBTProfileA2DP );
       
   825     profiles.AppendL( EBTProfileAVRCP );
       
   826     
       
   827 	RBTDevAddrArray addrArray;	
       
   828     for ( TInt i = 0; i < profiles.Count(); i++ )
       
   829         {
       
   830         GetConnectedAddresses( addrArray, profiles[i] );
       
   831         if ( addrArray.Count() > 0 )
       
   832             {
       
   833             result = ETrue;
       
   834             break;
       
   835             }
       
   836         addrArray.Reset();
       
   837         }
       
   838 	addrArray.Close();
       
   839 	
       
   840 	CleanupStack::PopAndDestroy( &profiles );
       
   841     TRACE_FUNC_RES( ( _L( "result: %d" ), result ) )
       
   842     return result;
       
   843     }