diff -r 000000000000 -r c3e98f10fcf4 localconnectivityservice/obexserviceman/utils/src/obexutilsmessagehandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/localconnectivityservice/obexserviceman/utils/src/obexutilsmessagehandler.cpp Mon Jan 18 21:03:15 2010 +0200 @@ -0,0 +1,1582 @@ +/* +* Copyright (c) 2002 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: +* +*/ + + +// INCLUDE FILES +#include "obexutilsmessagehandler.h" +#include "obexutilsuilayer.h" +#include "obexutilsdebug.h" +#include "obexutilsentryhandler.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include "updatemusiccollection.h" + +#include // provides interface for quering system paths + +#ifdef __BT_SAP + #include "vMessageHandler.h" +#endif // __BT_SAP + +// CONSTANT +const TInt KFFSBelowCritical = -2; +const TInt KRenameOffSet = 4 ; +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// RemoveObexBuffer Removes Obex buffer object. +// ----------------------------------------------------------------------------- +// +void TObexUtilsMessageHandler::RemoveObexBuffer(CObexBufObject* &aBufObject) + { + if (aBufObject) + { + delete aBufObject; + aBufObject = NULL; + } + } + +// ----------------------------------------------------------------------------- +// CreateMsvSessionLC Creates MSV session +// ----------------------------------------------------------------------------- +// +void TObexUtilsMessageHandler::CreateMsvSessionLC( + CDummySessionObserver* &aSessionObs, + CMsvSession* &aMsvSession) + { + aSessionObs = new( ELeave )CDummySessionObserver; + CleanupStack::PushL( aSessionObs ); //1st push + aMsvSession = CMsvSession::OpenSyncL( *aSessionObs ); + CleanupStack::PushL( aMsvSession ); //2nd push + } + +// ----------------------------------------------------------------------------- +// CreateMsvSessionLC Creates MSV session to selected destination +// ----------------------------------------------------------------------------- +// +void TObexUtilsMessageHandler::CreateMsvSessionLC( + CDummySessionObserver* &aSessionObs, + CMsvSession* &aMsvSession, + CMsvEntry* &aDestination, + TMsvId aMsvId) + { + CreateMsvSessionLC(aSessionObs, aMsvSession); + aDestination = aMsvSession->GetEntryL( aMsvId ); + CleanupStack::PushL( aDestination ); //3rd push + } + +// ----------------------------------------------------------------------------- +// GetCenRepKeyIntValueL Gets integer repository value +// Returns: Error +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt TObexUtilsMessageHandler::GetCenRepKeyIntValueL( + TUid aRepositoryUid, // aRepositoryUid Central repository's UID value + TUint32 aId, // Central repository's ID value + TInt& aVal) // Returned integer value + { + CRepository* storage = CRepository::NewLC( aRepositoryUid ); + TInt retval = storage->Get( aId, aVal ); + if (retval != KErrNone) + { + FLOG(_L("[OBEXUTILS]\t GetCenRepKeyIntValueL() Get failed")); + } + CleanupStack::PopAndDestroy( storage ); + return retval; + } + +// ----------------------------------------------------------------------------- +// GetCurrentTime Gets current time +// Returns: Current time +// ----------------------------------------------------------------------------- +// +TTime TObexUtilsMessageHandler::GetCurrentTime() + { + TTime time; + time.UniversalTime(); + return time; + } + +// ----------------------------------------------------------------------------- +// StoreAsRichTextL Change message content to Richtext +// Returns: None. +// ----------------------------------------------------------------------------- +// +void TObexUtilsMessageHandler::StoreAsRichTextL( + CMsvEntry* aParentEntry, // A pointer to new message server entry. + RFile& aFile) // New file to store + { + FLOG(_L("[OBEXUTILS]\t StoreAsRichTextL()")); + + // Read the file into buffer + + CBufFlat* buffer = CBufFlat::NewL( 16 ); + CleanupStack::PushL(buffer); // 1st push + + TInt fileLength = 0; + User::LeaveIfError( aFile.Size( fileLength ) ); + + buffer->ResizeL( fileLength ); + TPtr8 bufferPtr = buffer->Ptr(0); + + User::LeaveIfError( aFile.Read( bufferPtr ) ); + + // In order for Bio to understand 8-bit binary data, + // it needs to be stored in wide rich text object + // in the low byte of each word with the upper byte as 0. + // Do not use UTF8, just convert 8-bit to 16-bit. + + CRichText* richText = ConstructRichTextLC(); // 2nd, 3rd, 4th push + HBufC* convert8BitTo16Bit = HBufC::NewLC(fileLength); // 5th push + convert8BitTo16Bit->Des().Copy( bufferPtr ); + buffer->Reset(); // free unused memory before InsertL() + + richText->InsertL(0, *convert8BitTo16Bit); + CleanupStack::PopAndDestroy(convert8BitTo16Bit); + // -1 pop: free unused memory before StoreBodyTextL() + + CMsvStore* parentStore = aParentEntry->EditStoreL(); + CleanupStack::PushL(parentStore); // 5th push + parentStore->StoreBodyTextL(*richText); + parentStore->CommitL(); + + CleanupStack::PopAndDestroy(5); // parentStore, richText, richParaFormatLayer, + // richCharFormatLayer, buffer + + FLOG(_L("[OBEXUTILS]\t StoreAsRichTextL() completed")); + } + +// ----------------------------------------------------------------------------- +// UpdateAttachmentInformationL Add the obex object as a file attachment. +// Returns: None. +// ----------------------------------------------------------------------------- +// +void TObexUtilsMessageHandler::UpdateAttachmentInformationL( + TReceivedData& aRecData, // The obex received data + CMsvEntry* aAttachEntry, // Attachment entry + CMsvAttachment* aAttachInfo, // Attachment information + CMsvStore* aStore) // Message store (attachment) + { + FLOG(_L("[OBEXUTILS]\t UpdateAttachmentInformationL()")); + + TMsvEntry attachTEntry = aAttachEntry->Entry(); + + SetDetailsLC(attachTEntry.iDescription, aAttachInfo->MimeType()); + attachTEntry.iSize = aRecData.bytesReceived; + attachTEntry.iDate = aRecData.recTime; + aAttachEntry->ChangeL(attachTEntry); // Save properties. + CleanupStack::PopAndDestroy(); // unicode in SetDetailsLC + + aAttachInfo->SetSize(aRecData.bytesReceived); + aAttachInfo->SetAttachmentNameL(aRecData.msgName); + aAttachInfo->SetComplete(ETrue); + + aStore->AttachmentManagerExtensionsL().ModifyAttachmentInfoL(aAttachInfo); + + FLOG(_L("[OBEXUTILS]\t UpdateAttachmentInformation() completed")); + } + +// ----------------------------------------------------------------------------- +// FinaliseMessageL Save the size of all the attachments and make visible. +// Returns: None. +// ----------------------------------------------------------------------------- +// +void TObexUtilsMessageHandler::FinaliseMessageL( + CMsvEntry* aParentEntry, // Parent entry + TReceivedData& aRecData, // The obex received data + CMsvStore* aStore, // Attachment's store + TBool aIsBioMsg) // Is BIO message? + { + FLOG(_L("[OBEXUTILS]\t FinaliseMessageL()")); + // Save the size of all the attachment & make visible. + TMsvEntry parentTEntry = aParentEntry->Entry(); + parentTEntry.iDate = GetCurrentTime(); + parentTEntry.iSize = aRecData.bytesReceived; + parentTEntry.SetUnread(ETrue); + + // Saved OK. Make the entry visible and flag it as complete. + parentTEntry.SetVisible(ETrue); // visible + parentTEntry.SetInPreparation(EFalse); // complete + if (!aIsBioMsg) + { + parentTEntry.iDescription.Set(aRecData.msgName); // "Subject" + } + aParentEntry->ChangeL(parentTEntry); // commit changes + + aStore->CommitL(); + + FLOG(_L("[OBEXUTILS]\t FinaliseMessageL() completed")); + } + +// ----------------------------------------------------------------------------- +// FinaliseMessageL Save the size of all the attachments and make visible. +// for Saving file received via BT/IR directly to file system. +// Returns: None. +// ----------------------------------------------------------------------------- +// +void TObexUtilsMessageHandler::FinaliseMessageL( + CMsvEntry* aParentEntry, + CMsvStore* aStore, + TEntry& aFileEntry, + TParse& aFileNameParser) + { + FLOG(_L("[OBEXUTILS]\t FinaliseMessageL() new ")); + + // Save the size of all the attachment & make visible. + TMsvEntry parentTEntry = aParentEntry->Entry(); + parentTEntry.iDate = GetCurrentTime(); + parentTEntry.iSize = aFileEntry.iSize; + parentTEntry.SetUnread(EFalse); + // Saved OK. Make the entry visible and flag it as complete. + parentTEntry.SetVisible(ETrue); // visible + parentTEntry.SetInPreparation(EFalse); // complete + parentTEntry.iDescription.Set(aFileNameParser.Name()); // "Subject" + aParentEntry->ChangeL(parentTEntry); // commit changes + aStore->CommitL(); + + FLOG(_L("[OBEXUTILS]\t FinaliseMessageL() new completed ")); + } + +// ----------------------------------------------------------------------------- +// StoreAndUpdateBioMessageL Stores and updates a BIO message +// Returns: None. +// ----------------------------------------------------------------------------- +// +void TObexUtilsMessageHandler::StoreAndUpdateBioMessageL( + CBIODatabase* aBioDB, // Bio database + TUid aBioMsgId, // Bio message ID + CMsvEntry* parentEntry, // Parent message entry + RFile& aFile) // File to attachment + { + FLOG(_L("[OBEXUTILS]\t StoreAndUpdateBioMessageL()")); + + TInt index; + aBioDB->GetBioIndexWithMsgIDL(aBioMsgId, index); + + StoreAsRichTextL( parentEntry, aFile ); + + TMsvEntry parentTEntry = parentEntry->Entry(); + parentTEntry.iMtm = KUidBIOMessageTypeMtm; + parentTEntry.iServiceId = KMsvLocalServiceIndexEntryId; + parentTEntry.iBioType = aBioMsgId.iUid; + parentTEntry.iDescription.Set(aBioDB->BifReader(index).Description()); + parentEntry->ChangeL(parentTEntry); + + FLOG(_L("[OBEXUTILS]\t StoreAndUpdateBioMessageL() completed")); + } + +// ----------------------------------------------------------------------------- +// RecogniseObjectsL Recognised objects if no type field has been given. +// Returns: None. +// ----------------------------------------------------------------------------- +// +void TObexUtilsMessageHandler::RecogniseObjectsL( + TFileName& aFileName, + CMsvAttachment* aAttachInfo) // Attachment information + { + FLOG(_L("[OBEXUTILS]\t RecogniseObjectsL()")); + + TPtrC8 mimeType; + RApaLsSession lsSess; + User::LeaveIfError( lsSess.Connect() ); + CleanupClosePushL(lsSess); + TDataType appDataType; + TUid appUid; + if (lsSess.AppForDocument(aFileName, appUid, appDataType) == KErrNone) + { + mimeType.Set(appDataType.Des8()); + } + else + { + // Don't trust on sender's MIME type here. Just set to empty. + mimeType.Set(KNullDesC8); + FLOG(_L("[OBEXUTILS]\t RecogniseObjectsL() MIME check failed")); + } + CleanupStack::PopAndDestroy(); // lsSess + HBufC* buf16 = HBufC::NewLC(mimeType.Length()); + buf16->Des().Copy(mimeType); + TPtrC mimeType16(buf16->Des()); + CleanupStack::PopAndDestroy(); // buf16 + + CUpdateMusicCollection* updateMusiccollection =CUpdateMusicCollection::NewL() ; + if (updateMusiccollection->isSupported(mimeType16)) + { + updateMusiccollection->addToCollectionL(aFileName); + } + + aAttachInfo->SetMimeTypeL( mimeType ); + + FLOG(_L("[OBEXUTILS]\t RecogniseObjectsL() completed")); + } + +// ----------------------------------------------------------------------------- +// SaveMimeAndGetBioLC Saves MIME type and gets BIO database for that MIME +// Returns: BIO database if BIO message +// ----------------------------------------------------------------------------- +// +CBIODatabase* TObexUtilsMessageHandler::SaveMimeAndGetBioLC( + TFileName& aFileName, + RFs& aFsSess, // File session + CMsvAttachment* aAttachInfo, // Attachment information + TUid &aBioMsgId) // BIO message ID for data + { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::SaveMimeAndGetBioLC()")); + + RecogniseObjectsL( aFileName, aAttachInfo ); + + // For attachments / BIO check. + CBIODatabase* bioDB = CBIODatabase::NewLC( aFsSess ); // 1st push + + // Run through the data objects, seeing if they can be accepted by BIO. + // Check if they are bio objects + + TBioMsgIdText bioMessageIdText; + SetBioDataTextL( bioMessageIdText, aAttachInfo->MimeType() ); + + // Remove any zero termination on mime type + // + TInt zeroTermination = bioMessageIdText.Locate( TChar(0) ); + + if ( zeroTermination != KErrNotFound ) + { + bioMessageIdText.SetLength( zeroTermination ); + } + + TInt bioMsgErr = bioDB->IsBioMessageL( EBioMsgIdIana, bioMessageIdText, NULL, aBioMsgId ); + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::SaveMimeAndGetBioLC() completed")); + if (bioMsgErr != KErrNone) + { + return NULL; + } + return bioDB; + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CreateInboxAttachmentL Creates inbox entry and attachment for it +// If this leaves, it means the entry and obex object have already been deleted. +// In this case aMsvIdParent has been set to zero. +// Returns: None. +// ----------------------------------------------------------------------------- +// +EXPORT_C void TObexUtilsMessageHandler::CreateInboxAttachmentL( + CObexBufObject* &aBufObject, // Obex object + const TUid aMtmId, // Mtm ID of the message + TMsvId &aMsvIdParent, // Message ID of the parent message entry + RFile &aFile) // File to the attachment + { + TMsvId msvId = 0; + TRAPD(retTrap, DoCreateInboxAttachmentL(aMtmId, msvId, aFile,KNullDesC)) + if (retTrap != KErrNone) + { + aMsvIdParent = 0; + if (msvId) + { + RemoveInboxEntriesL(aBufObject, msvId); + } + User::Leave(retTrap); + } + aMsvIdParent = msvId; + } + +// ----------------------------------------------------------------------------- +// CreateInboxAttachmentL Creates inbox entry and attachment for it +// If this leaves, it means the entry and obex object have already been deleted. +// In this case aMsvIdParent has been set to zero. +// Returns: None. +// ----------------------------------------------------------------------------- +// +EXPORT_C void TObexUtilsMessageHandler::CreateInboxAttachmentL( + CObexBufObject* &aBufObject, // Obex object + const TUid aMtmId, // Mtm ID of the message + TMsvId &aMsvIdParent, // Message ID of the parent message entry + RFile &aFile, // File to the attachment + const TDesC& aRemoteBluetoothName) // bluetooth name of remote device + { + TMsvId msvId = 0; + TRAPD(retTrap, DoCreateInboxAttachmentL(aMtmId, msvId, aFile,aRemoteBluetoothName)) + if (retTrap != KErrNone) + { + aMsvIdParent = 0; + if (msvId) + { + RemoveInboxEntriesL(aBufObject, msvId); + } + User::Leave(retTrap); + } + aMsvIdParent = msvId; + } + +// ----------------------------------------------------------------------------- +// DoCreateInboxAttachmentL Creates inbox entry and attachment for it (private) +// Returns: None. +// ----------------------------------------------------------------------------- +// +void TObexUtilsMessageHandler::DoCreateInboxAttachmentL( + const TUid aMtmId, // Mtm ID of the message + TMsvId &aMsvIdParent, // Message ID of the parent message entry + RFile &aFile, // File to the attachment + const TDesC& aRemoteBluetoothName) // bluetooth name of remote device + { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::CreateInboxAttachmentL()")); + + CDummySessionObserver* sessionObs; + CMsvSession* msvSession; + CMsvEntry* inbox; + CreateMsvSessionLC(sessionObs, msvSession, inbox, KMsvGlobalInBoxIndexEntryId); + // 1st, 2nd, 3rd push + + TBuf toFrom; + TInt resourceId; + + if (aMtmId == KUidMsgTypeBt) + { + resourceId = R_BT_TO_FROM_IN_INBOX; + } + else + { + resourceId = R_IR_TO_FROM_IN_INBOX; + } + + TObexUtilsUiLayer::ReadResourceL( toFrom, resourceId ); + + TMsvEntry parentTEntry; + parentTEntry.iMtm = aMtmId; + parentTEntry.SetVisible(EFalse); // Make invisible.. + parentTEntry.SetUnread(ETrue); + + // ...and in preparation to make sure it gets cleaned up on errors. + // + parentTEntry.SetInPreparation(ETrue); + parentTEntry.iType = KUidMsvMessageEntry; + parentTEntry.iServiceId = KMsvUnknownServiceIndexEntryId; + // iDate & iSize will be set later + if ( aRemoteBluetoothName.Length() > 0 ) + { + parentTEntry.iDetails.Set(aRemoteBluetoothName); + } + else + { + parentTEntry.iDetails.Set(toFrom); + } + inbox->CreateL(parentTEntry); + + aMsvIdParent = parentTEntry.Id(); + + // Create attachment for the inbox entry + + TMsvEntry attachTEntry; + attachTEntry.iType = KUidMsvAttachmentEntry; + attachTEntry.iServiceId = KMsvUnknownServiceIndexEntryId; + attachTEntry.iMtm = aMtmId; + + CMsvEntry* parentEntry = msvSession->GetEntryL(aMsvIdParent); + CleanupStack::PushL(parentEntry); // 4th push + parentEntry->CreateL(attachTEntry); // create attachment as child of parent + + // create the v2 attachment, save RFile + + CMsvEntry* attachEntry = msvSession->GetEntryL(attachTEntry.Id()); + CleanupStack::PushL(attachEntry); // 5th push + + CMsvStore* store = attachEntry->EditStoreL(); + CleanupStack::PushL(store); // 6th push + CMsvAttachment* attachment = CMsvAttachment::NewL(CMsvAttachment::EMsvFile); + CleanupStack::PushL(attachment); // 7th push + + store->AttachmentManagerExtensionsL().CreateAttachmentL(_L("Unnamed"), aFile, attachment); + CleanupStack::Pop(attachment); + store->CommitL(); + // CommitL() required here otherwise EditStoreL() will fail in SaveObjToInbox() + + CleanupStack::PopAndDestroy(6); + // store, attachEntry, parentEntry, inbox, msvSession, sessionObs + + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::CreateInboxAttachmentL() completed")); + } + +// ----------------------------------------------------------------------------- +// CObexUtilsMessageHandler::RemoveInboxEntriesL +// ----------------------------------------------------------------------------- +EXPORT_C void TObexUtilsMessageHandler::RemoveInboxEntriesL( + CObexBufObject* &aBufObject, // Obex object + TMsvId aMsvIdParent) // Message ID of the parent message entry + { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::RemoveInboxEntriesL()")); + + CDummySessionObserver* sessionObs; + CMsvSession* msvSession; + CMsvEntry* inbox; + CreateMsvSessionLC(sessionObs, msvSession, inbox, KMsvGlobalInBoxIndexEntryId); + // 1st, 2nd, 3rd push + + // Close file + + RemoveObexBuffer(aBufObject); + + // Delete parent and descendants + if ( aMsvIdParent ) + { + inbox->DeleteL(aMsvIdParent); + } + + CleanupStack::PopAndDestroy(3); + + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::RemoveInboxEntriesL() completed")); + } + +// ----------------------------------------------------------------------------- +// CObexUtilsMessageHandler::SaveObjToInboxL +// ----------------------------------------------------------------------------- +// +EXPORT_C void TObexUtilsMessageHandler::SaveObjToInboxL( + CObexBufObject* /*aReceivedObject*/, const TDesC16& /*aPath*/, const TUid /*aMtmID*/ ) + { + } + +// ----------------------------------------------------------------------------- +// CObexUtilsMessageHandler::SaveObjToInboxL +// ----------------------------------------------------------------------------- +// +EXPORT_C void TObexUtilsMessageHandler::SaveObjToInboxL( + CObexBufObject* &aReceivedObject, // Obex object + RFile &aFile, + TMsvId aMsvIdParent) // Message ID of the parent message entry + { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::SaveObjToInboxL()")); + + // Open session. + CDummySessionObserver* sessionObs; + CMsvSession* msvSession; + CreateMsvSessionLC(sessionObs, msvSession); // 1st, 2nd push + + CMsvEntry* parentEntry = msvSession->GetEntryL(aMsvIdParent); + CleanupStack::PushL( parentEntry ); // 3rd push + +#ifdef __BT_SAP + if(CSapVMessageParser::HandleMessageL(aReceivedObject, parentEntry->Entry().iMtm, + aFile, msvSession, GetCurrentTime())) + { + RemoveObexBuffer(aReceivedObject); + CMsvEntry* inbox = msvSession->GetEntryL( KMsvGlobalInBoxIndexEntryId ); + CleanupStack::PushL( inbox ); //4th push + inbox->DeleteL(aMsvIdParent); + // Close session etc. + CleanupStack::PopAndDestroy(4, sessionObs); // inbox, parentEntry, session, sessionObs + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::SaveObjToInboxL() completed")); + return; + } +#endif // __BT_SAP + CMsvEntry* attachEntry = msvSession->GetEntryL(((*parentEntry)[0]).Id()); + CleanupStack::PushL(attachEntry); // 4th push + + CMsvStore* store = attachEntry->EditStoreL(); + CleanupStack::PushL( store ); // 5th push + + // Collect obex received data before obex buffer deletion + + TReceivedData receivedData; + receivedData.bytesReceived = aReceivedObject->BytesReceived(); + receivedData.recTime = aReceivedObject->Time(); + + RFs& fsSess = msvSession->FileSession(); + receivedData.msgName = aReceivedObject->Name(); + MakeValidFileName(fsSess, receivedData.msgName); + + // Rename attachment for MIME type checking + + RemoveObexBuffer(aReceivedObject); + store->AttachmentManagerExtensionsL().RenameAttachmentL(0, receivedData.msgName); + RFile newFile = store->AttachmentManagerL().GetAttachmentFileL(0); + CleanupClosePushL(newFile); // 6th push + + // RenameAttachmentL() modified attachment info, so read it now + + CMsvAttachment* attachInfo = store->AttachmentManagerL().GetAttachmentInfoL(0); + CleanupStack::PushL( attachInfo ); // 7th push + + TUid bioMsgId; // SaveMimeAndGetBioLC modifies this + TFileName fileName; + newFile.FullName(fileName); + CBIODatabase* bioDB = SaveMimeAndGetBioLC( fileName, fsSess, attachInfo, bioMsgId ); + // 8th push + if (bioDB) // bio message + { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::SaveObjToInboxL() BIO")); + StoreAndUpdateBioMessageL( bioDB, bioMsgId, parentEntry, newFile ); + FinaliseMessageL(parentEntry, receivedData, store, ETrue); + TMsvId attachId = attachEntry->EntryId(); + CleanupStack::PopAndDestroy(5); // bioDB, attachInfo, newFile (close), + // store, attachEntry + // PopAndDestroying here because open store locks the entry, + // it can be deleted only after destroying the store pointer + parentEntry->DeleteL(attachId); // invalidate unused attachment + CleanupStack::PopAndDestroy(3); // parentEntry, msvSession, sessionObs + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::SaveObjToInboxL() BIO completed")); + } + else // attachment message + { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::SaveObjToInboxL() Attachment")); + CleanupStack::PopAndDestroy(); // bioDB + UpdateAttachmentInformationL(receivedData, attachEntry, attachInfo, store); + CleanupStack::Pop(attachInfo); // ownership taken by ModifyAttachmentInfoL() + FinaliseMessageL(parentEntry, receivedData, store, EFalse); + CleanupStack::PopAndDestroy(6); // newFile (close), store, attachEntry, + // parentEntry, msvSession, sessionObs + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::SaveObjToInboxL() Attachment completed")); + } + + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::SaveObjToInboxL() completed")); + } + + +// ----------------------------------------------------------------------------- +// GetCenRepKeyStringValueL Gets integer repository value +// Returns: Error +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt TObexUtilsMessageHandler::GetCenRepKeyStringValueL( + TUid aRepositoryUid, // aRepositoryUid Central repository's UID value + TUint32 aId, // Central repository's ID value + TDes& aVal) // Returned String + { + CRepository* storage = CRepository::NewLC( aRepositoryUid ); + TInt retval = storage->Get( aId, aVal ); + if (retval != KErrNone) + { + FLOG(_L("[OBEXUTILS]\t GetCenRepKeyStringValueL() Get failed")); + } + CleanupStack::PopAndDestroy( storage ); + return retval; + } + +// ----------------------------------------------------------------------------- +// CreateReceiveBufferL Creates an Obex receive buffer object and RFile object. +// Returns: Symbian error code +// ----------------------------------------------------------------------------- +// + +EXPORT_C TInt TObexUtilsMessageHandler::CreateReceiveBufferAndRFileL( + RFile& aFile, + const TDesC& aPath, + TFileName& aFullName, + CBufFlat* &aReceiveObject, + const TInt aBufSize ) + { + + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::CreateReceiveBufferAndRFileL()")); + + aReceiveObject = CBufFlat::NewL(aBufSize); + aReceiveObject->ResizeL(aBufSize); + + + RFs rfs; + User::LeaveIfError( rfs.Connect() ); + if ( !BaflUtils::FolderExists( rfs, aPath ) ) + { + User::LeaveIfError(rfs.MkDirAll(aPath)); + } + User::LeaveIfError( aFile.Temp( rfs, aPath, aFullName, EFileWrite) ); + // Set temp file hidden file. + // + TUint setAttMask(0); + TUint clearAttMask(0); + aFile.SetAtt(setAttMask | KEntryAttHidden, clearAttMask); + aFile.Flush(); + aFile.Close(); + + RFile logFile; + TFileName logFilePath; + TFileName cenRepFolder; + GetCenRepKeyStringValueL(KCRUidBluetoothEngine, KLCReceiveFolder,cenRepFolder); + + logFilePath.Zero(); + logFilePath.Append(PathInfo::PhoneMemoryRootPath()); + logFilePath.Append(cenRepFolder); + + if ( !BaflUtils::FolderExists(rfs , logFilePath) ) + { + User::LeaveIfError(rfs.MkDirAll(logFilePath)); + } + logFilePath.Append(_L("log.txt")); + if ( !BaflUtils::FileExists( rfs, logFilePath )) + { + logFile.Create(rfs, logFilePath, EFileWrite); + } + else + { + User::LeaveIfError(logFile.Open(rfs, logFilePath, EFileWrite)); + } + + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::CreateReceiveBufferAndRFileL() log.txt is created")); + TFileText ft; + ft.Set(logFile); + ft.Write(aFullName); // restore tempfilename in logfile + + // Set log file + logFile.SetAtt(setAttMask | KEntryAttHidden, clearAttMask); + logFile.Flush(); + logFile.Close(); + rfs.Close(); + + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::CreateReceiveBufferAndRFileL() completed")); + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CObexUtilsMessageHandler::RemoveTemporaryRFileL +// ----------------------------------------------------------------------------- +// +EXPORT_C void TObexUtilsMessageHandler::RemoveTemporaryRFileL ( const TFileName& aFullName ) + { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::RemoveTemporaryRFileL()")); + RFs rfs; + User::LeaveIfError(rfs.Connect()); + + TParse fileNameParser; + User::LeaveIfError(fileNameParser.Set(aFullName, NULL, NULL)); + + TFileName logFilePath; + TFileName cenRepFolder; + GetCenRepKeyStringValueL(KCRUidBluetoothEngine, KLCReceiveFolder,cenRepFolder); + logFilePath.Zero(); + logFilePath.Append(PathInfo::PhoneMemoryRootPath()); + logFilePath.Append(cenRepFolder); + logFilePath.Append(_L("log.txt")); + + if ( fileNameParser.Ext().Compare(_L(".$$$")) == 0 ) + { + // aFullName is a temp file name, we need to remove it. + rfs.Delete( aFullName ); + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::RemoveTemporaryRFileL() temp file is removed (bt off)")); + } + else if ( (aFullName.Length() == 0) && BaflUtils::FileExists(rfs, logFilePath)) + { + RFile logFile; + User::LeaveIfError(logFile.Open(rfs, logFilePath, EFileRead)); + TFileText ft; + ft.Set(logFile); + TFileName tempFileName; + ft.Read(tempFileName); // read tempfile name stored in logfile. + + if ( tempFileName.Length() > 0 ) + { + rfs.Delete(tempFileName); + } + logFile.Close(); + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::RemoveTemporaryRFileL() temp files are removed (reboot)")); + } + rfs.Delete( logFilePath ); + rfs.Close(); + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::RemoveTemporaryRFileL() completed")); + } +// ----------------------------------------------------------------------------- +// CObexUtilsMessageHandler::SaveFileToFileSystemL +// ----------------------------------------------------------------------------- +// +EXPORT_C void TObexUtilsMessageHandler::SaveFileToFileSystemL( + CObexBufObject* &aReceivedObject, + const TUid aMtmId, + TMsvId& aMsvIdParent, + TFileName& aFullName, + RFile& aFile, + const TDesC& aSenderBluetoothName) + { + + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::SaveFileToFileSystemL()")); + // Create inbox entry ( this was done in CreateAttachment() before ) + // + CDummySessionObserver* sessionObs; + CMsvSession* msvSession; + CMsvEntry* inbox; + CreateMsvSessionLC(sessionObs, msvSession, inbox, KMsvGlobalInBoxIndexEntryId); + // 1st, 2nd, 3rd push + + TBuf toFrom; + TInt resourceId; + + if (aMtmId == KUidMsgTypeBt) + { + resourceId = R_BT_TO_FROM_IN_INBOX; + } + else + { + resourceId = R_IR_TO_FROM_IN_INBOX; + } + // NOTE: toFrom will be updated to Bluetooth sender's name + // + TObexUtilsUiLayer::ReadResourceL( toFrom, resourceId ); // read the toForm ( will be updated to sender's bt name in the future ) + + TMsvEntry parentTEntry; + parentTEntry.iMtm = aMtmId; + parentTEntry.SetVisible(EFalse); // Make invisible.. + parentTEntry.SetUnread(EFalse); // Msgs received via bluetooth will always be set to READ. + + // ...and in preparation to make sure it gets cleaned up on errors. + // + parentTEntry.SetInPreparation(ETrue); + parentTEntry.iType = KUidMsvMessageEntry; + parentTEntry.iServiceId = KMsvUnknownServiceIndexEntryId; + // iDate & iSize will be set later + if ( aSenderBluetoothName.Length() > 0 ) + { + parentTEntry.iDetails.Set(aSenderBluetoothName); + } + else + { + parentTEntry.iDetails.Set(toFrom); + } + inbox->CreateL(parentTEntry); + + aMsvIdParent = parentTEntry.Id(); + + // Create attachment for the inbox entry + + TMsvEntry attachTEntry; + attachTEntry.iType = KUidMsvAttachmentEntry; + attachTEntry.iServiceId = KMsvUnknownServiceIndexEntryId; + attachTEntry.iMtm = aMtmId; + + CMsvEntry* parentEntry = msvSession->GetEntryL(aMsvIdParent); + CleanupStack::PushL(parentEntry); // 4th push + parentEntry->CreateL(attachTEntry); // create attachment as child of parent + + // Check if message is sap message + // If we delete parent entry in sap, we have to delete the RFile object ourself as well ) + // + RFs& fsSess = msvSession->FileSession(); + TFileName tempFullName; + aFile.FullName(tempFullName); + +#ifdef __BT_SAP + if(CSapVMessageParser::HandleMessageL(aReceivedObject, parentEntry->Entry().iMtm, + aFile, msvSession, GetCurrentTime())) + { + RemoveObexBuffer(aReceivedObject); + CMsvEntry* inbox = msvSession->GetEntryL( KMsvGlobalInBoxIndexEntryId ); + CleanupStack::PushL( inbox ); //5th push + inbox->DeleteL(aMsvIdParent); + fsSess.Delete(tempFullName); // we have to use fullname to delete the file object in file system + // Close session etc. + CleanupStack::PopAndDestroy(5, sessionObs); // inbox, parentEntry, session, sessionObs + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::SaveFileToFileSystemL() completed")); + return; + } +#endif // __BT_SAP + + // Collect obex received data before obex buffer deletion + TReceivedData receivedData; + receivedData.bytesReceived = aReceivedObject->BytesReceived(); + receivedData.recTime = aReceivedObject->Time(); + receivedData.msgName = aReceivedObject->Name(); + + TFileName filename; + TParse parse; + parse.Set(aFullName, NULL, NULL); + filename.Copy(receivedData.msgName); + FixExtremeLongFileName(filename, parse.DriveAndPath()); + MakeValidFileName( fsSess, filename); + RemoveObexBuffer(aReceivedObject); + + // We set file to visible before renaming + // so that photo/music app can scan the media files we recevie. + // + // Set file back to visible + // + TUint setAttMask(0); + TUint clearAttMask(0); + User::LeaveIfError(aFile.Open(fsSess,tempFullName,EFileWrite)); + User::LeaveIfError(aFile.SetAtt(setAttMask , clearAttMask | KEntryAttHidden)); + aFile.Close(); + + + // Move file to the actual drive and directory + // as well rename the file with the correct file name instead of temporary name + // tempFullName will be updated in RenameFileL() + TInt error = RenameFileL(tempFullName, filename, parse.DriveAndPath(), fsSess); + + + + if ( error != KErrNone ) + { + fsSess.Delete(tempFullName); // If rename fails, we remove the temp RFile object. + } + aFullName = tempFullName; // assign new full Name back to aFullName,which goes back to caller + + CleanupStack::PopAndDestroy(4); // parentEntry, inbox, msvSession, sessionObs + + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::SaveFileToFileSystemL() completed")); + } + +// ----------------------------------------------------------------------------- +// CObexUtilsMessageHandler::AddEntryToInboxL +// ----------------------------------------------------------------------------- +// +EXPORT_C void TObexUtilsMessageHandler::AddEntryToInboxL( + TMsvId& aMsvIdParent, + TFileName& aFullName, + RArray* aMsvIdArray) + { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::AddEntryToInboxL() ")); + + CDummySessionObserver* sessionObs; + CMsvSession* msvSession; + CreateMsvSessionLC(sessionObs, msvSession); + // 1st, 2nd push + + CMsvEntry* parentEntry = msvSession->GetEntryL(aMsvIdParent); + CleanupStack::PushL(parentEntry); // 3th push + + CMsvEntry* attachEntry = msvSession->GetEntryL(((*parentEntry)[0]).Id()); + CleanupStack::PushL(attachEntry); // 4th push + + CMsvStore* store = attachEntry->EditStoreL(); + CleanupStack::PushL( store ); // 5th push + + CObexutilsEntryhandler* entryHandler = CObexutilsEntryhandler::NewL(); + CleanupStack::PushL(entryHandler); // 6th push + + CMsvAttachment* attachInfo = CMsvAttachment::NewL(CMsvAttachment::EMsvLinkedFile); + CleanupStack::PushL(attachInfo); // 7th push + + // Create attachment Info + // + RFs& fsSess = msvSession->FileSession(); + + TParse fileNameParser; + User::LeaveIfError(fileNameParser.Set(aFullName, NULL, NULL)); + attachInfo->SetAttachmentNameL(fileNameParser.NameAndExt()); + + TEntry fileEntry; + User::LeaveIfError(fsSess.Entry( fileNameParser.FullName(), fileEntry) ); + attachInfo->SetSize(fileEntry.iSize); + + // check if it's the bio message + + TUid bioMsgId; // SaveMimeAndGetBioLC modifies this + CBIODatabase* bioDB = SaveMimeAndGetBioLC( aFullName, fsSess, attachInfo, bioMsgId ); + // 8th push + if (bioDB) // bio message + { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::AddEntryToInboxL() BIO")); + + RFile file; + User::LeaveIfError(file.Open(fsSess,aFullName,EFileRead)); + TReceivedData receivedData; + receivedData.bytesReceived = fileEntry.iSize; + receivedData.recTime = fileEntry.iModified; + receivedData.msgName = fileNameParser.Name(); + + StoreAndUpdateBioMessageL( bioDB, bioMsgId, parentEntry, file ); + FinaliseMessageL(parentEntry, receivedData, store, ETrue); + TMsvId attachId = attachEntry->EntryId(); + file.Close(); + fsSess.Delete(aFullName); + CleanupStack::PopAndDestroy(5); // bioDB, attachInfo, linkHandler, + // store, attachEntry + + // PopAndDestroying here because open store locks the entry, + // it can be deleted only after destroying the store pointer + parentEntry->DeleteL(attachId); // invalidate unused attachment + CleanupStack::PopAndDestroy(3); // parentEntry, msvSession, sessionObs + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::AddEntryToInboxL() BIO completed")); + } + else + { + + CleanupStack::PopAndDestroy(); // bioDB + // Add entry to Inbox + entryHandler->AddEntryAttachment(aFullName, attachInfo, store); + CleanupStack::Pop(attachInfo); // attachInfo, Pass ownership to store + CleanupStack::PopAndDestroy(entryHandler); // entryHandler + FinaliseMessageL(parentEntry, store,fileEntry, fileNameParser); + CleanupStack::PopAndDestroy(5); // linkHandler, attachInfo, store, attachEntry, + // parentEntry, msvSession, sessionObs + + // File Link is created in INBOX successfully, + // We add MsvId to array. + // + aMsvIdArray->Append(aMsvIdParent); + + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::AddEntryToInboxL() completed ")); + } + + } + +// ----------------------------------------------------------------------------- +// CObexUtilsMessageHandler::UpdateEntryAttachmentL +// ----------------------------------------------------------------------------- +// +EXPORT_C void TObexUtilsMessageHandler::UpdateEntryAttachmentL ( + TFileName& aFullName, + CMsvEntry* aParentEntry) + { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::UpdateEntryAttachmentL() ")); + CDummySessionObserver* sessionObs; + CMsvSession* msvSession; + CreateMsvSessionLC(sessionObs, msvSession); + // 1st, 2nd push + + CMsvEntry* attachEntry = msvSession->GetEntryL(((*aParentEntry)[0]).Id()); + CleanupStack::PushL(attachEntry); // 3th push + + CMsvStore* store = attachEntry->EditStoreL(); + CleanupStack::PushL( store ); // 4th push + + CObexutilsEntryhandler* entryHandler = CObexutilsEntryhandler::NewL(); + CleanupStack::PushL(entryHandler); // 5th push + + // Note: + // Because setFilePath() in CMsvAttachment is not implementated by Symbian yet, + // we have to delete the original attachment and add another new one to fix the broken link. + // + + // remove the old attachment first. + // + store->AttachmentManagerExtensionsL().RemoveAttachmentL(0); + // Create a new attachment. + // + CMsvAttachment* attachInfo = CMsvAttachment::NewL(CMsvAttachment::EMsvLinkedFile); + CleanupStack::PushL(attachInfo); // 6th push + + // Get mime type + // + RecogniseObjectsL(aFullName, attachInfo); + RFs& fsSess = msvSession->FileSession(); + + TParse fileNameParser; + User::LeaveIfError(fileNameParser.Set(aFullName, NULL, NULL)); + attachInfo->SetAttachmentNameL(fileNameParser.NameAndExt()); + TEntry fileEntry; + User::LeaveIfError(fsSess.Entry( fileNameParser.FullName(), fileEntry) ); + attachInfo->SetSize(fileEntry.iSize); + + entryHandler->AddEntryAttachment(aFullName,attachInfo, store); + CleanupStack::Pop(attachInfo); // attachInfo, Pass ownership to store + CleanupStack::PopAndDestroy(entryHandler); // entryHandler + FinaliseMessageL(aParentEntry, store,fileEntry, fileNameParser); + CleanupStack::PopAndDestroy(4); // store, + // attachEntry, msvSession, sessionObs + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::UpdateEntryAttachmentL() completed ")); + } + + +// Common methods + +// ----------------------------------------------------------------------------- +// ConstructRichTextLC Handles rich text initialisation. +// Returns: CRichText* A pointer to the rich text. +// ----------------------------------------------------------------------------- +// +CRichText* TObexUtilsMessageHandler::ConstructRichTextLC() + { + FLOG(_L("[OBEXUTILS]\t ConstructRichTextLC()")); + + CParaFormatLayer* richParaFormatLayer = CParaFormatLayer::NewL(); + CleanupStack::PushL( richParaFormatLayer ); + + CCharFormatLayer* richCharFormatLayer = CCharFormatLayer::NewL(); + CleanupStack::PushL( richCharFormatLayer ); + CRichText* richText = CRichText::NewL( richParaFormatLayer, + richCharFormatLayer ); + CleanupStack::PushL(richText); + + FLOG(_L("[OBEXUTILS]\t ConstructRichTextLC() completed")); + + return richText; + } + +// ----------------------------------------------------------------------------- +// MakeValidFileName Rename the given filename to a valid filename. +// Removes invalid characters from a filename; if no characters left, filename +// is set to R_NAME_FOR_INVALID_FILE +// Returns: None. +// ----------------------------------------------------------------------------- +// +void TObexUtilsMessageHandler::MakeValidFileName( + RFs& aFileSession, // A reference to file server session. + TDes& aFileName ) // The filename to modify. + { + FLOG(_L("[OBEXUTILS]\t MakeValidFileName()")); + + TParse fileParse; + fileParse.Set(aFileName, NULL, NULL); + + TBool nameempty = ETrue; + if (fileParse.NameOrExtPresent()) + { + aFileName = fileParse.NameAndExt(); + nameempty=EFalse; + TText badChar; + TInt nameLength = aFileName.Length(); + + while ( !aFileSession.IsValidName(aFileName, badChar) ) + { + // Locate and delete all instances of the bad char + FOREVER + { + TInt index = aFileName.Locate(TChar(badChar)); + nameLength--; + if (index == KErrNotFound) + { + break; + } + aFileName.Delete(index,1); + } + if ( nameLength <= 0 ) + { + break; + } + } + } + + // Did we delete all the characters? If so then we must have some filename + if ( aFileName.Length() == 0 || nameempty ) + { + TInt resourceId = R_NAME_FOR_INVALID_FILE; + TRAPD( retVal, TObexUtilsUiLayer::ReadResourceL( aFileName, resourceId ) ); + if (retVal != KErrNone) + { + FLOG(_L("TObexUtilsMessageHandler::MakeValidFileName failed.")); + } + } + + FLOG(_L("[OBEXUTILS]\t MakeValidFileName() completed")); + } + +// ----------------------------------------------------------------------------- +// TObexUtilsMessageHandler::CreateOutboxEntryL +// ----------------------------------------------------------------------------- +// +EXPORT_C TMsvId TObexUtilsMessageHandler::CreateOutboxEntryL( + const TUid& aMtm, // Message type id + const TInt& aResourceID ) // Resource id for the message entry text + { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::CreateOutboxEntryL()")); + + CDummySessionObserver* sessionObs; + CMsvSession* msvSession; + CMsvEntry* outBoxEntry; + CreateMsvSessionLC(sessionObs, msvSession, outBoxEntry, KMsvGlobalOutBoxIndexEntryId); + // 1st, 2nd, 3rd push + + TBuf toFrom; + TObexUtilsUiLayer::ReadResourceL( toFrom, aResourceID ); + + // Message entry fields + TMsvEntry newTEntry; + newTEntry.SetVisible( ETrue ); // Make visible + newTEntry.SetInPreparation( ETrue ); // and in preparation to make sure gets cleaned up on errors. + newTEntry.iDetails.Set( toFrom ); // To/From field on Outbox + newTEntry.SetSendingState( KMsvSendStateSending ); + newTEntry.iType = KUidMsvMessageEntry; + newTEntry.iMtm = aMtm; // message type id + newTEntry.iServiceId = KMsvGlobalOutBoxIndexEntryId; + outBoxEntry->CreateL( newTEntry ); + + CleanupStack::PopAndDestroy(3); //outBoxEntry, msvSession, sessionObs + return newTEntry.Id(); + } + +// ----------------------------------------------------------------------------- +// TObexUtilsMessageHandler::DeleteOutboxEntryL +// ----------------------------------------------------------------------------- +// +EXPORT_C void TObexUtilsMessageHandler::DeleteOutboxEntryL( const TMsvId& aMessageServerIndex ) + { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::DeleteOutboxEntryL()")); + + CDummySessionObserver* sessionObs; + CMsvSession* msvSession; + CMsvEntry* outBoxEntry; + CreateMsvSessionLC(sessionObs, msvSession, outBoxEntry, KMsvGlobalOutBoxIndexEntryId); + // 1st, 2nd, 3rd push + + outBoxEntry->DeleteL( aMessageServerIndex ); + + CleanupStack::PopAndDestroy(3); //outBoxEntry, msvSession, sessionObs + } + +// ----------------------------------------------------------------------------- +// TObexUtilsMessageHandler::GetFileSystemStatus +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt TObexUtilsMessageHandler::GetFileSystemStatus() + { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::GetFileSystemStatus()")); + + /** + * Free space level of FFS file system (drive C:) + * The integer value may be: + * 0: Free space OK + * -1: Free space at or below warning level + * -2: Free space at or below critical level + */ + + TInt status = KErrNone; + TInt retVal = KErrNone; + + retVal = GetPubSubKeyIntValue(KPSUidUikon, KUikFFSFreeLevel, status); + if ( ( retVal == KErrNone ) && ( status == KFFSBelowCritical ) ) + { + retVal = KErrDiskFull; + } + + FTRACE(FPrint(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::GetFileSystemStatus completed with %d."), retVal)); + return retVal; + } + +// ----------------------------------------------------------------------------- +// TObexUtilsMessageHandler::GetMmcFileSystemStatus +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt TObexUtilsMessageHandler::GetMmcFileSystemStatus() + { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::GetMmcFileSystemStatus()")); + + /** + * Free space level of FFS file system (MMC) + * The integer value may be: + * 0: Free space OK + * -1: Free space at or below warning level + * -2: Free space at or below critical level + */ + + TInt retVal = KErrNone; + TInt status = KErrNone; + + retVal = GetPubSubKeyIntValue(KPSUidUikon, KUikMmcFFSFreeLevel, status); + if ( ( retVal == KErrNone ) && ( status == KFFSBelowCritical ) ) + { + retVal = KErrDiskFull; + } + + FTRACE(FPrint(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::GetMmcFileSystemStatus completed with %d."), retVal)); + return retVal; + } + +// ----------------------------------------------------------------------------- +// TObexUtilsMessageHandler::GetMessageCentreDriveL +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt TObexUtilsMessageHandler::GetMessageCentreDriveL() + { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::GetMessageCentreDriveL()")); + + CDummySessionObserver* sessionObs; + CMsvSession* msvSession; + CreateMsvSessionLC(sessionObs, msvSession); // 1st, 2nd push + + TDriveUnit driveUnit = msvSession->CurrentDriveL(); + CleanupStack::PopAndDestroy(2); // msvSession, sessionObs + + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::GetMessageCentreDriveL() Completed")); + return driveUnit; + } + +// ----------------------------------------------------------------------------- +// TObexUtilsMessageHandler::CreateDefaultMtmServiceL +// ----------------------------------------------------------------------------- +// +EXPORT_C void TObexUtilsMessageHandler::CreateDefaultMtmServiceL(TUid aMtm) + { + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::CreateDefaultMtmServiceL()")); + + CDummySessionObserver* sessionObs; + CMsvSession* msvSession; + CMsvEntry* root; + CreateMsvSessionLC(sessionObs, msvSession, root, KMsvRootIndexEntryId); + // 1st, 2nd, 3rd push + + TMsvSelectionOrdering msvSelectionOrdering = root->SortType(); + msvSelectionOrdering.SetShowInvisibleEntries( ETrue ); + root->SetSortTypeL( msvSelectionOrdering ); + + CMsvEntrySelection* sel = root->ChildrenWithMtmL( aMtm ); + CleanupStack::PushL( sel ); // 4th push + if (sel->Count() == 0) + { + TMsvEntry serviceEntry; + serviceEntry.iMtm = aMtm; + serviceEntry.iType = KUidMsvServiceEntry; + serviceEntry.SetVisible(EFalse); + serviceEntry.SetReadOnly(ETrue); + serviceEntry.SetInPreparation(EFalse); + root->CreateL(serviceEntry); + } + CleanupStack::PopAndDestroy(4); // sel, root, msvSession, sessionObs + + FLOG(_L("[OBEXUTILS]\t TObexUtilsMessageHandler::CreateDefaultMtmServiceL() Completed")); + } + +// ----------------------------------------------------------------------------- +// GetCenRepKeyIntValue Gets integer value for a specified CenRep key +// Returns: CenRep key's value +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt TObexUtilsMessageHandler::GetPubSubKeyIntValue( + TUid aCategory, // Category of the key + TUint aKey, // PUBSUB key + TInt& value) // Returned value + { + TInt retVal; + RProperty property; + retVal = property.Attach(aCategory, aKey); + if ( retVal == KErrNone ) + { + retVal = property.Get(value); + if (retVal != KErrNone) + { + FLOG(_L("[OBEXUTILS]\t GetPubSubKeyIntValue() Get failed for CenRep key")); + } + } + else + { + FLOG(_L("[OBEXUTILS]\t GetPubSubKeyIntValue() Attach failed for CenRep key")); + } + property.Close(); + return retVal; + } + +// ----------------------------------------------------------------------------- +// SetBioDataTextL Converts message type to bio message id. +// Returns: None. +// ----------------------------------------------------------------------------- +// +void TObexUtilsMessageHandler::SetBioDataTextL( + TBioMsgIdText& aText, // A bio message id text. + const TDesC8& aType ) // The type of the content. + { + FLOG(_L("[OBEXUTILS]\t SetBioDataTextL()")); + + HBufC16* unicode = CnvUtfConverter::ConvertToUnicodeFromUtf8L( aType ); + CleanupStack::PushL( unicode ); + + if (unicode->Length() > KMaxBioIdText ) + { + User::Leave( KErrOverflow ); + } + + aText = unicode->Des(); + CleanupStack::PopAndDestroy( unicode ); + + FLOG(_L("[OBEXUTILS]\t SetBioDataTextL() completed")); + } + +// ----------------------------------------------------------------------------- +// SetDetailsLC Converts message type to unicode. +// Returns: None. +// ----------------------------------------------------------------------------- +// +void TObexUtilsMessageHandler::SetDetailsLC( + TPtrC& aDetails, // A message text. + const TDesC8& aType ) // The type of the content. + { + FLOG(_L("[OBEXUTILS]\t SetDetailsLC()")); + + HBufC16* unicode = CnvUtfConverter::ConvertToUnicodeFromUtf8L( aType ); + CleanupStack::PushL( unicode ); + aDetails.Set(unicode->Des()); + + FLOG(_L("[OBEXUTILS]\t SetDetailsLC() completed")); + } + +//------------------------------------------------------------------------------- +// Rename a file and move file if needed +// Return: None. +//------------------------------------------------------------------------------- +// +TInt TObexUtilsMessageHandler::RenameFileL( + TFileName& aFileName, + TFileName& aNewFileName, + const TDesC& aNewPath, + RFs& aFileSession) + { + // We move the file to the final location + // + CFileMan* fileMan= CFileMan::NewL(aFileSession); + CleanupStack::PushL(fileMan); + + fileMan->Move(aFileName,aNewPath,CFileMan::ERecurse ); + CleanupStack::PopAndDestroy(fileMan); + + TParse fileParse; + fileParse.Set(aFileName, NULL, NULL); + + TFileName tempFile; + tempFile.Append(aNewPath); + tempFile.Append(fileParse.NameAndExt()); + aFileName = tempFile; + + // check the duplicated file name. if so, we renamed in a different way. + TInt segmentNum = 0; + TBuf<64> segmentString; + + TFileName newFullName; + newFullName.Zero(); + newFullName.Append(aNewPath); + newFullName.Append(aNewFileName); + + aFileSession.SetSessionPath(aNewPath); + + while ( BaflUtils::FileExists(aFileSession, newFullName) ) + { + segmentNum++; + User::LeaveIfError( RenameFileWithSegmentNumL(aNewFileName, segmentNum, segmentString) ); + newFullName.Zero(); + newFullName.Append(aNewPath); + newFullName.Append(aNewFileName); + } + // rename the file. + // + TInt error = aFileSession.Rename(aFileName, newFullName); + aFileName = newFullName; + + return error; + } + +//------------------------------------------------------------------------------- +// Rename a file by adding a additional segment string +// Return: None. +//------------------------------------------------------------------------------- +// +TInt TObexUtilsMessageHandler::RenameFileWithSegmentNumL( + TDes &aFileName, // name for the file + TInt aSegmentNum, // segment number + TDes &aSegmentString) // segment String with parenthesis + { + + FLOG(_L("[OBEXUTILS]\t RenameFileWithSegmentNumL()")); + + const char KDot = '.'; + const char KLeftParenthesis = '('; + const char KRightParenthesis = ')'; + + // Convert Integer to String + // + TBuf<64> buf; + buf.Zero(); + _LIT(KNum, "%d" ); + buf.AppendFormat(KNum, aSegmentNum); + + // Rules to modify the duplicated filenames. + // case 1: No extention in filename, we append aSegmentString directly. + // case 2: Filename with extention, we insert aSegmentString right before dot (.) + // case 3: Filename with aSegmentString is still duplicated, + // we remove the old aSegmentString from aFileName and add a new one and add a new aSegmentString. + + TInt posOfDot = aFileName.LocateReverse(KDot); + + if ( aSegmentNum > 1 ) // filename with aSegementString is still duplicated + { + // In case the original file name contains the same string as our aSegmentString + // eg 1 with ext. original filename is file(1).txt, after renaming, it is changed to file(1)(1).txt. + // eg 2 without ext. original filename is file(1), after renaming, it is changed to file(1)(1). + TInt posDeleteStarts = posOfDot == KErrNotFound ? + aFileName.Length() - aSegmentString.Length() : + posOfDot - aSegmentString.Length(); + + aFileName.Delete(posDeleteStarts, aSegmentString.Length()); + } + + // Construct (New) aSegmentString + aSegmentString.Zero(); + aSegmentString.Append(KLeftParenthesis); + aSegmentString.Append(buf); + aSegmentString.Append(KRightParenthesis); + + // + // If the length of new filename will be larger than KMaxFileName, we remove few chars from the end of aFilename + // in order to add aSegmentString without panic. + // + if ( KMaxFileName < (aFileName.Length() + aSegmentString.Length())) + { + aFileName.Delete(KMaxFileName - aSegmentString.Length(), KMaxFileName - aFileName.Length()); + } + + posOfDot = aFileName.LocateReverse(KDot); + if ( posOfDot == KErrNotFound ) + { + // aFileName has no extension + // we append the modification to aFileName + // + aFileName.Append(aSegmentString); + } + else + { + // Dot (.) is found, we insert the modifications before dot. + // + aFileName.Insert(posOfDot,aSegmentString); + + } + + FLOG(_L("[OBEXUTILS]\t RenameFileWithSegmentNumL() completed")); + return KErrNone; + } + +//------------------------------------------------------------------------------- +// Shorten an extreme long file name +// Return: None. +//------------------------------------------------------------------------------- +// +void TObexUtilsMessageHandler::FixExtremeLongFileName(TFileName& aExtremeLongFileName, const TDesC& aDriveAndPath) + { + FLOG( _L( "[OBEXUTILS]\t FixExtremeLongFileName() ") ); + const char KDot = '.'; + TInt combinedLength = aExtremeLongFileName.Length() + aDriveAndPath.Length(); + + if ( combinedLength > aExtremeLongFileName.MaxLength() ) + { + FLOG( _L( "[OBEXUTILS]\t FixExtremeLongFileName: combinedLenght > aExtremeLongFileName.MaxLength()\t") ); + //KDefaultFileExtensionSeparator + TFileName tempFileName; + TInt dotPos = aExtremeLongFileName.LocateReverse( KDot ); + TInt overLap = combinedLength - aExtremeLongFileName.MaxLength() + KRenameOffSet; + + if ( dotPos > 0 ) + { + tempFileName.Copy( aExtremeLongFileName.Left( dotPos - overLap ) ); + tempFileName.Append( aExtremeLongFileName.Right( aExtremeLongFileName.Length() - dotPos ) ); + } + else + { + tempFileName.Copy( aExtremeLongFileName.Left(aExtremeLongFileName.Length() - overLap ) ); + } + aExtremeLongFileName.Copy( tempFileName ); + } + FLOG( _L( "[OBEXUTILS]\t FixExtremeLongFileName() completed") ); + } + +// End of File +