locationtriggering/ltcontainer/src/lbtcontainerareafilter.cpp
author hgs
Mon, 23 Aug 2010 17:49:43 +0530
changeset 43 24e118dfbea1
parent 18 3825cf2dc8c2
child 45 6b6920c56e2f
permissions -rw-r--r--
201033

/*
* 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)
		{
		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( iHystRadiusArray.Count()>0)  
                    {
                    isFilterPresent++;
                    isEntryRequested=EFalse;
                    for(i=0;i<iHystRadiusArray.Count();i++)
                	    {
                	    if(contExtInfo->HysteresisRadius()==iHystRadiusArray[i])
                    	    {
                    	    
                            isEntryRequested=ETrue;
                    	    }
                        
                	    }
                    }
                     
                    
                    if((isFilterPresent>0 && isEntryRequested ) || ( isFilterPresent==0 ))  
                        {
                        	if(iTriggerFiredArray.Count()>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();
	}