bluetoothengine/btnotif/btnotifsrv/src/btnotifserviceauthorizer.cpp
changeset 42 b72428996822
child 47 9e2a905b887f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/btnotif/btnotifsrv/src/btnotifserviceauthorizer.cpp	Mon Jul 12 18:51:05 2010 +0300
@@ -0,0 +1,302 @@
+/*
+* Copyright (c) 2010 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: class for prompting user to authorize a service
+*              connection request.
+*
+*/
+
+#include <hb/hbcore/hbsymbianvariant.h>
+#include <btengconnman.h>
+#include "btnotifserviceauthorizer.h"
+#include "btnotifsecuritymanager.h"
+#include "bluetoothtrace.h"
+#include "btnotifclientserver.h"
+#include "bluetoothnotification.h"
+#include "btnotifconnectiontracker.h"
+#include "btnotificationmanager.h"
+#include "bluetoothnotification.h"
+#include "btnotifserver.h"
+#include "btnotifutil.h"
+
+//
+// SDP UUID Constants - Short form
+// Taken from Bluetooth Profile specification v1.1
+// These are used when registering the service to
+// local SDP database and when searching the service
+// information from remote device.
+const TUint KBTSdpDun                   = 0x1103;
+const TUint KBTSdpGenericTelephony      = 0x1204;
+const TUint KBTSdpFax                   = 0x1111;
+const TUint KBTSdpObjectPush            = 0x1105;
+const TUint KBTSdpFileTransfer          = 0x1106;
+const TUint KBTSdpHeadSet               = 0x1108;
+const TUint KBTSdpGenericNetworking     = 0x1201;
+const TUint KBTSdpBasicImaging          = 0x111b;
+
+
+CBTNotifServiceAuthorizer* CBTNotifServiceAuthorizer::NewL(
+                                        CBTNotifSecurityManager& aParent)
+    {
+    CBTNotifServiceAuthorizer* me = new (ELeave) CBTNotifServiceAuthorizer(aParent);
+    CleanupStack::PushL(me);
+    me->ConstructL();
+    CleanupStack::Pop(me);
+    return me;
+    }
+
+CBTNotifServiceAuthorizer::~CBTNotifServiceAuthorizer()
+    {
+    iParams.Close();
+    if( iNotification )
+        {
+        // Clear the notification callback, we cannot receive them anymore.
+        iNotification->RemoveObserver();
+        iNotification->Close(); // Also dequeues the notification from the queue.
+        iNotification = NULL;
+        }
+    if ( !iNotifierMessage.IsNull() )
+        {
+        iNotifierMessage.Complete( KErrServerTerminated );
+        }
+    }
+
+CBTNotifServiceAuthorizer::CBTNotifServiceAuthorizer(
+                                        CBTNotifSecurityManager& aParent)
+:iParent(aParent)
+    {
+    }
+
+void CBTNotifServiceAuthorizer::ConstructL()
+    {
+    }
+
+void CBTNotifServiceAuthorizer::StartNotifierL(const RMessage2& aMessage)
+    {
+    if (!iNotifierMessage.IsNull())
+        {
+        if(aMessage.Function() == EBTNotifCancelNotifier)
+            {
+            TInt err = iNotification->Close();
+            iNotifierMessage.Complete(KErrCancel);
+            aMessage.Complete(err);
+            return;
+            }
+        BOstrace0(TRACE_DEBUG,DUMMY_DEVLIST,"[BTNotif]:We are busy");
+        User::Leave(KErrServerBusy );
+        }
+
+    iParams.ReAllocL( aMessage.GetDesLengthL( EBTNotifSrvParamSlot ) );
+    aMessage.ReadL( EBTNotifSrvParamSlot, iParams );
+    
+    TBTAuthorisationParams params;
+    TPckgC<TBTAuthorisationParams> paramsPckg( params );
+    paramsPckg.Set( iParams );
+    
+    iServiceId = paramsPckg().iUid.iUid;
+    
+    const CBtDevExtension* dev = NULL;
+    dev = iParent.BTDevRepository().Device(paramsPckg().iBDAddr);
+
+    if(dev && dev->Device().GlobalSecurity().Banned() )
+        {
+        // If the device is banned, service connection from
+        // this device is not allowed:
+        BOstrace0(TRACE_DEBUG,DUMMY_DEVLIST,"[BTNotif]:Device is banned");
+        aMessage.Complete( KErrCancel);
+        return;    
+        }
+
+    if(dev && dev->Device().GlobalSecurity().NoAuthorise())
+        {
+        // If the device is a trusted one, no need to pop up query messages.
+        TPckgBuf<TBool> answer;
+        answer() = ETrue;
+        aMessage.Write(EBTNotifSrvReplySlot, answer);
+        aMessage.Complete(KErrNone);
+        return;
+        }
+    
+    // User must namually authorize this request. 
+    // Get needed info for the dialog:
+    iPairedDevice = (dev == NULL ) ? EFalse : dev->IsUserAwareBonded();
+    iDeviceClass = (dev == NULL ) ? 0 : dev->Device().DeviceClass().DeviceClass();
+    TBTNotifUtil::GetDeviceUiNameL(iCurrentDeviceName, 
+            dev, paramsPckg().iName, paramsPckg().iBDAddr );
+
+    TBool autoAuthorize;
+    PrepareNotificationL(autoAuthorize,
+            TBluetoothDialogParams::EUserAuthorization, 
+            EAuthorization, iPairedDevice);
+    if ( autoAuthorize ) 
+        {
+        TPckgBuf<TBool> answer; 
+        answer() = ETrue;
+        aMessage.Write(EBTNotifSrvReplySlot, answer);
+        aMessage.Complete(KErrNone);
+        }
+    else 
+        {
+        iNotification->ShowL();
+        // we do not save the message until all leavable functions have executed successfully.
+        // This makes sure the iNotifierMessage has a valid handle.
+        iNotifierMessage = aMessage;
+        }
+    }
+
+void CBTNotifServiceAuthorizer::MBRDataReceived( CHbSymbianVariantMap& aData )
+    {
+    // "actionResult" will be true if the user clicks 'Yes' on the dialog and false, if he/she clicks 'No'
+    // "iCheckBoxState" will be set to true of the checkbox is checked, else false.
+    if(aData.Keys().MdcaPoint(0).Compare(_L("actionResult")) == 0)
+        {
+        TBTAuthorisationParams params;
+        TPckgC<TBTAuthorisationParams> paramsPckg(params);
+        paramsPckg.Set(iParams);
+
+        TPckgBuf<TBool> answer;
+        TInt val = *(static_cast<TInt*>(aData.Get(_L("actionResult"))->Data()));
+        if(val)
+            {
+            answer() = ETrue;
+            if(iCheckBoxState)
+                {
+                // Set the device "Trusted" property
+                iParent.TrustDevice(paramsPckg().iBDAddr);
+                }
+             }
+        else
+            {
+            answer() = EFalse;
+            if(iCheckBoxState)
+                {
+                // If the device is paried, unpair it as well.
+                if(iPairedDevice)
+                    {
+                    iParent.UnpairDevice(paramsPckg().iBDAddr);
+                    }
+                
+                //Set the device "Blocked" property
+                iParent.BlockDevice(paramsPckg().iBDAddr,ETrue);
+                }
+            }
+        if ( !iNotifierMessage.IsNull() )
+            {
+            iNotifierMessage.Write(EBTNotifSrvReplySlot, answer);
+            iNotifierMessage.Complete(KErrNone);
+            }
+        }
+    else if(aData.Keys().MdcaPoint(0).Compare(_L("checkBoxState")) == 0)
+        {
+        iCheckBoxState = *(static_cast<TInt*>(aData.Get(_L("checkBoxState"))->Data()));
+        }
+    }
+
+void CBTNotifServiceAuthorizer::MBRNotificationClosed( TInt aError, const TDesC8& aData )
+    {
+    (void) aError;
+    (void) aData;
+    iNotification->RemoveObserver();
+    iNotification = NULL;
+    }
+
+void CBTNotifServiceAuthorizer::PrepareNotificationL(TBool& aAutoAuthorize,
+        TBluetoothDialogParams::TBTDialogType aType,
+    TBTDialogResourceId aResourceId, TBool aPaired)
+    {
+    iNotification = iParent.ConnectionTracker().NotificationManager()->GetNotification();
+    User::LeaveIfNull( iNotification ); // For OOM exception, leaves with KErrNoMemory
+    iNotification->SetObserver( this );
+    iNotification->SetNotificationType( aType, aResourceId );
+    TInt err = KErrNone;
+    aAutoAuthorize = EFalse;
+    
+    //Set the dialog title based on the service IDs
+    switch(iServiceId)
+        {
+        case KBTSdpObjectPush:
+        case KBTSdpBasicImaging:
+            {
+            if(aPaired)
+                {
+                err = iNotification->SetData( TBluetoothDialogParams::EDialogTitle, TBluetoothDialogParams::EReceiveFromPairedDevice);
+                // In case of receiving a msg from a paired deivce, the checkbox is checked by default.
+                iCheckBoxState = ETrue;
+                User::LeaveIfError(err);
+                }
+            else
+                {
+                err = iNotification->SetData( TBluetoothDialogParams::EDialogTitle, TBluetoothDialogParams::EReceive);
+                iCheckBoxState = EFalse;
+                User::LeaveIfError(err);
+                }
+            }
+            break;
+            
+        case KBTSdpFax:
+        case KBTSdpDun:
+        case KBTSdpFileTransfer:
+        case KBTSdpHeadSet:
+        case KBTSdpGenericTelephony:
+        case KBTSdpGenericNetworking:
+            {
+            err = iNotification->SetData( TBluetoothDialogParams::EDialogTitle, TBluetoothDialogParams::EConnect);
+            // In case of an incoming connection, the checkbox is checked by default.
+            iCheckBoxState = ETrue;
+            User::LeaveIfError(err);
+            }
+            break;
+            
+        default:
+            {
+            TBTAuthorisationParams params;
+            TPckgC<TBTAuthorisationParams> paramsPckg(params);
+            paramsPckg.Set(iParams);
+            
+            // In this case, if there already exists a connection to an audio device, then we simply accept
+            // the incoming connection without querying the user.
+            // If there is no existing connection, then we pop up a query message.
+            if(IsExistingConnectionToAudioL(paramsPckg().iBDAddr))
+                {
+                aAutoAuthorize = ETrue;
+                return;
+                }
+            else
+                {
+                err = iNotification->SetData( TBluetoothDialogParams::EDialogTitle, TBluetoothDialogParams::EConnect);
+                // In case of an incoming connection, the checkbox is checked by default.
+                iCheckBoxState = ETrue;
+                User::LeaveIfError(err);
+                }
+            }
+            break;
+        }
+    
+    //Add the device name 
+    err = iNotification->SetData( TBluetoothDeviceDialog::EDeviceName, iCurrentDeviceName );
+    User::LeaveIfError(err);
+    //Add the device class
+    err = iNotification->SetData( TBluetoothDeviceDialog::EDeviceClass, iDeviceClass );
+    User::LeaveIfError(err);
+    
+    }
+
+TBool CBTNotifServiceAuthorizer::IsExistingConnectionToAudioL(const TBTDevAddr& aDevAddr)
+    {
+    CBTEngConnMan* connMan = CBTEngConnMan::NewL();
+    TBTEngConnectionStatus conntatus(EBTEngNotConnected);
+    (void) connMan->IsConnected(aDevAddr,conntatus);      
+    delete connMan;
+    return (conntatus==EBTEngConnected || conntatus==EBTEngConnecting);
+    }
+