diff -r 78fbd574edf4 -r da856f45b798 zeroconf/cachemanager/src/cmdnscachemanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zeroconf/cachemanager/src/cmdnscachemanager.cpp Thu Jun 24 19:09:47 2010 +0530 @@ -0,0 +1,413 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include "cmdnscachemanager.h" +#include "cserviceinfo.h" +#include "ccacheentry.h" +#include "dnsconstants.h" + +using namespace HashInfo; + +EXPORT_C CMDNSCacheManager* CMDNSCacheManager::NewL(TUint aMaxCacheEntries) + { + CMDNSCacheManager* self = CMDNSCacheManager::NewLC(aMaxCacheEntries); + CleanupStack::Pop(self); + return self; + } + +EXPORT_C CMDNSCacheManager* CMDNSCacheManager::NewLC(TUint aMaxCacheEntries) + { + CMDNSCacheManager* self = new (ELeave)CMDNSCacheManager(); + CleanupStack::PushL(self); + self->ConstructL(aMaxCacheEntries); + return self; + } + +EXPORT_C CMDNSCacheManager* CMDNSCacheManager::NewL() + { + CMDNSCacheManager* self = new (ELeave)CMDNSCacheManager(); + return self; + } + +void CMDNSCacheManager::ConstructL(TUint aMaxCacheEntries) + { + iHashMap=CMDNSCacheMap::NewL(aMaxCacheEntries); + } + +CMDNSCacheManager::CMDNSCacheManager() + { + + } + +CMDNSCacheManager::~CMDNSCacheManager() + { + delete iHashMap; + iAuthoritativeEntries.ResetAndDestroy(); + iAuthoritativeEntries.Close(); + } + +/*Method to Insert / Update entries into Cache + * @param aEntry Record Entry to Insert + * @param aAuthoritative Flag to indicate whether the entry is Authoritative + * @param aSessionId To Store the Session Id for each entry + * @leave KErrNoMemory If Insert into Cache Failed because memory unavailability + * @leave KErrNotSupported if any record other than SRV, PTR, TXT ot A come + */ +EXPORT_C void CMDNSCacheManager::UpdateCacheL(CDnsResourceData& aEntry,TBool aAuthoritative,TUint32 aSessionId) + { + CDnsResourceData* resourceRecord = NULL; + CServiceInfo* foundEntry = NULL; + TBuf8<255> name; + _LIT8(KDot,"."); + //Clone the entry to Insert in Cache + resourceRecord = aEntry.CloneL(); + + TUint16 recType(resourceRecord->Type()); + + if(recType == EDnsType_SRV || recType == EDnsType_TXT || recType == EDnsType_A || recType == EDnsType_PTR) + { + if(recType == EDnsType_PTR) + { + //Extract the Key- Service Instance Name + CRdTypePtr* ptrRecord = static_cast (resourceRecord); + // before that insert the dot. + name.Copy(ptrRecord->DomainName()); + if(name[name.Size()-1]!='.') + name.Append(KDot); + ptrRecord->SetDomainNameL(name); + foundEntry = iHashMap->Find(ptrRecord->DomainName()); + } + else + { + //Extract the Key- Service Instance Name or Host Name + foundEntry = iHashMap->Find(resourceRecord->Name()); + } + + if(foundEntry) + { + //Update if the entry is already present in the Cache. + UpdateCacheEntry(foundEntry,resourceRecord); + } + else + { + //Entry not found in Cache,Insert it fresh + CServiceInfo* recordInfo = NULL; + recordInfo = CServiceInfo::NewL(); + switch(recType) + { + case EDnsType_SRV: + CRdTypeSrv* srvRecord = static_cast (resourceRecord); + recordInfo->SetServiceRecord(srvRecord); + break; + + case EDnsType_TXT: + CRdTypeTxt* txtRecord = static_cast (resourceRecord); + recordInfo->SetTxtRecord(txtRecord); + break; + + case EDnsType_PTR: + CRdTypePtr* ptrRecord = static_cast (resourceRecord); + recordInfo->SetPtrRecord(ptrRecord); + break; + + case EDnsType_A: + CRdTypeA* addressRecord = static_cast (resourceRecord); + recordInfo->SetAddressRecord(addressRecord); + break; + + + default: + User::Leave(KErrNotSupported); + break; + } + + recordInfo->SetAuthoritative(aAuthoritative); + recordInfo->SetSessionId(aSessionId); + + + // insert the entry + if(recType == EDnsType_PTR ) + { + CRdTypePtr* ptrRecord = static_cast (resourceRecord); + iHashMap->UpdateL(ptrRecord->DomainName(),recordInfo); + } + else + { + iHashMap->UpdateL(resourceRecord->Name(),recordInfo); + } + + /*Maintain a list of all Services Published by us + (Authoritative records)*/ + if(recordInfo->IsAuthoritative()) + { + iAuthoritativeEntries.Append(recordInfo->CloneL()); + } + } + + } + else + { + User::Leave(KErrNotSupported); + } + + } + + + + +/*Caters to finding varying types of records, for e.g:- find all the entries + that correspond to a particular service type or find the host name through the address record + @param aEntries List of entries that match the search constraint + @param aName could represent any search constraint Service Instance Type/ Name or the HostName + @param aType the desired record type + */ +EXPORT_C TInt CMDNSCacheManager::FindServiceL(RPointerArray & aEntries,const TDesC8& aName,TDnsType aType)const + { + TInt error(KErrNotFound); + TPtrC8 keyToFind(aName); + TInt count; + switch(aType) + { + case EDnsType_A: + case EDnsType_SRV: + case EDnsType_TXT: + { + //Search for a specific CacheEntry + CServiceInfo* cacheEntry = iHashMap->Find(aName); + if(cacheEntry) + { + CCacheEntry* entry = CCacheEntry::NewL(); + CacheEntryL(entry,cacheEntry); + aEntries.Append(entry); + error = KErrNone; + } + } + break; + + + case EDnsType_PTR: + //Match for all Cache Entries of the given Service Type + RPointerArray entries; + CleanupClosePushL(entries); + iHashMap->FindEntries(aName,entries); + + for(count =0; count< entries.Count();count++) + { + if((*entries[count]).PtrRecord()) + { + //The entries are considered only if they have PTR records + CCacheEntry* entry = CCacheEntry::NewL(); + CacheEntryL(entry,entries[count]); + aEntries.Append(entry); + error = KErrNone; + } + } + + CleanupStack::PopAndDestroy(&entries); + break; + + + case EDnsQType_Any: + { + //Search for a specific CacheEntry + CServiceInfo* cacheEntry = iHashMap->Find(aName); + if(cacheEntry) + { + CCacheEntry* entry = CCacheEntry::NewL(); + CacheEntryL(entry,cacheEntry); + aEntries.Append(entry); + error = KErrNone; + } + else // may be its a PTR record + { + RPointerArray entries; + CleanupClosePushL(entries); + iHashMap->FindEntries(aName,entries); + + for(count =0; count< entries.Count();count++) + { + if((*entries[count]).PtrRecord()) + { + //The entries are considered only if they have PTR records + CCacheEntry* entry = CCacheEntry::NewL(); + CacheEntryL(entry,entries[count]); + aEntries.Append(entry); + error = KErrNone; + } + } + + CleanupStack::PopAndDestroy(&entries); + } + } + + break; + + default: + User::Leave(KErrNotSupported); + break; + } + return error; + } + +/*Deletes the specified entry from the Cache + @param aServiceInstanceName Instance Name , whose entry needs to be deleted + @leave KErrNotFound if specified entry is not found + */ +EXPORT_C TInt CMDNSCacheManager::DeleteEntryL(const TDesC8& aServiceInstanceName) + { + TInt err = iHashMap->DeleteL(aServiceInstanceName); + + // check if it also on the authoritative list, if so delete it + + for(TInt i=0; iKey().Compare(aServiceInstanceName)==0) + { + // found the entry, now delete it; + CServiceInfo* info = iAuthoritativeEntries[i]; + iAuthoritativeEntries.Remove(i); + delete info; + } + } + return err; + } + + +EXPORT_C void CMDNSCacheManager::FlushCache() + { + iHashMap->DeleteAllEntries(); + } + +EXPORT_C CCacheEntry* CMDNSCacheManager::NextStaleEntry(TBool aActiveCacheMgmtEnabled,TBool aIteratorReset) + { + CServiceInfo* nextEntry = iHashMap->NextStaleEntry(aActiveCacheMgmtEnabled,aIteratorReset); + CCacheEntry* nextCacheEntry = NULL; + + if(nextEntry) + { + + nextCacheEntry = CCacheEntry::NewL(); + //Construct CCacheEntry object + CacheEntryL(nextCacheEntry,nextEntry); + + //Mark whether the entry has to be deleted or to be queried for (i.e., has exceeded 80%) + nextCacheEntry->SetEntryExpired(nextEntry->StaleEntry()); + } + + return nextCacheEntry; + } + +void CMDNSCacheManager::UpdateCacheEntry(CServiceInfo* aEntry,CDnsResourceData* aRecordInfo) + { + TUint16 recType(aRecordInfo->Type()); + switch(recType) + { + case EDnsType_SRV: + CRdTypeSrv* srvRecord = static_cast (aRecordInfo); + //Delete the previous Service Record and Insert the fresh one + delete aEntry->ServiceRecord(); + aEntry->SetServiceRecord(srvRecord); + break; + + case EDnsType_TXT: + CRdTypeTxt* txtRecord = static_cast (aRecordInfo); + //Delete the previous Text Record and Insert the fresh one + delete aEntry->TxtRecord(); + aEntry->SetTxtRecord(txtRecord); + break; + + case EDnsType_PTR: + CRdTypePtr* ptrRecord = static_cast (aRecordInfo); + //Delete the previous Ptr Record and Insert the fresh one + delete aEntry->PtrRecord(); + aEntry->SetPtrRecord(ptrRecord); + break; + + case EDnsType_A: + CRdTypeA* addressRecord = static_cast (aRecordInfo); + //Delete the previous Address Record and Insert the fresh one + delete aEntry->AddressRecord(); + aEntry->SetAddressRecord(addressRecord); + break; + + default: + //Do nothing + break; + } + } + +EXPORT_C void CMDNSCacheManager::DumpCacheL() + { + iHashMap->DumpCacheL(); + } + +EXPORT_C TUint32 CMDNSCacheManager::CacheEntryCount() + { + return iHashMap->NumberOfEntries(); + } + + +void CMDNSCacheManager::CacheEntryL(CCacheEntry* aTargetEntry,const CServiceInfo* aSourceEntry)const + { + //Check whether the specific records existed before making a copy + if(aSourceEntry->PtrRecord()) + { + aTargetEntry->SetPtrRecord(static_cast ( aSourceEntry->PtrRecord()->CloneL())); + } + + if(aSourceEntry->AddressRecord()) + { + //This case occurs only for an idividual Address Record + aTargetEntry->SetAddressRecord(static_cast (aSourceEntry->AddressRecord()->CloneL())); + } + + if(aSourceEntry->ServiceRecord()) + { + aTargetEntry->SetServiceRecord(static_cast (aSourceEntry->ServiceRecord()->CloneL())); + //Set Address Record ; if it exists + CServiceInfo* entry = iHashMap->Find(aTargetEntry->ServiceRecord()->Target()); + if(entry) + { + aTargetEntry->SetAddressRecord(static_cast (entry->AddressRecord()->CloneL())); + } + } + + if(aSourceEntry->TxtRecord()) + { + aTargetEntry->SetTxtRecord(static_cast (aSourceEntry->TxtRecord()->CloneL())); + } + + aTargetEntry->SetAuthoritative(aSourceEntry->IsAuthoritative()); + aTargetEntry->SetSessionId(aSourceEntry->SessionId()); + } + + +void CMDNSCacheManager::AuthoritativeEntriesL(RPointerArray & aCacheEntries) + { + for(TInt index =0; index < iAuthoritativeEntries.Count();index++) + { + CCacheEntry* entry = CCacheEntry::NewL(); + CacheEntryL(entry,iAuthoritativeEntries[index]); + aCacheEntries.Append(entry); + } + } + +TUint CMDNSCacheManager::NumberOfEntries() + { + return iHashMap->NumberOfEntries(); + }