multimediacommsengine/tsrc/testdriver/testclient/net/src/CTcBtManager.cpp
changeset 0 1bce908db942
--- /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 <btmanclient.h>
+#include <bt_sock.h>
+
+#ifdef __SERIES60_
+	#include <btnotif.h>
+#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
+	}