int LWIP_SOCKETS_Driver::GetSockOpt( SOCK_SOCKET socket, int level, int optname, char* optval, int* optlen )
{ 
    NATIVE_PROFILE_PAL_NETWORK();
    int         nativeLevel;
    int         nativeOptionName;
    char*       pNativeOptval = optval;
    int         ret;
    
    switch(level)
    {
        case SOCK_IPPROTO_IP:
            nativeLevel         = IPPROTO_IP;
            nativeOptionName    = GetNativeIPOption(optname);
            break;
        case SOCK_IPPROTO_TCP:    
            nativeLevel         = IPPROTO_TCP;
            nativeOptionName    = GetNativeTcpOption(optname);
            break;
        case SOCK_IPPROTO_UDP: 
        case SOCK_IPPROTO_ICMP:
        case SOCK_IPPROTO_IGMP:
        case SOCK_IPPROTO_IPV4:
        case SOCK_SOL_SOCKET:
            nativeLevel         = SOL_SOCKET;
            nativeOptionName    = GetNativeSockOption(optname);
            break;
        default:
            nativeLevel         = level;
            nativeOptionName    = optname;
            break;
    }

    ret = lwip_getsockopt(socket, nativeLevel, nativeOptionName, pNativeOptval, (u32_t*)optlen);

    if(ret == 0)
    {
        switch(level)
        {
            case SOCK_SOL_SOCKET:
                switch(optname)
                {
                    case SOCK_SOCKO_EXCLUSIVEADDRESSUSE:
                    case SOCK_SOCKO_DONTLINGER:
                        *optval = !(*(int*)optval != 0);
                        break;
                        
                    case SOCK_SOCKO_ACCEPTCONNECTION:
                    case SOCK_SOCKO_BROADCAST:
                    case SOCK_SOCKO_KEEPALIVE:
                        *optval = (*(int*)optval != 0);
                        break;
                }
                break;
        }
    }

    return ret;    
}
int LWIP_SOCKETS_Driver::SetSockOpt( SOCK_SOCKET socket, int level, int optname, const char* optval, int  optlen )
{ 
    NATIVE_PROFILE_PAL_NETWORK();
    int nativeLevel;
    int nativeOptionName;
    int nativeIntValue;
    char *pNativeOptionValue = (char*)optval;

    switch(level)
    {
        case SOCK_IPPROTO_IP:
            nativeLevel = IPPROTO_IP;
            nativeOptionName = GetNativeIPOption(optname);
            break;
        case SOCK_IPPROTO_TCP:    
            nativeLevel = IPPROTO_TCP;
            nativeOptionName = GetNativeTcpOption(optname);
            break;
        case SOCK_IPPROTO_UDP: 
        case SOCK_IPPROTO_ICMP:
        case SOCK_IPPROTO_IGMP:
        case SOCK_IPPROTO_IPV4:
        case SOCK_SOL_SOCKET:
            nativeLevel      = SOL_SOCKET;
            nativeOptionName = GetNativeSockOption(optname);            

            switch(optname)
            {        
                // LINGER and DONTLINGER are not implemented in LWIP
                case SOCK_SOCKO_LINGER:
                    errno = SOCK_ENOPROTOOPT;
                    return SOCK_SOCKET_ERROR;
                case SOCK_SOCKO_DONTLINGER:
                    errno = SOCK_ENOPROTOOPT;
                    return SOCK_SOCKET_ERROR;
				// ignore this item to enable http to work
				case SOCK_SOCKO_REUSEADDRESS:
					return 0;
                
                case SOCK_SOCKO_EXCLUSIVEADDRESSUSE:
                    nativeIntValue     = !*(int*)optval;
                    pNativeOptionValue = (char*)&nativeIntValue;
                    break;
                default:
                    break;
            }
            break;
        default:
            nativeLevel         = 0;
            nativeOptionName    = 0;
            break;
    }

    return lwip_setsockopt(socket, nativeLevel, nativeOptionName, pNativeOptionValue, optlen);
}
int RTIP_SOCKETS_Driver::GetSockOpt( SOCK_SOCKET socket, int level, int optname, char* optval, int* optlen )
{ 
    NATIVE_PROFILE_PAL_NETWORK();
    int         ret;
    int         nativeLevel;
    int         nativeOptionName;
    
    switch(level)
    {
        case SOCK_IPPROTO_IP:
            nativeLevel = RTP_NET_IPROTO_IP;
            nativeOptionName = GetNativeIPOption(optname);
            break;
        case SOCK_IPPROTO_TCP:    
        case SOCK_IPPROTO_UDP: 
        case SOCK_IPPROTO_ICMP:
        case SOCK_IPPROTO_IGMP:
        case SOCK_IPPROTO_IPV4:
        case SOCK_SOL_SOCKET:
            nativeLevel         = RTP_NET_SOL_SOCKET;
            nativeOptionName    = GetNativeSockOption(level, optname);
            break;
        default:
            nativeLevel         = 0;
            nativeOptionName    = 0;
            break;
    }
    


    ret = rtp_net_getsockopt((RTP_HANDLE)socket, 
                            nativeLevel, 
                            nativeOptionName,     
                            optval, 
                            optlen);

    if(SOCK_SOCKET_ERROR != ret)
    {
        switch(optname)
        {
            case SOCK_SOCKO_NOCHECKSUM:
            case SOCK_SOCKO_EXCLUSIVEADDRESSUSE:
                *((int *) optval) = !*(int*)optval;
                break;
            default:
                break;
        }
    }

    return ret; 
}
int RTIP_SOCKETS_Driver::SetSockOpt( SOCK_SOCKET socket, int level, int optname, const char* optval, int  optlen )
{ 
    NATIVE_PROFILE_PAL_NETWORK();
    int ret;
    int nativeLevel;
    int nativeOptionName;
    int nativeIntValue;
    char *pNativeOptionValue = (char*)optval;
    
    switch(level)
    {
        case SOCK_IPPROTO_IP:
            nativeLevel = RTP_NET_IPROTO_IP;
            nativeOptionName = GetNativeIPOption(optname);
            break;
        case SOCK_IPPROTO_TCP:    
        case SOCK_IPPROTO_UDP: 
        case SOCK_IPPROTO_ICMP:
        case SOCK_IPPROTO_IGMP:
        case SOCK_IPPROTO_IPV4:
        case SOCK_SOL_SOCKET:
            nativeLevel      = RTP_NET_SOL_SOCKET;
            nativeOptionName = GetNativeSockOption(level, optname);            

            switch(optname)
            {
                case SOCK_SOCKO_EXCLUSIVEADDRESSUSE:
                case SOCK_SOCKO_NOCHECKSUM:
                case SOCK_SOCKO_DONTLINGER:
                    nativeIntValue     = !*(int*)optval;
                    pNativeOptionValue = (char*)&nativeIntValue;
                    break;
                default:
                    break;
            }
            break;
        default:
            nativeLevel         = 0;
            nativeOptionName    = 0;
            break;
    }
    
    ret = rtp_net_setsockoopt((RTP_HANDLE) socket, 
                nativeLevel,
                nativeOptionName, 
                pNativeOptionValue,
                optlen);

    return ret;
    
}
int LWIP_SOCKETS_Driver::SetSockOpt( SOCK_SOCKET socket, int level, int optname, const char* optval, int  optlen )
{ 
    NATIVE_PROFILE_PAL_NETWORK();
    int nativeLevel;
    int nativeOptionName;
    int nativeIntValue;
    char *pNativeOptionValue = (char*)optval;

    switch(level)
    {
        case SOCK_IPPROTO_IP:
            nativeLevel = IPPROTO_IP;
            nativeOptionName = GetNativeIPOption(optname);
            break;
        case SOCK_IPPROTO_TCP:    
            nativeLevel = IPPROTO_TCP;
            nativeOptionName = GetNativeTcpOption(optname);
            break;
        case SOCK_IPPROTO_UDP: 
        case SOCK_IPPROTO_ICMP:
        case SOCK_IPPROTO_IGMP:
        case SOCK_IPPROTO_IPV4:
        case SOCK_SOL_SOCKET:
            nativeLevel      = SOL_SOCKET;
            nativeOptionName = GetNativeSockOption(optname);            

            switch(optname)
            {
                case SOCK_SOCKO_EXCLUSIVEADDRESSUSE:
                case SOCK_SOCKO_DONTLINGER:
                    nativeIntValue     = !*(int*)optval;
                    pNativeOptionValue = (char*)&nativeIntValue;
                    break;
                default:
                    break;
            }
            break;
        default:
            nativeLevel         = 0;
            nativeOptionName    = 0;
            break;
    }

    return lwip_setsockopt(socket, nativeLevel, nativeOptionName, pNativeOptionValue, optlen);
}