
#include "tcpserver.h"

#if (SERVER_NUM > 0)


// TCP server
#include "socket.h"
#include "inout.h"

//---------------------------------------------------------------

int g_linksta;		// 物理层连接状态
int g_linkCount;	// 物理层连接断开计数器

//-------------------------------------------

SocketCtrl g_serverSocket[SERVER_NUM] = 
{
	{TCP_SERVER, STA_INIT, TCP_SERVER_SN_BEG+0, TCP_SERVER_LOCAL_IP_BEG+TCP_SERVER_LOCAL_IP_ADD*0, TCP_SERVER_PORT_BEG+0, 0, 0},
#if (SERVER_NUM > 1)
	{TCP_SERVER, STA_INIT, TCP_SERVER_SN_BEG+1, TCP_SERVER_LOCAL_IP_BEG+TCP_SERVER_LOCAL_IP_ADD*1, TCP_SERVER_PORT_BEG+0, 0, 0},
#endif
#if (SERVER_NUM > 2)
	{TCP_SERVER, STA_INIT, TCP_SERVER_SN_BEG+2, TCP_SERVER_LOCAL_IP_BEG+TCP_SERVER_LOCAL_IP_ADD*2, TCP_SERVER_PORT_BEG+0, 0, 0},
#endif
#if (SERVER_NUM > 3)
	{TCP_SERVER, STA_INIT, TCP_SERVER_SN_BEG+3, TCP_SERVER_LOCAL_IP_BEG+TCP_SERVER_LOCAL_IP_ADD*3, TCP_SERVER_PORT_BEG+0, 0, 0},
#endif
#if (SERVER_NUM > 4)
	{TCP_SERVER, STA_INIT, TCP_SERVER_SN_BEG+4, TCP_SERVER_LOCAL_IP_BEG+TCP_SERVER_LOCAL_IP_ADD*4, TCP_SERVER_PORT_BEG+0, 0, 0},
#endif
#if (SERVER_NUM > 5)
	{TCP_SERVER, STA_INIT, TCP_SERVER_SN_BEG+5, TCP_SERVER_LOCAL_IP_BEG+TCP_SERVER_LOCAL_IP_ADD*5, TCP_SERVER_PORT_BEG+0, 0, 0},
#endif
#if (SERVER_NUM > 6)
	{TCP_SERVER, STA_INIT, TCP_SERVER_SN_BEG+6, TCP_SERVER_LOCAL_IP_BEG+TCP_SERVER_LOCAL_IP_ADD*6, TCP_SERVER_PORT_BEG+0, 0, 0},
#endif
#if (SERVER_NUM > 7)
	{TCP_SERVER, STA_INIT, TCP_SERVER_SN_BEG+7, TCP_SERVER_LOCAL_IP_BEG+TCP_SERVER_LOCAL_IP_ADD*7, TCP_SERVER_PORT_BEG+0, 0, 0},
#endif
};

void InitTcpServer(void)
{
	int i;
	for (i = 0; i < SERVER_NUM; i++)
	{
		g_serverSocket[i].status = STA_CLOSED;
	}

	g_linksta = LINK_INIT;
	g_linkCount = 0;
}

void SetTcpKeepAlive(void)
{
	int i;
	uint8_t alivetime = 1;
	for (i = 0; i < SERVER_NUM; i++)
	{
		setsockopt(g_serverSocket[i].socket, SO_KEEPALIVEAUTO, &alivetime);
		printf("enable socket %d auto keep alive\r\n", g_serverSocket[i].socket);
	}
}

void TcpServerRun(void)
{
	int i;
	int rslt;
	int crsocket;
	u8 sn, tmp8;
	u16 port, ir;

	crsocket = 0;

	// PHY物理层连接状态检查
	rslt = ctlwizchip(CW_GET_PHYLINK, (void*)(&tmp8));

	if (1)	// 连续读取稳定数据
	{
		int tprslt, retry;
		u8 temp;
		retry = 10;
		do
		{
			tprslt = ctlwizchip(CW_GET_PHYLINK, (void*)(&temp));
			if (rslt != tprslt)
			{
				printf("1. net link rslt = %d\r\n", tprslt);
				break;
			}
			else
			{
				if (temp != tmp8)
				{
					printf("1. net link sta = 0x%x, old=0x%x\r\n", temp, tmp8);
					break;
				}
			}
			retry--;
		}while(retry > 0);
		if (retry != 0)
		{
			return;
		}
	}

	if (rslt == -1)
	{
		g_linksta = LINK_INIT;
		printf("Unknown PHY Link stauts.\r\n");
		return;
	}
	else
	{
		if (tmp8 == PHY_LINK_ON)
		{
			if (g_linksta != LINK_UP)
			{
				crsocket = 1;				// 创建socket
				g_linksta = LINK_UP;
				printf("PHY Link UP.\r\n");
				g_linkCount = 0;
			}
		}
		else if (tmp8 == PHY_LINK_OFF)
		{
			if (g_linksta == LINK_INIT || g_linksta == LINK_UP)
			{
				if (g_linksta == LINK_INIT)
				{
					crsocket = 2;				// 关闭socket
					g_linksta = LINK_DOWN;
					printf("1. PHY Link DOWN.\r\n");
				}
				else
				{
					g_linkCount = 0;
					g_linksta = LINK_WAIT;
					printf("1. PHY Link WAIT.\r\n");
				}
			}
			else if (g_linksta == LINK_WAIT)
			{
				printf("2. PHY Link WAIT.\r\n");
				g_linkCount++;
				if (g_linkCount > 10)		// 断开超时
				{
					crsocket = 2;				// 关闭socket
					g_linksta = LINK_DOWN;
					printf("1. PHY Link DOWN.\r\n");
				}
			}
			else if (g_linksta == LINK_DOWN)
			{

			}
			else
			{
				printf("other Link sta.\r\n");
			}
		}
		else
		{
			printf("waite PHY connect.\r\n");
			return;
		}
	}

	// 关闭连接
	if (g_linksta == LINK_DOWN && crsocket == 2)
	{
		for (i = 0; i < SERVER_NUM; i++)
		{
			if (g_serverSocket[i].status != STA_CLOSED)
			{
				g_serverSocket[i].status = STA_CLOSED;
				printf("Close TCP server socket %d and disconnect.\r\n", g_serverSocket[i].socket);
				disconnect(g_serverSocket[i].socket);
				close(g_serverSocket[i].socket);
			}
		}
		return;
	}

	// tcp 服务器
	for (i = 0; i < SERVER_NUM; i++)
	{
		sn = g_serverSocket[i].socket;
		port = g_serverSocket[i].localPort;
		tmp8 = getSn_SR(sn);

		if (1)	// 连续读取稳定数据
		{
			int retry;
			u8 temp;
			retry = 10;
			do
			{
				temp = getSn_SR(sn);

				if (temp != tmp8)
				{
					printf("1. socket %d sr = 0x%x, old=0x%x\r\n", sn, temp, tmp8);
					break;
				}
				retry--;
			}while(retry > 0);
			if (retry != 0)
			{
				return;
			}
		}

		switch(tmp8)
		{
			case SOCK_ESTABLISHED:		// 建立了连接
			{
				ir = getSn_IR(sn);				// 读取中断寄存器
				if ((ir & Sn_IR_CON) != 0)
				{
					u32 ip;
					u16 port;
					g_serverSocket[i].status = STA_CONNECT;
					getsockopt(sn, SO_DESTIP, &ip);
					getsockopt(sn, SO_DESTPORT, &port);

					printf("TCP server is connected to socket %d, destination ip=%d.%d.%d.%d, port=%d\r\n", sn,
							GETIP1(ip), GETIP2(ip), GETIP3(ip), GETIP4(ip), port);
					setSn_IR(sn, Sn_IR_CON);	// 清除中断状态
				}

				if((ir & Sn_IR_CON) != 0)		// 连接
				{
				}

				if ((ir & Sn_IR_DISCON) != 0)	// 断开
				{
				}

				if ((ir & Sn_IR_RECV) != 0)		// 接收到数据
				{
				}

				if ((ir & Sn_IR_TIMEOUT) != 0)	// 超时
				{
				}

				if ((ir & Sn_IR_SENDOK) != 0)	// 发送完成
				{
				}
				break;
			}

			case SOCK_CLOSE_WAIT:		// 如果对方请求关闭当前连接
			{
				rslt = disconnect(sn);
				close(sn);

				printf("TCP server socket %d wait close, rslt=%d\r\n", sn, rslt);

			//	if (rslt == SOCK_OK)
				{
					g_serverSocket[i].status = STA_CLOSED;
				}
				break;
			}

			case SOCK_CLOSED:			// 如果是关闭状态
			{
				printf("TCP server socket %d is closed, create a new socket\r\n", sn);
				rslt = socket(sn, Sn_MR_TCP, port, SF_IO_NONBLOCK|0);					// 创建新连接	SF_TCP_NODELAY
				if(rslt == sn)
				{
					printf("TCP server socket %d create success\r\n", sn);
				}
				else
				{
					printf("Create TCP server socket %d failed, code=%d\r\n", sn, rslt);
					if (rslt == SOCKERR_SOCKINIT)
					{
						printf("Re Init Network\r\n");
						InitNetConfig();			// 重启芯片并重新配置
					}
				}
				break;
			}

			case SOCK_INIT:				// 初始化
			{
				rslt = listen(sn);
				if (rslt == SOCK_OK)
				{
					g_serverSocket[i].status = STA_READY;
					printf("TCP server socket %d Listening......\r\n\tserver ip= %d.%d.%d.%d, port=%d\r\n", \
						sn, g_netInfo.ip[0],g_netInfo.ip[1],g_netInfo.ip[2],g_netInfo.ip[3], port);
				}
				else
				{
					printf("TCP server socket %d Listen error, code=%d\r\n", sn, rslt);
				}
				break;
			}
			case SOCK_LISTEN:
			{
				break;
			}
			default:
			{
/*
				SOCK_SYNSENT		0x15
				SOCK_SYNRECV		0x16
				SOCK_ESTABLISHED	0x17
				SOCK_FIN_WAIT		0x18
				SOCK_CLOSING		0x1A
				SOCK_TIME_WAIT		0x1B
				SOCK_CLOSE_WAIT		0x1C
				SOCK_LAST_ACK		0x1D
				SOCK_UDP			0x22
				SOCK_MACRAW			0x42
 */
				if (tmp8 != 0)
				{
					printf("TCP server default, getSn_SR=0x%x\r\n", tmp8);
				}
				break;
			}
		} // end of switch
	}
}

SocketCtrl * GetTcpServerCtrlFromSocketId(int sIdx)
{
	if (sIdx < SERVER_NUM)
	{
		return &(g_serverSocket[sIdx]);
	}
	else
	{
		return NULL;
	}
}

#if (0)

void TcpServerGetData(void)
{
	int i;
	int len, rslt, expt;
	u8 buff[MAX_TRANS_DATA];

	for (i = 0; i < SERVER_NUM; i++)
	{
		len = EthernetGetRsLen(&(g_serverSocket[i]));
		if (len != 0)
		{
			printf("receive data from socket%d, len=%d\r\n", g_serverSocket[i].socket, len);
		}

		while (len != 0)
		{
			if (len > MAX_TRANS_DATA)
			{
				expt = MAX_TRANS_DATA;
			}
			else
			{
				expt = len;
			}
			rslt = EthernetGetData(&(g_serverSocket[i]), buff, expt);

			if (rslt == expt)
			{
				len -= expt;
			}
			else
			{
				printf("receive data error\r\n");
			}
		}
	}

}

#endif

#endif
