* Accept a new connection on a TCP listening netconn. * * @param conn the TCP listen netconn * @param new_conn pointer where the new connection is stored * @return ERR_OK if a new connection has been received or an error * code otherwise */
| 274 | * code otherwise |
| 275 | */ |
| 276 | err_t |
| 277 | netconn_accept(struct netconn *conn, struct netconn **new_conn) |
| 278 | { |
| 279 | #if LWIP_TCP |
| 280 | struct netconn *newconn; |
| 281 | err_t err; |
| 282 | #if TCP_LISTEN_BACKLOG |
| 283 | struct api_msg msg; |
| 284 | #endif /* TCP_LISTEN_BACKLOG */ |
| 285 | |
| 286 | LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;); |
| 287 | *new_conn = NULL; |
| 288 | LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;); |
| 289 | LWIP_ERROR("netconn_accept: invalid acceptmbox", sys_mbox_valid(&conn->acceptmbox), return ERR_ARG;); |
| 290 | |
| 291 | err = conn->last_err; |
| 292 | if (ERR_IS_FATAL(err)) { |
| 293 | /* don't recv on fatal errors: this might block the application task |
| 294 | waiting on acceptmbox forever! */ |
| 295 | return err; |
| 296 | } |
| 297 | |
| 298 | #if LWIP_SO_RCVTIMEO |
| 299 | if (sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) { |
| 300 | NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT); |
| 301 | return ERR_TIMEOUT; |
| 302 | } |
| 303 | #else |
| 304 | sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, 0); |
| 305 | #endif /* LWIP_SO_RCVTIMEO*/ |
| 306 | /* Register event with callback */ |
| 307 | API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); |
| 308 | |
| 309 | if (newconn == NULL) { |
| 310 | /* connection has been aborted */ |
| 311 | NETCONN_SET_SAFE_ERR(conn, ERR_ABRT); |
| 312 | return ERR_ABRT; |
| 313 | } |
| 314 | #if TCP_LISTEN_BACKLOG |
| 315 | /* Let the stack know that we have accepted the connection. */ |
| 316 | msg.function = do_recv; |
| 317 | msg.msg.conn = conn; |
| 318 | /* don't care for the return value of do_recv */ |
| 319 | TCPIP_APIMSG(&msg); |
| 320 | #endif /* TCP_LISTEN_BACKLOG */ |
| 321 | |
| 322 | *new_conn = newconn; |
| 323 | /* don't set conn->last_err: it's only ERR_OK, anyway */ |
| 324 | return ERR_OK; |
| 325 | #else /* LWIP_TCP */ |
| 326 | LWIP_UNUSED_ARG(conn); |
| 327 | LWIP_UNUSED_ARG(new_conn); |
| 328 | return ERR_ARG; |
| 329 | #endif /* LWIP_TCP */ |
| 330 | } |
| 331 | |
| 332 | /** |
| 333 | * Receive data: actual implementation that doesn't care whether pbuf or netbuf |
no test coverage detected