--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/esockapiextensions/internetsockets/src/eui_addr.cpp Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,284 @@
+// Copyright (c) 2004-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:
+// eui_addr.cpp - EUI-xx address structure
+//
+
+#include "eui_addr.h" // This
+#include <e32std.h> // Mem::*, User::*, TTime
+#include <e32math.h> // Math::*
+
+static void EuiPanic(TEuiPanic aReason);
+static void EuiPanic(TEuiPanic aReason)
+{
+ User::Panic(_L("EUI"), aReason);
+}
+
+EXPORT_C TE64Addr::TE64Addr()
+{
+ SetAddrZero();
+}
+
+EXPORT_C TE64Addr::TE64Addr(const TE64Addr& aAddr)
+{
+ SetAddr(aAddr);
+}
+
+EXPORT_C TE64Addr::TE64Addr(const TInt64& aAddr)
+{
+ SetAddr(aAddr);
+}
+
+EXPORT_C TE64Addr::TE64Addr(const TUint8* aPtr, TUint aLength)
+{
+ SetAddr(aPtr, aLength);
+}
+
+EXPORT_C void TE64Addr::SetAddr(const TE64Addr& aAddr)
+{
+ u = aAddr.u;
+}
+
+EXPORT_C void TE64Addr::SetAddr(const TInt64& aAddr)
+{
+#ifdef I64HIGH
+ u.iAddr32[0] = I64HIGH(aAddr);
+ u.iAddr32[1] = I64LOW(aAddr);
+#else
+ u.iAddr32[0] = aAddr.High();
+ u.iAddr32[1] = aAddr.Low();
+#endif
+}
+
+EXPORT_C void TE64Addr::SetAddr(const TUint8* aPtr, TUint aLength)
+{
+ __ASSERT_DEBUG(aLength <= AddrLen(), EuiPanic(EEuiPanicSourceTooLong));
+ Mem::Copy(AddrPtr(), aPtr, aLength);
+}
+
+EXPORT_C void TE64Addr::SetGroupBit(TBool aBit)
+{
+ __ASSERT_DEBUG(aBit == 0 || aBit == 1, EuiPanic(EEuiPanicBitIsNotBit));
+
+ // 0 0 0 1 1 2 ..
+ // |0 7 8 5 6 3|..
+ // +----+----+----+----+----+----+
+ // |cccc|ccug|cccc|cccc|cccc|cccc|..
+ // +----+----+----+----+----+----+
+
+ if (aBit)
+ {
+ u.iAddr8[0] |= 0x1;
+ }
+ else
+ {
+ u.iAddr8[0] &= 0xFE;
+ }
+}
+
+EXPORT_C void TE64Addr::SetUniversalBit(TBool aBit)
+{
+ __ASSERT_DEBUG(aBit == 0 || aBit == 1, EuiPanic(EEuiPanicBitIsNotBit));
+
+ // 0 0 0 1 1 2 ..
+ // |0 7 8 5 6 3|..
+ // +----+----+----+----+----+----+
+ // |cccc|ccug|cccc|cccc|cccc|cccc|..
+ // +----+----+----+----+----+----+
+
+ if (aBit)
+ {
+ u.iAddr8[0] |= 0x2;
+ }
+ else
+ {
+ u.iAddr8[0] &= 0xFD;
+ }
+}
+
+EXPORT_C void TE64Addr::SetAddrZero()
+{
+ Mem::FillZ(AddrPtr(), AddrLen());
+}
+
+EXPORT_C void TE64Addr::SetAddrRandom()
+{
+ TTime now;
+
+#ifndef EUI_PSEUDORANDOM
+ now.UniversalTime();
+#endif
+
+ TInt64 seed = now.Int64();
+ u.iAddr32[0] = Math::Rand(seed);
+ u.iAddr32[1] = Math::Rand(seed);
+ SetUniversalBit(0);
+ SetGroupBit(0);
+}
+
+EXPORT_C void TE64Addr::SetAddrRandomNZ()
+{
+ do {
+ SetAddrRandom();
+ }
+ while (IsZero());
+}
+
+EXPORT_C void TE64Addr::SetAddrRandomNZButNot(const TE64Addr& aAddr)
+{
+ do {
+ SetAddrRandomNZ();
+ }
+ while (Match(aAddr));
+}
+
+// Really should define TE48Addr for this... -tom
+
+EXPORT_C void TE64Addr::SetAddrFromEUI48(const TUint8* aPtr)
+{
+ u.iAddr8[0] = aPtr[0];
+ u.iAddr8[1] = aPtr[1];
+ u.iAddr8[2] = aPtr[2];
+ u.iAddr8[3] = 0xff;
+ u.iAddr8[4] = 0xfe;
+ u.iAddr8[5] = aPtr[3];
+ u.iAddr8[6] = aPtr[4];
+ u.iAddr8[7] = aPtr[5];
+
+ // The following is really not part of EUI-64 standard
+ // but required for IPv6 when forming an IPv6 interface
+ // identifier from an EUI-64 adderss. See RFC-2464,
+ // RFC-2373. Probably the stack should do this instead. -tom
+
+ // > It is required that the "u" bit (universal/local bit
+ // > in IEEE EUI-64 terminology) be inverted when forming
+ // > the interface identifier from the EUI-64. The "u" bit
+ // > is set to one (1) to indicate global scope, and it is
+ // > set to zero (0) to indicate local scope.
+
+ // So at this moment the address complies EUI-64
+
+ SetUniversalBit(!IsUniversal());
+
+ // Now it doesn't, but complies to IPv6 an interface identifier
+}
+
+EXPORT_C TBool TE64Addr::Match(const TE64Addr& aAddr) const
+{
+ return Mem::Compare(AddrPtrC(), AddrLen(), aAddr.AddrPtrC(), AddrLen()) ? 0 : 1;
+}
+
+EXPORT_C TBool TE64Addr::IsZero() const
+{
+ return (u.iAddr32[0] == 0) && (u.iAddr32[1] == 0);
+}
+
+EXPORT_C TBool TE64Addr::IsGroup() const
+{
+ return (u.iAddr8[0] & 0x1);
+}
+
+EXPORT_C TBool TE64Addr::IsUniversal() const
+{
+ return (u.iAddr8[0] & 0x2);
+}
+
+EXPORT_C void TE64Addr::Output(TDes& aBuf) const
+{
+ TPtrC8 e64Addr(AddrPtrC(), AddrLen());
+ TUint i;
+
+ for (i = 0; i < AddrLen(); i++)
+ {
+ if (i) {
+ aBuf.Append(':');
+ }
+
+ aBuf.AppendNum(TUint(e64Addr[i]), EHex);
+ }
+}
+
+EXPORT_C TUint TE64Addr::AddrLen()
+{
+ return sizeof(TE64Addr);
+}
+
+EXPORT_C TUint8* TE64Addr::AddrPtr()
+{
+ return &u.iAddr8[0];
+}
+
+EXPORT_C const TUint8* TE64Addr::AddrPtrC() const
+{
+ return &u.iAddr8[0];
+}
+
+EXPORT_C TEui64Addr::TEui64Addr() : TSockAddr()
+{
+ Init();
+ Address().SetAddrZero();
+}
+
+EXPORT_C TEui64Addr::TEui64Addr(const TSockAddr& aAddr) : TSockAddr()
+{
+ __ASSERT_ALWAYS(aAddr.Family() == KAfEui64 || aAddr.Family() == 0, EuiPanic(EEuiPanicFamilyMismatch));
+ Init();
+ SetAddress(TEui64Addr::Cast(aAddr).Address());
+}
+
+EXPORT_C void TEui64Addr::Init()
+{
+ SetFamily(KAfEui64);
+ SetPort(0);
+ SetUserLen(AddrLen());
+}
+
+EXPORT_C void TEui64Addr::SetAddress(const TE64Addr& aAddr)
+{
+ Address().SetAddr(aAddr);
+}
+
+EXPORT_C TE64Addr& TEui64Addr::Address() const
+{
+ return AddrPtr()->iAddr;
+}
+
+EXPORT_C TBool TEui64Addr::Match(const TEui64Addr& aAddr) const
+{
+ return Address().Match(aAddr.Address());
+}
+
+EXPORT_C TBool TEui64Addr::IsZero() const
+{
+ return Address().IsZero();
+}
+
+EXPORT_C TEui64Addr& TEui64Addr::Cast(const TSockAddr& aAddr)
+{
+ return *((TEui64Addr*)&aAddr); //lint !e1773 // standard way to implement Cast
+}
+
+EXPORT_C TEui64Addr& TEui64Addr::Cast(const TSockAddr* aAddr)
+{
+ return *((TEui64Addr*)aAddr); //lint !e1773 // standard way to implement Cast
+}
+
+EXPORT_C SE64Addr* TEui64Addr::AddrPtr() const
+{
+ return (SE64Addr*)UserPtr();
+}
+
+EXPORT_C TUint TEui64Addr::AddrLen()
+{
+ return TE64Addr::AddrLen();
+}