connectivitymodules/SeCon/servers/pcconn/src/sconbtengine.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:20:56 +0100
branchRCL_3
changeset 20 4a793f564d72
parent 18 453dfc402455
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201032 Kit: 201035

/*
* Copyright (c) 2009 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:  CSconBtEngine implementation
*
*/



#include <centralrepository.h>
#include <btengdomaincrkeys.h>

#include <e32property.h>
#include <bttypes.h> 
#include <bt_subscribe.h>

#include "sconbtengine.h"
#include "debug.h"

CSconBtEngine* CSconBtEngine::NewL()
    {
    TRACE_FUNC;
    CSconBtEngine* self = new (ELeave) CSconBtEngine();
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    return self;
    }

CSconBtEngine::~CSconBtEngine()
    {
    TRACE_FUNC;
    if ( iBtEng )
        {
        iBtEng->Cancel();
        delete iBtEng;
        }
    
    delete iBtSettings;
    }

CSconBtEngine::CSconBtEngine()
    {
    }

void CSconBtEngine::ConstructL()
    {
    iBtEng = CBTEngDevMan::NewL( this );
    iBtSettings = CBTEngSettings::NewL( this );
    iState = EIdle;
    }

void CSconBtEngine::ReadBTInfoL( RBufWriteStream& aStream )
    {
    TRACE_FUNC_ENTRY;
    if ( iState != EIdle )
        {
        User::Leave( KErrInUse );
        }
    iStream = &aStream;
    iOperationError = KErrNone;
    
    // Write local name (8 bit name length + unicode name)
    TBuf<100> localName;
    TInt err = iBtSettings->GetLocalName( localName );
    User::LeaveIfError( err );
    LOGGER_WRITE_1("localName: %S", &localName);
    iStream->WriteUint8L( localName.Length() );
    iStream->WriteL( localName, localName.Length() );
    
    if ( iBtAddress.Length() == 0 )
        {
        LOGGER_WRITE("Try to read bt address");
        
        CRepository* cenRep = NULL;
        // Use TRAP to catch a leave if the CenRep key does not exist.
        TRAP( err, cenRep = CRepository::NewL( KCRUidBluetoothLocalDeviceAddress ) );
        CleanupStack::PushL( cenRep );
        if( !err )
            {
            err = cenRep->Get( KBTLocalDeviceAddress, iBtAddress );
            LOGGER_WRITE_1("cenRep->Get err: %d", err);
            }
        CleanupStack::PopAndDestroy( cenRep );
        
        if ( err )
            {
            iBtAddress.Zero();
            }
        }
    
    // Write bt address (8 bit addr length + unicode address)
    if ( iBtAddress.Length() > 0 )
        {
        LOGGER_WRITE_1("btAddr: %S", &iBtAddress);
        iStream->WriteUint8L( iBtAddress.Length() );
        iStream->WriteL( iBtAddress, iBtAddress.Length() );
        }
    else
        {
        iStream->WriteUint8L( 0 );
        }
    
    // Write BT Power State (8-bit, 0=Off, 1=On)
    TBTPowerStateValue state;
    err = iBtSettings->GetPowerState( state );
    User::LeaveIfError( err );
    LOGGER_WRITE_1("PowerState: %d", state);
    iStream->WriteUint8L( state );
    
    // Get device info
    TBTRegistrySearch crit;
    crit.FindAll();
    if ( !iBtDevArray )
        {
        LOGGER_WRITE("create arr");
        iBtDevArray = new (ELeave) CBTDeviceArray(5);
        LOGGER_WRITE("create arr -ok");
        }
    else
        {
        iBtDevArray->ResetAndDestroy();
        }
    err = iBtEng->GetDevices( crit, iBtDevArray );
    LOGGER_WRITE_1("GetDevices err: %d", err);
    User::LeaveIfError( err );
    iState = ERequestBtInfo;
    
    // Wait until completed
    iWait.Start();
    iState = EIdle;
    if ( iOperationError )
        {
        LOGGER_WRITE_1("Operation failed, leave %d", iOperationError);
        User::Leave( iOperationError );
        }
    TRACE_FUNC_EXIT;
    }

void CSconBtEngine::SetBtAuthorizedL( const TDesC& aBtDevAddress, TBool aAuthorized )
    {
    TRACE_FUNC_ENTRY;
    if ( iState != EIdle )
        {
        User::Leave( KErrInUse );
        }
    
    TBTRegistrySearch crit;
    TBTDevAddr addr;
    addr.SetReadable( aBtDevAddress );
    crit.FindAddress( addr );
    
    if ( !iBtDevArray )
        {
        LOGGER_WRITE("create arr");
        iBtDevArray = new (ELeave) CBTDeviceArray(5);
        LOGGER_WRITE("create arr -ok");
        }
    else
        {
        iBtDevArray->ResetAndDestroy();
        }
    TInt err = iBtEng->GetDevices( crit, iBtDevArray );
    LOGGER_WRITE_1("GetDevices err: %d", err);
    User::LeaveIfError( err );
    iState = EChangeAuthorized;
    iOperationError = KErrNone;
    iAuthorizedValue = aAuthorized;
    
    // Wait until completed
    iWait.Start();
    iState = EIdle;
    if ( iOperationError )
        {
        LOGGER_WRITE_1("Operation failed, leave %d", iOperationError);
        User::Leave( iOperationError );
        
        }
    
    TRACE_FUNC_EXIT;
    }

TInt CSconBtEngine::SetBtPowerState( TBool aPower )
    {
    TRACE_FUNC_ENTRY;
    if ( iState != EIdle )
        {
        return KErrInUse;
        }
    
    TBTPowerStateValue state;
    iOperationError = iBtSettings->GetPowerState( state );
    if ( iOperationError )
        {
        return iOperationError;
        }
    else if ( ( aPower && state == EBTPowerOn )
            || ( !aPower && state == EBTPowerOff ) )
        {
        // No need to change state
        return KErrNone;
        }
    
    state = EBTPowerOff;
    if ( aPower )
        {
        state = EBTPowerOn;
        }
    iOperationError = iBtSettings->SetPowerState( state );
    if ( iOperationError )
        {
        return iOperationError;
        }
    iState = EChangeBtState;
    
    // Wait until completed
    iWait.Start();
    
    iState = EIdle;
    TRACE_FUNC_RET( iOperationError );
    return iOperationError;
    }

TInt CSconBtEngine::SetBtName( const TDesC& aBtName )
    {
    LOGGER_WRITE_1("SetBtName aBtName: %S", &aBtName);
    TInt err = iBtSettings->SetLocalName( static_cast<const TDes&>( aBtName ) );
    TRACE_FUNC_RET( err );
    return err;
    }

// From MBTEngDevManObserver
void CSconBtEngine::HandleDevManComplete( TInt aErr )
    {
    TRACE_FUNC;
    LOGGER_WRITE_1("aErr: %d", aErr );
    if ( iState == EChangeAuthorized )
        {
        if ( iWait.IsStarted() )
            {
            iOperationError = aErr;
            iWait.AsyncStop();
            }
        }
    
    }

void CSconBtEngine::HandleGetDevicesComplete( TInt aErr, 
       CBTDeviceArray* aDeviceArray )
    {
    TRACE_FUNC_ENTRY;
    LOGGER_WRITE_1("aErr: %d", aErr);
    //iBtReqOngoing = EFalse;
    if ( iState == ERequestBtInfo )
        {
        // Continue to write devices info
        TRAP( iOperationError, PrintDevicesL() );
        LOGGER_WRITE_1("PrintDevicesL err: %d", iOperationError);
        
        if ( iWait.IsStarted() )
            {
            iWait.AsyncStop();
            }
        }
    else if ( iState == EChangeAuthorized )
        {
        iOperationError = aErr;
        if ( !aErr && aDeviceArray->Count() == 1 )
            {
            CBTDevice* btRef = aDeviceArray->At(0);
            TBTDeviceSecurity devSec = btRef->GlobalSecurity();
            if ( btRef->IsPaired() && !devSec.Banned() )
                {
                LOGGER_WRITE8_1("btAdrr: %S", &btRef->BDAddr().Des() );
                CBTDevice* btDevice = CBTDevice::NewLC( btRef->BDAddr() );
                
                btDevice->SetPaired( ETrue );
                
                btDevice->SetDeviceNameL( btRef->DeviceName() );
                btDevice->SetFriendlyNameL( btRef->FriendlyName() );
                LOGGER_WRITE8_1("name: %S", &btRef->DeviceName());
                LOGGER_WRITE8_1("FriendlyName: %S", &btRef->FriendlyName());
                
                LOGGER_WRITE_1("iAuthorizedValue: %d", iAuthorizedValue);
                // Set as authorized and store the device
                TBTDeviceSecurity security;
                security.SetNoAuthenticate( EFalse );
                security.SetNoAuthorise( iAuthorizedValue );
                security.SetBanned( EFalse );
                
                btDevice->SetGlobalSecurity (security );
                
                //iOperationError = iBtEng->ModifyDevice(*aDeviceArray->At(0));
                iOperationError = iBtEng->ModifyDevice( *btDevice );
                LOGGER_WRITE_1( "ModifyDevice err: %d", iOperationError );
                CleanupStack::PopAndDestroy( btDevice );
                }
            else
                {
                LOGGER_WRITE("Device was not paired or it's banned")
                iOperationError = KErrAccessDenied;
                }
            }
        
        // If error occured stop waiting, otherwise continue waiting until
        // HandleDevManComplete has been called
        if ( iOperationError && iWait.IsStarted() )
            {
            iWait.AsyncStop();
            }
        }
    TRACE_FUNC_EXIT;
    }

void CSconBtEngine::PrintDevicesL()
    {
    TRACE_FUNC_ENTRY;
    // calculate devices count
    TInt devCount(0);
    
    for ( TInt i=0 ; i<iBtDevArray->Count(); i++ )
        {
        CBTDevice* device = iBtDevArray->At(i);
        // show only paired and banned devices
        if ( device->IsPaired() || device->GlobalSecurity().Banned() )
            {
            devCount++;
            }
        }
    
    // Print info
    iStream->WriteUint8L( devCount );
    
    for ( TInt i=0 ; i<iBtDevArray->Count(); i++ )
        {
        CBTDevice* device = iBtDevArray->At(i);
        
        const TBTDeviceSecurity btSec = device->GlobalSecurity();
        
        // show only paired and banned devices
        if ( device->IsPaired() || btSec.Banned() )
            {
            LOGGER_WRITE_1("IsValidDeviceName: %d", device->IsValidDeviceName());
            const TDesC8& deviceName = device->DeviceName();
            LOGGER_WRITE8_1("DeviceName: %S", &deviceName );
            iStream->WriteUint8L( deviceName.Length() );
            iStream->WriteL( deviceName, deviceName.Length() );
            
            LOGGER_WRITE_1("IsValidFriendlyName: %d", device->IsValidFriendlyName());
            LOGGER_WRITE_1("FriendlyName: %S", &device->FriendlyName() );
            
            const TBTDevAddr& addr = device->BDAddr();
            
            TBuf<100> readable;
            addr.GetReadable( readable );
            LOGGER_WRITE_1("readable addr: %S", &readable);
            iStream->WriteUint8L( readable.Length() );
            iStream->WriteL( readable, readable.Length() );
            
            LOGGER_WRITE_1("paired: %d", device->IsPaired() );
            LOGGER_WRITE_1("IsValidPaired: %d", device->IsValidPaired() );
            TUint8 paired(0);
            if ( device->IsPaired() && device->IsValidPaired() )
                {
                paired = 1;
                }
            iStream->WriteUint8L( paired );
            
            TUint8 noAuthorise(0);
            if ( btSec.NoAuthorise() )
                {
                noAuthorise = 1;
                }
            iStream->WriteUint8L( noAuthorise );
            
            TUint8 banned(0);
            if ( btSec.Banned() )
                {
                banned = 1;
                }
            iStream->WriteUint8L( banned );
            
            LOGGER_WRITE("");
            }
        }
    iStream->CommitL();
    iStream = NULL; //delete reference only
    TRACE_FUNC_EXIT;
    }

// From MBTEngSettingsObserver
void CSconBtEngine::PowerStateChanged( TBTPowerStateValue /*aState*/ )
    {
    TRACE_FUNC;
    if ( iState == EChangeBtState && iWait.IsStarted() )
        {
        iWait.AsyncStop();
        }
    
    }

void CSconBtEngine::VisibilityModeChanged( TBTVisibilityMode /*aState*/ )
    {
    TRACE_FUNC;
    }