/*
 * net.h
 *
 * Copyright 2004, Minoru Murashima. All rights reserved.
 * Distributed under the terms of the BSD License.
 *
 * ネットワーク共通ヘッダ。
 */


#ifndef net_h
#define net_h


#include<types.h>
#include<proc.h>
#include<fs.h>
#include<mm.h>
#include<sys/ip.h>
#include<sys/socket.h>
#include<netinet/in.h>


#ifndef ASM_FILE


enum{
	/* コネクション状態。 */
	SOCK_CNCT_ON			= 1<<0,	/* コネクション済み。 */
	SOCK_CNCT_TRANS_FIN		= 1<<1,	/* コネクション終了送信。 */
	SOCK_CNCT_RECV_FINACK	= 1<<2,	/* コネクション終了応答受信。 */
	SOCK_CNCT_RECV_FIN		= 1<<3,	/* コネクション相手方終了受信。 */
	SOCK_LISTEN				= 1<<4,	/* リッスン待ち開始。 */
	SOCK_DISCON_RECV		= 1<<5,	/* 受信コネクション切断。 */
	SOCK_DISCON_SEND		= 1<<6,	/* 送信コネクション切断。 */
	SOCK_LINK_ON			= 1<<7,	/* ソケットリンク済み。 */
};


typedef struct mbuf{
	char  *data[3];		/* 送信フレームアドレス。 */
	int    size[3];		/* データフレームサイズ。 */
	ushort type;		/* フレームタイプ。 */
	uchar  ipType;		/* IPプロトコルタイプ。 */
}TRANS_BUF_INFO;

// ソケットオプション
typedef struct{
	int	name;
}SOCK_OPT;

// IPオプション
typedef struct{
	int name;
	int value;
}IP_OPT;

// 送信バッファ
// バッファサイズはコネクション先の送信セグメント最大サイズに同じ
typedef struct{
	int curLen;	// 現在の保存サイズ
	char *buf;	// 
}SEND_BUF;

/*
 * Note!
 *  fsとscの位置は仮想ファイル構造体の位置とリンクしているので注意。
 */
typedef struct SOCKET{
	F_DSC			 fd;			// ファイルディスクリプタ構造体。
	FS				*fs;			// FS構造体アドレス。
	struct SOCKET	*sc;			// ソケットアドレス、VENTRY構造体のinodeに対応する。
	uint16_t		 sockType;		// ソケットタイプ。
	uint16_t		 stat;			// コネクション状態。
	void			*sinf;			// SOCKET_INFO.
	in_port_t		 srcport;		// Source port number.
	in_port_t		 dstport;		// Connection port number.
	in_addr_t		 dstip;			// Connection IP address.
	in_addr_t		 srcip;			// Local host IP address.
	void			*recvBuf;		// Receive buffer address.
	PROC			*waitProc;		// Interrupt wait queue.
	uint32_t		 seqnum;		// Sequence number.
	uint32_t		 acknum;		// Ack number.
	uint32_t		 prevAck;		// send()でデータを受信したとき応答番号を記憶しておく
	struct SOCKET	*next;			// コネクションリンク。
	struct SOCKET	*prev;			// 　　　〃　　　　　　
	struct SOCKET	*waitNext;		// コネクト切断処理待ちリンク。
	uint			 waitTime;		// 切断処理待ち開始時間ms。
	uint16_t		 mss;			// コネクション先の送信セグメント最大サイズ。
	uint16_t		 window;		// コネクション先ウィンドウサイズ。
	SEND_BUF		 sendBuf;		// 送信バッファ構造体
	void			*ringBuf;		// 送信データ一時保存用リングバッファ
	PROC			*listenThread;	// リッスンスレッド
	struct SOCKET	*newsc_next;	// リッスンコネクション済ソケットリンク
	int				 lockGate;		// スピンロックゲート
	SOCK_OPT		 sockOpt;		// ソケットオプション
	IP_OPT			 ipOpt;			// IPオプション
}SOCKET;

typedef struct{
	int (*send)(SOCKET*, void*, size_t, int, struct sockaddr*);
	int (*recv)(SOCKET*, struct msghdr*);
	int (*connect)(SOCKET*);
	int (*shutdown)(SOCKET*, int);
	int (*listen)(SOCKET*, int);
	int (*accept)(SOCKET*, SOCKET**, uint32_t*);
	int (*poll)(SOCKET*);
}SOCKET_INFO;


extern inline uint16_t swapWord(ushort value)
{
	return (value>>8)+(value<<8);
}

extern inline uint32_t swapInt32(uint32_t value)
{
	return (value>>24)+((value>>8)&0xff00)+((value<<8)&0xff0000)+(value<<24);
}

extern ushort getEphemeralPort();
extern void closeSocket(SOCKET*);
extern int makeSocket(int,int,SOCKET**);
extern int sys_socket();
extern int sys_send();
extern int sys_sendmsg();
extern int sys_recv();
extern int sys_recvmsg();
extern int sys_connect();
extern int sys_shutdown();
extern int sys_bind();
extern int sys_listen();
extern int sys_accept();
extern int sys_getsockname();
extern int sys_getpeername();
extern int sys_getsockopt();
extern int sys_setsockopt();
extern int registSocket(SOCKET_INFO*,int);
extern int initNet();


#endif


#endif
