tcpiputils/dnd/src/hostname.cpp
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2004-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 // hostname.cpp - hostnames of the local node
       
    15 //
       
    16 
       
    17 #include "hostname.h"
       
    18 #include "inet6log.h"
       
    19 
       
    20 #if defined(TCPIP6_USE_COMMDB)
       
    21 #	include <commdb.h>
       
    22 #else
       
    23 #	include <commsdattypesv1_1.h>
       
    24 	using namespace CommsDat;
       
    25 #endif
       
    26 
       
    27 class CLocalHostName : public CBase
       
    28 	/**
       
    29 	* Stores a local hostname.
       
    30 	*
       
    31 	* The hostnames are stored in separate objects and reference counted.
       
    32 	* The same hostname can be mapped to multiple network ids.
       
    33 	*
       
    34 	*/
       
    35 	{
       
    36 	/**
       
    37 	* Constructor.
       
    38 	* Private, only used from CLocalHostName::New method, due to somewhat
       
    39 	* dubious tricks with TLitC class (to store the name).
       
    40 	*/
       
    41 	CLocalHostName(const THostName &aName, CLocalHostName *aNext) : iNext(aNext)
       
    42 		{
       
    43 		// See _LIT and TLitC for this initializer!!!
       
    44 		iName.iTypeLength = aName.Length();
       
    45 		TPtr((TText *)&iName.iBuf[0], aName.Length()).Copy(aName);
       
    46 		}
       
    47 
       
    48 public:
       
    49 	static CLocalHostName *New(const THostName &aName, CLocalHostName *aNext);
       
    50 	CLocalHostName *iNext;	//< Link to the next name.
       
    51 	TInt iRefs;				//< The reference count (value 0 implies already one reference).
       
    52 	TLitC<1> iName;			//< Host name (<1> is *FAKE*!)
       
    53 	//
       
    54 	// This is followed by the actual name characters.
       
    55 	// CHostName class *CANNOT* be subclassed!!!!
       
    56 	};
       
    57 
       
    58 
       
    59 CLocalHostName *CLocalHostName::New(const THostName &aName, CLocalHostName *aNext)
       
    60 	{
       
    61 	// note: TLitC<1> causes extra allocation of sizeof(TInt) [depends on align
       
    62 	// settings]. Could try to adjust the extra requested size down by that amount,
       
    63 	// but it would result more complex code... -- msa
       
    64 	return new (aName.Size()) CLocalHostName(aName, aNext);
       
    65 	}
       
    66 
       
    67 class TLocalHostMap
       
    68 	{
       
    69 public:
       
    70 	TLocalHostMap(TUint32 aId, const CLocalHostName *aName) : iId(aId), iName(aName) {}
       
    71 	const TUint32 iId;
       
    72 	const CLocalHostName *iName;
       
    73 	};
       
    74 
       
    75 THostNames::~THostNames()
       
    76 	{
       
    77 	Cleanup();
       
    78 	}
       
    79 
       
    80 
       
    81 
       
    82 void THostNames::Cleanup()
       
    83 	{
       
    84 	// note: this does not need to worry about reference counts
       
    85 	// in hostnames, because everything is cleaned.
       
    86 	delete iMap;
       
    87 	iMap = NULL;
       
    88 
       
    89 	while (iNameList != NULL)
       
    90 		{
       
    91 		CLocalHostName *e = iNameList;
       
    92 		iNameList = e->iNext;
       
    93 		delete e;
       
    94 		}
       
    95 	}
       
    96 
       
    97 void THostNames::ReferenceRemoved(const CLocalHostName *aName)
       
    98 	{
       
    99 	for (CLocalHostName **h = &iNameList, *p; (p = *h) != NULL; h = &p->iNext)
       
   100 		{
       
   101 		if (p == aName)
       
   102 			{
       
   103 			if (--p->iRefs < 0)
       
   104 				{
       
   105 				*h = p->iNext;
       
   106 				delete p;
       
   107 				}
       
   108 			return;
       
   109 			}
       
   110 		}
       
   111 	}
       
   112 
       
   113 
       
   114 TInt THostNames::Map(TUint32 aId, const TDesC &aName)
       
   115 	{
       
   116 	//
       
   117 	// Locate or create a hostname entry
       
   118 	//
       
   119 	TInt err = KErrNoMemory;
       
   120 
       
   121 	CLocalHostName *name = iNameList;
       
   122 	for (;;name = name->iNext)
       
   123 		{
       
   124 		if (name == NULL)
       
   125 			{
       
   126 			name = CLocalHostName::New(aName, iNameList);
       
   127 			if (name == NULL)
       
   128 				return KErrNoMemory;
       
   129 			iNameList = name;
       
   130 			// The initial iRefs = 0 is ok.
       
   131 			break;
       
   132 			}
       
   133 		else if (aName.Compare(name->iName) == 0)
       
   134 			{
       
   135 			// Additional reference to an existing name.
       
   136 			name->iRefs++;
       
   137 			break;
       
   138 			}
       
   139 		}
       
   140 
       
   141 	if (iMap != NULL || (iMap = new CArrayFixFlat<TLocalHostMap>(4)) != NULL)
       
   142 		{
       
   143 		//
       
   144 		// Remove old mapping, if any
       
   145 		//
       
   146 		for (TInt i = iMap->Count(); i > 0; )
       
   147 			{
       
   148 			TLocalHostMap &m = iMap->At(--i);
       
   149 			if (m.iId == aId)
       
   150 				{
       
   151 				// Id already present, just change the name reference (if changed).
       
   152 				if (m.iName != name)
       
   153 					{
       
   154 					LOG(Log::Printf(_L("\tlocalhost unmapped: <%u, %S(%d)>"), m.iId, &m.iName->iName, m.iName->iRefs));
       
   155 					ReferenceRemoved(m.iName);
       
   156 					m.iName = name;
       
   157 					}
       
   158 				LOG(Log::Printf(_L("\tlocalhost mapped: <%u, %S(%d)>"), m.iId, &m.iName->iName, m.iName->iRefs));
       
   159 				return KErrNone;
       
   160 				}
       
   161 			}
       
   162 		// Id was not recorded before this, create a new entry.
       
   163 		TRAP(err, iMap->AppendL(TLocalHostMap(aId, name)));
       
   164 		if (err == KErrNone)
       
   165 			{
       
   166 			LOG(Log::Printf(_L("\tlocalhost mapped: <%u, %S(%d)>"), aId, &name->iName, name->iRefs));
       
   167 			return KErrNone;
       
   168 			}
       
   169 		}
       
   170 	ReferenceRemoved(name);
       
   171 	return err;
       
   172 	}
       
   173 
       
   174 
       
   175 void THostNames::Unmap(TUint32 aId)
       
   176 	{
       
   177 	//
       
   178 	// Remove old mapping, if any
       
   179 	//
       
   180 	if (iMap)
       
   181 		{
       
   182 		for (TInt i = iMap->Count(); i > 0; )
       
   183 			{
       
   184 			const TLocalHostMap &m = iMap->At(--i);
       
   185 			if (m.iId == aId)
       
   186 				{
       
   187 				LOG(Log::Printf(_L("\tlocalhost unmapped: <%u, %S(%d)>"), m.iId, &m.iName->iName, m.iName->iRefs));
       
   188 				ReferenceRemoved(m.iName);
       
   189 				iMap->Delete(i);
       
   190 				break;	// There can be only one matching id!
       
   191 				}
       
   192 			}
       
   193 		iMap->Compress();
       
   194 		}
       
   195 	}
       
   196 
       
   197 const TDesC &THostNames::Find(TUint32 aId) const
       
   198 	{
       
   199 	if (iMap)
       
   200 		{
       
   201 		for (TInt i = iMap->Count(); i > 0; )
       
   202 			{
       
   203 			const TLocalHostMap &m = iMap->At(--i);
       
   204 			if (m.iId == aId)
       
   205 				return m.iName->iName;
       
   206 			}
       
   207 		}
       
   208 	return KNullDesC;
       
   209 	}
       
   210 
       
   211 TInt THostNames::Reset(const TDesC &aLocalHost)
       
   212 	{
       
   213 	Cleanup();
       
   214 
       
   215 	// Define the return, when network id is not specified.
       
   216 
       
   217 	Map(0, aLocalHost);
       
   218 
       
   219 	// ----------------------------------------------
       
   220 	// Insert here the code to scan the commdb and,
       
   221 	// for each pair <nid, name>, call Map(id, name).
       
   222 	// ----------------------------------------------
       
   223 	TRAPD(err, GetCommDbDataL(0));
       
   224 
       
   225 	return err;
       
   226 	}
       
   227 	
       
   228 TInt THostNames::Refresh(TUint32 aId)
       
   229 	{
       
   230 	TRAPD(err, GetCommDbDataL(aId));
       
   231 	return err;
       
   232 	}
       
   233 
       
   234 
       
   235 void THostNames::GetCommDbDataL(TUint32 aId)
       
   236 	{
       
   237 #if defined(TCPIP6_USE_COMMDB)
       
   238 #	ifdef HOST_NAME
       
   239 	CCommsDatabase* db = CCommsDatabase::NewL();
       
   240 	CleanupStack::PushL(db);
       
   241 
       
   242 	CCommsDbTableView* view = db->OpenTableLC(TPtrC(NETWORK));
       
   243 	for (TInt ret = view->GotoFirstRecord(); ret == KErrNone; ret = view->GotoNextRecord())
       
   244 		{
       
   245 		THostName name;
       
   246 		TUint32 nid = 0;
       
   247 		TRAP(ret,
       
   248 			view->ReadTextL(TPtrC(HOST_NAME), name);
       
   249 			view->ReadUintL(TPtrC(COMMDB_ID), nid));
       
   250 		if (ret == KErrNone)
       
   251 			Map(nid, name);
       
   252 		}
       
   253 	CleanupStack::PopAndDestroy(2);
       
   254 #endif
       
   255 #else
       
   256 	// . (not tested)
       
   257 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   258 	CMDBSession *dB = CMDBSession::NewLC(KCDVersion1_2);
       
   259 #else
       
   260 	CMDBSession *dB = CMDBSession::NewLC(KCDVersion1_1);
       
   261 #endif
       
   262 
       
   263 
       
   264 	// Reveal hidden or private IAP records if a licensee has chosen to protect a record
       
   265 	// using one of these flags - the API to do this is public so internal components
       
   266 	// have to support the use of such records.
       
   267 	dB->SetAttributeMask( ECDHidden | ECDPrivate );
       
   268 
       
   269 	CMDBRecordSet<CCDNetworkRecord> *networkTable;
       
   270 	networkTable = new (ELeave) CMDBRecordSet<CCDNetworkRecord>(KCDTIdNetworkRecord);
       
   271 	CleanupStack::PushL(networkTable);
       
   272 	networkTable->LoadL(*dB);
       
   273 	const TInt totalRecords = networkTable->iRecords.Count();
       
   274 	for (TInt i = 0; i < totalRecords; ++i)
       
   275 		{
       
   276 		const TUint32 nid = (*networkTable)[i]->RecordId();
       
   277 		if (aId == 0 || nid == aId)
       
   278 			Map(nid, (*networkTable)[i]->iHostName);	
       
   279 		}
       
   280 	CleanupStack::PopAndDestroy(2);		
       
   281 #endif
       
   282 	}