/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "Licence").
 * You may not use this file except in compliance with the Licence.
 *
 * You can obtain a copy of the licence at RISC OS path @.^.LICENCE
 * or  http://www.riscosdev.com/lanman98/LICENCE.CDDL
 * See the Licence for the specific language governing permissions
 * and limitations under the Licence.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the Licence file. If applicable, add the
 * following below this CDDL HEADER, with the fields enclosed by
 * brackets "[]" replaced with your own identifying information:
 * Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
 
/*
 *   Copyright 1996 Warm Silence Software Ltd.  All rights reserved.
 *   Use is subject to license terms.
 */


/*
 *   PHBG 20/12/96: Initial version
 *   PHBG 5/2/97:   Added UDP support
 *   PHBG 27/7/98:  Threaded version
 */

#ifndef _TCP_
#define _TCP_

typedef int tcp_port_t;
typedef struct tcp_addr_s *tcp_addr_t;
/*
    Ports are just integers, but IP addresses are more complicated things
    that need destructing when you've finished with them.
*/

typedef struct tcp_conn_s *tcp_conn_t;
typedef struct tcp_bleeper_s *tcp_bleeper_t;
/*
    Things of type tcp_conn_t are full duplex connections between
    a local port and a port on a remote host, specified by its
    IP address.

    A connection can be created by making an outgoing call, or by
    having a bleeper, which listens on a port for incoming calls.
*/

typedef struct udp_conn_s *udp_conn_t;
/*
    Things of type udp_conn_t are unreliable connections that may not even
    have a corresponding other-half on the remote machine.  Soon as you
    create one you can read from and write to it, but you may be just
    %@$ing in the wind.
*/


#ifndef NULL
#define NULL (0)
#endif

#define TCP_PORT_ANY (0)
/*
    When making an outgoing call, you can ask that a fresh port be chosen
    for you, by specifying TCP_PORT_ANY
*/

void TcpInitialise(void);
/*
  Must be called before any other entry point.
*/

void TcpFinalise(void);
/*
  Call when you've finished with this tcp module.
*/

char *TcpHostName(void);
/*
  Returns the host name for this machine.
*/

tcp_addr_t TcpAddrFromQuad(char *);
/*
   Creates, from an array of char of size 4, an address in tcp_addr_t form.
*/

void TcpAddrToQuad(tcp_addr_t, char *);
/*
  Derives size 4 char array from address in tcp_addr_t form.
*/

tcp_addr_t TcpResolve(char * /* URL */);
/*
  Request for address resolution.  The calling thread will sleep until
  the call has completed.  Returns NULL if address unknown.
*/

tcp_addr_t TcpPeer(tcp_conn_t);
/*
  Obtains the address of the remote end of a TCP connection.
*/

void TcpAddrDestruct(tcp_addr_t);
/*
  IP addresses are not trivial structures and need destructing.
*/


tcp_conn_t TcpCall(tcp_port_t /* local */,
                   tcp_port_t /* remote */,
                   tcp_addr_t /* remote */);
/*
  Make an outgoing call.  The calling thread will sleep until the call
  has completed.
*/

tcp_addr_t TcpLocalAddr(tcp_conn_t);
/*
  Return the local address of a TCP connection.
*/

tcp_port_t TcpLocalPort(tcp_conn_t);
/*
  Return the local port of a TCP connection.
*/

tcp_bleeper_t TcpListen(tcp_port_t /* local */);
/*
  Create a socket on which to listen for incoming connections.
*/

tcp_bleeper_t TcpListenToConn(tcp_conn_t);
/*
  Listen for incoming connections on an existing socket.
*/

tcp_port_t TcpBleeperPort(tcp_bleeper_t);
/*
  Find out what port we're on.
*/

void TcpBleeperDestruct(tcp_bleeper_t);
/*
  Get rid of bleeper.
*/

tcp_conn_t TcpAnswer(tcp_bleeper_t);
/*
  Wait for an incoming connection.  The calling thread will sleep until
  a connection arrives.
*/

void TcpSetNoDelay(tcp_conn_t);
/*
  Instruct a connection not to buffer outgoing data.
*/

void TcpConnDestruct(tcp_conn_t);
/*
  Free all resources associated with a connection.  Best done when a
  connection has been closed, but can be called before this.
*/

int TcpRead(void *, int, tcp_conn_t);
/*
  Read from a connection.  The calling thread sleeps until the requested
  amount of data arrives, or end-of-data is detected.  Returns the amount
  of data received (less than that requested, only if the sender has closed
  the connection).
*/

int TcpReadSome(void *, int, tcp_conn_t);
/*
  Read from a connection.  The calling thread sleeps until some data has
  arrived, or end-of-data is detected.  Returns the amount of data
  received (may be less than that requested, but never zero, unless
  end-of-data has been detected).
*/

void TcpWrite(void *, int, tcp_conn_t);
/*
  Write to a connection.  The calling thread sleeps until the requested
  amount of data has been sent.
*/

void TcpClose(tcp_conn_t);
/*
  Request closing of a connection.  After doing this, you should typically
  read all remaining data from the peer.
*/

udp_conn_t UdpCreate(tcp_port_t /* local */);
/*
  Create the local half of a UDP connection.
*/

void UdpSetPeer(tcp_port_t, tcp_addr_t, udp_conn_t);
/*
  Specialise the local half of a UDP connection to work with
  a particular remote half.  Essential before writes.
*/

void UdpDestruct(udp_conn_t);
/*
  Remove local half of a UDP connection.
*/

tcp_port_t UdpLocalPort(udp_conn_t);
/*
  Find out what port we're on.
*/

int UdpRead(void *, int, udp_conn_t);
/*
  Read from a connection.  Sleeps until a packet arrives.
*/

void UdpWrite(void *, int, udp_conn_t);
/*
  Write to a connection.  Sleeps until the packet has been sent.
*/

#endif
