diff -r 000000000000 -r 1bce908db942 multimediacommsengine/tsrc/testdriver/testclient/net/src/CTcBtManager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multimediacommsengine/tsrc/testdriver/testclient/net/src/CTcBtManager.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,307 @@ +/* +* Copyright (c) 2004 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: Implementation +* +*/ + +#include +#include + +#ifdef __SERIES60_ + #include +#endif + +#include "CTcBtManager.h" +#include "TTcBtFactory.h" + +#include "debuglog.h" + +/// See https://www.bluetooth.org/foundry/assignnumb/document/service_discovery +const TInt KTcSerialClassID( 0x1101 ); +const TInt KTcRootBrowseGroup( 0x1002 ); + +/// Name and description of our BT service in SDP. +_LIT( KTcServiceName, "TestClient" ); +_LIT( KTcServiceDescription, "Serial IUTCP connection" ); + +CTcBtManager* CTcBtManager::NewL( const TTcBtFactory& aFactory ) + { + CTcBtManager* self = new( ELeave ) CTcBtManager( aFactory ); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +CTcBtManager::~CTcBtManager() + { + LOG( _L("CTcBtManager::~CTcBtManager()") ); + Close(); + iSockServ.Close(); + } + +CTcBtManager::CTcBtManager( const TTcBtFactory& /*aFactory*/ ) + { + } + +void CTcBtManager::ConstructL() + { + LOG( _L("CTcBtManager::ConstructL()") ); + User::LeaveIfError( iSockServ.Connect() ); + iConn.SetObserver( this ); + iConn.SetConnection( &iSockServ, NULL ); + } + +void CTcBtManager::ConnectL( TInetAddr* /*aRemoteAddr*/ ) + { + LOG( _L("CTcBtManager::ConnectL()") ); + // Make sure that BT is enabled + TurnOnBtL(); + + // Start waiting for connections + iConn.ConnectL(); + +#ifndef __BLUETOOTH_API_V2__ + // Define security requirements (lowest possible) + SetSecurityL( iConn.LocalPort(), EFalse, EFalse, EFalse ); +#endif + + // Start advertising the local BT channel for our service + StartAdvertiserL( iConn.LocalPort() ); + LOG( _L("CTcBtManager::ConnectL() end") ); + } + +void CTcBtManager::Close() + { + LOG( _L("CTcBtManager::Close()") ); + // Stop advertising our service + StopAdvertiser(); + + // Shut down the service port + iConn.Close(); + } + +void CTcBtManager::Send( const TDesC8& aDes ) + { + iConn.Send( aDes ); + } + +void CTcBtManager::Receive( TDes8& aDes ) + { + iConn.Receive( aDes ); + } + +void CTcBtManager::ReceiveOneOrMore( TDes8& aDes ) + { + iConn.ReceiveOneOrMore( aDes ); + } + +void CTcBtManager::SetObserver( MTcBearerObserver* aObserver ) + { + iObserver = aObserver; + } + +void CTcBtManager::GetLocalAddressL( TDes& /*aDes*/ ) + { + User::Leave( KErrNotSupported ); + } + +void CTcBtManager::BearerCompletion( MTcBearerObserver::TOperation aOp, + TInt aStatus ) + { + LOG( _L("CTcBtManager::BearerCompletion( %d, %d ) start"), aOp, aStatus ); + if( ( aOp == MTcBearerObserver::EConnect ) && !aStatus ) + { + // A client has connected, mark the service as fully booked + // It's safe to ignore any leaves + TRAP_IGNORE( MakeAvailableL( EFalse ) ) + } + + if( iObserver ) + { + iObserver->BearerCompletion( aOp, aStatus ); + } + LOG( _L("CTcBtManager::BearerCompletion() end") ); + } + +void CTcBtManager::StartAdvertiserL( TInt aChannel ) + { + LOG( _L("CTcBtManager::StartAdvertiserL( %d ) start"), aChannel ); + StopAdvertiser(); + + User::LeaveIfError( iSdpServ.Connect() ); + User::LeaveIfError( iSdpDb.Open( iSdpServ ) ); + + // Create service record + iSdpDb.CreateServiceRecordL( KTcSerialClassID, iSdpRecord ); + + LOG( _L("CTcBtManager::StartAdvertiserL() created service record") ); + + // Add a Protocol to the record + CSdpAttrValueDES* protocolDesList = CSdpAttrValueDES::NewDESL( NULL ); + CleanupStack::PushL( protocolDesList ); + + TBuf8< 1 > channel; + channel.Append( (TChar)aChannel ); + + protocolDesList + ->StartListL() // List of protocols required for this method + ->BuildDESL() + ->StartListL() + ->BuildUUIDL( KL2CAP ) + ->EndListL() + + ->BuildDESL() + ->StartListL() + ->BuildUUIDL( KRFCOMM ) + ->BuildUintL( channel ) + ->EndListL() + ->EndListL(); + + iSdpDb.UpdateAttributeL( iSdpRecord, + KSdpAttrIdProtocolDescriptorList, + *protocolDesList ); + + CleanupStack::PopAndDestroy( protocolDesList ); + + LOG( _L("CTcBtManager::StartAdvertiserL() adding uid") ); + + // Add a Unique ID to the record + iSdpDb.UpdateAttributeL( iSdpRecord, + KSdpAttrIdServiceID, + 0x10001234 ); // REPLACE!! + + LOG( _L("CTcBtManager::StartAdvertiserL() adding name") ); + + // Add a name to the record + iSdpDb.UpdateAttributeL( iSdpRecord, + KSdpAttrIdBasePrimaryLanguage + + KSdpAttrIdOffsetServiceName, + KTcServiceName ); + + LOG( _L("CTcBtManager::StartAdvertiserL() adding description") ); + + // Add a description to the record + iSdpDb.UpdateAttributeL( iSdpRecord, + KSdpAttrIdBasePrimaryLanguage + + KSdpAttrIdOffsetServiceDescription, + KTcServiceDescription ); + + // "Attach" our service to the root browse group. + // This is required by some BT devices for successful remote SDP query + TUUID rootTUUID( KTcRootBrowseGroup ); + CSdpAttrValueUUID* rootBrowseGroupAttr = CSdpAttrValueUUID::NewUUIDL( rootTUUID ); + CleanupStack::PushL( rootBrowseGroupAttr ); + iSdpDb.UpdateAttributeL( iSdpRecord, KSdpAttrIdBrowseGroupList, *rootBrowseGroupAttr ); + CleanupStack::PopAndDestroy( rootBrowseGroupAttr ); + + MakeAvailableL( ETrue ); + LOG( _L("CTcBtManager::StartAdvertiserL() end") ); + } + +void CTcBtManager::StopAdvertiser() + { + LOG( _L("CTcBtManager::StopAdvertiser()") ); + if( iSdpDb.SubSessionHandle() && iSdpRecord ) + { + TRAP_IGNORE( iSdpDb.DeleteRecordL( iSdpRecord ) ) + iSdpRecord = 0; + } + } + +void CTcBtManager::MakeAvailableL( TBool aIsAvailable ) + { + // Fully unused (0xFF) or Fully used (0x00) + TUint state = aIsAvailable ? 0xFF : 0x00; + LOG( _L("CTcBtManager::MakeAvailableL( %d ) start, state = %d"), aIsAvailable, state ); + + // Update the availibility attribute field + iSdpDb.UpdateAttributeL( iSdpRecord, KSdpAttrIdServiceAvailability, state ); + + // Mark the record as changed - by increasing its state number (version) + iSdpDb.UpdateAttributeL( iSdpRecord, KSdpAttrIdServiceRecordState, + ++iSdpRecordState ); + LOG( _L("CTcBtManager::MakeAvailableL() end") ); + } + +// Note that security settings should be implemented for 8.x in BtConnection level +// That is not done yet!!!!! TODO when 8.x hw must be used +#ifndef __BLUETOOTH_API_V2__ +void CTcBtManager::SetSecurityL( TInt aChannel, + TBool aAuthentication, + TBool aEncryption, + TBool aAuthorisation ) + { + LOG( _L("CTcBtManager::SetSecurityL() start") ); + RBTMan secManager; + User::LeaveIfError( secManager.Connect() ); + CleanupClosePushL( secManager ); + + RBTSecuritySettings secSession; + User::LeaveIfError( secSession.Open( secManager ) ); + CleanupClosePushL( secSession ); + + // Define security requirements for our application and RFCOMM. + TBTServiceSecurity settings( TUid::Uid( 0x10001234 ), KSolBtRFCOMM, aChannel ); + settings.SetAuthentication( aAuthentication ); + settings.SetEncryption( aEncryption ); + settings.SetAuthorisation( aAuthorisation ); + + // Register security settings, wait for async operation to complete + TRequestStatus status; + secSession.RegisterService( settings, status ); + User::WaitForRequest( status ); + + // Report any errors + User::LeaveIfError( status.Int() ); + + CleanupStack::PopAndDestroy( 2 ); // secSession, secManager + LOG( _L("CTcBtManager::SetSecurityL() end") ); + } +#endif + +void CTcBtManager::TurnOnBtL() + { +#ifdef __SERIES60_ + LOG( _L("CTcBtManager::TurnOnBtL() start") ); + + // Connect to notitifier service + RNotifier notifier; + User::LeaveIfError( notifier.Connect() ); + CleanupClosePushL( notifier ); + + // Request notification about power, don't care about the results + // This results in a UI popup being displayed to the user shortly + TRequestStatus status; + TPckgBuf< TBool > pckg; + TPckgBuf< TBool > resultPckg; + notifier.StartNotifierAndGetResponse( status, + KPowerModeSettingNotifierUid, + pckg, + resultPckg ); + User::WaitForRequest( status ); + // Disable error checking. this would make auto-reconnect impossible + // The power notifier reports an error if the time between the last + // connection attempt and this connection is too small (even if it + // doesn't hurt..) + //User::LeaveIfError( status.Int() ); + + notifier.CancelNotifier( KPowerModeSettingNotifierUid ); + + CleanupStack::PopAndDestroy(); // notifier + LOG( _L("CTcBtManager::TurnOnBtL() end") ); +#endif + }