static err_t http_accept(void *arg, tcp_pcb *pcb, err_t err) { LWIP_UNUSED_ARG(arg); LWIP_UNUSED_ARG(err); tcp_setprio(pcb, TCP_PRIO_MIN); //RepRapNetworkMessage("http_accept\n"); HttpState *hs = (HttpState*)mem_malloc(sizeof(HttpState)); if (hs == NULL) { RepRapNetworkMessage("Out of memory!\n"); return ERR_MEM; } /* Initialize the structure. */ hs->pcb = pcb; hs->file = NULL; hs->left = 0; hs->retries = 0; hs->sendingRs = NULL; tcp_accepted(listening_pcb); // tell TCP to accept further connections tcp_arg(pcb, hs); // tell TCP that this is the structure we wish to be passed for our callbacks tcp_recv(pcb, http_recv); // tell TCP that we wish to be informed of incoming data by a call to the http_recv() function tcp_err(pcb, conn_err); tcp_poll(pcb, http_poll, 4); return ERR_OK; }
static socket_error_t accept_v2(struct socket *listener, struct socket *sock, socket_api_handler_t handler) { if (sock == NULL || sock->impl == NULL) return SOCKET_ERROR_NULL_PTR; switch (sock->family) { case SOCKET_DGRAM: return SOCKET_ERROR_UNIMPLEMENTED; case SOCKET_STREAM: { struct tcp_pcb *tcp = (struct tcp_pcb *)sock->impl; struct tcp_pcb *lpcb = (struct tcp_pcb *)listener->impl; /* NOTE: tcp_accepted() is replaced with an empty statement in release, * so we need a cast-to-void to remove the unused variable warning */ (void) lpcb; tcp_accepted(lpcb); tcp_arg(tcp, (void*) sock); tcp_err(tcp, tcp_error_handler); tcp_sent(tcp, irqTCPSent); tcp_recv(tcp, irqTCPRecv); break; } default: return SOCKET_ERROR_BAD_FAMILY; } sock->handler = (void*)handler; sock->rxBufChain = NULL; return SOCKET_ERROR_NONE; }
static int tcp_do_accept(struct socket * listen_sock, message * m, struct tcp_pcb * newpcb) { struct socket * newsock; unsigned sock_num; int ret; debug_tcp_print("socket num %ld", get_sock_num(listen_sock)); if ((ret = copy_from_user(m->m_source, &sock_num, sizeof(sock_num), (cp_grant_id_t) m->IO_GRANT, 0)) != OK) return EFAULT; if (!is_valid_sock_num(sock_num)) return EBADF; newsock = get_sock(sock_num); assert(newsock->pcb); /* because of previous open() */ /* we really want to forget about this socket */ tcp_err((struct tcp_pcb *)newsock->pcb, NULL); tcp_abandon((struct tcp_pcb *)newsock->pcb, 0); tcp_arg(newpcb, newsock); tcp_err(newpcb, tcp_error_callback); tcp_sent(newpcb, tcp_sent_callback); tcp_recv(newpcb, tcp_recv_callback); tcp_nagle_disable(newpcb); tcp_accepted(((struct tcp_pcb *)(listen_sock->pcb))); newsock->pcb = newpcb; debug_tcp_print("Accepted new connection using socket %d\n", sock_num); return OK; }
/****************************************************************************** * FunctionName : tcp_server_listen * Description : TCP server listened a connection successfully * Parameters : arg -- Additional argument to pass to the callback function * Returns : none *******************************************************************************/ LOCAL err_t tcp_server_listen(void *arg, struct tcp_pcb *newpcb, err_t err) { char* hello = "hello"; // struct espconn *pesp_conn = arg; printf("tcp_server_listen !!! \r\n"); tcp_setprio(newpcb, TCP_PRIO_MIN); tcp_recv(newpcb, tcp_server_recv_cb); tcp_sent(newpcb, tcp_server_sent_cb); tcp_accepted(opcb); // printf("%d\n",espconn_set_opt(arg, ESPCONN_NODELAY)); // espconn_regist_recvcb(pesp_conn, tcp_server_recv_cb); // espconn_regist_reconcb(pesp_conn, tcp_server_recon_cb); // espconn_regist_disconcb(pesp_conn, tcp_server_discon_cb); // printf("%d\n", espconn_regist_sentcb(pesp_conn, tcp_server_sent_cb)); // tcp_server_multi_send(arg); return ERR_OK; }
/* This function animates an accept request from `ol->accepted` queue */ static void bake_one_accepted(outlet_t *ol, proc_t *cont_proc) { #if LING_WITH_LWIP tcp_accepted(ol->tcp); // not needed, really #endif assert(ol->accepted != 0); acc_pend_t *pend = pop_from_ring(&ol->accepted); outlet_t *new_ol = ol_tcp_factory(cont_proc, 0); // default bit options? if (new_ol == 0) scheduler_signal_exit_N(cont_proc, ol->oid, A_NO_MEMORY); else { ol_tcp_animate(new_ol, pend); // BEAM copies some options in the driver code and some - in gen_tcp. // This creates an interplay that may result in the first packet getting // lost of interpreted as a wrong packet type. The following assignments // are determined by trial and error to let the right first packet // through. new_ol->active = INET_PASSIVE; new_ol->packet = ol->packet; new_ol->binary = ol->binary; inet_async2(ol->oid, cont_proc->pid, ASYNC_REF, A_OK, new_ol->oid); } reuse_pending(&ol->free_pends, pend); }
static err_t net_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err) { lnet_userdata *ud = (lnet_userdata*)arg; if (!ud || ud->type != TYPE_TCP_SERVER || !ud->pcb) return ERR_ABRT; if (ud->self_ref == LUA_NOREF || ud->server.cb_accept_ref == LUA_NOREF) return ERR_ABRT; lua_State *L = lua_getstate(); lua_rawgeti(L, LUA_REGISTRYINDEX, ud->server.cb_accept_ref); lnet_userdata *nud = net_create(L, TYPE_TCP_CLIENT); lua_pushvalue(L, 2); nud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); nud->tcp_pcb = newpcb; tcp_arg(nud->tcp_pcb, nud); tcp_err(nud->tcp_pcb, net_err_cb); tcp_recv(nud->tcp_pcb, net_tcp_recv_cb); tcp_sent(nud->tcp_pcb, net_sent_cb); nud->tcp_pcb->so_options |= SOF_KEEPALIVE; nud->tcp_pcb->keep_idle = ud->server.timeout * 1000; nud->tcp_pcb->keep_cnt = 1; tcp_accepted(ud->tcp_pcb); lua_call(L, 1, 0); return net_connected_cb(nud, nud->tcp_pcb, ERR_OK); }
int8_t AsyncServer::_accept(tcp_pcb* pcb, int8_t err){ tcp_accepted(_pcb); if(_connect_cb){ if (_noDelay) tcp_nagle_disable(pcb); else tcp_nagle_enable(pcb); AsyncClient *c = new AsyncClient(pcb); if(c){ _in_lwip_thread = true; c->_in_lwip_thread = true; _connect_cb(_connect_cb_arg, c); c->_in_lwip_thread = false; _in_lwip_thread = false; return ERR_OK; } } if(tcp_close(pcb) != ERR_OK){ tcp_abort(pcb); } log_e("FAIL"); return ERR_OK; }
int8_t WiFiServer::_accept(tcp_pcb* apcb, int8_t err) { DEBUGV("WS:ac\r\n"); ClientContext* client = new ClientContext(apcb, &WiFiServer::_s_discard, this); _unclaimed = slist_append_tail(_unclaimed, client); tcp_accepted(_pcb); // printf("WiFiServer::_accept\r\n"); return ERR_OK; }
/** * Delete rcvmbox and acceptmbox of a netconn and free the left-over data in * these mboxes * * @param conn the netconn to free * @bytes_drained bytes drained from recvmbox * @accepts_drained pending connections drained from acceptmbox */ static void netconn_drain(struct netconn *conn) { void *mem; #if LWIP_TCP struct pbuf *p; #endif /* LWIP_TCP */ /* This runs in tcpip_thread, so we don't need to lock against rx packets */ /* Delete and drain the recvmbox. */ if (sys_mbox_valid(&conn->recvmbox)) { while (sys_mbox_tryfetch(&conn->recvmbox, &mem) != SYS_MBOX_EMPTY) { #if LWIP_TCP if (conn->type == NETCONN_TCP) { if(mem != NULL) { p = (struct pbuf*)mem; /* pcb might be set to NULL already by err_tcp() */ if (conn->pcb.tcp != NULL) { tcp_recved(conn->pcb.tcp, p->tot_len); } pbuf_free(p); } } else #endif /* LWIP_TCP */ { netbuf_delete((struct netbuf *)mem); } } sys_mbox_free(&conn->recvmbox); sys_mbox_set_invalid(&conn->recvmbox); } /* Delete and drain the acceptmbox. */ #if LWIP_TCP if (sys_mbox_valid(&conn->acceptmbox)) { while (sys_mbox_tryfetch(&conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) { struct netconn *newconn = (struct netconn *)mem; /* Only tcp pcbs have an acceptmbox, so no need to check conn->type */ /* pcb might be set to NULL already by err_tcp() */ if (conn->pcb.tcp != NULL) { tcp_accepted(conn->pcb.tcp); } /* drain recvmbox */ netconn_drain(newconn); if (newconn->pcb.tcp != NULL) { tcp_abort(newconn->pcb.tcp); newconn->pcb.tcp = NULL; } netconn_free(newconn); } sys_mbox_free(&conn->acceptmbox); sys_mbox_set_invalid(&conn->acceptmbox); } #endif /* LWIP_TCP */ }
CAMLprim value caml_tcp_accepted(value v_tw) { CAMLparam1(v_tw); tcp_wrap *tw = tcp_wrap_of_value(v_tw); LWIP_STUB_DPRINTF("caml_tcp_accepted"); tw->desc->state = TCP_ACCEPTED; tcp_accepted(tw->pcb); CAMLreturn(Val_unit); }
NetTcpSocketErr LwipNetTcpSocket::accept(Host* pClient, NetTcpSocket** ppNewNetTcpSocket) { if( !m_pPcb ) //Pcb doesn't exist (anymore) return NETTCPSOCKET_MEM; //Dequeue a connection //if( m_lpInPcb.empty() ) if( m_lpInNetTcpSocket.empty() ) return NETTCPSOCKET_EMPTY; tcp_accepted( ((tcp_pcb*) m_pPcb) ); //Should fire proper events //WARN: m_pPcb is the GOOD param here (and not pInPcb) /* tcp_pcb* pInPcb = m_lpInPcb.front(); m_lpInPcb.pop();*/ if( (m_lpInNetTcpSocket.front()) == NULL ) { m_lpInNetTcpSocket.pop(); return NETTCPSOCKET_RST; } if( (m_lpInNetTcpSocket.front())->m_closed ) { Net::releaseTcpSocket(m_lpInNetTcpSocket.front()); m_lpInNetTcpSocket.pop(); return NETTCPSOCKET_RST; } ip_addr_t* ip = (ip_addr_t*) &( (m_lpInNetTcpSocket.front()->m_pPcb)->remote_ip); *ppNewNetTcpSocket = m_lpInNetTcpSocket.front(); *pClient = Host( IpAddr( ip ), m_lpInNetTcpSocket.front()->m_pPcb->remote_port ); m_lpInNetTcpSocket.pop(); // *pClient = Host( IpAddr(pInPcb->remote_ip), pInPcb->remote_port ); //Return a new socket // *ppNewNetTcpSocket = (NetTcpSocket*) new LwipNetTcpSocket(pInPcb); //tcp_accepted( ((tcp_pcb*) m_pPcb) ); //Should fire proper events //WARN: m_pPcb is the GOOD param here (and not pInPcb) /* if(*ppNewNetTcpSocket == NULL) { DBG("Not enough mem, socket dropped in LwipNetTcpSocket::accept.\n"); tcp_abort(pInPcb); }*/ return NETTCPSOCKET_OK; }
void LibTCPAccept(PTCP_PCB pcb, struct tcp_pcb *listen_pcb, void *arg) { ASSERT(arg); tcp_arg(pcb, NULL); tcp_recv(pcb, InternalRecvEventHandler); tcp_sent(pcb, InternalSendEventHandler); tcp_err(pcb, InternalErrorEventHandler); tcp_arg(pcb, arg); tcp_accepted(listen_pcb); }
static err_t conn_accept(void *arg, tcp_pcb *pcb, err_t err) { LWIP_UNUSED_ARG(arg); LWIP_UNUSED_ARG(err); tcp_setprio(pcb, TCP_PRIO_MIN); //RepRapNetworkMessage("conn_accept\n"); /* Allocate a new ConnectionState for this connection */ ConnectionState *cs = reprap.GetNetwork()->ConnectionAccepted(pcb); if (cs == NULL) { tcp_abort(pcb); return ERR_ABRT; } /* Keep the listening PCBs running */ switch (pcb->local_port) // tell LWIP to accept further connections on the listening PCB { case ftpPort: // FTP tcp_accepted(ftp_main_pcb); break; case telnetPort: // Telnet tcp_accepted(telnet_pcb); break; default: // HTTP and FTP data tcp_accepted((pcb->local_port == httpPort) ? http_pcb : ftp_pasv_pcb); break; } tcp_arg(pcb, cs); // tell LWIP that this is the structure we wish to be passed for our callbacks tcp_recv(pcb, conn_recv); // tell LWIP that we wish to be informed of incoming data by a call to the conn_recv() function tcp_err(pcb, conn_err); tcp_poll(pcb, conn_poll, 4); return ERR_OK; }
static err_t net_server_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { struct net_server_instance *instance; struct net_server_connstate *cs; instance = (struct net_server_instance *)arg; cs = cs_new(instance); if(!cs) return ERR_MEM; tcp_accepted(instance->listen_pcb); tcp_arg(newpcb, cs); tcp_recv(newpcb, net_server_recv); tcp_err(newpcb, net_server_err); return ERR_OK; }
/** * A new incoming connection has been accepted. */ err_t http_simple_accept(void *arg, struct tcp_pcb *pcb, err_t err) { LWIP_UNUSED_ARG(err); /* Decrease the listen backlog counter */ tcp_accepted(((struct tcp_pcb_listen*)arg)); tcp_setprio(pcb, ECHO_TCP_PRIO); /* Set up the various callback functions */ tcp_recv(pcb, http_simple_recv); tcp_err(pcb, NULL); tcp_poll(pcb, NULL, ECHO_POLL_INTERVAL); tcp_sent(pcb, NULL); return ERR_OK; }
static err_t newConnection(void *arg, struct tcp_pcb *newpcb, err_t err) { err_t error; printf("new connection: %p\n", newpcb); if (connectedPCB != NULL){ printf("too many connections\n" ); error = tcp_close(newpcb); if (error != ERR_OK){ printf("Unable to close the connection: %d\n", error); } } connectedPCB = newpcb; tcp_sent(newpcb, sent); tcp_recv(newpcb,recv ); tcp_accepted(newpcb); return ERR_OK; }
/* * \brief Callback from LWIP when a client connects to our TCP listen sock */ static err_t accept_cb(void *arg, struct tcp_pcb *tpcb, err_t err) { printf("bfscope: connected\n"); assert(err == ERR_OK); tcp_recv(tpcb, recv_cb); tcp_sent(tpcb, send_cb); tcp_err(tpcb, error_cb); tcp_arg(tpcb, (void*)tpcb); tcp_accepted(tpcb); bfscope_client = tpcb; return ERR_OK; }
/** * A new incoming connection has been accepted. */ static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err) { struct http_state *hs; struct tcp_pcb_listen *lpcb = (struct tcp_pcb_listen*)arg; LWIP_UNUSED_ARG(err); LWIP_DEBUGF(HTTPD_DEBUG, ("http_accept(%p)\n", arg)); /* Decrease the listen backlog counter */ tcp_accepted(lpcb); tcp_setprio(pcb, HTTPD_TCP_PRIO); /* Allocate memory for the structure that holds the state of the connection. */ hs = http_state_alloc(); if (hs == NULL) { LWIP_DEBUGF(HTTPD_DEBUG, ("http_accept: Out of memory, RST\n")); return ERR_MEM; } /* Initialize the structure. */ hs->file = NULL; #if HTTPD_SUPPORT_DYNAMIC_PAGES hs->file_orig = NULL; #endif /* HTTPD_SUPPORT_DYNAMIC_PAGES */ hs->left = 0; hs->retries = 0; #if HTTPD_TRACK_SENT_BYTES hs->sent_total = 0; #endif /* HTTPD_TRACK_SENT_BYTES */ /* Tell TCP that this is the structure we wish to be passed for our callbacks. */ tcp_arg(pcb, hs); /* Set up the various callback functions */ tcp_recv(pcb, http_recv); tcp_err(pcb, http_err); tcp_poll(pcb, http_poll, HTTPD_POLL_INTERVAL); tcp_sent(pcb, http_sent); return ERR_OK; }
/** * Accept the client and resume accepting thread. */ static void tcp_accept_resume(struct socket_t *socket_p) { struct tcp_accept_args_t *args_p; struct tcp_pcb *pcb_p; fs_counter_increment(&module.tcp_accepts, 1); pcb_p = socket_p->input.u.accept.pcb_p; socket_p->input.u.accept.left = 0; socket_p->input.u.accept.pcb_p = NULL; args_p = socket_p->input.cb.args_p; tcp_arg(pcb_p, args_p->accepted_p); tcp_recv(pcb_p, on_tcp_recv); tcp_sent(pcb_p, on_tcp_sent); tcp_err(pcb_p, on_tcp_err); init(args_p->accepted_p, SOCKET_TYPE_STREAM, pcb_p); tcp_accepted(((struct tcp_pcb *)socket_p->pcb_p)); resume_thrd(socket_p->input.cb.thrd_p, 0); }
/** * Indicate data has been received from a TCP pcb contained in a netconn * Called from netconn_recv * * @param msg the api_msg_msg pointing to the connection */ void do_recv(struct api_msg_msg *msg) { #if LWIP_TCP if (!ERR_IS_FATAL(msg->conn->err)) { if (msg->conn->pcb.tcp != NULL) { if (msg->conn->type == NETCONN_TCP) { #if TCP_LISTEN_BACKLOG if (msg->conn->pcb.tcp->state == LISTEN) { tcp_accepted(msg->conn->pcb.tcp); } else #endif /* TCP_LISTEN_BACKLOG */ { tcp_recved(msg->conn->pcb.tcp, msg->msg.r.len); } } } } #endif /* LWIP_TCP */ TCPIP_APIMSG_ACK(msg); }
/** * Indicate data has been received from a TCP pcb contained in a netconn * Called from netconn_recv * * @param msg the api_msg_msg pointing to the connection */ void do_recv(struct api_msg_msg *msg) { msg->err = ERR_OK; if (msg->conn->pcb.tcp != NULL) { if (msg->conn->type == NETCONN_TCP) { #if TCP_LISTEN_BACKLOG if (msg->conn->pcb.tcp->state == LISTEN) { tcp_accepted(msg->conn->pcb.tcp); } else #endif /* TCP_LISTEN_BACKLOG */ { u32_t remaining = msg->msg.r.len; do { u16_t recved = (remaining > 0xffff) ? 0xffff : (u16_t)remaining; tcp_recved(msg->conn->pcb.tcp, recved); remaining -= recved; } while(remaining != 0); } } } TCPIP_APIMSG_ACK(msg); }
static socket_error_t lwipv4_socket_accept(struct socket *sock, socket_api_handler_t handler) { if (sock == NULL || sock->impl == NULL) return SOCKET_ERROR_NULL_PTR; switch (sock->family) { case SOCKET_DGRAM: return SOCKET_ERROR_UNIMPLEMENTED; case SOCKET_STREAM: { struct tcp_pcb *tcp = (struct tcp_pcb *)sock->impl; tcp_accepted(tcp); tcp_arg(tcp, (void*) sock); tcp_err(tcp, tcp_error_handler); tcp_sent(tcp,irqTCPSent); tcp_recv(tcp, irqTCPRecv); break; } default: return SOCKET_ERROR_BAD_FAMILY; } sock->handler = (void*)handler; sock->rxBufChain = NULL; return SOCKET_ERROR_NONE; }
net_connection_t net_accept(spdid_t spdid, net_connection_t nc) { struct intern_connection *ic, *new_ic; net_connection_t ret = -1; //NET_LOCK_TAKE(); ic = net_verify_tcp_connection(nc, &ret); if (NULL == ic) { ret = -EINVAL; goto done; } /* No accepts are pending on this connection?: block */ if (NULL == ic->accepted_ic) { ret = -EAGAIN; goto done; /* assert(ic->tid == cos_get_thd_id()); */ /* ic->thd_status = ACCEPTING; */ /* NET_LOCK_RELEASE(); */ /* prints("net_accept: blocking!"); */ /* if (sched_block(cos_spd_id(), 0) < 0) BUG(); */ /* NET_LOCK_TAKE(); */ /* assert(ACTIVE == ic->thd_status); */ } assert(NULL != ic->accepted_ic && NULL != ic->accepted_last); new_ic = ic->accepted_ic; ic->accepted_ic = new_ic->next; if (NULL == ic->accepted_ic) ic->accepted_last = NULL; new_ic->next = NULL; assert(ic->conn.tp); tcp_accepted(ic->conn.tp); ret = net_conn_get_opaque(new_ic); done: //NET_LOCK_RELEASE(); return ret; }
static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err) { struct http_state *http; tcp_setprio(pcb, TCP_PRIO_MIN); /* Allocate memory for the structure that holds the state of the connection. */ http = mem_malloc(sizeof (struct http_state)); if (http == NULL) { printf("http_accept: Out of memory\n"); return ERR_MEM; } /* Initialize the structure. */ http->retries = 0; httpd_init(http); /* Tell TCP that this is the structure we wish to be passed for our callbacks. */ tcp_arg(pcb, http); /* Tell TCP that we wish to be informed of incoming data by a call to the http_recv() function. */ tcp_recv(pcb, http_recv); tcp_err(pcb, conn_err); tcp_sent(pcb, http_sent); tcp_poll(pcb, http_poll, 4); tcp_accepted(listen_pcb); //lwip 1.3.0 // printf("accept!\n"); return ERR_OK; }
void tcp_accepted1(struct tcp_pcb *pcb) { tcp_accepted(pcb); // tcp_accepted() is a macro }
/** * Accept callback function for TCP netconns. */ static err_t net_tcp_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err) { err_t err_ret = ERR_OK; struct tls_netconn *conn = (struct tls_netconn *)arg; struct tls_netconn *newconn; struct tcp_pcb *pcb; u32 cpu_sr; //TLS_DBGPRT_INFO("=====>\n"); #if 0 if (conn->tcp_connect_cnt >= TLS_MAX_SOCKET_NUM) { return ERR_ABRT; } #endif newconn = net_alloc_socket(conn); if (!newconn) { /* connection aborted */ /* not happen */ tcp_abort(newpcb); //printf("\r\nnet_tcp_accept_cb err\r\n"); return ERR_ABRT; } if (conn){ tcp_accepted(conn->pcb.tcp); } //conn->tcp_connect_cnt++; newconn->used = true; newconn->pcb.tcp = newpcb; newconn->client = true; newconn->idle_time = conn->idle_time; newconn->proto = TLS_NETCONN_TCP; newconn->state = NETCONN_STATE_CONNECTED; pcb = newconn->pcb.tcp; ip_set_option(newconn->pcb.tcp, SOF_KEEPALIVE); newconn->skd = conn->skd; tcp_arg(pcb, newconn); tcp_recv(pcb, net_tcp_recv_cb); //tcp_sent(pcb, net_tcp_sent_cb); tcp_poll(pcb, net_tcp_poll_cb, 2); tcp_err(pcb, net_tcp_err_cb); cpu_sr = tls_os_set_critical(); dl_list_add_tail(&conn->list, &newconn->list); tls_os_release_critical(cpu_sr); newconn->port = host_to_le16(pcb->remote_port); newconn->localport = conn->localport; ip_addr_set(&newconn->addr, &pcb->remote_ip); net_send_event_to_hostif(newconn, NET_EVENT_TCP_JOINED); if(conn->skd->acceptf != NULL) { err_ret =conn->skd->acceptf(newconn->skt_num, err); if(err_ret == ERR_ABRT) { tcp_abort(pcb); } } //conn->state = NETCONN_STATE_CONNECTED; return err_ret; }
STATIC mp_obj_t lwip_socket_accept(mp_obj_t self_in) { lwip_socket_obj_t *socket = self_in; if (socket->pcb == NULL) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EBADF))); } if (socket->type != MOD_NETWORK_SOCK_STREAM) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EOPNOTSUPP))); } // I need to do this because "tcp_accepted", later, is a macro. struct tcp_pcb *listener = (struct tcp_pcb*)socket->pcb; if (listener->state != LISTEN) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EINVAL))); } // accept incoming connection if (socket->incoming == NULL) { if (socket->timeout != -1) { for (mp_uint_t retries = socket->timeout / 100; retries--;) { mp_hal_delay_ms(100); if (socket->incoming != NULL) break; } if (socket->incoming == NULL) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ETIMEDOUT))); } } else { while (socket->incoming == NULL) { mp_hal_delay_ms(100); } } } // create new socket object lwip_socket_obj_t *socket2 = m_new_obj_with_finaliser(lwip_socket_obj_t); socket2->base.type = (mp_obj_t)&lwip_socket_type; // We get a new pcb handle... socket2->pcb = socket->incoming; socket->incoming = NULL; // ...and set up the new socket for it. socket2->domain = MOD_NETWORK_AF_INET; socket2->type = MOD_NETWORK_SOCK_STREAM; socket2->incoming = NULL; socket2->timeout = socket->timeout; socket2->connected = 2; socket2->leftover_count = 0; tcp_arg((struct tcp_pcb*)socket2->pcb, (void*)socket2); tcp_err((struct tcp_pcb*)socket2->pcb, _lwip_tcp_error); tcp_recv((struct tcp_pcb*)socket2->pcb, _lwip_tcp_recv); tcp_accepted(listener); // make the return value uint8_t ip[NETUTILS_IPV4ADDR_BUFSIZE]; memcpy(ip, &(((struct tcp_pcb*)socket2->pcb)->remote_ip), 4); mp_uint_t port = (mp_uint_t)((struct tcp_pcb*)socket2->pcb)->remote_port; mp_obj_tuple_t *client = mp_obj_new_tuple(2, NULL); client->items[0] = socket2; client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); return client; }
STATIC mp_obj_t lwip_socket_accept(mp_obj_t self_in) { lwip_socket_obj_t *socket = self_in; if (socket->pcb.tcp == NULL) { mp_raise_OSError(MP_EBADF); } if (socket->type != MOD_NETWORK_SOCK_STREAM) { mp_raise_OSError(MP_EOPNOTSUPP); } // I need to do this because "tcp_accepted", later, is a macro. struct tcp_pcb *listener = socket->pcb.tcp; if (listener->state != LISTEN) { mp_raise_OSError(MP_EINVAL); } // accept incoming connection if (socket->incoming.connection == NULL) { if (socket->timeout == 0) { mp_raise_OSError(MP_EAGAIN); } else if (socket->timeout != -1) { for (mp_uint_t retries = socket->timeout / 100; retries--;) { mp_hal_delay_ms(100); if (socket->incoming.connection != NULL) break; } if (socket->incoming.connection == NULL) { mp_raise_OSError(MP_ETIMEDOUT); } } else { while (socket->incoming.connection == NULL) { poll_sockets(); } } } // create new socket object lwip_socket_obj_t *socket2 = m_new_obj_with_finaliser(lwip_socket_obj_t); socket2->base.type = (mp_obj_t)&lwip_socket_type; // We get a new pcb handle... socket2->pcb.tcp = socket->incoming.connection; socket->incoming.connection = NULL; // ...and set up the new socket for it. socket2->domain = MOD_NETWORK_AF_INET; socket2->type = MOD_NETWORK_SOCK_STREAM; socket2->incoming.pbuf = NULL; socket2->timeout = socket->timeout; socket2->state = STATE_CONNECTED; socket2->recv_offset = 0; socket2->callback = MP_OBJ_NULL; tcp_arg(socket2->pcb.tcp, (void*)socket2); tcp_err(socket2->pcb.tcp, _lwip_tcp_error); tcp_recv(socket2->pcb.tcp, _lwip_tcp_recv); tcp_accepted(listener); // make the return value uint8_t ip[NETUTILS_IPV4ADDR_BUFSIZE]; memcpy(ip, &(socket2->pcb.tcp->remote_ip), sizeof(ip)); mp_uint_t port = (mp_uint_t)socket2->pcb.tcp->remote_port; mp_obj_tuple_t *client = mp_obj_new_tuple(2, NULL); client->items[0] = socket2; client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); return client; }