btobexprofiles/obexreceiveservices/bip/src/BIPController.cpp
author hgs
Tue, 19 Oct 2010 15:09:34 +0300
changeset 70 f5508c13dfe0
parent 67 16e4b9007960
permissions -rw-r--r--
201041

/*
* Copyright (c) 2007-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:  Obex Server image receiver module implementation
*
*/


// INCLUDE FILES
#include    "BIPController.h"
#include    "BIPCapabilityHandler.h"
#include    "BIPImageHandler.h"


#include    <e32base.h>
#include    <obexutilsmessagehandler.h>
#include    <sysutil.h>
#include    <bautils.h>
#include    <driveinfo.h>                   
#include    <btengdomaincrkeys.h> 
#include    <e32math.h> 
#include    <es_sock.h>
#include    <bt_sock.h>
#include    <msvids.h>
#include    "debug.h"
#include    <bluetoothdevicedialogs.h>
#include    "btconversationviewlauncher.h"
        
// CONSTANTS
_LIT8(KBipCapabilityType, "x-bt/img-capabilities\0");
const TInt KFileManagerUID3 = 0x101F84EB; /// File Manager application UID3
const TInt    KBufferSize = 0x10000;  // 64 kB
_LIT( KBTDevDialogId, "com.nokia.hb.btdevicedialog/1.0" );
const TInt KMaxDisplayFileName = 20; 
const TInt KMinStringSize = 11;


// ================= MEMBER FUNCTIONS =======================

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

// ---------------------------------------------------------
// ConstructL()
// ---------------------------------------------------------
//
void CBIPController::ConstructL()
    {
    TRACE_FUNC_ENTRY
    iBIPImageHandler = CBIPImageHandler::NewL();
    iLowMemoryActiveCDrive = CObexUtilsPropertyNotifier::NewL(this, ECheckPhoneMemory);
    iLowMemoryActiveMMC = CObexUtilsPropertyNotifier::NewL(this, ECheckMMCMemory);
    iDevMan = CBTEngDevMan::NewL(this);
    iResultArray = new(ELeave) CBTDeviceArray(1);
    // Get default folder from CenRep 
    TObexUtilsMessageHandler::GetCenRepKeyStringValueL(KCRUidBluetoothEngine, KLCReceiveFolder, iCenRepFolder);
    iBtCnvViewLauncher = CBtConversationViewLauncher::NewL();
    TRACE_FUNC_EXIT
    }

// ---------------------------------------------------------
// ~CBIPController()
// ---------------------------------------------------------
//
CBIPController::~CBIPController()
    {   
    TRACE_FUNC_ENTRY    
    delete iGetObject;    
    delete iBIPCapabilityHandler;    
    delete iBIPImageHandler;    
    delete iLowMemoryActiveCDrive;    
    delete iLowMemoryActiveMMC;    
    delete iBuf;
    delete iBTObject;
    delete iDevMan;
    if (iResultArray)
        {
        iResultArray->ResetAndDestroy();
        delete iResultArray;
        }
    iFs.Close();
    
    delete iProgressDialog;
    delete iFailureDialog;
    delete iRecvDoneDialog;
    delete iMemoryFullDailog;
    delete iBtCnvViewLauncher;
    
    TRACE_FUNC_EXIT    
    }

// ---------------------------------------------------------
// ErrorIndication()
// ---------------------------------------------------------
//
void CBIPController::ErrorIndication(TInt TRACE_ONLY(aError))
    {
    TRACE_FUNC_ENTRY
    TRACE_ERROR((_L("[obexreceiveservicebip] CBIPController: ErrorIndication error:\t %d"), aError));
    HandleError(EFalse); // false because this is not an explicit abort
    TRACE_FUNC_EXIT
    }

// ---------------------------------------------------------
// AbortIndication()
// ---------------------------------------------------------
//
void CBIPController::AbortIndication()
    {
    TRACE_FUNC_ENTRY
    HandleError(ETrue); // true because this is an explicit abort
    TRACE_FUNC_EXIT
    }

void CBIPController::HandleError(TBool aAbort)
    {
    TRACE_FUNC_ENTRY
    iReceivingFailed = ETrue;
    iShowRecvCompleteDialog = EFalse;
    if( iBTTransferState == ETransferPut || (!aAbort && iBTTransferState == ETransferPutDiskError) )
        {
        CancelTransfer();

        TRAP_IGNORE( 
                    LaunchFailureDialogL();
                );
        
        if(iBTObject)
            {
            iBTObject->Reset();
            }
        } 
    delete iBuf;
    iBuf = NULL;
    
    iBTTransferState = ETransferIdle;
    TRAP_IGNORE(TObexUtilsMessageHandler::RemoveInboxEntriesL(iBTObject,iMsvIdParent));
    TRAP_IGNORE(TObexUtilsMessageHandler::RemoveTemporaryRFileL(iFullPathFilename));
    
    TRACE_FUNC_EXIT
    }

// ---------------------------------------------------------
// CancelTransfer()
// ---------------------------------------------------------
//
void CBIPController::CancelTransfer()
    {
    TRACE_FUNC_ENTRY
    CloseReceivingIndicator();
    if(iBTTransferState == ETransferPut)
        {
        iBTTransferState = ETransferPutCancel;
        }
    else // go to idle for all other states
        {
        iBTTransferState = ETransferIdle;
        }
    }
// ---------------------------------------------------------
// TransportUpIndication()
// ---------------------------------------------------------
//
void CBIPController::TransportUpIndication()
    {
    TRACE_FUNC
    iReceivingFailed = EFalse;
    if (!iFs.Handle())
        {
        TRACE_INFO( (_L( "[bipreceiveservice] TransportUpIndication iFs.Connect()" )) ); 
        if (iFs.Connect())   // error value not checked, iFs.Handle() checked one more time before first useage
            {
            TRACE_INFO( (_L( "[bipreceiveservice] TransportUpIndication iFs.Connect() failed" )) ); 
            }
        }
    
    iFile = RFile();
    iFullPathFilename.Zero();
    iCapabilityFileName.Zero();
    }

// ---------------------------------------------------------
// ObexConnectIndication()
// ---------------------------------------------------------
//
TInt CBIPController::ObexConnectIndication( const TObexConnectInfo& aRemoteInfo, const TDesC8& aInfo )
    {
    TRACE_FUNC
    
    (void) aRemoteInfo;
    (void) aInfo;
    
    // Get remote device socket address and bluetooth name
    // Remote bluetooth name will be displayed in the new message in inbox.
    //
    TSockAddr addr;
    iBTObexServer->RemoteAddr(addr);
    TBTDevAddr tBTDevAddr = static_cast<TBTSockAddr>(addr).BTAddr();
    
    TBTRegistrySearch nameSearch;
    nameSearch.FindAddress(tBTDevAddr);
    
    iResultArray->Reset();
    // Ignore any errors here, if we don't get the name, we don't get the name.
    // It is also possible that the name is received too late....
    static_cast<void>(iDevMan->GetDevices(nameSearch, iResultArray));
    
    return KErrNone;
    }

// ---------------------------------------------------------
// ObexDisconnectIndication()
// ---------------------------------------------------------
//
void CBIPController::ObexDisconnectIndication(const TDesC8& aInfo)
    {
    TRACE_FUNC
    (void) aInfo;
    }

// ---------------------------------------------------------
// TransportDownIndication()
// ---------------------------------------------------------
//
void CBIPController::TransportDownIndication()
    {
    TRACE_FUNC  
    if(!iReceivingFailed && iShowRecvCompleteDialog)
        {
        TFileName shortname;
        if ( iReceivingFileName.Length() > KMaxDisplayFileName ) 
            {
            // Filename is too long, 
            // We make it shorter. Hiding the chars in the middle part of filename. 
            shortname = iReceivingFileName.Mid(0,KMaxDisplayFileName/2);
            shortname.Append(_L("..."));
            shortname.Append(iReceivingFileName.Mid(iReceivingFileName.Length() - KMaxDisplayFileName/2, KMaxDisplayFileName/2));
            }
        else
            {
            shortname.Copy(iReceivingFileName);
            }

        //Launch recevice completed dialog.
        iRecvDoneDialog = CHbDeviceDialogSymbian::NewL();
        iRecvDoneDialog->SetObserver(this);
    
        CHbSymbianVariantMap* variantMap = CHbSymbianVariantMap::NewL();
        CleanupStack::PushL(variantMap);
        
        TInt dialogIdx = TBluetoothDialogParams::EReceiveDone;
        AddParamL(TBluetoothDialogParams::EDialogType, (TAny*) &dialogIdx,
                CHbSymbianVariant::EInt, *variantMap);
        
        AddParamL(TBluetoothDeviceDialog::EDeviceName, (TAny*) &iRemoteDeviceName,
                CHbSymbianVariant::EDes, *variantMap);
        
        AddParamL(TBluetoothDeviceDialog::EReceivingFileName, (TAny*) &shortname,
                CHbSymbianVariant::EDes, *variantMap);
        
        AddParamL(TBluetoothDeviceDialog::EReceivingFileSize, (TAny*) &iTotalSizeByte,
                CHbSymbianVariant::EInt, *variantMap);
        
        AddParamL(TBluetoothDeviceDialog::EReceivedFileCount, (TAny*) &iFileCount,
                CHbSymbianVariant::EInt, *variantMap);
        
        TBuf<KMinStringSize> key(_L("OpenCnvView"));
        TBool option = ETrue;
        CHbSymbianVariant* value = CHbSymbianVariant::NewL( (TAny*) &option, CHbSymbianVariant::EBool );
        CleanupStack::PushL(value);
        variantMap->Add(key, value);
        CleanupStack::Pop(value);

        iRecvDoneDialog->Show( KBTDevDialogId(), *variantMap, this );
        CleanupStack::PopAndDestroy(variantMap);
        
        iShowRecvCompleteDialog = EFalse;
        }
    
    // Remove receiving buffer and files used during file receiving.
    //
    delete iBTObject;
    iBTObject = NULL;
    TRAP_IGNORE(TObexUtilsMessageHandler::RemoveTemporaryRFileL (iFullPathFilename));  
    iFs.Close();
    iFileCount = 0;
    }

// ---------------------------------------------------------
// PutRequestIndication()
// ---------------------------------------------------------
//
CObexBufObject* CBIPController::PutRequestIndication()
    {   
    TRACE_FUNC_ENTRY
    iLengthHeaderReceived = EFalse; // New put request so clear header based state
    iBTTransferState = ETransferPut;
    
    // Checking if backup is running now - if backup process is active, then we
    // need to cancel transfer - otherwise phone will freeze during receiving
    // data
    if ( IsBackupRunning() )
        {
        TRACE_INFO ( _L ("Backup in progress! Canceling incoming transfer."));
        iBTTransferState = ETransferPutInitError;
        return NULL;
        }
        
    TRAPD(err, HandlePutImageRequestL());
    if (err == KErrNone)
        {
        return iBTObject;
        }
    if (iBTTransferState != ETransferPutInitError)
        {
        iBTTransferState = ETransferPutDiskError;
        }
    TRACE_FUNC_EXIT
    return NULL;
    }

// ---------------------------------------------------------
// PutPacketIndication() 
// ---------------------------------------------------------
//
TInt CBIPController::PutPacketIndication()
    {
    TRACE_FUNC_ENTRY
    if(iBTTransferState == ETransferPutCancel)
        {
        // User cancelled the put request, so error the next packet to terminate the put request.
        // BIP considers the Unauthorized error response suitable for this...
        HandleError(ETrue); // reset state and clear up
        return KErrIrObexRespUnauthorized;
        }
    
    // For every packet received, this check is required to ensure that the case where the 
    // memory card is removed while a transfer is in progress is handled in the right way.
    TVolumeInfo volInfo;
    TInt err = iFs.Volume(volInfo, iDrive);
    if(err != KErrNone)
        {
        HandleError(ETrue);
        return err;
        }
    
    if (iBTObject)
        {
        iTotalSizeByte = iBTObject->Length();     // get size of receiving file
        iReceivingFileName = iBTObject->Name();   // get name of receiving file
        
        // Check that capacity is suitable as soon as possible
        if(!iLengthHeaderReceived && iTotalSizeByte > 0)
            {
            iLengthHeaderReceived = ETrue; // total size value is from length header
            TBool capacity = ETrue;
            TRAPD(retTrap, capacity = CheckCapacityL());
            if(retTrap != KErrNone)
                {
                return KErrGeneral;
                }
            if(!capacity)
                {
                //TRAP_IGNORE(TObexUtilsUiLayer::ShowGlobalConfirmationQueryL(R_OUT_OF_MEMORY));
                //todo: Need to use Localized string.
                //_LIT(KText, "Not enough memory to execute operation. Delete some documents and try again.");
                //TRAP_IGNORE(iDialog->ShowErrorNoteL(KText));
                LaunchMemoryFullDialogL(iDrive);
    
                return KErrDiskFull;
                }
            }
        if(iBTObject->Name().Length() > KMaxFileName)
            {
            return KErrAccessDenied;
            }
        if(iBTTransferState == ETransferPutDiskError)
            {
            return KErrDiskFull;
            }
        // successfully received put packet if we reached here
        iBTTransferState = ETransferPut;
        
        // Now we need to either create (in the first instance) or update the dialog on the UI.
        if(ReceivingIndicatorActive())
            {
            TRAPD(err, UpdateReceivingIndicatorL());
            if(err < KErrNone)
                {
                return err;
                }
            }
        else if(!iNoteDisplayed)
            {
            // No note launched yet, so try to launch
            TRAPD(err, LaunchReceivingIndicatorL());
            iNoteDisplayed = (err == KErrNone);
            }
        }
    
    TRACE_FUNC_EXIT
    return KErrNone;
    }

// ---------------------------------------------------------
// PutCompleteIndication() 
// ---------------------------------------------------------
//
TInt CBIPController::PutCompleteIndication()  // Once receive has completed.
    {
    TRACE_FUNC_ENTRY
    TInt retVal = KErrNone;
    if(iBTTransferState == ETransferPutCancel)
        {
        retVal = KErrIrObexRespUnauthorized;
        HandleError(ETrue);
        }
    else
        {
        retVal = HandlePutCompleteIndication();
        iBTTransferState = ETransferIdle;
        CloseReceivingIndicator();
        iFileCount++;
        iShowRecvCompleteDialog = ETrue;
        }
    TRACE_FUNC_EXIT
    return retVal;
    }

// ---------------------------------------------------------
// GetRequestIndication()
// ---------------------------------------------------------
//
CObexBufObject* CBIPController::GetRequestIndication( CObexBaseObject* aRequiredObject )
    {
    TRACE_FUNC_ENTRY
    iBTTransferState = ETransferGet;
    TInt err = RemoveCapabilityObject();
    if (err == KErrNone)
        {
        if( aRequiredObject->Type() == KBipCapabilityType )
            {
            TRAP( err, HandleGetCapabilityRequestL( ) );
            if( err == KErrNone )
                {
                return iGetObject;
                }
            }
        }
    TRACE_FUNC_EXIT
    return NULL;
    }

// ---------------------------------------------------------
// GetPacketIndication()
// ---------------------------------------------------------
//
TInt CBIPController::GetPacketIndication()
    {
    TRACE_FUNC_ENTRY
    return KErrNone;
    }

// ---------------------------------------------------------
// GetCompleteIndication()
// ---------------------------------------------------------
//
TInt CBIPController::GetCompleteIndication()
    {
    TRACE_FUNC_ENTRY
    delete iGetObject;
    iGetObject=NULL;
    TInt err = RemoveCapabilityObject();
    if (err != KErrNone)
        {
        err = KErrGeneral;
        }
    iBTTransferState = ETransferIdle;
    TRACE_FUNC_EXIT
    return err;
    }

// ---------------------------------------------------------
// SetPathIndication()
// ---------------------------------------------------------
//
TInt CBIPController::SetPathIndication( const CObex::TSetPathInfo& aPathInfo, 
                                        const TDesC8& aInfo)
    {
    TRACE_FUNC
    // SetPath is not implemented in BIP - so following IrOBEX guidance, return
    // the Forbidden response code.
    (void) aPathInfo;
    (void) aInfo;
    
    return KErrIrObexRespForbidden;
    }

/**
* This function is implementation for mixin-class for Obexutils.
* It is called every time another instance modifies disk status,
* for example when it cross warning/critical level.
* Parameters:
* @param aCheckType             Disktype changes.
*/
void CBIPController::HandleNotifyL(TMemoryPropertyCheckType aCheckType)
    {    
    TRACE_FUNC_ENTRY    
    // Only interested on this notification if we are receiving something
    if ( iBTTransferState == ETransferPut )
        {
       // Check the keys, what has been changed.
       if ( aCheckType == ECheckPhoneMemory )
           {
           if ( SysUtil::FFSSpaceBelowCriticalLevelL( NULL, 0 ) )
               {                
               TRACE_INFO( _L( "[obexreceiveservicebip] CBIPController: Obex Server error diskfull:\t" ) );
               iBTTransferState = ETransferPutDiskError;
               }
           }
       else if ( aCheckType == ECheckMMCMemory )
           {                
           if ( SysUtil::MMCSpaceBelowCriticalLevelL( NULL, 0 ) )
               {                    
               TRACE_INFO( _L( "[obexreceiveservicebip] CBIPController: Obex Server error diskfull:\t" ) );
               iBTTransferState = ETransferPutDiskError;
               }
           }            
        }        
    TRACE_FUNC_EXIT    
    }
    
// ---------------------------------------------------------
// HandleGetCapabilityRequestL()
// ---------------------------------------------------------
//
void CBIPController::HandleGetCapabilityRequestL()
    {
    TRACE_FUNC_ENTRY    
    CBIPCapabilityHandler* capHandler = CBIPCapabilityHandler::NewL();
    CleanupStack::PushL(capHandler);
    capHandler->CreateCapabilityObjectL(iCapabilityFileName);
    delete iGetObject;
    iGetObject = NULL; 
    iGetObject = CObexBufObject::NewL(NULL);
    iGetObject->SetDataBufL(iCapabilityFileName);
    CleanupStack::PopAndDestroy(capHandler);
    TRACE_FUNC_EXIT
    }

// ---------------------------------------------------------
// HandlePutImageRequest()
// ---------------------------------------------------------
//
void CBIPController::HandlePutImageRequestL()
    {
    TRACE_FUNC_ENTRY
    
    delete iBTObject;
    iBTObject = NULL;

    if (!iFs.Handle())
        {
        User::Leave(KErrGeneral);
        }
    
    // Assign an initial value to iDrive
    iDrive = GetDriveWithMaximumFreeSpaceL();    
    
    // If iDrive is at critical space level, we immediately show out_of_memory.
    //
    if (SysUtil::DiskSpaceBelowCriticalLevelL(&iFs, 0, iDrive))
        {
        //TRAP_IGNORE(TObexUtilsUiLayer::ShowGlobalConfirmationQueryL(R_OUT_OF_MEMORY));
        //todo: Need to use Localized string.
        //_LIT(KText, "Not enough memory to execute operation. Delete some documents and try again.");
        //TRAP_IGNORE(iDialog->ShowErrorNoteL(KText));
        
        LaunchMemoryFullDialogL(iDrive);
        User::Leave(KErrGeneral);
        }
    
    iBTObject = CObexBufObject::NewL(NULL);    
    
    delete iBuf;
    iBuf = NULL;
    
    TChar driveLetter;
    iDefaultFolder.Zero();
    iFs.DriveToChar(iDrive, driveLetter);
    iDefaultFolder.Append(driveLetter);
    if ( iDrive == EDriveC )
        {
        iDefaultFolder.Append(_L(":\\data\\"));
        }
    else
        {
        iDefaultFolder.Append(_L(":\\"));
        }
    
    iDefaultFolder.Append(iCenRepFolder);
    
    iFile = RFile();
    iFullPathFilename.Zero();
    TObexUtilsMessageHandler::CreateReceiveBufferAndRFileL(iFile, iDefaultFolder, iFullPathFilename, iBuf, KBufferSize);
    User::LeaveIfError(iFile.Open(iFs, iFullPathFilename, EFileWrite));
    TObexRFileBackedBuffer bufferdetails(*iBuf, iFile, CObexBufObject::EDoubleBuffering);
    TRAPD(err, iBTObject->SetDataBufL(bufferdetails));
    if (err != KErrNone)
        {
        iBTTransferState = ETransferPutInitError;
        User::Leave(KErrGeneral); 
        }
        
    TRACE_FUNC_EXIT
    }


// ---------------------------------------------------------
// HandlePutCompleteIndication()
// ---------------------------------------------------------
//
TInt CBIPController::HandlePutCompleteIndication()
	{
    TRACE_FUNC_ENTRY
    TInt retVal = KErrNone;

    // Before saving the file received, this check is required to ensure that the case where the 
    // memory card is removed while a transfer is in progress is handled in the right way.
    TVolumeInfo volInfo;
    retVal = iFs.Volume(volInfo, iDrive);
    if(retVal != KErrNone)
        {
        TRACE_ERROR((_L( "[obexreceiveservicebip] CBIPController: HandlePutCompleteIndication error:\t %d" ), retVal ) );              
        HandleError(ETrue);
        
        // Even if the object saving fails we must return image handle with error code
        TRAP_IGNORE( iBIPImageHandler->AddImageHandleHeaderL( iBTObexServer ) );            
        
        TRACE_INFO( _L( "[obexreceiveservicebip] HandlePutCompleteIndication Done\t" ) );
        
        delete iBTObject;
        iBTObject = NULL;
        
        delete iBuf;
        iBuf = NULL;
        
        iPreviousDefaultFolder = iDefaultFolder;  // save the last file path where file is successfully saved to file system.
        iMsvIdParent = KMsvNullIndexEntryId;
        
        TRACE_FUNC_EXIT    
        
        return retVal;
        }

    iDefaultFolder.Zero();
    TChar driveLetter;
    if ( iDrive == EDriveC )
        {
        iFs.DriveToChar(iDrive, driveLetter);
        iDefaultFolder.Append(driveLetter);
        iDefaultFolder.Append(_L(":\\data\\"));
        iDefaultFolder.Append(iCenRepFolder);
        }
    else
        {
        iFs.DriveToChar(iDrive, driveLetter);
        iDefaultFolder.Append(driveLetter);
        iDefaultFolder.Append(_L(":\\"));
        iDefaultFolder.Append(iCenRepFolder);
        }
    
    iFullPathFilename.Zero();
    iFullPathFilename.Append(iDefaultFolder);
    TRAP ( retVal, TObexUtilsMessageHandler::SaveFileToFileSystemL(iBTObject,
                                                                   KUidMsgTypeBt,
                                                                   iMsvIdParent,
                                                                   iFullPathFilename,
                                                                   iFile,
                                                                   iRemoteDeviceName));
    if ( retVal == KErrNone)
        {
        TRAP (retVal, TObexUtilsMessageHandler::AddEntryToInboxL(iMsvIdParent, iFullPathFilename));
        
        if( retVal != KErrNone )
            {
            TRACE_ERROR((_L( "[obexreceiveservicebip] CBIPController: HandlePutCompleteIndication error:\t %d" ), retVal ) );              
            TRAP( retVal, TObexUtilsMessageHandler::RemoveInboxEntriesL(iBTObject, iMsvIdParent));
            retVal = KErrDiskFull;
            }
        }
    
    // Even if the object saving fails we must return image handle with error code
    TRAP_IGNORE( iBIPImageHandler->AddImageHandleHeaderL( iBTObexServer ) );            
    TRACE_INFO( _L( "[obexreceiveservicebip] HandlePutCompleteIndication Done\t" ) );
    delete iBTObject;
    iBTObject = NULL;
    delete iBuf;
    iBuf = NULL;
    iPreviousDefaultFolder = iDefaultFolder;  // save the last file path where file is successfully saved to file system.
    iMsvIdParent = KMsvNullIndexEntryId;
    TRACE_FUNC_EXIT     
    return retVal;
	}
// ---------------------------------------------------------
// RemoveCapabilityObject()
// ---------------------------------------------------------
//		
TInt CBIPController::RemoveCapabilityObject()
    {
    TRACE_FUNC_ENTRY
    if ( (iCapabilityFileName.Compare(KNullDesC)) == 0 )
        {
        return KErrNone; 
        }     
    if ( !iFs.Handle() )
        {
        TRACE_INFO( (_L( "[bipreceiveservice] RemoveCapabilityObject return" )) ); 
        return KErrGeneral;
        }               
    iFs.Delete(iCapabilityFileName);        
    iCapabilityFileName=KNullDesC; 
    TRACE_FUNC_EXIT 
    return KErrNone;    
    }
	 
// ---------------------------------------------------------
// CheckCapacity()
// ---------------------------------------------------------
//	    
TBool CBIPController::CheckCapacityL()
    {
    TRACE_FUNC_ENTRY   
    
    iDrive = EDriveZ; // Intialize iDrive to Z
    TInt filesize = iBTObject->Length();
    
    TInt mmcDrive = KDefaultDrive;   // External memory card  
    TInt imsDrive = KDefaultDrive;   // Internal mass storage
    
    User::LeaveIfError(DriveInfo::GetDefaultDrive(DriveInfo::EDefaultMassStorage, imsDrive));
    User::LeaveIfError(DriveInfo::GetDefaultDrive(DriveInfo::EDefaultRemovableMassStorage, mmcDrive));      
     
    TRACE_INFO( (_L( "[oppreceiveservice] CheckCapacityL imsDrive=%d; mmcDrive=%d\t" ),imsDrive, mmcDrive ) );

    TVolumeInfo volumeInfo;
    TInt err = iFs.Volume(volumeInfo, imsDrive);
    
    // If err != KErrNone, Drive is not available.
    //
    if ( !err )
        {
        // Check capacity on Internal mass storage            
        TRACE_INFO( (_L( "[obexreceiveservicebip] CheckCapacityL Internal mass storage \t" )) );
        if ( !SysUtil::DiskSpaceBelowCriticalLevelL( &iFs, filesize, imsDrive ) )
            {
            iDrive = imsDrive;            
            }
        }
    if ( iDrive == EDriveZ )
        {
        err = iFs.Volume(volumeInfo, mmcDrive);
        if ( !err )
            {
            // Check capacity on memory card    
            TRACE_INFO( (_L( "[obexreceiveservicebip] CheckCapacityL Checking memory card\t" )) );
            if ( !SysUtil::DiskSpaceBelowCriticalLevelL( &iFs, filesize, mmcDrive ) )
                {                    
                iDrive = mmcDrive;
                }   
            }
        }           
    if ( iDrive == EDriveZ )
        {
        TRACE_INFO( (_L( "[obexreceiveservicebip] CheckCapacityL Checking phone memory\t" )) );
        // Phone memory
        if( !SysUtil::DiskSpaceBelowCriticalLevelL( &iFs, filesize, EDriveC ))
            {
            iDrive = EDriveC;
            }
        }
  
    TRACE_INFO( (_L( "[obexreceiveservicebip] CheckCapacityL iDrive = %d\t" ),iDrive ) );                   
    TRACE_FUNC_EXIT
    
    if (iDrive == EDriveZ)
        {
        // If there is no free space for receiving file, we need to set iPreviousDefaultFolder back to iDefaultFolder.
        // In order to show the file receveing dialog correctly.
        iDefaultFolder = iPreviousDefaultFolder;
        return EFalse;
        }
    return ETrue;
    }    


// ---------------------------------------------------------
// IsOBEXActive()
// ---------------------------------------------------------
//
TBool CBIPController::IsOBEXActive()
    {    
    TRACE_FUNC    
    return ETrue;
    }

// ---------------------------------------------------------
// SetMediaType()
// ---------------------------------------------------------
//
void CBIPController::SetMediaType( TSrcsMediaType __DEBUG_ONLY(aMediaType) ) 
    {
    TRACE_FUNC
    // BIP is only for Bluetooth, so that is all we expect
    __ASSERT_DEBUG(aMediaType == ESrcsMediaBT, User::Panic(KBipPanicCategory, EBipPanicNotBluetoothMediaType));
    }

// ---------------------------------------------------------
// SetObexServer()
// ---------------------------------------------------------
//
TInt CBIPController::SetObexServer( CObexServer* aServer)
    {
    TInt retVal=KErrNone;
    if (aServer)
        {
        iBTObexServer=aServer;
        retVal=aServer->Start(this);
        }
    return retVal;
    }    

void CBIPController::LaunchReceivingIndicatorL()
    {
    if(ReceivingIndicatorActive())
        {
        return;
        }
    
    if(iTotalSizeByte > 0)
        {
        if(iReceivingFileName.Length() > 0)
            {
            TFileName shortname;
            if ( iReceivingFileName.Length() > KMaxDisplayFileName ) 
                {
                // Filename is too long, 
                // We make it shorter. Hiding the chars in the middle part of filename. 
                shortname = iReceivingFileName.Mid(0,KMaxDisplayFileName/2);
                shortname.Append(_L("..."));
                shortname.Append(iReceivingFileName.Mid(iReceivingFileName.Length() - KMaxDisplayFileName/2, KMaxDisplayFileName/2));
                }
            else
                {
                shortname.Copy(iReceivingFileName);
                }

            iProgressDialog = CHbDeviceDialogSymbian::NewL();
            iProgressDialog->SetObserver(this);
    
            CHbSymbianVariantMap* variantMap = CHbSymbianVariantMap::NewL();
            CleanupStack::PushL(variantMap);
            
            TInt dialogIdx = TBluetoothDialogParams::EReceiveProgress;
            AddParamL(TBluetoothDialogParams::EDialogType, (TAny*) &dialogIdx, 
                    CHbSymbianVariant::EInt, *variantMap);
            
            AddParamL(TBluetoothDeviceDialog::EDeviceName, (TAny*) &iRemoteDeviceName,
                    CHbSymbianVariant::EDes, *variantMap);
            
            AddParamL(TBluetoothDeviceDialog::EReceivingFileName, (TAny*) &shortname,
                    CHbSymbianVariant::EDes, *variantMap);
            
            AddParamL(TBluetoothDeviceDialog::EReceivingFileSize, (TAny*) &iTotalSizeByte,
                    CHbSymbianVariant::EInt, *variantMap);
            
            AddParamL(TBluetoothDeviceDialog::EReceivedFileCount, (TAny*) &iFileCount,
                    CHbSymbianVariant::EInt, *variantMap);

            iDialogActive = ETrue;
            iProgressDialog->Show( KBTDevDialogId(), *variantMap, this );
            CleanupStack::PopAndDestroy(variantMap);
            }
        else
            {
            // TODO
            iDialogActive = ETrue;
            }
        }
    else
        {
        iDialogActive = ETrue;
        /*
         * TODO - The functionality provided by CGlobalDialog will be removed
         * TODO - and this will be provided by CGlobalProgressDialog.
         */
        
        }
    }

void CBIPController::UpdateReceivingIndicatorL()
    {
    if(iProgressDialog)
        {
        CHbSymbianVariantMap* variantMap = CHbSymbianVariantMap::NewL();
        CleanupStack::PushL(variantMap);
        
        TInt bytesReceived = iBTObject->BytesReceived();
        CHbSymbianVariant* progress = CHbSymbianVariant::NewL( (TAny*) &bytesReceived, CHbSymbianVariant::EInt );
        CleanupStack::PushL(progress);
        User::LeaveIfError(variantMap->Add(_L("progress"), progress));
        CleanupStack::Pop(progress);

        iProgressDialog->Update(*variantMap);
        CleanupStack::PopAndDestroy(variantMap);
        }
    }

void CBIPController::CloseReceivingIndicator(TBool aResetDisplayedState)
    {
    TRACE_FUNC
    if(aResetDisplayedState)
        {
        iNoteDisplayed = EFalse;
        }
    if(iProgressDialog)
        {
        iProgressDialog->Cancel();
        iDialogActive = EFalse;
        delete iProgressDialog;
        iProgressDialog = NULL;
        }
    }
 
 // ---------------------------------------------------------
 // GetDriveWithMaximumFreeSpace()
 // ---------------------------------------------------------
 // 
 TInt CBIPController::GetDriveWithMaximumFreeSpaceL()
     {
     // Get drive with maximum freespace among phone memory, MMC, internal mass storage.
     //
      TRACE_FUNC   
     
     TVolumeInfo volumeInfoC;
     TVolumeInfo volumeInfoE;
     TVolumeInfo volumeInfoF;
     TInt64 max = 0;
     TInt drive = 0;
     
     TInt err = iFs.Volume(volumeInfoC, EDriveC);
    
     if ( !err )
         {
         // set initial values to max and drive.
         max = volumeInfoC.iFree;
         drive = EDriveC;
         }
          
     err = iFs.Volume(volumeInfoE, EDriveE);     
     if ( !err )
         {
         if (volumeInfoE.iFree >= max)
             {
             max = volumeInfoE.iFree;
             drive = EDriveE;             
             }
         
         }
          
     err = iFs.Volume(volumeInfoF, EDriveF);
     if ( !err )
         {
         if (volumeInfoF.iFree >= max)
             {
             max = volumeInfoF.iFree;
             drive = EDriveF;             
             }
         }
     max = 0;
     return drive;
     }
 
 // ----------------------------------------------------------
 // COPPController::HandleDevManComplete
 // Callback from devman
 // ----------------------------------------------------------
 //    
 // 
 void CBIPController::HandleGetDevicesComplete(TInt aErr, CBTDeviceArray* aDeviceArray)
    {
    (void) aDeviceArray;
     
    if ( aErr == KErrNone )
        {
        if ( iResultArray->Count())
            {
            iRemoteDeviceName.Zero();
            if ( iResultArray->At(0)->FriendlyName().Length() > 0 )
                {
                TRACE_INFO( _L( "[CBIPController] HandleGetDevicesComplete: got friendly name \t" ) );
                iRemoteDeviceName.Copy(iResultArray->At(0)->FriendlyName());
                }
            else
                {
                TRACE_INFO( _L( "[CBIPController] HandleGetDevicesComplete: got devciename name \t" ) );                
                TRAP_IGNORE(iRemoteDeviceName.Copy(BTDeviceNameConverter::ToUnicodeL(iResultArray->At(0)->DeviceName())));
                }
            }
        }
    }
 
 TBool CBIPController::IsBackupRunning()
    {
    const TUint32 KFileManagerBkupStatus = 0x00000001;
    
    TInt status = EFileManagerBkupStatusUnset;
    TBool retValue = EFalse;
    TInt err = RProperty::Get( TUid::Uid(KFileManagerUID3), KFileManagerBkupStatus,
                              status );
    if ( err == KErrNone )
        {
        if ( status == EFileManagerBkupStatusBackup || 
             status == EFileManagerBkupStatusRestore )
            {
            TSecureId fileManagerSecureId( KFileManagerUID3 );
            //only returning ETrue if backup process is still active
            retValue = ProcessExists( fileManagerSecureId );
            }
        }
   
    return retValue;
    }
 
 TBool CBIPController::ProcessExists( const TSecureId& aSecureId )
     {
     _LIT( KFindPattern, "*" );
     TFindProcess finder(KFindPattern);
     TFullName processName;
     while( finder.Next( processName ) == KErrNone )
         {
         RProcess process;
         if ( process.Open( processName ) == KErrNone )
             {
             TSecureId processId( process.SecureId() );
             process.Close();
             if( processId == aSecureId )
                 {
                 return ETrue;
                 }
             }
         }
     return EFalse;
     }
 
 void CBIPController::DataReceived(CHbSymbianVariantMap& aData)
     {
     if(aData.Keys().MdcaPoint(0).Compare(_L("actionResult")) == 0)
         {
         TInt val = *(static_cast<TInt*>(aData.Get(_L("actionResult"))->Data()));
         switch(val)
             {
             case TBluetoothDialogParams::ECancelReceive:
                 {
                 //User choose to cancel receiving.
                 CancelTransfer();
                 }break;
                 
             case TBluetoothDialogParams::EHide:
                 {
                 //Use choose to hide the progress dialog.
                 CloseReceivingIndicator(EFalse);
                 }break;
                 
             case TBluetoothDialogParams::EShow:
                 {
                 TRAP_IGNORE(iBtCnvViewLauncher->LaunchConversationViewL());
                 }
             //No break statement after the preview case since the receive dialog must be closed anyway    
             case TBluetoothDialogParams::ECancelShow:
                 {
                 //In case of Show, the device dialog will handle the opening of conversation view.
                 iRecvDoneDialog->Cancel();
                 delete iRecvDoneDialog;
                 iRecvDoneDialog = NULL;
                 }break;
             default:
                 break;
             }
         }
     }
 
 void CBIPController::DeviceDialogClosed(TInt aCompletionCode)
     {
     (void) aCompletionCode;
     }

 void CBIPController::LaunchFailureDialogL()
     {
     if(iFailureDialog)
         {
         iFailureDialog->Cancel();
         delete iFailureDialog;
         iFailureDialog = NULL;
         }

     iFailureDialog = CHbDeviceDialogSymbian::NewL();
     
     CHbSymbianVariantMap* variantMap = CHbSymbianVariantMap::NewL();
     CleanupStack::PushL(variantMap);
     
     TInt dialogIdx = TBluetoothDialogParams::EInformationDialog;
     AddParamL(TBluetoothDialogParams::EDialogType, (TAny*) &dialogIdx,
             CHbSymbianVariant::EInt, *variantMap);
     
     AddParamL(TBluetoothDeviceDialog::EDeviceName, (TAny*) &iRemoteDeviceName,
             CHbSymbianVariant::EDes, *variantMap);
     
     TInt dialogTitleIdx = TBluetoothDialogParams::ERecvFailed;
     AddParamL(TBluetoothDialogParams::EDialogTitle, (TAny*) &dialogTitleIdx,
             CHbSymbianVariant::EInt, *variantMap);
     
     TUint32 deviceClass = iResultArray->At(0)->DeviceClass().DeviceClass();
     AddParamL(TBluetoothDeviceDialog::EDeviceClass, (TAny*) &deviceClass,
             CHbSymbianVariant::EInt, *variantMap);
     
     iFailureDialog->Show( KBTDevDialogId(), *variantMap );
     CleanupStack::PopAndDestroy(variantMap);
     
     iReceivingFailed = EFalse;
     }
 
 void CBIPController::LaunchMemoryFullDialogL(TInt aDrive)
     {
     if(iMemoryFullDailog)
         {
         iMemoryFullDailog->Cancel();
         delete iMemoryFullDailog;
         iMemoryFullDailog = NULL;
         }

     iMemoryFullDailog = CHbDeviceDialogSymbian::NewL();
     
     CHbSymbianVariantMap* variantMap = CHbSymbianVariantMap::NewL();
     CleanupStack::PushL(variantMap);
     
     TInt dialogIdx = TBluetoothDialogParams::EInformationDialog;
     AddParamL(TBluetoothDialogParams::EDialogType, (TAny*) &dialogIdx,
             CHbSymbianVariant::EInt, *variantMap);
     
     TInt dialogTitleIdx = TBluetoothDialogParams::EMemoryFull;
     AddParamL(TBluetoothDialogParams::EDialogTitle, (TAny*) &dialogTitleIdx,
             CHbSymbianVariant::EInt, *variantMap);
     
     TChar driveLetter;
     iFs.DriveToChar(aDrive, driveLetter);
     AddParamL(TBluetoothDeviceDialog::EDriveLetter, (TAny*) &driveLetter,
             CHbSymbianVariant::EChar, *variantMap);
     
     TVolumeInfo volumeInfo;
     iFs.Volume(volumeInfo, aDrive);
     AddParamL(TBluetoothDeviceDialog::EDriveName, (TAny*) &(volumeInfo.iName),
             CHbSymbianVariant::EDes, *variantMap);
     
     iMemoryFullDailog->Show( KBTDevDialogId(), *variantMap );
     CleanupStack::PopAndDestroy(variantMap);
     }

 void CBIPController::AddParamL(const TInt aKey, const TAny* aValue, 
         CHbSymbianVariant::TType aValueType,  CHbSymbianVariantMap& aVariantMap)
     {
     //Prepare the key
     TBuf<KMinStringSize> key;
     key.Num(aKey);
     
     //Prepare the value
     CHbSymbianVariant* value = CHbSymbianVariant::NewL( aValue, aValueType );
     CleanupStack::PushL(value);
     
     //add the key-value pair to the variant map
     User::LeaveIfError(aVariantMap.Add(key, value));
     
     CleanupStack::Pop(value);
     }
 
 //////////////////////////// Global part ////////////////////////////

//  End of File