
#include "tcpclient.h"

#if (CLIENT_NUM > 0)

#include "socket.h"
#include "inout.h"
#include "console.h"
#include "delay.h"
#include "trigger.h"

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

int g_clinetLinksta;	// 物理层连接状态
int g_clinetLinkCount;	// 物理层连接断开计数器


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

SocketCtrl g_clientSocket[CLIENT_NUM] = 
{
	{TCP_CLIENT, STA_INIT, TCP_CLIENT_SN_BEG+0, TCP_CLIENT_LOCAL_IP, TCP_CLIENT_LOCAL_PORT_BEG+0, TCP_CLIENT_REMOTE_IP_BEG+TCP_CLIENT_REMOTE_IP_ADD*0, TCP_CLIENT_REMOTE_PORT_BEG},
#if (CLIENT_NUM > 1)
	{TCP_CLIENT, STA_INIT, TCP_CLIENT_SN_BEG+1, TCP_CLIENT_LOCAL_IP, TCP_CLIENT_LOCAL_PORT_BEG+1, TCP_CLIENT_REMOTE_IP_BEG+TCP_CLIENT_REMOTE_IP_ADD*1, TCP_CLIENT_REMOTE_PORT_BEG},
#endif
#if (CLIENT_NUM > 2)
	{TCP_CLIENT, STA_INIT, TCP_CLIENT_SN_BEG+2, TCP_CLIENT_LOCAL_IP, TCP_CLIENT_LOCAL_PORT_BEG+2, TCP_CLIENT_REMOTE_IP_BEG+TCP_CLIENT_REMOTE_IP_ADD*2, TCP_CLIENT_REMOTE_PORT_BEG},
#endif
#if (CLIENT_NUM > 3)
	{TCP_CLIENT, STA_INIT, TCP_CLIENT_SN_BEG+3, TCP_CLIENT_LOCAL_IP, TCP_CLIENT_LOCAL_PORT_BEG+3, TCP_CLIENT_REMOTE_IP_BEG+TCP_CLIENT_REMOTE_IP_ADD*3, TCP_CLIENT_REMOTE_PORT_BEG},
#endif
#if (CLIENT_NUM > 4)
	{TCP_CLIENT, STA_INIT, TCP_CLIENT_SN_BEG+4, TCP_CLIENT_LOCAL_IP, TCP_CLIENT_LOCAL_PORT_BEG+4, TCP_CLIENT_REMOTE_IP_BEG+TCP_CLIENT_REMOTE_IP_ADD*4, TCP_CLIENT_REMOTE_PORT_BEG},
#endif
#if (CLIENT_NUM > 5)
	{TCP_CLIENT, STA_INIT, TCP_CLIENT_SN_BEG+5, TCP_CLIENT_LOCAL_IP, TCP_CLIENT_LOCAL_PORT_BEG+5, TCP_CLIENT_REMOTE_IP_BEG+TCP_CLIENT_REMOTE_IP_ADD*5, TCP_CLIENT_REMOTE_PORT_BEG},
#endif
#if (CLIENT_NUM > 6)
	{TCP_CLIENT, STA_INIT, TCP_CLIENT_SN_BEG+6, TCP_CLIENT_LOCAL_IP, TCP_CLIENT_LOCAL_PORT_BEG+6, TCP_CLIENT_REMOTE_IP_BEG+TCP_CLIENT_REMOTE_IP_ADD*6, TCP_CLIENT_REMOTE_PORT_BEG},
#endif
#if (CLIENT_NUM > 7)
	{TCP_CLIENT, STA_INIT, TCP_CLIENT_SN_BEG+7, TCP_CLIENT_LOCAL_IP, TCP_CLIENT_LOCAL_PORT_BEG+7, TCP_CLIENT_REMOTE_IP_BEG+TCP_CLIENT_REMOTE_IP_ADD*7, TCP_CLIENT_REMOTE_PORT_BEG},
#endif
};


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

void InitTcpClient(void)
{
	int i;

	g_clinetLinksta = LINK_INIT;
	g_clinetLinkCount = 0;

	for (i = 0; i < CLIENT_NUM; i++)
	{
		g_clientSocket[i].status = STA_CLOSED;
	}

}

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

void TcpClientRun(void)
{
	int i;
	int rslt;
	u8 sn, tmp8;
	u16 port, ir;
	int crsocket;
	u16 sport;
	u32 sip;

	crsocket = 0;

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

#if (0)
	{
		u32 timer;
		timer = GetMsSoftTimer();
		printf("at%d, TcpClientRun\r\n", timer);
	}
#endif

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

	// 关闭连接
	if (g_clinetLinksta == LINK_DOWN && crsocket == 2)
	{
		printf("link down or crsocket == 2\r\n");
		for (i = 0; i < CLIENT_NUM; i++)
		{
			if (g_clientSocket[i].status != STA_CLOSED)
			{
				g_clientSocket[i].status = STA_CLOSED;
				printf("close socket %d and disconnect.\r\n", g_clientSocket[i].socket);
				disconnect(g_clientSocket[i].socket);
				close(g_clientSocket[i].socket);
			}
		}
		return;
	}

	// 创建 tcp 客户端
	for (i = 0; i < CLIENT_NUM; i++)
	{
		sn = g_clientSocket[i].socket;
		port = g_clientSocket[i].localPort;

		tmp8 = getSn_SR(sn);
		switch(tmp8)
		{
			case SOCK_ESTABLISHED:		// 建立了连接
			{
			//	printf("TCP client socket %d SOCK_ESTABLISHED\r\n", sn);

				ir = getSn_IR(sn);				// 读取中断寄存器
				if ((ir & Sn_IR_CON) != 0)
				{
					g_clientSocket[i].status = STA_CONNECT;
					getsockopt(sn, SO_DESTIP, &sip);
					getsockopt(sn, SO_DESTPORT, &sport);
					printf("TCP client socket %d is connected, destination ip=%d.%d.%d.%d, port=%d\r\n", sn,
							GETIP1(sip), GETIP2(sip), GETIP3(sip), GETIP4(sip), sport);
					setSn_IR(sn, Sn_IR_CON);	// 清除中断状态
				}
				break;
			}

			case SOCK_CLOSE_WAIT:		// 如果对方请求关闭当前连接
			{
				printf("TCP client socket %d wait close\r\n", sn);
				disconnect(sn);
				g_clientSocket[i].status = STA_CLOSED;
				break;
			}

			case SOCK_CLOSED:			// 如果是关闭状态
			{
				// 等待建立新的连接

				printf("TCP client socket %d is closed, create a new socket\r\n", sn);
				rslt = socket(sn, Sn_MR_TCP, port, SF_IO_NONBLOCK);	// 创建新连接
				if (rslt == sn)
				{
					printf("Create TCP client success at socket %d\r\n", sn);
				}
				else
				{
					printf("Create TCP client failed at socket %d, code=%d\r\n", sn, rslt);
				}
				break;
			}
			case SOCK_INIT:				// 初始化
			{
				sip = g_clientSocket[i].remoteIp;
				sport = g_clientSocket[i].remotePort;

				printf("TCP client socket %d connect to ip=%d.%d.%d.%d, port=%d\r\n", sn,
						GETIP1(sip), GETIP2(sip), GETIP3(sip), GETIP4(sip), sport);

				rslt = connect(sn, (u8*)(&sip), sport);
				if (rslt == SOCK_OK)
				{
					g_clientSocket[i].status = STA_READY;
					printf("TCP client socket %d connecting......\r\n", sn);
				}
				else
				{
				//	printf("TCP client socket %d connect error, code=%d\r\n", sn, rslt);
				}
				break;
			}
			case SOCK_LISTEN:
			{
				printf("TCP client socket %d SOCK_LISTEN\r\n", sn);
				break;
			}
			case SOCK_SYNSENT:
			{
				printf("TCP client socket %d SOCK_SYNSENT\r\n", sn);
				break;
			}
			case SOCK_SYNRECV:
			{
				printf("TCP client socket %d SOCK_SYNRECV\r\n", sn);
				break;
			}
			default:
			{
			//	printf("default, TCP client socket %d status=0x%x\r\n", sn, tmp8);
				break;
			}
		} // end of switch
	}
}


/*

void CreateTcpClient(void)
{
	int i;
	int rslt;
	u8 sn, tmp8;
	u16 port;
	for (i = 0; i < 8; i++)
	{
		if (g_clientSocket.status != STA_CLOSED)
		{
			printf("tcp clinet not closed\r\n");
			return;
		}

		sn = g_clientSocket.socket;
		port = g_clientSocket.port;
		
		tmp8 = SF_IO_NONBLOCK;
		rslt = socket(sn, Sn_MR_TCP, port, tmp8);
		if (rslt == sn)
		{
			g_clientSocket.status = STA_READY;
			printf("create tcp client success\r\n");
		}
		else
		{
			printf("create tcp client failed\r\n");
		}
	}
}

void ConnectTcpClient(void)
{
	int rslt;
	u8 sn;
	u16 port;
	u32 ipaddr;
	if (g_clientSocket.status != STA_READY)
	{
		printf("tcp clinet not ready\r\n");
		return;
	}

	sn = g_clientSocket.socket;
	ipaddr = PLC_SERVER_IP;
	port = PLC_SERVER_PORT;

	rslt = connect(sn, (u8*)(&ipaddr), port);
	if (rslt == SOCK_OK)
	{
		g_clientSocket.status = STA_CONNECT;
		printf("connect server success......\r\n");
	}
	else if (rslt == SOCKERR_SOCKNUM)
	{
		printf("Invalid socket number\r\n");
	}
	else if (rslt == SOCKERR_SOCKMODE)
	{
		printf("Invalid socket mode\r\n");
	}
	else if (rslt == SOCKERR_SOCKINIT)
	{
		printf("Socket is not initialized\r\n");
	}
	else if (rslt == SOCKERR_IPINVALID)
	{
		printf("Wrong server IP address\r\n");
	}
	else if (rslt == SOCKERR_PORTZERO)
	{
		printf("Server port zero\r\n");
	}
	else if (rslt == SOCKERR_TIMEOUT)
	{
		printf("Timeout occurred during request connection\r\n");
	}
	else // if (rslt == SOCK_BUSY)
	{
		printf("0. socket is busy\r\n");
	}
}
*/

void TestNetTrans(void)
{
	int i[8], sta[8], rslt;
	int j;
	u8 buff[MAX_TRANS_DATA];

	memset(i, 0, sizeof(int)*8);
	memset(sta, 0, sizeof(int)*8);
	memset(buff, 0x5A, MAX_TRANS_DATA);

	do
	{
		if (IsConsoleCancel() != 0)
		{
			printf("send cancel\r\n");
			break;
		}

		for (j = 0; j < CLIENT_NUM; j++)
		{
			if (g_clientSocket[j].status == STA_CONNECT)
			{
				if (sta[j] == 0)
				{
					if (i[j]%10 == 0)
					{
						printf("socket %d send data from tcp client to server %d times\r\n", g_clientSocket[j].socket, i[j]);
					}
					if (i[j]%2 == 0)
					{
						SetLedOn();
					}
					else
					{
						SetLedOff();
					}

					sta[j] = 1;
				}

				if (sta[j] == 1)
				{
					rslt = EthernetSendData(&(g_clientSocket[j]), buff, MAX_TRANS_DATA);
					if (rslt != MAX_TRANS_DATA)
					{
						continue;
					}
	//				printf("send data %d times success\r\n", i);
					sta[j] = 0;
					i[j]++;
				}
			}
		}
	}while(1);

}
#endif

SocketCtrl * GetTcpClientCtrlFromSocketId(int sIdx)
{
#if (CLIENT_NUM > 0)
	if (sIdx < CLIENT_NUM)
	{
		return &(g_clientSocket[sIdx]);
	}
	else
#endif
	{
		return NULL;
	}
}

int IsClinetConnect(int sIdx)
{
#if (CLIENT_NUM > 0)
	if (sIdx < CLIENT_NUM)
	{
		return g_clientSocket[sIdx].status;
	}
	else
#endif
	{
		return -1;
	}
}

