error_t socketSendTo(Socket *socket, const IpAddr *destIpAddr, uint16_t destPort, const void *data, size_t length, size_t *written, uint_t flags) { error_t error; //No data has been transmitted yet if(written) *written = 0; //Make sure the socket handle is valid if(!socket) return ERROR_INVALID_PARAMETER; #if (TCP_SUPPORT == ENABLED) //Connection-oriented socket? if(socket->type == SOCKET_TYPE_STREAM) { //Enter critical section osAcquireMutex(&socketMutex); //For connection-oriented sockets, target address is ignored error = tcpSend(socket, data, length, written, flags); //Leave critical section osReleaseMutex(&socketMutex); } else #endif #if (UDP_SUPPORT == ENABLED) //Connectionless socket? if(socket->type == SOCKET_TYPE_DGRAM) { //Send UDP datagram error = udpSendDatagram(socket, destIpAddr, destPort, data, length, written); } else #endif #if (RAW_SOCKET_SUPPORT == ENABLED) //Raw socket? if(socket->type == SOCKET_TYPE_RAW_IP) { //Send a raw IP packet error = rawSocketSendIpPacket(socket, destIpAddr, data, length, written); } else if(socket->type == SOCKET_TYPE_RAW_ETH) { //Send a raw Ethernet packet error = rawSocketSendEthPacket(socket, data, length, written); } else #endif //Socket type not supported... { //Invalid socket type error = ERROR_INVALID_SOCKET; } //Return status code return error; }
void procPerMessage::telnetSend(int protocol_id, Message* msg) { //Add header and send telnetHeader *header = new telnetHeader; header->hlp = protocol_id; header->m_size = msg->msgLen(); msg->msgAddHdr((char *)header, sizeof(telnetHeader)); tcpSend(TELNET_ID, msg); delete header; }
void procPerMessage::ftpSend(int protocol_id, Message* msg) { //Add header to send out ftpHeader *header = new ftpHeader; header->hlp = protocol_id; header->m_size = msg->msgLen(); msg->msgAddHdr((char *)header, sizeof(ftpHeader)); tcpSend(FTP_ID, msg); delete header; }
int Net::serverExecute() { int i=0; printf("init done!\n"); int quit = 0; ipPeer.resolvehost("NULL", 9999); tcpOpen(); ipPeer.resolveIP(); printf("main loop\n"); while (running) { if (tcpAccept()) { tcpGetPeerAddress(); fprintf(stdout, "client connected:\n"); quit = 0; while (!quit) { if ((SDLNet_TCP_Recv(socketPeer, buffer, DIMBUFFER) > 0)) { fprintf(stdout, "reci:\t%s", buffer); snprintf(buffer, DIMBUFFER, "server123\t%d\n", i); tcpSend(socketPeer, buffer); fprintf(stdout, "send:\t%s", buffer); } // if ((strcmp(buffer, "exit") == 0)) { // fprintf(stdout, "session terminated\n"); // quit2 = 1; // } // if ((strcmp(buffer, "quit") == 0)) { // fprintf(stdout, "programm terminated\n"); // quit2 = 1; // quit = 1; // } // SDL_Delay(100); i++; } } SDL_Delay(100); } // SDLNet_TCP_Close(socketClient); cleanup(); return 0; }
/** * @ingroup tcp * * Processes an incoming packet for a TCP connection in the SYNSENT state. * Function based on RFC 763, pg 66-68. * @param pkt incoming packet * @param tcbptr pointer to transmission control block for connection * @return OK or TCP_ERR_SNDRST * @pre-condition TCB mutex is already held */ int tcpRecvSynsent(struct packet *pkt, struct tcb *tcbptr) { struct tcpPkt *tcp; bool ackAccept = FALSE; /* Setup packet pointers */ tcp = (struct tcpPkt *)pkt->curr; /* Process ACK */ if (tcp->control & TCP_CTRL_ACK) { TCP_TRACE("ACK"); /* If ACK is unacceptable send reset */ if (seqlte(tcp->acknum, tcbptr->iss) || seqlt(tcbptr->sndnxt, tcp->acknum)) { if (!(tcp->control & TCP_CTRL_RST)) { tcbptr->sndflg |= TCP_FLG_SNDRST; return OK; } return OK; } /* Check if ACK is acceptable */ if (seqlte(tcbptr->snduna, tcp->acknum) && seqlte(tcp->acknum, tcbptr->sndnxt)) { ackAccept = TRUE; } } /* Process RST */ if (tcp->control & TCP_CTRL_RST) { TCP_TRACE("RST"); if (ackAccept) { /* ERROR: Connection reset */ return TCP_ERR_RESET; } return OK; } /* Process SYN */ if (tcp->control & TCP_CTRL_SYN) { TCP_TRACE("SYN"); tcbptr->sndwnd = tcp->window; tcbptr->sndwl1 = tcp->seqnum; tcbptr->rcvnxt = seqadd(tcp->seqnum, 1); tcbptr->rcvwnd = seqadd(tcp->seqnum, TCP_INIT_WND); tcbptr->rcvflg |= TCP_FLG_SYN; tcbptr->sndflg |= TCP_FLG_SNDACK; if (ackAccept) { tcbptr->snduna = tcp->acknum; tcbptr->sndwl2 = tcp->acknum; } /* Remove any segments from retransmission queue which are ACKed */ tcbptr->rxtcount = 0; tcpTimerPurge(tcbptr, TCP_EVT_RXT); /* If unacknowledged data remains, reschedule retransmit timer */ if (seqlt(tcbptr->snduna, tcbptr->sndnxt)) { tcpTimerSched(tcbptr->rxttime, tcbptr, TCP_EVT_RXT); } if (seqlt(tcbptr->iss, tcbptr->snduna)) { tcbptr->state = TCP_ESTAB; signal(tcbptr->openclose); /* Signal connection open */ tcbptr->sndflg |= TCP_FLG_SNDDATA; return tcpRecvData(pkt, tcbptr); } else { tcbptr->state = TCP_SYNRECV; /* This send is like a retransmission */ tcpSend(tcbptr, TCP_CTRL_SYN | TCP_CTRL_ACK, tcbptr->iss, tcbptr->rcvnxt, NULL, 1); return tcpRecvData(pkt, tcbptr); } } return OK; }
/** * Sends an ACK packet to ackowledge all received data for a TCP connection. * @param tcpptr pointer to the transmission control block for connection * @pre-condition TCB mutex is already held * @post-condition TCB mutex is still held */ int tcpSendAck(struct tcb *tcbptr) { tcbptr->sndflg &= ~TCP_FLG_SNDACK; return tcpSend(tcbptr, TCP_CTRL_ACK, tcbptr->sndnxt, tcbptr->rcvnxt, 0, 0); }
void cmd_task(void) { static char rst = 0; char *sp,*cp,*next; //,str[4]; long i=0; if(rcv_cmd) { rcv = 0; wdt_feed(); sp = get_entry (&buf_rx[0], &next); if(*sp == 0) { if(rst++ >= 10) { printf ("[FAIL CMD..restart now]\r"); fflush(stdout); LPC_WDT->WDTC = 0x003FFFF; /*0.5s*/ wdt_feed(); while(1); } sprintf(buf_tx,"ERROR %u",ERROR_COMMAND); }else { for (cp = sp; *cp && *cp != ' '; cp++) *cp = toupper (*cp); for (i = 0; i < CMD_COUNT; i++) { if (strcmp (sp, (const char *)&cmd[i].val)) continue; cmd[i].func (next); rst = 0; break; } } if(i == CMD_COUNT) sprintf(buf_tx,"ERROR %u",ERROR_COMMAND); if(i!=6 && rcv_cmd == RCV_CMD_UART_0) /*i=6 (Rcv Touch lpc1113)*/ { if(buf_tx[0] == 'E') beep(BEEP_ERROR); else beep(BEEP_CFG); }else /*Função IR learn, IR learn Scene, Detect Swing e IR learn app via TCP?*/ if((i == 0 || i == 12 || i == 13 || i == 17) && (rcv_cmd == RCV_CMD_TCP_SERVER || rcv_cmd == RCV_CMD_TCP_CLIENT)) { if(buf_tx[0] == 'E') beep(BEEP_ERROR); else beep(BEEP_CFG); } strcat(buf_tx,"\r\n\0"); if(rcv_cmd == RCV_CMD_UART_2) { // uart_putString(2,buf_tx); }else if(rcv_cmd == RCV_CMD_UART_0) uart_putString(0,buf_tx); #if USE_TCP_CLIENT /*Comunicação TCP CLIENT será usada?*/ else if((rcv_cmd == RCV_CMD_TCP_CLIENT)) { tcpSend (buf_tx, strlen(buf_tx), last_soc_client,CMD_SEND_TO_CLIENT); uart_putString(0,buf_tx); } #endif #if USE_TCP_SERVER /*Comunicação TCP SERVER será usada?*/ else if((rcv_cmd == RCV_CMD_TCP_SERVER)) { tcpSend (buf_tx, strlen(buf_tx), tcp_server_soc,CMD_SEND_TO_SERVER); uart_putString(0,buf_tx); } #endif memset(buf_rx,0,sizeof(buf_rx)); memset(buf_tx,0,sizeof(buf_tx)); if(!rcv) rcv_cmd = __FALSE; cntUART2 = 0; cntUART0 = 0; NVIC_EnableIRQ(UART2_IRQn); NVIC_EnableIRQ(UART0_IRQn); } }
error_t tcpShutdown(Socket *socket, uint_t how) { error_t error; uint_t event; //Disable transmission? if(how == SOCKET_SD_SEND || how == SOCKET_SD_BOTH) { //Check current state switch(socket->state) { //CLOSED or LISTEN state? case TCP_STATE_CLOSED: case TCP_STATE_LISTEN: //Connection does not exist return ERROR_NOT_CONNECTED; //SYN-RECEIVED or ESTABLISHED state? case TCP_STATE_SYN_RECEIVED: case TCP_STATE_ESTABLISHED: //Flush the send buffer error = tcpSend(socket, NULL, 0, NULL, SOCKET_FLAG_NO_DELAY); //Any error to report? if(error) return error; //Make sure all the data has been sent out event = tcpWaitForEvents(socket, SOCKET_EVENT_TX_DONE, socket->timeout); //Timeout error? if(event != SOCKET_EVENT_TX_DONE) return ERROR_TIMEOUT; //Send a FIN segment error = tcpSendSegment(socket, TCP_FLAG_FIN | TCP_FLAG_ACK, socket->sndNxt, socket->rcvNxt, 0, TRUE); //Failed to send FIN segment? if(error) return error; //Sequence number expected to be received socket->sndNxt++; //Switch to the FIN-WAIT1 state tcpChangeState(socket, TCP_STATE_FIN_WAIT_1); //Wait for the FIN to be acknowledged event = tcpWaitForEvents(socket, SOCKET_EVENT_TX_SHUTDOWN, socket->timeout); //Timeout interval elapsed? if(event != SOCKET_EVENT_TX_SHUTDOWN) return ERROR_TIMEOUT; //Continue processing... break; //CLOSE-WAIT state? case TCP_STATE_CLOSE_WAIT: //Flush the send buffer error = tcpSend(socket, NULL, 0, NULL, SOCKET_FLAG_NO_DELAY); //Any error to report? if(error) return error; //Make sure all the data has been sent out event = tcpWaitForEvents(socket, SOCKET_EVENT_TX_DONE, socket->timeout); //Timeout error? if(event != SOCKET_EVENT_TX_DONE) return ERROR_TIMEOUT; //Send a FIN segment error = tcpSendSegment(socket, TCP_FLAG_FIN | TCP_FLAG_ACK, socket->sndNxt, socket->rcvNxt, 0, TRUE); //Failed to send FIN segment? if(error) return error; //Sequence number expected to be received socket->sndNxt++; //Switch to the LAST-ACK state tcpChangeState(socket, TCP_STATE_LAST_ACK); //Wait for the FIN to be acknowledged event = tcpWaitForEvents(socket, SOCKET_EVENT_TX_SHUTDOWN, socket->timeout); //Timeout interval elapsed? if(event != SOCKET_EVENT_TX_SHUTDOWN) return ERROR_TIMEOUT; //Continue processing... break; //SYN-SENT, FIN-WAIT-1, FIN-WAIT-2, CLOSING, //TIME-WAIT or LAST-ACK state? default: //Continue processing... break; } } //Disable reception? if(how == SOCKET_SD_RECEIVE || how == SOCKET_SD_BOTH) { //Check current state switch(socket->state) { //CLOSED or LISTEN state? case TCP_STATE_CLOSED: case TCP_STATE_LISTEN: //Connection does not exist return ERROR_NOT_CONNECTED; //SYN-SENT, SYN-RECEIVED, ESTABLISHED, FIN-WAIT-1 or FIN-WAIT-2 state? case TCP_STATE_SYN_SENT: case TCP_STATE_SYN_RECEIVED: case TCP_STATE_ESTABLISHED: case TCP_STATE_FIN_WAIT_1: case TCP_STATE_FIN_WAIT_2: //Wait for a FIN to be received event = tcpWaitForEvents(socket, SOCKET_EVENT_RX_SHUTDOWN, socket->timeout); //Timeout interval elapsed? if(event != SOCKET_EVENT_RX_SHUTDOWN) return ERROR_TIMEOUT; //A FIN segment has been received break; //CLOSING, TIME-WAIT, CLOSE-WAIT or LAST-ACK state? default: //A FIN segment has already been received break; } } //Successful operation return NO_ERROR; }
/** * @ingroup tcp * * Sends pending outbound data (including SYN and FIN) for a TCP connection, * if new data is ready for transmission. * @param tcpptr pointer to the transmission control block for connection * @return number of octets sent * @pre-condition TCB mutex is already held * @post-condition TCB mutex is still held */ int tcpSendData(struct tcb *tcbptr) { uint wndused; /**< amount of window filled with data pending ACK */ uint pending; /**< amount of data pending ACK or transmission */ uint tosend; uint sent; uchar ctrl; /* Verify sender MSS is greater than 0 */ if (tcbptr->sndmss == 0) { return SYSERR; } /* If FIN was already sent, then cannot send more data */ if ((tcbptr->sndflg & TCP_FLG_FIN) && seqlt(tcbptr->sndfin, tcbptr->sndnxt)) { return SYSERR; } /* If in retransmission or persist, cannot send data */ if ((tcbptr->rxtcount > 0) || (tcbptr->sndflg & TCP_FLG_PERSIST)) { return 0; } /* If the send window is zero, schedule a persist event */ if (0 == tcbptr->sndwnd) { tcbptr->sndflg |= TCP_FLG_PERSIST; tcbptr->psttime = TCP_PST_INITTIME; tcpTimerSched(tcbptr->psttime, tcbptr, TCP_EVT_PERSIST); return 0; } /* Check if new transmssion is allowed */ /* If (SNDNXT >= SNDUNA + SNDWND), then can't send data */ if (seqlte(seqadd(tcbptr->snduna, tcbptr->sndwnd), tcbptr->sndnxt)) { return 0; } /* Check if there is data to send */ pending = tcbptr->ocount; if (tcbptr->sndflg & TCP_FLG_FIN) { pending++; } wndused = tcpSeqdiff(tcbptr->sndnxt, tcbptr->snduna); if (pending == wndused) { if (seqlt(tcbptr->snduna, tcbptr->sndnxt) && (tcpTimerRemain(tcbptr, TCP_EVT_RXT) <= 0)) { tcpTimerSched(tcbptr->rxttime, tcbptr, TCP_EVT_RXT); } return 0; } /* There is data to send and space in the window to send it */ ctrl = TCP_CTRL_ACK; /* Determine how much data to send */ if (pending > tcbptr->sndwnd) { tosend = tcbptr->sndwnd - wndused; } else { tosend = pending - wndused; if (tcbptr->sndflg & TCP_FLG_FIN) { ctrl |= TCP_CTRL_FIN; } } /* Send as many maximum size segments as possible */ sent = 0; while (tosend > tcbptr->sndmss) { tcpSend(tcbptr, TCP_CTRL_ACK, tcbptr->sndnxt, tcbptr->rcvnxt, (tcbptr->ostart + wndused) % TCP_OBLEN, tcbptr->sndmss); tosend -= tcbptr->sndmss; sent += tcbptr->sndmss; wndused += tcbptr->sndmss; tcbptr->sndnxt = seqadd(tcbptr->sndnxt, tcbptr->sndmss); } /* Send the remainder of the sendable data */ tcpSend(tcbptr, ctrl, tcbptr->sndnxt, tcbptr->rcvnxt, (tcbptr->ostart + wndused) % TCP_OBLEN, tosend); sent += tosend; wndused += tosend; tcbptr->sndnxt = seqadd(tcbptr->sndnxt, tosend); /* If one does not already exist, schedule a retransmission event */ if (tcpTimerRemain(tcbptr, TCP_EVT_RXT) <= 0) { tcpTimerSched(tcbptr->rxttime, tcbptr, TCP_EVT_RXT); } /* No longer need to ACK if data was sent, since ACK was piggybacked */ if (sent > 0) { tcbptr->sndflg &= ~TCP_FLG_SNDACK; } tcbptr->sndflg &= ~TCP_FLG_SNDDATA; return sent; }
/* Process a specific test case. File name is provided. * Needs to return 0 if all is OK, something else otherwise. */ int processTestFile(int fd, char *pszFileName) { FILE *fp; char *testdata = NULL; char *expected = NULL; int ret = 0; size_t lenLn; char buf[4096]; if((fp = fopen((char*)pszFileName, "r")) == NULL) { perror((char*)pszFileName); return(2); } /* skip comments at start of file */ while(!feof(fp)) { getline(&testdata, &lenLn, fp); while(!feof(fp)) { if(*testdata == '#') getline(&testdata, &lenLn, fp); else break; /* first non-comment */ } /* this is not perfect, but works ;) */ if(feof(fp)) break; ++iTests; /* increment test count, we now do one! */ testdata[strlen(testdata)-1] = '\0'; /* remove \n */ /* now we have the test data to send (we could use function pointers here...) */ unescapeTestdata(testdata); if(inputMode == inputUDP) { if(udpSend(testdata, strlen(testdata)) != 0) return(2); } else { if(tcpSend(testdata, strlen(testdata)) != 0) return(2); } /* next line is expected output * we do not care about EOF here, this will lead to a failure and thus * draw enough attention. -- rgerhards, 2009-03-31 */ getline(&expected, &lenLn, fp); expected[strlen(expected)-1] = '\0'; /* remove \n */ /* pull response from server and then check if it meets our expectation */ readLine(fd, buf); if(strcmp(expected, buf)) { ++iFailed; printf("\nExpected Response:\n'%s'\nActual Response:\n'%s'\n", expected, buf); ret = 1; } /* we need to free buffers, as we have potentially modified them! */ free(testdata); testdata = NULL; free(expected); expected = NULL; } free(expected); fclose(fp); return(ret); }
/***************************************************************************** ** Function name: U16 tcp_task (void) ** ** Descriptions: envia dados para o servidor TCP *****************************************************************************/ void tcp_task(void) { static U32 tcp_timer = 0u; U8 buf_udp[100],i; /****************** instantâneo ********************************/ #if USE_TCP_SERVER /*Comunicação TCP SERVER será usada?*/ U8 ip[4]; #if USE_PCK_SERV static U32 cnt_tcp_serv = 0u; if(tcp_state.bit.dataToSend) { tcp_state.bit.dataToSend = __FALSE; cnt_tcp_serv = 0; //if(tcp_buf[0] == 0) //sprintf((char*)tcp_buf,"%02X.%02X.%02X.%02X.%02X.%02X\r\n\0",own_hw_adr[0],own_hw_adr[1],own_hw_adr[2],own_hw_adr[3],own_hw_adr[4],own_hw_adr[5]); //tcpSend((char*)tcp_buf, strlen((const char*)tcp_buf), tcp_server_soc, CMD_SEND_TO_SERVER); //memset(tcp_buf,0,sizeof(tcp_buf)); } #endif #endif /****************** a cada 100ms *******************************/ if(!tick) return; ++tcp_timer; dhcp_check(); /****************** a cada 1s **********************************/ if((tcp_timer%TASK_1S)) return; #if USE_TCP_CLIENT if(!(tcp_timer%TASK_5S)) { /*Pacote UDP de identificação*/ sprintf((char*)buf_udp,"%s %u.%u.%u.%u %02X.%02X.%02X.%02X.%02X.%02X %s %s %u.%u.%u.%u %u.%u.%u.%u\r\n\0",lhost_name,MY_IP[0],MY_IP[1],MY_IP[2],MY_IP[3], own_hw_adr[0],own_hw_adr[1],own_hw_adr[2],own_hw_adr[3],own_hw_adr[4],own_hw_adr[5], cfg.tcp.port_serv_rem, cfg.tcp.ip_serv_rem, MY_MASK[0], MY_MASK[1], MY_MASK[2], MY_MASK[3], MY_GATEWAY[0], MY_GATEWAY[1], MY_GATEWAY[2], MY_GATEWAY[3]); if(!ftp_state.bit.UpdateTcp) udpSendBroadcast(buf_udp); //udpSendUnicast(buf_udp,cfg.tcp.ip_app); } if(!(tcp_timer%TASK_30S)) /*A cada 30s*/ { /*Mantém o link ativo*/ //if(tcp_get_state (tcp_client_soc[0]) == TCP_STATE_CONNECT) //{ sprintf(buf_tx,"LOK OK\r\n\0"); for(i=0;i<MAX_NUM_SOC;i++) tcpSend (buf_tx, strlen(buf_tx), tcp_client_soc[i], CMD_SEND_TO_CLIENT); //tcpSend (buf_tx, strlen(buf_tx), tcp_client_soc[0], CMD_SEND_TO_CLIENT); //} } #endif #if USE_TCP_SERVER && USE_PCK_SERV /*Comunicação TCP SERVER será usada?*/ if(!(++cnt_tcp_serv % atoi(cfg.tcp.interval_packet_serv))) tcp_state.bit.dataToSend = __TRUE; #endif #if USE_TCP_SERVER /*Comunicação TCP SERVER será usada?*/ /*Analisa estado de comunicação com o servidor externo*/ if(tcp_get_state (tcp_server_soc) != TCP_STATE_CONNECT) { tcp_state.bit.serverConnected = __FALSE; inet_aton((U8*)cfg.tcp.ip_serv_rem,ip); tcp_connect(tcp_server_soc,ip,atoi(cfg.tcp.port_serv_rem),atoi(cfg.tcp.port_serv_loc)); }else tcp_state.bit.serverConnected = __TRUE; #endif /*Houve alteração das cenas via FTP?*/ if(ftp_state.bit.UpdateScene) { printf ("[Scene config via FTP]\r\r"); fflush(stdout); ftp_state.bit.UpdateScene = __FALSE; init_scene(0xFF); } if(ftp_state.bit.UpdateFileCfg) { printf ("[CFG.CFG configurado via FTP]\r\r"); fflush(stdout); ftp_state.bit.UpdateFileCfg = __FALSE; read_file_cfg(); } /*Houve alteração das configurações TCP via FTP?*/ if(ftp_state.bit.UpdateTcp) { printf ("[TCP Config via FTP..Reiniciando]\r\r"); fflush(stdout); #if USE_TCP_CLIENT for(i=0;i<MAX_NUM_SOC;i++) tcp_close (tcp_client_soc[i]); #endif #if USE_TCP_SERVER tcp_close (tcp_server_soc); #endif LPC_WDT->WDTC = 0x003FFFF; /*0.5s*/ wdt_feed(); while(1); } }