/************************************************************************ * NAME: fapp_bench_tcp_rx * * DESCRIPTION: Start Benchmark TCP server. ************************************************************************/ static void fapp_bench_tcp_rx (fnet_shell_desc_t desc, fnet_address_family_t family) { struct sockaddr local_addr; fnet_int32_t received; fnet_char_t ip_str[FNET_IP_ADDR_STR_SIZE]; struct linger linger_option = {FNET_TRUE, /*l_onoff*/ 4 /*l_linger*/ }; fnet_size_t bufsize_option = FAPP_BENCH_SOCKET_BUF_SIZE; fnet_int32_t keepalive_option = 1; fnet_int32_t keepcnt_option = FAPP_BENCH_TCP_KEEPCNT; fnet_int32_t keepintvl_option = FAPP_BENCH_TCP_KEEPINTVL; fnet_int32_t keepidle_option = FAPP_BENCH_TCP_KEEPIDLE; struct sockaddr foreign_addr; fnet_size_t addr_len; fnet_bool_t exit_flag = FNET_FALSE; fapp_bench.socket_foreign = FNET_ERR; /* Create listen socket */ if((fapp_bench.socket_listen = fnet_socket(family, SOCK_STREAM, 0)) == FNET_ERR) { FNET_DEBUG("BENCH: Socket creation error."); goto ERROR_1; } /* Bind socket.*/ fnet_memset_zero(&local_addr, sizeof(local_addr)); local_addr.sa_port = FAPP_BENCH_PORT; local_addr.sa_family = family; if(fnet_socket_bind(fapp_bench.socket_listen, &local_addr, sizeof(local_addr)) == FNET_ERR) { FNET_DEBUG("BENCH: Socket bind error."); goto ERROR_2; } /* Set Socket options. */ if( /* Setup linger option. */ (fnet_socket_setopt (fapp_bench.socket_listen, SOL_SOCKET, SO_LINGER, (fnet_uint8_t *)&linger_option, sizeof(linger_option)) == FNET_ERR) || /* Set socket buffer size. */ (fnet_socket_setopt(fapp_bench.socket_listen, SOL_SOCKET, SO_RCVBUF, (fnet_uint8_t *) &bufsize_option, sizeof(bufsize_option))== FNET_ERR) || (fnet_socket_setopt(fapp_bench.socket_listen, SOL_SOCKET, SO_SNDBUF, (fnet_uint8_t *) &bufsize_option, sizeof(bufsize_option))== FNET_ERR) || /* Enable keepalive_option option. */ (fnet_socket_setopt (fapp_bench.socket_listen, SOL_SOCKET, SO_KEEPALIVE, (fnet_uint8_t *)&keepalive_option, sizeof(keepalive_option)) == FNET_ERR) || /* Keepalive probe retransmit limit. */ (fnet_socket_setopt (fapp_bench.socket_listen, IPPROTO_TCP, TCP_KEEPCNT, (fnet_uint8_t *)&keepcnt_option, sizeof(keepcnt_option)) == FNET_ERR) || /* Keepalive retransmit interval.*/ (fnet_socket_setopt (fapp_bench.socket_listen, IPPROTO_TCP, TCP_KEEPINTVL, (fnet_uint8_t *)&keepintvl_option, sizeof(keepintvl_option)) == FNET_ERR) || /* Time between keepalive probes.*/ (fnet_socket_setopt (fapp_bench.socket_listen, IPPROTO_TCP, TCP_KEEPIDLE, (fnet_uint8_t *)&keepidle_option, sizeof(keepidle_option)) == FNET_ERR) ) { FNET_DEBUG("BENCH: Socket setsockopt error.\n"); goto ERROR_2; } /* Listen. */ if(fnet_socket_listen(fapp_bench.socket_listen, 1) == FNET_ERR) { FNET_DEBUG("BENCH: Socket listen error.\n"); goto ERROR_2; } /* ------ Start test.----------- */ fnet_shell_println(desc, FAPP_DELIMITER_STR); fnet_shell_println(desc, " TCP RX Test"); fnet_shell_println(desc, FAPP_DELIMITER_STR); fapp_netif_addr_print(desc, family, fnet_netif_get_default(), FNET_FALSE); fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Local Port", FNET_NTOHS(FAPP_BENCH_PORT)); fnet_shell_println(desc, FAPP_TOCANCEL_STR); fnet_shell_println(desc, FAPP_DELIMITER_STR); while(exit_flag == FNET_FALSE) { fnet_shell_println(desc, "Waiting."); fapp_bench.bytes = 0; fapp_bench.remote_bytes = 0; if(fapp_bench.socket_foreign != FNET_ERR) { fnet_socket_close(fapp_bench.socket_foreign); fapp_bench.socket_foreign = FNET_ERR; } while((fapp_bench.socket_foreign == FNET_ERR) && (exit_flag == FNET_FALSE)) { /*Accept*/ addr_len = sizeof(foreign_addr); fapp_bench.socket_foreign = fnet_socket_accept(fapp_bench.socket_listen, &foreign_addr, &addr_len); exit_flag = fnet_shell_ctrlc (desc); if(fapp_bench.socket_foreign != FNET_ERR) { fnet_shell_println(desc,"Receiving from %s:%d", fnet_inet_ntop(foreign_addr.sa_family, (fnet_uint8_t*)(foreign_addr.sa_data), ip_str, sizeof(ip_str)), fnet_ntohs(foreign_addr.sa_port)); fapp_bench.first_time = fnet_timer_ticks(); while(1) /* Receiving data.*/ { received = fnet_socket_recv(fapp_bench.socket_foreign, (fnet_uint8_t*)(&fapp_bench.buffer[0]), FAPP_BENCH_BUFFER_SIZE, 0); if ((received == FNET_ERR) || exit_flag) { fapp_bench.last_time = fnet_timer_ticks(); /* Print benchmark results.*/ fapp_bench_print_results (desc); break; } else { fapp_bench.bytes += received; } exit_flag = fnet_shell_ctrlc (desc); /* Check [Ctrl+c]*/ } } } } fnet_socket_close(fapp_bench.socket_foreign); ERROR_2: fnet_socket_close(fapp_bench.socket_listen); ERROR_1: fnet_shell_println(desc, FAPP_BENCH_COMPLETED_STR); }
/************************************************************************ * DESCRIPTION: Telnet server state machine. ************************************************************************/ static void fnet_telnet_state_machine( void *telnet_if_p ) { struct sockaddr foreign_addr; fnet_int32_t res; struct fnet_telnet_if *telnet = (struct fnet_telnet_if *)telnet_if_p; fnet_uint8_t rx_data[1]; fnet_size_t len; fnet_index_t i; struct fnet_telnet_session_if *session; for( i = 0u; i < FNET_CFG_TELNET_SESSION_MAX; i++) { session = &telnet->session[i]; telnet->session_active = session; do { switch(session->state) { /*---- LISTENING ------------------------------------------------*/ case FNET_TELNET_STATE_LISTENING: len = sizeof(foreign_addr); session->socket_foreign = fnet_socket_accept(telnet->socket_listen, (struct sockaddr *) &foreign_addr, &len); if(session->socket_foreign != FNET_ERR) { #if FNET_CFG_DEBUG_TELNET && FNET_CFG_DEBUG { fnet_uint8_t ip_str[FNET_IP_ADDR_STR_SIZE]; fnet_inet_ntop(foreign_addr.sa_family, foreign_addr.sa_data, ip_str, sizeof(ip_str)); FNET_DEBUG_TELNET("\nTELNET: New connection: %s; Port: %d.", ip_str, fnet_ntohs(foreign_addr.sa_port)); } #endif /* Init Shell. */ session->shell_descriptor = fnet_shell_init(&session->shell_params); if(session->shell_descriptor) { fnet_socket_listen(telnet->socket_listen, --telnet->backlog); /* Ignor other connections.*/ /* Reset TX timeout. */ session->state = FNET_TELNET_STATE_RECEIVING; /* => WAITING data */ } else { FNET_DEBUG_TELNET("TELNET: Shell Service registration error."); session->state = FNET_TELNET_STATE_CLOSING; /*=> CLOSING */ } } break; /*---- NORMAL -----------------------------------------------*/ case FNET_TELNET_STATE_RECEIVING: if(rx_buffer_free_space(session) > 0u) { res = fnet_socket_recv(session->socket_foreign, rx_data, 1u, 0u); if(res == 1) { if(rx_data[0] == FNET_TELNET_CMD_IAC ) { session->state = FNET_TELNET_STATE_IAC; /*=> Handle IAC */ } else { rx_buffer_write (session, rx_data[0]); } } else if (res == FNET_ERR) { session->state = FNET_TELNET_STATE_CLOSING; /*=> CLOSING */ } else {} } break; /*---- IAC -----------------------------------------------*/ case FNET_TELNET_STATE_IAC: FNET_DEBUG_TELNET("TELNET: STATE_IAC"); if((res = fnet_socket_recv(session->socket_foreign, rx_data, 1u, 0u) ) != FNET_ERR) { if(res) { switch(rx_data[0]) { case FNET_TELNET_CMD_WILL: session->state = FNET_TELNET_STATE_DONT; break; case FNET_TELNET_CMD_DO: session->state = FNET_TELNET_STATE_WONT; break; case FNET_TELNET_CMD_WONT: case FNET_TELNET_CMD_DONT: session->state = FNET_TELNET_STATE_SKIP ; break; case FNET_TELNET_CMD_IAC: /* the IAC need be doubled to be sent as data, and the other 255 codes may be passed transparently. */ rx_buffer_write (session, rx_data[0]); session->state = FNET_TELNET_STATE_RECEIVING; break; default: session->state = FNET_TELNET_STATE_RECEIVING; /*=> Ignore commands */ break; } } } else { session->state = FNET_TELNET_STATE_CLOSING; /*=> CLOSING */ } break; /*---- DONT & WONT -----------------------------------------------*/ case FNET_TELNET_STATE_DONT: case FNET_TELNET_STATE_WONT: { fnet_uint8_t command; if(session->state == FNET_TELNET_STATE_DONT) { FNET_DEBUG_TELNET("TELNET: STATE_DONT"); command = FNET_TELNET_CMD_DONT; } else { FNET_DEBUG_TELNET("TELNET: STATE_WONT"); command = FNET_TELNET_CMD_WONT; } if(tx_buffer_free_space(session) >= 3u) { res = fnet_socket_recv(session->socket_foreign, rx_data, 1u, 0u); if(res == 1) { /* Send command. */ fnet_telnet_send_cmd(session, command, rx_data[0]); session->state = FNET_TELNET_STATE_RECEIVING; } else if (res == FNET_ERR) { session->state = FNET_TELNET_STATE_CLOSING; /*=> CLOSING */ } else {} } } break; /*---- SKIP -----------------------------------------------*/ case FNET_TELNET_STATE_SKIP: FNET_DEBUG_TELNET("TELNET: STATE_SKIP"); res = fnet_socket_recv(session->socket_foreign, rx_data, 1u, 0u); if(res == 1) { session->state = FNET_TELNET_STATE_RECEIVING; } else if (res == FNET_ERR) { session->state = FNET_TELNET_STATE_CLOSING; /*=> CLOSING */ } else {} break; /*---- CLOSING --------------------------------------------*/ case FNET_TELNET_STATE_CLOSING: FNET_DEBUG_TELNET("TELNET: STATE_CLOSING"); if(session->shell_descriptor) { fnet_shell_release(session->shell_descriptor); session->shell_descriptor = 0; } session->rx_buffer_head = session->rx_buffer; session->rx_buffer_tail = session->rx_buffer; fnet_socket_close(session->socket_foreign); session->socket_foreign = FNET_ERR; fnet_socket_listen(telnet->socket_listen, ++telnet->backlog); /* Allow connection.*/ session->state = FNET_TELNET_STATE_LISTENING; /*=> LISTENING */ break; default: break; } } while(session->state == FNET_TELNET_STATE_CLOSING); } }