Example #1
0
/************************************************************************
* NAME: fapp_bench_udp_rx
*
* DESCRIPTION: Start Benchmark UDP server.
************************************************************************/
static void fapp_bench_udp_rx (fnet_shell_desc_t desc, fnet_address_family_t family, struct sockaddr *multicast_address /* optional, set to 0*/)
{
    struct sockaddr         local_addr;
    const fnet_size_t       bufsize_option = FAPP_BENCH_SOCKET_BUF_SIZE;
    fnet_int32_t            received;
    fnet_char_t             ip_str[FNET_IP_ADDR_STR_SIZE];
    struct sockaddr         addr;
    fnet_size_t             addr_len;
    fnet_bool_t             is_first = FNET_TRUE;
    fnet_bool_t             exit_flag = FNET_FALSE;


    /* Create listen socket */
    if((fapp_bench.socket_listen = fnet_socket(family, SOCK_DGRAM, 0)) == FNET_ERR)
    {
        FNET_DEBUG("BENCH: Socket creation error.\n");
        goto ERROR_1;
    }

    /*Bind.*/
    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.\n");
        goto ERROR_2;
    }


    /* Set socket options. */
    if(
        /* 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)
    )
    {
        FNET_DEBUG("BENCH: Socket setsockopt error.\n");
        goto ERROR_2;
    }

    /* Join multicast group, if set. */
    if(multicast_address)
    {

#if FNET_CFG_IP4
        if(multicast_address->sa_family == AF_INET)
        {
            struct ip_mreq mreq; /* Multicast group information.*/

            mreq.imr_multiaddr.s_addr = ((struct sockaddr_in*)multicast_address)->sin_addr.s_addr;
            mreq.imr_interface = 0; /* Default Interface.*/

            /* Join multicast group. */
            if(fnet_socket_setopt(fapp_bench.socket_listen, IPPROTO_IP, IP_ADD_MEMBERSHIP, (fnet_uint8_t *)&mreq, sizeof(mreq)) == FNET_ERR)
            {
                FNET_DEBUG("BENCH: Joining to multicast group is failed.\n");
                goto ERROR_2;
            }
        }
#endif
#if FNET_CFG_IP6
        if(multicast_address->sa_family == AF_INET6)
        {
            struct ipv6_mreq mreq6; /* Multicast group information.*/

            FNET_IP6_ADDR_COPY(&((struct sockaddr_in6*)multicast_address)->sin6_addr.s6_addr, &mreq6.ipv6imr_multiaddr.s6_addr);
            mreq6.ipv6imr_interface = ((struct sockaddr_in6*)multicast_address)->sin6_scope_id;

            /* Join multicast group. */
            if(fnet_socket_setopt(fapp_bench.socket_listen, IPPROTO_IPV6, IPV6_JOIN_GROUP, (fnet_uint8_t *)&mreq6, sizeof(mreq6)) == FNET_ERR)
            {
                FNET_DEBUG("BENCH: Joining to multicast group is failed.\n");
                goto ERROR_2;
            }
        }
#endif

    }

    /* ------ Start test.----------- */
    fnet_shell_println(desc, FAPP_DELIMITER_STR);
    fnet_shell_println(desc, " UDP RX Test" );
    fnet_shell_println(desc, FAPP_DELIMITER_STR);
    fapp_netif_addr_print(desc, family, fnet_netif_get_default(), FNET_FALSE);
    if(multicast_address)
    {
        fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_S, "Multicast Group", fnet_inet_ntop(multicast_address->sa_family, (fnet_uint8_t*)(multicast_address->sa_data), ip_str, sizeof(ip_str)) );
    }
    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) /* Main loop */
    {
        fnet_shell_println(desc, "Waiting.");

        fapp_bench.bytes = 0;
        fapp_bench.remote_bytes = 0;
        addr_len = sizeof(addr);
        is_first = FNET_TRUE;

        while(exit_flag == FNET_FALSE) /* Test loop. */
        {

            /* Receive data */
            received = fnet_socket_recvfrom  (fapp_bench.socket_listen, (fnet_uint8_t*)(&fapp_bench.buffer[0]), FAPP_BENCH_BUFFER_SIZE, 0,
                                              &addr, &addr_len );

            if(received >= FAPP_BENCH_UDP_END_BUFFER_LENGTH)
            {

                /* Reset timeout. */
                fapp_bench.last_time = fnet_timer_ticks();

                if(is_first)
                {
                    if( received > FAPP_BENCH_UDP_END_BUFFER_LENGTH )
                    {
                        fnet_shell_println(desc,"Receiving from %s:%d",  fnet_inet_ntop(addr.sa_family, (fnet_uint8_t*)(addr.sa_data), ip_str, sizeof(ip_str)), fnet_ntohs(addr.sa_port));
                        fapp_bench.first_time = fnet_timer_ticks();
                        is_first = FNET_FALSE;
                    }
                }
                else
                {
                    if(received == FAPP_BENCH_UDP_END_BUFFER_LENGTH ) /* End of transfer. */
                    {
                        /* Send ACK containing amount of received data.*/
                        fnet_uint32_t ack_bytes = fnet_htonl(fapp_bench.bytes);

                        /* Send several times, just to be sure that it is received/not lost.*/
                        fnet_socket_sendto(fapp_bench.socket_listen, (fnet_uint8_t*)(&ack_bytes), sizeof(ack_bytes), 0, (struct sockaddr*)&addr, sizeof(addr));
                        fnet_socket_sendto(fapp_bench.socket_listen, (fnet_uint8_t*)(&ack_bytes), sizeof(ack_bytes), 0, (struct sockaddr*)&addr, sizeof(addr));
                        fnet_socket_sendto(fapp_bench.socket_listen, (fnet_uint8_t*)(&ack_bytes), sizeof(ack_bytes), 0, (struct sockaddr*)&addr, sizeof(addr));

                        /* Print benchmark results.*/
                        fapp_bench_print_results (desc);

                        break;
                    }
                    else
                        fapp_bench.bytes += received;
                }
            }
            else
            {
                /* Check error. Check timeout */
                if(received == FNET_ERR)
                {
                    fnet_shell_println(desc, "BENCH: Error (%d).", fnet_error_get());
                    break;
                }
                /* Check timeout. */
                if((is_first == FNET_FALSE) &&
                        (fnet_timer_get_interval(fapp_bench.last_time, fnet_timer_ticks()) > (FAPP_UDP_TIMEOUT_MS/FNET_TIMER_PERIOD_MS)))
                {
                    fnet_shell_println(desc, "BENCH: Exit on timeout.");
                    fapp_bench_print_results (desc);
                    break;
                }
            }

            exit_flag = fnet_shell_ctrlc (desc);
        }
    }

ERROR_2:
    fnet_socket_close(fapp_bench.socket_listen);

ERROR_1:

    fnet_shell_println(desc, FAPP_BENCH_COMPLETED_STR);
}
Example #2
0
/************************************************************************
* 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" */
    }
}