int Socket::WaitForConnect() { lwip_fd_set fds; struct timeval tmo; int error; socklen_t len = sizeof(error); LWIP_FD_ZERO(&fds); LWIP_FD_SET(socket_->fd, &fds); tmo.tv_sec = 5; tmo.tv_usec = 0; //log(LOG_WARN) << "waiting"; if ( lwip_select(socket_->fd+1, NULL, &fds, NULL, &tmo) <= 0) { return -1; } if ( lwip_getsockopt(socket_->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0 || error > 0 ) { return -1; } return 0; }
// return: 0 timeout. // >0 length // <0 socket error int blocking_lwip_recv(int s, void *mem, size_t len, int timeout) // the len param here is the length to recv. { int readlen, offset = 0; fd_set fds; int ret; struct timeval to; to.tv_sec = timeout/1000; to.tv_usec = (timeout%1000)*1000; while(1) { FD_ZERO(&fds); FD_SET(s,&fds); ret = lwip_select(s+1,&fds,0,0,&to); if( ret == 0 ) break; else if( ret < 0 ) return ret; readlen = lwip_recvfrom(s, ((char*)mem)+offset, len-offset, 0, NULL, NULL); if( readlen == 0 ) // select is ok and readlen == 0 means connection lost. return -1; else if( readlen < 0 ) return readlen; if( readlen == (len-offset) ) { offset = len; break; } offset += readlen; } return offset; }
int mc_event_main(xsMachine *the, mc_event_shutdown_callback_t *cb) { struct timeval tv; fd_set rs, ws; int n = -1, i; unsigned int flags; uint64_t timeInterval; struct sockaddr_in sin; int localevent_sock; mc_shutdown_callback = cb; g_status = -1; /* not ready yet */ if ((localevent_sock = lwip_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) return -1; sin.sin_family = AF_INET; sin.sin_port = htons(MC_LOCAL_EVENT_PORT); sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); lwip_bind(localevent_sock, (struct sockaddr *)&sin, sizeof(sin)); mc_event_register(localevent_sock, MC_SOCK_READ, mc_event_local_callback, the); mc_event_delegation_init(); g_status = 0; /* running */ while (!g_status) { timeInterval = mc_event_process_timeout(the); if (timeInterval != 0) { tv.tv_sec = timeInterval / 1000; tv.tv_usec = (timeInterval % 1000) * 1000; } if (maxfd < 0) { /* @@ what if only timer is running?? */ mc_log_debug("event: no one is waiting!\n"); break; /* no one is waiting for anything! will be blocked forever unless break */ } rs = reads; ws = writes; n = lwip_select(maxfd + 1, &rs, &ws, NULL, timeInterval > 0 ? &tv : NULL); if (mc_event_callback_any.callback != NULL) (*mc_event_callback_any.callback)(mc_event_callback_any.fd, (unsigned int)n, mc_event_callback_any.closure); if (n > 0) { for (i = 0; i <= maxfd; i++) { flags = 0; if (FD_ISSET(i, &rs)) flags |= MC_SOCK_READ; if (FD_ISSET(i, &ws)) flags |= MC_SOCK_WRITE; if (flags) { if (mc_event_callbacks[i].callback == NULL) { mc_log_error("event: %s ready for closed socket(%d)!?\n", flags & MC_SOCK_WRITE ? "write" : "read", i); continue; } (*mc_event_callbacks[i].callback)(i, flags, mc_event_callbacks[i].closure); } } } } mc_event_delegation_fin(); lwip_close(localevent_sock); return g_exit_status; }
static void SC_Select(__SYSCALL_PARAM_BLOCK* pspb) { pspb->lpRetValue = (LPVOID)lwip_select( (INT)PARAM(0), (fd_set*)PARAM(1), (fd_set*)PARAM(2), (fd_set*)PARAM(3), (struct timeval*)PARAM(4) ); }
int socket_select(struct mySocket *sock, struct timeval *timeout, int read, int write) { fd_set fdSet; FD_ZERO(&fdSet); FD_SET(sock->_sock_fd, &fdSet); fd_set* readset = (read ) ? (&fdSet) : (NULL); fd_set* writeset = (write) ? (&fdSet) : (NULL); int ret = lwip_select(FD_SETSIZE, readset, writeset, NULL, timeout); return (ret <= 0 || !FD_ISSET(sock->_sock_fd, &fdSet)) ? (-1) : (0); }
/** 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); } 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); }
int LWIP_SOCKETS_Driver::Select( int nfds, SOCK_fd_set* readfds, SOCK_fd_set* writefds, SOCK_fd_set* exceptfds, const SOCK_timeval* timeout ) { NATIVE_PROFILE_PAL_NETWORK(); int ret = 0; fd_set read; fd_set write; fd_set excpt; fd_set* pR = (readfds != NULL) ? &read : NULL; fd_set* pW = (writefds != NULL) ? &write : NULL; fd_set* pE = (exceptfds != NULL) ? &excpt : NULL; // If the network goes down then we should alert any pending socket actions if(exceptfds != NULL && exceptfds->fd_count > 0) { struct netif *pNetIf = netif_find_interface(g_LWIP_SOCKETS_Driver.m_interfaces[0].m_interfaceNumber); if(pNetIf != NULL) { if(!netif_is_up(pNetIf)) { if(readfds != NULL) readfds->fd_count = 0; if(writefds != NULL) writefds->fd_count = 0; errno = ENETDOWN; return exceptfds->fd_count; } } } MARSHAL_SOCK_FDSET_TO_FDSET(readfds , pR); MARSHAL_SOCK_FDSET_TO_FDSET(writefds , pW); MARSHAL_SOCK_FDSET_TO_FDSET(exceptfds, pE); ret = lwip_select(MEMP_NUM_NETCONN, pR, pW, pE, (struct timeval *)timeout); MARSHAL_FDSET_TO_SOCK_FDSET(readfds , pR); MARSHAL_FDSET_TO_SOCK_FDSET(writefds , pW); MARSHAL_FDSET_TO_SOCK_FDSET(exceptfds, pE); return ret; }
//-------------------------------------------------------------- int recv_noblock(int sock, u8 *buf, int bsize) { int r; fd_set rfd; FD_ZERO(&rfd); FD_SET(sock, &rfd); r = lwip_select(sock+1, &rfd, NULL, NULL, NULL); if (r < 0) return -1; // receive the packet r = lwip_recv(sock, buf, bsize, 0); if (r < 0) return -2; return r; }
static int sendCallback(WOLFSSL* ssl, char *buf, int sz, void *ctx) { int fd = *(int*)ctx; int result; (void)ssl; fd_set wfds; FD_ZERO(&wfds); FD_SET(fd, &wfds); if (lwip_select(FD_SETSIZE, NULL, &wfds, NULL, NULL) < 0) { return -1; } else { result = lwip_send(fd, buf, sz, 0); } return result; }
END_TEST START_TEST(test_sockets_select) { #if LWIP_SOCKET_SELECT int s; int ret; fd_set readset; fd_set writeset; fd_set errset; struct timeval tv; fail_unless(test_sockets_get_used_count() == 0); s = lwip_socket(AF_INET, SOCK_STREAM, 0); fail_unless(s >= 0); fail_unless(test_sockets_get_used_count() == 0); FD_ZERO(&readset); FD_SET(s, &readset); FD_ZERO(&writeset); FD_SET(s, &writeset); FD_ZERO(&errset); FD_SET(s, &errset); tv.tv_sec = tv.tv_usec = 0; ret = lwip_select(s + 1, &readset, &writeset, &errset, &tv); fail_unless(ret == 0); fail_unless(test_sockets_get_used_count() == 0); ret = lwip_close(s); fail_unless(ret == 0); #endif LWIP_UNUSED_ARG(_i); }
void net_listen_thread_entry(void *p) { int listenfd; struct sockaddr_in saddr; fd_set readset; // check mode first. if( !((getWorkingMode() == TCP_SERVER) || (getWorkingMode() == TCP_AUTO)) ) return; // Acquire our socket for listening for connections listenfd = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if( listenfd == -1 ) { rt_kprintf("Can not create socket!\n"); return; } memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = htons(getListenPort()); //server port if (lwip_bind(listenfd, (struct sockaddr *) &saddr, sizeof(saddr)) == -1) { lwip_close(listenfd); rt_kprintf("Socket bind failed!\n"); return; } /* Put socket into listening mode */ if (lwip_listen(listenfd, MAX_LISTEN_SOCK) == -1) { lwip_close(listenfd); rt_kprintf("Listen failed.\n"); return; } /* Wait for data or a new connection */ while(1) { /* Determine what sockets need to be in readset */ FD_ZERO(&readset); FD_SET(listenfd, &readset); // wait forever. if( lwip_select(listenfd+1, &readset, 0, 0, 0) == 0 ) continue; if (FD_ISSET(listenfd, &readset)) { int i; socklen_t clilen = sizeof(struct sockaddr_in); for( i = 0 ; i < SOCKET_LIST_SIZE ; i++ ) { // we don't block here. rt_err_t ret = rt_mutex_take(&(socket_list[i].mu_sock),RT_WAITING_NO); if( ret == -RT_ETIMEOUT ) continue; // we already took the mutex here. if( socket_list[i].used ) { rt_mutex_release(&(socket_list[i].mu_sock)); continue; } // it's an empty slot. socket_list[i].socket = lwip_accept(listenfd, (struct sockaddr *)&(socket_list[i].cliaddr),&clilen); // if accept failed. if( socket_list[i].socket < 0 ) { rt_kprintf("Accept failed!\n"); } // accept successfully. else { int optval = 1; // set keepalive. lwip_setsockopt(socket_list[i].socket,SOL_SOCKET,SO_KEEPALIVE,&optval,sizeof(optval)); // set used flag. socket_list[i].used = 1; rt_kprintf("Accept connection.\n"); } rt_mutex_release(&(socket_list[i].mu_sock)); break; } // check if not enough slot. if( i == SOCKET_LIST_SIZE ) { // just accept and disconnect. int sock; struct sockaddr cliaddr; socklen_t clilen; sock = lwip_accept(listenfd, &cliaddr, &clilen); if (sock >= 0) lwip_close(sock); rt_kprintf("Not enough slot, accept and close connection.\n"); } } else { rt_kprintf("ERROR,should not reach here!\n"); } } }
void usart_tx_thread_entry(void *p) { fd_set readset; struct timeval timeout; int fd_max; timeout.tv_sec = 0; // second. timeout.tv_usec = 100*1000; //wait micro second. while( 1 ) { int i; // prepare select fd. FD_ZERO(&readset); fd_max = 0; for( i = 0 ; i < SOCKET_LIST_SIZE ; i++ ) { if( socket_list[i].used ) { if( fd_max < socket_list[i].socket ) fd_max = socket_list[i].socket; FD_SET(socket_list[i].socket,&readset); } } // no connection. if( fd_max == 0 ) { rt_thread_delay(1); // delay 10ms. continue; } if( lwip_select(fd_max+1,&readset,NULL,0,&timeout) == 0 ) continue; for( i = 0 ; i < SOCKET_LIST_SIZE ; i++ ) { rt_err_t ret; // NOTE: we can take tx semaphore here means that the DMA buffer is not in use. // We must NOT write the DMA buffer until notified to be used. rt_sem_take(&tx1_sem,RT_WAITING_FOREVER); rt_sem_take(&tx2_sem,RT_WAITING_FOREVER); // Timeout 100ms. ret = rt_mutex_take(&(socket_list[i].mu_sock),10); if( ret == -RT_ETIMEOUT ) { rt_kprintf("Taking mu_sock timeout.\n"); rt_sem_release(&tx2_sem); rt_sem_release(&tx1_sem); continue; } if( socket_list[i].used && FD_ISSET(socket_list[i].socket,&readset) ) { unsigned short dataLen = lwip_recv(socket_list[i].socket,tx_buf,TX_BUF_SIZE,MSG_DONTWAIT); if( dataLen > 0 ) { usart_bytes_sent += dataLen; usart_led_flash(); dev_uart1->write(dev_uart1,0,tx_buf,dataLen); dev_uart2->write(dev_uart2,0,tx_buf,dataLen); // we have sent data to usart. rt_mutex_release(&(socket_list[i].mu_sock)); continue; } else { lwip_close(socket_list[i].socket); socket_list[i].used = 0; rt_kprintf("recv failed or FIN recv, close socket.\n"); } } rt_mutex_release(&(socket_list[i].mu_sock)); rt_sem_release(&tx2_sem); rt_sem_release(&tx1_sem); } } }
void udp_setup_thread_entry(void *p) { int sock; int bytes_read; struct sockaddr_in server_addr , client_addr; int optval = 1; fd_set readset; /* create socket */ if ((sock = lwip_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { rt_kprintf("Can not create udp setup socket.\n"); return; } lwip_setsockopt(sock,SOL_SOCKET,SO_BROADCAST,&optval ,sizeof(optval)); /* init server socket address */ server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SETUP_UDP_PORT); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); rt_memset(&(server_addr.sin_zero),0, sizeof(server_addr.sin_zero)); if (lwip_bind(sock,(struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) { rt_kprintf("Bind error\n"); return; } rt_kprintf("UDPServer Waiting for client on port %d \n",SETUP_UDP_PORT); while (1) { int bytes_ret; rt_uint32_t addr_len = sizeof(struct sockaddr_in); FD_ZERO(&readset); FD_SET(sock, &readset); if( lwip_select(sock+1, &readset, 0, 0, 0) == 0 ) continue; rt_mutex_take(&setup_data_buf_mutex,RT_WAITING_FOREVER); bytes_read = lwip_recvfrom(sock, setup_data_buf, DATA_BUF_SIZE, MSG_DONTWAIT, (struct sockaddr *)&client_addr, &addr_len); rt_mutex_release(&setup_data_buf_mutex); if( bytes_read < 0 ) { continue; } rt_mutex_take(&setup_data_buf_mutex,RT_WAITING_FOREVER); setup_data_buf[bytes_read] = 0; bytes_ret = processCMD(setup_data_buf,bytes_read); rt_mutex_release(&setup_data_buf_mutex); if( bytes_ret > 0 ) { // command execute success, send reply in buffer. client_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); rt_mutex_take(&setup_data_buf_mutex,RT_WAITING_FOREVER); lwip_sendto(sock,setup_data_buf,bytes_ret,0,(struct sockaddr*)&client_addr, sizeof(struct sockaddr)); rt_mutex_release(&setup_data_buf_mutex); } } // Should not reach here!. }
/** This is an example function that tests the recv function (timeout etc.). */ static void sockex_testrecv(void *arg) { int s; int ret; int err; int opt; struct sockaddr_in addr; size_t len; char rxbuf[1024]; fd_set readset; fd_set errset; struct timeval tv; LWIP_UNUSED_ARG(arg); /* set up address to connect to */ memset(&addr, 0, sizeof(addr)); addr.sin_len = sizeof(addr); addr.sin_family = AF_INET; addr.sin_port = PP_HTONS(SOCK_TARGET_PORT); addr.sin_addr.s_addr = inet_addr(SOCK_TARGET_HOST); /* first try blocking: */ /* create the socket */ s = lwip_socket(AF_INET, SOCK_STREAM, 0); 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) */ opt = 100; ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &opt, sizeof(int)); LWIP_ASSERT("ret == 0", ret == 0); /* 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); /* 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, 1024); LWIP_ASSERT("ret > 0", ret > 0); /* 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)); /* should not time out but receive a response */ ret = lwip_read(s, rxbuf, 1024); /* might receive a second packet for HTTP/1.1 servers */ if (ret > 0) { /* should return 0: closed */ ret = lwip_read(s, rxbuf, 1024); LWIP_ASSERT("ret == 0", ret == 0); } /* close */ ret = lwip_close(s); LWIP_ASSERT("ret == 0", ret == 0); printf("sockex_testrecv finished successfully\n"); }
/** This is an example function that tests blocking- and nonblocking connect. */ static void sockex_nonblocking_connect(void *arg) { int s; int ret; u32_t opt; struct sockaddr_in addr; fd_set readset; fd_set writeset; fd_set errset; struct timeval tv; u32_t ticks_a, ticks_b; int err; LWIP_UNUSED_ARG(arg); /* set up address to connect to */ memset(&addr, 0, sizeof(addr)); addr.sin_len = sizeof(addr); addr.sin_family = AF_INET; addr.sin_port = PP_HTONS(SOCK_TARGET_PORT); addr.sin_addr.s_addr = inet_addr(SOCK_TARGET_HOST); /* first try blocking: */ /* create the socket */ s = lwip_socket(AF_INET, SOCK_STREAM, 0); 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 */ s = lwip_socket(AF_INET, SOCK_STREAM, 0); 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 */ s = lwip_socket(AF_INET, SOCK_STREAM, 0); 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); FD_ZERO(&readset); FD_SET(s, &readset); FD_ZERO(&writeset); FD_SET(s, &writeset); FD_ZERO(&errset); FD_SET(s, &errset); tv.tv_sec = 0; tv.tv_usec = 0; /* select without waiting should fail */ ret = lwip_select(s + 1, &readset, &writeset, &errset, &tv); LWIP_ASSERT("ret == 0", ret == 0); LWIP_ASSERT("!FD_ISSET(s, &writeset)", !FD_ISSET(s, &writeset)); LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &readset)); LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &errset)); FD_ZERO(&readset); FD_SET(s, &readset); FD_ZERO(&writeset); FD_SET(s, &writeset); FD_ZERO(&errset); FD_SET(s, &errset); ticks_a = sys_now(); /* select with waiting should succeed */ ret = lwip_select(s + 1, &readset, &writeset, &errset, NULL); ticks_b = sys_now(); LWIP_ASSERT("ret == 1", ret == 1); LWIP_ASSERT("FD_ISSET(s, &writeset)", FD_ISSET(s, &writeset)); LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &readset)); LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &errset)); /* 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", 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 */ s = lwip_socket(AF_INET, SOCK_STREAM, 0); LWIP_ASSERT("s >= 0", s >= 0); /* nonblocking */ opt = 1; ret = lwip_ioctl(s, FIONBIO, &opt); LWIP_ASSERT("ret == 0", ret == 0); addr.sin_addr.s_addr++; /* 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); FD_ZERO(&readset); FD_SET(s, &readset); FD_ZERO(&writeset); FD_SET(s, &writeset); FD_ZERO(&errset); FD_SET(s, &errset); tv.tv_sec = 0; tv.tv_usec = 0; /* select without waiting should fail */ ret = lwip_select(s + 1, &readset, &writeset, &errset, &tv); LWIP_ASSERT("ret == 0", ret == 0); FD_ZERO(&readset); FD_SET(s, &readset); FD_ZERO(&writeset); FD_SET(s, &writeset); FD_ZERO(&errset); FD_SET(s, &errset); ticks_a = sys_now(); /* select with waiting should eventually succeed and return errset! */ ret = lwip_select(s + 1, &readset, &writeset, &errset, NULL); ticks_b = sys_now(); LWIP_ASSERT("ret > 0", ret > 0); LWIP_ASSERT("FD_ISSET(s, &errset)", FD_ISSET(s, &errset)); LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &readset)); LWIP_ASSERT("!FD_ISSET(s, &writeset)", !FD_ISSET(s, &writeset)); /* close */ ret = lwip_close(s); LWIP_ASSERT("ret == 0", ret == 0); printf("select() needed %d ticks to return error\n", ticks_b - ticks_a); printf("all tests done, thread ending\n"); }
// // Receive a file from the client // static void tftpd_write_file(struct tftphdr *hdr, struct sockaddr_in *from_addr, int from_len) { struct tftphdr *reply = (struct tftphdr *)data_out; struct tftphdr *response = (struct tftphdr *)data_in; int fd, len, ok, tries, closed, data_len, s; unsigned short block; struct timeval timeout; fd_set fds; int total_timeouts = 0; struct sockaddr_in client_addr, local_addr; socklen_t client_len; s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { return; } memset((char *)&local_addr, 0, sizeof(local_addr)); local_addr.sin_family = AF_INET; local_addr.sin_len = sizeof(local_addr); local_addr.sin_addr.s_addr = htonl(INADDR_ANY); local_addr.sin_port = htons(INADDR_ANY); if (bind(s, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) { // Problem setting up my end close(s); return; } if ((fd = tftpd_open_data_file((int)hdr->th_stuff, O_WRONLY)) < 0) { tftpd_send_error(s,reply,TFTP_ENOTFOUND,from_addr, from_len); close(s); return; } ok = pdTRUE; closed = pdFALSE; block = 0; while (ok) { // Send ACK telling client he can send data reply->th_opcode = htons(ACK); reply->th_block = htons(block++); // postincrement for (tries = 0; tries < TFTP_RETRIES_MAX; tries++) { sendto(s, reply, 4, 0, (struct sockaddr *)from_addr, from_len); repeat_select: timeout.tv_sec = TFTP_TIMEOUT_PERIOD; timeout.tv_usec = 0; FD_ZERO(&fds); FD_SET(s, &fds); vParTestToggleLED( TFTP_LED ); if (lwip_select(s+1, &fds, 0, 0, &timeout) <= 0) { if (++total_timeouts > TFTP_TIMEOUT_MAX) { tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len); ok = pdFALSE; break; } continue; // retry the send, using up one retry. } vParTestToggleLED( TFTP_LED ); // Some data has arrived data_len = sizeof(data_in); client_len = sizeof(client_addr); if ((data_len = recvfrom(s, data_in, data_len, 0, (struct sockaddr *)&client_addr, &client_len)) < 0) { // What happened? No data here! continue; // retry the send, using up one retry. } if (ntohs(response->th_opcode) == DATA && ntohs(response->th_block) < block) { // Then it is repeat DATA with an old block; listen again, // but do not repeat sending the current ack, and do not // use up a retry count. (we do re-send the ack if // subsequently we time out) goto repeat_select; } if (ntohs(response->th_opcode) == DATA && ntohs(response->th_block) == block) { // Good data - write to file len = tftpd_write_data_file(fd, response->th_data, data_len-4); if (len < (data_len-4)) { // File is "full" tftpd_send_error(s,reply,TFTP_ENOSPACE, from_addr, from_len); ok = pdFALSE; // Give up break; // out of the retries loop } if (data_len < (SEGSIZE+4)) { // End of file closed = pdTRUE; ok = pdFALSE; vParTestSetLED( 0 , 0 ); if (tftpd_close_data_file(fd) == -1) { tftpd_send_error(s,reply,TFTP_EACCESS, from_addr, from_len); break; // out of the retries loop } // Exception to the loop structure: we must ACK the last // packet, the one that implied EOF: reply->th_opcode = htons(ACK); reply->th_block = htons(block++); // postincrement sendto(s, reply, 4, 0, (struct sockaddr *)from_addr, from_len); break; // out of the retries loop } // Happy! Break out of the retries loop. break; } } // End of the retries loop. if (TFTP_RETRIES_MAX <= tries) { tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len); ok = pdFALSE; } } close(s); if (!closed) { tftpd_close_data_file(fd); } }
int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout) { int index, result; int sock, maxfd; fd_set sock_readset; fd_set sock_writeset; fd_set sock_exceptset; FD_ZERO(&sock_readset); FD_ZERO(&sock_writeset); FD_ZERO(&sock_exceptset); maxfd = 0; for (index = 0; index < maxfdp1; index ++) { /* convert fd to sock */ sock = dfs_lwip_getsocket(index); if (sock == -1) continue; if (sock > maxfd) maxfd = sock; /* if FD is set, set the socket set */ if (readset && FD_ISSET(index, readset)) { FD_SET(sock, &sock_readset); } if (writeset && FD_ISSET(index, writeset)) { FD_SET(sock, &sock_writeset); } if (exceptset && FD_ISSET(index, exceptset)) { FD_SET(sock, &sock_exceptset); } } /* no socket found, return bad file descriptor */ if (maxfd == 0) return -EBADF; maxfd += 1; result = lwip_select(maxfd, &sock_readset, &sock_writeset, &sock_exceptset, timeout); if (readset) FD_ZERO(readset); if (writeset) FD_ZERO(writeset); if (exceptset) FD_ZERO(exceptset); if (result != -1) { for (index = 0; index < maxfd; index ++) { /* check each socket */ if ((FD_ISSET(index, &sock_readset)) || (FD_ISSET(index, &sock_writeset)) || (FD_ISSET(index, &sock_exceptset))) { int fd_index; /* Because we can not get the corresponding fd, we have to search it one by one */ for (fd_index = 0; fd_index < maxfdp1; fd_index ++) { sock = dfs_lwip_getsocket(fd_index); if (sock == index) /* found it */ { if (readset && FD_ISSET(index, &sock_readset)) { FD_SET(sock, readset); } if (writeset && FD_ISSET(index, &sock_writeset)) { FD_SET(sock, writeset); } if (exceptset && FD_ISSET(index, &sock_exceptset)) { FD_SET(sock, exceptset); } /* end of search */ break; } } } } } return result; }
int dump_data(UrlResource *rsrc, int sock, FILE *out, libnet_callback notify) { Progress *p = NULL; int bytes_read = 0; ssize_t written = 0; char *buf = NULL; int lenth, final, final2 = 0; int buflen; if ((out == NULL) && (rsrc->buffer == NULL) && (NULL == rsrc->strfile_handle)) return 0; /* if we already have all of it */ if ( !(rsrc->options ) ) { if ( rsrc->outfile_size &&(rsrc->outfile_offset >= rsrc->outfile_size) ) { LIBNET_DEBUG( "you already have all of `%s', skipping", rsrc->outfile); //S_CLOSE(sock); return 0; } } p = progress_new(); p->tranfer_callback = notify; if(NULL == rsrc->strfile_handle) { progress_init(p, rsrc, rsrc->outfile_size); progress_update(p, rsrc->outfile_offset); buflen = BUFSIZE; }else { progress_init(p, rsrc, rsrc->outfile_size); buflen = BUFSIZE * 3; } p->offset = rsrc->outfile_offset; if ( out && (rsrc->outfile_offset > 0) && (rsrc->options & OPT_RESUME)) { fseek(out, rsrc->outfile_offset, SEEK_SET); LIBNET_DEBUG("ftell = %d \n", ftell(out)); } buf = MALLOC(buflen); if(rsrc->strfile_handle) { fd_set set; struct timeval tv = {30, 0}; FD_ZERO(&set); FD_SET(sock, &set); while (lwip_select(sock + 1, &set, NULL, NULL, &tv) > 0 && (rsrc->running)) { bytes_read = S_READ(sock, buf, buflen); if(0 >= bytes_read) break; lenth = bytes_read; final += bytes_read; final2 += bytes_read; while(lenth) { written = httpstrfile_writedatatobuff(rsrc->strfile_handle, buf + (bytes_read - lenth), (UINT32)lenth); lenth -= written; osal_task_sleep(1); } if(0x20000 <= final2) { // libc_printf("final = %d/%d\n", final, rsrc->outfile_size); progress_update(p, final2); final2 = 0; } }
BST_IP_ERR_T BST_IP_SslReceive( BST_FD_T fd, BST_UINT8* pData, BST_UINT16 usLength ) { SSL *pstSsl; BST_UINT8 *pucTmpBuf; BST_INT32 lRtnVal; BST_INT32 lCopyedLen; BST_INT32 lSelect; BST_INT32 lSockFd; fd_set stRdFds; timeval stTval; stTval.tv_sec = 0; stTval.tv_usec = 0; if ( BST_NULL_PTR == fd.pFd ) { return BST_IP_ERR_ARG; } if ( BST_NULL_PTR == pData ) { return BST_IP_ERR_ARG; } lCopyedLen = 0; pstSsl = (SSL *)fd.pFd; lSockFd = SSL_get_fd( pstSsl ); pucTmpBuf = (BST_UINT8 *)BST_OS_MALLOC( usLength ); if ( BST_NULL_PTR == pucTmpBuf ) { return BST_IP_ERR_MEM; } do { FD_ZERO( &stRdFds ); FD_SET( lSockFd, &stRdFds ); lRtnVal = SSL_read( pstSsl, pucTmpBuf, usLength ); if ( lRtnVal <= 0 ) { BST_RLS_LOG( "BST_IP_SslReceive SSL_read error" ); break; } if ( 0 == lCopyedLen ) { BST_OS_MEMCPY( pData, pucTmpBuf, lRtnVal ); lCopyedLen = lRtnVal; BST_DBG_LOG1( "BST_IP_SslReceive lCopyedLen", lCopyedLen ); } /*如果ssl内部缓冲区没有数据可读,则判断IP协议栈是否有数据可读*/ if ( !SSL_pending( pstSsl ) ) { lSelect = lwip_select( lSockFd + 1, &stRdFds, NULL, NULL, &stTval ); if ( lSelect < 0) { BST_RLS_LOG( "BST_IP_SslReceive lwip_select error" ); break; } /*如果协议栈也没有数据可读,则说明这次读取完毕,退出*/ if ( !FD_ISSET( lSockFd,&stRdFds ) ) { BST_DBG_LOG( "BST_IP_SslReceive socket is not data" ); break; } } } while( 1 ); BST_OS_FREE( pucTmpBuf ); return lCopyedLen; }
int poll(struct pollfd *fds, unsigned long nfds, int timeout) { int i,err; fd_set rfd, wfd, efd, ifd; struct timeval timebuf; struct timeval *tbuf = (struct timeval *)0; int n = 0; int count; FD_ZERO(&ifd); FD_ZERO(&rfd); FD_ZERO(&wfd); FD_ZERO(&efd); for (i = 0; i < nfds; i++) { int events = fds[i].events; int fd = fds[i].fd; fds[i].revents = 0; if ((fd < 0) || (FD_ISSET(fd, &ifd))) continue; if (fd > n) n = fd; if (events & POLL_CAN_READ) FD_SET(fd, &rfd); if (events & POLL_CAN_WRITE) FD_SET(fd, &wfd); if (events & POLL_HAS_EXCP) FD_SET(fd, &efd); } if (timeout >= 0) { timebuf.tv_sec = timeout / 1000; timebuf.tv_usec = (timeout % 1000) * 1000; tbuf = &timebuf; } err = lwip_select(n+1, &rfd, &wfd, &efd, tbuf); if (err < 0) return err; count = 0; for (i = 0; i < nfds; i++) { int revents = (fds[i].events & POLL_EVENTS_MASK); int fd = fds[i].fd; if (fd < 0) continue; if (FD_ISSET(fd, &ifd)) revents = POLLNVAL; else { if (!FD_ISSET(fd, &rfd)) revents &= ~POLL_CAN_READ; if (!FD_ISSET(fd, &wfd)) revents &= ~POLL_CAN_WRITE; if (!FD_ISSET(fd, &efd)) revents &= ~POLL_HAS_EXCP; } if ((fds[i].revents = revents) != 0) count++; } return count; }
/* Just poll without blocking */ static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds) { int i, n = 0; #ifdef HAVE_LWIP int sock_n = 0, sock_nfds = 0; fd_set sock_readfds, sock_writefds, sock_exceptfds; struct timeval timeout = { .tv_sec = 0, .tv_usec = 0}; #endif #ifdef LIBC_VERBOSE static int nb; static int nbread[NOFILE], nbwrite[NOFILE], nbexcept[NOFILE]; static s_time_t lastshown; nb++; #endif #ifdef HAVE_LWIP /* first poll network */ FD_ZERO(&sock_readfds); FD_ZERO(&sock_writefds); FD_ZERO(&sock_exceptfds); for (i = 0; i < nfds; i++) { if (files[i].type == FTYPE_SOCKET) { if (FD_ISSET(i, readfds)) { FD_SET(files[i].socket.fd, &sock_readfds); sock_nfds = i+1; } if (FD_ISSET(i, writefds)) { FD_SET(files[i].socket.fd, &sock_writefds); sock_nfds = i+1; } if (FD_ISSET(i, exceptfds)) { FD_SET(files[i].socket.fd, &sock_exceptfds); sock_nfds = i+1; } } } if (sock_nfds > 0) { DEBUG("lwip_select("); dump_set(nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout); DEBUG("); -> "); sock_n = lwip_select(sock_nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout); dump_set(nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout); DEBUG("\n"); } #endif /* Then see others as well. */ for (i = 0; i < nfds; i++) { switch(files[i].type) { default: if (FD_ISSET(i, readfds) || FD_ISSET(i, writefds) || FD_ISSET(i, exceptfds)) printk("bogus fd %d in select\n", i); /* Fallthrough. */ case FTYPE_CONSOLE: if (FD_ISSET(i, readfds)) { if (xencons_ring_avail(files[i].cons.dev)) n++; else FD_CLR(i, readfds); } if (FD_ISSET(i, writefds)) n++; FD_CLR(i, exceptfds); break; #ifdef CONFIG_XENBUS case FTYPE_XENBUS: if (FD_ISSET(i, readfds)) { if (files[i].xenbus.events) n++; else FD_CLR(i, readfds); } FD_CLR(i, writefds); FD_CLR(i, exceptfds); break; #endif case FTYPE_EVTCHN: case FTYPE_TAP: case FTYPE_BLK: case FTYPE_KBD: case FTYPE_FB: if (FD_ISSET(i, readfds)) { if (files[i].read) n++; else FD_CLR(i, readfds); } FD_CLR(i, writefds); FD_CLR(i, exceptfds); break; #ifdef HAVE_LWIP case FTYPE_SOCKET: if (FD_ISSET(i, readfds)) { /* Optimize no-network-packet case. */ if (sock_n && FD_ISSET(files[i].socket.fd, &sock_readfds)) n++; else FD_CLR(i, readfds); } if (FD_ISSET(i, writefds)) { if (sock_n && FD_ISSET(files[i].socket.fd, &sock_writefds)) n++; else FD_CLR(i, writefds); } if (FD_ISSET(i, exceptfds)) { if (sock_n && FD_ISSET(files[i].socket.fd, &sock_exceptfds)) n++; else FD_CLR(i, exceptfds); } break; #endif } #ifdef LIBC_VERBOSE if (FD_ISSET(i, readfds)) nbread[i]++; if (FD_ISSET(i, writefds)) nbwrite[i]++; if (FD_ISSET(i, exceptfds)) nbexcept[i]++; #endif } #ifdef LIBC_VERBOSE if (NOW() > lastshown + 1000000000ull) { lastshown = NOW(); printk("%lu MB free, ", num_free_pages() / ((1 << 20) / PAGE_SIZE)); printk("%d(%d): ", nb, sock_n); for (i = 0; i < nfds; i++) { if (nbread[i] || nbwrite[i] || nbexcept[i]) printk(" %d(%c):", i, file_types[files[i].type]); if (nbread[i]) printk(" %dR", nbread[i]); if (nbwrite[i]) printk(" %dW", nbwrite[i]); if (nbexcept[i]) printk(" %dE", nbexcept[i]); } printk("\n"); memset(nbread, 0, sizeof(nbread)); memset(nbwrite, 0, sizeof(nbwrite)); memset(nbexcept, 0, sizeof(nbexcept)); nb = 0; } #endif return n; } /* The strategy is to * - announce that we will maybe sleep * - poll a bit ; if successful, return * - if timeout, return * - really sleep (except if somebody woke us in the meanwhile) */ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { int n, ret; fd_set myread, mywrite, myexcept; struct thread *thread = get_current(); s_time_t start = NOW(), stop; #ifdef CONFIG_NETFRONT DEFINE_WAIT(netfront_w); #endif DEFINE_WAIT(event_w); #ifdef CONFIG_BLKFRONT DEFINE_WAIT(blkfront_w); #endif #ifdef CONFIG_XENBUS DEFINE_WAIT(xenbus_watch_w); #endif #ifdef CONFIG_KBDFRONT DEFINE_WAIT(kbdfront_w); #endif DEFINE_WAIT(console_w); assert(thread == main_thread); DEBUG("select(%d, ", nfds); dump_set(nfds, readfds, writefds, exceptfds, timeout); DEBUG(");\n"); if (timeout) stop = start + SECONDS(timeout->tv_sec) + timeout->tv_usec * 1000; else /* just make gcc happy */ stop = start; /* Tell people we're going to sleep before looking at what they are * saying, hence letting them wake us if events happen between here and * schedule() */ #ifdef CONFIG_NETFRONT add_waiter(netfront_w, netfront_queue); #endif add_waiter(event_w, event_queue); #ifdef CONFIG_BLKFRONT add_waiter(blkfront_w, blkfront_queue); #endif #ifdef CONFIG_XENBUS add_waiter(xenbus_watch_w, xenbus_watch_queue); #endif #ifdef CONFIG_KBDFRONT add_waiter(kbdfront_w, kbdfront_queue); #endif add_waiter(console_w, console_queue); if (readfds) myread = *readfds; else FD_ZERO(&myread); if (writefds) mywrite = *writefds; else FD_ZERO(&mywrite); if (exceptfds) myexcept = *exceptfds; else FD_ZERO(&myexcept); DEBUG("polling "); dump_set(nfds, &myread, &mywrite, &myexcept, timeout); DEBUG("\n"); n = select_poll(nfds, &myread, &mywrite, &myexcept); if (n) { dump_set(nfds, readfds, writefds, exceptfds, timeout); if (readfds) *readfds = myread; if (writefds) *writefds = mywrite; if (exceptfds) *exceptfds = myexcept; DEBUG(" -> "); dump_set(nfds, readfds, writefds, exceptfds, timeout); DEBUG("\n"); wake(thread); ret = n; goto out; } if (timeout && NOW() >= stop) { if (readfds) FD_ZERO(readfds); if (writefds) FD_ZERO(writefds); if (exceptfds) FD_ZERO(exceptfds); timeout->tv_sec = 0; timeout->tv_usec = 0; wake(thread); ret = 0; goto out; } if (timeout) thread->wakeup_time = stop; schedule(); if (readfds) myread = *readfds; else FD_ZERO(&myread); if (writefds) mywrite = *writefds; else FD_ZERO(&mywrite); if (exceptfds) myexcept = *exceptfds; else FD_ZERO(&myexcept); n = select_poll(nfds, &myread, &mywrite, &myexcept); if (n) { if (readfds) *readfds = myread; if (writefds) *writefds = mywrite; if (exceptfds) *exceptfds = myexcept; ret = n; goto out; } errno = EINTR; ret = -1; out: #ifdef CONFIG_NETFRONT remove_waiter(netfront_w, netfront_queue); #endif remove_waiter(event_w, event_queue); #ifdef CONFIG_BLKFRONT remove_waiter(blkfront_w, blkfront_queue); #endif #ifdef CONFIG_XENBUS remove_waiter(xenbus_watch_w, xenbus_watch_queue); #endif #ifdef CONFIG_KBDFRONT remove_waiter(kbdfront_w, kbdfront_queue); #endif remove_waiter(console_w, console_queue); return ret; }
/* ------------------------------------------------------------------------------------------------------ * sockex_nonblocking_connect() * * Description : tests socket blocking and nonblocking connect. * * Argument(s) : none. * */ void sockex_nonblocking_connect(void *arg) { int ret; struct sockaddr_in addr; fd_set readset; fd_set writeset; fd_set errset; struct timeval tv; LWIP_UNUSED_ARG(arg); memset(&addr, 0, sizeof(addr)); /* set up address to connect to */ addr.sin_len = sizeof(addr); addr.sin_family = AF_INET; addr.sin_port = PP_HTONS(SOCK_TARGET_PORT); addr.sin_addr.s_addr = inet_addr(SOCK_TARGET_HOST); socket_state = SOCKET_NEW; for(;;) { if(g_bNetStatus == NETS_LOCIP) /* IP is setted.*/ { switch(socket_state) { case SOCKET_NEW: { s = lwip_socket(AF_INET, SOCK_STREAM, 0); socket_state = SOCKET_CON; break; } case SOCKET_CON: { unsigned int ip; ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr)); LWIP_ASSERT("ret == 0", ret == 0); if(ret < 0) { lwip_close(s); socket_state = SOCKET_NEW; OSTimeDly(2); RS232printf("socket connect failed.\n"); break; } ip = lwIPLocalIPAddrGet(); NetDisplayIPAddress(ip); /* Socket updata IP address.*/ socket_state = SOCKET_IDIE; } case SOCKET_IDIE: { INT8U *msg; INT8U err; msg = (INT8U *)OSMboxPend(NET_RfMbox, 0, &err); /* Waiting socket writing data.*/ if(err != OS_ERR_NONE) break; ret = lwip_write(s, msg, 6); if(ret < 0) { lwip_close(s); socket_state = SOCKET_CON; } } break; case SOCKET_CHECK: // TODO: Check socket connecting. FD_ZERO(&readset); FD_SET(s, &readset); FD_ZERO(&writeset); FD_SET(s, &writeset); FD_ZERO(&errset); FD_SET(s, &errset); tv.tv_sec = 3; tv.tv_usec = 0; /* Set time out 3s, 函数立即返回*/ ret = lwip_select(s+1, &readset, &writeset, &errset, &tv); if(ret == 0) { RS232printf("socket check timeout.\n"); lwip_close(s); socket_state = SOCKET_CON; /* Reconnect socket.*/ } if(FD_ISSET(s, &writeset) == 0) /* If socket couldn't write.*/ { RS232printf("socket write test error.\n"); lwip_close(s); socket_state = SOCKET_CON; /* Reconnect socket.*/ } ret = lwip_write(s, "test", 6); if(ret < 0) { lwip_close(s); socket_state = SOCKET_CON; } OSTimeDly(2000); break; default: break; } } OSTimeDly(2); } }
/* ------------------------------------------------------------------------------------------------------ * sockex_selects() * * Description : socket selects test. * * Argument(s) : none. * */ void sockex_selects(void *arg) { int sock_fd, new_fd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; socklen_t sin_size; int yes; INT8U buf[BUF_SIZE]; int ret; int i; fd_set fdsr; /* Create file descriptor.*/ int maxsock; struct timeval tv; conn_amount = 0; LWIP_UNUSED_ARG(arg); sock_fd = lwip_socket(AF_INET, SOCK_STREAM, 0); yes = 1; ret = lwip_setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); if(ret == -1) { return; } memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_len = sizeof(server_addr); server_addr.sin_port = PP_HTONS(SOCK_HOSR_PORT); server_addr.sin_addr.s_addr = lwIPLocalIPAddrGet(); /* IP_ADDR_ANY is '0.0.0.0'.*/ lwip_bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); lwip_listen(sock_fd, BACKLOG + 1); /* MAX TCP client is BACKLOG.*/ sin_size = sizeof(client_addr); maxsock = sock_fd; while(1) { FD_ZERO(&fdsr); /* Initialize file descriptor set.*/ FD_SET(sock_fd, &fdsr); tv.tv_sec = 10; /* Timeout setting.*/ tv.tv_usec = 0; for (i = 0; i < BACKLOG; i++) /* Add active connection to fd set.*/ { if (fd_A[i] != 0) { FD_SET(fd_A[i], &fdsr); } } ret = lwip_select(maxsock + 1, &fdsr, NULL, NULL, &tv); if(ret < 0) { break; } else if(ret == 0) { continue; } for (i = 0; i < conn_amount; i++) /* Check every fd in the set.*/ { if (FD_ISSET(fd_A[i], &fdsr)) { int opt = 100; /* set recv timeout (100 ms) */ lwip_setsockopt(fd_A[i], SOL_SOCKET, SO_RCVTIMEO, &opt, sizeof(int)); ret = lwip_read(fd_A[i], buf, 8); if (ret <= 0) { // lwip_close(fd_A[i]); // FD_CLR(fd_A[i], &fdsr); // fd_A[i] = 0; } else /* receive data.*/ { if((buf[0] == 'C')&&(buf[1] == 'o')) { // address_t addr; // INT8U mac[8] = {0x00, 0x12, 0x4B, 0x00, 0x01, 0xC0, 0xB7, 0xE0}; // addr.mode = LONG_ADDR; // utilReverseBuf(mac, 8); // memcpy(addr.long_addr, mac, 8); // mac_tx_handle(&addr, &buf[7], 1, MAC_DATA); } if (ret < BUF_SIZE) memset(&buf[ret], '\0', 1); } } } if(FD_ISSET(sock_fd, &fdsr)) /* Check whether a new connection comes.*/ { new_fd = lwip_accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size); if(new_fd <= 0) { continue; } // lwip_send(new_fd, "con", 4, 0); if(conn_amount < BACKLOG) /* Add to fd queue.*/ { fd_A[conn_amount++] = new_fd; if(new_fd > maxsock) maxsock = new_fd; } else { // conn_amount = 0; lwip_close(fd_A[conn_amount-1]); fd_A[conn_amount-1] = new_fd; if(new_fd > maxsock) maxsock = new_fd; // lwip_send(new_fd, "bye", 4, 0); // lwip_close(new_fd); /* Close larger than 5 socket.*/ } } // for (i = 0; i < BACKLOG; i++) /* Close other connections.*/ // { // if (fd_A[i] != 0) { // lwip_close(fd_A[i]); // } // } } }
static int local_select(THandle aHandle, int aMode, uint32_t aTimeoutMs) { OsNetworkHandle* h = (OsNetworkHandle*) aHandle; LOGFUNCIN(); fd_set read_set; fd_set write_set; FD_ZERO(&read_set); FD_ZERO(&write_set); if ( aMode == LS_READ ) FD_SET(h->iSocket, &read_set); else FD_SET(h->iSocket, &write_set); #if INT_ENABLED FD_SET(h->iIntSocket, &read_set); #endif struct timeval t, *t_ptr = NULL; if ( aTimeoutMs != LS_FOREVER ) { t.tv_sec = aTimeoutMs / 1000; t.tv_usec = 1000 * (aTimeoutMs % 1000); t_ptr = &t; } int nfds = 1 + ( h->iSocket > h->iIntSocket ? h->iSocket : h->iIntSocket ); int fd = lwip_select(nfds, &read_set, &write_set, NULL, t_ptr); if ( fd == 0 ) return -2; if ( fd == -1 ) exit(-1); #if INT_ENABLED if ( FD_ISSET(h->iIntSocket, &read_set) ) { LOG("local_select - interrupted %d", h->iSocket); return -1; } #endif if ( (aMode == LS_READ) && FD_ISSET(h->iSocket, &read_set) ) { LOGFUNCOUT(); return h->iSocket; } if ( (aMode != LS_READ) && FD_ISSET(h->iSocket, &write_set) ) { LOGFUNCOUT(); return h->iSocket; } exit(-1); }
int select(std::set<Socket*>* readsockets, std::set<Socket*>* writesockets, std::set<Socket*>* errsockets, int timeout) { int maxfd = 0; int rc; lwip_fd_set readfds, writefds, errfds; std::set<Socket*>::iterator it; struct timeval tmo; LWIP_FD_ZERO(&readfds); LWIP_FD_ZERO(&writefds); LWIP_FD_ZERO(&errfds); if (readsockets) { for (it = readsockets->begin(); it != readsockets->end(); it++) { LWIP_FD_SET((*it)->socket_->fd, &readfds); if ((*it)->socket_->fd > maxfd) maxfd = (*it)->socket_->fd; } } if (writesockets) { for (it = writesockets->begin(); it != writesockets->end(); it++) { LWIP_FD_SET((*it)->socket_->fd, &writefds); if ((*it)->socket_->fd > maxfd) maxfd = (*it)->socket_->fd; } } if (errsockets) { for (it = errsockets->begin(); it != errsockets->end(); it++) { LWIP_FD_SET((*it)->socket_->fd, &errfds); if ((*it)->socket_->fd > maxfd) maxfd = (*it)->socket_->fd; } } tmo.tv_sec = timeout/1000; tmo.tv_usec = (timeout % 1000) * 1000; if ( (rc = lwip_select(maxfd+1, &readfds, &writefds, &errfds, &tmo) ) < 0 ) { log(LOG_WARN) << "select() failed"; return rc; } if (readsockets) { it = readsockets->begin(); while (it != readsockets->end()) { if (!LWIP_FD_ISSET((*it)->socket_->fd, &readfds)) readsockets->erase(it++); else it++; } } if (writesockets) { it = writesockets->begin(); while (it != writesockets->end()) { if (!LWIP_FD_ISSET((*it)->socket_->fd, &writefds)) { writesockets->erase(it++); } else it++; } } if (errsockets) { it = errsockets->begin(); while (it != errsockets->end()) { if (!LWIP_FD_ISSET((*it)->socket_->fd, &errfds)) errsockets->erase(it++); else it++; } } return rc; }
LOCAL int openssl_thread_LWIP_CONNECTION(TLS_IO_INSTANCE* p) { //LogInfo("openssl_thread_LWIP_CONNECTION begin: %d", system_get_free_heap_size()); //system_show_malloc(); int result = 0; int ret = 0; int sock; struct sockaddr_in sock_addr; fd_set readset; fd_set writeset; fd_set errset; SSL_CTX *ctx; SSL *ssl; TLS_IO_INSTANCE* tls_io_instance = p; LogInfo("OpenSSL thread start..."); { LogInfo("create SSL context"); /* Codes_SRS_TLSIO_SSL_ESP8266_99_085: [ If SSL_CTX_new failed, the tlsio_openssl_open shall return __LINE__. ] */ ctx = SSL_CTX_new(TLSv1_client_method()); if (ctx == NULL) { result = __LINE__; LogError("create new SSL CTX failed"); } else { tls_io_instance->ssl_context = ctx; LogInfo("set SSL context read buffer size"); SSL_CTX_set_default_read_buffer_len(ctx, OPENSSL_FRAGMENT_SIZE); // LogInfo("create socket ......"); // LogInfo("size before creating socket: %d", system_get_free_heap_size()); /* Codes_SRS_TLSIO_SSL_ESP8266_99_080: [ If socket failed, the tlsio_openssl_open shall return __LINE__. ] */ sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { result = __LINE__; LogError("create socket failed"); } else { int keepAlive = 1; //enable keepalive int keepIdle = 20; //20s int keepInterval = 2; //2s int keepCount = 3; //retry # of times tls_io_instance->sock = sock; LogInfo("sock: %d", sock); LogInfo("create socket OK"); LogInfo("set socket keep-alive "); ret = 0; ret = ret || setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive)); ret = ret || setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&keepIdle, sizeof(keepIdle)); ret = ret || setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval)); ret = ret || setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount)); if (ret != 0){ result = __LINE__; LogError("set socket keep-alive failed, ret = %d ", ret); } else { LogInfo("set socket keep-alive OK"); lwip_set_non_block(sock); LogInfo("bind socket ......"); memset(&sock_addr, 0, sizeof(sock_addr)); sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = 0; sock_addr.sin_port = 0; // random local port /* Codes_SRS_TLSIO_SSL_ESP8266_99_082: [ If bind failed, the tlsio_openssl_open shall return __LINE__. ] */ ret = bind(sock, (struct sockaddr*)&sock_addr, sizeof(sock_addr)); // LogInfo("bind return: %d", ret); if (ret != 0) { result = __LINE__; LogError("bind socket failed"); } else { LogInfo("bind socket OK"); memset(&sock_addr, 0, sizeof(sock_addr)); sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = tls_io_instance->target_ip.addr; sock_addr.sin_port = (in_port_t)htons(tls_io_instance->port); ret = connect(sock, (struct sockaddr*)&sock_addr, sizeof(sock_addr)); //LogInfo("connect return: %d %s", ret, ip_ntoa(&tls_io_instance->target_ip)); //LogInfo("EINPROGRESS: %d", EINPROGRESS); if (ret == -1) { ret = lwip_net_errno(sock); LogInfo("lwip_net_errno ret: %d", ret); /* Codes_SRS_TLSIO_SSL_ESP8266_99_083: [ If connect and getsockopt failed, the tlsio_openssl_open shall return __LINE__. ] */ if (ret != 115) { // EINPROGRESS result = __LINE__; ret = -1; LogError("socket connect failed, not EINPROGRESS %s", tls_io_instance->hostname); } } if(ret != -1) { FD_ZERO(&readset); FD_ZERO(&writeset); FD_ZERO(&errset); FD_SET(sock, &readset); FD_SET(sock, &writeset); FD_SET(sock, &errset); ret = lwip_select(sock + 1, NULL, &writeset, &errset, NULL); if (ret <= 0) { result = __LINE__; LogError("select failed: %d", lwip_net_errno(sock)); } else { if (!FD_ISSET(sock, &writeset) || FD_ISSET(sock, &errset)) { result = __LINE__; LogError("socket Error: %d", lwip_net_errno(sock)); }else { { LogInfo("Socket Connect OK"); /* Codes_SRS_TLSIO_SSL_ESP8266_99_087: [ If SSL_new failed, the tlsio_openssl_open shall return __LINE__. ] */ ssl = SSL_new(ctx); //LogInfo("after ssl new"); if (ssl == NULL) { result = __LINE__; LogError("create ssl failed"); } else { tls_io_instance->ssl = ssl; // LogInfo("SSL set fd"); /* Codes_SRS_TLSIO_SSL_ESP8266_99_088: [ If SSL_set_fd failed, the tlsio_openssl_open shall return __LINE__. ] */ ret = SSL_set_fd(ssl, sock); LogInfo("SSL_set_fd ret:%d", ret); if (ret != 1){ result = __LINE__; LogError("SSL_set_fd failed"); } else{ int retry_connect = 0; int connect_succeeded = false; LogInfo("SSL connect... "); FD_ZERO(&readset); FD_SET(sock, &readset); FD_ZERO(&writeset); FD_SET(sock, &writeset); FD_ZERO(&errset); FD_SET(sock, &errset); /* Codes_SRS_TLSIO_SSL_ESP8266_99_027: [ The tlsio_openssl_open shall set the tlsio to try to open the connection for MAX_RETRY times before assuming that connection failed. ]*/ while (retry_connect < MAX_RETRY) { int ssl_state; ret = lwip_select(sock + 1, &readset, &writeset, &errset, &timeout); if (ret == 0) { result = __LINE__; LogInfo("SSL connect timeout"); break; } if (FD_ISSET(sock, &errset)) { unsigned int len; result = __LINE__; LogInfo("error return : %d", lwip_net_errno(sock)); len = (unsigned int) sizeof( int ); if (0 != getsockopt (sock, SOL_SOCKET, SO_ERROR, &ret, &len)) LogInfo("SSL error ret : %d", ret); // socket is in error state break; } ret = SSL_connect(ssl); if (ret == 1) { // ssl connect success connect_succeeded = true; break; } FD_ZERO(&readset); FD_ZERO(&writeset); FD_ZERO(&errset); FD_SET(sock, &errset); ssl_state = SSL_get_error(ssl, ret); if (ssl_state == SSL_ERROR_WANT_READ) { FD_SET(sock, &readset); } else if(ssl_state == SSL_ERROR_WANT_WRITE) { FD_SET(sock, &writeset); } else { LogInfo("SSL state:%d", ssl_state); result = __LINE__; break; } retry_connect = retry_connect + 1; //LogInfo("SSL connect retry: %d", retry_connect); os_delay_us(RETRY_DELAY); } /* Codes_SRS_TLSIO_SSL_ESP8266_99_089: [ If SSL_connect failed, the tlsio_openssl_open shall return __LINE__. ] */ if (connect_succeeded == false) { /* Codes_SRS_TLSIO_SSL_ESP8266_99_042: [ If the tlsio_openssl_open retry SSL_connect to open more than MAX_RETRY times without success, it shall return __LINE__. ]*/ result = __LINE__; LogError("SSL_connect failed"); }else{ LogInfo("SSL connect ok"); result = 0; } } } } } } } } } } } } //LogInfo("openssl_thread_LWIP_CONNECTION end: %d", system_get_free_heap_size()); if(result!=0){ tls_io_instance->tlsio_state = TLSIO_STATE_ERROR; } return result; }
void tcp_setup_thread_entry(void *p) { int listenfd; struct sockaddr_in saddr; fd_set readset; listenfd = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if( listenfd == -1 ) { rt_kprintf("TCP setup can not create socket!\n"); return; } memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = htons(SETUP_TCP_PORT); if( lwip_bind(listenfd, (struct sockaddr *)&saddr, sizeof(saddr)) == -1 ) { lwip_close(listenfd); rt_kprintf("TCP setup thread socket bind failed!\n"); return; } /* Put socket into listening mode */ if (lwip_listen(listenfd,2) == -1) { lwip_close(listenfd); rt_kprintf("Listen failed.\n"); return; } /* Wait for data or a new connection */ while(1) { /* Determine what sockets need to be in readset */ FD_ZERO(&readset); FD_SET(listenfd, &readset); // wait forever. if( lwip_select(listenfd+1, &readset, 0, 0, 0) == 0 ) continue; if (FD_ISSET(listenfd, &readset)) { int ret,optval = 1; struct sockaddr_in addrin; u32_t sockaddrLen = sizeof(addrin); int socket = lwip_accept(listenfd,(struct sockaddr*)&addrin,&sockaddrLen); if( socket < 0 ) // accept failed. { rt_kprintf("TCP setup accept failed.\n"); continue; } rt_kprintf("TCP setup accept connection.\n"); // set socket keep alive. lwip_setsockopt(socket,SOL_SOCKET,SO_KEEPALIVE,&optval ,sizeof(optval)); // begin to recv & send. while(1) { int dataLen,bytesRet; ret = blocking_lwip_recv(socket,setup_data_buf,P2X_HEADER_LEN,500); if( ret == 0 ) continue; if( ret != P2X_HEADER_LEN ) break; dataLen = P2X_GET_LENGTH(setup_data_buf); if( dataLen > 0 ) { int gotDataLen = blocking_lwip_recv(socket,setup_data_buf+P2X_HEADER_LEN,dataLen,500); if( gotDataLen != dataLen ) break; } bytesRet = processCMD(setup_data_buf,P2X_HEADER_LEN+dataLen); if( lwip_send(socket,setup_data_buf,bytesRet,0) < 0 ) break; } rt_kprintf("TCP setup disconnected.\n"); lwip_close(socket); } }// while(1) listen. }
/* Codes_SRS_TLSIO_SSL_ESP8266_99_053: [ The tlsio_openssl_send shall send all bytes in a buffer to the ssl connection. ]*/ int tlsio_openssl_send(CONCRETE_IO_HANDLE tls_io, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context) { int result; if ((tls_io == NULL) || (buffer == NULL) || (size == 0)) { /* Codes_SRS_TLSIO_SSL_ESP8266_99_060: [ If the tls_io handle is NULL, the tlsio_openssl_send shall not do anything, and return _LINE_. ]*/ /* Codes_SRS_TLSIO_SSL_ESP8266_99_061: [ If the buffer is NULL, the tlsio_openssl_send shall not do anything, and return _LINE_. ]*/ /* Codes_SRS_TLSIO_SSL_ESP8266_99_062: [ If the size is 0, the tlsio_openssl_send shall not do anything, and return _LINE_. ]*/ result = __LINE__; LogError("Invalid parameter."); } else { TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; if (tls_io_instance->tlsio_state != TLSIO_STATE_OPEN) { /* Codes_SRS_TLSIO_SSL_ESP8266_99_059: [ If the tlsio state is not TLSIO_STATE_OPEN, the tlsio_openssl_send shall return _LINE_. ]*/ result = __LINE__; LogError("TLS is not ready to send data. Expected state is TLSIO_STATE_OPEN."); //LogInfo("TLS is not ready to send data. Expected state is TLSIO_STATE_OPEN."); } else { int total_write = 0; int ret = 0; int need_sent_bytes = (int)size; fd_set writeset; fd_set errset; /* Codes_SRS_TLSIO_SSL_ESP8266_99_056: [ The ssl will continue to send all data in the buffer until all bytes have been sent. ]*/ while(need_sent_bytes > 0) { FD_ZERO(&writeset); FD_SET(tls_io_instance->sock, &writeset); FD_ZERO(&errset); FD_SET(tls_io_instance->sock, &errset); ret = lwip_select(tls_io_instance->sock + 1, NULL, &writeset, &errset, &timeout); if (ret == 0) { result = __LINE__; LogError("select timeout and no data to be write"); break; } else if (ret < 0 || FD_ISSET(tls_io_instance->sock, &errset)) { result = __LINE__; LogError("get error %d", lwip_net_errno(tls_io_instance->sock)); break; } ret = SSL_write(tls_io_instance->ssl, ((uint8*)buffer)+total_write, (int)size); // LogInfo("SSL_write ret: %d", ret); //LogInfo("SSL_write res: %d, size: %d, retry: %d", res, size, retry); if(ret > 0){ total_write += ret; need_sent_bytes = need_sent_bytes - ret; } else { result = __LINE__; LogError("SSL_write failed."); break; } } if (need_sent_bytes != 0) { LogInfo("ssl write failed, return [-0x%x]", -ret); ret = SSL_shutdown(tls_io_instance->ssl); LogInfo("SSL_shutdown ret: %d", ret); /* Codes_SRS_TLSIO_SSL_ESP8266_99_054: [ The tlsio_openssl_send shall use the provided on_io_send_complete callback function address. ]*/ /* Codes_SRS_TLSIO_SSL_ESP8266_99_055: [ The tlsio_openssl_send shall use the provided on_io_send_complete_context handle. ]*/ /* Codes_SRS_TLSIO_SSL_ESP8266_99_057: [ If the ssl was not able to send all the bytes in the buffer, the tlsio_openssl_send shall call the on_send_complete with IO_SEND_ERROR, and return _LINE_. ]*/ result = __LINE__; if (on_send_complete != NULL) { /* Codes_SRS_TLSIO_SSL_ESP8266_99_003: [ The tlsio_ssl_esp8266 shall report the send operation status using the IO_SEND_RESULT enumerator defined in the `xio.h`. ]*/ on_send_complete(callback_context, IO_SEND_ERROR); } } else { result = 0; // LogInfo("SSL Write OK"); /* Codes_SRS_TLSIO_SSL_ESP8266_99_058: [ If the ssl finish to send all bytes in the buffer, then tlsio_openssl_send shall call the on_send_complete with IO_SEND_OK, and return 0 ]*/ /* Codes_SRS_TLSIO_SSL_ESP8266_99_054: [ The tlsio_openssl_send shall use the provided on_io_send_complete callback function address. ]*/ /* Codes_SRS_TLSIO_SSL_ESP8266_99_055: [ The tlsio_openssl_send shall use the provided on_io_send_complete_context handle. ]*/ if (on_send_complete != NULL) { /* Codes_SRS_TLSIO_SSL_ESP8266_99_003: [ The tlsio_ssl_esp8266 shall report the send operation status using the IO_SEND_RESULT enumerator defined in the `xio.h`. ]*/ on_send_complete(callback_context, IO_SEND_OK); } } // LogInfo("total write: %d", total_write); } } return result; }
/************************************************************** * void chargen_thread(void *arg) * * chargen task. This server will wait for connections on well * known TCP port number: 19. For every connection, the server will * write as much data as possible to the tcp port. **************************************************************/ static void chargen_thread(void *arg) { int listenfd; struct sockaddr_in chargen_saddr; fd_set readset; fd_set writeset; int i, maxfdp1; struct charcb *p_charcb; /* First acquire our socket for listening for connections */ listenfd = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); LWIP_ASSERT("chargen_thread(): Socket create failed.", listenfd >= 0); memset(&chargen_saddr, 0, sizeof(chargen_saddr)); chargen_saddr.sin_family = AF_INET; chargen_saddr.sin_addr.s_addr = htonl(INADDR_ANY); chargen_saddr.sin_port = htons(19); // Chargen server port if (lwip_bind(listenfd, (struct sockaddr *) &chargen_saddr, sizeof(chargen_saddr)) == -1) LWIP_ASSERT("chargen_thread(): Socket bind failed.", 0); /* Put socket into listening mode */ if (lwip_listen(listenfd, MAX_SERV) == -1) LWIP_ASSERT("chargen_thread(): Listen failed.", 0); /* Wait forever for network input: This could be connections or data */ for (;;) { maxfdp1 = listenfd+1; /* Determine what sockets need to be in readset */ FD_ZERO(&readset); FD_ZERO(&writeset); FD_SET(listenfd, &readset); for (p_charcb = charcb_list; p_charcb; p_charcb = p_charcb->next) { if (maxfdp1 < p_charcb->socket + 1) maxfdp1 = p_charcb->socket + 1; FD_SET(p_charcb->socket, &readset); FD_SET(p_charcb->socket, &writeset); } /* Wait for data or a new connection */ i = lwip_select(maxfdp1, &readset, &writeset, 0, 0); if (i == 0) continue; /* At least one descriptor is ready */ if (FD_ISSET(listenfd, &readset)) { /* We have a new connection request!!! */ /* Lets create a new control block */ p_charcb = (struct charcb *)rt_calloc(1, sizeof(struct charcb)); if (p_charcb) { p_charcb->socket = lwip_accept(listenfd, (struct sockaddr *) &p_charcb->cliaddr, &p_charcb->clilen); if (p_charcb->socket < 0) rt_free(p_charcb); else { /* Keep this tecb in our list */ p_charcb->next = charcb_list; charcb_list = p_charcb; p_charcb->nextchar = 0x21; } } else { /* No memory to accept connection. Just accept and then close */ int sock; struct sockaddr cliaddr; socklen_t clilen; sock = lwip_accept(listenfd, &cliaddr, &clilen); if (sock >= 0) lwip_close(sock); } } /* Go through list of connected clients and process data */ for (p_charcb = charcb_list; p_charcb; p_charcb = p_charcb->next) { if (FD_ISSET(p_charcb->socket, &readset)) { /* This socket is ready for reading. This could be because someone typed * some characters or it could be because the socket is now closed. Try reading * some data to see. */ if (do_read(p_charcb) < 0) break; } if (FD_ISSET(p_charcb->socket, &writeset)) { char line[80]; char setchar = p_charcb->nextchar; for( i = 0; i < 59; i++) { line[i] = setchar; if (++setchar == 0x7f) setchar = 0x21; } line[i] = 0; strcat(line, "\n\r"); if (lwip_write(p_charcb->socket, line, strlen(line)) < 0) { close_chargen(p_charcb); break; } if (++p_charcb->nextchar == 0x7f) p_charcb->nextchar = 0x21; } } } }
int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout) { return lwip_select(maxfdp1, readset, writeset, exceptset, timeout); }