--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pimprotocols/pbap/server/pbapfoldernodech.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,429 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "pbapfoldernodech.h"
+#include "pbapfolderclient.h"
+#include "pbaperrorreporter.h"
+#include "pbapappheader.h"
+#include "pbapserver.h"
+#include "pbapchview.h"
+#include "pbapchexporter.h"
+
+#include "btaccesshostlog.h"
+
+
+// constants
+_LIT(KFolderIch, "ich");
+_LIT(KFolderOch, "och");
+_LIT(KFolderMch, "mch");
+_LIT(KFolderCch, "cch");
+
+
+CFolderNodeCallHistory::CFolderNodeCallHistory(MVirtualFolderClient& aClient, const TDesC& aFolderName, THistoryType aHistoryType)
+: CFolderNode(aClient, aFolderName), iHistoryType(aHistoryType), iPendingExport(ENoExport)
+ {
+ LOG_FUNC
+ }
+
+// must be called by any class that inherits from CFolderNodeCallHistory
+void CFolderNodeCallHistory::ConstructL()
+ {
+ LOG_FUNC
+
+ // create the view for this folder node
+ iFolderView = CPbapChView::NewL(iClient.LogClient(), iHistoryType, *this, KLogNullFlags);
+ }
+
+CFolderNodeCallHistory::~CFolderNodeCallHistory()
+ {
+ LOG_FUNC
+
+ delete iAsyncExporter;
+ delete iFolderView;
+ delete iReadFolderView;
+ }
+
+
+void CFolderNodeCallHistory::CancelGet()
+ {
+ LOG_FUNC
+
+ // cancel any asynchronous export operations and avoid iAsyncExporter is deleted
+ // by itself
+ CPbapChExporter* tmpExporter = iAsyncExporter;
+ iAsyncExporter = NULL;
+ delete tmpExporter;
+
+ delete iAppHeader;
+ iAppHeader = NULL;
+ }
+
+void CFolderNodeCallHistory::GetComplete()
+ {
+ LOG_FUNC
+
+ if (iAsyncExporter)
+ {
+ delete iAsyncExporter;
+ iAsyncExporter = NULL;
+ }
+ }
+
+TInt CFolderNodeCallHistory::DoExport(TExportType aExportType, TInt aHandle)
+ {
+ LOG_FUNC
+
+ if(iAsyncExporter)
+ {
+ __ASSERT_DEBUG(EFalse, Panic(EVirtualFolderChExportAlreadyExists));
+ return KErrAlreadyExists;
+ }
+
+
+ TInt err = KErrNone;
+
+ if ((aExportType == EExportItem) && (iCallHistoryChanged))
+ {
+ // the Call History db has been modified since the last get request
+ // report precondition failed error to obex until next listing
+ // request completes (or new Pbap session initiated)
+ iClient.ErrorReporter().SendPreconditionFailedError();
+ // error already reported above so don't update error
+
+ delete iAppHeader;
+ iAppHeader = NULL;
+ }
+ else if (iReadyToExport)
+ {
+ err = StartExport(aExportType, aHandle);
+ }
+ else
+ {
+ // views not ready, setup a pending export until they are
+ if(iPendingExport != ENoExport)
+ {
+ __ASSERT_DEBUG(EFalse, Panic(EVirtualFolderExportAlreadyPending));
+ return KErrAlreadyExists;
+ }
+
+ if (!iFolderView)
+ {
+ // creating the folder view failed before, try again
+ TRAP(err, iFolderView = CPbapChView::NewL(iClient.LogClient(), iHistoryType, *this, KLogNullFlags));
+ }
+
+ // setup this export as pending until we are ready to export
+ if (err == KErrNone)
+ {
+ iPendingExport = aExportType;
+ iPendingHandle = aHandle;
+ }
+ }
+ return err;
+ }
+
+TInt CFolderNodeCallHistory::DoGetItem(TInt aHandle)
+ {
+ LOG_FUNC
+ return DoExport(EExportItem, aHandle);
+ }
+
+TInt CFolderNodeCallHistory::DoGetListing()
+ {
+ LOG_FUNC
+ return DoExport(EExportListing);
+ }
+
+TInt CFolderNodeCallHistory::DoGetCount()
+ {
+ LOG_FUNC
+ return DoExport(EExportCount);
+ }
+
+TInt CFolderNodeCallHistory::DoGetFolder()
+ {
+ LOG_FUNC
+ return DoExport(EExportFolder);
+ }
+
+ void CFolderNodeCallHistory::HandleExportComplete(TInt aError)
+ {
+ LOG_FUNC
+
+ if (aError == KErrNotFound && iAppHeader->Operation() == EPullVCard)
+ {
+ // must report not found to client if attempting to pull a vCard which
+ // doesnot exist
+ iClient.ErrorReporter().SendNotFoundError();
+ }
+ else if (aError && iCallHistoryChanged)
+ {
+ iClient.ErrorReporter().SendPreconditionFailedError();
+ }
+ else if (aError)
+ {
+ // error occured during export report service unavailable error to obex
+ iClient.ErrorReporter().SendServiceUnavailableError();
+ }
+
+ // a successful listing request allows the ch entries to be pulled again
+ // after the database has been modified
+ if (aError == KErrNone && iAppHeader->Operation() == EPullVCardListing)
+ {
+ iCallHistoryChanged = EFalse;
+ }
+
+ delete iAppHeader;
+ iAppHeader = NULL;
+ }
+
+
+void CFolderNodeCallHistory::CancelPendingExport(TInt err)
+ {
+ LOG_FUNC
+
+ if (iPendingExport != ENoExport)
+ {
+ // complete the export with an error
+ HandleExportComplete(err);
+
+ // pending export done
+ iPendingExport = ENoExport;
+ }
+ }
+
+TInt CFolderNodeCallHistory::StartExport(TExportType aExportType, TInt aHandle)
+ {
+ LOG_FUNC
+
+ if(iAsyncExporter)
+ {
+ __ASSERT_DEBUG(EFalse, Panic(EVirtualFolderChExportAlreadyExists));
+ return KErrAlreadyExists;
+ }
+ if(iReadyToExport == EFalse)
+ {
+ __ASSERT_DEBUG(EFalse, Panic(EVirtualFolderNotReadyToExport));
+ return KErrNotReady;
+ }
+ if(!iFolderView)
+ {
+ __ASSERT_DEBUG(EFalse, Panic(EVirtualFolderIncompleteViews));
+ return KErrNotFound;
+ }
+
+ TInt err = KErrNone;
+
+ switch(aExportType)
+ {
+ case EExportItem:
+ // aHandle is decremented here as the PBAP handles for call histories start at 1 and our event index starts at 0
+ TRAP(err, iAsyncExporter = CPbapChSingleItemExporter::NewL(iClient, *this, *iFolderView, aHandle - 1, iAppHeader->VCardVersion(), iAppHeader->Filter()));
+ break;
+
+ case EExportListing:
+ TRAP(err, iAsyncExporter = CPbapChListingExporter::NewL(iClient, *this, *iFolderView, iReadFolderView, iAppHeader->ListStartOffset(), iAppHeader->MaxListCount()));
+ break;
+
+ case EExportCount:
+ TRAP(err, iAsyncExporter = CPbapChCountExporter::NewL(iClient, *this, *iFolderView, iReadFolderView));
+ break;
+
+ case EExportFolder:
+ TRAP(err, iAsyncExporter = CPbapChItemExporter::NewL(iClient, *this, *iFolderView, iReadFolderView, iAppHeader->ListStartOffset(), iAppHeader->MaxListCount(), iAppHeader->VCardVersion(), iAppHeader->Filter()));
+ break;
+
+ case ENoExport:
+ // nothing to do
+ break;
+ default:
+ break;
+ }
+ return err;
+ }
+
+// From MPbapChViewObserver.
+void CFolderNodeCallHistory::CallHistoryViewReady(TInt aError)
+ {
+ LOG_FUNC
+
+ if(aError != KErrNone)
+ {
+ __ASSERT_DEBUG(EFalse, Panic(EVirtualFolderIncompleteViews));
+ }
+
+ // assume we are ready to export unless we determine otherwise
+ iReadyToExport = ETrue;
+
+ // make sure that we have all the view required to be able to export
+ if ((aError == KErrNone) && (iHistoryType == EMissed) && (!iReadFolderView))
+ {
+ // create view of read missed events, used to determine the number of unread events
+ TRAP(aError, iReadFolderView = CPbapChView::NewL(iClient.LogClient(), iHistoryType, *this, KLogEventRead));
+
+ if (aError == KErrNone)
+ {
+ // we will be notified again when the read missed events view is ready so wait for
+ // that notification before we are ready to export
+ iReadyToExport = EFalse;
+ }
+ else
+ {
+ // log error but still allow exports to take place, they will just not include the
+ // new unread event count in any export
+ LOG1(_L("Failed to create read missed call view, error: %d"), aError);
+ }
+ }
+ else if (aError != KErrNone)
+ {
+ if (iReadFolderView)
+ {
+ // log error but still allow exports to take place, they will just not include the
+ // new unread event count in any export
+ LOG1(_L("Failed to create read missed call view, error: %d"), aError);
+
+ delete iReadFolderView;
+ iReadFolderView = NULL;
+ }
+ else
+ {
+ // log error and attempt to create views again on next export
+ LOG1(_L("Failed to create folder call history view, error: %d"), aError);
+
+ delete iFolderView;
+ iFolderView = NULL;
+
+ iReadyToExport = EFalse;
+ CancelPendingExport(aError);
+ }
+ }
+
+ // check for any pending exports
+ if ((iReadyToExport) && (iPendingExport != ENoExport))
+ {
+ aError = StartExport(iPendingExport, iPendingHandle);
+
+ if (aError != KErrNone)
+ {
+ // complete the export with an error
+ HandleExportComplete(aError);
+ }
+
+ // pending export done
+ iPendingExport = ENoExport;
+ }
+ }
+
+void CFolderNodeCallHistory::CallHistoryChangeNotification(TBool aViewReady)
+ {
+ LOG_FUNC
+
+ // Force the PCE to issue a PullvCardListing before we will respond to another
+ // PullvCardEntry request for this folder
+ iCallHistoryChanged = ETrue;
+
+ // check to see if there is an export in progress
+ if (iAsyncExporter)
+ {
+ // cancel the export and report error according to the error reporting
+ // scheme for modified/deleted handles
+ CancelGet();
+ }
+
+ // the view may need refreshing after a change and therefore we are ready to
+ // export if the view is ready to use. If not, then we will get notification
+ // via the CallHistoryViewReady callback
+ iReadyToExport = aViewReady;
+ }
+
+
+//
+// CFolderNodeIch
+//
+/*static*/ CFolderNodeIch* CFolderNodeIch::NewL(MVirtualFolderClient& aClient)
+ {
+ LOG_STATIC_FUNC
+ CFolderNodeIch* self = new (ELeave) CFolderNodeIch(aClient);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CFolderNodeIch::CFolderNodeIch(MVirtualFolderClient& aClient)
+: CFolderNodeCallHistory(aClient, KFolderIch(), EIncoming)
+ {
+ LOG_FUNC
+ }
+
+
+//
+// CFolderNodeOch
+//
+/*static*/ CFolderNodeOch* CFolderNodeOch::NewL(MVirtualFolderClient& aClient)
+ {
+ LOG_STATIC_FUNC
+ CFolderNodeOch* self = new (ELeave) CFolderNodeOch(aClient);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CFolderNodeOch::CFolderNodeOch(MVirtualFolderClient& aClient)
+: CFolderNodeCallHistory(aClient, KFolderOch(), EOutgoing)
+ {
+ LOG_FUNC
+ }
+
+
+//
+// CFolderNodeMch
+//
+/*static*/ CFolderNodeMch* CFolderNodeMch::NewL(MVirtualFolderClient& aClient)
+ {
+ LOG_STATIC_FUNC
+ CFolderNodeMch* self = new (ELeave) CFolderNodeMch(aClient);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CFolderNodeMch::CFolderNodeMch(MVirtualFolderClient& aClient)
+: CFolderNodeCallHistory(aClient, KFolderMch(), EMissed)
+ {
+ LOG_FUNC
+ }
+
+
+//
+// CFolderNodeCch
+//
+/*static*/ CFolderNodeCch* CFolderNodeCch::NewL(MVirtualFolderClient& aClient)
+ {
+ LOG_STATIC_FUNC
+ CFolderNodeCch* self = new (ELeave) CFolderNodeCch(aClient);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CFolderNodeCch::CFolderNodeCch(MVirtualFolderClient& aClient)
+: CFolderNodeCallHistory(aClient, KFolderCch(), ECombined)
+ {
+ LOG_FUNC
+ }