locationtriggering/ltcontainer/src/lbtcontainerareafilter.cpp
changeset 0 667063e416a2
child 13 19bff11d6c18
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/locationtriggering/ltcontainer/src/lbtcontainerareafilter.cpp	Tue Feb 02 01:06:48 2010 +0200
@@ -0,0 +1,542 @@
+/*
+* Copyright (c) 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: Implementation of container area filter class
+*
+*/
+
+
+#include <s32strm.h>
+#include <lbttriggerfilterbyarea.h>
+#include <lbtgeoareabase.h>
+#include <lbttriggerconditionarea.h>
+#include <lbtgeocircle.h>
+#include <lbtgeorect.h>
+#include <lbtgeocell.h>
+#include <lbtgeohybrid.h>
+#include "lbtcontainerfilterbase.h"
+#include "lbtcontainertriggerfilter.h"
+#include "lbtcontainerareafilter.h"
+#include "lbtlogger.h"
+
+
+
+
+// ======== LOCAL FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CLbtContainerAttrFilter::NewL()
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+CLbtContainerAreaFilter* CLbtContainerAreaFilter::NewL(CLbtTriggerFilterBase* aTrigFilter,CLbtContainerFilter* aContFilter)
+    {
+    FUNC_ENTER("CLbtContainerAreaFilter::NewL");
+  	CLbtContainerAreaFilter* self = new( ELeave ) CLbtContainerAreaFilter;
+    CleanupStack::PushL( self );
+    self->ConstructL(aTrigFilter,aContFilter);
+	CleanupStack::Pop( self );    
+    return self;
+    }
+
+void CLbtContainerAreaFilter::ProcessFilter(CLbtContainerTriggerEntry* aEntry,TInt& aIsFilterPresent,TBool& aIsEntryRequested  )
+	{
+	FUNC_ENTER("CLbtContainerAreaFilter::ProcessFilter");
+	ProcessContFilter( aEntry,aIsFilterPresent, aIsEntryRequested);
+	
+	if((aIsFilterPresent>0 && aIsEntryRequested)||(aIsFilterPresent == 0))
+		{
+		CLbtGeoAreaBase::TGeoAreaType type = iArea->Type();
+		switch( type )
+		    {
+		    case CLbtGeoAreaBase::ECircle:
+		        {
+		        ProcessCircleFilter(aEntry,aIsFilterPresent,aIsEntryRequested);
+		        }
+		        break;
+          case CLbtGeoAreaBase::ERectangular:
+                {
+                ProcessRectFilter(aEntry,aIsFilterPresent,aIsEntryRequested);       
+                }
+                break;
+          case CLbtGeoAreaBase::ECellular:
+               {
+               ProcessCellFilter(aEntry,aIsFilterPresent,aIsEntryRequested);
+               }
+               break;
+          case CLbtGeoAreaBase::EHybrid:
+               {
+               ProcessHybridFilter(aEntry,aIsFilterPresent,aIsEntryRequested);
+               }
+               break;
+          default:
+              {
+              break;
+              }
+		    }
+		}
+	}
+	
+void CLbtContainerAreaFilter::ProcessCellFilter(CLbtContainerTriggerEntry* aEntry,TInt& aIsFilterPresent,TBool& aIsEntryRequested  )
+	{
+	FUNC_ENTER("CLbtContainerAreaFilter::ProcessCellFilter");
+	
+	CLbtGeoCell* cellArea=static_cast<CLbtGeoCell*>(iArea);
+        
+    // If the filter does not have a valid network mode then return ETrue
+    //case only for simcard change from server
+    //from client side, it is restricted
+    if(cellArea->NetworkType() == RMobilePhone::ENetworkModeUnknown)
+        {
+        aIsFilterPresent++;
+        aIsEntryRequested = ETrue;
+        return;
+        }
+    
+	if(aEntry!=NULL)
+	    {	    
+	    CLbtTriggerEntry* trigEntry=aEntry->TriggerEntry();
+	    if(!trigEntry)
+	    	{
+	    	aIsFilterPresent = 0;
+	    	return;
+	    	}
+	    CLbtTriggerConditionBase* condBase=trigEntry->GetCondition();
+	    if(!condBase)
+	    	{
+	    	aIsFilterPresent = 0;
+	    	return;
+	    	}
+	    	
+	    CLbtTriggerConditionArea* trigCond = static_cast<CLbtTriggerConditionArea*> (condBase);
+	    
+	    
+	    CLbtGeoAreaBase::TGeoAreaType trigAreaType =  trigCond->TriggerArea()->Type();
+	    
+	    //if other than cell/hybrid
+	    if( trigAreaType != CLbtGeoAreaBase::ECellular && trigAreaType != CLbtGeoAreaBase::EHybrid )
+	    	{
+	    	// The area type is not the same. 
+	    	aIsFilterPresent++;
+			aIsEntryRequested = EFalse;
+			return;
+	    	}	    	
+	    
+	    //if cell
+	    if( trigAreaType == CLbtGeoAreaBase::ECellular )
+	        { 
+	        CLbtGeoCell* trigArea=static_cast<CLbtGeoCell*>(trigCond->TriggerArea());
+            CompareCells( trigArea,cellArea, aIsFilterPresent, aIsEntryRequested );
+            return;
+	        }
+	    //hybrid
+	    CLbtGeoHybrid* hybridArea=static_cast<CLbtGeoHybrid*>(trigCond->TriggerArea());
+	    const RPointerArray<CLbtGeoAreaBase>& trigAreaArray = hybridArea->HybridArea();
+        TInt cnt = trigAreaArray.Count();
+        TInt index;
+        CLbtGeoCell* trigArea = NULL;
+        for(index=0;index<cnt;index++)
+            {
+            //Current support is only for cellular hybrid triggers
+            if( trigAreaArray[index]->Type() != CLbtGeoAreaBase::ECellular )
+                {
+                continue;
+                }
+            trigArea = static_cast<CLbtGeoCell*> (trigAreaArray[index]);
+            CompareCells( trigArea,cellArea, aIsFilterPresent, aIsEntryRequested );
+            //if atleast one cell matches, return, else goto next value
+            if( aIsEntryRequested ) return;
+            }
+	    }// end of if(aEntry!=NULL)
+	}
+
+void CLbtContainerAreaFilter::ProcessHybridFilter(CLbtContainerTriggerEntry* aEntry,TInt& aIsFilterPresent,TBool& aIsEntryRequested  )
+    {
+    FUNC_ENTER("CLbtContainerAreaFilter::ProcessHybridFilter");
+    if(aEntry!=NULL)
+        {       
+        CLbtTriggerEntry* trigEntry=aEntry->TriggerEntry();
+        if(!trigEntry)
+           {
+           aIsFilterPresent = 0;
+           return;
+           }
+        CLbtTriggerConditionBase* condBase=trigEntry->GetCondition();
+        if(!condBase)
+           {
+           aIsFilterPresent = 0;
+           return;
+           }
+           
+        CLbtTriggerConditionArea* trigCond = static_cast<CLbtTriggerConditionArea*> (condBase);
+       
+       
+        CLbtGeoAreaBase::TGeoAreaType trigAreaType =  trigCond->TriggerArea()->Type();
+       
+        //if other than cell/hybrid
+        if( trigAreaType != CLbtGeoAreaBase::ECellular && trigAreaType != CLbtGeoAreaBase::EHybrid )
+           {
+           // The area type is not the same. 
+           aIsFilterPresent++;
+           aIsEntryRequested = EFalse;
+           return;
+           }
+       
+        //start filtering
+        CLbtGeoHybrid* hybridArea = static_cast<CLbtGeoHybrid*>(iArea);
+        const RPointerArray<CLbtGeoAreaBase>& hybridAreaArray = hybridArea->HybridArea();
+        TInt cnt = hybridAreaArray.Count();
+        TInt index;
+        CLbtGeoCell* hybridCellArea = NULL;
+        CLbtGeoCell* trigCellArea = NULL;
+        for(index=0;index<cnt;index++)
+            {      
+            //Current support is only for cellular hybrid triggers -check for dest
+            if( hybridAreaArray[index]->Type() != CLbtGeoAreaBase::ECellular )
+                {
+                continue;
+                }    
+            hybridCellArea = static_cast<CLbtGeoCell*> (hybridAreaArray[index]);
+            
+            if( trigAreaType == CLbtGeoAreaBase::ECellular ) //source
+                {   
+                trigCellArea=static_cast<CLbtGeoCell*>(trigCond->TriggerArea());                
+                CompareCells( trigCellArea,hybridCellArea, aIsFilterPresent, aIsEntryRequested );
+                if(  aIsFilterPresent > 0 && aIsEntryRequested  ) return;
+                }
+            else
+                {
+                CLbtGeoHybrid* trigHybridArea=static_cast<CLbtGeoHybrid*>(trigCond->TriggerArea());
+                const RPointerArray<CLbtGeoAreaBase>& trigHybridAreaArray = trigHybridArea->HybridArea();
+                TInt count = trigHybridAreaArray.Count();
+                TInt indexTrig;                
+                for(indexTrig=0;indexTrig<count;indexTrig++)
+                    {
+                    //Current support is only for cellular hybrid triggers -check for source
+                   if( trigHybridAreaArray[indexTrig]->Type() != CLbtGeoAreaBase::ECellular )
+                       {
+                       continue;
+                       }                   
+                   trigCellArea = static_cast<CLbtGeoCell*> (trigHybridAreaArray[indexTrig]);
+                   CompareCells( trigCellArea, hybridCellArea, aIsFilterPresent, aIsEntryRequested );
+                   //if atleast one cell matches, return, else goto next value
+                   if( aIsFilterPresent > 0 && aIsEntryRequested ) 
+                       {
+                       return;
+                       }
+                    } //inner for
+                }//else  trigAreaType == CLbtGeoAreaBase::ECellular
+            }   //outer for     
+        }// end of if(aEntry!=NULL)
+    }
+    
+void CLbtContainerAreaFilter::ProcessCircleFilter(CLbtContainerTriggerEntry* aEntry,TInt& aIsFilterPresent,TBool& aIsEntryRequested  )
+	{
+	FUNC_ENTER("CLbtContainerAreaFilter::ProcessCircleFilter");
+	// Add cicular filtering here.	
+	if(aEntry!=NULL)
+	    {	    
+	    CLbtTriggerEntry* trigEntry=aEntry->TriggerEntry();
+        if(!trigEntry)
+        	{
+        	//CHECK HOW TO HANDLE THIS SCENARIO
+        	aIsFilterPresent = 0;
+        	return;
+        	}
+
+        CLbtTriggerConditionBase* condBase=trigEntry->GetCondition();
+        if(!condBase)
+        	{
+        	//CHECK HOW TO HANDLE THIS SCENARIO
+        	aIsFilterPresent = 0;
+        	return;
+        	}
+
+        CLbtTriggerConditionArea* trigCond=(CLbtTriggerConditionArea*)condBase;
+        CLbtGeoCircle* trigArea=static_cast<CLbtGeoCircle*>(trigCond->TriggerArea());
+        if( trigArea->Type() != CLbtGeoAreaBase::ECircle )
+	    	{
+	    	// The area type is not the same. 
+	    	aIsFilterPresent++;
+			aIsEntryRequested = EFalse;
+			return;
+	    	}	    	
+        
+    	CLbtGeoCircle* circArea=static_cast<CLbtGeoCircle*>(iArea);
+    	TCoordinate filterCenter=circArea->Center();
+    	TCoordinate trigCenter=trigArea->Center();
+    	TReal filterRadius=circArea->Radius();
+        TReal trigRadius=trigArea->Radius();
+    	TReal32 distance;
+    	filterCenter.Distance(trigCenter,distance);
+    	
+    	/* If the distance between the trigger center and the filter center
+    	 * is less than the radius of the filter circle
+    	 * and if this distance + the radius of the trigger
+    	 * is less than the radius of the filter 
+    	 * then the given trigger lies within the specified area
+    	 * and will be returned back to the client
+    	 */
+    	if((distance<filterRadius) && ((distance+trigRadius)<=filterRadius))
+    	    {
+    	    aIsFilterPresent++ ;
+    	    aIsEntryRequested = ETrue;
+    	    }
+    	else
+    		{
+    		aIsEntryRequested = EFalse;
+    		}
+	    }
+	}
+	
+void CLbtContainerAreaFilter::ProcessRectFilter(CLbtContainerTriggerEntry* aEntry,TInt& aIsFilterPresent,TBool& aIsEntryRequested  )
+	{
+	FUNC_ENTER("CLbtContainerAreaFilter::ProcessRectFilter");
+	// Add rectangular filtering here.
+	if(aEntry != NULL)
+		{
+		CLbtTriggerEntry* trigEntry=aEntry->TriggerEntry();
+    	CLbtGeoRect* rectArea=static_cast<CLbtGeoRect*>(iArea);
+    	TReal northLat,southLat,eastLong,westLong;
+    	rectArea->GetBorder(southLat,northLat,westLong,eastLong);
+    	CLbtExtendedTriggerInfo* contExtInfo = aEntry->ExtendedTriggerInfo();
+    	CLbtExtendedTriggerInfo::TLbtTriggerRectArea trigArea=contExtInfo->TriggerReactangleArea();
+    	if( trigArea.iTrigAreaNorthLat <= northLat && trigArea.iTrigAreaSouthLat >= southLat &&
+    	    trigArea.iTrigAreaEastLong <= eastLong && trigArea.iTrigAreaWestLong >= westLong )
+    		{
+    		aIsFilterPresent++;
+    		aIsEntryRequested = ETrue;
+    		}	
+		}
+		
+	}	
+	
+void CLbtContainerAreaFilter::ProcessContFilter(CLbtContainerTriggerEntry* aEntry,TInt& aIsFilterPresent,TBool& aIsEntryRequested  )
+	{
+	FUNC_ENTER("CLbtContainerAreaFilter::ProcessContFilter");
+	CLbtExtendedTriggerInfo* contExtInfo=aEntry->ExtendedTriggerInfo(); 
+	TInt isFilterPresent = 0;
+	TBool isEntryRequested = EFalse;
+	TInt i;
+	if(contExtInfo!=NULL)
+             	{
+                 if((isFilterPresent>0 && isEntryRequested && iHystRadiusArray.Count()>0) || (iHystRadiusArray.Count()>0 && isFilterPresent==0 ))  
+                    {
+                    isFilterPresent++;
+                    isEntryRequested=EFalse;
+                    for(i=0;i<iHystRadiusArray.Count();i++)
+                	    {
+                	    if(contExtInfo->HysteresisRadius()==iHystRadiusArray[i])
+                    	    {
+                    	    
+                            isEntryRequested=ETrue;
+                    	    }
+                        
+                	    }
+                    }
+                     
+                    
+                    if((isFilterPresent>0 && isEntryRequested && iTriggerFiredArray.Count()>0) || (iTriggerFiredArray.Count()>0 && isFilterPresent==0 ))  
+                        {
+                        isFilterPresent++;
+                        isEntryRequested=EFalse;
+                        for(i=0;i<iTriggerFiredArray.Count();i++)
+                    	    {
+                    	    if(contExtInfo->IsTriggerFired()==iTriggerFiredArray[i])
+                    		    {
+                                isEntryRequested=ETrue;
+                        
+                    		    }
+                   		    }
+                        }
+                        
+                     if((isFilterPresent>0 && isEntryRequested && iSidArray.Count()>0) || (iSidArray.Count()>0 && isFilterPresent==0 ))  
+                        {
+                        isFilterPresent++;
+                        isEntryRequested=EFalse;
+                        for(i=0;i<iSidArray.Count();i++)
+                    	    {
+                    	    if(contExtInfo->OwnerSid()==iSidArray[i])
+                        	    {
+                        	    
+                                isEntryRequested=ETrue;
+                        	    }
+                            
+                    	    }
+                         }     
+                    
+                     if((isFilterPresent>0 && isEntryRequested && iTriggerFireOnCreationArray.Count()>0) || (iTriggerFireOnCreationArray.Count()>0 && isFilterPresent==0 ))  
+                        {
+                        isFilterPresent++;
+                        isEntryRequested=EFalse;
+                        for(i=0;i<iTriggerFireOnCreationArray.Count();i++)
+                    	    {
+                    	    if(contExtInfo->IsTriggerFireOnCreation()==iTriggerFireOnCreationArray[i])
+                        	    {
+                        	    
+                                isEntryRequested=ETrue;
+                        	    }
+                            
+                    	    }
+                        }  
+                    
+                    
+                    }
+                     
+                    // end of if(contExtInfo!=NULL)
+       aIsFilterPresent = isFilterPresent;
+       aIsEntryRequested = isEntryRequested;
+	}
+void CLbtContainerAreaFilter::RetrieveFilterDataL()
+	{
+	FUNC_ENTER("CLbtContainerAreaFilter::RetrieveFilterDataL");
+	CLbtContainerFilter* contFilter = ContFilter();
+	CLbtTriggerFilterBase* trigFilter = TrigFilter();
+	CLbtTriggerFilterByArea* areaFilter = static_cast<CLbtTriggerFilterByArea*>(trigFilter);
+    iArea = areaFilter->Area();
+	
+	if(contFilter)
+       {
+        contFilter->GetSidArrayL(&iSidArray) ;
+        contFilter->GetHystRadiusArrayL(&iHystRadiusArray); 
+        contFilter->GetRectAreaArrayL(&iTriggerRectAreaArray) ;
+        contFilter->GetTriggerFiredArrayL(&iTriggerFiredArray) ;
+        contFilter->GetTriggerFireOnCreationArrayL( &iTriggerFireOnCreationArray );
+        }
+       
+	}
+
+void CLbtContainerAreaFilter::CompareCells( CLbtGeoCell* aCellToBeMatched,  CLbtGeoCell* aCellFilter, TInt& aIsFilterPresent,TBool& aIsEntryRequested )
+    { 
+    if(aCellToBeMatched->NetworkType() != aCellFilter->NetworkType())
+        {
+        aIsFilterPresent++;
+        aIsEntryRequested = EFalse;
+        return ;
+        }
+    else
+        {
+        aIsFilterPresent++;
+        TLex lex( aCellFilter->NetworkCountryCode() );
+        TUint netCountryCode;
+        lex.Val( netCountryCode );
+        
+        TLex lexTrig( aCellToBeMatched->NetworkCountryCode() );
+        TUint trigNetCountryCode;
+        lexTrig.Val( trigNetCountryCode );
+        
+        if(netCountryCode == 0 )
+            {
+            aIsEntryRequested=ETrue;
+            return;
+            }
+        else
+            {
+            if(netCountryCode != trigNetCountryCode)                
+                {
+                aIsFilterPresent++;
+                aIsEntryRequested = EFalse;
+                return;
+                }
+                
+            if(netCountryCode == trigNetCountryCode)
+                {
+                aIsEntryRequested = ETrue;
+                aIsFilterPresent++;
+                TLex idcode( aCellFilter->NetworkIdentityCode() );
+                TUint netIdCode;
+                idcode.Val( netIdCode );
+                
+                TLex trigIdcode( aCellToBeMatched->NetworkIdentityCode() );
+                TUint trigNetIdCode;
+                trigIdcode.Val( trigNetIdCode );    
+                if(netIdCode == 0 )    
+                    {
+                    aIsEntryRequested = ETrue;
+                    return;
+                    }
+                else
+                    {
+                    if(netIdCode != trigNetIdCode)
+                        {
+                        aIsFilterPresent++;
+                        aIsEntryRequested = EFalse;
+                        return;
+                        }
+                    if(netIdCode == trigNetIdCode)  
+                        {   
+                        aIsFilterPresent++;
+                        aIsEntryRequested = EFalse;
+                        if(aCellFilter->LocationAreaCode() == 0)   
+                            {
+                            aIsEntryRequested = ETrue;
+                            return;
+                            }
+                        else
+                            {
+                            if(aCellFilter->LocationAreaCode() != aCellToBeMatched->LocationAreaCode())
+                                {
+                                aIsFilterPresent++;
+                                aIsEntryRequested = EFalse;
+                                return;
+                                }   
+                            if(aCellFilter->LocationAreaCode() == aCellToBeMatched->LocationAreaCode())
+                                {
+                                aIsFilterPresent++;
+                                aIsEntryRequested = ETrue;
+                                if(aCellFilter->CellId() == 0)
+                                    {
+                                    aIsEntryRequested = ETrue;
+                                    return ;
+                                    }
+                                else if(aCellFilter->CellId() != aCellToBeMatched->CellId())
+                                    {
+                                    aIsFilterPresent++;
+                                    aIsEntryRequested = EFalse;
+                                    return ;
+                                    }                                 
+                                }// if(cellArea->LocationAreaCode() == trigArea->LocationAreaCode())    
+                            } // end of else if(cellArea->LocationAreaCode() == 0)                       
+                        }// end of if(netIdCode == trigNetIdCode)                       
+                    }// end of else     if(netIdCode == 0 )                 
+                } //end of  if(netCountryCode == trigNetCountryCode)    
+            }// end of else after if(netCountryCode == 0 )
+        }// end of if(trigArea->NetworkType() == cellArea->NetworkType())
+    }
+
+CLbtContainerAreaFilter::CLbtContainerAreaFilter()
+	{
+	
+	}
+
+
+CLbtContainerAreaFilter::~CLbtContainerAreaFilter()
+	{
+	FUNC_ENTER("CLbtContainerAreaFilter::~CLbtContainerAreaFilter");
+	iHystRadiusArray.Close();
+	iTriggerRectAreaArray.Close();
+	iTriggerFiredArray.Close();
+	iSidArray.Close();
+	iTriggerFireOnCreationArray.Close();
+	
+	}
+ 
+void CLbtContainerAreaFilter::ConstructL(CLbtTriggerFilterBase* aTrigFilter,CLbtContainerFilter* aContFilter)
+	{
+	FUNC_ENTER("CLbtContainerAreaFilter::ConstructL");
+	SetTrigFilter(aTrigFilter);
+	SetContFilter(aContFilter);
+	RetrieveFilterDataL();
+	}
+