/* * * * * * * * * */ #include "bsp.h" #include "utils.h" #include "usart.h" #include "w5500.h" #include "socket.h" #include "tcpserver.h" #include "configprotocal.h" /*========================================================================================*/ // #define SOCK_IDLE 0x00 #define SOCK_OPENED 0x01 #define SOCK_INITIALLIZED 0x02 #define SOCK_CONNECTTED 0x04 #define SOCK_RECEIVED 0x08 #define SOCK_TRANSMITOK 0x10 #define TX_BUF_THRESHHOLD 1200 #define SVR_MSG_POOL_COUNT 8 typedef struct _msg_pool_{ uint8_t status; uint8_t index; uint8_t tail; uint8_t count; stSockBuffer msgSlots[SVR_MSG_POOL_COUNT]; }stServerMessagePool; #define SVR_MSG_BUF_SIZE (W5500BUFLEN*8) #if SVR_MSG_BUF_SIZE>65500 #error "TCP server: SVR_MSG_BUF_SIZE is too large!!!" #endif typedef struct _msg_buffer_{ uint16_t head; uint16_t tail; uint16_t count; uint16_t status; uint8_t messageBuffer[SVR_MSG_BUF_SIZE]; }stServerMessageBuffer; /*========================================================================================*/ stEthernetConfig ethConfig = { .state=2, .extMode=0, .mac={0x00,0x08,0xdc,0x11,0x11,0x11}, .lip={192,168,3,150}, .sub={255,255,255,0}, .gw={192,168,3,1}, .dns={8,8,8,8}, }; const stEthernetConfig defaultEthConfig ={ .state=2, .extMode=0, .mac={0x00,0x08,0xdc,0x11,0x11,0x11}, .lip={192,168,3,150}, .sub={255,255,255,0}, .gw={192,168,3,1}, .dns={8,8,8,8}, }; stServerAddress ethServer={ .sip = {192,168,3,100}, .port = 31000, }; stServerAddress ethDbgServer={ .sip = {192,168,100,200}, .port = 32000, }; const stServerAddress defaultEthServer ={ .sip = {192,168,3,100}, .port = 31000, }; volatile uint32_t W5500_Interrupt=0; /*========================================================================================*/ static const uint8_t txsize[MAX_SOCK_NUM] = {2,2,2,2,2,2,2,2}; static const uint8_t rxsize[MAX_SOCK_NUM] = {2,2,2,2,2,2,2,2}; static stSockBuffer recvBuf = {0}; static stSockBuffer sendBuf = {0}; stServerMessageBuffer msgBuf ={0}; static volatile uint32_t Sock0_state[MAX_SOCK_NUM] = {0}; static const SOCKET sock = 0; static const SOCKET sockDbg = 1; char sockDelayFlag = 1; char sockDbgDelayFlag = 1; uint32_t sockDelay = 2*10; uint32_t sockDbgDelay = 2*10; static volatile uint32_t local_port = 31000; static volatile uint32_t local_portDbg = 31000; //static uint8_t debugTcpMsg[128]={0}; int SendDataToTCP(uint32_t flush); /*========================================================================================*/ void set_network(void) { uint8_t ip[4]={0}; uint8_t ver = getVersion(); sprintf((char*)recvBuf.buffer,"Version : %d\r\n", ver); DebugMessage(recvBuf.buffer); setSHAR(ethConfig.mac); setSUBR(ethConfig.sub); setGAR(ethConfig.gw); setSIPR(ethConfig.lip); sysinit(txsize, rxsize); if(ethConfig.state == ETHNET_TCP_CLIENT) { setRTR(4000); setRCR(5); } else { setRTR(50); setRCR(2); } getSIPR (ip); sprintf((char*)recvBuf.buffer,"IP: %d.%d.%d.%d\r\n", ip[0],ip[1],ip[2],ip[3]); DebugMessage(recvBuf.buffer); getSUBR(ip); sprintf((char*)recvBuf.buffer,"SN: %d.%d.%d.%d\r\n", ip[0],ip[1],ip[2],ip[3]); DebugMessage(recvBuf.buffer); getGAR(ip); sprintf((char*)recvBuf.buffer,"GW: %d.%d.%d.%d\r\n", ip[0],ip[1],ip[2],ip[3]); DebugMessage(recvBuf.buffer); if (ethConfig.state == ETHNET_UDP_CLIENT) { sprintf((char*)recvBuf.buffer,"ETH MODE: UDP\r\n"); DebugMessage(recvBuf.buffer); } else if (ethConfig.state == ETHNET_TCP_CLIENT) { sprintf((char*)recvBuf.buffer,"ETH MODE: TCP\r\n"); DebugMessage(recvBuf.buffer); } } void set_int(void) { uint8_t ch; setIR(IR_CONFLICT | IR_UNREACH); setIMR(IR_CONFLICT | IR_UNREACH); setSIR(SIR_SOCKALL); setSIMR(SIR_SOCKALL); for(ch=0;ch 0) { recv(sock,recvBuf.buffer,len); recvBuf.len += len; //sprintf(debugTcpMsg, "%s\r\n",recvBuf.buffer); //DebugMessage(debugTcpMsg); //send(sock,buffer,len); } Sock0_state[sock] &= ~SOCK_RECEIVED; } } } #ifdef W5500_INT_MODE int SendMessage(uint8_t* buf,int len) { uint32_t state = Sock0_state[sock] & SOCK_CONNECTTED;//(SOCK_OPENED | SOCK_INITIALLIZED); if(!state) { return -1; } state=Sock0_state[sock] & SOCK_TRANSMITOK; //if(sendBuf.index == 0) if(state == 0) { Sock0_state[sock] |= SOCK_TRANSMITOK;//Start memcpy(sendBuf.buffer, buf, len); sendBuf.index = len; send(sock, sendBuf.buffer, len); return len; } return 0; } int SendMessageDbg(uint8_t* buf,int len) { uint32_t state = Sock0_state[sockDbg] & SOCK_CONNECTTED;//(SOCK_OPENED | SOCK_INITIALLIZED); if(!state) { return -1; } state=Sock0_state[sockDbg] & SOCK_TRANSMITOK; //if(sendBuf.index == 0) if(state == 0) { Sock0_state[sockDbg] |= SOCK_TRANSMITOK;//Start memcpy(sendBuf.buffer, buf, len); sendBuf.index = len; send(sockDbg, sendBuf.buffer, len); return len; } return 0; } typedef struct _retry_record{ uint16_t connectRetry; uint16_t connectRetryCount; uint32_t lastConnectTryTime; }stConnectRetryRecord; stConnectRetryRecord retryRecord={0}; void Run_Client(uint32_t tick) { uint32_t len = 0; if(Sock0_state[sock] == SOCK_IDLE) { if(retryRecord.connectRetry) { len = HAL_GetTick(); if(len < retryRecord.lastConnectTryTime ) { retryRecord.lastConnectTryTime = len; } if(len - retryRecord.lastConnectTryTime < 5000) { return; } } else { local_port++; if(local_port<10000 || local_port > 65000) local_port=10000; } len = socket(sock,Sn_MR_TCP,local_port,Sn_MR_ND);//Open socket0 port if(len==1) { Sock0_state[sock] |= SOCK_OPENED; DebugMessage("open Sock!\r\n"); } } if((Sock0_state[sock] & SOCK_OPENED) && !(Sock0_state[sock] & SOCK_INITIALLIZED)) { len = connect(sock, ethServer.sip ,ethServer.port);//In tcp mode, send the connect request to server if(len==1) { Sock0_state[sock] |= SOCK_INITIALLIZED; DebugMessage("Init Sock!\r\n"); memset(&sendBuf,0,sizeof(stSockBuffer)); memset(&recvBuf,0,sizeof(stSockBuffer)); memset(&retryRecord,0,sizeof(stConnectRetryRecord)); } else if(len == 0xff) { Sock0_state[sock] = SOCK_IDLE; retryRecord.lastConnectTryTime = HAL_GetTick(); retryRecord.connectRetry=1; retryRecord.connectRetryCount++; //len = getSn_SR(sock); sprintf((char*)recvBuf.buffer, "Close sock 111: %d\r\n",len); DebugMessage(recvBuf.buffer); } } else if(Sock0_state[sock] & (SOCK_OPENED | SOCK_INITIALLIZED)) { // if(Sock0_state[sock] & SOCK_TRANSMITOK) // { // Sock0_state[sock] &= ~SOCK_TRANSMITOK; // //DebugMessage("Send ok!\r\n"); // sendBuf.index = 0; // } if(Sock0_state[sock] & SOCK_RECEIVED) { len = getSn_RX_RSR(sock); if(len > 0) { recv(sock,recvBuf.buffer,len); //send(sock,recvBuf.buffer,len); //SendMessage(recvBuf.buffer,len); //DebugMessage("Recv ok!\r\n"); } Sock0_state[sock] &= ~SOCK_RECEIVED; } len = getSn_SR(sock); if(SOCK_SYNSENT > len || SOCK_ESTABLISHED < len) { setSn_CR(sock, Sn_CR_CLOSE); Sock0_state[sock] = SOCK_IDLE; sprintf((char*)recvBuf.buffer, "Close sock 222: %d\r\n",len); DebugMessage(recvBuf.buffer); } } } void Run_ClientDbg(uint32_t tick) { uint32_t len = 0; if(Sock0_state[sockDbg] == SOCK_IDLE) { if(retryRecord.connectRetry) { len = HAL_GetTick(); if(len < retryRecord.lastConnectTryTime ) { retryRecord.lastConnectTryTime = len; } if(len - retryRecord.lastConnectTryTime < 5000) { return; } } else { local_portDbg++; if(local_portDbg<10000 || local_portDbg > 65000) local_portDbg=10000; } len = socket(sockDbg,Sn_MR_TCP,local_portDbg,Sn_MR_ND);//Open socket0 port if(len==1) { Sock0_state[sockDbg] |= SOCK_OPENED; DebugMessage("open Sock!\r\n"); } } if((Sock0_state[sockDbg] & SOCK_OPENED) && !(Sock0_state[sockDbg] & SOCK_INITIALLIZED)) { len = connect(sockDbg, ethServer.sip ,ethServer.port);//In tcp mode, send the connect request to server if(len==1) { Sock0_state[sockDbg] |= SOCK_INITIALLIZED; DebugMessage("Init Sock!\r\n"); memset(&sendBuf,0,sizeof(stSockBuffer)); memset(&recvBuf,0,sizeof(stSockBuffer)); memset(&retryRecord,0,sizeof(stConnectRetryRecord)); } else if(len == 0xff) { Sock0_state[sockDbg] = SOCK_IDLE; retryRecord.lastConnectTryTime = HAL_GetTick(); retryRecord.connectRetry=1; retryRecord.connectRetryCount++; //len = getSn_SR(sock); sprintf((char*)recvBuf.buffer, "Close sock 111: %d\r\n",len); DebugMessage(recvBuf.buffer); } } else if(Sock0_state[sockDbg] & (SOCK_OPENED | SOCK_INITIALLIZED)) { // if(Sock0_state[sock] & SOCK_TRANSMITOK) // { // Sock0_state[sock] &= ~SOCK_TRANSMITOK; // //DebugMessage("Send ok!\r\n"); // sendBuf.index = 0; // } if(Sock0_state[sockDbg] & SOCK_RECEIVED) { len = getSn_RX_RSR(sockDbg); if(len > 0) { recv(sockDbg,recvBuf.buffer,len); //send(sock,recvBuf.buffer,len); //SendMessage(recvBuf.buffer,len); //DebugMessage("Recv ok!\r\n"); } Sock0_state[sockDbg] &= ~SOCK_RECEIVED; } len = getSn_SR(sockDbg); if(SOCK_SYNSENT > len || SOCK_ESTABLISHED < len) { setSn_CR(sockDbg, Sn_CR_CLOSE); Sock0_state[sockDbg] = SOCK_IDLE; sprintf((char*)recvBuf.buffer, "Close sock 222: %d\r\n",len); DebugMessage(recvBuf.buffer); } } } /*******************************************************************************/ void W5500_Interrupt_Process(void) { unsigned char status,sockstatus; IntDispose: W5500_Interrupt = 0; status = getIR(); clearIR(status & IR_ALL); if((status & IR_CONFLICT) == IR_CONFLICT) { ; } if((status & IR_UNREACH) == IR_UNREACH) { ; } status = getSIR(); if((status & SIR_SOCK0) == SIR_SOCK0)//Socket0 { sockstatus = getSn_IR(sock); setSn_IR(sock,sockstatus);//Write 1 to clear the interrupt flag if(sockstatus & Sn_IR_CON) { Sock0_state[sock] |= SOCK_CONNECTTED; } if(sockstatus & Sn_IR_DISCON) { setSn_CR(sock, Sn_CR_CLOSE); //Socket_Init(0); Sock0_state[sock] = SOCK_IDLE; } if(sockstatus & Sn_IR_SEND_OK) { //Sock0_state[sock] |= SOCK_TRANSMITOK; Sock0_state[sock] &= ~SOCK_TRANSMITOK; } if(sockstatus & Sn_IR_RECV) { Sock0_state[sock] |= SOCK_RECEIVED; } if(sockstatus & Sn_IR_TIMEOUT) { setSn_CR(sock,Sn_CR_CLOSE); Sock0_state[sock] = SOCK_IDLE; } } if(getSIR() != 0) goto IntDispose; } void W5500_Interrupt_ProcessDbg(void) { unsigned char status,sockstatus; IntDispose: W5500_Interrupt = 0; status = getIR(); clearIR(status & IR_ALL); if((status & IR_CONFLICT) == IR_CONFLICT) { ; } if((status & IR_UNREACH) == IR_UNREACH) { ; } status = getSIR(); if((status & SIR_SOCK0) == SIR_SOCK0)//Socket0 { sockstatus = getSn_IR(sockDbg); setSn_IR(sockDbg,sockstatus);//Write 1 to clear the interrupt flag if(sockstatus & Sn_IR_CON) { Sock0_state[sockDbg] |= SOCK_CONNECTTED; } if(sockstatus & Sn_IR_DISCON) { setSn_CR(sockDbg, Sn_CR_CLOSE); //Socket_Init(0); Sock0_state[sockDbg] = SOCK_IDLE; } if(sockstatus & Sn_IR_SEND_OK) { //Sock0_state[sock] |= SOCK_TRANSMITOK; Sock0_state[sockDbg] &= ~SOCK_TRANSMITOK; } if(sockstatus & Sn_IR_RECV) { Sock0_state[sockDbg] |= SOCK_RECEIVED; } if(sockstatus & Sn_IR_TIMEOUT) { setSn_CR(sockDbg,Sn_CR_CLOSE); Sock0_state[sockDbg] = SOCK_IDLE; } } if(getSIR() != 0) goto IntDispose; } #else void Run_Client(uint32_t tick) { if (ethConfig.state==ETHNET_CLOSED) { return; } int32_t len = 0; int32_t retval = 0; uint32_t retlen = 0; uint8_t remoteIp[4]={0}; uint16_t remote_port =0; uint32_t status = getSn_SR(sock); if (sockDelayFlag == 1) { if (tick - sockDelay >= 10 * 1000) { sockDelayFlag = 0; } else { return; } } if (status == SOCK_SYNSENT || status == SOCK_INIT) { if (sockDelayFlag == 2) { if (tick - sockDelay >= 1500) { sockDelayFlag = 1; sockDelay = tick; return; } } } //sprintf((char*)recvBuf.buffer,"SockDelay, status=%x\r\n", status); //DebugMessage(recvBuf.buffer); switch(status)//Get socket0 status { case SOCK_INIT://socket initiallize //Delay_s(10); if (sockDelayFlag <= 0) { len = connect(sock, ethServer.sip ,ethServer.port);// send connect request to tcp server sockDelayFlag = 2; sockDelay = tick; } break; case SOCK_LISTEN: case SOCK_SYNSENT: case SOCK_SYNRECV: break; case SOCK_ESTABLISHED://socket connection established //Socket n interrupt register mask; status = getSn_IR(sock); if(status & Sn_IR_CON) //TCP CON interrupt = connection with peer is successful { setSn_IR(sock, Sn_IR_CON); // this interrupt should be write the bit cleared to '1' } if(status & Sn_IR_SEND_OK) { setSn_IR(sock, Sn_IR_SEND_OK); } if(status & Sn_IR_TIMEOUT) { setSn_IR(sock, Sn_IR_TIMEOUT); } if(status & Sn_IR_DISCON) { setSn_IR(sock, Sn_IR_DISCON); } //if(status & Sn_IR_RECV) { //setSn_IR(sock, Sn_IR_RECV); len = getSn_RX_RSR(sock);// get received data length if(len > 0) { len = recv(sock,recvBuf.buffer,len);//receive data in W5500 from server retval = DataPackageHeadHandler(recvBuf.buffer,len); if(0 < retval) { retval = DataPackageCompleteHandler(recvBuf.buffer, len, sendBuf.buffer, &retlen); if(0 < retval || retlen > 0) { status = send(sock, sendBuf.buffer, retlen); } } } } break; case SOCK_CLOSE_WAIT://socket waiting for close close(sock); break; case SOCK_FIN_WAIT: case SOCK_CLOSING: case SOCK_TIME_WAIT: case SOCK_LAST_ACK: break; case SOCK_CLOSED://socket is closed if(local_port < 10000 || local_port > 65000) local_port=10000; if(ethConfig.state == ETHNET_TCP_CLIENT ) { socket(sock,Sn_MR_TCP,local_port++,Sn_MR_ND);//open another socket } else { socket(sock,Sn_MR_UDP,local_port++,0);//open another socket } break; case SOCK_UDP: status = getSn_IR(sock); if(status & Sn_IR_RECV) { setSn_IR(sock, Sn_IR_RECV); // Sn_IR } if(status & Sn_IR_SEND_OK) { setSn_IR(sock, Sn_IR_SEND_OK); } len = getSn_RX_RSR(sock);// get received data length if(len > 0) { len = recvfrom(sock, recvBuf.buffer, len, remoteIp, &remote_port); retval = DataPackageHeadHandler(recvBuf.buffer,len); if(0 < retval) { retval = DataPackageCompleteHandler(recvBuf.buffer, len, sendBuf.buffer, &retlen); if(0 < retval || retlen > 0) { status = sendto(sock, sendBuf.buffer, retlen,ethServer.sip ,ethServer.port); } } } break; default: //sprintf((char*)recvBuf.buffer,"W5500 status: 0x%x\r\n", status); //DebugMessage(recvBuf.buffer); break; } } void Run_ClientDbg(uint32_t tick) { if (!(ethConfig.extMode & ETHNET_EXT_DBG)) { return; } //return; if (sockDbgDelayFlag >= 2) { if (tick - sockDbgDelay >= 10 * 1000) { sockDbgDelayFlag = 0; } else { return; } } //return; int32_t len = 0; int32_t retval = 0; uint32_t retlen = 0; uint8_t remoteIp[4]={0}; uint16_t remote_port =0; uint32_t status = getSn_SR(sockDbg); if (sockDbgDelayFlag == 1) { if (tick - sockDbgDelay >= 10 * 1000) { sockDbgDelayFlag = 0; } else { return; } } if (status == SOCK_SYNSENT || status == SOCK_INIT) { if (sockDbgDelayFlag == 2) { if (tick - sockDbgDelay >= 1500) { sockDbgDelayFlag = 1; sockDbgDelay = tick; return; } } } //sprintf((char*)recvBuf.buffer,"SockDelay, status=%x\r\n", status); //DebugMessage(recvBuf.buffer); // sprintf((char*)recvBuf.buffer,"SockDbgDelay <= 0, status=%x\r\n", status); // DebugMessage(recvBuf.buffer); switch(status)//Get socket0 status { case SOCK_INIT://socket initiallize //Delay_s(10); if (sockDbgDelayFlag <= 0) { len = connect(sockDbg, ethDbgServer.sip ,ethDbgServer.port);// send connect request to tcp server sockDbgDelayFlag = 2; sockDbgDelay = tick; } else { //sockDbgDelay = tick; // delay 10s, 0.5s * 2 * 10 = 10s //sprintf((char*)recvBuf.buffer,"SockDbgDelay Set Value=%d\r\n", sockDbgDelay); //DebugMessage(recvBuf.buffer); } break; case SOCK_LISTEN: case SOCK_SYNSENT: case SOCK_SYNRECV: break; case SOCK_ESTABLISHED://socket connection established //Socket n interrupt register mask; status = getSn_IR(sockDbg); if(status & Sn_IR_CON) //TCP CON interrupt = connection with peer is successful { setSn_IR(sockDbg, Sn_IR_CON); // this interrupt should be write the bit cleared to '1' } if(status & Sn_IR_SEND_OK) { setSn_IR(sockDbg, Sn_IR_SEND_OK); } if(status & Sn_IR_TIMEOUT) { setSn_IR(sockDbg, Sn_IR_TIMEOUT); } if(status & Sn_IR_DISCON) { setSn_IR(sockDbg, Sn_IR_DISCON); } //if(status & Sn_IR_RECV) { //setSn_IR(sock, Sn_IR_RECV); len = getSn_RX_RSR(sockDbg);// get received data length if(len > 0) { len = recv(sockDbg,recvBuf.buffer,len);//receive data in W5500 from server retval = DataPackageHeadHandler(recvBuf.buffer,len); if(0 < retval) { retval = DataPackageCompleteHandler(recvBuf.buffer, len, sendBuf.buffer, &retlen); if(0 < retval || retlen > 0) { status = send(sockDbg, sendBuf.buffer, retlen); } } } } break; case SOCK_CLOSE_WAIT://socket waiting for close close(sockDbg); break; case SOCK_FIN_WAIT: case SOCK_CLOSING: case SOCK_TIME_WAIT: case SOCK_LAST_ACK: break; case SOCK_CLOSED://socket is closed if(local_portDbg < 10000 || local_portDbg > 65000) local_portDbg=10000; if(ethConfig.state == ETHNET_TCP_CLIENT ) { socket(sockDbg,Sn_MR_TCP,local_portDbg++,Sn_MR_ND);//open another socket } else { socket(sockDbg,Sn_MR_UDP,local_portDbg++,0);//open another socket } break; case SOCK_UDP: status = getSn_IR(sockDbg); if(status & Sn_IR_RECV) { setSn_IR(sockDbg, Sn_IR_RECV); // Sn_IR } if(status & Sn_IR_SEND_OK) { setSn_IR(sockDbg, Sn_IR_SEND_OK); } len = getSn_RX_RSR(sockDbg);// get received data length if(len > 0) { len = recvfrom(sockDbg, recvBuf.buffer, len, remoteIp, &remote_port); retval = DataPackageHeadHandler(recvBuf.buffer,len); if(0 < retval) { retval = DataPackageCompleteHandler(recvBuf.buffer, len, sendBuf.buffer, &retlen); if(0 < retval || retlen > 0) { status = sendto(sockDbg, sendBuf.buffer, retlen, ethDbgServer.sip ,ethDbgServer.port); } } } break; default: //sprintf((char*)recvBuf.buffer,"W5500 status: 0x%x\r\n", status); //DebugMessage(recvBuf.buffer); break; } } extern void InformRunLed(int32_t status); int SendMessage(uint8_t* buf,int len) { if(ethConfig.state==ETHNET_CLOSED) { InformRunLed(0); return 0; } uint32_t status = getSn_SR(sock); if((ethConfig.state == ETHNET_TCP_CLIENT && status != SOCK_ESTABLISHED) || (ethConfig.state == ETHNET_UDP_CLIENT && status != SOCK_UDP)) { InformRunLed(-1); return -1; } memcpy(sendBuf.buffer, buf, len); sendBuf.index = len; if(ethConfig.state == ETHNET_TCP_CLIENT ) { status = send(sock, sendBuf.buffer, len); } else { status = sendto(sock, sendBuf.buffer, len, ethServer.sip, ethServer.port); } InformRunLed(status); return status; } int SendMessageDbg(uint8_t* buf,int len) { if (!(ethConfig.extMode & ETHNET_EXT_DBG)) { return -1; } uint32_t status = getSn_SR(sockDbg); if((ethConfig.state == ETHNET_TCP_CLIENT && status != SOCK_ESTABLISHED) || (ethConfig.state == ETHNET_UDP_CLIENT && status != SOCK_UDP)) { InformRunLed(-1); return -1; } memcpy(sendBuf.buffer, buf, len); sendBuf.index = len; if(ethConfig.state == ETHNET_TCP_CLIENT ) { status = send(sockDbg, sendBuf.buffer, len); } else { status = sendto(sockDbg, sendBuf.buffer, len, ethDbgServer.sip, ethDbgServer.port); } InformRunLed(status); return status; } void W5500_Interrupt_Process(void) { } #endif /*******************************************************************************/