realtimenetprots/sipfw/ClientResolver/Server/src/CSIPCRRoutingTable.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Name          : CSIPCRRoutingTable.cpp
       
    15 // Part of       : SIP Client Resolver
       
    16 // Version       : 1.0
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDES
       
    22 #include <e32base.h>
       
    23 #include "CSIPCRRoutingTable.h"
       
    24 
       
    25 // -----------------------------------------------------------------------------
       
    26 // CSIPCRRoutingTable::CSIPCRRoutingTable
       
    27 // -----------------------------------------------------------------------------
       
    28 //
       
    29 CSIPCRRoutingTable::CSIPCRRoutingTable()
       
    30     {
       
    31     }
       
    32 
       
    33 // -----------------------------------------------------------------------------
       
    34 // CSIPCRRoutingTable::NewL
       
    35 // -----------------------------------------------------------------------------
       
    36 //
       
    37 CSIPCRRoutingTable* CSIPCRRoutingTable::NewL()
       
    38     {
       
    39     CSIPCRRoutingTable* self = new (ELeave) CSIPCRRoutingTable();
       
    40     CleanupStack::PushL(self);
       
    41     self->ConstructL();
       
    42     CleanupStack::Pop(self);
       
    43     return self;
       
    44     }
       
    45 
       
    46 // -----------------------------------------------------------------------------
       
    47 // CSIPCRRoutingTable::ConstructL
       
    48 // -----------------------------------------------------------------------------
       
    49 //
       
    50 void CSIPCRRoutingTable::ConstructL()
       
    51     {
       
    52     //create the entry object for find operations with dummy id 0
       
    53     iFindEntry = CSIPCRRoutingEntry::NewL(TUid::Uid(0));        
       
    54     }
       
    55 
       
    56 // -----------------------------------------------------------------------------
       
    57 // CSIPCRRoutingTable::~CSIPCRRoutingTable
       
    58 // Destructor
       
    59 // -----------------------------------------------------------------------------
       
    60 //
       
    61 CSIPCRRoutingTable::~CSIPCRRoutingTable()
       
    62     {
       
    63     iTable.ResetAndDestroy();
       
    64     delete iFindEntry;
       
    65     }
       
    66 
       
    67 // -----------------------------------------------------------------------------
       
    68 // CSIPCRRoutingTable::AddL
       
    69 // -----------------------------------------------------------------------------
       
    70 //
       
    71 void CSIPCRRoutingTable::AddL( const TUid& aUid )
       
    72     {    
       
    73     // first check that this top level uid does not exist already,
       
    74     // if it does then we leave with error code KErrAlreadyExists 
       
    75 	if (FindEntryIndex(aUid)!=KErrNotFound) 
       
    76 	    {	    
       
    77 	    User::Leave (KErrAlreadyExists);
       
    78 	    }
       
    79 	    
       
    80 	TUid topLevelUid;
       
    81     if (FindToplevelMatch(aUid,topLevelUid))
       
    82         {
       
    83         // This entry is already in the tree, increase reference count
       
    84 	    TInt topLevelIndex = FindEntryIndex(topLevelUid);
       
    85         CSIPCRRoutingEntry* topLevelEntry = iTable[topLevelIndex];        
       
    86         CSIPCRRoutingEntry* entry = topLevelEntry->FindEntryInTree(aUid);
       
    87         if (entry)
       
    88             {
       
    89             entry->ReferenceCount()++;
       
    90             }
       
    91         }
       
    92     else
       
    93         {
       
    94         // Add a new entry in the top level
       
    95         CSIPCRRoutingEntry* entry = CSIPCRRoutingEntry::NewL(aUid);
       
    96         CleanupStack::PushL(entry);
       
    97         iTable.AppendL(entry);
       
    98         CleanupStack::Pop(entry);
       
    99         }
       
   100     }
       
   101 
       
   102 // -----------------------------------------------------------------------------
       
   103 // CSIPCRRoutingTable::FindEntryIndex
       
   104 // -----------------------------------------------------------------------------
       
   105 //
       
   106 TInt CSIPCRRoutingTable::FindEntryIndex(const TUid& aUid)
       
   107 	{
       
   108 	TIdentityRelation<CSIPCRRoutingEntry> compareId(CSIPCRRoutingEntry::Compare);
       
   109     iFindEntry->SetUID(aUid);
       
   110 	return (iTable.Find(iFindEntry, compareId));
       
   111 	}
       
   112 
       
   113 // -----------------------------------------------------------------------------
       
   114 // CSIPCRRoutingTable::AssociateL
       
   115 // -----------------------------------------------------------------------------
       
   116 //
       
   117 void CSIPCRRoutingTable::AssociateL( const TUid& aUid, const TUid& aAssociatedUid )
       
   118     {
       
   119     TUid associatedUidTop;
       
   120     TUid parentUidTop;
       
   121     TInt index;
       
   122     CSIPCRRoutingEntry* topLevelEntry = NULL;
       
   123     CSIPCRRoutingEntry* associatedEntryObject = NULL;
       
   124     CSIPCRRoutingEntry* uidEntry = NULL;
       
   125     TBool alreadyExists = EFalse;
       
   126     
       
   127     // first check that the parent uid exists..
       
   128     // if it does not then we leave with error code KErrNotFound 
       
   129     if (!FindToplevelMatch(aUid, parentUidTop))
       
   130         {        
       
   131         User::Leave(KErrNotFound);
       
   132         }
       
   133     
       
   134     // first check if the associated uid exists
       
   135     // if it does then we may have to move it under the right entry
       
   136     alreadyExists = FindToplevelMatch(aAssociatedUid, associatedUidTop);        
       
   137     if (alreadyExists)    
       
   138         {
       
   139         CSIPCRRoutingEntry* currentParent = NULL; 
       
   140         
       
   141         // search the top level entry 
       
   142 	    index = FindEntryIndex(associatedUidTop);	
       
   143         topLevelEntry = iTable[index];
       
   144         // get associated uid's current parent entry..
       
   145 
       
   146         currentParent = topLevelEntry->FindParent(aAssociatedUid);
       
   147         
       
   148         // if the current parent entry is the same 
       
   149         // as the one given, then dont do anything..        
       
   150         if (currentParent->UID() == aUid)
       
   151             {
       
   152             return; 
       
   153             }
       
   154         
       
   155         // we need to move the existing associated entry
       
   156         // to the new location, first remove the old
       
   157         associatedEntryObject = currentParent->Detach(aAssociatedUid);
       
   158         CleanupStack::PushL(associatedEntryObject);                
       
   159         }
       
   160         
       
   161     // search the parent top level entry 
       
   162 	index = FindEntryIndex(parentUidTop);	
       
   163     topLevelEntry = iTable[index];        
       
   164                     
       
   165     //now get the uid entry if it is not at the top level
       
   166     if (topLevelEntry->UID() == aUid)
       
   167         {        
       
   168         uidEntry = topLevelEntry;
       
   169         }
       
   170     else
       
   171         {            
       
   172         uidEntry = topLevelEntry->FindEntryInTree(aUid);
       
   173         }
       
   174                     
       
   175     //Finally, add the associated entry
       
   176     if (associatedEntryObject)
       
   177         {
       
   178         // moving the already allocated entry object
       
   179         // to a new location
       
   180         uidEntry->AddL(associatedEntryObject);
       
   181         CleanupStack::Pop(associatedEntryObject);                    
       
   182         }
       
   183     else
       
   184         {                
       
   185         // first time inserting this uid..
       
   186         // no object created yet            
       
   187         uidEntry->AddL(aAssociatedUid);
       
   188         }
       
   189     }
       
   190 
       
   191 // -----------------------------------------------------------------------------
       
   192 // CSIPCRRoutingTable::Remove
       
   193 // -----------------------------------------------------------------------------
       
   194 //
       
   195 TInt CSIPCRRoutingTable::Remove( const TUid& aUid )
       
   196     {
       
   197     TUid topLevelUid(TUid::Null());
       
   198     if (!FindToplevelMatch(aUid, topLevelUid))
       
   199         {
       
   200         return KErrNotFound;
       
   201         }
       
   202 
       
   203 	TInt topLevelIndex = FindEntryIndex(topLevelUid);
       
   204     CSIPCRRoutingEntry* topLevelEntry = iTable[topLevelIndex];    
       
   205     
       
   206     if (topLevelEntry->UID() == aUid)
       
   207         {
       
   208         iTable.Remove(topLevelIndex);
       
   209         delete topLevelEntry;
       
   210         return KErrNone;
       
   211         }
       
   212         
       
   213     CSIPCRRoutingEntry* entry = topLevelEntry->FindEntryInTree(aUid);
       
   214     if (--entry->ReferenceCount() == 0)
       
   215         {
       
   216         CSIPCRRoutingEntry* parent = topLevelEntry->FindParent(aUid);
       
   217         return (parent->Remove(aUid));
       
   218         }
       
   219        
       
   220     return KErrNone;
       
   221     }
       
   222 
       
   223 // -----------------------------------------------------------------------------
       
   224 // CSIPCRRoutingTable::FindMatch
       
   225 // -----------------------------------------------------------------------------
       
   226 //
       
   227 TBool CSIPCRRoutingTable::FindMatch( const TUid& aClientUid, 
       
   228                          const TUid& aParentUid, 
       
   229                          TUid& aNextHopUid )
       
   230     {
       
   231     TUid clientUidTop;       
       
   232     TBool match = EFalse;
       
   233     TBool fContinue = ETrue;            
       
   234     
       
   235     // first check that the leaf uid exists..
       
   236     // if it does not then return false 
       
   237     if (!FindToplevelMatch(aClientUid, clientUidTop))
       
   238         {        
       
   239         return EFalse;
       
   240         }
       
   241         
       
   242     // search the top level entry 
       
   243 	TInt index = FindEntryIndex(clientUidTop);	
       
   244     CSIPCRRoutingEntry* topLevelEntry = iTable[index];
       
   245     
       
   246     CSIPCRRoutingEntry*uidEntry = NULL;
       
   247     TUid uid = aClientUid;
       
   248 
       
   249     while (fContinue)
       
   250         {                        
       
   251         uidEntry = topLevelEntry->FindParent(uid);        
       
   252         if (!uidEntry)
       
   253             {
       
   254             // no match
       
   255             return EFalse;
       
   256             }             
       
   257                        
       
   258         if (uidEntry->UID() == aParentUid)
       
   259             {
       
   260             // match..
       
   261             match = ETrue;
       
   262             aNextHopUid = uid;
       
   263             fContinue = EFalse;
       
   264             }                                    
       
   265         else if (uidEntry->UID() == clientUidTop)
       
   266             {
       
   267             // we are at the top level.. 
       
   268             // no match
       
   269             match = EFalse;
       
   270             fContinue = EFalse;
       
   271             }
       
   272         else
       
   273             {            
       
   274             // no match yet..
       
   275             // continue climbing up
       
   276             uid = uidEntry->UID();
       
   277             }
       
   278         }  
       
   279 
       
   280     return match;
       
   281     }
       
   282     
       
   283 // -----------------------------------------------------------------------------
       
   284 // CSIPCRRoutingTable::HasUid
       
   285 // -----------------------------------------------------------------------------
       
   286 //    
       
   287 TBool CSIPCRRoutingTable::HasUid( const TUid& aClientUid )
       
   288     {
       
   289     TBool found = EFalse;
       
   290     TInt count = iTable.Count();
       
   291     
       
   292     for ( TInt i=0; i < count && !found; i++ )
       
   293         {
       
   294         CSIPCRRoutingEntry* entry = iTable[i];
       
   295         if ( entry->UID() == aClientUid ||
       
   296              entry->HasClient( aClientUid ) )
       
   297             {
       
   298             found = ETrue;
       
   299             }
       
   300         }
       
   301     
       
   302     return found;
       
   303     }                       
       
   304 
       
   305 // -----------------------------------------------------------------------------
       
   306 // CSIPCRRoutingTable::FindToplevelMatch
       
   307 // -----------------------------------------------------------------------------
       
   308 //
       
   309 TBool CSIPCRRoutingTable::FindToplevelMatch( const TUid& aUid, TUid& aTopLevelUid )
       
   310     {                 
       
   311     TInt count = iTable.Count();
       
   312     
       
   313     if (count > 0)
       
   314         {
       
   315         CSIPCRRoutingEntry* entry = NULL;
       
   316         TInt index;
       
   317         for (index = 0; index < count; index++)
       
   318             {
       
   319             entry = iTable[index];
       
   320             
       
   321             // if the requested uid is top level uid itself, return it.. 
       
   322             if (entry->UID() == aUid)
       
   323                 {
       
   324                 aTopLevelUid = entry->UID();
       
   325                 return ETrue;
       
   326                 }
       
   327             
       
   328             // or else check the clients..
       
   329             if (entry->HasClient(aUid))
       
   330                 {
       
   331                 aTopLevelUid = entry->UID();
       
   332                 return ETrue;
       
   333                 }
       
   334             }
       
   335         }
       
   336         
       
   337     return EFalse;       
       
   338     }