/*

net.h - Networking

*/

#ifndef NET_H
#define	NET_H

/*...sincludes:0:*/
#include "types.h"

/*...vtypes\46\h:0:*/
/*...e*/

#define	SS_FREE        0
#define	SS_ALLOCATED   1
#define	SS_CONNECT     2
#define	SS_LISTEN      3
#define	SS_ESTABLISHED 4
#define	SS_SEND        5
#define	SS_RECV        6
#define	SS_ERROR       7
#define	SS_DISCONNECT  8

typedef struct
	{
	FIBER fiber_int;
	BOOLEAN fiber_int_queued;
	word sra;
	word tx_buf;
	word rx_buf;
	byte int_bit;
	byte state; /* SS_* */
	FIBER fiber_op;
	const byte *send_ptr;
	byte *recv_ptr;
	word length;
	word thisgo;
	word actual;
	word consumed;
	} SOCKET;

typedef struct
	{
	FIBER fiber;
	SOCKET *socket;
	} SOCKET_ALLOC;

extern void net_init(void);

extern void net_handle_interrupts(void);

/* On output, state will be SS_ALLOCATED. */
extern void net_alloc(SOCKET_ALLOC *sockalloc, NF nf, void *nfp);

/* On input, state must be SS_ALLOCATED. */
extern void net_free(SOCKET *socket);

/* On input, state must be SS_ALLOCATED.
   On output, state will transition to SS_ESTABLISHED if ok, or remain in SS_ALLOCATED if refused or timeout. */
extern void net_connect(SOCKET *socket, const byte *ip, word port, NF nf, void *nfp);

/* On input, state must be SS_ALLOCATED.
   On output, state will be SS_ESTABLISHED when connection accepted. */
extern void net_listen(SOCKET *socket, word port, NF nf, void *nfp);

/* On input, state must be SS_ESTABLISHED or SS_ERROR.
   On output, state will be SS_ALLOCATED. */
extern void net_disconnect(SOCKET *socket, NF nf, void *nfp);

/* On input, state must be SS_ESTABLISHED.
   On output, state will change to SS_ERROR if disconnected or timeout.
   Can send in multiple chunks if length is large, and actual reflects how much sent. */
extern void net_send(SOCKET *socket, const byte *ptr, size_t length, NF nf, void *nfp);

/* On input, state must be SS_ESTABLISHED.
   On output, state will change to SS_ERROR if disconnected or timeout.
   actual is set to the actual number of bytes received (0<actual<=length), or 0 if SS_ERROR. */
extern void net_recv(SOCKET *socket, byte *ptr, size_t length, NF nf, void *nfp);

#endif
