locationtriggering/ltserver/ltserverlogic/src/lbtserverlogic.cpp
changeset 0 667063e416a2
child 13 19bff11d6c18
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/locationtriggering/ltserver/ltserverlogic/src/lbtserverlogic.cpp	Tue Feb 02 01:06:48 2010 +0200
@@ -0,0 +1,1668 @@
+/*
+* Copyright (c) 2007 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:  LBT Sever Logic
+*
+*/
+
+
+// INCLUDE FILES
+#include <ecom.h>
+#include <e32base.h>
+#include <implementationproxy.h>
+#include <e32property.h>
+#include <lbtstatuspskeys.h>
+#include <lbttriggeringsystemsettings.h>
+#include <lbterrors.h>
+#include "lbtcontainertriggerfilter.h"
+#include "lbtserverlogic.h"
+#include "lbtserverconsts.h"
+#include "lbtcreatetriggeraooperation.h"
+#include "lbtstrategybase.h"
+#include "lbttriggerfirehandler.h"
+#include "lbtbackuprestorelistener.h"
+#include "lbtcontainer.h"
+#include "lbtglobal.h"
+#include "lbtstratergycontainer.h"
+#include "lbtlistaooperation.h"
+#include "lbtsettingsmanager.h"
+#include "lbtcontainertriggerentry.h"
+#include "lbttriggermodifyaooperation.h"
+#include "lbtnotificationmap.h"
+#include "lbttriggerchangeevent.h"
+#include "lbtcontainerupdatefilter.h"
+#include "lbttriggerfilterbyattribute.h"
+#include "lbtlogger.h"
+#include "lbtdeletesessiontriggers.h"
+#include "lbtappchangehandler.h"
+#include "lbtcleanuphandler.h"
+#include "lbtsimchangehandler.h"
+#include "lbtlogger.h"
+
+// ===================== LOCAL FUNCTIONS =====================
+
+const TImplementationProxy ImplementationTable[] = 
+	{
+    IMPLEMENTATION_PROXY_ENTRY( 0x1028312C, CLbtServerLogic::NewL ) 
+    };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount )
+    {
+    aTableCount = sizeof( ImplementationTable ) / sizeof( TImplementationProxy );
+    return ImplementationTable;
+    }
+
+
+TInt OrderTriggerEntryBySid(
+    const CLbtContainerTriggerEntry& aLhs, 
+    const CLbtContainerTriggerEntry& aRhs)
+	{
+	CLbtContainerTriggerEntry& lhs = const_cast<CLbtContainerTriggerEntry&>(aLhs);
+	CLbtContainerTriggerEntry& rhs = const_cast<CLbtContainerTriggerEntry&>(aRhs);
+	
+	if(lhs.ExtendedTriggerInfo()->OwnerSid() < rhs.ExtendedTriggerInfo()->OwnerSid())
+		{
+		return -1;
+		}
+	else if(lhs.ExtendedTriggerInfo()->OwnerSid() > rhs.ExtendedTriggerInfo()->OwnerSid())
+		{
+		return 1;
+		}
+	else
+		{
+		return 0;
+		}
+	}
+
+// ===================== MEMBER FUNCTIONS =====================
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::NewL
+// Symbian Two - phase constructor
+// ---------------------------------------------------------------------------
+//
+CLbtServerLogic* CLbtServerLogic::NewL()
+	{
+    LBT_TRACE(KLbtLogVerbose|KLbtLogServerLogic,__FILE__, __LINE__, "Entering NewL" );
+	CLbtServerLogic* self = new ( ELeave ) CLbtServerLogic;
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+    LBT_TRACE(KLbtLogVerbose|KLbtLogServerLogic,__FILE__, __LINE__, "Returning from NewL" );
+    return self;
+	}
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::~CLbtServerLogic
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CLbtServerLogic::~CLbtServerLogic()
+	{
+	FUNC_ENTER("CLbtServerLogic::~CLbtServerLogic");
+    // Cancel all outstanding operations.		
+	CancelAllOperations();
+
+	delete iBackupRestoreListener;
+	delete iStratergyContainer;
+	delete iSettingsManager;
+	delete iFireHandler;
+	delete iAppChangeHandler;
+	delete iNotificationMap;
+	delete iCleanupHandler;
+    delete iSimChangeHandler;	
+	iAOOArray.ResetAndDestroy();
+	iDeleteSessionTriggersArray.ResetAndDestroy();
+	CLbtContainer::Destroy();
+	iProperty.Close();
+	}
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::CLbtServerLogic
+// ---------------------------------------------------------------------------
+//
+CLbtServerLogic::CLbtServerLogic() : iContainer(NULL)
+	{
+	}
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::ServiceL
+// ---------------------------------------------------------------------------
+//
+void CLbtServerLogic::ServiceL(const RMessage2 &aMessage, TSubSessionType aType)
+	{
+	FUNC_ENTER("CLbtServerLogic::ServiceL");
+    LBT_TRACE(KLbtLogVerbose|KLbtLogServerLogic,__FILE__, __LINE__, "Received IPC function = %d client = %x", aMessage.Function(), aMessage.SecureId().iId );
+	// If backup or restore operation is in progress then return server busy
+	if(iBackupRestoreListener->IsBackupRestoreOperationInProgress())
+		{
+		LbtGlobal::RequestComplete(aMessage, KErrServerBusy);
+		return;
+		}	
+		
+	/**
+	 * All IPC messages which requires notification will be 
+	 * stored and serviced by server logic. Other messages will
+	 * be serviced by AOOperation objects
+	 */ 
+	switch(aMessage.Function())
+		{
+		/**
+		 * The below are all notification requests. Hence insert the 
+		 * message into the message array and notify the requestor  
+		 * when the event occurs	
+		 */
+		case ELbtNotifyTriggerChangeEvent:
+		case ELbtNotifyTriggerFired:
+		case ELbtNotifyNearestTriggerChange:
+		case ELbtNotifyTriggeringSysSettingChange:
+		case ELbtNotifyTriggeringSysStatusChange:
+			{
+			TInt retValue=ValidateChangeNotification(aMessage);
+			
+			if(retValue!=KErrNone)
+				{
+				// If validation failed then complete the request with the appropriate error code
+				LbtGlobal::RequestComplete(aMessage, retValue);				
+				break;
+				}
+			InsertIntoNotificationMapL(aMessage, aType);			
+			break;
+			}
+		case ELbtCnclNotifyTriggerChangeEvent:		
+			{
+			TInt retVal = RemoveFromNotificationMap(aMessage, ELbtNotifyTriggerChangeEvent);
+			LbtGlobal::RequestComplete(aMessage, retVal);
+			break;
+			}
+		case ELbtCnclNotifyTriggerFired:
+			{
+			TInt retVal = RemoveFromNotificationMap(aMessage, ELbtNotifyTriggerFired);
+			LbtGlobal::RequestComplete(aMessage, retVal);			
+			break;
+			}
+		case ELbtCnclNotifyNearestTriggerChange:
+			{
+			TInt retVal = RemoveFromNotificationMap(aMessage, ELbtNotifyNearestTriggerChange);
+			LbtGlobal::RequestComplete(aMessage, retVal);			
+			break;
+			}
+		case ELbtCnclNotifyTriggeringSysStatusChange:
+			{
+			TInt retVal = RemoveFromNotificationMap(aMessage, ELbtNotifyTriggeringSysStatusChange);
+			LbtGlobal::RequestComplete(aMessage, retVal);			
+			break;
+			}
+		case ELbtCnclNotifyTriggeringSysSettingChange:
+			{
+			TInt retVal = RemoveFromNotificationMap(aMessage, ELbtNotifyTriggeringSysSettingChange);
+			LbtGlobal::RequestComplete(aMessage, retVal);			
+			break;
+			}
+		case ELbtCreateTrigger: // create trigger
+			{
+			// Validate the IPC message and the trigger for create trigger
+			TInt retVal = ValidateCreateTriggerMessage(aMessage);
+			
+			if( retVal != KErrNone )
+				{
+				// If validation failed then complete the request with the appropriate error code
+				LbtGlobal::RequestComplete(aMessage, retVal);				
+				break;
+				}
+				
+			// If capability check is successful then create the aooperation object
+			CLbtCreateTriggerAOOperation* operation = 
+						CLbtCreateTriggerAOOperation::NewL(*this, 
+														   aMessage, 
+														   *iContainer, 
+														   aType,
+														   *iSettingsManager);
+			iAOOArray.Append(operation);
+			operation->StartOperationL();
+			break;
+			}
+		case ELbtGetTriggers:
+		case ELbtGetFiredTriggers:
+		case ELbtListTriggerIds:
+			{
+			TInt retValue=ValidateGeneralOperation(aMessage);
+			
+			if(retValue!=KErrNone)
+				{
+				// If validation failed then complete the request with the appropriate error code
+				LbtGlobal::RequestComplete(aMessage, retValue);				
+				break;
+				}
+			for(TInt i = 0; i < iAOOArray.Count(); ++i)
+				{
+				CLbtAOOperationBase* operation = iAOOArray[i];				
+				if(operation->GetSecureId() == aMessage.SecureId() &&
+				   operation->GetSubSessionHandle() == aMessage.Int3() &&
+				   ( iAOOArray[i]->GetFunction() == ELbtGetTriggersBufferSize ||
+    			     iAOOArray[i]->GetFunction() == EGetFiredTriggersCount ||
+    			     iAOOArray[i]->GetFunction() == ELbtGetListTriggerIdsSize ) )
+					{
+					// The session id and the client of the message are the 
+					// same and since a sub-session can have just one outstanding
+					// asynchronous service request, the AO object obtained must be
+					// the listAO operation object to service this request
+					CLbtListAOOperation* listOperation = static_cast<CLbtListAOOperation*>(operation);
+					listOperation->ServiceMessageL(aMessage);
+					break;
+					}
+				}
+			break;
+			}
+		case ELbtGetTriggersBufferSize:
+		case EGetFiredTriggersCount:
+		case ELbtGetListTriggerIdsSize:
+			{
+			TInt retValue=ValidateGeneralOperation(aMessage);
+			
+			if(retValue!=KErrNone)
+				{
+				// If validation failed then complete the request with the appropriate error code
+				LbtGlobal::RequestComplete(aMessage, retValue);				
+				break;
+				}
+			CLbtListAOOperation* operation = 
+						CLbtListAOOperation::NewL(*this, aMessage, *iContainer, aType);
+		    iAOOArray.Append(operation);
+			operation->StartOperationL();
+			break;
+			}
+		case ELbtUpdateTrigger:
+		case ELbtSetTriggerState:
+		case ELbtSetTriggersState:
+		case ELbtDeleteTrigger:
+		case ELbtDeleteTriggers:
+			{
+			TInt retValue=ValidateGeneralOperation(aMessage);
+			
+			if(retValue!=KErrNone)
+				{
+				// If validation failed then complete the request with the appropriate error code
+				LbtGlobal::RequestComplete(aMessage, retValue);				
+				break;
+				}
+			
+			CLbtTriggerModifyAOOperation* operation = 
+						CLbtTriggerModifyAOOperation::NewL(*this, aMessage, *iContainer, aType,*iSettingsManager);
+		    iAOOArray.Append(operation);
+			operation->StartOperationL();
+			break;
+			}
+		case ELbtGetTriggeringSysSetting:
+			{
+			TInt retValue=ValidateGetTriggeringSysSetting(aMessage);
+			
+			if(retValue!=KErrNone)
+				{
+				// If validation failed then complete the request with the appropriate error code
+				LbtGlobal::RequestComplete(aMessage, retValue);				
+				break;
+				}
+				
+			TInt retVal = GetTriggeringSystemSettings( aMessage, aType );
+
+			if(retVal == KErrNone)
+				{
+				LbtGlobal::RequestComplete(aMessage, KErrNone);
+				}
+			break;
+			}
+			
+		case ELbtSetTriggeringSettings:
+			{
+			TInt retValue=ValidateSetTriggeringSetting(aMessage);
+			
+			if(retValue!=KErrNone)
+				{
+				// If validation failed then complete the request with the appropriate error code
+				LbtGlobal::RequestComplete(aMessage, retValue);				
+				break;
+				}
+				
+        	// The request can only be through the LT management API.
+        	// ToDo : Check for capabilities.
+			if ( TLbtManagementLibrary != aType ) 
+			    {
+			    // This is not a management library. Hence return access denied.
+    		    aMessage.Complete( KErrAccessDenied );
+			    }
+            else
+                {
+        	    TLbtTriggeringSystemManagementSettings settings;
+        		TPckg<TLbtTriggeringSystemManagementSettings> pckgSettings(settings);
+                // In case of error in LbtGlobal::Read then the client is already
+                // panic'ed hence there is no need to complete the message again.
+    			if( !LbtGlobal::Read(aMessage, KParamSettings, pckgSettings) )
+    				{
+                    // KParamMask slot contains the mask of the settings to be changed.
+                    SetTriggeringSystemSettings( settings, aMessage.Int0() );
+        		    aMessage.Complete( KErrNone );
+    				}
+                }
+			// TODO: Handle triggering settings change request from management library
+			//HandleNotificationOperationsL(aMessage);
+			break;
+			}
+		case ELbtGetTriggeringSysStatus:
+	        {
+	        TInt retValue=ValidateGetTriggeringSysStatus(aMessage);
+			
+			if(retValue!=KErrNone)
+				{
+				// If validation failed then complete the request with the appropriate error code
+				LbtGlobal::RequestComplete(aMessage, retValue);				
+				break;
+				}
+				
+			if ( TLbtManagementLibrary != aType ) 
+			    {
+			    // This is not a management library. Hence return access denied.
+    		    aMessage.Complete( KErrAccessDenied );
+			    }
+		    
+		    TLbtTriggeringSystemStatus systemStatus;
+		    GetTriggeringSysStatus( systemStatus );
+		    
+		    TPckg<TLbtTriggeringSystemStatus> systemStatusPckg( systemStatus );
+		    
+		    TInt error = LbtGlobal::Write(aMessage, KParamStatus, systemStatusPckg); 
+		    LbtGlobal::RequestComplete(aMessage, error);
+		    
+            break;
+	        }
+	        
+	    case ELbtCancelCreateTrigger:
+	    	{
+	    	if(!iAOOArray.Count())
+	    		{
+	    		LbtGlobal::RequestComplete(aMessage,KErrNotFound);	
+	    		break;
+	    		}
+	    	for(TInt i=0;i<iAOOArray.Count();i++)
+	    		{
+	    		if((iAOOArray[i]->GetSecureId()==aMessage.SecureId()) &&
+	    			(iAOOArray[i]->GetFunction()==ELbtCreateTrigger) &&
+	    			(iAOOArray[i]->GetSubSessionHandle()==aMessage.Int3()))
+	    			{
+	    			CLbtCreateTriggerAOOperation* createTriggerAOOperation=
+	    							static_cast<CLbtCreateTriggerAOOperation*>
+	    							(iAOOArray[i]);
+	    			createTriggerAOOperation->CancelCreateTrigger();	
+	    			LbtGlobal::RequestComplete(aMessage,KErrNone);
+	    			return;	
+	    			}
+	    		}
+	    	LbtGlobal::RequestComplete(aMessage,KErrNotFound);
+			break;	    
+	    	}
+	    		
+		case ELbtCancelDeleteTriggers:
+		    {
+		    if(!iAOOArray.Count())
+                {
+                LbtGlobal::RequestComplete(aMessage,KErrNotFound);  
+                break;
+                }
+            for(TInt i=0;i<iAOOArray.Count();i++)
+                {
+                if((iAOOArray[i]->GetSecureId()==aMessage.SecureId())&& 
+                    (iAOOArray[i]->GetSubSessionHandle()==aMessage.Int3()) &&
+                    (iAOOArray[i]->GetFunction()==ELbtDeleteTriggers))
+                    {
+                    CLbtTriggerModifyAOOperation* triggerModifyAOOperation=
+                                    static_cast<CLbtTriggerModifyAOOperation*>
+                                    (iAOOArray[i]);
+                    triggerModifyAOOperation->CancelModifyOperation();  
+                    LbtGlobal::RequestComplete(aMessage,KErrNone); 
+                    return;
+                    }
+                }
+            LbtGlobal::RequestComplete(aMessage,KErrNotFound);  
+            break;      
+            }
+		case ELbtCancelSetTriggersState:
+		    {
+		    if(!iAOOArray.Count())
+                {
+                LbtGlobal::RequestComplete(aMessage,KErrNotFound);  
+                break;
+                }
+            for(TInt i=0;i<iAOOArray.Count();i++)
+                {
+                if((iAOOArray[i]->GetSecureId()==aMessage.SecureId())&& 
+                    (iAOOArray[i]->GetSubSessionHandle()==aMessage.Int3()) &&
+                    (iAOOArray[i]->GetFunction()==ELbtSetTriggersState))
+                    {
+                    CLbtTriggerModifyAOOperation* triggerModifyAOOperation=
+                                    static_cast<CLbtTriggerModifyAOOperation*>
+                                    (iAOOArray[i]);
+                    triggerModifyAOOperation->CancelModifyOperation();  
+                    LbtGlobal::RequestComplete(aMessage,KErrNone); 
+                    return;
+                    }
+                }
+            LbtGlobal::RequestComplete(aMessage,KErrNotFound);  
+            break;      
+            }
+		case ELbtCancelUpdateTrigger:    
+	    	{
+	    	if(!iAOOArray.Count())
+	    		{
+	    		LbtGlobal::RequestComplete(aMessage,KErrNotFound);	
+	    		break;
+	    		}
+	    	for(TInt i=0;i<iAOOArray.Count();i++)
+	    		{
+	    		if((iAOOArray[i]->GetSecureId()==aMessage.SecureId())&& 
+	    		    (iAOOArray[i]->GetSubSessionHandle()==aMessage.Int3()) &&
+	    			(iAOOArray[i]->GetFunction()==ELbtUpdateTrigger ))
+	    			{
+	    			CLbtTriggerModifyAOOperation* triggerModifyAOOperation=
+	    							static_cast<CLbtTriggerModifyAOOperation*>
+	    							(iAOOArray[i]);
+	    			triggerModifyAOOperation->CancelModifyOperation();	
+                    LbtGlobal::RequestComplete(aMessage,KErrNone); 
+                    return;
+	    			}
+	    		}
+	    	LbtGlobal::RequestComplete(aMessage,KErrNotFound);	
+			break;	 	
+	    	} 
+	    
+		case ELbtCancelListTriggerIds:
+		    {
+		    if(!iAOOArray.Count())
+                {
+                LbtGlobal::RequestComplete(aMessage,KErrNotFound);  
+                break;
+                }
+            for(TInt i=0;i<iAOOArray.Count();i++)
+                {
+                if((iAOOArray[i]->GetSecureId()==aMessage.SecureId()) &&
+                    (iAOOArray[i]->GetSubSessionHandle()==aMessage.Int3()) &&
+                    (iAOOArray[i]->GetFunction()==ELbtGetListTriggerIdsSize))
+                    {
+                    CLbtListAOOperation* listAOOperation=
+                                    static_cast<CLbtListAOOperation*>
+                                    (iAOOArray[i]);
+                    listAOOperation->CancelListOperation(); 
+                    LbtGlobal::RequestComplete(aMessage,KErrNone); 
+                    return;
+                    }
+                }
+            LbtGlobal::RequestComplete(aMessage,KErrNotFound);  
+            break;   
+            }
+		case ELbtCancelGetTriggers:
+	    	{
+	    	if(!iAOOArray.Count())
+	    		{
+	    		LbtGlobal::RequestComplete(aMessage,KErrNotFound);	
+	    		break;
+	    		}
+	    	for(TInt i=0;i<iAOOArray.Count();i++)
+	    		{
+	    		if((iAOOArray[i]->GetSecureId()==aMessage.SecureId()) &&
+	    			(iAOOArray[i]->GetSubSessionHandle()==aMessage.Int3()) &&
+	    			(iAOOArray[i]->GetFunction()==ELbtGetTriggersBufferSize))
+	    			{
+	    			CLbtListAOOperation* listAOOperation=
+	    							static_cast<CLbtListAOOperation*>
+	    							(iAOOArray[i]);
+	    			listAOOperation->CancelListOperation();	
+                    LbtGlobal::RequestComplete(aMessage,KErrNone); 
+                    return;
+	    			}
+	    		}
+	    	LbtGlobal::RequestComplete(aMessage,KErrNotFound);	
+			break;	 
+	    	}
+	    	
+		case ELbtCancelAll:
+			{
+			RMessage2 message;
+		    while( !iNotificationMap->Retreive( message,aMessage.Int3(),aMessage.SecureId() ) )
+		           {
+	               LbtGlobal::RequestComplete(message, KErrCancel);
+		           }
+			if(!iAOOArray.Count())
+	    		{
+	    		LbtGlobal::RequestComplete(aMessage,KErrNotFound);	
+	    		break;
+	    		}
+			for(TInt i=0;i<iAOOArray.Count();i++)
+				{
+				if(iAOOArray[i]->GetSecureId()==aMessage.SecureId() &&
+					(iAOOArray[i]->GetSubSessionHandle()==aMessage.Int3()))
+					{
+					switch(iAOOArray[i]->GetFunction())
+						{
+						case ELbtCreateTrigger:
+							{
+							CLbtCreateTriggerAOOperation* createTriggerAOOperation=
+	    							static_cast<CLbtCreateTriggerAOOperation*>
+	    							(iAOOArray[i]);
+	    					createTriggerAOOperation->CancelCreateTrigger();
+	    					break;	
+							}
+						case ELbtDeleteTriggers:
+						case ELbtSetTriggersState:
+						case ELbtUpdateTrigger:    
+							{
+							CLbtTriggerModifyAOOperation* triggerModifyAOOperation=
+	    							static_cast<CLbtTriggerModifyAOOperation*>
+	    							(iAOOArray[i]);
+	    					triggerModifyAOOperation->CancelModifyOperation();
+	    					break;
+							}
+						case ELbtGetListTriggerIdsSize:
+						case ELbtGetTriggersBufferSize: 
+							{
+							CLbtListAOOperation* listAOOperation=
+	    							static_cast<CLbtListAOOperation*>
+	    							(iAOOArray[i]);
+	    					listAOOperation->CancelListOperation();	
+	    					break;
+							}
+						default:
+							{
+							break;
+							}	
+						}
+					}
+				}
+			LbtGlobal::RequestComplete(aMessage,KErrNone);		
+			break;	
+			} 
+		default:
+			{
+			break;
+			}
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::LoadOrUnloadStrategyPluginL
+// ---------------------------------------------------------------------------
+//
+void CLbtServerLogic::LoadOrUnloadStrategyPluginL()
+	{
+	FUNC_ENTER("CLbtServerLogic::LoadOrUnloadStrategyPluginL");
+	// Load stratergy if it is not already loaded and if there are valid
+	// and enabled triggers in the system
+	if(!iStratergyContainer->Stratergy() &&  // if stratergy not already loaded
+		iContainer->GetCountOfEnabledAndValidTriggers() && // if there are enabled and valid triggers
+		( iSettingsManager->GetTriggeringMechanismState() == ETriggeringMechanismOn )&&
+		!iBackupRestoreListener->IsBackupRestoreOperationInProgress()) // if backup or restore operation is not in progress
+		{
+        LBT_TRACE(KLbtLogVerbose|KLbtLogServerLogic,__FILE__, __LINE__, "Loading Strategy plugin");
+		iStratergyContainer->LoadStratergyL(this);
+		iStratergyContainer->Stratergy()->StartSupervision();	
+		iStrategyDynamicInfo.iLocationAcquisitionStatus = ELocationAcquisitionActive;
+		NotifyTriggeringSystemStatusChange();
+		}
+	
+	else if(!iContainer->GetCountOfEnabledAndValidTriggers())
+		{
+		// If there are no triggers in the system to be supervised then
+		// unload stratergy
+        LBT_TRACE(KLbtLogVerbose|KLbtLogServerLogic,__FILE__, __LINE__, "Unloading Strategy plugin");
+		iStratergyContainer->UnloadStratergy();
+		iStrategyDynamicInfo.iLocationAcquisitionStatus = ELocationAcquisitionInactive;
+		NotifyTriggeringSystemStatusChange();
+		} 
+	}
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::HandleSubSessionClosure
+// ---------------------------------------------------------------------------
+//
+void CLbtServerLogic::HandleSubSessionClosure(const TInt aSubSessionId, const CSession2* aSession)
+	{
+	FUNC_ENTER("CLbtServerLogic::HandleSubSessionClosure");
+    LBT_TRACE(KLbtLogVerbose|KLbtLogServerLogic,__FILE__, __LINE__, "HandleSubSessionClosure called");
+	// Since the sub-session is being closed remove all the messages
+	// from the message array
+	iNotificationMap->CompleteMessagesOfSubsession(aSession, aSubSessionId, KErrDisconnected);
+
+	// Stop all the AOOperation object pertaining to the 
+	// sub-session that is being closed. 
+	for(TInt i = iAOOArray.Count() - 1; i >= 0 ; --i)
+		{
+		CLbtAOOperationBase* operation = iAOOArray[i];
+		if(operation->GetSubSessionHandle() == aSubSessionId && 
+		   operation->GetSession() == aSession )
+			{
+			iAOOArray.Remove(i);
+			delete operation;
+			}
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::HandleSessionClosureL
+// ---------------------------------------------------------------------------
+//
+void CLbtServerLogic::HandleSessionClosureL(const TSecureId aSecureId)
+	{
+	FUNC_ENTER("CLbtServerLogic::HandleSessionClosureL");
+    LBT_TRACE(KLbtLogVerbose|KLbtLogServerLogic,__FILE__, __LINE__, "Session closed by client %x", aSecureId.iId );
+	// Inform container to delete all the sessions triggers of 
+	// the client with secure id aSecureId.	
+	CLbtContainerFilter* filter = CLbtContainerFilter::NewL();
+	CleanupStack::PushL(filter);
+	filter->AddOwnerSidInFilterL(aSecureId);
+	
+	CLbtTriggerFilterByAttribute* filterByAttribute = 
+				CLbtTriggerFilterByAttribute::NewL();
+	CleanupStack::PushL(filterByAttribute);
+	filterByAttribute->AddTriggerTypeL(CLbtTriggerEntry::ETypeSession);
+	
+	CLbtContainerUpdateFilter* containerFilter = 
+							CLbtContainerUpdateFilter::NewL(filterByAttribute, filter);
+	CleanupStack::PushL(containerFilter);
+	
+	CLbtDeleteSessionTriggers* deleteSessionTriggers=
+							CLbtDeleteSessionTriggers::NewL(*this,*iContainer,*iNotificationMap);
+	iDeleteSessionTriggersArray.Append(deleteSessionTriggers);
+							
+	deleteSessionTriggers->DeleteSessionTriggers(containerFilter);
+	iNotificationMap->RemoveAllClientMessages(aSecureId);
+	CleanupStack::Pop(containerFilter);
+	CleanupStack::Pop(filterByAttribute);
+	CleanupStack::Pop(filter);						
+	}
+	
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::HandleDeleteSessionTriggersClosureL
+// ---------------------------------------------------------------------------
+//
+void CLbtServerLogic::HandleDeleteSessionTriggersClosureL(CLbtDeleteSessionTriggers* aDeleteSessionTriggers)
+	{
+	FUNC_ENTER("CLbtServerLogic::HandleDeleteSessionTriggersClosureL");
+	TInt index = iDeleteSessionTriggersArray.Find(aDeleteSessionTriggers);
+	if(index != KErrNotFound)
+		{
+		iDeleteSessionTriggersArray.Remove(index);
+		}
+	delete aDeleteSessionTriggers;
+	}
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::HandleOperationClosureL
+// ---------------------------------------------------------------------------
+//
+void CLbtServerLogic::HandleOperationClosureL(CLbtAOOperationBase* aOperation, TInt aStatus)
+	{
+	FUNC_ENTER("CLbtServerLogic::HandleOperationClosureL");
+	switch(aOperation->GetFunction())
+		{
+		case ELbtCreateTrigger:
+		case ELbtUpdateTrigger:
+		case ELbtSetTriggerState:
+		case ELbtSetTriggersState:
+		case ELbtDeleteTrigger:
+		case ELbtDeleteTriggers:
+			{
+			LoadOrUnloadStrategyPluginL();
+			if(aStatus == KErrNone)
+				{
+				// Send the active object operation object and the notification type
+				HandleNotificationOperationsL(aOperation, ELbtNotifyTriggerChangeEvent);
+				}
+			break;
+			}
+		default:
+			{
+			break;
+			}
+		}
+
+	// Check which AOOperation object has notified. Delete the	
+	// object and remove it from the aooperation array.
+	TInt index = iAOOArray.Find(aOperation);
+	if(index != KErrNotFound)
+		{
+		iAOOArray.Remove(index);
+		}
+	delete aOperation;
+	}
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::HandleBackupRestoreOperationL
+// ---------------------------------------------------------------------------
+//
+void CLbtServerLogic::HandleBackupRestoreOperationL(TBRState aState)
+	{
+	FUNC_ENTER("CLbtServerLogic::HandleBackupRestoreOperationL");
+	if(aState == MLbtBackupRestoreObserver::EStarted)
+		{
+		// The logic to handle backup / restore operation is as follows.
+		// 1. Cancel All outstanding requests from clients first. Since the AO 
+		//    operations will be using container, this should be done first. 
+		//    This will also close all pending IPC messages with KErrServerBusy.
+		// 2. Then unload the strategy implementation.
+		// 3. Delete the Container instance now.
+
+        // Cancel all outstanding operations.		
+		CancelAllOperations();
+		
+		// Delete all handlers that use server logics container instance
+		delete iFireHandler;
+		iFireHandler = NULL;
+		
+		delete iSimChangeHandler;
+		iSimChangeHandler = NULL;
+		
+		delete iAppChangeHandler;
+		iAppChangeHandler = NULL;
+		
+		delete iCleanupHandler;
+		iCleanupHandler = NULL;
+		
+		// If backup or restore operation has started then unload strategy.
+		iStratergyContainer->UnloadStratergy();
+		// Destroy the container instance. This will close the open Database
+		// file so that it can be backed up or restored.
+		CLbtContainer::Destroy();
+		iContainer = NULL;
+		}
+	else
+		{
+		// Backup and restore operation finished.
+		
+		// Load the Container First since it is required to determine whether
+		// strategy should be loaded or not.
+		iContainer = CLbtContainer::NewL();
+		
+		// Load all handlers that use container same instance
+		iFireHandler = CLbtTriggerFireHandler::NewL(*iNotificationMap, *iContainer);
+		
+		iCleanupHandler = CLbtCleanupHandler::NewL( *iContainer );
+		
+		iSimChangeHandler = CLbtSimChangeHandler::NewL( *iContainer,*iCleanupHandler,*this );
+		iSimChangeHandler->StartToListenL();
+		
+		iAppChangeHandler = CLbtAppChangeHandler::NewL(*iContainer, *iCleanupHandler,*this);
+		iAppChangeHandler->StartListeningL();				
+		
+		// Load Strategy if there are triggers to be monitored.
+		LoadOrUnloadStrategyPluginL();
+		}
+	}
+
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::TriggerFiredL
+// ---------------------------------------------------------------------------
+//
+void CLbtServerLogic::TriggerFiredL( CLbtGeoAreaBase::TGeoAreaType aAreaType,
+                                     TLbtTriggerId aId, const TPositionInfo& aPosInfo )
+	{
+	FUNC_ENTER("CLbtServerLogic::TriggerFiredL");
+	/**
+	 * Create the trigger fire handler. The trigger fire handler is an active 
+	 * object and does the firing operation asynchronously since firing in
+	 * this function will block stratergy's normal operation
+	 */
+	TLbtTriggerFireInfo triggerFireInfo;
+	triggerFireInfo.iAreaType = aAreaType;
+	triggerFireInfo.iTriggerId = aId;
+	triggerFireInfo.iFiredPositionInfo = aPosInfo;
+	iFireHandler->FireTriggerL(triggerFireInfo);
+	}
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::SetTriggeringSupervisionDynamicInfo
+// ---------------------------------------------------------------------------
+//
+void CLbtServerLogic::SetTriggeringSupervisionDynamicInfo( 
+    const TLbtStrategySupervisionDynamicInfo& aStatus )
+	{
+	FUNC_ENTER("CLbtServerLogic::SetTriggeringSupervisionDynamicInfo");
+    iStrategyDynamicInfo = aStatus;
+    NotifyTriggeringSystemStatusChange();
+    }
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::GetTriggeringSupervisionSettings
+// ---------------------------------------------------------------------------
+//
+void CLbtServerLogic::GetTriggeringSupervisionSettings( TLbtStrategyTriggeringSupervisionSettings& aSettings )
+	{
+	FUNC_ENTER("CLbtServerLogic::GetTriggeringSupervisionSettings");
+	aSettings.iGpsTrackingModeInterval = iSettingsManager->GetMinimumUpdateInterval();
+	aSettings.iLocationRequestTimeout = iSettingsManager->GetLocationRequestTimeOut();
+	aSettings.iMaximumUserSpeed = iSettingsManager->GetMaximumUserSpeed();
+	aSettings.iMinimumLocationUpdateInterval = iSettingsManager->GetMinimumUpdateInterval();
+	aSettings.iMinimumLocationUpdateIntervalWithoutGps = iSettingsManager->GetMinimumUpdateIntervalOnGpsFailure();
+	aSettings.iPositioningTechnology = iSettingsManager->GetModuleId();	
+	}
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CLbtServerLogic::ConstructL()
+	{
+	FUNC_ENTER("CLbtServerLogic::ConstructL");
+	iBackupRestoreListener = CLbtBackupRestoreListener::NewL(*this);
+	iBackupRestoreListener->StartToListenL();
+	iContainer = CLbtContainer::NewL();
+	iStratergyContainer = CLbtStratergyContainer::NewL();
+	iSettingsManager = CLbtSettingsManager::NewL();
+	iNotificationMap = CLbtNotificationMap::NewL();
+	iFireHandler = CLbtTriggerFireHandler::NewL(*iNotificationMap, *iContainer);
+	iStrategyDynamicInfo.iLocationAcquisitionStatus = ELocationAcquisitionNotReady;
+	iCleanupHandler = CLbtCleanupHandler::NewL( *iContainer );
+	iSimChangeHandler = CLbtSimChangeHandler::NewL( *iContainer,*iCleanupHandler,*this );
+	iSimChangeHandler->StartToListenL();
+	// App change handler to handle application uninstallation and MMC card removal
+	iAppChangeHandler = CLbtAppChangeHandler::NewL(*iContainer, *iCleanupHandler,*this);
+	iAppChangeHandler->StartListeningL();
+	LoadOrUnloadStrategyPluginL();
+	User::LeaveIfError( iProperty.Attach(KPSUidLbtStatusInformation, 
+                                         KLbtLocationTriggeringSupervisionStatus,
+	                                     EOwnerThread) );
+	
+	if( iSettingsManager->GetTriggeringMechanismState() == ETriggeringMechanismOff )
+        {
+        // Change the status information to supervision not active
+        iProperty.Set(KPSUidLbtStatusInformation, 
+                      KLbtLocationTriggeringSupervisionStatus, 
+                      ELbtLocationTriggeringSupervisionOff);
+        }
+	}
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::CancelAllOperations
+// ---------------------------------------------------------------------------
+//
+void CLbtServerLogic::CancelAllOperations()
+	{
+	FUNC_ENTER("CLbtServerLogic::CancelAllOperations");
+	
+	if(iNotificationMap)
+		{
+		// Inform all outstanding IPC messages that the server is busy with some other operation
+		iNotificationMap->Reset(KErrServerBusy);
+		}	
+	
+	// Destroy all the AOO operation objects
+	iAOOArray.ResetAndDestroy();		
+	}
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::RemoveFromNotificationMap
+// ---------------------------------------------------------------------------
+//
+TInt CLbtServerLogic::RemoveFromNotificationMap(const RMessage2& aMessage, TInt aServiceId)
+	{
+	FUNC_ENTER("CLbtServerLogic::RemoveFromNotificationMap");
+	RMessage2 msg;
+	TInt retVal = iNotificationMap->Retreive(msg,
+											 aMessage.Int3(), 
+											 aMessage.SecureId(), 
+											 aServiceId, 
+											 aMessage.Session());
+	if(retVal == KErrNone)
+		{
+		LbtGlobal::RequestComplete(msg, KErrCancel);
+		}
+	return retVal;
+	}
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::InsertIntoNotificationMapL
+// ---------------------------------------------------------------------------
+//
+void CLbtServerLogic::InsertIntoNotificationMapL(
+    const RMessage2& aMessage,
+    TSubSessionType aType)	
+	{
+	FUNC_ENTER("CLbtServerLogic::InsertIntoNotificationMapL");
+	// Valid request. Insert in sorted order into to the message array	
+	iNotificationMap->InsertL(aMessage, aType);
+	}
+	
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::ValidateChangeNotification
+// ---------------------------------------------------------------------------
+//
+TInt CLbtServerLogic::ValidateChangeNotification(const RMessage2& aMessage)
+	{
+	FUNC_ENTER("CLbtServerLogic::ValidateChangeNotification");
+	if( !aMessage.HasCapability(ECapabilityLocation) ||
+	    !aMessage.HasCapability(ECapabilityReadDeviceData)||
+	    !aMessage.HasCapability(ECapabilityReadUserData))
+		{
+		return KErrPermissionDenied;
+		}
+
+	return KErrNone;
+	}
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::ValidateGeneralOperation
+// ---------------------------------------------------------------------------
+//
+TInt CLbtServerLogic::ValidateGeneralOperation(const RMessage2& aMessage)
+	{
+	FUNC_ENTER("CLbtServerLogic::ValidateGeneralOperation");
+	if( !aMessage.HasCapability(ECapabilityLocation))
+		{
+		return KErrPermissionDenied;
+		}
+
+	return KErrNone;
+	}
+	
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::ValidateCreateTriggerMessage
+// ---------------------------------------------------------------------------
+//
+TInt CLbtServerLogic::ValidateCreateTriggerMessage(const RMessage2& aMessage)
+	{
+	FUNC_ENTER("CLbtServerLogic::ValidateCreateTriggerMessage");
+	// The server should check for the following parameters
+	// 1. capability checks for security.
+	// 2. checks for the Trigger area, ie. radius. (ToDo)
+
+	// Check if the requesting process has location and write user data capability
+	// ToDo : check the required set of capabilities from req spec.
+	if( !aMessage.HasCapability(ECapabilityLocation) ||
+	    !aMessage.HasCapability(ECapabilityWriteUserData) )
+		{
+		return KErrPermissionDenied;
+		}
+
+	return KErrNone;
+	}	
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::ValidateGetTriggeringSysSetting
+// ---------------------------------------------------------------------------
+//
+TInt CLbtServerLogic::ValidateGetTriggeringSysSetting(const RMessage2& aMessage)
+	{
+	FUNC_ENTER("CLbtServerLogic::ValidateGetTriggeringSysSetting");
+	if( !aMessage.HasCapability(ECapabilityLocation)||
+		!aMessage.HasCapability(ECapabilityReadDeviceData))
+		{
+		return KErrPermissionDenied;
+		}
+
+	return KErrNone;
+	}
+	
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::ValidateSetTriggeringSetting
+// ---------------------------------------------------------------------------
+//
+TInt CLbtServerLogic::ValidateSetTriggeringSetting(const RMessage2& aMessage)
+	{
+	FUNC_ENTER("CLbtServerLogic::ValidateSetTriggeringSetting");
+	if( !aMessage.HasCapability(ECapabilityLocation)||
+		!aMessage.HasCapability(ECapabilityWriteDeviceData))
+		{
+		return KErrPermissionDenied;
+		}
+
+	return KErrNone;
+	}		
+	
+	
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::ValidateGetTriggeringSysStatus	
+// ---------------------------------------------------------------------------
+//
+TInt CLbtServerLogic::ValidateGetTriggeringSysStatus(const RMessage2& aMessage)
+	{
+	FUNC_ENTER("CLbtServerLogic::ValidateGetTriggeringSysStatus");
+	if( !aMessage.HasCapability(ECapabilityLocation)||
+		!aMessage.HasCapability(ECapabilityReadDeviceData))
+		{
+		return KErrPermissionDenied;
+		}
+
+	return KErrNone;
+	}
+	
+
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::IsNotificationRequest
+// ---------------------------------------------------------------------------
+//
+TBool CLbtServerLogic::IsNotificationRequest(TInt aServiceId)
+	{
+	FUNC_ENTER("CLbtServerLogic::IsNotificationRequest");
+	if(aServiceId >= ELbtNotifyTriggerFired &&
+	   aServiceId <= ELbtNotifyTriggeringSysSettingChange)
+		{
+		return ETrue;
+		}
+	return EFalse;
+	}
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::HandleNotificationOperationsL
+// ---------------------------------------------------------------------------
+//
+void CLbtServerLogic::HandleNotificationOperationsL(
+    CLbtAOOperationBase* aOperation, 
+    TInt aServiceId)
+	{
+	FUNC_ENTER("CLbtServerLogic::HandleNotificationOperationsL");
+	// This method handles all notifications. The IPC messsage has actually
+	// been compleated and hence the client side buffers should NOT be accessed 
+	// through this message object.
+			
+	// First get the set of registered messages for notification for notification map
+	
+	// 2 types of operations
+	// 1. Client side -- Use the secureId in iMessage
+	// 2. Management Side -- Use the ownerSid retrieved by list triggers.
+
+	// For each secureId now retrieve all messages for the same secureId and serviceId.
+	// Also retrieve all notif msgs from management API.
+	// respond to the pending messages.
+	
+    if ( aOperation->GetFunction() == ELbtCreateTrigger ||
+         aOperation->GetClientType() == CLbtServerLogicBase::TLbtClientLibrary )
+        {
+        HandleSingleNotificationOperationsL( aOperation, aServiceId );
+        }
+    else
+        {
+        HandleMultipleNotificationOperationsL( aOperation, aServiceId );
+        }
+	}
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::HandleSingleNotificationOperationsL
+// ---------------------------------------------------------------------------
+//	
+void CLbtServerLogic::HandleSingleNotificationOperationsL(
+    CLbtAOOperationBase* aOperation, 
+    TInt aServiceId)
+    {
+    FUNC_ENTER("CLbtServerLogic::HandleSingleNotificationOperationsL");
+	RArray<RMessage2> array;
+	RMessage2 message;
+	
+	RArray<TUid> managerUidArray =aOperation->GetManagerArray();
+	for( TInt i=0;i<managerUidArray.Count();i++ )
+	    {
+	    TSecureId secureId(managerUidArray[i]);
+    	// Retrieve all client session notification messages.
+    	while(!iNotificationMap->Retreive(message, secureId, aServiceId) )
+    		{
+    		array.Append(message);
+    		}
+		}
+
+    // Retrieve all management notification messages.
+	while(!iNotificationMap->Retreive(message, 
+	                                  aServiceId,
+	                                  CLbtServerLogicBase::TLbtManagementLibrary))
+		{
+		array.Append(message);
+		}
+
+	if(array.Count() == 0)
+		{
+		array.Close();
+		return;
+		}
+	
+	// Populate the change event structure to send the information to the client based
+	// on the message for which the notification needs to be made
+	TLbtTriggerChangeEvent event;
+	
+	switch(aOperation->GetFunction())
+		{
+		case ELbtCreateTrigger:
+			{
+			event.iEventType = ELbtTriggerChangeEventCreated;
+			// Get the trigger id from the create trigger AO object
+			CLbtCreateTriggerAOOperation* operation = 
+						static_cast<CLbtCreateTriggerAOOperation*>(aOperation);
+        	event.iTriggerId = operation->GetTriggerId();
+			break;
+			}
+		case ELbtSetTriggerState:
+		case ELbtUpdateTrigger:
+			{
+			// Just one trigger has been updated
+			event.iEventType = ELbtTriggerChangeEventUpdated;
+			CLbtTriggerModifyAOOperation* operation = 
+						static_cast<CLbtTriggerModifyAOOperation*>(aOperation);
+			event.iTriggerId = operation->GetTriggerId();
+			break;
+			}		
+		case ELbtDeleteTrigger:
+            {
+			event.iEventType = ELbtTriggerChangeEventDeleted;
+			CLbtTriggerModifyAOOperation* operation = 
+						static_cast<CLbtTriggerModifyAOOperation*>(aOperation);
+			event.iTriggerId = operation->GetTriggerId();
+            break;
+            }
+		case ELbtSetTriggersState:			
+		case ELbtDeleteTriggers:
+			{
+			// Multiple triggers have been updated
+			event.iEventType = ELbtTriggerChangeEventMultiple;
+			break;
+			}
+		default:
+			{
+			break;
+			}
+		}
+	
+	// Respond with the change structure on all registered IPC's
+	for(TInt i=0;i<array.Count();++i)
+		{
+		TPckgBuf<TLbtTriggerChangeEvent> changeEvent(event);
+		if(LbtGlobal::Write(array[i], KParamChangeEvent, changeEvent) == KErrNone)
+			{
+			LbtGlobal::RequestComplete(array[i], KErrNone);
+			}
+		}
+	
+	array.Close();
+    }
+	
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::HandleMultipleNotificationOperationsL
+// ---------------------------------------------------------------------------
+//
+void CLbtServerLogic::HandleMultipleNotificationOperationsL(
+    CLbtAOOperationBase* aOperation, 
+    TInt aServiceId)
+    {
+    FUNC_ENTER("CLbtServerLogic::HandleMultipleNotificationOperationsL");
+	CLbtTriggerModifyAOOperation* operation = 
+		static_cast<CLbtTriggerModifyAOOperation*>(aOperation);
+		// list of triggers that were modified.
+	RPointerArray<CLbtContainerTriggerEntry>& list = 
+	    operation->GetUpdatedTriggerList();
+
+	RArray<RMessage2> array;
+	RMessage2 message;
+	TLbtTriggerChangeEvent event;
+	
+    // sort by SID the retrieved list of triggers that were modified.
+    TLinearOrder<CLbtContainerTriggerEntry> TriggerSidOrderPredicate(OrderTriggerEntryBySid);
+    list.Sort(TriggerSidOrderPredicate);
+    
+    TInt multipleOps = 0;
+    TInt totalTriggersModified = list.Count();
+        
+    for( TInt i = totalTriggersModified - 1; i >= 0 ; --i  )
+        {
+        const TLbtTriggerId& id = list[i]->TriggerEntry()->Id();
+        const TSecureId& sid = list[i]->ExtendedTriggerInfo()->OwnerSid();
+        // Using ternary operator here to check if i is zero becoz then list[i -1] will
+        // be crossing the array boundary.
+        const TSecureId& prevSid = i ? list[i - 1]->ExtendedTriggerInfo()->OwnerSid() : TSecureId(0);
+        
+        if ( sid == prevSid )
+            {
+            // The modification is on the same client as the previous one.
+            // Rather than sending the notification collate them into single event.
+            multipleOps++;
+            continue;
+            }
+    	else
+    	    {
+    	    // The next trigger in list belongs to a different client.
+    	    // So reply back on the notification now.
+        	// retrieve all notification messages of this client.
+        	
+        	while( !iNotificationMap->Retreive(message, sid, aServiceId) )
+        		{
+        		array.Append(message);
+        		}
+
+            SetNotificationEventType(aOperation, event);
+            
+            if ( multipleOps )
+                {
+    			event.iEventType = ELbtTriggerChangeEventMultiple;
+                }
+
+        	event.iTriggerId = id;
+        	// Respond with the change structure on all registered IPC's
+        	for(TInt j = array.Count(); j ; --j)
+        		{
+        		TPckgBuf<TLbtTriggerChangeEvent> changeEvent(event);
+        		if(LbtGlobal::Write(array[j - 1], KParamChangeEvent, changeEvent) == KErrNone)
+        			{
+        			LbtGlobal::RequestComplete(array[j - 1], KErrNone);
+        			}
+        		}
+        	array.Close();
+
+    	    multipleOps = 0;
+    	    }
+        }
+
+    // Retrieve all management Notification messages
+    // Retrieve all management notification messages.
+	while(!iNotificationMap->Retreive(message,
+	                                  aServiceId,
+	                                  CLbtServerLogicBase::TLbtManagementLibrary))
+		{
+		array.Append(message);
+		}
+
+    if ( totalTriggersModified > 1 )
+        {
+        event.iEventType = ELbtTriggerChangeEventMultiple;
+        event.iTriggerId = 0;
+        }
+        
+	// Respond with the change structure on all registered IPC's
+	for(TInt j = array.Count(); j ; --j)
+		{
+		TPckgBuf<TLbtTriggerChangeEvent> changeEvent(event);
+		if(LbtGlobal::Write(array[j - 1], KParamChangeEvent, changeEvent) == KErrNone)
+			{
+			LbtGlobal::RequestComplete(array[j - 1], KErrNone);
+			}
+		}
+	array.Close();
+    }
+
+
+
+void CLbtServerLogic::SetNotificationEventType( 
+    CLbtAOOperationBase* aOperation, 
+    TLbtTriggerChangeEvent& aEvent )
+    {
+    FUNC_ENTER("CLbtServerLogic::SetNotificationEventType");
+	switch(aOperation->GetFunction())
+		{
+		case ELbtCreateTrigger:
+			{
+			aEvent.iEventType = ELbtTriggerChangeEventCreated;
+			break;
+			}
+		case ELbtSetTriggerState:
+		case ELbtUpdateTrigger:
+			{
+			// Just one trigger has been updated
+			aEvent.iEventType = ELbtTriggerChangeEventUpdated;
+			break;
+			}		
+		case ELbtDeleteTrigger:
+            {
+			aEvent.iEventType = ELbtTriggerChangeEventDeleted;
+            break;
+            }
+		case ELbtSetTriggersState:			
+		case ELbtDeleteTriggers:
+		default:
+			{
+			// Multiple triggers have been updated
+			aEvent.iEventType = ELbtTriggerChangeEventMultiple;
+			break;
+			}
+		}
+    }
+
+TInt CLbtServerLogic::GetTriggeringSystemSettings(
+    const RMessage2& aMessage, 
+    TSubSessionType aClientType )
+    {
+    FUNC_ENTER("CLbtServerLogic::GetTriggeringSystemSettings");
+	// The request can be either through LT client API or LT management API.
+	// and the handling has to be slightly different depending on the client type.
+    switch ( aClientType )
+        {
+        case TLbtManagementLibrary:
+    	    {
+    	    // This is the req from the LT client API, Hence return only
+    	    // the min trigger area and triggering engine state ( On/Off ).
+    	    TLbtTriggeringSystemManagementSettings settings;
+
+    		settings.SetMinimumTriggerAreaSize(
+    		    iSettingsManager->MinimumTriggeringArea());
+
+    		TLbtTriggeringMechanismState state = 
+    			static_cast<TLbtTriggeringMechanismState>(
+			    iSettingsManager->GetTriggeringMechanismState());
+    		settings.SetTriggeringMechanismState(state);
+
+    		settings.SetMinimumLocationUpdateInterval( 
+    		    iSettingsManager->GetMinimumUpdateInterval() );
+
+            settings.SetMinimumLocationUpdateIntervalWhenGpsFails( 
+                iSettingsManager->GetMinimumUpdateIntervalOnGpsFailure() );
+
+            settings.SetUsedPositioningModule( 
+                iSettingsManager->GetModuleId() );
+            
+            settings.SetMaximumUserSpeed( 
+                iSettingsManager->GetMaximumUserSpeed() );
+
+    		TPckg<TLbtTriggeringSystemManagementSettings> pckgSettings(settings);
+    		return LbtGlobal::Write(aMessage, KParamSettings, pckgSettings);
+    	    }
+    	    
+
+        case TLbtClientLibrary:
+    	    {
+    	    // This is the req from the LT client API, Hence return only
+    	    // the min trigger area and triggering engine state ( On/Off ).
+    		TLbtTriggeringSystemSettings settings;
+
+    		settings.SetMinimumTriggerAreaSize(
+    		    iSettingsManager->MinimumTriggeringArea() );
+
+    		TLbtTriggeringMechanismState state = 
+				static_cast<TLbtTriggeringMechanismState>(
+				iSettingsManager->GetTriggeringMechanismState());
+
+    		settings.SetTriggeringMechanismState(state);
+
+    		TPckg<TLbtTriggeringSystemSettings> pckgSettings(settings);
+    		return LbtGlobal::Write(aMessage, KParamSettings, pckgSettings);
+    	    }
+    	default :
+            // This is a bug in server implementation. There is no other
+            // session type as of now. Hence treating this as a LT API
+            // client.
+            
+            // Note : Fall through is intended
+            break;
+    	    
+        }
+    return KErrNotSupported;
+    }
+
+void CLbtServerLogic::GetTriggeringSysStatus( TLbtTriggeringSystemStatus& aSystemStatus )
+    {
+    FUNC_ENTER("CLbtServerLogic::GetTriggeringSysStatus");
+    aSystemStatus.iLocationAcquisitionStatus = iStrategyDynamicInfo.iLocationAcquisitionStatus;
+    
+    aSystemStatus.iPositioningMethod = iSettingsManager->GetModuleId();
+    
+    //aSystemStatus.iPositioningMethodName
+    
+    TPosition position;
+    iStrategyDynamicInfo.iLatestAcquiredPosInfo.GetPosition( position );
+    aSystemStatus.iLatestLocationUpdate = position.Time();
+    }
+
+
+void CLbtServerLogic::SetTriggeringSystemSettings(
+    TLbtTriggeringSystemManagementSettings& aSettings,
+    TLbtManagementSettingsMask aSettingsMask )
+    {
+    FUNC_ENTER("CLbtServerLogic::SetTriggeringSystemSettings");
+    if ( aSettingsMask & EMinimumLocationUpdateInterval )
+        {
+        iSettingsManager->SetMinimumUpdateInterval( aSettings.MinimumLocationUpdateInterval() );
+        }
+    if ( aSettingsMask & EMinimumLocationUpdateIntervalWhenGpsFails )
+        {
+        iSettingsManager->SetMinimumUpdateIntervalOnGpsFailure( aSettings.MinimumLocationUpdateIntervalWhenGpsFails() );
+        }
+    if ( aSettingsMask & EUsedPositioningmodule )
+        {
+        iSettingsManager->SetModuleId( aSettings.UsedPositioningModule() );
+        }
+    if ( aSettingsMask & EMaximumUserSpeed )
+        {
+        iSettingsManager->SetMaximumUserSpeed( aSettings.MaximumUserSpeed() );
+        }
+    if ( aSettingsMask & ETriggeringMechanismState )
+        {
+        iSettingsManager->SetTriggeringMechanismState( aSettings.TriggeringMechanismState() );
+        }
+    
+    
+    if( aSettings.TriggeringMechanismState() == ETriggeringMechanismOff )
+        {
+        if( iStratergyContainer->Stratergy() )
+            {
+            iStratergyContainer->UnloadStratergy();
+            }
+        iStrategyDynamicInfo.iLocationAcquisitionStatus = ELocationAcquisitionOff;
+        
+        // Change the status information to supervision off
+        iProperty.Set(KPSUidLbtStatusInformation, 
+                                         KLbtLocationTriggeringSupervisionStatus, 
+                                         ELbtLocationTriggeringSupervisionOff);
+                                         
+        NotifyTriggeringSystemStatusChange();
+        }
+    else
+        {
+        if(!iStratergyContainer->Stratergy() && 
+		   iContainer->GetCountOfEnabledAndValidTriggers() && 
+		   !iBackupRestoreListener->IsBackupRestoreOperationInProgress())
+		    {
+            TRAPD(error,iStratergyContainer->LoadStratergyL(this));
+		    if( KErrNone == error )
+		        {
+		        iStratergyContainer->Stratergy()->StartSupervision();
+		        iStrategyDynamicInfo.iLocationAcquisitionStatus = ELocationAcquisitionActive;
+		        NotifyTriggeringSystemStatusChange();
+		        }
+		    }
+        else
+            {
+            // Change the status information to supervision off
+            iProperty.Set(KPSUidLbtStatusInformation, 
+                      KLbtLocationTriggeringSupervisionStatus, 
+                      ELbtLocationTriggeringSupervisionNotActive);
+            }
+        }    
+        
+    // ToDo : the management header does not have this optimization level. Hence fix in the management lib
+    // iSettingsManager->SetOptimizationLevel(   );
+
+    // Inform Strategy that the Triggering Engine Settings have changed.
+    // These settings values might affect the behaviour of the supervision algorithm.
+    CLbtStrategyBase* strategy = iStratergyContainer->Stratergy();
+    if ( strategy )
+        {
+        strategy->TriggeringSupervisionSettingsChanged();
+        }
+        
+    //ToDo : we also need to notify clients that the triggering settings has changed.
+    NotifyTriggeringSystemSettingChange(aSettingsMask);   
+    }
+
+void CLbtServerLogic::NotifyTriggeringSystemSettingChange(TLbtManagementSettingsMask aSettingsMask )
+	{
+	FUNC_ENTER("CLbtServerLogic::NotifyTriggeringSystemSettingChange");
+	RArray<RMessage2> messageArray;
+	RMessage2 message;
+	if((aSettingsMask & ETriggeringMechanismState))
+		{
+		while( !iNotificationMap->Retreive(message,ELbtNotifyTriggeringSysSettingChange,
+										CLbtServerLogicBase::TLbtClientLibrary))
+			{
+			messageArray.Append( message );
+			}
+		if(messageArray.Count())
+			{
+			TLbtTriggeringSystemSettings triggeringSystemSettings;
+			if(iSettingsManager->GetTriggeringMechanismState()==1)	
+				{
+				triggeringSystemSettings.SetTriggeringMechanismState(ETriggeringMechanismOn);
+				}
+			else
+				{
+				triggeringSystemSettings.SetTriggeringMechanismState(ETriggeringMechanismOff);
+				}	
+			triggeringSystemSettings.SetMinimumTriggerAreaSize(
+								iSettingsManager->MinimumTriggeringArea());	
+			TPckg<TLbtTriggeringSystemSettings> pckSystemSettings(triggeringSystemSettings);
+			for(TInt i=messageArray.Count();i>0;i--)
+				{
+				LbtGlobal::Write(messageArray[i-1],0,pckSystemSettings);
+				LbtGlobal::RequestComplete(messageArray[i-1],KErrNone);
+				}
+			}
+		}
+	messageArray.Reset();
+	while( !iNotificationMap->Retreive(message,ELbtNotifyTriggeringSysSettingChange,
+									CLbtServerLogicBase::TLbtManagementLibrary))
+		{
+		messageArray.Append( message );
+		}
+	if(messageArray.Count())
+		{
+		TLbtTriggeringSystemManagementSettings triggeringSystemManagementSettings;
+		if(iSettingsManager->GetTriggeringMechanismState()==1)	
+			{
+			triggeringSystemManagementSettings.SetTriggeringMechanismState(ETriggeringMechanismOn);
+			}
+		else
+			{
+			triggeringSystemManagementSettings.SetTriggeringMechanismState(ETriggeringMechanismOff);
+			}	
+		triggeringSystemManagementSettings.SetMinimumTriggerAreaSize(
+							iSettingsManager->MinimumTriggeringArea());	
+		triggeringSystemManagementSettings.SetMinimumLocationUpdateInterval(
+							iSettingsManager->GetMinimumUpdateInterval());	
+		triggeringSystemManagementSettings.SetMinimumLocationUpdateIntervalWhenGpsFails(
+							iSettingsManager->GetMinimumUpdateIntervalOnGpsFailure());
+		triggeringSystemManagementSettings.SetUsedPositioningModule(
+							iSettingsManager->GetModuleId());
+		triggeringSystemManagementSettings.SetMaximumUserSpeed(
+							iSettingsManager->GetMaximumUserSpeed());															
+		TPckg<TLbtTriggeringSystemManagementSettings> pckSystemManagementSettings(
+										triggeringSystemManagementSettings);
+		for(TInt i=messageArray.Count();i>0;i--)
+			{
+			LbtGlobal::Write(messageArray[i-1],0,pckSystemManagementSettings);
+			LbtGlobal::RequestComplete(messageArray[i-1],KErrNone);
+			}
+		}
+	messageArray.Close();	
+	}
+	
+void CLbtServerLogic::NotifyTriggeringSystemStatusChange()
+    {
+    FUNC_ENTER("CLbtServerLogic::NotifyTriggeringSystemStatusChange");
+    RArray<RMessage2> messageArray;
+	RMessage2 message;
+	
+	while( !iNotificationMap->Retreive(message,ELbtNotifyTriggeringSysStatusChange,
+										CLbtServerLogicBase::TLbtClientLibrary))
+			{
+			messageArray.Append( message );
+			}
+	if( messageArray.Count() )		
+	    {
+	    for(TInt i=messageArray.Count();i>0;i--)
+			{
+			LbtGlobal::RequestComplete(messageArray[i-1],KErrNotSupported);
+			}
+	    messageArray.Reset();
+	    }
+	
+	while( !iNotificationMap->Retreive(message,ELbtNotifyTriggeringSysStatusChange,
+										CLbtServerLogicBase::TLbtManagementLibrary))
+			{
+			messageArray.Append( message );
+			}    
+    if( messageArray.Count() )
+        {
+        for(TInt i=messageArray.Count();i>0;i--)
+			{
+			LbtGlobal::RequestComplete(messageArray[i-1],KErrNone);
+			}
+        }
+    messageArray.Close();    
+    }
+
+// ---------------------------------------------------------------------------
+// CLbtServerLogic::HandleTriggersChange
+// ---------------------------------------------------------------------------
+//
+void CLbtServerLogic::HandleTriggersChange( RArray<TLbtTriggerId>& aTriggerIds,
+                                            RArray<TUid>& aManagerUids,
+                                            TLbtTriggerEventMask aEventMask )
+    {
+    FUNC_ENTER("CLbtServerLogic::HandleContainerTriggerChange");
+    RMessage2 message;
+    
+    TLbtTriggerChangeEvent event;
+    // If there is change in the single trigger, set the trigger id else
+    // update KLbtNullTriggerId for trigger id
+    if( aTriggerIds.Count() == 1)
+        {
+        event.iTriggerId = aTriggerIds[0];
+        }
+    else
+        {
+        event.iTriggerId = KLbtNullTriggerId;
+        }
+    
+    // Check for type of notification
+    if( aEventMask & CLbtContainer::ELbtConTriggerDeleted &&
+        aEventMask & CLbtContainer::ELbtConTriggerValidityFieldChanged )
+        {
+        event.iEventType = ELbtTriggerChangeEventMultiple;
+        }
+    else if( aEventMask & CLbtContainer::ELbtConTriggerDeleted )
+        {
+        event.iEventType = ELbtTriggerChangeEventDeleted;
+        }
+    else if ( aEventMask & CLbtContainer::ELbtConTriggerValidityFieldChanged )
+        {
+        event.iEventType = ELbtTriggerChangeEventUpdated;
+        }
+    TPckgBuf<TLbtTriggerChangeEvent> changeEvent(event);
+
+    for( TInt i=0;i<aManagerUids.Count();i++ )
+        {
+        TSecureId secureId(aManagerUids[i]);
+        // Retrieve all client session trigger change notification messages.
+        while(!iNotificationMap->Retreive(message, secureId, ELbtNotifyTriggerChangeEvent) )
+            {
+            if(LbtGlobal::Write(message, KParamChangeEvent, changeEvent) == KErrNone)
+                {
+                LbtGlobal::RequestComplete(message, KErrNone);
+                }
+            }
+        }
+    
+    // Retrieve all management library notification messages
+    while( !iNotificationMap->Retreive( message,ELbtNotifyTriggerChangeEvent,
+                                   CLbtServerLogicBase::TLbtManagementLibrary ) )
+           {
+           if(LbtGlobal::Write(message, KParamChangeEvent, changeEvent) == KErrNone)
+               {
+               LbtGlobal::RequestComplete(message, KErrNone);
+               }
+           }
+    
+    
+    TRAP_IGNORE(LoadOrUnloadStrategyPluginL());
+    }
+// end of file