summaryrefslogtreecommitdiff
path: root/nuttx/net/net_close.c
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/net/net_close.c')
-rw-r--r--nuttx/net/net_close.c87
1 files changed, 40 insertions, 47 deletions
diff --git a/nuttx/net/net_close.c b/nuttx/net/net_close.c
index 10f7e199e..6e14cafb0 100644
--- a/nuttx/net/net_close.c
+++ b/nuttx/net/net_close.c
@@ -1,7 +1,7 @@
/****************************************************************************
* net/net_close.c
*
- * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -87,38 +87,41 @@ struct tcp_close_s
****************************************************************************/
#ifdef CONFIG_NET_TCP
-static uint16_t netclose_interrupt(struct uip_driver_s *dev, void *pvconn,
- void *pvpriv, uint16_t flags)
+static uint16_t netclose_interrupt(FAR struct uip_driver_s *dev,
+ FAR void *pvconn, FAR void *pvpriv,
+ uint16_t flags)
{
- struct tcp_close_s *pstate = (struct tcp_close_s *)pvpriv;
+ FAR struct uip_conn *conn = (FAR struct uip_conn*)pvconn;
- nllvdbg("flags: %04x\n", flags);
+ DEBUGASSERT(conn != NULL);
- if (pstate)
+ nlldbg("flags: %04x\n", flags);
+
+ /* UIP_CLOSE: The remote host has closed the connection
+ * UIP_ABORT: The remote host has aborted the connection
+ * UIP_TIMEDOUT: The remote did not respond, the connection timed out
+ */
+
+ if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
{
- /* UIP_CLOSE: The remote host has closed the connection
- * UIP_ABORT: The remote host has aborted the connection
- */
+ /* The disconnection is complete */
- if ((flags & (UIP_CLOSE|UIP_ABORT)) != 0)
- {
- /* The disconnection is complete */
+ conn->closecb->flags = 0;
+ conn->closecb->priv = NULL;
+ conn->closecb->event = NULL;
- pstate->cl_cb->flags = 0;
- pstate->cl_cb->priv = NULL;
- pstate->cl_cb->event = NULL;
- sem_post(&pstate->cl_sem);
- nllvdbg("Resuming\n");
- }
- else
- {
- /* Drop data received in this state and make sure that UIP_CLOSE
- * is set in the response
- */
+ /* Free connection resources */
- dev->d_len = 0;
- return (flags & ~UIP_NEWDATA) | UIP_CLOSE;
- }
+ uip_tcpfree(conn);
+ }
+ else
+ {
+ /* Drop data received in this state and make sure that UIP_CLOSE
+ * is set in the response
+ */
+
+ dev->d_len = 0;
+ return (flags & ~UIP_NEWDATA) | UIP_CLOSE;
}
return flags;
@@ -158,34 +161,25 @@ static inline void netclose_disconnect(FAR struct socket *psock)
{
struct uip_conn *conn = (struct uip_conn*)psock->s_conn;
+ DEBUGASSERT(conn->closecb == NULL);
+
/* Check for the case where the host beat us and disconnected first */
if (conn->tcpstateflags == UIP_ESTABLISHED)
{
- /* Set up to receive TCP data event callbacks */
+ /* This callback will be freed together with conn */
- state.cl_cb = uip_tcpcallbackalloc(conn);
- if (state.cl_cb)
+ conn->closecb = uip_tcpcallbackalloc(conn);
+ if (conn->closecb)
{
- state.cl_psock = psock;
- sem_init(&state.cl_sem, 0, 0);
+ /* Set up to receive TCP data event callbacks */
- state.cl_cb->flags = UIP_NEWDATA|UIP_POLL|UIP_CLOSE|UIP_ABORT;
- state.cl_cb->priv = (void*)&state;
- state.cl_cb->event = netclose_interrupt;
+ conn->closecb->flags = UIP_NEWDATA|UIP_POLL|UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT;
+ conn->closecb->event = netclose_interrupt;
- /* Notify the device driver of the availaibilty of TX data */
+ /* Notify the device driver of the availaibilty of TX data */
netdev_txnotify(conn->ripaddr);
-
- /* Wait for the disconnect event */
-
- (void)uip_lockedwait(&state.cl_sem);
-
- /* We are now disconnected */
-
- sem_destroy(&state.cl_sem);
- uip_tcpcallbackfree(conn, state.cl_cb);
}
}
}
@@ -242,17 +236,16 @@ int psock_close(FAR struct socket *psock)
struct uip_conn *conn = psock->s_conn;
/* Is this the last reference to the connection structure (there
- * could be more if the socket was dup'ed.
+ * could be more if the socket was dup'ed).
*/
if (conn->crefs <= 1)
{
- /* Yes... free the connection structure */
+ /* Yes... then perform the disconnection now */
uip_unlisten(conn); /* No longer accepting connections */
netclose_disconnect(psock); /* Break any current connections */
conn->crefs = 0; /* No more references on the connection */
- uip_tcpfree(conn); /* Free uIP resources */
}
else
{