// ---------------------------------------------------------------------------
// - cnet.hpp                                                                -
// - standard system library - c network native function definition          -
// ---------------------------------------------------------------------------
// - This program is free software;  you can redistribute it  and/or  modify -
// - it provided that this copyright notice is kept intact.                  -
// -                                                                         -
// - This program  is  distributed in  the hope  that it will be useful, but -
// - without  any  warranty;  without  even   the   implied    warranty   of -
// - merchantability or fitness for a particular purpose.  In no event shall -
// - the copyright holder be liable for any  direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software.     -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2001 amaury darsch                                   -
// ---------------------------------------------------------------------------

#ifndef  ALEPH_CNET_HPP
#define  ALEPH_CNET_HPP

#ifndef  ALEPH_CCNF_HPP
#include "ccnf.hpp"
#endif

namespace aleph {
  /// the shutdown mode
  enum t_shut {
    SOCKET_SHUT_BOTH, //shutdown both directions
    SOCKET_SHUT_RECV, // shutdown reception
    SOCKET_SHUT_SEND  // shutdown emission
  };

  /// the supported socket options
  enum t_sockopt {
    SOCKET_BROADCAST, // enable packet broadcast
    SOCKET_DONTROUTE, // bypass routing table
    SOCKET_KEEPALIVE, // set connection test
    SOCKET_LINGER,    // set linger time
    SOCKET_RCVSIZE,   // receive buffer size
    SOCKET_SNDSIZE,   // send buffer size
    SOCKET_HOPLIMIT,  // set hop limit
    SOCKET_MCASTLOOP, // multicast use lopback
    SOCKET_MCASTHOP,  // multicast hop limit
    SOCKET_MAXSEG,    // tcp maximum segment size
    SOCKET_NODELAY    // disable naggle algorithm
  };

  /// set a socket option
  /// @param int  sid the socket id
  /// @param opt  the option to set
  /// @param flag the option flag
  /// @param val  the option value
  bool c_ipsetopt (const int sid, t_sockopt opt, bool flag, long val);

  /// shutdown a socket connection
  /// @param sid the socket id
  /// @param how the shutdown mode
  bool c_ipshut (const int sid, t_shut how);

  /// @return the loopback name
  const char* c_loopname (void);

  /// convert an array of bytes (network byte order) to an ip address name
  /// the first byte is the length of the array (4 or 16)
  /// @param addr the address to convert
  char* c_iprepr (t_byte* addr);

  /// get the ip canonical name by name
  /// @param name the name to resolve
  char* c_ipcanon (const char* name);

  /// get an ip address by name - the byte array has the first byte set to
  /// either 4 or 16 to indicate the array length (ipv4 or ipv6)
  /// @param name the name to convert
  /// @return a byte array
  t_byte* c_ipaddr (const char* name);

  /// get a service by name and flag
  /// @param name the service name to find
  /// @param flag check for udp if false, or tcp if true
  t_word c_ipserv (const char* name, bool flag);

  /// check for an ipv6 socket
  /// @param sid the socket id to check
  bool c_isipv6 (const int sid);

  /// get the socket address of a socket
  /// @param sid the socket id
  t_byte* c_ipsockaddr (const int sid);

  /// get the peer address of a socket
  /// @param sid the socket id
  t_byte* c_ippeeraddr (const int sid);

  /// get the socket port of a socket
  /// @param sid the socket id
  t_word c_ipsockport (const int sid);

  /// get the peer port of a socket
  /// @param sid the socket id
  t_word c_ippeerport (const int sid);

  /// create a tcp socket
  int c_ipsocktcp (void);

  /// create a udp socket
  int c_ipsockudp (void);

  /// connect a socket with a server
  /// @param sid the client socket id
  /// @param port the port to connect
  /// @param dest the server address
  bool c_ipconnect (const int sid, t_word port, t_byte* dest);

  /// join a multicast group
  /// @param sid the socket id
  /// @param dest the multicast group address
  bool c_ipjoin (const int sid, t_byte* dest);

  /// drop a multicast group
  /// @param sid the socket id
  /// @param dest the multicast group address
  bool c_ipdrop (const int sid, t_byte* dest);

  /// send data to a socket
  /// @param sid the client socket
  /// @param buf the buffer of data to send
  /// @param size the buffer size
  long c_ipsend (const int sid, const char* buf, long size);

  /// send a datagram by address and port
  /// @param sid  the client socket
  /// @param port the destination port
  /// @param dest the destination address
  /// @param buf  the buffer of data to send
  /// @param size the buffer size
  long c_ipsendto (const int sid, t_word port, t_byte* dest, const char* buf, 
		   const long size);

  /// receive data from a socket
  /// @param sid the client socket
  /// @param buf the buffer to receive
  /// @param size the buffer size
  long c_iprecv (const int sid, char* buf, long size);

  /// receive a datagram on a port and update address
  /// @param sid  the client socket
  /// @param port the received port
  /// @param dest the received address
  /// @param buf  the buffer of data to receive
  /// @param size the buffer size
  long c_iprecvfr (const int sid, t_word& port, t_byte* dest, char* buf, 
		   const long size);

  /// bind and listen for a server socket
  /// @param sid the server socket
  /// @param port the port to bind
  /// @param backlog the backlog of incoming connection
  bool c_ipbind (const int sid, t_word port);

  /// bind and listen for a server socket at a certain address
  /// @param sid the server socket
  /// @param port the port to bind
  /// @param dest the server address to use
  bool c_ipbind (const int sid, t_word port, t_byte* dest);

  /// listen for a server socket
  /// @param sid the server socket
  /// @param backlog the backlog of incoming connection
  bool c_iplisten (const int sid, const long backlog);

  /// accept a connection for a server socket
  /// sid the socket id
  int c_ipaccept (const int sid);
}

#endif
