/************************************************************************ * NAME: fapp_bench_tcp_tx * * DESCRIPTION: Start TX TCP Benchmark. ************************************************************************/ static void fapp_bench_tcp_tx (struct fapp_bench_tx_params *params) { fnet_int32_t send_result; fnet_char_t ip_str[FNET_IP_ADDR_STR_SIZE]; const struct linger linger_option = {FNET_TRUE, /*l_onoff*/ 4 /*l_linger*/ }; const fnet_size_t bufsize_option = FAPP_BENCH_SOCKET_BUF_SIZE; const fnet_int32_t keepalive_option = 1; const fnet_int32_t keepcnt_option = FAPP_BENCH_TCP_KEEPCNT; const fnet_int32_t keepintvl_option = FAPP_BENCH_TCP_KEEPINTVL; const fnet_int32_t keepidle_option = FAPP_BENCH_TCP_KEEPIDLE; struct sockaddr foreign_addr; fnet_bool_t exit_flag = FNET_FALSE; fnet_int32_t sock_err ; fnet_size_t option_len; fnet_shell_desc_t desc = params->desc; fnet_socket_state_t connection_state; fnet_size_t packet_size = params->packet_size; fnet_index_t cur_packet_number; fnet_size_t buffer_offset; fnet_index_t iterations = params->iteration_number; fnet_address_family_t family = params->foreign_addr.sa_family; if(packet_size > FAPP_BENCH_BUFFER_SIZE) /* Check max size.*/ packet_size = FAPP_BENCH_BUFFER_SIZE; fapp_bench.socket_listen = FNET_ERR; /* ------ Start test.----------- */ fnet_shell_println(desc, FAPP_DELIMITER_STR); fnet_shell_println(desc, " TCP TX Test" ); fnet_shell_println(desc, FAPP_DELIMITER_STR); fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_S, "Remote IP Addr", fnet_inet_ntop(family, params->foreign_addr.sa_data, ip_str, sizeof(ip_str))); fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Remote Port", fnet_ntohs(params->foreign_addr.sa_port)); fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Message Size", params->packet_size); fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Num. of messages", params->packet_number); fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Num. of iterations", params->iteration_number); fnet_shell_println(desc, FAPP_TOCANCEL_STR); fnet_shell_println(desc, FAPP_DELIMITER_STR); while(iterations--) { /* Create socket */ if((fapp_bench.socket_foreign = fnet_socket(family, SOCK_STREAM, 0)) == FNET_ERR) { FNET_DEBUG("BENCH: Socket creation error.\n"); iterations = 0; goto ERROR_1; } /* Set Socket options. */ if( /* Setup linger option. */ (fnet_socket_setopt (fapp_bench.socket_foreign, SOL_SOCKET, SO_LINGER, (fnet_uint8_t *)&linger_option, sizeof(linger_option)) == FNET_ERR) || /* Set socket buffer size. */ (fnet_socket_setopt(fapp_bench.socket_foreign, SOL_SOCKET, SO_RCVBUF, (fnet_uint8_t *) &bufsize_option, sizeof(bufsize_option))== FNET_ERR) || (fnet_socket_setopt(fapp_bench.socket_foreign, SOL_SOCKET, SO_SNDBUF, (fnet_uint8_t *) &bufsize_option, sizeof(bufsize_option))== FNET_ERR) || /* Enable keepalive_option option. */ (fnet_socket_setopt (fapp_bench.socket_foreign, SOL_SOCKET, SO_KEEPALIVE, (fnet_uint8_t *)&keepalive_option, sizeof(keepalive_option)) == FNET_ERR) || /* Keepalive probe retransmit limit. */ (fnet_socket_setopt (fapp_bench.socket_foreign, IPPROTO_TCP, TCP_KEEPCNT, (fnet_uint8_t *)&keepcnt_option, sizeof(keepcnt_option)) == FNET_ERR) || /* Keepalive retransmit interval.*/ (fnet_socket_setopt (fapp_bench.socket_foreign, IPPROTO_TCP, TCP_KEEPINTVL, (fnet_uint8_t *)&keepintvl_option, sizeof(keepintvl_option)) == FNET_ERR) || /* Time between keepalive probes.*/ (fnet_socket_setopt (fapp_bench.socket_foreign, IPPROTO_TCP, TCP_KEEPIDLE, (fnet_uint8_t *)&keepidle_option, sizeof(keepidle_option)) == FNET_ERR) ) { FNET_DEBUG("BENCH: Socket setsockopt error.\n"); iterations = 0; goto ERROR_2; } /* Connect to the server.*/ fnet_shell_println(desc,"Connecting."); fnet_memcpy(&foreign_addr, ¶ms->foreign_addr, sizeof(foreign_addr)); fnet_socket_connect(fapp_bench.socket_foreign, (struct sockaddr *)(&foreign_addr), sizeof(foreign_addr)); do { option_len = sizeof(connection_state); fnet_socket_getopt(fapp_bench.socket_foreign, SOL_SOCKET, SO_STATE, (fnet_uint8_t*)&connection_state, &option_len); } while (connection_state == SS_CONNECTING); if(connection_state != SS_CONNECTED) { fnet_shell_println(desc, "Connection failed."); iterations = 0; goto ERROR_2; } /* Sending.*/ fnet_shell_println(desc,"Sending."); fapp_bench.bytes = 0; fapp_bench.remote_bytes = 0; cur_packet_number = 0; buffer_offset = 0; fapp_bench.first_time = fnet_timer_ticks(); while(1) { send_result = fnet_socket_send( fapp_bench.socket_foreign, (fnet_uint8_t*)(&fapp_bench.buffer[buffer_offset]), (packet_size-buffer_offset), 0); fapp_bench.last_time = fnet_timer_ticks(); if ( send_result == FNET_ERR ) { option_len = sizeof(sock_err); fnet_socket_getopt(fapp_bench.socket_foreign, SOL_SOCKET, SO_ERROR, &sock_err, &option_len); fnet_shell_println(desc, "Socket error = %d", sock_err); iterations = 0; #if 0 /* Print benchmark results.*/ fapp_bench_print_results (desc); #endif break; } else if(send_result) { fapp_bench.bytes += send_result; buffer_offset += send_result; if(buffer_offset == packet_size) { cur_packet_number ++; buffer_offset = 0; } exit_flag = fnet_shell_ctrlc(desc); /* Check [Ctrl+c]*/ if((cur_packet_number >= params->packet_number)|| exit_flag) { if(exit_flag) { fnet_shell_println(desc, FAPP_SHELL_CANCELED_CTRL_C); iterations = 0; } /* Print benchmark results.*/ fapp_bench_print_results (desc); break; } } else {} } ERROR_2: fnet_socket_close(fapp_bench.socket_foreign); } ERROR_1: fnet_shell_println(desc, FAPP_BENCH_COMPLETED_STR); }
/************************************************************************ * NAME: fapp_bench_udp_tx * * DESCRIPTION: Start TX TCP Benchmark. ************************************************************************/ static void fapp_bench_udp_tx (struct fapp_bench_tx_params *params) { fnet_int32_t send_result; fnet_char_t ip_str[FNET_IP_ADDR_STR_SIZE]; fnet_index_t i; fnet_int32_t received; const struct linger linger_option = {FNET_TRUE, /*l_onoff*/ 4 /*l_linger*/ }; const fnet_size_t bufsize_option = FAPP_BENCH_SOCKET_BUF_SIZE; struct sockaddr foreign_addr; fnet_bool_t exit_flag = FNET_FALSE; fnet_int32_t sock_err; fnet_size_t option_len; fnet_shell_desc_t desc = params->desc; fnet_size_t packet_size = params->packet_size; fnet_index_t cur_packet_number; fnet_index_t iterations = params->iteration_number; fnet_address_family_t family = params->foreign_addr.sa_family; if(packet_size > FAPP_BENCH_BUFFER_SIZE) /* Check max size.*/ packet_size = FAPP_BENCH_BUFFER_SIZE; fapp_bench.socket_listen = FNET_ERR; /* ------ Start test.----------- */ fnet_shell_println(desc, FAPP_DELIMITER_STR); fnet_shell_println(desc, " UDP TX Test" ); fnet_shell_println(desc, FAPP_DELIMITER_STR); fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_S, "Remote IP addr", fnet_inet_ntop(family, params->foreign_addr.sa_data, ip_str, sizeof(ip_str))); fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Remote Port", fnet_ntohs(params->foreign_addr.sa_port)); fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Message Size", params->packet_size); fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Num. of messages", params->packet_number); fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Num. of iterations", params->iteration_number); fnet_shell_println(desc, FAPP_TOCANCEL_STR); fnet_shell_println(desc, FAPP_DELIMITER_STR); while(iterations--) { /* Create socket */ if((fapp_bench.socket_foreign = fnet_socket(family, SOCK_DGRAM, 0)) == FNET_ERR) { FNET_DEBUG("BENCH: Socket creation error.\n"); iterations = 0; goto ERROR_1; } /* Set Socket options. */ if( /* Setup linger option. */ (fnet_socket_setopt (fapp_bench.socket_foreign, SOL_SOCKET, SO_LINGER, (fnet_uint8_t *)&linger_option, sizeof(linger_option)) == FNET_ERR) || /* Set socket buffer size. */ (fnet_socket_setopt(fapp_bench.socket_foreign, SOL_SOCKET, SO_RCVBUF, (fnet_uint8_t *) &bufsize_option, sizeof(bufsize_option))== FNET_ERR) || (fnet_socket_setopt(fapp_bench.socket_foreign, SOL_SOCKET, SO_SNDBUF, (fnet_uint8_t *) &bufsize_option, sizeof(bufsize_option))== FNET_ERR) ) { FNET_DEBUG("BENCH: Socket setsockopt error.\n"); iterations = 0; goto ERROR_2; } /* Bind to the server.*/ fnet_shell_println(desc,"Connecting."); fnet_memcpy(&foreign_addr, ¶ms->foreign_addr, sizeof(foreign_addr)); if(fnet_socket_connect(fapp_bench.socket_foreign, &foreign_addr, sizeof(foreign_addr))== FNET_ERR) { fnet_shell_println(desc, "Connection failed."); iterations = 0; goto ERROR_2; } /* Sending.*/ fnet_shell_println(desc,"Sending."); fapp_bench.bytes = 0; fapp_bench.remote_bytes = 0; cur_packet_number = 0; fapp_bench.first_time = fnet_timer_ticks(); while(1) { send_result = fnet_socket_send( fapp_bench.socket_foreign, (fnet_uint8_t*)(&fapp_bench.buffer[0]), packet_size, 0); fapp_bench.last_time = fnet_timer_ticks(); if ( send_result == FNET_ERR ) { option_len = sizeof(sock_err); fnet_socket_getopt(fapp_bench.socket_foreign, SOL_SOCKET, SO_ERROR, (fnet_uint8_t*)&sock_err, &option_len); fnet_shell_println(desc, "socket_error = %d", sock_err); iterations = 0; goto ERROR_2; } else { fapp_bench.bytes += send_result; cur_packet_number ++; exit_flag = fnet_shell_ctrlc (desc); /* Check [Ctrl+c]*/ if((cur_packet_number >= params->packet_number)|| exit_flag) { if(exit_flag) { fnet_shell_println(desc, FAPP_SHELL_CANCELED_CTRL_C); iterations = 0; } break;/* => TX END. */ } } } /* Send End mark.*/ for(i=0; i < FAPP_BENCH_TX_UDP_END_ITERATIONS; i++) { fnet_uint32_t ack_bytes; /* Send END mark.*/ fnet_socket_send( fapp_bench.socket_foreign, (fnet_uint8_t*)(&fapp_bench.buffer[0]), 1, 0); fnet_timer_delay(1); /* Check ACK. It should contain recieved amount of data.*/ received = fnet_socket_recv(fapp_bench.socket_foreign, (fnet_uint8_t*)(&ack_bytes), sizeof(ack_bytes), 0); if(received == sizeof(ack_bytes)) /* ACK received.*/ { fapp_bench.remote_bytes = fnet_ntohl(ack_bytes); break; } else if(received == FNET_ERR) { break; } else {} } /* Print benchmark results.*/ fapp_bench_print_results (desc); ERROR_2: fnet_socket_close(fapp_bench.socket_foreign); } ERROR_1: fnet_shell_println(desc, FAPP_BENCH_COMPLETED_STR); }
/************************************************************************ * NAME: fnet_ping_state_machine * * DESCRIPTION: PING service state machine. ************************************************************************/ static void fnet_ping_state_machine(void *fnet_ping_if_p) { fnet_int32_t received; fnet_icmp_echo_header_t *hdr; fnet_ping_if_t *ping_if = (fnet_ping_if_t *)fnet_ping_if_p; struct sockaddr addr; fnet_size_t addr_len = sizeof(addr); switch(ping_if->state) { /*===================================*/ case FNET_PING_STATE_SENDING_REQUEST: /* Build message.*/ hdr = (fnet_icmp_echo_header_t *)&fnet_ping_if.buffer[0]; /* Fill ICMP Echo request header.*/ fnet_memset_zero(hdr, sizeof(*hdr)); hdr->header.type = (fnet_uint8_t)((fnet_ping_if.family == AF_INET) ? FNET_ICMP_ECHO: FNET_ICMP6_TYPE_ECHO_REQ); hdr->identifier = FNET_CFG_PING_IDENTIFIER; fnet_ping_if.sequence_number++; hdr->sequence_number = fnet_htons(fnet_ping_if.sequence_number); /* Fill payload data by pattern.*/ fnet_memset(&fnet_ping_if.buffer[sizeof(*hdr)], ping_if->pattern, ping_if->packet_size); /* Checksum.*/ #if FNET_CFG_IP4 if(ping_if->family == AF_INET) { hdr->header.checksum = fnet_checksum_buf(&fnet_ping_if.buffer[0], (sizeof(*hdr) + ping_if->packet_size)); } else #endif #if FNET_CFG_IP6 if(ping_if->family == AF_INET6) { const fnet_ip6_addr_t *src_ip = fnet_ip6_select_src_addr(FNET_NULL, (fnet_ip6_addr_t *)ping_if->target_addr.sa_data); /*TBD Check result.*/ hdr->header.checksum = fnet_checksum_pseudo_buf(&fnet_ping_if.buffer[0], (fnet_uint16_t)(sizeof(*hdr) + ping_if->packet_size), FNET_HTONS((fnet_uint16_t)IPPROTO_ICMPV6), (const fnet_uint8_t *)src_ip, ping_if->target_addr.sa_data, sizeof(fnet_ip6_addr_t)); } else #endif {} /* Send request.*/ fnet_socket_sendto(fnet_ping_if.socket_foreign, (fnet_uint8_t*)(&fnet_ping_if.buffer[0]), (sizeof(*hdr) + ping_if->packet_size), 0u, &ping_if->target_addr, sizeof(ping_if->target_addr)); ping_if->packet_count--; fnet_ping_if.send_time = fnet_timer_ticks(); ping_if->state = FNET_PING_STATE_WAITING_REPLY; break; /*===================================*/ case FNET_PING_STATE_WAITING_REPLY: /* Receive data */ received = fnet_socket_recvfrom(ping_if->socket_foreign, (fnet_uint8_t*)(&ping_if->buffer[0]), FNET_PING_BUFFER_SIZE, 0u, &addr, &addr_len ); if(received > 0 ) { fnet_uint16_t checksum = 0u; hdr = (fnet_icmp_echo_header_t *)(ping_if->buffer); /* Check checksum.*/ #if FNET_CFG_IP4 if(ping_if->family == AF_INET) { checksum = fnet_checksum_buf(&fnet_ping_if.buffer[0], (fnet_size_t)received); } else #endif #if 0 /* #if FNET_CFG_IP6 */ /* TBD case to receive from multicast address ff02::1*/ if(ping_if->family == AF_INET6) { checksum = fnet_checksum_pseudo_buf(&fnet_ping_if.buffer[0], (fnet_uint16_t)(received), IPPROTO_ICMPV6, ping_if->local_addr.sa_data, ping_if->target_addr.sa_data, sizeof(fnet_ip6_addr_t)); } else #endif {} /* Check header.*/ if( checksum ||(hdr->header.type != ((addr.sa_family == AF_INET) ? FNET_ICMP_ECHOREPLY: FNET_ICMP6_TYPE_ECHO_REPLY)) ||(hdr->identifier != FNET_CFG_PING_IDENTIFIER) ||(hdr->sequence_number != fnet_htons(ping_if->sequence_number)) ) { goto NO_DATA; } /* Call handler.*/ if(ping_if->handler) { ping_if->handler(FNET_ERR_OK, ping_if->packet_count, &addr, ping_if->handler_cookie); } if(ping_if->packet_count) { ping_if->state = FNET_PING_STATE_WAITING_TIMEOUT; } else { fnet_ping_release(); } } else if(received == FNET_ERR) { /* Call handler.*/ if(ping_if->handler) { fnet_error_t sock_err ; fnet_size_t option_len; /* Get socket error.*/ option_len = sizeof(sock_err); fnet_socket_getopt(ping_if->socket_foreign, SOL_SOCKET, SO_ERROR, (fnet_uint8_t*)&sock_err, &option_len); ping_if->handler(sock_err, ping_if->packet_count, FNET_NULL, ping_if->handler_cookie); } if(ping_if->packet_count) { ping_if->state = FNET_PING_STATE_WAITING_TIMEOUT; } else { fnet_ping_release(); } } else /* No data. Check timeout */ { NO_DATA: if(fnet_timer_get_interval(fnet_ping_if.send_time, fnet_timer_ticks()) > fnet_ping_if.timeout_clk) { /* Call handler.*/ if(ping_if->handler) { ping_if->handler(FNET_ERR_TIMEDOUT, ping_if->packet_count, FNET_NULL, ping_if->handler_cookie); } if(ping_if->packet_count) { ping_if->state = FNET_PING_STATE_SENDING_REQUEST; } else { fnet_ping_release(); } } } break; /*===================================*/ case FNET_PING_STATE_WAITING_TIMEOUT: if(fnet_timer_get_interval(fnet_ping_if.send_time, fnet_timer_ticks()) > fnet_ping_if.timeout_clk) { ping_if->state = FNET_PING_STATE_SENDING_REQUEST; } break; default: break; /* do nothing, avoid compiler warning "enumeration value not handled in switch" */ } }