/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_MODULES_UDP_TRANSPORT_INTERFACE_UDP_TRANSPORT_H_
#define WEBRTC_MODULES_UDP_TRANSPORT_INTERFACE_UDP_TRANSPORT_H_

#include "common_types.h"
#include "module.h"
#include "typedefs.h"

#define SS_MAXSIZE 128
#define SS_ALIGNSIZE (sizeof (WebRtc_UWord64))
#define SS_PAD1SIZE  (SS_ALIGNSIZE - sizeof(WebRtc_Word16))
#define SS_PAD2SIZE  (SS_MAXSIZE - (sizeof(WebRtc_Word16) + SS_PAD1SIZE +\
                                    SS_ALIGNSIZE))

// BSD requires use of HAVE_STRUCT_SOCKADDR_SA_LEN
namespace webrtc {
struct SocketAddressIn
{
    // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6)
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
    WebRtc_Word8      sin_length;
    WebRtc_Word8      sin_family;
#else
    WebRtc_Word16     sin_family;
#endif
    WebRtc_UWord16    sin_port;
    WebRtc_UWord32    sin_addr;
    WebRtc_Word8      sin_zero[8];
};

struct Version6InAddress
{
    union
    {
        WebRtc_UWord8     _s6_u8[16];
        WebRtc_UWord32    _s6_u32[4];
        WebRtc_UWord64    _s6_u64[2];
    } Version6AddressUnion;
};

struct SocketAddressInVersion6
{
    // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6)
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
    WebRtc_Word8      sin_length;
    WebRtc_Word8      sin_family;
#else
    WebRtc_Word16     sin_family;
#endif
    // Transport layer port number.
    WebRtc_UWord16 sin6_port;
    // IPv6 traffic class and flow info or ip4 address.
    WebRtc_UWord32 sin6_flowinfo;
    // IPv6 address
    struct Version6InAddress sin6_addr;
    // Set of interfaces for a scope.
    WebRtc_UWord32 sin6_scope_id;
};

struct SocketAddressStorage
{
    // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6)
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
    WebRtc_Word8   sin_length;
    WebRtc_Word8   sin_family;
#else
    WebRtc_Word16  sin_family;
#endif
    WebRtc_Word8   __ss_pad1[SS_PAD1SIZE];
    WebRtc_UWord64 __ss_align;
    WebRtc_Word8   __ss_pad2[SS_PAD2SIZE];
};

struct SocketAddress
{
    union
    {
        struct SocketAddressIn _sockaddr_in;
        struct SocketAddressInVersion6 _sockaddr_in6;
        struct SocketAddressStorage _sockaddr_storage;
    };
};

// Callback class that receives packets from UdpTransport.
class UdpTransportData
{
public:
    virtual ~UdpTransportData()  {};

    virtual void IncomingRTPPacket(const WebRtc_Word8* incomingRtpPacket,
                                   const WebRtc_Word32 rtpPacketLength,
                                   const WebRtc_Word8* fromIP,
                                   const WebRtc_UWord16 fromPort) = 0;

    virtual void IncomingRTCPPacket(const WebRtc_Word8* incomingRtcpPacket,
                                    const WebRtc_Word32 rtcpPacketLength,
                                    const WebRtc_Word8* fromIP,
                                    const WebRtc_UWord16 fromPort) = 0;
};


class UdpTransport : public Module, public Transport
{
public:
    enum
    {
        kIpAddressVersion6Length = 64,
        kIpAddressVersion4Length = 16
    };
    enum ErrorCode
    {
        kNoSocketError            = 0,
        kFailedToBindPort         = 1,
        kIpAddressInvalid         = 2,
        kAddressInvalid           = 3,
        kSocketInvalid            = 4,
        kPortInvalid              = 5,
        kTosInvalid               = 6,
        kMulticastAddressInvalid  = 7,
        kQosError                 = 8,
        kSocketAlreadyInitialized = 9,
        kIpVersion6Error          = 10,
        FILTER_ERROR              = 11,
        kStartReceiveError        = 12,
        kStopReceiveError         = 13,
        kCannotFindLocalIp        = 14,
        kTosError                 = 16,
        kNotInitialized           = 17,
        kPcpError                 = 18
    };

    // Factory method. Constructor disabled.
    static UdpTransport* Create(const WebRtc_Word32 id,
                                WebRtc_UWord8& numSocketThreads);
    static void Destroy(UdpTransport* module);

    // Prepares the class for sending RTP packets to ipAddr:rtpPort and RTCP
    // packets to ipAddr:rtpPort+1 if rtcpPort is zero. Otherwise to
    // ipAddr:rtcpPort.
    virtual WebRtc_Word32 InitializeSendSockets(
        const WebRtc_Word8* ipAddr,
        const WebRtc_UWord16 rtpPort,
        const WebRtc_UWord16 rtcpPort = 0) = 0;

    // Register packetCallback for receiving incoming packets. Set the local
    // RTP port to rtpPort. Bind local IP address to ipAddr. If ipAddr is NULL
    // bind to local IP ANY. Set the local rtcp port to rtcpPort or rtpPort + 1
    // if rtcpPort is 0.
    virtual WebRtc_Word32 InitializeReceiveSockets(
        UdpTransportData* const packetCallback,
        const WebRtc_UWord16 rtpPort,
        const WebRtc_Word8* ipAddr = NULL,
        const WebRtc_Word8* multicastIpAddr = NULL,
        const WebRtc_UWord16 rtcpPort = 0) = 0;

    // Set local RTP port to rtpPort and RTCP port to rtcpPort or rtpPort + 1 if
    // rtcpPort is 0. These ports will be used for sending instead of the local
    // ports set by InitializeReceiveSockets(..).
    virtual WebRtc_Word32 InitializeSourcePorts(
        const WebRtc_UWord16 rtpPort,
        const WebRtc_UWord16 rtcpPort = 0) = 0;

    // Retrieve local ports used for sending if other than the ports specified
    // by InitializeReceiveSockets(..). rtpPort is set to the RTP port.
    // rtcpPort is set to the RTCP port.
    virtual WebRtc_Word32 SourcePorts(WebRtc_UWord16& rtpPort,
                                      WebRtc_UWord16& rtcpPort) const = 0;

    // Set ipAddr to the IP address that is currently being listened on. rtpPort
    // to the RTP port listened to. rtcpPort to the RTCP port listened on.
    // multicastIpAddr to the multicast IP address group joined (the address
    // is NULL terminated).
    virtual WebRtc_Word32 ReceiveSocketInformation(
        WebRtc_Word8 ipAddr[kIpAddressVersion6Length],
        WebRtc_UWord16& rtpPort,
        WebRtc_UWord16& rtcpPort,
        WebRtc_Word8 multicastIpAddr[kIpAddressVersion6Length]) const = 0;

    // Set ipAddr to the IP address being sent from. rtpPort to the local RTP
    // port used for sending and rtcpPort to the local RTCP port used for
    // sending.
    virtual WebRtc_Word32 SendSocketInformation(
        WebRtc_Word8 ipAddr[kIpAddressVersion6Length],
        WebRtc_UWord16& rtpPort,
        WebRtc_UWord16& rtcpPort) const = 0;

    // Put the IP address, RTP port and RTCP port from the last received packet
    // into ipAddr, rtpPort and rtcpPort respectively.
    virtual WebRtc_Word32 RemoteSocketInformation(
        WebRtc_Word8 ipAddr[kIpAddressVersion6Length],
        WebRtc_UWord16& rtpPort,
        WebRtc_UWord16& rtcpPort) const = 0;

    // Enable/disable quality of service if QoS is true or false respectively.
    // Set the type of service to serviceType, max bitrate in kbit/s to
    // maxBitrate and override DSCP if overrideDSCP is not 0.
    // Note: Must be called both InitializeSendSockets() and
    // InitializeReceiveSockets() has been called.
    virtual WebRtc_Word32 SetQoS(const bool QoS,
                                 const WebRtc_Word32 serviceType,
                                 const WebRtc_UWord32 maxBitrate = 0,
                                 const WebRtc_Word32 overrideDSCP = 0,
                                 const bool audio = false) = 0;

    // Set QoS to true if quality of service has been turned on. If QoS is true,
    // also set serviceType to type of service and overrideDSCP to override
    // DSCP.
    virtual WebRtc_Word32 QoS(bool& QoS,
                              WebRtc_Word32& serviceType,
                              WebRtc_Word32& overrideDSCP) const = 0;

    // Set type of service.
    virtual WebRtc_Word32 SetToS(const WebRtc_Word32 DSCP,
                                 const bool useSetSockOpt = false) = 0;

    // Get type of service configuration.
    virtual WebRtc_Word32 ToS(WebRtc_Word32& DSCP,
                              bool& useSetSockOpt) const = 0;

    // Set Priority Code Point (IEEE 802.1Q)
    // Note: for Linux this function will set the priority for the socket,
    // which then can be mapped to a PCP value with vconfig.
    virtual WebRtc_Word32 SetPCP(const WebRtc_Word32 PCP) = 0;

    // Get Priority Code Point
    virtual WebRtc_Word32 PCP(WebRtc_Word32& PCP) const = 0;

    // Enable IPv6.
    // Note: this API must be called before any call to
    // InitializeReceiveSockets() or InitializeSendSockets(). It is not
    // possible to go back to IPv4 (default) after this call.
    virtual WebRtc_Word32 EnableIpV6() = 0;

    // Return true if IPv6 has been enabled.
    virtual bool IpV6Enabled() const = 0;

    // Only allow packets received from filterIPAddress to be processed.
    // Note: must be called after EnableIPv6(), if IPv6 is used.
    virtual WebRtc_Word32 SetFilterIP(
        const WebRtc_Word8 filterIPAddress[kIpAddressVersion6Length]) = 0;

    // Write the filter IP address (if any) to filterIPAddress.
    virtual WebRtc_Word32 FilterIP(
        WebRtc_Word8 filterIPAddress[kIpAddressVersion6Length]) const = 0;

    // Only allow RTP packets from rtpFilterPort and RTCP packets from
    // rtcpFilterPort be processed.
    // Note: must be called after EnableIPv6(), if IPv6 is used.
    virtual WebRtc_Word32 SetFilterPorts(
        const WebRtc_UWord16 rtpFilterPort,
        const WebRtc_UWord16 rtcpFilterPort) = 0;

    // Set rtpFilterPort to the filter RTP port and rtcpFilterPort to the
    // filter RTCP port (if filtering based on port is enabled).
    virtual WebRtc_Word32 FilterPorts(WebRtc_UWord16& rtpFilterPort,
                                      WebRtc_UWord16& rtcpFilterPort) const = 0;

    // Set the number of buffers that the socket implementation may use for
    // receiving packets to numberOfSocketBuffers. I.e. the number of packets
    // that can be received in parallell.
    // Note: this API only has effect on Windows.
    virtual WebRtc_Word32 StartReceiving(
        const WebRtc_UWord32 numberOfSocketBuffers) = 0;

    // Stop receive incoming packets.
    virtual WebRtc_Word32 StopReceiving() = 0;

    // Return true incoming packets are received.
    virtual bool Receiving() const = 0;

    // Return true if send sockets have been initialized.
    virtual bool SendSocketsInitialized() const = 0;

    // Return true if local ports for sending has been set.
    virtual bool SourcePortsInitialized() const = 0;

    // Return true if receive sockets have been initialized.
    virtual bool ReceiveSocketsInitialized() const = 0;

    // Send data with size length to ip:portnr. The same port as the set
    // with InitializeSendSockets(..) is used if portnr is 0. The same IP
    // address as set with InitializeSendSockets(..) is used if ip is NULL.
    // If isRTCP is true the port used will be the RTCP port.
    virtual WebRtc_Word32 SendRaw(const WebRtc_Word8* data,
                                  WebRtc_UWord32 length,
                                  WebRtc_Word32 isRTCP,
                                  WebRtc_UWord16 portnr = 0,
                                  const WebRtc_Word8* ip = NULL) = 0;

    // Send RTP data with size length to the address specified by to.
    virtual WebRtc_Word32 SendRTPPacketTo(const WebRtc_Word8* data,
                                          WebRtc_UWord32 length,
                                          const SocketAddress& to) = 0;


    // Send RTCP data with size length to the address specified by to.
    virtual WebRtc_Word32 SendRTCPPacketTo(const WebRtc_Word8* data,
                                           WebRtc_UWord32 length,
                                           const SocketAddress& to) = 0;

    // Send RTP data with size length to ip:rtpPort where ip is the ip set by
    // the InitializeSendSockets(..) call.
    virtual WebRtc_Word32 SendRTPPacketTo(const WebRtc_Word8* data,
                                          WebRtc_UWord32 length,
                                          WebRtc_UWord16 rtpPort) = 0;


    // Send RTCP data with size length to ip:rtcpPort where ip is the ip set by
    // the InitializeSendSockets(..) call.
    virtual WebRtc_Word32 SendRTCPPacketTo(const WebRtc_Word8* data,
                                           WebRtc_UWord32 length,
                                           WebRtc_UWord16 rtcpPort) = 0;

    // Set the IP address to which packets are sent to ipaddr.
    virtual WebRtc_Word32 SetSendIP(
        const WebRtc_Word8 ipaddr[kIpAddressVersion6Length]) = 0;

    // Set the send RTP and RTCP port to rtpPort and rtcpPort respectively.
    virtual WebRtc_Word32 SetSendPorts(const WebRtc_UWord16 rtpPort,
                                       const WebRtc_UWord16 rtcpPort = 0) = 0;

    // Retreive the last registered error code.
    virtual ErrorCode LastError() const = 0;

    // Put the local IPv4 address in localIP.
    // Note: this API is for IPv4 only.
    static WebRtc_Word32 LocalHostAddress(WebRtc_UWord32& localIP);

    // Put the local IP6 address in localIP.
    // Note: this API is for IPv6 only.
    static WebRtc_Word32 LocalHostAddressIPV6(WebRtc_UWord8 localIP[16]);

    // Return a copy of hostOrder (host order) in network order.
    static WebRtc_UWord16 Htons(WebRtc_UWord16 hostOrder);

    // Return a copy of hostOrder (host order) in network order.
    static WebRtc_UWord32 Htonl(WebRtc_UWord32 hostOrder);

    // Return IPv4 address in ip as 32 bit integer.
    static WebRtc_UWord32 InetAddrIPV4(const WebRtc_Word8* ip);

    // Convert the character string src into a network address structure in
    // the af address family and put it in dst.
    // Note: same functionality as inet_pton(..)
    static WebRtc_Word32 InetPresentationToNumeric(WebRtc_Word32 af,
                                                   const WebRtc_Word8* src,
                                                   void* dst);

    // Set ip and sourcePort according to address. As input parameter ipSize
    // is the length of ip. As output parameter it's the number of characters
    // written to ip (not counting the '\0' character).
    // Note: this API is only implemented on Windows and Linux.
    static WebRtc_Word32 IPAddress(const SocketAddress& address,
                                   WebRtc_Word8* ip,
                                   WebRtc_UWord32& ipSize,
                                   WebRtc_UWord16& sourcePort);

    // Set ip and sourcePort according to address. As input parameter ipSize
    // is the length of ip. As output parameter it's the number of characters
    // written to ip (not counting the '\0' character).
    // Note: this API is only implemented on Windows and Linux.
    // Additional note: this API caches the address of the last call to it. If
    // address is likley to be the same for multiple calls it may be beneficial
    // to call this API instead of IPAddress().
    virtual WebRtc_Word32 IPAddressCached(const SocketAddress& address,
                                          WebRtc_Word8* ip,
                                          WebRtc_UWord32& ipSize,
                                          WebRtc_UWord16& sourcePort) = 0;

    // Return true if ipaddr is a valid IP address.
    // If ipV6 is false ipaddr is interpreted as an IPv4 address otherwise it
    // is interptreted as IPv6.
    static bool IsIpAddressValid(const WebRtc_Word8* ipaddr, const bool ipV6);
};
} // namespace webrtc

#endif // WEBRTC_MODULES_UDP_TRANSPORT_INTERFACE_UDP_TRANSPORT_H_
