|
25 | 25 |
|
26 | 26 | #define SIGNAL_SIGIO 0x1
|
27 | 27 | #define SIGIO_TIMEOUT 5000 //[ms]
|
| 28 | +#define RECV_TIMEOUT 1 //[s] |
28 | 29 |
|
29 | 30 | namespace
|
30 | 31 | {
|
@@ -56,78 +57,86 @@ void free_tx_buffers() {
|
56 | 57 | }
|
57 | 58 | }
|
58 | 59 |
|
| 60 | +static void _sigio_handler(osThreadId id) { |
| 61 | + osSignalSet(id, SIGNAL_SIGIO); |
| 62 | +} |
| 63 | + |
59 | 64 | void test_udpsocket_echotest_burst()
|
60 | 65 | {
|
61 | 66 | SocketAddress udp_addr;
|
62 | 67 | get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr);
|
63 | 68 | udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
|
64 | 69 |
|
65 | 70 | UDPSocket sock;
|
| 71 | + const int TIMEOUT = 5000; // [ms] |
66 | 72 | TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface()));
|
67 |
| - sock.set_timeout(5000); |
| 73 | + sock.set_timeout(TIMEOUT); |
| 74 | + sock.sigio(callback(_sigio_handler, Thread::gettid())); |
68 | 75 |
|
69 | 76 | // TX buffers to be preserved for comparison
|
70 | 77 | prepare_tx_buffers();
|
71 | 78 |
|
| 79 | + int bt_total = 0; |
72 | 80 | int ok_bursts = 0;
|
73 | 81 | int pkg_fail = 0;
|
74 |
| - SocketAddress temp_addr; |
75 | 82 | int recvd = 0;
|
76 |
| - int bt_total = 0; |
| 83 | + int recv_timeout = RECV_TIMEOUT;; |
| 84 | + SocketAddress temp_addr; |
77 | 85 | for (int i = 0; i < BURST_CNT; i++) {
|
78 | 86 | for (int x = 0; x < BURST_PKTS; x++) {
|
79 | 87 | TEST_ASSERT_EQUAL(tx_buffers[x].len, sock.sendto(udp_addr, tx_buffers[x].payload, tx_buffers[x].len));
|
80 | 88 | }
|
81 | 89 |
|
82 |
| - recvd = 0; |
83 | 90 | bt_total = 0;
|
| 91 | + recvd = 0; |
84 | 92 | for (int j = 0; j < BURST_PKTS; j++) {
|
85 | 93 | recvd = sock.recvfrom(&temp_addr, rx_buffer, 500);
|
86 |
| - if (recvd < 0) { |
87 |
| - pkg_fail++; |
| 94 | + if (recvd == NSAPI_ERROR_WOULD_BLOCK) { |
| 95 | + if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) { |
| 96 | + pkg_fail += BURST_PKTS-j; |
| 97 | + break; |
| 98 | + } |
| 99 | + } else if (recvd < 0) { |
| 100 | + pkg_fail += BURST_PKTS-j; // Assume all the following packets of the burst to be lost |
88 | 101 | printf("[%02d] network error %d\n", i, recvd);
|
89 |
| - continue; |
| 102 | + wait(recv_timeout); |
| 103 | + recv_timeout *= 2; // Back off, |
| 104 | + break; |
90 | 105 | } else if (temp_addr != udp_addr) {
|
91 | 106 | printf("[%02d] packet from wrong address\n", i);
|
| 107 | + --j; |
92 | 108 | continue;
|
93 | 109 | }
|
94 | 110 |
|
| 111 | + recv_timeout = recv_timeout > RECV_TIMEOUT ? recv_timeout/2 : RECV_TIMEOUT; |
| 112 | + |
95 | 113 | // Packets might arrive unordered
|
96 | 114 | for (int k = 0; k < BURST_PKTS; k++) {
|
97 | 115 | if (tx_buffers[k].len == recvd &&
|
98 | 116 | (memcmp(tx_buffers[k].payload, rx_buffer, recvd) == 0)) {
|
99 | 117 | bt_total += recvd;
|
100 |
| - goto PKT_OK; |
101 | 118 | }
|
102 | 119 | }
|
103 |
| - pkg_fail++; |
104 |
| - break; |
105 |
| -PKT_OK: |
106 |
| - continue; |
107 | 120 | }
|
108 | 121 |
|
109 | 122 | if (bt_total == RECV_TOTAL) {
|
110 | 123 | ok_bursts++;
|
111 | 124 | } else {
|
112 |
| - drop_bad_packets(sock); |
| 125 | + drop_bad_packets(sock, TIMEOUT); |
113 | 126 | printf("[%02d] burst failure\n", i);
|
114 | 127 | }
|
115 | 128 | }
|
116 | 129 |
|
117 | 130 | free_tx_buffers();
|
118 | 131 |
|
119 |
| - // Packet loss up to 10% tolerated |
120 |
| - TEST_ASSERT_INT_WITHIN((BURST_CNT*BURST_PKTS/10), BURST_CNT*BURST_PKTS, BURST_CNT*BURST_PKTS-pkg_fail); |
121 |
| - // 90% of the bursts need to be successful |
122 |
| - TEST_ASSERT_INT_WITHIN((BURST_CNT/10), BURST_CNT, ok_bursts); |
| 132 | + // Packet loss up to 1/4 tolerated |
| 133 | + TEST_ASSERT_INT_WITHIN((BURST_CNT*BURST_PKTS/4), BURST_CNT*BURST_PKTS, BURST_CNT*BURST_PKTS-pkg_fail); |
| 134 | + // 3/4 of the bursts need to be successful |
| 135 | + TEST_ASSERT_INT_WITHIN((BURST_CNT/4), BURST_CNT, ok_bursts); |
123 | 136 |
|
124 | 137 | TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
|
125 | 138 | }
|
126 | 139 |
|
127 |
| -static void _sigio_handler(osThreadId id) { |
128 |
| - osSignalSet(id, SIGNAL_SIGIO); |
129 |
| -} |
130 |
| - |
131 | 140 | void test_udpsocket_echotest_burst_nonblock()
|
132 | 141 | {
|
133 | 142 | SocketAddress udp_addr;
|
@@ -188,7 +197,7 @@ void test_udpsocket_echotest_burst_nonblock()
|
188 | 197 | if (bt_total == RECV_TOTAL) {
|
189 | 198 | ok_bursts++;
|
190 | 199 | } else {
|
191 |
| - drop_bad_packets(sock); |
| 200 | + drop_bad_packets(sock, -1); // timeout equivalent to set_blocking(false) |
192 | 201 | sock.set_blocking(false);
|
193 | 202 | }
|
194 | 203 | }
|
|
0 commit comments