mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Merge pull request #9875 from tymoteuszblochmobica/testfix
Apply proper network interface verification. Only run for platforms which have two interfaces and prevent crashes otherwise.pull/9930/head
						commit
						355f09bbac
					
				| 
						 | 
				
			
			@ -24,7 +24,12 @@
 | 
			
		|||
#error [NOT_SUPPORTED] Requires parameters from mbed_app.json
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "mbed.h"
 | 
			
		||||
#if !defined(DEVICE_EMAC) || \
 | 
			
		||||
    (!defined(MBED_CONF_APP_WIFI_SECURE_SSID) && !defined(MBED_CONF_APP_WIFI_UNSECURE_SSID))
 | 
			
		||||
#error [NOT_SUPPORTED] Both Wifi and Ethernet devices are required for multihoming tests.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "greentea-client/test_env.h"
 | 
			
		||||
#include "unity/unity.h"
 | 
			
		||||
#include "utest.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +39,8 @@
 | 
			
		|||
using namespace utest::v1;
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
NetworkInterface *net;
 | 
			
		||||
EthInterface *eth;
 | 
			
		||||
WiFiInterface *wifi;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char interface_name[MBED_CONF_MULTIHOMING_MAX_INTERFACES_NUM][INTERFACE_NAME_LEN];
 | 
			
		||||
| 
						 | 
				
			
			@ -48,26 +54,27 @@ mbed_stats_socket_t udp_stats[MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT];
 | 
			
		|||
#define SSID_MAX_LEN 32
 | 
			
		||||
#define PWD_MAX_LEN 64
 | 
			
		||||
 | 
			
		||||
WiFiInterface *wifi;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
NetworkInterface *get_interface()
 | 
			
		||||
NetworkInterface *get_interface(int interface_index)
 | 
			
		||||
{
 | 
			
		||||
    return net;
 | 
			
		||||
    if (interface_index == ETH_INTERFACE) {
 | 
			
		||||
        return eth;
 | 
			
		||||
    } else if (interface_index == WIFI_INTERFACE) {
 | 
			
		||||
        return wifi;
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _ifup()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#if DEVICE_EMAC
 | 
			
		||||
    net = EthInterface::get_default_instance();
 | 
			
		||||
    nsapi_error_t err = net->connect();
 | 
			
		||||
    net->get_interface_name(interface_name[0]);
 | 
			
		||||
    interface_num++;
 | 
			
		||||
    eth = EthInterface::get_default_instance();
 | 
			
		||||
    nsapi_error_t err = eth->connect();
 | 
			
		||||
    eth->get_interface_name(interface_name[interface_num]);
 | 
			
		||||
    TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);
 | 
			
		||||
    printf("MBED: IP address is '%s' interface name %s\n", net->get_ip_address(), interface_name[0]);
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(MBED_CONF_APP_WIFI_SECURE_SSID) || defined(MBED_CONF_APP_WIFI_UNSECURE_SSID)
 | 
			
		||||
    printf("MBED: IP address is '%s' interface name %s\n", eth->get_ip_address(), interface_name[interface_num]);
 | 
			
		||||
    interface_num++;
 | 
			
		||||
 | 
			
		||||
    wifi = WiFiInterface::get_default_instance();
 | 
			
		||||
 | 
			
		||||
    if (wifi) {
 | 
			
		||||
| 
						 | 
				
			
			@ -88,27 +95,29 @@ static void _ifup()
 | 
			
		|||
            TEST_FAIL_MESSAGE("Wifi connection error!");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        wifi->get_interface_name(interface_name[1]);
 | 
			
		||||
        interface_num++;
 | 
			
		||||
        wifi->get_interface_name(interface_name[interface_num]);
 | 
			
		||||
        printf("MAC: %s\n", wifi->get_mac_address());
 | 
			
		||||
        printf("IP: %s\n", wifi->get_ip_address());
 | 
			
		||||
        printf("Netmask: %s\n", wifi->get_netmask());
 | 
			
		||||
        printf("Gateway: %s\n", wifi->get_gateway());
 | 
			
		||||
        printf("RSSI: %d\n\n", wifi->get_rssi());
 | 
			
		||||
        printf("Wifi interface name: %s\n\n", interface_name[1]);
 | 
			
		||||
 | 
			
		||||
        printf("Wifi interface name: %s\n\n", interface_name[interface_num]);
 | 
			
		||||
        interface_num++;
 | 
			
		||||
    } else {
 | 
			
		||||
        TEST_FAIL_MESSAGE("ERROR: No WiFiInterface found!");
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _ifdown()
 | 
			
		||||
{
 | 
			
		||||
    interface_num = 0;
 | 
			
		||||
    net->disconnect();
 | 
			
		||||
    if (eth != NULL) {
 | 
			
		||||
        eth->disconnect();
 | 
			
		||||
    }
 | 
			
		||||
#if defined(MBED_CONF_APP_WIFI_SECURE_SSID) || defined(MBED_CONF_APP_WIFI_UNSECURE_SSID)
 | 
			
		||||
    wifi->disconnect();
 | 
			
		||||
    if (wifi != NULL) {
 | 
			
		||||
        wifi->disconnect();
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    printf("MBED: ifdown\n");
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,35 +55,41 @@ void MULTIHOMING_ASYNCHRONOUS_DNS()
 | 
			
		|||
 | 
			
		||||
    for (unsigned int i = 0; i < MBED_CONF_APP_DNS_TEST_HOSTS_NUM; i++) {
 | 
			
		||||
 | 
			
		||||
        for (unsigned int j = 0; j < interface_num; j++) {
 | 
			
		||||
 | 
			
		||||
            nsapi_error_t err = get_interface()->gethostbyname_async(dns_test_hosts[i],
 | 
			
		||||
                                                                     mbed::Callback<void(nsapi_error_t, SocketAddress *)>(hostbyname_cb, (void *) &data), NSAPI_UNSPEC, interface_name[j]);
 | 
			
		||||
            TEST_ASSERT(err >= 0);
 | 
			
		||||
 | 
			
		||||
            semaphore.wait();
 | 
			
		||||
 | 
			
		||||
            TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, data.result);
 | 
			
		||||
            printf("DNS: query  interface_name %s %d \n", interface_name[j], j);
 | 
			
		||||
            if (data.result == NSAPI_ERROR_OK) {
 | 
			
		||||
                result_ok++;
 | 
			
		||||
                printf("DNS: query OK \"%s\" => \"%s\"\n", dns_test_hosts[i], data.addr.get_ip_address());
 | 
			
		||||
            } else if (data.result == NSAPI_ERROR_DNS_FAILURE) {
 | 
			
		||||
                result_dns_failure++;
 | 
			
		||||
                printf("DNS: query \"%s\" => DNS failure\n", dns_test_hosts[i]);
 | 
			
		||||
            } else if (data.result == NSAPI_ERROR_TIMEOUT) {
 | 
			
		||||
                result_exp_timeout++;
 | 
			
		||||
                printf("DNS: query \"%s\" => timeout\n", dns_test_hosts[i]);
 | 
			
		||||
            } else if (data.result == NSAPI_ERROR_NO_MEMORY) {
 | 
			
		||||
                result_no_mem++;
 | 
			
		||||
                printf("DNS: query \"%s\" => no memory\n", dns_test_hosts[i]);
 | 
			
		||||
            } else {
 | 
			
		||||
                printf("DNS: query \"%s\" => %d, unexpected answer\n", dns_test_hosts[i], data.result);
 | 
			
		||||
                TEST_ASSERT(data.result == NSAPI_ERROR_OK || data.result == NSAPI_ERROR_NO_MEMORY || data.result == NSAPI_ERROR_DNS_FAILURE || data.result == NSAPI_ERROR_TIMEOUT);
 | 
			
		||||
        for (unsigned int interface_index = 0; interface_index < MBED_CONF_MULTIHOMING_MAX_INTERFACES_NUM; interface_index++) {
 | 
			
		||||
            NetworkInterface  *interface = get_interface(interface_index);
 | 
			
		||||
            if (interface == NULL) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
            for (unsigned int j = 0; j < interface_num; j++) {
 | 
			
		||||
 | 
			
		||||
                nsapi_error_t err = interface->gethostbyname_async(dns_test_hosts[i],
 | 
			
		||||
                                                                       mbed::Callback<void(nsapi_error_t, SocketAddress *)>(hostbyname_cb, (void *) &data), NSAPI_UNSPEC, interface_name[j]);
 | 
			
		||||
                TEST_ASSERT(err >= 0);
 | 
			
		||||
 | 
			
		||||
                semaphore.wait();
 | 
			
		||||
 | 
			
		||||
                TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, data.result);
 | 
			
		||||
                printf("DNS: query  interface_name %s %d \n", interface_name[j], j);
 | 
			
		||||
                if (data.result == NSAPI_ERROR_OK) {
 | 
			
		||||
                    result_ok++;
 | 
			
		||||
                    printf("DNS: query OK \"%s\" => \"%s\"\n", dns_test_hosts[i], data.addr.get_ip_address());
 | 
			
		||||
                } else if (data.result == NSAPI_ERROR_DNS_FAILURE) {
 | 
			
		||||
                    result_dns_failure++;
 | 
			
		||||
                    printf("DNS: query \"%s\" => DNS failure\n", dns_test_hosts[i]);
 | 
			
		||||
                } else if (data.result == NSAPI_ERROR_TIMEOUT) {
 | 
			
		||||
                    result_exp_timeout++;
 | 
			
		||||
                    printf("DNS: query \"%s\" => timeout\n", dns_test_hosts[i]);
 | 
			
		||||
                } else if (data.result == NSAPI_ERROR_NO_MEMORY) {
 | 
			
		||||
                    result_no_mem++;
 | 
			
		||||
                    printf("DNS: query \"%s\" => no memory\n", dns_test_hosts[i]);
 | 
			
		||||
                } else {
 | 
			
		||||
                    printf("DNS: query \"%s\" => %d, unexpected answer\n", dns_test_hosts[i], data.result);
 | 
			
		||||
                    TEST_ASSERT(data.result == NSAPI_ERROR_OK || data.result == NSAPI_ERROR_NO_MEMORY || data.result == NSAPI_ERROR_DNS_FAILURE || data.result == NSAPI_ERROR_TIMEOUT);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,29 +44,35 @@ void MULTIHOMING_SYNCHRONOUS_DNS()
 | 
			
		|||
 | 
			
		||||
    for (unsigned int i = 0; i < MBED_CONF_APP_DNS_TEST_HOSTS_NUM; i++) {
 | 
			
		||||
        SocketAddress address;
 | 
			
		||||
        for (unsigned int j = 0; j < interface_num; j++) {
 | 
			
		||||
 | 
			
		||||
            nsapi_error_t err = get_interface()->gethostbyname(dns_test_hosts[i], &address, NSAPI_UNSPEC, interface_name[j]);
 | 
			
		||||
            printf("DNS: query  interface_name %s %d \n", interface_name[j], j);
 | 
			
		||||
 | 
			
		||||
            if (err == NSAPI_ERROR_OK) {
 | 
			
		||||
                result_ok++;
 | 
			
		||||
                printf("DNS: query OK \"%s\" => \"%s\"\n", dns_test_hosts[i], address.get_ip_address());
 | 
			
		||||
            } else if (err == NSAPI_ERROR_DNS_FAILURE) {
 | 
			
		||||
                result_dns_failure++;
 | 
			
		||||
                printf("DNS: query \"%s\" => DNS failure\n", dns_test_hosts[i]);
 | 
			
		||||
            } else if (err == NSAPI_ERROR_TIMEOUT) {
 | 
			
		||||
                result_exp_timeout++;
 | 
			
		||||
                printf("DNS: query \"%s\" => timeout\n", dns_test_hosts[i]);
 | 
			
		||||
            } else if (err == NSAPI_ERROR_NO_MEMORY) {
 | 
			
		||||
                result_no_mem++;
 | 
			
		||||
                printf("DNS: query \"%s\" => no memory\n", dns_test_hosts[i]);
 | 
			
		||||
            } else {
 | 
			
		||||
                printf("DNS: query \"%s\" => %d, unexpected answer\n", dns_test_hosts[i], err);
 | 
			
		||||
                TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_NO_MEMORY || err == NSAPI_ERROR_DNS_FAILURE || err == NSAPI_ERROR_TIMEOUT);
 | 
			
		||||
        for (unsigned int interface_index = 0; interface_index < MBED_CONF_MULTIHOMING_MAX_INTERFACES_NUM; interface_index++) {
 | 
			
		||||
            NetworkInterface  *interface = get_interface(interface_index);
 | 
			
		||||
            if (interface == NULL) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (unsigned int j = 0; j < interface_num; j++) {
 | 
			
		||||
 | 
			
		||||
                nsapi_error_t err = interface->gethostbyname(dns_test_hosts[i], &address, NSAPI_UNSPEC, interface_name[j]);
 | 
			
		||||
                printf("DNS: query  interface_name %s %d \n", interface_name[j], j);
 | 
			
		||||
 | 
			
		||||
                if (err == NSAPI_ERROR_OK) {
 | 
			
		||||
                    result_ok++;
 | 
			
		||||
                    printf("DNS: query OK \"%s\" => \"%s\"\n", dns_test_hosts[i], address.get_ip_address());
 | 
			
		||||
                } else if (err == NSAPI_ERROR_DNS_FAILURE) {
 | 
			
		||||
                    result_dns_failure++;
 | 
			
		||||
                    printf("DNS: query \"%s\" => DNS failure\n", dns_test_hosts[i]);
 | 
			
		||||
                } else if (err == NSAPI_ERROR_TIMEOUT) {
 | 
			
		||||
                    result_exp_timeout++;
 | 
			
		||||
                    printf("DNS: query \"%s\" => timeout\n", dns_test_hosts[i]);
 | 
			
		||||
                } else if (err == NSAPI_ERROR_NO_MEMORY) {
 | 
			
		||||
                    result_no_mem++;
 | 
			
		||||
                    printf("DNS: query \"%s\" => no memory\n", dns_test_hosts[i]);
 | 
			
		||||
                } else {
 | 
			
		||||
                    printf("DNS: query \"%s\" => %d, unexpected answer\n", dns_test_hosts[i], err);
 | 
			
		||||
                    TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_NO_MEMORY || err == NSAPI_ERROR_DNS_FAILURE || err == NSAPI_ERROR_TIMEOUT);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,8 @@
 | 
			
		|||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "mbed.h"
 | 
			
		||||
 | 
			
		||||
#ifndef MULTIHOMING_TESTS_H
 | 
			
		||||
#define MULTIHOMING_TESTS_H
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -22,7 +24,7 @@
 | 
			
		|||
#define INTERFACE_NAME_LEN 6
 | 
			
		||||
 | 
			
		||||
#ifndef MBED_CONF_MULTIHOMING_MAX_INTERFACES_NUM
 | 
			
		||||
#define MBED_CONF_MULTIHOMING_MAX_INTERFACES_NUM    3
 | 
			
		||||
#define MBED_CONF_MULTIHOMING_MAX_INTERFACES_NUM    2
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef MBED_CONF_APP_DNS_TEST_HOSTS_NUM
 | 
			
		||||
| 
						 | 
				
			
			@ -36,6 +38,8 @@
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define ETH_INTERFACE  0
 | 
			
		||||
#define WIFI_INTERFACE 1
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct dns_application_data {
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +57,7 @@ extern int  interface_num;
 | 
			
		|||
const char dns_test_hosts[MBED_CONF_APP_DNS_TEST_HOSTS_NUM][DNS_TEST_HOST_LEN] = MBED_CONF_APP_DNS_TEST_HOSTS;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
NetworkInterface *get_interface();
 | 
			
		||||
NetworkInterface *get_interface(int interface_index);
 | 
			
		||||
void drop_bad_packets(UDPSocket &sock, int orig_timeout);
 | 
			
		||||
void fill_tx_buffer_ascii(char *buff, size_t len);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,50 +54,56 @@ static void _sigio_handler(osThreadId id)
 | 
			
		|||
 | 
			
		||||
void MULTIHOMING_UDPSOCKET_ECHOTEST()
 | 
			
		||||
{
 | 
			
		||||
    SocketAddress udp_addr;
 | 
			
		||||
    get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr);
 | 
			
		||||
    udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
 | 
			
		||||
 | 
			
		||||
    UDPSocket sock;
 | 
			
		||||
    TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface()));
 | 
			
		||||
    for (unsigned int interface_index = 0; interface_index < MBED_CONF_MULTIHOMING_MAX_INTERFACES_NUM; interface_index++) {
 | 
			
		||||
        NetworkInterface  *interface = get_interface(interface_index);
 | 
			
		||||
        if (interface == NULL) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        SocketAddress udp_addr;
 | 
			
		||||
        interface->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr);
 | 
			
		||||
        udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
 | 
			
		||||
 | 
			
		||||
    for (unsigned int j = 0; j < interface_num; j++) {
 | 
			
		||||
        int recvd;
 | 
			
		||||
        int sent;
 | 
			
		||||
        int s_idx = 0;
 | 
			
		||||
        int packets_sent = 0;
 | 
			
		||||
        int packets_recv = 0;
 | 
			
		||||
        sock.setsockopt(NSAPI_SOCKET, NSAPI_BIND_TO_DEVICE, interface_name[j], INTERFACE_NAME_LEN);
 | 
			
		||||
        for (int pkt_s = pkt_sizes[s_idx]; s_idx < PKTS; pkt_s = ++s_idx) {
 | 
			
		||||
            pkt_s = pkt_sizes[s_idx];
 | 
			
		||||
            fill_tx_buffer_ascii(tx_buffer, BUFF_SIZE);
 | 
			
		||||
            for (int retry_cnt = 0; retry_cnt <= 2; retry_cnt++) {
 | 
			
		||||
                memset(rx_buffer, 0, BUFF_SIZE);
 | 
			
		||||
                sent = sock.sendto(udp_addr, tx_buffer, pkt_s);
 | 
			
		||||
                if (sent > 0) {
 | 
			
		||||
                    packets_sent++;
 | 
			
		||||
        UDPSocket sock;
 | 
			
		||||
        TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(interface));
 | 
			
		||||
        for (unsigned int j = 0; j < interface_num; j++) {
 | 
			
		||||
            int recvd;
 | 
			
		||||
            int sent;
 | 
			
		||||
            int s_idx = 0;
 | 
			
		||||
            int packets_sent = 0;
 | 
			
		||||
            int packets_recv = 0;
 | 
			
		||||
            sock.setsockopt(NSAPI_SOCKET, NSAPI_BIND_TO_DEVICE, interface_name[j], INTERFACE_NAME_LEN);
 | 
			
		||||
            for (int pkt_s = pkt_sizes[s_idx]; s_idx < PKTS; pkt_s = ++s_idx) {
 | 
			
		||||
                pkt_s = pkt_sizes[s_idx];
 | 
			
		||||
                fill_tx_buffer_ascii(tx_buffer, BUFF_SIZE);
 | 
			
		||||
                for (int retry_cnt = 0; retry_cnt <= 2; retry_cnt++) {
 | 
			
		||||
                    memset(rx_buffer, 0, BUFF_SIZE);
 | 
			
		||||
                    sent = sock.sendto(udp_addr, tx_buffer, pkt_s);
 | 
			
		||||
                    if (sent > 0) {
 | 
			
		||||
                        packets_sent++;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (sent != pkt_s) {
 | 
			
		||||
                        printf("[Round#%02d - Sender] error, returned %d\n", s_idx, sent);
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                    recvd = sock.recvfrom(NULL, rx_buffer, pkt_s);
 | 
			
		||||
                    if (recvd == pkt_s) {
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (sent != pkt_s) {
 | 
			
		||||
                    printf("[Round#%02d - Sender] error, returned %d\n", s_idx, sent);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                recvd = sock.recvfrom(NULL, rx_buffer, pkt_s);
 | 
			
		||||
                if (recvd == pkt_s) {
 | 
			
		||||
                    break;
 | 
			
		||||
                if (memcmp(tx_buffer, rx_buffer, pkt_s) == 0) {
 | 
			
		||||
                    packets_recv++;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (memcmp(tx_buffer, rx_buffer, pkt_s) == 0) {
 | 
			
		||||
                packets_recv++;
 | 
			
		||||
            // Packet loss up to 30% tolerated
 | 
			
		||||
            if (packets_sent > 0) {
 | 
			
		||||
                double loss_ratio = 1 - ((double)packets_recv / (double)packets_sent);
 | 
			
		||||
                printf("Interface %s, packets sent: %d, packets received %d, loss ratio %.2lf\r\n", interface_name[j], packets_sent, packets_recv, loss_ratio);
 | 
			
		||||
                TEST_ASSERT_DOUBLE_WITHIN(TOLERATED_LOSS_RATIO, EXPECTED_LOSS_RATIO, loss_ratio);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // Packet loss up to 30% tolerated
 | 
			
		||||
        if (packets_sent > 0) {
 | 
			
		||||
            double loss_ratio = 1 - ((double)packets_recv / (double)packets_sent);
 | 
			
		||||
            printf("Interface %s, packets sent: %d, packets received %d, loss ratio %.2lf\r\n", interface_name[j], packets_sent, packets_recv, loss_ratio);
 | 
			
		||||
            TEST_ASSERT_DOUBLE_WITHIN(TOLERATED_LOSS_RATIO, EXPECTED_LOSS_RATIO, loss_ratio);
 | 
			
		||||
        }
 | 
			
		||||
        TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
 | 
			
		||||
    }
 | 
			
		||||
    TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void udpsocket_echotest_nonblock_receiver(void *receive_bytes)
 | 
			
		||||
| 
						 | 
				
			
			@ -127,83 +133,87 @@ void MULTIHOMING_UDPSOCKET_ECHOTEST_NONBLOCK()
 | 
			
		|||
        TEST_ASSERT_EQUAL(SOCK_CLOSED, udp_stats[j].state);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    for (unsigned int interface_index = 0; interface_index < MBED_CONF_MULTIHOMING_MAX_INTERFACES_NUM; interface_index++) {
 | 
			
		||||
        NetworkInterface  *interface = get_interface(interface_index);
 | 
			
		||||
        if (interface == NULL) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        SocketAddress udp_addr;
 | 
			
		||||
        interface->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr);
 | 
			
		||||
        udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
 | 
			
		||||
        TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(interface));
 | 
			
		||||
        sock.set_blocking(false);
 | 
			
		||||
        sock.sigio(callback(_sigio_handler, ThisThread::get_id()));
 | 
			
		||||
        for (unsigned int j = 0; j < interface_num; j++) {
 | 
			
		||||
            int s_idx = 0;
 | 
			
		||||
            int packets_sent = 0;
 | 
			
		||||
            int packets_recv = 0;
 | 
			
		||||
            int sent;
 | 
			
		||||
            Thread *thread;
 | 
			
		||||
            unsigned char *stack_mem = (unsigned char *)malloc(OS_STACK_SIZE);
 | 
			
		||||
            sock.setsockopt(NSAPI_SOCKET, NSAPI_BIND_TO_DEVICE, interface_name[j], INTERFACE_NAME_LEN);
 | 
			
		||||
            TEST_ASSERT_NOT_NULL(stack_mem);
 | 
			
		||||
 | 
			
		||||
    SocketAddress udp_addr;
 | 
			
		||||
    get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr);
 | 
			
		||||
    udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
 | 
			
		||||
            for (int pkt_s = pkt_sizes[s_idx]; s_idx < PKTS; ++s_idx) {
 | 
			
		||||
                pkt_s = pkt_sizes[s_idx];
 | 
			
		||||
 | 
			
		||||
    TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface()));
 | 
			
		||||
    sock.set_blocking(false);
 | 
			
		||||
    sock.sigio(callback(_sigio_handler, ThisThread::get_id()));
 | 
			
		||||
    for (unsigned int j = 0; j < interface_num; j++) {
 | 
			
		||||
        int s_idx = 0;
 | 
			
		||||
        int packets_sent = 0;
 | 
			
		||||
        int packets_recv = 0;
 | 
			
		||||
        int sent;
 | 
			
		||||
        Thread *thread;
 | 
			
		||||
        unsigned char *stack_mem = (unsigned char *)malloc(OS_STACK_SIZE);
 | 
			
		||||
        sock.setsockopt(NSAPI_SOCKET, NSAPI_BIND_TO_DEVICE, interface_name[j], INTERFACE_NAME_LEN);
 | 
			
		||||
        TEST_ASSERT_NOT_NULL(stack_mem);
 | 
			
		||||
                thread = new Thread(osPriorityNormal,
 | 
			
		||||
                                    OS_STACK_SIZE,
 | 
			
		||||
                                    stack_mem,
 | 
			
		||||
                                    "receiver");
 | 
			
		||||
                TEST_ASSERT_EQUAL(osOK, thread->start(callback(udpsocket_echotest_nonblock_receiver, &pkt_s)));
 | 
			
		||||
 | 
			
		||||
        for (int pkt_s = pkt_sizes[s_idx]; s_idx < PKTS; ++s_idx) {
 | 
			
		||||
            pkt_s = pkt_sizes[s_idx];
 | 
			
		||||
                for (int retry_cnt = 0; retry_cnt <= RETRIES; retry_cnt++) {
 | 
			
		||||
                    fill_tx_buffer_ascii(tx_buffer, pkt_s);
 | 
			
		||||
 | 
			
		||||
            thread = new Thread(osPriorityNormal,
 | 
			
		||||
                                OS_STACK_SIZE,
 | 
			
		||||
                                stack_mem,
 | 
			
		||||
                                "receiver");
 | 
			
		||||
            TEST_ASSERT_EQUAL(osOK, thread->start(callback(udpsocket_echotest_nonblock_receiver, &pkt_s)));
 | 
			
		||||
 | 
			
		||||
            for (int retry_cnt = 0; retry_cnt <= RETRIES; retry_cnt++) {
 | 
			
		||||
                fill_tx_buffer_ascii(tx_buffer, pkt_s);
 | 
			
		||||
 | 
			
		||||
                sent = sock.sendto(udp_addr, tx_buffer, pkt_s);
 | 
			
		||||
                if (sent > 0) {
 | 
			
		||||
                    packets_sent++;
 | 
			
		||||
                }
 | 
			
		||||
                if (sent == NSAPI_ERROR_WOULD_BLOCK) {
 | 
			
		||||
                    if (osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) {
 | 
			
		||||
                    sent = sock.sendto(udp_addr, tx_buffer, pkt_s);
 | 
			
		||||
                    if (sent > 0) {
 | 
			
		||||
                        packets_sent++;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (sent == NSAPI_ERROR_WOULD_BLOCK) {
 | 
			
		||||
                        if (osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) {
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                        --retry_cnt;
 | 
			
		||||
                    } else if (sent != pkt_s) {
 | 
			
		||||
                        printf("[Round#%02d - Sender] error, returned %d\n", s_idx, sent);
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (tx_sem.wait(WAIT2RECV_TIMEOUT * 2) == 0) { // RX might wait up to WAIT2RECV_TIMEOUT before recvfrom
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                    --retry_cnt;
 | 
			
		||||
                } else if (sent != pkt_s) {
 | 
			
		||||
                    printf("[Round#%02d - Sender] error, returned %d\n", s_idx, sent);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                if (tx_sem.wait(WAIT2RECV_TIMEOUT * 2) == 0) { // RX might wait up to WAIT2RECV_TIMEOUT before recvfrom
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            thread->join();
 | 
			
		||||
            delete thread;
 | 
			
		||||
            if (memcmp(tx_buffer, rx_buffer, pkt_s) == 0) {
 | 
			
		||||
                packets_recv++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        free(stack_mem);
 | 
			
		||||
 | 
			
		||||
        // Packet loss up to 30% tolerated
 | 
			
		||||
        if (packets_sent > 0) {
 | 
			
		||||
            double loss_ratio = 1 - ((double)packets_recv / (double)packets_sent);
 | 
			
		||||
            printf("Interface %s, Packets sent: %d, packets received %d, loss ratio %.2lf\r\n", interface_name[j], packets_sent, packets_recv, loss_ratio);
 | 
			
		||||
            TEST_ASSERT_DOUBLE_WITHIN(TOLERATED_LOSS_RATIO, EXPECTED_LOSS_RATIO, loss_ratio);
 | 
			
		||||
 | 
			
		||||
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLED
 | 
			
		||||
            count = fetch_stats();
 | 
			
		||||
            for (j = 0; j < count; j++) {
 | 
			
		||||
                if ((NSAPI_UDP == udp_stats[j].proto) && (SOCK_OPEN == udp_stats[j].state)) {
 | 
			
		||||
                    TEST_ASSERT(udp_stats[j].sent_bytes != 0);
 | 
			
		||||
                    TEST_ASSERT(udp_stats[j].recv_bytes != 0);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                thread->join();
 | 
			
		||||
                delete thread;
 | 
			
		||||
                if (memcmp(tx_buffer, rx_buffer, pkt_s) == 0) {
 | 
			
		||||
                    packets_recv++;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            loss_ratio = 1 - ((double)udp_stats[j].recv_bytes / (double)udp_stats[j].sent_bytes);
 | 
			
		||||
            printf("Bytes sent: %d, bytes received %d, loss ratio %.2lf\r\n", udp_stats[j].sent_bytes, udp_stats[j].recv_bytes, loss_ratio);
 | 
			
		||||
            TEST_ASSERT_DOUBLE_WITHIN(TOLERATED_LOSS_RATIO, EXPECTED_LOSS_RATIO, loss_ratio);
 | 
			
		||||
            free(stack_mem);
 | 
			
		||||
 | 
			
		||||
            // Packet loss up to 30% tolerated
 | 
			
		||||
            if (packets_sent > 0) {
 | 
			
		||||
                double loss_ratio = 1 - ((double)packets_recv / (double)packets_sent);
 | 
			
		||||
                printf("Interface %s, Packets sent: %d, packets received %d, loss ratio %.2lf\r\n", interface_name[j], packets_sent, packets_recv, loss_ratio);
 | 
			
		||||
                TEST_ASSERT_DOUBLE_WITHIN(TOLERATED_LOSS_RATIO, EXPECTED_LOSS_RATIO, loss_ratio);
 | 
			
		||||
 | 
			
		||||
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLED
 | 
			
		||||
                count = fetch_stats();
 | 
			
		||||
                for (j = 0; j < count; j++) {
 | 
			
		||||
                    if ((NSAPI_UDP == udp_stats[j].proto) && (SOCK_OPEN == udp_stats[j].state)) {
 | 
			
		||||
                        TEST_ASSERT(udp_stats[j].sent_bytes != 0);
 | 
			
		||||
                        TEST_ASSERT(udp_stats[j].recv_bytes != 0);
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                loss_ratio = 1 - ((double)udp_stats[j].recv_bytes / (double)udp_stats[j].sent_bytes);
 | 
			
		||||
                printf("Bytes sent: %d, bytes received %d, loss ratio %.2lf\r\n", udp_stats[j].sent_bytes, udp_stats[j].recv_bytes, loss_ratio);
 | 
			
		||||
                TEST_ASSERT_DOUBLE_WITHIN(TOLERATED_LOSS_RATIO, EXPECTED_LOSS_RATIO, loss_ratio);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
 | 
			
		||||
    }
 | 
			
		||||
    TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue