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; }
//***************************************************************************** // // Finalizes the TCP connection in client mode. // // \param pvArg is the state data for this connection. // \param psPcb is the pointer to the TCP control structure. // \param iErr is not used in this implementation. // // This function is called when the lwIP TCP/IP stack has completed a TCP // connection. // // \return This function will return an lwIP defined error code. // //***************************************************************************** static err_t TCPConnected(void *pvArg, struct tcp_pcb *psPcb, err_t iErr) { // // Check if there was a TCP error. // if(iErr != ERR_OK) { // // Clear out all of the TCP callbacks. // tcp_sent(psPcb, NULL); tcp_recv(psPcb, NULL); tcp_err(psPcb, NULL); // // Close the TCP connection. // tcp_close(psPcb); if(psPcb == g_sEnet.psTCP) { g_sEnet.psTCP = 0; } // // And return. // return (ERR_OK); } // // Setup the TCP receive function. // tcp_recv(psPcb, TCPReceive); // // Setup the TCP error function. // tcp_err(psPcb, TCPError); // // Setup the TCP sent callback function. // tcp_sent(psPcb, TCPSent); // // Connection is complete. // g_sEnet.eState = iEthTCPConnectComplete; // // Return a success code. // return(ERR_OK); }
/** * Internal helper function to close a TCP netconn: since this sometimes * doesn't work at the first attempt, this function is called from multiple * places. * * @param conn the TCP netconn to close */ static void do_close_internal(struct netconn *conn) { err_t err; LWIP_ASSERT("invalid conn", (conn != NULL)); LWIP_ASSERT("this is for tcp netconns only", (conn->type == NETCONN_TCP)); LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE)); LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL)); /* Set back some callback pointers */ tcp_arg(conn->pcb.tcp, NULL); if (conn->pcb.tcp->state == LISTEN) { tcp_accept(conn->pcb.tcp, NULL); } else { tcp_recv(conn->pcb.tcp, NULL); tcp_accept(conn->pcb.tcp, NULL); /* some callbacks have to be reset if tcp_close is not successful */ tcp_sent(conn->pcb.tcp, NULL); tcp_poll(conn->pcb.tcp, NULL, 4); tcp_err(conn->pcb.tcp, NULL); } /* Try to close the connection */ err = tcp_close(conn->pcb.tcp); if (err == ERR_OK) { /* Closing succeeded */ conn->state = NETCONN_NONE; /* Set back some callback pointers as conn is going away */ conn->pcb.tcp = NULL; conn->err = ERR_OK; /* Trigger select() in socket layer. This send should something else so the errorfd is set, not the read and write fd! */ API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); /* wake up the application task */ sys_sem_signal(conn->op_completed); } else { /* Closing failed, restore some of the callbacks */ /* Closing of listen pcb will never fail! */ LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN)); tcp_sent(conn->pcb.tcp, sent_tcp); tcp_poll(conn->pcb.tcp, poll_tcp, 4); tcp_err(conn->pcb.tcp, err_tcp); tcp_arg(conn->pcb.tcp, conn); } /* If closing didn't succeed, we get called again either from poll_tcp or from sent_tcp */ }
void EthernetClient::stop() { if(cpcb == NULL) return; _connected = false; /* Stop frees any resources including any unread buffers */ err_t err; if(cpcb) { tcp_err(cpcb, NULL); if(cs->p) { tcp_recved(cpcb, cs->p->tot_len); pbuf_free(cs->p); cs->p = NULL; } err = tcp_close(cpcb); } if (err != ERR_OK) { /* Error closing, try again later in poll (every 2 sec) */ tcp_poll(cpcb, do_poll, 4); } else { cpcb = NULL; } }
/****************************************************************************** * FunctionName : espconn_client_close * Description : The connection shall be actively closed. * Parameters : pcb -- Additional argument to pass to the callback function * pcb -- the pcb to close * Returns : none *******************************************************************************/ static void ICACHE_FLASH_ATTR espconn_client_close(void *arg, struct tcp_pcb *pcb, uint8 type) { err_t err; espconn_msg *pclose = arg; pclose->pcommon.pcb = pcb; /*avoid recalling the disconnect function*/ tcp_recv(pcb, NULL); if(type == 0) err = tcp_close(pcb); else {tcp_abort(pcb); err = ERR_OK;} if (err != ERR_OK) { /* closing failed, try again later */ tcp_recv(pcb, espconn_client_recv); } else { /* closing succeeded */ tcp_sent(pcb, NULL); tcp_err(pcb, NULL); /*switch the state of espconn for application process*/ pclose->pespconn->state = ESPCONN_CLOSE; ets_post(espconn_TaskPrio, SIG_ESPCONN_CLOSE, (uint32_t)pclose); printf("ets_post close\n"); } }
AsyncClient::AsyncClient(tcp_pcb* pcb): _connect_cb(0) , _connect_cb_arg(0) , _discard_cb(0) , _discard_cb_arg(0) , _sent_cb(0) , _sent_cb_arg(0) , _error_cb(0) , _error_cb_arg(0) , _recv_cb(0) , _recv_cb_arg(0) , _timeout_cb(0) , _timeout_cb_arg(0) , _refcnt(0) , _pcb_busy(false) , _pcb_sent_at(0) , _close_pcb(false) , _rx_last_packet(0) , _rx_since_timeout(0) , prev(NULL) , next(NULL) { _pcb = pcb; if(pcb){ tcp_setprio(_pcb, TCP_PRIO_MIN); tcp_arg(_pcb, this); tcp_recv(_pcb, (tcp_recv_fn) &_s_recv); tcp_sent(_pcb, &_s_sent); tcp_err(_pcb, &_s_error); tcp_poll(_pcb, &_s_poll, 1); } }
static err_t lwip_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err) { phase_expected(PHASE_EVENTS); debug("<--- %s(arg 0x%pp, newpcb 0x%pp, err %d)\n", __FUNCTION__, arg, newpcb, err); outlet_t *ol = (outlet_t *)arg; assert(ol != 0); assert(err == ERR_OK); acc_pend_t *pend = get_free_pending(ol); if (pend == 0) { tcp_abort(newpcb); return ERR_ABRT; } pend->pcb = newpcb; pend->ante = 0; // The newpcb is being enqueued into // Data may be received for the newpcb while // it is still on the queue. Such data is handled by a *temporary* recevive // callback accept_recv_cb. tcp_arg(newpcb, pend); tcp_recv(newpcb, accept_recv_cb); tcp_err(newpcb, accept_error_cb); return try_to_bake(ol, pend); }
/** Close an iperf tcp session */ static void lwiperf_tcp_close(lwiperf_state_tcp_t* conn, enum lwiperf_report_type report_type) { err_t err; lwip_tcp_conn_report(conn, report_type); lwiperf_list_remove(&conn->base); if (conn->conn_pcb != NULL) { tcp_arg(conn->conn_pcb, NULL); tcp_poll(conn->conn_pcb, NULL, 0); tcp_sent(conn->conn_pcb, NULL); tcp_recv(conn->conn_pcb, NULL); tcp_err(conn->conn_pcb, NULL); err = tcp_close(conn->conn_pcb); if (err != ERR_OK) { /* don't want to wait for free memory here... */ tcp_abort(conn->conn_pcb); } } else { /* no conn pcb, this is the server pcb */ err = tcp_close(conn->server_pcb); LWIP_ASSERT("error", err != ERR_OK); } LWIPERF_FREE(lwiperf_state_tcp_t, conn); }
void EthernetClient::stop() { /* Stop frees any resources including any unread buffers */ err_t err; INT_PROTECT_INIT(oldLevel); /* protect the code from preemption of the ethernet interrupt servicing */ INT_PROTECT(oldLevel); struct tcp_pcb * cpcb_copy = (tcp_pcb *) SYNC_FETCH_AND_NULL(&cs->cpcb); struct pbuf * p_copy = (pbuf *) SYNC_FETCH_AND_NULL(&cs->p); _connected = false; cs->port = 0; if (cpcb_copy) { tcp_err(cpcb_copy, NULL); if (p_copy) { tcp_recved(cpcb_copy, p_copy->tot_len); pbuf_free(p_copy); } err = tcp_close(cpcb_copy); if (err != ERR_OK) { /* Error closing, try again later in poll (every 2 sec) */ tcp_poll(cpcb_copy, do_poll, 4); } } INT_UNPROTECT(oldLevel); }
void ol_tcp_animate(outlet_t *new_ol, struct tcp_pcb *pcb, struct pbuf *ante) { // // lwIP tries hard to allocate a new PCB. If there is not enough memory it // first kills TIME-WAIT connections and then active connections. The // error_cb callback is used along the way. The callback may sent an exit // signal to an outlet and the chain of exit signal may reach the current // outlet. To avoid this the priority of all PCBs is set to TCP_PRIO_MAX+1. // tcp_setprio(pcb, TCP_PRIO_MAX +1); tcp_arg(pcb, new_ol); // callback arg tcp_recv(pcb, recv_cb); tcp_sent(pcb, sent_cb); tcp_err(pcb, error_cb); new_ol->tcp = pcb; if (ante != 0) // data receive while enqueued { uint16_t len = ante->tot_len; if (len > new_ol->recv_bufsize) { debug("ol_tcp_animate: tot_len=%d, recv_bufsize=%d, truncating\n", ante->tot_len, new_ol->recv_bufsize); len = new_ol->recv_bufsize; } pbuf_copy_partial(ante, new_ol->recv_buffer, len, 0); new_ol->recv_buf_off = len; pbuf_free(ante); } }
static err_t ftpd_dataaccept(void *arg, struct tcp_pcb *pcb, err_t err) { struct ftpd_datastate *fsd = arg; fsd->msgfs->datapcb = pcb; fsd->connected = 1; /* Tell TCP that we wish to be informed of incoming data by a call to the http_recv() function. */ tcp_recv(pcb, ftpd_datarecv); /* Tell TCP that we wish be to informed of data that has been successfully sent by a call to the ftpd_sent() function. */ tcp_sent(pcb, ftpd_datasent); tcp_err(pcb, ftpd_dataerr); switch (fsd->msgfs->state) { case FTPD_LIST: send_next_directory(fsd, pcb, 0); break; case FTPD_NLST: send_next_directory(fsd, pcb, 1); break; case FTPD_RETR: send_file(fsd, pcb); break; default: break; } return ERR_OK; }
/*-----------------------------------------------------------------------------------*/ static err_t ident_accept(void *arg, struct tcp_pcb *pcb, err_t err) { struct ident_state *hs; /* Allocate memory for the structure that holds the state of the connection. */ hs = mem_malloc(sizeof(struct ident_state)); if(hs == NULL) { printf("ident_accept: Out of memory\n"); return ERR_MEM; } /* Initialize the structure. */ memset (hs, 0, sizeof (*hs)); if (sizeof (hs->remote) != sizeof (pcb->remote_ip)) die ("sizeof (hs.remote) != sizeof (pcb->remote_ip)"); memcpy (&hs->remote, &pcb->remote_ip, sizeof (hs->remote)); /* Tell TCP that this is the structure we wish to be passed for our callbacks. */ tcp_arg(pcb, hs); /* Tell TCP that we wish to be informed of incoming data by a call to the ident_recv() function. */ tcp_recv(pcb, ident_recv); tcp_err(pcb, conn_err); tcp_poll(pcb, ident_poll, 10); return ERR_OK; }
/** * Clean up and free the ttcp structure */ static void ard_tcp_abort(struct ttcp* ttcp) { INFO_TCP("Abort ttcb:%p tpcb:%p lpcb:%p\n", ttcp, ttcp->tpcb, ttcp->lpcb); if (ttcp->tpcb) { tcp_arg(ttcp->tpcb, NULL); tcp_sent(ttcp->tpcb, NULL); tcp_recv(ttcp->tpcb, NULL); tcp_err(ttcp->tpcb, NULL); tcp_abort(ttcp->tpcb); } if (ttcp->lpcb) { tcp_arg(ttcp->lpcb, NULL); tcp_accept(ttcp->lpcb, NULL); tcp_abort(ttcp->lpcb); } if (ttcp->upcb) { udp_disconnect(ttcp->upcb); udp_remove(ttcp->upcb); } if (ttcp->payload) free(ttcp->payload); free(ttcp); }
/** * Clean up and free the ttcp structure */ static void ard_tcp_destroy(struct ttcp* ttcp) { err_t err = ERR_OK; DUMP_TCP_STATE(ttcp); if (getSock(ttcp)==-1) WARN("ttcp already deallocated!\n"); if (ttcp->tpcb) { tcp_arg(ttcp->tpcb, NULL); tcp_sent(ttcp->tpcb, NULL); tcp_recv(ttcp->tpcb, NULL); tcp_err(ttcp->tpcb, NULL); //TEMPORAQARY //err = tcp_close(ttcp->tpcb); INFO_TCP("Closing tpcb: state:0x%x err:%d\n", ttcp->tpcb->state, err); } if (ttcp->lpcb) { tcp_arg(ttcp->lpcb, NULL); tcp_accept(ttcp->lpcb, NULL); err = tcp_close(ttcp->lpcb); INFO_TCP("Closing lpcb: state:0x%x err:%d\n", ttcp->lpcb->state, err); } if (ttcp->upcb) { udp_disconnect(ttcp->upcb); udp_remove(ttcp->upcb); } if (ttcp->payload) free(ttcp->payload); free(ttcp); }
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; }
//lwIP tcp_accept()的回调函数 err_t tcp_server_accept(void *arg,struct tcp_pcb *newpcb,err_t err) { err_t ret_err; struct tcp_server_struct *es; LWIP_UNUSED_ARG(arg); LWIP_UNUSED_ARG(err); tcp_setprio(newpcb,TCP_PRIO_MIN);//设置新创建的pcb优先级 es=(struct tcp_server_struct*)mem_malloc(sizeof(struct tcp_server_struct)); //分配内存 if(es!=NULL) //内存分配成功 { es->state=ES_TCPSERVER_ACCEPTED; //接收连接 es->pcb=newpcb; es->p=NULL; tcp_arg(newpcb,es); tcp_recv(newpcb,tcp_server_recv); //初始化tcp_recv()的回调函数 tcp_err(newpcb,tcp_server_error); //初始化tcp_err()回调函数 tcp_poll(newpcb,tcp_server_poll,1); //初始化tcp_poll回调函数 tcp_sent(newpcb,tcp_server_sent); //初始化发送回调函数 tcp_server_flag|=1<<5; //标记有客户端连上了 lwipdev.remoteip[0]=newpcb->remote_ip.addr&0xff; //IADDR4 lwipdev.remoteip[1]=(newpcb->remote_ip.addr>>8)&0xff; //IADDR3 lwipdev.remoteip[2]=(newpcb->remote_ip.addr>>16)&0xff; //IADDR2 lwipdev.remoteip[3]=(newpcb->remote_ip.addr>>24)&0xff; //IADDR1 ret_err=ERR_OK; }else ret_err=ERR_MEM;
/*-----------------------------------------------------------------------------------*/ static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err) { struct http_state *hs; /* Allocate memory for the structure that holds the state of the connection. */ hs = mem_malloc(sizeof(struct http_state)); if (hs == NULL) { return ERR_MEM; } /* Initialize the structure. */ hs->file = NULL; hs->left = 0; /* Tell TCP that this is the structure we wish to be passed for our callbacks. */ tcp_arg(pcb, hs); /* 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_poll(pcb, http_poll, 10); return ERR_OK; }
static err_t tcpecho_raw_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { err_t ret_err; struct tcpecho_raw_state *es; LWIP_UNUSED_ARG(arg); if ((err != ERR_OK) || (newpcb == NULL)) { return ERR_VAL; } /* Unless this pcb should have NORMAL priority, set its priority now. When running out of pcbs, low priority pcbs can be aborted to create new pcbs of higher priority. */ tcp_setprio(newpcb, TCP_PRIO_MIN); es = (struct tcpecho_raw_state *)mem_malloc(sizeof(struct tcpecho_raw_state)); if (es != NULL) { es->state = ES_ACCEPTED; es->pcb = newpcb; es->retries = 0; es->p = NULL; /* pass newly allocated es to our callbacks */ tcp_arg(newpcb, es); tcp_recv(newpcb, tcpecho_raw_recv); tcp_err(newpcb, tcpecho_raw_error); tcp_poll(newpcb, tcpecho_raw_poll, 0); tcp_sent(newpcb, tcpecho_raw_sent); ret_err = ERR_OK; } else { ret_err = ERR_MEM; } return ret_err; }
/** * @brief This function is the implementation of tcp_accept LwIP callback * @param arg: not used * @param newpcb: pointer on tcp_pcb struct for the newly created tcp connection * @param err: not used * @retval err_t: error status */ static err_t TCP_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { err_t ret_err; TCP *es; LWIP_UNUSED_ARG(arg); LWIP_UNUSED_ARG(err); tcp_setprio(newpcb, TCP_PRIO_MIN); /* set priority for the newly accepted tcp connection newpcb */ es = (TCP *)mem_malloc(sizeof(TCP)); /* allocate structure es to maintain tcp connection informations */ if (es != NULL) { es->state = ES_ACCEPTED; es->pcb = newpcb; es->tx = NULL; es->rx = NULL; tcp_arg(newpcb, es); /* pass newly allocated es structure as argument to newpcb */ tcp_recv(newpcb, TCP_recv); /* initialize lwip tcp_recv callback function for newpcb */ tcp_err(newpcb, TCP_error); /* initialize lwip tcp_err callback function for newpcb */ tcp_poll(newpcb, TCP_poll, 1); /* initialize lwip tcp_poll callback function for newpcb */ es->io=((func*)arg)(NULL); // prvi klic if(es->io) { // tole je lahko tut drugace es->f=(func *)arg; _thread_add(es->f,es->io,"user app.",0); _thread_add(_tcp_flush,es,"tcp flush",0); } ret_err = ERR_OK; } else { ret_err = ERR_MEM; /* return memory error */ } return ret_err; }
void socks_tcp_connect(struct socks_data *data) { struct tcp_pcb *pcb; err_t ret; bufferevent_disable(data->bev, EV_READ); LWIP_DEBUGF(SOCKS_DEBUG, ("%s: %s:%d\n", __func__, ipaddr_ntoa(&data->ipaddr), data->port)); pcb = tcp_new(); if (!pcb) data->connect_failed(data); pcb->flags |= TF_NODELAY; if (data->keep_alive) { pcb->so_options |= SOF_KEEPALIVE; pcb->keep_intvl = data->keep_alive; pcb->keep_idle = data->keep_alive; } ret = tcp_connect(pcb, &data->ipaddr, data->port, socks_tcp_connect_ok); if (ret < 0) { tcp_abort(pcb); data->connect_failed(data); } else { data->pcb = pcb; tcp_arg(pcb, data); tcp_err(pcb, socks_tcp_connect_err); } }
static void net_tcp_err_cb(void *arg, err_t err) { struct tls_netconn *conn = (struct tls_netconn *)arg; struct tcp_pcb *pcb = conn->pcb.tcp; u8 event = NET_EVENT_TCP_CONNECT_FAILED; TLS_DBGPRT_INFO("tcp err = %d\n", err); if (pcb) { tcp_arg(pcb, NULL); tcp_sent(pcb, NULL); tcp_recv(pcb, NULL); tcp_err(pcb, NULL); if (!conn->client) { tcp_accept(pcb, NULL); } if(err == ERR_OK) { tcp_close(pcb); } if(conn->state != NETCONN_STATE_NONE) { conn->state = NETCONN_STATE_NONE; event = NET_EVENT_TCP_DISCONNECT; } net_send_event_to_hostif(conn, event); if(conn->skd->errf != NULL) { conn->skd->errf(conn->skt_num, err); } conn->pcb.tcp = NULL; net_free_socket(conn); } }
int lwip_bind(int s, struct sockaddr *name, socklen_t namelen) { sockfd_t * fd; struct ip_addr ip; int port, rv = 0; s = sock_for_fd(s); if (s < 0) { errno = EBADF; return -1; } fd = fds + s; // Make sure it's an internet address we understand. if (namelen != sizeof(struct sockaddr_in)) { errno = ENAMETOOLONG; return -1; } // Get access mutex_lock(fd->mutex); // Copy it over memcpy(&fd->name, name, namelen); // Convert this to an lwIP-happy format ip.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr; port = ((struct sockaddr_in *)name)->sin_port; // Are we TCP or UDP? switch (fd->type) { case SOCK_STREAM: fd->tcppcb = tcp_new(); tcp_arg(fd->tcppcb, (void *)s); tcp_recv(fd->tcppcb, recv_tcp); tcp_sent(fd->tcppcb, sent_tcp); tcp_poll(fd->tcppcb, poll_tcp, 4); // 4 == 4 TCP timer intervals tcp_err(fd->tcppcb, err_tcp); if (tcp_bind(fd->tcppcb, &ip, ntohs(port)) != ERR_OK) { if (tcp_close(fd->tcppcb) != ERR_OK) tcp_abort(fd->tcppcb); fd->tcppcb = NULL; errno = EINVAL; rv = -1; goto out; } break; case SOCK_DGRAM: fd->udppcb = udp_new(); udp_recv(fd->udppcb, recv_udp, (void *)s); udp_bind(fd->udppcb, &ip, ntohs(port)); break; default: assert( 0 ); errno = EINVAL; rv = -1; goto out; } out: mutex_unlock(fd->mutex); return rv; }
/** This is called when a new client connects for an iperf tcp session */ static err_t lwiperf_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { lwiperf_state_tcp_t *s, *conn; if ((err != ERR_OK) || (newpcb == NULL) || (arg == NULL)) { return ERR_VAL; } s = (lwiperf_state_tcp_t*)arg; conn = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t); if (conn == NULL) { return ERR_MEM; } memset(conn, 0, sizeof(lwiperf_state_tcp_t)); conn->base.tcp = 1; conn->base.server = 1; conn->base.related_server_state = &s->base; conn->server_pcb = s->server_pcb; conn->conn_pcb = newpcb; conn->time_started = sys_now(); conn->report_fn = s->report_fn; conn->report_arg = s->report_arg; /* setup the tcp rx connection */ tcp_arg(newpcb, conn); tcp_recv(newpcb, lwiperf_tcp_recv); tcp_poll(newpcb, lwiperf_tcp_poll, 2U); tcp_err(conn->conn_pcb, lwiperf_tcp_err); lwiperf_list_add(&conn->base); return ERR_OK; }
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); }
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; }
/** * Clean up and free the ttcp structure */ static void ttcp_destroy(struct ttcp* ttcp) { if (ttcp->tpcb) { tcp_arg(ttcp->tpcb, NULL); tcp_sent(ttcp->tpcb, NULL); tcp_recv(ttcp->tpcb, NULL); tcp_err(ttcp->tpcb, NULL); tcp_close(ttcp->tpcb); } if (ttcp->lpcb) { tcp_arg(ttcp->lpcb, NULL); tcp_accept(ttcp->lpcb, NULL); tcp_close(ttcp->lpcb); } if (ttcp->upcb) { udp_disconnect(ttcp->upcb); udp_remove(ttcp->upcb); } if (ttcp->payload) free(ttcp->payload); timer_cancel_timeout(ttcp->tid); free(ttcp); }
static err_t mg_lwip_accept_cb(void *arg, struct tcp_pcb *newtpcb, err_t err) { struct mg_connection *lc = (struct mg_connection *) arg; (void) err; DBG(("%p conn %p from %s:%u", lc, newtpcb, ipaddr_ntoa(&newtpcb->remote_ip), newtpcb->remote_port)); struct mg_connection *nc = mg_if_accept_new_conn(lc); if (nc == NULL) { tcp_abort(newtpcb); return ERR_ABRT; } struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; cs->pcb.tcp = newtpcb; tcp_arg(newtpcb, nc); tcp_err(newtpcb, mg_lwip_tcp_error_cb); tcp_sent(newtpcb, mg_lwip_tcp_sent_cb); tcp_recv(newtpcb, mg_lwip_tcp_recv_cb); #ifdef SSL_KRYPTON if (lc->ssl_ctx != NULL) { nc->ssl = SSL_new(lc->ssl_ctx); if (nc->ssl == NULL || SSL_set_fd(nc->ssl, (intptr_t) nc) != 1) { LOG(LL_ERROR, ("SSL error")); tcp_close(newtpcb); } } else #endif { mg_lwip_accept_conn(nc, newtpcb); } return ERR_OK; }
/** * Callback function called when Server (THIS) receives a valid connection from a client * or a server connects to this client in CLIENT mode * * @param argument sent by lwIP * @param tcp connection descriptor * @param reception error flag * @return error type on callback to be processed by lwIP */ static err_t BRIDGE_UART_Accept(void *arg, struct tcp_pcb *pcb, err_t err) { struct bridge_state *hs; /* Allocate memory for the structure that holds the state of the connection */ hs = mem_malloc(sizeof(struct bridge_state)); if (hs == NULL) { return ERR_MEM; } /* Initialize the structure. */ hs->data = NULL; hs->left = 0; hs->retries = 0; /*uart structure*/ p_uart_tx_state.tx_pcb = pcb; p_uart_tx_state.p_bridge_state = hs; /* Tell TCP that this is the structure we wish to be passed for our callbacks */ tcp_arg(pcb, hs); /*called function when RX*/ tcp_recv(pcb, BRIDGE_UART_ETH_RX); tcp_err(pcb, BRIDGE_UART_ETH_ERROR); tcp_setprio(pcb,TCP_PRIO_MAX); return ERR_OK; }
err_t iperfserver_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { err_t ret_err; struct iperfserver_state *es; LWIP_UNUSED_ARG(arg); LWIP_UNUSED_ARG(err); /* commonly observed practive to call tcp_setprio(), why? */ tcp_setprio(newpcb, TCP_PRIO_MIN); es = (struct iperfserver_state *)mem_malloc(sizeof(struct iperfserver_state)); if (es != NULL) { es->state = ES_ACCEPTED; es->pcb = newpcb; es->retries = 0; es->p = NULL; /* pass newly allocated es to our callbacks */ tcp_arg(newpcb, es); tcp_recv(newpcb, iperfserver_recv); tcp_err(newpcb, iperfserver_error); ret_err = ERR_OK; } else { ret_err = ERR_MEM; } return ret_err; }
bool AsyncClient::connect(IPAddress ip, uint16_t port){ if (_pcb){ log_w("already connected, state %d", _pcb->state); return false; } if(!_start_async_task()){ log_e("failed to start task"); return false; } ip_addr_t addr; addr.type = IPADDR_TYPE_V4; addr.u_addr.ip4.addr = ip; tcp_pcb* pcb = tcp_new_ip_type(IPADDR_TYPE_V4); if (!pcb){ log_e("pcb == NULL"); return false; } tcp_arg(pcb, this); tcp_err(pcb, &_tcp_error); if(_in_lwip_thread){ tcp_connect(pcb, &addr, port,(tcp_connected_fn)&_s_connected); } else { _tcp_connect(pcb, &addr, port,(tcp_connected_fn)&_s_connected); } return true; }