| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680 |
- #include "socket_examples.h"
- #include "lwip/opt.h"
- #if LWIP_SOCKET && (LWIP_IPV4 || LWIP_IPV6)
- #include "lwip/sockets.h"
- #include "lwip/sys.h"
- #include <string.h>
- #include <stdio.h>
- #ifndef SOCK_TARGET_HOST4
- #define SOCK_TARGET_HOST4 "192.168.0.1"
- #endif
- #ifndef SOCK_TARGET_HOST6
- #define SOCK_TARGET_HOST6 "FE80::12:34FF:FE56:78AB"
- #endif
- #ifndef SOCK_TARGET_PORT
- #define SOCK_TARGET_PORT 80
- #endif
- #ifndef SOCK_TARGET_MAXHTTPPAGESIZE
- #define SOCK_TARGET_MAXHTTPPAGESIZE 1024
- #endif
- #ifndef SOCKET_EXAMPLES_RUN_PARALLEL
- #define SOCKET_EXAMPLES_RUN_PARALLEL 0
- #endif
- static const u8_t cmpbuf[8] = {0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab};
- /* a helper struct to ensure memory before/after fd_set is not touched */
- typedef struct _xx
- {
- u8_t buf1[8];
- fd_set readset;
- u8_t buf2[8];
- fd_set writeset;
- u8_t buf3[8];
- fd_set errset;
- u8_t buf4[8];
- } fdsets;
- #define INIT_FDSETS(sets) do { \
- memset((sets)->buf1, 0xab, 8); \
- memset((sets)->buf2, 0xab, 8); \
- memset((sets)->buf3, 0xab, 8); \
- memset((sets)->buf4, 0xab, 8); \
- }while(0)
- #define CHECK_FDSETS(sets) do { \
- LWIP_ASSERT("buf1 fail", !memcmp((sets)->buf1, cmpbuf, 8)); \
- LWIP_ASSERT("buf2 fail", !memcmp((sets)->buf2, cmpbuf, 8)); \
- LWIP_ASSERT("buf3 fail", !memcmp((sets)->buf3, cmpbuf, 8)); \
- LWIP_ASSERT("buf4 fail", !memcmp((sets)->buf4, cmpbuf, 8)); \
- }while(0)
- static ip_addr_t dstaddr;
- /** This is an example function that tests
- blocking- and nonblocking connect. */
- static void
- sockex_nonblocking_connect(void *arg)
- {
- #if LWIP_SOCKET_SELECT
- int s;
- int ret;
- int opt;
- #if LWIP_IPV6
- struct sockaddr_in6 addr;
- #else /* LWIP_IPV6 */
- struct sockaddr_in addr;
- #endif /* LWIP_IPV6 */
- fdsets sets;
- struct timeval tv;
- u32_t ticks_a, ticks_b;
- int err;
- const ip_addr_t *ipaddr = (const ip_addr_t*)arg;
- struct pollfd fds;
- INIT_FDSETS(&sets);
- /* set up address to connect to */
- memset(&addr, 0, sizeof(addr));
- #if LWIP_IPV6
- addr.sin6_len = sizeof(addr);
- addr.sin6_family = AF_INET6;
- addr.sin6_port = PP_HTONS(SOCK_TARGET_PORT);
- inet6_addr_from_ip6addr(&addr.sin6_addr, ip_2_ip6(ipaddr));
- #else /* LWIP_IPV6 */
- addr.sin_len = sizeof(addr);
- addr.sin_family = AF_INET;
- addr.sin_port = PP_HTONS(SOCK_TARGET_PORT);
- inet_addr_from_ip4addr(&addr.sin_addr, ip_2_ip4(ipaddr));
- #endif /* LWIP_IPV6 */
- /* first try blocking: */
- /* create the socket */
- #if LWIP_IPV6
- s = lwip_socket(AF_INET6, SOCK_STREAM, 0);
- #else /* LWIP_IPV6 */
- s = lwip_socket(AF_INET, SOCK_STREAM, 0);
- #endif /* LWIP_IPV6 */
- LWIP_ASSERT("s >= 0", s >= 0);
- /* connect */
- ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
- /* should succeed */
- LWIP_ASSERT("ret == 0", ret == 0);
- /* write something */
- ret = lwip_write(s, "test", 4);
- LWIP_ASSERT("ret == 4", ret == 4);
- /* close */
- ret = lwip_close(s);
- LWIP_ASSERT("ret == 0", ret == 0);
- /* now try nonblocking and close before being connected */
- /* create the socket */
- #if LWIP_IPV6
- s = lwip_socket(AF_INET6, SOCK_STREAM, 0);
- #else /* LWIP_IPV6 */
- s = lwip_socket(AF_INET, SOCK_STREAM, 0);
- #endif /* LWIP_IPV6 */
- LWIP_ASSERT("s >= 0", s >= 0);
- /* nonblocking */
- opt = lwip_fcntl(s, F_GETFL, 0);
- LWIP_ASSERT("ret != -1", ret != -1);
- opt |= O_NONBLOCK;
- ret = lwip_fcntl(s, F_SETFL, opt);
- LWIP_ASSERT("ret != -1", ret != -1);
- /* connect */
- ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
- /* should have an error: "inprogress" */
- LWIP_ASSERT("ret == -1", ret == -1);
- err = errno;
- LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);
- /* close */
- ret = lwip_close(s);
- LWIP_ASSERT("ret == 0", ret == 0);
- /* try to close again, should fail with EBADF */
- ret = lwip_close(s);
- LWIP_ASSERT("ret == -1", ret == -1);
- err = errno;
- LWIP_ASSERT("errno == EBADF", err == EBADF);
- printf("closing socket in nonblocking connect succeeded\n");
- /* now try nonblocking, connect should succeed:
- this test only works if it is fast enough, i.e. no breakpoints, please! */
- /* create the socket */
- #if LWIP_IPV6
- s = lwip_socket(AF_INET6, SOCK_STREAM, 0);
- #else /* LWIP_IPV6 */
- s = lwip_socket(AF_INET, SOCK_STREAM, 0);
- #endif /* LWIP_IPV6 */
- LWIP_ASSERT("s >= 0", s >= 0);
- /* nonblocking */
- opt = 1;
- ret = lwip_ioctl(s, FIONBIO, &opt);
- LWIP_ASSERT("ret == 0", ret == 0);
- /* connect */
- ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
- /* should have an error: "inprogress" */
- LWIP_ASSERT("ret == -1", ret == -1);
- err = errno;
- LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);
- /* write should fail, too */
- ret = lwip_write(s, "test", 4);
- LWIP_ASSERT("ret == -1", ret == -1);
- err = errno;
- LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);
- CHECK_FDSETS(&sets);
- FD_ZERO(&sets.readset);
- CHECK_FDSETS(&sets);
- FD_SET(s, &sets.readset);
- CHECK_FDSETS(&sets);
- FD_ZERO(&sets.writeset);
- CHECK_FDSETS(&sets);
- FD_SET(s, &sets.writeset);
- CHECK_FDSETS(&sets);
- FD_ZERO(&sets.errset);
- CHECK_FDSETS(&sets);
- FD_SET(s, &sets.errset);
- CHECK_FDSETS(&sets);
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- /* select without waiting should fail */
- ret = lwip_select(s + 1, &sets.readset, &sets.writeset, &sets.errset, &tv);
- CHECK_FDSETS(&sets);
- LWIP_ASSERT("ret == 0", ret == 0);
- LWIP_ASSERT("!FD_ISSET(s, &writeset)", !FD_ISSET(s, &sets.writeset));
- LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &sets.readset));
- LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &sets.errset));
- fds.fd = s;
- fds.events = POLLIN|POLLOUT;
- fds.revents = 0;
- ret = lwip_poll(&fds, 1, 0);
- LWIP_ASSERT("ret == 0", ret == 0);
- LWIP_ASSERT("fds.revents == 0", fds.revents == 0);
- FD_ZERO(&sets.readset);
- FD_SET(s, &sets.readset);
- FD_ZERO(&sets.writeset);
- FD_SET(s, &sets.writeset);
- FD_ZERO(&sets.errset);
- FD_SET(s, &sets.errset);
- ticks_a = sys_now();
- /* select with waiting should succeed */
- ret = lwip_select(s + 1, &sets.readset, &sets.writeset, &sets.errset, NULL);
- ticks_b = sys_now();
- LWIP_ASSERT("ret == 1", ret == 1);
- LWIP_ASSERT("FD_ISSET(s, &writeset)", FD_ISSET(s, &sets.writeset));
- LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &sets.readset));
- LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &sets.errset));
- fds.fd = s;
- fds.events = POLLIN|POLLOUT;
- fds.revents = 0;
- ret = lwip_poll(&fds, 1, 0);
- LWIP_ASSERT("ret == 1", ret == 1);
- LWIP_ASSERT("fds.revents & POLLOUT", fds.revents & POLLOUT);
- /* now write should succeed */
- ret = lwip_write(s, "test", 4);
- LWIP_ASSERT("ret == 4", ret == 4);
- /* close */
- ret = lwip_close(s);
- LWIP_ASSERT("ret == 0", ret == 0);
- printf("select() needed %d ticks to return writable\n", (int)(ticks_b - ticks_a));
- /* now try nonblocking to invalid address:
- this test only works if it is fast enough, i.e. no breakpoints, please! */
- /* create the socket */
- #if LWIP_IPV6
- s = lwip_socket(AF_INET6, SOCK_STREAM, 0);
- #else /* LWIP_IPV6 */
- s = lwip_socket(AF_INET, SOCK_STREAM, 0);
- #endif /* LWIP_IPV6 */
- LWIP_ASSERT("s >= 0", s >= 0);
- /* nonblocking */
- opt = 1;
- ret = lwip_ioctl(s, FIONBIO, &opt);
- LWIP_ASSERT("ret == 0", ret == 0);
- #if LWIP_IPV6
- addr.sin6_addr.un.u8_addr[0]++; /* this should result in an invalid address */
- #else /* LWIP_IPV6 */
- addr.sin_addr.s_addr++; /* this should result in an invalid address */
- #endif /* LWIP_IPV6 */
- /* connect */
- ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
- /* should have an error: "inprogress" */
- LWIP_ASSERT("ret == -1", ret == -1);
- err = errno;
- LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);
- /* write should fail, too */
- ret = lwip_write(s, "test", 4);
- LWIP_ASSERT("ret == -1", ret == -1);
- err = errno;
- LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);
- LWIP_UNUSED_ARG(err);
- FD_ZERO(&sets.readset);
- FD_SET(s, &sets.readset);
- FD_ZERO(&sets.writeset);
- FD_SET(s, &sets.writeset);
- FD_ZERO(&sets.errset);
- FD_SET(s, &sets.errset);
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- /* select without waiting should fail */
- ret = lwip_select(s + 1, &sets.readset, &sets.writeset, &sets.errset, &tv);
- LWIP_ASSERT("ret == 0", ret == 0);
- FD_ZERO(&sets.readset);
- FD_SET(s, &sets.readset);
- FD_ZERO(&sets.writeset);
- FD_SET(s, &sets.writeset);
- FD_ZERO(&sets.errset);
- FD_SET(s, &sets.errset);
- ticks_a = sys_now();
- /* select with waiting should eventually succeed and return errset! */
- ret = lwip_select(s + 1, &sets.readset, &sets.writeset, &sets.errset, NULL);
- ticks_b = sys_now();
- LWIP_ASSERT("ret > 0", ret > 0);
- LWIP_ASSERT("FD_ISSET(s, &errset)", FD_ISSET(s, &sets.errset));
- /*LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &sets.readset));
- LWIP_ASSERT("!FD_ISSET(s, &writeset)", !FD_ISSET(s, &sets.writeset));*/
- /* close */
- ret = lwip_close(s);
- LWIP_ASSERT("ret == 0", ret == 0);
- LWIP_UNUSED_ARG(ret);
- printf("select() needed %d ticks to return error\n", (int)(ticks_b - ticks_a));
- printf("sockex_nonblocking_connect finished successfully\n");
- #else
- LWIP_UNUSED_ARG(arg);
- #endif
- }
- /** This is an example function that tests
- the recv function (timeout etc.). */
- static void
- sockex_testrecv(void *arg)
- {
- int s;
- int ret;
- int err;
- #if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
- int opt, opt2;
- #else
- struct timeval opt, opt2;
- #endif
- socklen_t opt2size;
- #if LWIP_IPV6
- struct sockaddr_in6 addr;
- #else /* LWIP_IPV6 */
- struct sockaddr_in addr;
- #endif /* LWIP_IPV6 */
- size_t len;
- char rxbuf[SOCK_TARGET_MAXHTTPPAGESIZE];
- #if LWIP_SOCKET_SELECT
- fd_set readset;
- fd_set errset;
- struct timeval tv;
- #endif
- const ip_addr_t *ipaddr = (const ip_addr_t*)arg;
- /* set up address to connect to */
- memset(&addr, 0, sizeof(addr));
- #if LWIP_IPV6
- addr.sin6_len = sizeof(addr);
- addr.sin6_family = AF_INET6;
- addr.sin6_port = PP_HTONS(SOCK_TARGET_PORT);
- inet6_addr_from_ip6addr(&addr.sin6_addr, ip_2_ip6(ipaddr));
- #else /* LWIP_IPV6 */
- addr.sin_len = sizeof(addr);
- addr.sin_family = AF_INET;
- addr.sin_port = PP_HTONS(SOCK_TARGET_PORT);
- inet_addr_from_ip4addr(&addr.sin_addr, ip_2_ip4(ipaddr));
- #endif /* LWIP_IPV6 */
- /* first try blocking: */
- /* create the socket */
- #if LWIP_IPV6
- s = lwip_socket(AF_INET6, SOCK_STREAM, 0);
- #else /* LWIP_IPV6 */
- s = lwip_socket(AF_INET, SOCK_STREAM, 0);
- #endif /* LWIP_IPV6 */
- LWIP_ASSERT("s >= 0", s >= 0);
- /* connect */
- ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
- /* should succeed */
- LWIP_ASSERT("ret == 0", ret == 0);
- /* set recv timeout (100 ms) */
- #if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
- opt = 100;
- #else
- opt.tv_sec = 0;
- opt.tv_usec = 100 * 1000;
- #endif
- ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &opt, sizeof(opt));
- LWIP_ASSERT("ret == 0", ret == 0);
- #if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
- opt2 = 0;
- #else
- opt2.tv_sec = 0;
- opt2.tv_usec = 0;
- #endif
- opt2size = sizeof(opt2);
- ret = lwip_getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &opt2, &opt2size);
- LWIP_ASSERT("ret == 0", ret == 0);
- LWIP_ASSERT("opt2size == sizeof(opt2)", opt2size == sizeof(opt2));
- #if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
- LWIP_ASSERT("opt == opt2", opt == opt2);
- #else
- LWIP_ASSERT("opt == opt2", opt.tv_sec == opt2.tv_sec);
- LWIP_ASSERT("opt == opt2", opt.tv_usec == opt2.tv_usec);
- #endif
- /* write the start of a GET request */
- #define SNDSTR1 "G"
- len = strlen(SNDSTR1);
- ret = lwip_write(s, SNDSTR1, len);
- LWIP_ASSERT("ret == len", ret == (int)len);
- /* should time out if the other side is a good HTTP server */
- ret = lwip_read(s, rxbuf, 1);
- LWIP_ASSERT("ret == -1", ret == -1);
- err = errno;
- LWIP_ASSERT("errno == EAGAIN", err == EAGAIN);
- LWIP_UNUSED_ARG(err);
- /* write the rest of a GET request */
- #define SNDSTR2 "ET / HTTP_1.1\r\n\r\n"
- len = strlen(SNDSTR2);
- ret = lwip_write(s, SNDSTR2, len);
- LWIP_ASSERT("ret == len", ret == (int)len);
- /* wait a while: should be enough for the server to send a response */
- sys_msleep(1000);
- /* should not time out but receive a response */
- ret = lwip_read(s, rxbuf, SOCK_TARGET_MAXHTTPPAGESIZE);
- LWIP_ASSERT("ret > 0", ret > 0);
- #if LWIP_SOCKET_SELECT
- /* now select should directly return because the socket is readable */
- FD_ZERO(&readset);
- FD_ZERO(&errset);
- FD_SET(s, &readset);
- FD_SET(s, &errset);
- tv.tv_sec = 10;
- tv.tv_usec = 0;
- ret = lwip_select(s + 1, &readset, NULL, &errset, &tv);
- LWIP_ASSERT("ret == 1", ret == 1);
- LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &errset));
- LWIP_ASSERT("FD_ISSET(s, &readset)", FD_ISSET(s, &readset));
- #endif
- /* should not time out but receive a response */
- ret = lwip_read(s, rxbuf, SOCK_TARGET_MAXHTTPPAGESIZE);
- /* might receive a second packet for HTTP/1.1 servers */
- if (ret > 0) {
- /* should return 0: closed */
- ret = lwip_read(s, rxbuf, SOCK_TARGET_MAXHTTPPAGESIZE);
- LWIP_ASSERT("ret == 0", ret == 0);
- }
- /* close */
- ret = lwip_close(s);
- LWIP_ASSERT("ret == 0", ret == 0);
- LWIP_UNUSED_ARG(ret);
- printf("sockex_testrecv finished successfully\n");
- }
- #if LWIP_SOCKET_SELECT
- /** helper struct for the 2 functions below (multithreaded: thread-argument) */
- struct sockex_select_helper {
- int socket;
- int wait_read;
- int expect_read;
- int wait_write;
- int expect_write;
- int wait_err;
- int expect_err;
- int wait_ms;
- sys_sem_t sem;
- };
- /** helper thread to wait for socket events using select */
- static void
- sockex_select_waiter(void *arg)
- {
- struct sockex_select_helper *helper = (struct sockex_select_helper *)arg;
- int ret;
- fd_set readset;
- fd_set writeset;
- fd_set errset;
- struct timeval tv;
- LWIP_ASSERT("helper != NULL", helper != NULL);
- FD_ZERO(&readset);
- FD_ZERO(&writeset);
- FD_ZERO(&errset);
- if (helper->wait_read) {
- FD_SET(helper->socket, &readset);
- }
- if (helper->wait_write) {
- FD_SET(helper->socket, &writeset);
- }
- if (helper->wait_err) {
- FD_SET(helper->socket, &errset);
- }
- tv.tv_sec = helper->wait_ms / 1000;
- tv.tv_usec = (helper->wait_ms % 1000) * 1000;
- ret = lwip_select(helper->socket, &readset, &writeset, &errset, &tv);
- if (helper->expect_read || helper->expect_write || helper->expect_err) {
- LWIP_ASSERT("ret > 0", ret > 0);
- } else {
- LWIP_ASSERT("ret == 0", ret == 0);
- }
- LWIP_UNUSED_ARG(ret);
- if (helper->expect_read) {
- LWIP_ASSERT("FD_ISSET(helper->socket, &readset)", FD_ISSET(helper->socket, &readset));
- } else {
- LWIP_ASSERT("!FD_ISSET(helper->socket, &readset)", !FD_ISSET(helper->socket, &readset));
- }
- if (helper->expect_write) {
- LWIP_ASSERT("FD_ISSET(helper->socket, &writeset)", FD_ISSET(helper->socket, &writeset));
- } else {
- LWIP_ASSERT("!FD_ISSET(helper->socket, &writeset)", !FD_ISSET(helper->socket, &writeset));
- }
- if (helper->expect_err) {
- LWIP_ASSERT("FD_ISSET(helper->socket, &errset)", FD_ISSET(helper->socket, &errset));
- } else {
- LWIP_ASSERT("!FD_ISSET(helper->socket, &errset)", !FD_ISSET(helper->socket, &errset));
- }
- sys_sem_signal(&helper->sem);
- }
- /** This is an example function that tests
- more than one thread being active in select. */
- static void
- sockex_testtwoselects(void *arg)
- {
- int s1;
- int s2;
- int ret;
- #if LWIP_IPV6
- struct sockaddr_in6 addr;
- #else /* LWIP_IPV6 */
- struct sockaddr_in addr;
- #endif /* LWIP_IPV6 */
- size_t len;
- err_t lwiperr;
- struct sockex_select_helper h1, h2, h3, h4;
- const ip_addr_t *ipaddr = (const ip_addr_t*)arg;
- /* set up address to connect to */
- memset(&addr, 0, sizeof(addr));
- #if LWIP_IPV6
- addr.sin6_len = sizeof(addr);
- addr.sin6_family = AF_INET6;
- addr.sin6_port = PP_HTONS(SOCK_TARGET_PORT);
- inet6_addr_from_ip6addr(&addr.sin6_addr, ip_2_ip6(ipaddr));
- #else /* LWIP_IPV6 */
- addr.sin_len = sizeof(addr);
- addr.sin_family = AF_INET;
- addr.sin_port = PP_HTONS(SOCK_TARGET_PORT);
- inet_addr_from_ip4addr(&addr.sin_addr, ip_2_ip4(ipaddr));
- #endif /* LWIP_IPV6 */
- /* create the sockets */
- #if LWIP_IPV6
- s1 = lwip_socket(AF_INET6, SOCK_STREAM, 0);
- s2 = lwip_socket(AF_INET6, SOCK_STREAM, 0);
- #else /* LWIP_IPV6 */
- s1 = lwip_socket(AF_INET, SOCK_STREAM, 0);
- s2 = lwip_socket(AF_INET, SOCK_STREAM, 0);
- #endif /* LWIP_IPV6 */
- LWIP_ASSERT("s1 >= 0", s1 >= 0);
- LWIP_ASSERT("s2 >= 0", s2 >= 0);
- /* connect, should succeed */
- ret = lwip_connect(s1, (struct sockaddr*)&addr, sizeof(addr));
- LWIP_ASSERT("ret == 0", ret == 0);
- ret = lwip_connect(s2, (struct sockaddr*)&addr, sizeof(addr));
- LWIP_ASSERT("ret == 0", ret == 0);
- /* write the start of a GET request */
- #define SNDSTR1 "G"
- len = strlen(SNDSTR1);
- ret = lwip_write(s1, SNDSTR1, len);
- LWIP_ASSERT("ret == len", ret == (int)len);
- ret = lwip_write(s2, SNDSTR1, len);
- LWIP_ASSERT("ret == len", ret == (int)len);
- LWIP_UNUSED_ARG(ret);
- h1.wait_read = 1;
- h1.wait_write = 1;
- h1.wait_err = 1;
- h1.expect_read = 0;
- h1.expect_write = 0;
- h1.expect_err = 0;
- lwiperr = sys_sem_new(&h1.sem, 0);
- LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK);
- h1.socket = s1;
- h1.wait_ms = 500;
- h2 = h1;
- lwiperr = sys_sem_new(&h2.sem, 0);
- LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK);
- h2.socket = s2;
- h2.wait_ms = 1000;
- h3 = h1;
- lwiperr = sys_sem_new(&h3.sem, 0);
- LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK);
- h3.socket = s2;
- h3.wait_ms = 1500;
- h4 = h1;
- lwiperr = sys_sem_new(&h4.sem, 0);
- LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK);
- LWIP_UNUSED_ARG(lwiperr);
- h4.socket = s2;
- h4.wait_ms = 2000;
- /* select: all sockets should time out if the other side is a good HTTP server */
- sys_thread_new("sockex_select_waiter1", sockex_select_waiter, &h2, 0, 0);
- sys_msleep(100);
- sys_thread_new("sockex_select_waiter2", sockex_select_waiter, &h1, 0, 0);
- sys_msleep(100);
- sys_thread_new("sockex_select_waiter2", sockex_select_waiter, &h4, 0, 0);
- sys_msleep(100);
- sys_thread_new("sockex_select_waiter2", sockex_select_waiter, &h3, 0, 0);
- sys_sem_wait(&h1.sem);
- sys_sem_wait(&h2.sem);
- sys_sem_wait(&h3.sem);
- sys_sem_wait(&h4.sem);
- /* close */
- ret = lwip_close(s1);
- LWIP_ASSERT("ret == 0", ret == 0);
- ret = lwip_close(s2);
- LWIP_ASSERT("ret == 0", ret == 0);
- printf("sockex_testtwoselects finished successfully\n");
- }
- #else
- static void
- sockex_testtwoselects(void *arg)
- {
- LWIP_UNUSED_ARG(arg);
- }
- #endif
- #if !SOCKET_EXAMPLES_RUN_PARALLEL
- static void
- socket_example_test(void* arg)
- {
- sys_msleep(1000);
- sockex_nonblocking_connect(arg);
- sockex_testrecv(arg);
- sockex_testtwoselects(arg);
- printf("all tests done, thread ending\n");
- }
- #endif
- void socket_examples_init(void)
- {
- int addr_ok;
- #if LWIP_IPV6
- IP_SET_TYPE_VAL(dstaddr, IPADDR_TYPE_V6);
- addr_ok = ip6addr_aton(SOCK_TARGET_HOST6, ip_2_ip6(&dstaddr));
- #else /* LWIP_IPV6 */
- IP_SET_TYPE_VAL(dstaddr, IPADDR_TYPE_V4);
- addr_ok = ip4addr_aton(SOCK_TARGET_HOST4, ip_2_ip4(&dstaddr));
- #endif /* LWIP_IPV6 */
- LWIP_ASSERT("invalid address", addr_ok);
- #if SOCKET_EXAMPLES_RUN_PARALLEL
- sys_thread_new("sockex_nonblocking_connect", sockex_nonblocking_connect, &dstaddr, 0, 0);
- sys_thread_new("sockex_testrecv", sockex_testrecv, &dstaddr, 0, 0);
- sys_thread_new("sockex_testtwoselects", sockex_testtwoselects, &dstaddr, 0, 0);
- #else
- sys_thread_new("socket_example_test", socket_example_test, &dstaddr, 0, 0);
- #endif
- }
- #endif /* LWIP_SOCKET */
|