sdkcreationmw/sdkruntimes/wsock/src/WinsockProtocolFamily.cpp
author rajpuroh
Wed, 21 Apr 2010 09:56:53 +0530
changeset 1 ac50fd48361b
parent 0 b26acd06ea60
permissions -rw-r--r--
Second Contribution

/*
* Copyright (c) 2004-2005 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* which accompanies this distribution, and is available
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
*
*/


#define TRACE_PREFIX "WSOCK: ProtocolFamily: "
#include "wsock.h"
#include "WinsockProtocol.h"
#include "WinsockProtocolFamily.h"
#include <winsock2.h>

#define IPPROTO_ICMPV6 58

const TUint KProtocolInetRes = 0xF01;

// Initializer for TWinProtocolDesc structure
class TWinProtocolDescInit: public TWinProtocolDesc
{
public:
    TWinProtocolDescInit(const TText * aName,
        TUint aAddrFamily, TUint aSockType, TUint aProtocol,
        TUint aServiceInfo, TInt aMessageSize, TInt aServiceTypeInfo,
        TUint aWinSockType, TUint aWinProtocol)
    {
        iName = aName;
        iAddrFamily = aAddrFamily;
        iSockType = aSockType;
        iProtocol = aProtocol;
        iVersion = TVersion(1,0,0);
        iByteOrder = EBigEndian;
        iServiceInfo = aServiceInfo;
        iNamingServices = KNSNameResolution;
        iSecurity = KSocketNoSecurity;
        iMessageSize = aMessageSize;
        iServiceTypeInfo = aServiceTypeInfo;
        iNumSockets = KUnlimitedSockets;
        iWinSockType = aWinSockType;
        iWinProtocol = aWinProtocol;
    }
};

#if 0

TWinProtocolDescInit IP(_S("ip"),
    KAfInet,  KSockStream,  KProtocolInetTcp, KSIStreamBased | KSIInOrder |
    KSIReliable | KSIGracefulClose | KSIPeekData | KSIUrgentData, 
    KSocketMessageSizeIsStream, ESocketSupport,
    SOCK_STREAM, IPPROTO_TCP);

#ifdef WSOCK_IPV6

TWinProtocolDescInit IP6(_S("ip6"),
    KAfInet6,  KSockStream,  KProtocolInetTcp, KSIStreamBased | KSIInOrder |
    KSIReliable | KSIGracefulClose | KSIPeekData | KSIUrgentData, 
    KSocketMessageSizeIsStream, ESocketSupport,
    SOCK_STREAM, IPPROTO_TCP);
#endif

// NOTE: the order of protocols must match the order of entries in the
// ip.tcp.esk file (at the time of thie writing this file was located 
// in c:\private\101f7989\ESock directory).
static const TWinProtocolDesc* ipProtocols[] = {
     &IP,
#ifdef WSOCK_IPV6
     &IP6
#endif // WSOCK_IPV6
};
#else
TWinProtocolDescInit IP(_S("ip"),
    KAfInet,  KSockStream,  KProtocolInetTcp, KSIStreamBased | KSIInOrder |
    KSIReliable | KSIGracefulClose | KSIPeekData | KSIUrgentData, 
    KSocketMessageSizeIsStream, ESocketSupport,
    SOCK_STREAM, IPPROTO_IP);

TWinProtocolDescInit TCP(_S("tcp"),
    KAfInet,  KSockStream,  KProtocolInetTcp, KSIStreamBased | KSIInOrder |
    KSIReliable | KSIGracefulClose | KSIPeekData | KSIUrgentData, 
    KSocketMessageSizeIsStream, ESocketSupport,
    SOCK_STREAM, IPPROTO_TCP);

TWinProtocolDescInit UDP(_S("udp"),
    KAfInet,  KSockDatagram,  KProtocolInetUdp, 
    KSIConnectionLess | KSIDatagram | KSIGracefulClose | KSIPeekData,
    65516, ESocketSupport,
    SOCK_DGRAM, IPPROTO_UDP);

TWinProtocolDescInit ICMP4(_S("icmp"),
    KAfInet,  KSockDatagram,  KProtocolInetIcmp, KSIConnectionLess |
    KSIMessageBased | KSIBroadcast | KSIPeekData | KSIGracefulClose,
    65000, ESocketSupport | ETransport | EPreferDescriptors | EUseCanSend,
    SOCK_RAW, IPPROTO_ICMP);

TWinProtocolDescInit ICMP6(_S("icmp6"),
    KAfInet,  KSockDatagram,  KProtocolInet6Icmp, KSIConnectionLess |
    KSIMessageBased | KSIBroadcast | KSIPeekData | KSIGracefulClose,
    65000, ESocketSupport | ETransport | EPreferDescriptors | EUseCanSend,
    SOCK_RAW, IPPROTO_ICMPV6);

#ifdef WSOCK_IPV6

TWinProtocolDescInit IP6(_S("ip6"),
    KAfInet6,  KSockStream,  KProtocolInetTcp, KSIStreamBased | KSIInOrder |
    KSIReliable | KSIGracefulClose | KSIPeekData | KSIUrgentData, 
    KSocketMessageSizeIsStream, ESocketSupport,
    SOCK_STREAM, IPPROTO_IP);

TWinProtocolDescInit TCP6(_S("tcp"),
    KAfInet6,  KSockStream,  KProtocolInetTcp, KSIStreamBased | KSIInOrder |
    KSIReliable | KSIGracefulClose | KSIPeekData | KSIUrgentData, 
    KSocketMessageSizeIsStream, ESocketSupport,
    SOCK_STREAM, IPPROTO_TCP);

TWinProtocolDescInit UDP6(_S("udp"),
    KAfInet6,  KSockDatagram,  KProtocolInetUdp, 
    KSIConnectionLess | KSIDatagram |KSIGracefulClose | KSIPeekData,
    65516, ESocketSupport,
    SOCK_DGRAM, IPPROTO_UDP);

TWinProtocolDescInit ICMP46(_S("icmp"),
    KAfInet6,  KSockDatagram,  KProtocolInetIcmp, KSIConnectionLess |
    KSIMessageBased | KSIBroadcast | KSIPeekData | KSIGracefulClose,
    65000, ESocketSupport | ETransport | EPreferDescriptors | EUseCanSend,
    SOCK_RAW, IPPROTO_ICMP);

TWinProtocolDescInit ICMP66(_S("icmp6"),
    KAfInet6,  KSockDatagram,  KProtocolInet6Icmp, KSIConnectionLess |
    KSIMessageBased | KSIBroadcast | KSIPeekData | KSIGracefulClose,
    65000, ESocketSupport | ETransport | EPreferDescriptors | EUseCanSend,
    SOCK_RAW, IPPROTO_ICMPV6);

#endif // WSOCK_IPV6



// NOTE: the order of protocols must match the order of entries in the
// ip.tcp.esk file (at the time of thie writing this file was located 
// in c:\private\101f7989\ESock directory).
static const TWinProtocolDesc* ipProtocols[] = {
    &IP,&TCP,&UDP,&ICMP4,&ICMP6,
#ifdef WSOCK_IPV6
    &IP6,&TCP6,&UDP6,&ICMP46,&ICMP66
#endif // WSOCK_IPV6
};
#endif
CWinsockProtocolFamily::CWinsockProtocolFamily(TUint aAddrFamily) :
iAddrFamily(aAddrFamily)
{
    TRACE2("[%08X] created (0x%04x)",this,aAddrFamily);
}

CWinsockProtocolFamily::~CWinsockProtocolFamily()
{
    TRACE1("[%08X] destroyed",this);
}

TInt CWinsockProtocolFamily::Install()
{
    TRACE1("[%08X] Install",this);
    return KErrNone;
}

// Access to the list of protocols
TInt CWinsockProtocolFamily::ProtocolCount()
{
    return N(ipProtocols);
}

const TServerProtocolDesc* CWinsockProtocolFamily::ProtocolDesc(TInt aIndex)
{
    ASSERT(aIndex >= 0 && aIndex < N(ipProtocols));
    if (aIndex >= 0 && aIndex < N(ipProtocols))
    {
        return ipProtocols[aIndex];
    }
    else
    {
        return NULL;
    }
}

// Returns comma separated list of protocol names
void CWinsockProtocolFamily::ProtocolNamesfownetwork(TDes& aProtocols)
{
    aProtocols.SetLength(0);
 /*   for (TInt i=0; i<N(ipProtocols); i++)
    {
        TBool alreadyThere = EFalse;
        for (TInt k=0; k<i; k++)
        {
            if (!ipProtocols[i]->iName.Compare(ipProtocols[k]->iName))
            {
                alreadyThere = ETrue;
                break;
            }
        }
        if (!alreadyThere)
        {
            if (i > 0) aProtocols.Append(',');
            aProtocols.Append(ipProtocols[i]->iName);
        }
    }*/
    aProtocols.Append(ipProtocols[0]->iName);
    aProtocols.Append(',');
    aProtocols.Append(ipProtocols[5]->iName);
    
    TRACE1("ProtocolNames: %S",&aProtocols);
}

// Returns comma separated list of protocol names
void CWinsockProtocolFamily::ProtocolNames(TDes& aProtocols)
{
    aProtocols.SetLength(0);
    for (TInt i=0; i<N(ipProtocols); i++)
    {
        TBool alreadyThere = EFalse;
        for (TInt k=0; k<i; k++)
        {
            if (!ipProtocols[i]->iName.Compare(ipProtocols[k]->iName))
            {
                alreadyThere = ETrue;
                break;
            }
        }
        if (!alreadyThere)
        {
            if (i > 0) aProtocols.Append(',');
            aProtocols.Append(ipProtocols[i]->iName);
        }
    }
    TRACE1("ProtocolNames: %S",&aProtocols);
}

// CProtocolFamilyBase
TUint CWinsockProtocolFamily::ProtocolList(TServerProtocolDesc*& aProtocolList)
{
    // we allocate slightly more, but that's OK
    TInt count = 0;
    aProtocolList = new(ELeave)TServerProtocolDesc[N(ipProtocols)];
    if (aProtocolList)
    {
        for (TInt i=0; i<N(ipProtocols); i++)
        {
            if (ipProtocols[i]->iAddrFamily == iAddrFamily)
            {
                const TServerProtocolDesc* src = ipProtocols[i];
                aProtocolList[count++] = *src;
            }
        }

        if (!count)
        {
            delete aProtocolList;
            aProtocolList =  NULL;
        }
    }
    
    TRACE2("[%08X] ProtocolList - %d protocols",this,count);
    return count;
}

CProtocolBase* CWinsockProtocolFamily::NewProtocolL(TUint aSockType,
                                                    TUint aProtocol)
{
    TRACE3("[%08X] NewProtocolL(%d,%d)",this,aSockType,aProtocol);
    if (aProtocol == KUndefinedProtocol)
    {
        switch (aSockType)
        {
        case KSockDatagram:
            aProtocol = KProtocolInetUdp;
            break;
        case KSockStream:
            aProtocol = KProtocolInetTcp;
            break;
        default:
            LEAVE(KErrNotSupported);
            break;
        }
    }

    // Finds requested protocol
    for (TInt i=0; i<N(ipProtocols); i++)
    {
        if (ipProtocols[i]->iAddrFamily == iAddrFamily &&
            ipProtocols[i]->iSockType == aSockType &&
            ipProtocols[i]->iProtocol == aProtocol)
        {
            return new(ELeave)CWinsockProtocol(ipProtocols[i]);
        }
    }

    LEAVE(KErrNotSupported);
    return NULL;   
}

/**
 * Local Variables:
 * c-basic-offset: 4
 * indent-tabs-mode: nil
 * End:
 */