esockapiextensions/internetsockets/src/eui_addr.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 // eui_addr.cpp - EUI-xx address structure
       
    15 //
       
    16 
       
    17 #include "eui_addr.h"	// This
       
    18 #include <e32std.h>		// Mem::*, User::*, TTime
       
    19 #include <e32math.h>	// Math::*
       
    20 
       
    21 static void EuiPanic(TEuiPanic aReason);
       
    22 static void EuiPanic(TEuiPanic aReason)
       
    23 {
       
    24 	User::Panic(_L("EUI"), aReason);
       
    25 }
       
    26 
       
    27 EXPORT_C TE64Addr::TE64Addr()
       
    28 {
       
    29 	SetAddrZero();
       
    30 }
       
    31 
       
    32 EXPORT_C TE64Addr::TE64Addr(const TE64Addr& aAddr)
       
    33 {
       
    34 	SetAddr(aAddr);
       
    35 }
       
    36 
       
    37 EXPORT_C TE64Addr::TE64Addr(const TInt64& aAddr)
       
    38 {
       
    39 	SetAddr(aAddr);
       
    40 }
       
    41 
       
    42 EXPORT_C TE64Addr::TE64Addr(const TUint8* aPtr, TUint aLength)
       
    43 {
       
    44 	SetAddr(aPtr, aLength);
       
    45 }
       
    46 
       
    47 EXPORT_C void TE64Addr::SetAddr(const TE64Addr& aAddr)
       
    48 {
       
    49 	u = aAddr.u;
       
    50 }
       
    51 
       
    52 EXPORT_C void TE64Addr::SetAddr(const TInt64& aAddr)
       
    53 {
       
    54 #ifdef I64HIGH
       
    55 	u.iAddr32[0] = I64HIGH(aAddr);
       
    56 	u.iAddr32[1] = I64LOW(aAddr);
       
    57 #else
       
    58 	u.iAddr32[0] = aAddr.High();
       
    59 	u.iAddr32[1] = aAddr.Low();
       
    60 #endif
       
    61 }
       
    62 
       
    63 EXPORT_C void TE64Addr::SetAddr(const TUint8* aPtr, TUint aLength)
       
    64 {
       
    65 	__ASSERT_DEBUG(aLength <= AddrLen(), EuiPanic(EEuiPanicSourceTooLong));
       
    66 	Mem::Copy(AddrPtr(), aPtr, aLength);
       
    67 }
       
    68 
       
    69 EXPORT_C void TE64Addr::SetGroupBit(TBool aBit)
       
    70 {
       
    71 	__ASSERT_DEBUG(aBit == 0 || aBit == 1, EuiPanic(EEuiPanicBitIsNotBit));
       
    72 
       
    73 	//   0       0 0       1 1       2 ..
       
    74 	//  |0       7 8       5 6       3|..
       
    75 	//  +----+----+----+----+----+----+
       
    76 	//  |cccc|ccug|cccc|cccc|cccc|cccc|..
       
    77 	//  +----+----+----+----+----+----+
       
    78 
       
    79 	if (aBit)
       
    80 	{
       
    81 		u.iAddr8[0] |= 0x1;
       
    82 	}
       
    83 	else
       
    84 	{
       
    85 		u.iAddr8[0] &= 0xFE;
       
    86 	}
       
    87 }
       
    88 
       
    89 EXPORT_C void TE64Addr::SetUniversalBit(TBool aBit)
       
    90 {
       
    91 	__ASSERT_DEBUG(aBit == 0 || aBit == 1, EuiPanic(EEuiPanicBitIsNotBit));
       
    92 
       
    93 	//   0       0 0       1 1       2 ..
       
    94 	//  |0       7 8       5 6       3|..
       
    95 	//  +----+----+----+----+----+----+
       
    96 	//  |cccc|ccug|cccc|cccc|cccc|cccc|..
       
    97 	//  +----+----+----+----+----+----+
       
    98 
       
    99 	if (aBit)
       
   100 	{
       
   101 		u.iAddr8[0] |= 0x2;
       
   102 	}
       
   103 	else
       
   104 	{
       
   105 		u.iAddr8[0] &= 0xFD;
       
   106 	}
       
   107 }
       
   108 
       
   109 EXPORT_C void TE64Addr::SetAddrZero()
       
   110 {
       
   111 	Mem::FillZ(AddrPtr(), AddrLen());
       
   112 }
       
   113 
       
   114 EXPORT_C void TE64Addr::SetAddrRandom()
       
   115 {
       
   116 	TTime now;
       
   117 
       
   118 #ifndef EUI_PSEUDORANDOM
       
   119 	now.UniversalTime();
       
   120 #endif
       
   121 
       
   122 	TInt64 seed = now.Int64();
       
   123 	u.iAddr32[0] = Math::Rand(seed);
       
   124 	u.iAddr32[1] = Math::Rand(seed);
       
   125 	SetUniversalBit(0);
       
   126 	SetGroupBit(0);
       
   127 }
       
   128 
       
   129 EXPORT_C void TE64Addr::SetAddrRandomNZ()
       
   130 {
       
   131 	do {
       
   132 		SetAddrRandom();
       
   133 	}
       
   134 	while (IsZero());
       
   135 }
       
   136 
       
   137 EXPORT_C void TE64Addr::SetAddrRandomNZButNot(const TE64Addr& aAddr)
       
   138 {
       
   139 	do {
       
   140 		SetAddrRandomNZ();
       
   141 	}
       
   142 	while (Match(aAddr));
       
   143 }
       
   144 
       
   145 // Really should define TE48Addr for this... -tom
       
   146 
       
   147 EXPORT_C void TE64Addr::SetAddrFromEUI48(const TUint8* aPtr)
       
   148 {
       
   149 	u.iAddr8[0] = aPtr[0];
       
   150 	u.iAddr8[1] = aPtr[1];
       
   151 	u.iAddr8[2] = aPtr[2];
       
   152 	u.iAddr8[3] = 0xff;
       
   153 	u.iAddr8[4] = 0xfe;
       
   154 	u.iAddr8[5] = aPtr[3];
       
   155 	u.iAddr8[6] = aPtr[4];
       
   156 	u.iAddr8[7] = aPtr[5];
       
   157 
       
   158 	// The following is really not part of EUI-64 standard
       
   159 	// but required for IPv6 when forming an IPv6 interface
       
   160 	// identifier from an EUI-64 adderss. See RFC-2464,
       
   161 	// RFC-2373. Probably the stack should do this instead. -tom
       
   162 
       
   163 	// > It is required that the "u" bit (universal/local bit
       
   164 	// > in IEEE EUI-64 terminology) be inverted when forming
       
   165 	// > the interface identifier from the EUI-64.  The "u" bit
       
   166 	// > is set to one (1) to indicate global scope, and it is
       
   167 	// > set to zero (0) to indicate local scope.
       
   168 
       
   169 	// So at this moment the address complies EUI-64
       
   170 
       
   171 	SetUniversalBit(!IsUniversal());
       
   172 
       
   173 	// Now it doesn't, but complies to IPv6 an interface identifier
       
   174 }
       
   175 
       
   176 EXPORT_C TBool TE64Addr::Match(const TE64Addr& aAddr) const
       
   177 {
       
   178 	return Mem::Compare(AddrPtrC(), AddrLen(), aAddr.AddrPtrC(), AddrLen()) ? 0 : 1;
       
   179 }
       
   180 
       
   181 EXPORT_C TBool TE64Addr::IsZero() const
       
   182 {
       
   183 	return (u.iAddr32[0] == 0) && (u.iAddr32[1] == 0);
       
   184 }
       
   185 
       
   186 EXPORT_C TBool TE64Addr::IsGroup() const
       
   187 {
       
   188 	return (u.iAddr8[0] & 0x1);
       
   189 }
       
   190 
       
   191 EXPORT_C TBool TE64Addr::IsUniversal() const
       
   192 {
       
   193 	return (u.iAddr8[0] & 0x2);
       
   194 }
       
   195 
       
   196 EXPORT_C void TE64Addr::Output(TDes& aBuf) const
       
   197 {
       
   198 	TPtrC8 e64Addr(AddrPtrC(), AddrLen());
       
   199 	TUint i;
       
   200 
       
   201 	for (i = 0; i < AddrLen(); i++)
       
   202 	{
       
   203 		if (i) {
       
   204 			aBuf.Append(':');
       
   205 		}
       
   206 
       
   207 		aBuf.AppendNum(TUint(e64Addr[i]), EHex);
       
   208 	}
       
   209 }
       
   210 
       
   211 EXPORT_C TUint TE64Addr::AddrLen()
       
   212 {
       
   213 	return sizeof(TE64Addr);
       
   214 }
       
   215 
       
   216 EXPORT_C TUint8* TE64Addr::AddrPtr()
       
   217 {
       
   218 	return &u.iAddr8[0];
       
   219 }
       
   220 
       
   221 EXPORT_C const TUint8* TE64Addr::AddrPtrC() const
       
   222 {
       
   223 	return &u.iAddr8[0];
       
   224 }
       
   225 
       
   226 EXPORT_C TEui64Addr::TEui64Addr() : TSockAddr()
       
   227 {
       
   228 	Init();
       
   229 	Address().SetAddrZero();
       
   230 }
       
   231 
       
   232 EXPORT_C TEui64Addr::TEui64Addr(const TSockAddr& aAddr) : TSockAddr()
       
   233 {
       
   234 	__ASSERT_ALWAYS(aAddr.Family() == KAfEui64 || aAddr.Family() == 0, EuiPanic(EEuiPanicFamilyMismatch));
       
   235 	Init();
       
   236 	SetAddress(TEui64Addr::Cast(aAddr).Address());
       
   237 }
       
   238 
       
   239 EXPORT_C void TEui64Addr::Init()
       
   240 {
       
   241 	SetFamily(KAfEui64);
       
   242 	SetPort(0);
       
   243 	SetUserLen(AddrLen());
       
   244 }
       
   245 
       
   246 EXPORT_C void TEui64Addr::SetAddress(const TE64Addr& aAddr)
       
   247 {
       
   248 	Address().SetAddr(aAddr);
       
   249 }
       
   250 
       
   251 EXPORT_C TE64Addr& TEui64Addr::Address() const
       
   252 {
       
   253 	return AddrPtr()->iAddr;
       
   254 }
       
   255 
       
   256 EXPORT_C TBool TEui64Addr::Match(const TEui64Addr& aAddr) const
       
   257 {
       
   258 	return Address().Match(aAddr.Address());
       
   259 }
       
   260 
       
   261 EXPORT_C TBool TEui64Addr::IsZero() const
       
   262 {
       
   263 	return Address().IsZero();
       
   264 }
       
   265 
       
   266 EXPORT_C TEui64Addr& TEui64Addr::Cast(const TSockAddr& aAddr)
       
   267 {
       
   268 	return *((TEui64Addr*)&aAddr); //lint !e1773 // standard way to implement Cast
       
   269 }
       
   270 
       
   271 EXPORT_C TEui64Addr& TEui64Addr::Cast(const TSockAddr* aAddr)
       
   272 {
       
   273        return *((TEui64Addr*)aAddr); //lint !e1773 // standard way to implement Cast
       
   274 }
       
   275 
       
   276 EXPORT_C SE64Addr* TEui64Addr::AddrPtr() const
       
   277 {
       
   278 	return (SE64Addr*)UserPtr();
       
   279 }
       
   280 
       
   281 EXPORT_C TUint TEui64Addr::AddrLen()
       
   282 {
       
   283 	return TE64Addr::AddrLen();
       
   284 }