/************************************************************************
* 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);
}
/************************************************************************
* 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, &params->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);
}
Exemple #3
0
/************************************************************************
* 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);
    }
}