source: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/socket_examples/socket_examples.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 18.8 KB
Line 
1
2#include "socket_examples.h"
3
4#include "lwip/opt.h"
5
6#if LWIP_SOCKET && (LWIP_IPV4 || LWIP_IPV6)
7
8#include "lwip/sockets.h"
9#include "lwip/sys.h"
10
11#include <string.h>
12#include <stdio.h>
13
14#ifndef SOCK_TARGET_HOST4
15#define SOCK_TARGET_HOST4 "192.168.0.1"
16#endif
17
18#ifndef SOCK_TARGET_HOST6
19#define SOCK_TARGET_HOST6 "FE80::12:34FF:FE56:78AB"
20#endif
21
22#ifndef SOCK_TARGET_PORT
23#define SOCK_TARGET_PORT 80
24#endif
25
26#ifndef SOCK_TARGET_MAXHTTPPAGESIZE
27#define SOCK_TARGET_MAXHTTPPAGESIZE 1024
28#endif
29
30#ifndef SOCKET_EXAMPLES_RUN_PARALLEL
31#define SOCKET_EXAMPLES_RUN_PARALLEL 0
32#endif
33
34const u8_t cmpbuf[8] = {0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab};
35
36/* a helper struct to ensure memory before/after fd_set is not touched */
37typedef struct _xx
38{
39 u8_t buf1[8];
40 fd_set readset;
41 u8_t buf2[8];
42 fd_set writeset;
43 u8_t buf3[8];
44 fd_set errset;
45 u8_t buf4[8];
46} fdsets;
47
48#define INIT_FDSETS(sets) do { \
49 memset((sets)->buf1, 0xab, 8); \
50 memset((sets)->buf2, 0xab, 8); \
51 memset((sets)->buf3, 0xab, 8); \
52 memset((sets)->buf4, 0xab, 8); \
53}while(0)
54
55#define CHECK_FDSETS(sets) do { \
56 LWIP_ASSERT("buf1 fail", !memcmp((sets)->buf1, cmpbuf, 8)); \
57 LWIP_ASSERT("buf2 fail", !memcmp((sets)->buf2, cmpbuf, 8)); \
58 LWIP_ASSERT("buf3 fail", !memcmp((sets)->buf3, cmpbuf, 8)); \
59 LWIP_ASSERT("buf4 fail", !memcmp((sets)->buf4, cmpbuf, 8)); \
60}while(0)
61
62static ip_addr_t dstaddr;
63
64/** This is an example function that tests
65 blocking- and nonblocking connect. */
66static void
67sockex_nonblocking_connect(void *arg)
68{
69#if LWIP_SOCKET_SELECT
70 int s;
71 int ret;
72 int opt;
73#if LWIP_IPV6
74 struct sockaddr_in6 addr;
75#else /* LWIP_IPV6 */
76 struct sockaddr_in addr;
77#endif /* LWIP_IPV6 */
78 fdsets sets;
79 struct timeval tv;
80 u32_t ticks_a, ticks_b;
81 int err;
82 const ip_addr_t *ipaddr = (const ip_addr_t*)arg;
83 struct pollfd fds;
84 INIT_FDSETS(&sets);
85
86 /* set up address to connect to */
87 memset(&addr, 0, sizeof(addr));
88#if LWIP_IPV6
89 addr.sin6_len = sizeof(addr);
90 addr.sin6_family = AF_INET6;
91 addr.sin6_port = PP_HTONS(SOCK_TARGET_PORT);
92 inet6_addr_from_ip6addr(&addr.sin6_addr, ip_2_ip6(ipaddr));
93#else /* LWIP_IPV6 */
94 addr.sin_len = sizeof(addr);
95 addr.sin_family = AF_INET;
96 addr.sin_port = PP_HTONS(SOCK_TARGET_PORT);
97 inet_addr_from_ip4addr(&addr.sin_addr, ip_2_ip4(ipaddr));
98#endif /* LWIP_IPV6 */
99
100 /* first try blocking: */
101
102 /* create the socket */
103#if LWIP_IPV6
104 s = lwip_socket(AF_INET6, SOCK_STREAM, 0);
105#else /* LWIP_IPV6 */
106 s = lwip_socket(AF_INET, SOCK_STREAM, 0);
107#endif /* LWIP_IPV6 */
108 LWIP_ASSERT("s >= 0", s >= 0);
109
110 /* connect */
111 ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
112 /* should succeed */
113 LWIP_ASSERT("ret == 0", ret == 0);
114
115 /* write something */
116 ret = lwip_write(s, "test", 4);
117 LWIP_ASSERT("ret == 4", ret == 4);
118
119 /* close */
120 ret = lwip_close(s);
121 LWIP_ASSERT("ret == 0", ret == 0);
122
123 /* now try nonblocking and close before being connected */
124
125 /* create the socket */
126#if LWIP_IPV6
127 s = lwip_socket(AF_INET6, SOCK_STREAM, 0);
128#else /* LWIP_IPV6 */
129 s = lwip_socket(AF_INET, SOCK_STREAM, 0);
130#endif /* LWIP_IPV6 */
131 LWIP_ASSERT("s >= 0", s >= 0);
132 /* nonblocking */
133 opt = lwip_fcntl(s, F_GETFL, 0);
134 LWIP_ASSERT("ret != -1", ret != -1);
135 opt |= O_NONBLOCK;
136 ret = lwip_fcntl(s, F_SETFL, opt);
137 LWIP_ASSERT("ret != -1", ret != -1);
138 /* connect */
139 ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
140 /* should have an error: "inprogress" */
141 LWIP_ASSERT("ret == -1", ret == -1);
142 err = errno;
143 LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);
144 /* close */
145 ret = lwip_close(s);
146 LWIP_ASSERT("ret == 0", ret == 0);
147 /* try to close again, should fail with EBADF */
148 ret = lwip_close(s);
149 LWIP_ASSERT("ret == -1", ret == -1);
150 err = errno;
151 LWIP_ASSERT("errno == EBADF", err == EBADF);
152 printf("closing socket in nonblocking connect succeeded\n");
153
154 /* now try nonblocking, connect should succeed:
155 this test only works if it is fast enough, i.e. no breakpoints, please! */
156
157 /* create the socket */
158#if LWIP_IPV6
159 s = lwip_socket(AF_INET6, SOCK_STREAM, 0);
160#else /* LWIP_IPV6 */
161 s = lwip_socket(AF_INET, SOCK_STREAM, 0);
162#endif /* LWIP_IPV6 */
163 LWIP_ASSERT("s >= 0", s >= 0);
164
165 /* nonblocking */
166 opt = 1;
167 ret = lwip_ioctl(s, FIONBIO, &opt);
168 LWIP_ASSERT("ret == 0", ret == 0);
169
170 /* connect */
171 ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
172 /* should have an error: "inprogress" */
173 LWIP_ASSERT("ret == -1", ret == -1);
174 err = errno;
175 LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);
176
177 /* write should fail, too */
178 ret = lwip_write(s, "test", 4);
179 LWIP_ASSERT("ret == -1", ret == -1);
180 err = errno;
181 LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);
182
183 CHECK_FDSETS(&sets);
184 FD_ZERO(&sets.readset);
185 CHECK_FDSETS(&sets);
186 FD_SET(s, &sets.readset);
187 CHECK_FDSETS(&sets);
188 FD_ZERO(&sets.writeset);
189 CHECK_FDSETS(&sets);
190 FD_SET(s, &sets.writeset);
191 CHECK_FDSETS(&sets);
192 FD_ZERO(&sets.errset);
193 CHECK_FDSETS(&sets);
194 FD_SET(s, &sets.errset);
195 CHECK_FDSETS(&sets);
196 tv.tv_sec = 0;
197 tv.tv_usec = 0;
198 /* select without waiting should fail */
199 ret = lwip_select(s + 1, &sets.readset, &sets.writeset, &sets.errset, &tv);
200 CHECK_FDSETS(&sets);
201 LWIP_ASSERT("ret == 0", ret == 0);
202 LWIP_ASSERT("!FD_ISSET(s, &writeset)", !FD_ISSET(s, &sets.writeset));
203 LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &sets.readset));
204 LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &sets.errset));
205
206 fds.fd = s;
207 fds.events = POLLIN|POLLOUT;
208 fds.revents = 0;
209 ret = lwip_poll(&fds, 1, 0);
210 LWIP_ASSERT("ret == 0", ret == 0);
211 LWIP_ASSERT("fds.revents == 0", fds.revents == 0);
212
213 FD_ZERO(&sets.readset);
214 FD_SET(s, &sets.readset);
215 FD_ZERO(&sets.writeset);
216 FD_SET(s, &sets.writeset);
217 FD_ZERO(&sets.errset);
218 FD_SET(s, &sets.errset);
219 ticks_a = sys_now();
220 /* select with waiting should succeed */
221 ret = lwip_select(s + 1, &sets.readset, &sets.writeset, &sets.errset, NULL);
222 ticks_b = sys_now();
223 LWIP_ASSERT("ret == 1", ret == 1);
224 LWIP_ASSERT("FD_ISSET(s, &writeset)", FD_ISSET(s, &sets.writeset));
225 LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &sets.readset));
226 LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &sets.errset));
227
228 fds.fd = s;
229 fds.events = POLLIN|POLLOUT;
230 fds.revents = 0;
231 ret = lwip_poll(&fds, 1, 0);
232 LWIP_ASSERT("ret == 1", ret == 1);
233 LWIP_ASSERT("fds.revents & POLLOUT", fds.revents & POLLOUT);
234
235 /* now write should succeed */
236 ret = lwip_write(s, "test", 4);
237 LWIP_ASSERT("ret == 4", ret == 4);
238
239 /* close */
240 ret = lwip_close(s);
241 LWIP_ASSERT("ret == 0", ret == 0);
242
243 printf("select() needed %d ticks to return writable\n", (int)(ticks_b - ticks_a));
244
245
246 /* now try nonblocking to invalid address:
247 this test only works if it is fast enough, i.e. no breakpoints, please! */
248
249 /* create the socket */
250#if LWIP_IPV6
251 s = lwip_socket(AF_INET6, SOCK_STREAM, 0);
252#else /* LWIP_IPV6 */
253 s = lwip_socket(AF_INET, SOCK_STREAM, 0);
254#endif /* LWIP_IPV6 */
255 LWIP_ASSERT("s >= 0", s >= 0);
256
257 /* nonblocking */
258 opt = 1;
259 ret = lwip_ioctl(s, FIONBIO, &opt);
260 LWIP_ASSERT("ret == 0", ret == 0);
261
262#if LWIP_IPV6
263 addr.sin6_addr.un.u8_addr[0]++; /* this should result in an invalid address */
264#else /* LWIP_IPV6 */
265 addr.sin_addr.s_addr++; /* this should result in an invalid address */
266#endif /* LWIP_IPV6 */
267
268 /* connect */
269 ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
270 /* should have an error: "inprogress" */
271 LWIP_ASSERT("ret == -1", ret == -1);
272 err = errno;
273 LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);
274
275 /* write should fail, too */
276 ret = lwip_write(s, "test", 4);
277 LWIP_ASSERT("ret == -1", ret == -1);
278 err = errno;
279 LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);
280 LWIP_UNUSED_ARG(err);
281
282 FD_ZERO(&sets.readset);
283 FD_SET(s, &sets.readset);
284 FD_ZERO(&sets.writeset);
285 FD_SET(s, &sets.writeset);
286 FD_ZERO(&sets.errset);
287 FD_SET(s, &sets.errset);
288 tv.tv_sec = 0;
289 tv.tv_usec = 0;
290 /* select without waiting should fail */
291 ret = lwip_select(s + 1, &sets.readset, &sets.writeset, &sets.errset, &tv);
292 LWIP_ASSERT("ret == 0", ret == 0);
293
294 FD_ZERO(&sets.readset);
295 FD_SET(s, &sets.readset);
296 FD_ZERO(&sets.writeset);
297 FD_SET(s, &sets.writeset);
298 FD_ZERO(&sets.errset);
299 FD_SET(s, &sets.errset);
300 ticks_a = sys_now();
301 /* select with waiting should eventually succeed and return errset! */
302 ret = lwip_select(s + 1, &sets.readset, &sets.writeset, &sets.errset, NULL);
303 ticks_b = sys_now();
304 LWIP_ASSERT("ret > 0", ret > 0);
305 LWIP_ASSERT("FD_ISSET(s, &errset)", FD_ISSET(s, &sets.errset));
306 /*LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &sets.readset));
307 LWIP_ASSERT("!FD_ISSET(s, &writeset)", !FD_ISSET(s, &sets.writeset));*/
308
309 /* close */
310 ret = lwip_close(s);
311 LWIP_ASSERT("ret == 0", ret == 0);
312 LWIP_UNUSED_ARG(ret);
313
314 printf("select() needed %d ticks to return error\n", (int)(ticks_b - ticks_a));
315 printf("sockex_nonblocking_connect finished successfully\n");
316#else
317 LWIP_UNUSED_ARG(arg);
318#endif
319}
320
321/** This is an example function that tests
322 the recv function (timeout etc.). */
323static void
324sockex_testrecv(void *arg)
325{
326 int s;
327 int ret;
328 int err;
329#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
330 int opt, opt2;
331#else
332 struct timeval opt, opt2;
333#endif
334 socklen_t opt2size;
335#if LWIP_IPV6
336 struct sockaddr_in6 addr;
337#else /* LWIP_IPV6 */
338 struct sockaddr_in addr;
339#endif /* LWIP_IPV6 */
340 size_t len;
341 char rxbuf[SOCK_TARGET_MAXHTTPPAGESIZE];
342#if LWIP_SOCKET_SELECT
343 fd_set readset;
344 fd_set errset;
345 struct timeval tv;
346#endif
347 const ip_addr_t *ipaddr = (const ip_addr_t*)arg;
348
349 /* set up address to connect to */
350 memset(&addr, 0, sizeof(addr));
351#if LWIP_IPV6
352 addr.sin6_len = sizeof(addr);
353 addr.sin6_family = AF_INET6;
354 addr.sin6_port = PP_HTONS(SOCK_TARGET_PORT);
355 inet6_addr_from_ip6addr(&addr.sin6_addr, ip_2_ip6(ipaddr));
356#else /* LWIP_IPV6 */
357 addr.sin_len = sizeof(addr);
358 addr.sin_family = AF_INET;
359 addr.sin_port = PP_HTONS(SOCK_TARGET_PORT);
360 inet_addr_from_ip4addr(&addr.sin_addr, ip_2_ip4(ipaddr));
361#endif /* LWIP_IPV6 */
362
363 /* first try blocking: */
364
365 /* create the socket */
366#if LWIP_IPV6
367 s = lwip_socket(AF_INET6, SOCK_STREAM, 0);
368#else /* LWIP_IPV6 */
369 s = lwip_socket(AF_INET, SOCK_STREAM, 0);
370#endif /* LWIP_IPV6 */
371 LWIP_ASSERT("s >= 0", s >= 0);
372
373 /* connect */
374 ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
375 /* should succeed */
376 LWIP_ASSERT("ret == 0", ret == 0);
377
378 /* set recv timeout (100 ms) */
379#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
380 opt = 100;
381#else
382 opt.tv_sec = 0;
383 opt.tv_usec = 100 * 1000;
384#endif
385 ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &opt, sizeof(opt));
386 LWIP_ASSERT("ret == 0", ret == 0);
387#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
388 opt2 = 0;
389#else
390 opt2.tv_sec = 0;
391 opt2.tv_usec = 0;
392#endif
393 opt2size = sizeof(opt2);
394 ret = lwip_getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &opt2, &opt2size);
395 LWIP_ASSERT("ret == 0", ret == 0);
396 LWIP_ASSERT("opt2size == sizeof(opt2)", opt2size == sizeof(opt2));
397#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
398 LWIP_ASSERT("opt == opt2", opt == opt2);
399#else
400 LWIP_ASSERT("opt == opt2", opt.tv_sec == opt2.tv_sec);
401 LWIP_ASSERT("opt == opt2", opt.tv_usec == opt2.tv_usec);
402#endif
403
404 /* write the start of a GET request */
405#define SNDSTR1 "G"
406 len = strlen(SNDSTR1);
407 ret = lwip_write(s, SNDSTR1, len);
408 LWIP_ASSERT("ret == len", ret == (int)len);
409
410 /* should time out if the other side is a good HTTP server */
411 ret = lwip_read(s, rxbuf, 1);
412 LWIP_ASSERT("ret == -1", ret == -1);
413 err = errno;
414 LWIP_ASSERT("errno == EAGAIN", err == EAGAIN);
415 LWIP_UNUSED_ARG(err);
416
417 /* write the rest of a GET request */
418#define SNDSTR2 "ET / HTTP_1.1\r\n\r\n"
419 len = strlen(SNDSTR2);
420 ret = lwip_write(s, SNDSTR2, len);
421 LWIP_ASSERT("ret == len", ret == (int)len);
422
423 /* wait a while: should be enough for the server to send a response */
424 sys_msleep(1000);
425
426 /* should not time out but receive a response */
427 ret = lwip_read(s, rxbuf, SOCK_TARGET_MAXHTTPPAGESIZE);
428 LWIP_ASSERT("ret > 0", ret > 0);
429
430#if LWIP_SOCKET_SELECT
431 /* now select should directly return because the socket is readable */
432 FD_ZERO(&readset);
433 FD_ZERO(&errset);
434 FD_SET(s, &readset);
435 FD_SET(s, &errset);
436 tv.tv_sec = 10;
437 tv.tv_usec = 0;
438 ret = lwip_select(s + 1, &readset, NULL, &errset, &tv);
439 LWIP_ASSERT("ret == 1", ret == 1);
440 LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &errset));
441 LWIP_ASSERT("FD_ISSET(s, &readset)", FD_ISSET(s, &readset));
442#endif
443
444 /* should not time out but receive a response */
445 ret = lwip_read(s, rxbuf, SOCK_TARGET_MAXHTTPPAGESIZE);
446 /* might receive a second packet for HTTP/1.1 servers */
447 if (ret > 0) {
448 /* should return 0: closed */
449 ret = lwip_read(s, rxbuf, SOCK_TARGET_MAXHTTPPAGESIZE);
450 LWIP_ASSERT("ret == 0", ret == 0);
451 }
452
453 /* close */
454 ret = lwip_close(s);
455 LWIP_ASSERT("ret == 0", ret == 0);
456 LWIP_UNUSED_ARG(ret);
457
458 printf("sockex_testrecv finished successfully\n");
459}
460
461#if LWIP_SOCKET_SELECT
462/** helper struct for the 2 functions below (multithreaded: thread-argument) */
463struct sockex_select_helper {
464 int socket;
465 int wait_read;
466 int expect_read;
467 int wait_write;
468 int expect_write;
469 int wait_err;
470 int expect_err;
471 int wait_ms;
472 sys_sem_t sem;
473};
474
475/** helper thread to wait for socket events using select */
476static void
477sockex_select_waiter(void *arg)
478{
479 struct sockex_select_helper *helper = (struct sockex_select_helper *)arg;
480 int ret;
481 fd_set readset;
482 fd_set writeset;
483 fd_set errset;
484 struct timeval tv;
485
486 LWIP_ASSERT("helper != NULL", helper != NULL);
487
488 FD_ZERO(&readset);
489 FD_ZERO(&writeset);
490 FD_ZERO(&errset);
491 if (helper->wait_read) {
492 FD_SET(helper->socket, &readset);
493 }
494 if (helper->wait_write) {
495 FD_SET(helper->socket, &writeset);
496 }
497 if (helper->wait_err) {
498 FD_SET(helper->socket, &errset);
499 }
500
501 tv.tv_sec = helper->wait_ms / 1000;
502 tv.tv_usec = (helper->wait_ms % 1000) * 1000;
503
504 ret = lwip_select(helper->socket, &readset, &writeset, &errset, &tv);
505 if (helper->expect_read || helper->expect_write || helper->expect_err) {
506 LWIP_ASSERT("ret > 0", ret > 0);
507 } else {
508 LWIP_ASSERT("ret == 0", ret == 0);
509 }
510 LWIP_UNUSED_ARG(ret);
511 if (helper->expect_read) {
512 LWIP_ASSERT("FD_ISSET(helper->socket, &readset)", FD_ISSET(helper->socket, &readset));
513 } else {
514 LWIP_ASSERT("!FD_ISSET(helper->socket, &readset)", !FD_ISSET(helper->socket, &readset));
515 }
516 if (helper->expect_write) {
517 LWIP_ASSERT("FD_ISSET(helper->socket, &writeset)", FD_ISSET(helper->socket, &writeset));
518 } else {
519 LWIP_ASSERT("!FD_ISSET(helper->socket, &writeset)", !FD_ISSET(helper->socket, &writeset));
520 }
521 if (helper->expect_err) {
522 LWIP_ASSERT("FD_ISSET(helper->socket, &errset)", FD_ISSET(helper->socket, &errset));
523 } else {
524 LWIP_ASSERT("!FD_ISSET(helper->socket, &errset)", !FD_ISSET(helper->socket, &errset));
525 }
526 sys_sem_signal(&helper->sem);
527}
528
529/** This is an example function that tests
530 more than one thread being active in select. */
531static void
532sockex_testtwoselects(void *arg)
533{
534 int s1;
535 int s2;
536 int ret;
537#if LWIP_IPV6
538 struct sockaddr_in6 addr;
539#else /* LWIP_IPV6 */
540 struct sockaddr_in addr;
541#endif /* LWIP_IPV6 */
542 size_t len;
543 err_t lwiperr;
544 struct sockex_select_helper h1, h2, h3, h4;
545 const ip_addr_t *ipaddr = (const ip_addr_t*)arg;
546
547 /* set up address to connect to */
548 memset(&addr, 0, sizeof(addr));
549#if LWIP_IPV6
550 addr.sin6_len = sizeof(addr);
551 addr.sin6_family = AF_INET6;
552 addr.sin6_port = PP_HTONS(SOCK_TARGET_PORT);
553 inet6_addr_from_ip6addr(&addr.sin6_addr, ip_2_ip6(ipaddr));
554#else /* LWIP_IPV6 */
555 addr.sin_len = sizeof(addr);
556 addr.sin_family = AF_INET;
557 addr.sin_port = PP_HTONS(SOCK_TARGET_PORT);
558 inet_addr_from_ip4addr(&addr.sin_addr, ip_2_ip4(ipaddr));
559#endif /* LWIP_IPV6 */
560
561 /* create the sockets */
562#if LWIP_IPV6
563 s1 = lwip_socket(AF_INET6, SOCK_STREAM, 0);
564 s2 = lwip_socket(AF_INET6, SOCK_STREAM, 0);
565#else /* LWIP_IPV6 */
566 s1 = lwip_socket(AF_INET, SOCK_STREAM, 0);
567 s2 = lwip_socket(AF_INET, SOCK_STREAM, 0);
568#endif /* LWIP_IPV6 */
569 LWIP_ASSERT("s1 >= 0", s1 >= 0);
570 LWIP_ASSERT("s2 >= 0", s2 >= 0);
571
572 /* connect, should succeed */
573 ret = lwip_connect(s1, (struct sockaddr*)&addr, sizeof(addr));
574 LWIP_ASSERT("ret == 0", ret == 0);
575 ret = lwip_connect(s2, (struct sockaddr*)&addr, sizeof(addr));
576 LWIP_ASSERT("ret == 0", ret == 0);
577
578 /* write the start of a GET request */
579#define SNDSTR1 "G"
580 len = strlen(SNDSTR1);
581 ret = lwip_write(s1, SNDSTR1, len);
582 LWIP_ASSERT("ret == len", ret == (int)len);
583 ret = lwip_write(s2, SNDSTR1, len);
584 LWIP_ASSERT("ret == len", ret == (int)len);
585 LWIP_UNUSED_ARG(ret);
586
587 h1.wait_read = 1;
588 h1.wait_write = 1;
589 h1.wait_err = 1;
590 h1.expect_read = 0;
591 h1.expect_write = 0;
592 h1.expect_err = 0;
593 lwiperr = sys_sem_new(&h1.sem, 0);
594 LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK);
595 h1.socket = s1;
596 h1.wait_ms = 500;
597
598 h2 = h1;
599 lwiperr = sys_sem_new(&h2.sem, 0);
600 LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK);
601 h2.socket = s2;
602 h2.wait_ms = 1000;
603
604 h3 = h1;
605 lwiperr = sys_sem_new(&h3.sem, 0);
606 LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK);
607 h3.socket = s2;
608 h3.wait_ms = 1500;
609
610 h4 = h1;
611 lwiperr = sys_sem_new(&h4.sem, 0);
612 LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK);
613 LWIP_UNUSED_ARG(lwiperr);
614 h4.socket = s2;
615 h4.wait_ms = 2000;
616
617 /* select: all sockets should time out if the other side is a good HTTP server */
618
619 sys_thread_new("sockex_select_waiter1", sockex_select_waiter, &h2, 0, 0);
620 sys_msleep(100);
621 sys_thread_new("sockex_select_waiter2", sockex_select_waiter, &h1, 0, 0);
622 sys_msleep(100);
623 sys_thread_new("sockex_select_waiter2", sockex_select_waiter, &h4, 0, 0);
624 sys_msleep(100);
625 sys_thread_new("sockex_select_waiter2", sockex_select_waiter, &h3, 0, 0);
626
627 sys_sem_wait(&h1.sem);
628 sys_sem_wait(&h2.sem);
629 sys_sem_wait(&h3.sem);
630 sys_sem_wait(&h4.sem);
631
632 /* close */
633 ret = lwip_close(s1);
634 LWIP_ASSERT("ret == 0", ret == 0);
635 ret = lwip_close(s2);
636 LWIP_ASSERT("ret == 0", ret == 0);
637
638 printf("sockex_testtwoselects finished successfully\n");
639}
640#else
641static void
642sockex_testtwoselects(void *arg)
643{
644 LWIP_UNUSED_ARG(arg);
645}
646#endif
647
648#if !SOCKET_EXAMPLES_RUN_PARALLEL
649static void
650socket_example_test(void* arg)
651{
652 sys_msleep(1000);
653 sockex_nonblocking_connect(arg);
654 sockex_testrecv(arg);
655 sockex_testtwoselects(arg);
656 printf("all tests done, thread ending\n");
657}
658#endif
659
660void socket_examples_init(void)
661{
662 int addr_ok;
663#if LWIP_IPV6
664 IP_SET_TYPE_VAL(dstaddr, IPADDR_TYPE_V6);
665 addr_ok = ip6addr_aton(SOCK_TARGET_HOST6, ip_2_ip6(&dstaddr));
666#else /* LWIP_IPV6 */
667 IP_SET_TYPE_VAL(dstaddr, IPADDR_TYPE_V4);
668 addr_ok = ip4addr_aton(SOCK_TARGET_HOST4, ip_2_ip4(&dstaddr));
669#endif /* LWIP_IPV6 */
670 LWIP_ASSERT("invalid address", addr_ok);
671#if SOCKET_EXAMPLES_RUN_PARALLEL
672 sys_thread_new("sockex_nonblocking_connect", sockex_nonblocking_connect, &dstaddr, 0, 0);
673 sys_thread_new("sockex_testrecv", sockex_testrecv, &dstaddr, 0, 0);
674 sys_thread_new("sockex_testtwoselects", sockex_testtwoselects, &dstaddr, 0, 0);
675#else
676 sys_thread_new("socket_example_test", socket_example_test, &dstaddr, 0, 0);
677#endif
678}
679
680#endif /* LWIP_SOCKET */
Note: See TracBrowser for help on using the repository browser.