mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 13:18:50 +08:00
TCP networking: Hook the network monitor into the device event notification logic
This commit is contained in:
parent
5142a1a1db
commit
8b029fbbee
5 changed files with 113 additions and 14 deletions
|
@ -15,8 +15,8 @@ config NET_NACTIVESOCKETS
|
|||
int "Max socket operations"
|
||||
default 16
|
||||
---help---
|
||||
Maximum number of concurrent socket operations (recv, send, etc.).
|
||||
Default: 16
|
||||
Maximum number of concurrent socket operations (recv, send,
|
||||
connection monitoring, etc.). Default: 16
|
||||
|
||||
config NET_SOCKOPTS
|
||||
bool "Socket options"
|
||||
|
|
|
@ -58,7 +58,9 @@
|
|||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static void connection_event(FAR struct tcp_conn_s *conn, uint16_t flags);
|
||||
static uint16_t connection_event(FAR struct net_driver_s *dev,
|
||||
FAR void *pvconn, FAR void *pvpriv,
|
||||
uint16_t flags);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
|
@ -70,6 +72,7 @@ static void connection_event(FAR struct tcp_conn_s *conn, uint16_t flags);
|
|||
* Some connection related event has occurred
|
||||
*
|
||||
* Parameters:
|
||||
* dev The device which as active when the event was detected.
|
||||
* conn The connection structure associated with the socket
|
||||
* flags Set of events describing why the callback was invoked
|
||||
*
|
||||
|
@ -77,13 +80,15 @@ static void connection_event(FAR struct tcp_conn_s *conn, uint16_t flags);
|
|||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Running at the interrupt level
|
||||
* The network is locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void connection_event(FAR struct tcp_conn_s *conn, uint16_t flags)
|
||||
static uint16_t connection_event(FAR struct net_driver_s *dev,
|
||||
FAR void *pvconn, FAR void *pvpriv,
|
||||
uint16_t flags)
|
||||
{
|
||||
FAR struct socket *psock = (FAR struct socket *)conn->connection_private;
|
||||
FAR struct socket *psock = (FAR struct socket *)pvpriv;
|
||||
|
||||
if (psock)
|
||||
{
|
||||
|
@ -108,6 +113,8 @@ static void connection_event(FAR struct tcp_conn_s *conn, uint16_t flags)
|
|||
psock->s_flags &= ~_SF_CLOSED;
|
||||
}
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -129,13 +136,16 @@ static void connection_event(FAR struct tcp_conn_s *conn, uint16_t flags)
|
|||
* case, -ENOTCONN is returned.
|
||||
*
|
||||
* Assumptions:
|
||||
* The caller holds the network lock.
|
||||
* The caller holds the network lock (if not, it will be locked momentarily
|
||||
* by this function).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int net_startmonitor(FAR struct socket *psock)
|
||||
{
|
||||
FAR struct tcp_conn_s *conn = psock->s_conn;
|
||||
FAR struct devif_callback_s *cb;
|
||||
net_lock_t save;
|
||||
|
||||
DEBUGASSERT(psock && conn);
|
||||
|
||||
|
@ -144,30 +154,51 @@ int net_startmonitor(FAR struct socket *psock)
|
|||
* registered the monitoring callback.)
|
||||
*/
|
||||
|
||||
save = net_lock();
|
||||
if (!(conn->tcpstateflags == TCP_ESTABLISHED ||
|
||||
conn->tcpstateflags == TCP_SYN_RCVD))
|
||||
{
|
||||
/* Invoke the TCP_CLOSE connection event now */
|
||||
|
||||
connection_event(conn, TCP_CLOSE);
|
||||
(void)connection_event(NULL, conn, psock, TCP_CLOSE);
|
||||
|
||||
/* Make sure that the monitor is stopped */
|
||||
|
||||
conn->connection_private = NULL;
|
||||
conn->connection_devcb = NULL;
|
||||
conn->connection_event = NULL;
|
||||
|
||||
/* And return -ENOTCONN to indicate the the monitor was not started
|
||||
* because the socket was already disconnected.
|
||||
*/
|
||||
|
||||
net_unlock(save);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
DEBUGASSERT(conn->connection_event == NULL &&
|
||||
conn->connection_devcb == NULL);
|
||||
|
||||
/* Allocate a callback structure that we will use to get callbacks if
|
||||
* the network goes down.
|
||||
*/
|
||||
|
||||
cb = tcp_monitor_callback_alloc(conn);
|
||||
if (cb != NULL)
|
||||
{
|
||||
cb->event = connection_event;
|
||||
cb->priv = (void*)psock;
|
||||
cb->flags = NETDEV_DOWN;
|
||||
}
|
||||
|
||||
conn->connection_devcb = cb;
|
||||
|
||||
/* Set up to receive callbacks on connection-related events */
|
||||
|
||||
conn->connection_private = (void*)psock;
|
||||
conn->connection_event = connection_event;
|
||||
|
||||
net_unlock(save);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -183,14 +214,32 @@ int net_startmonitor(FAR struct socket *psock)
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* The caller holds the network lock (if not, it will be locked momentarily
|
||||
* by this function).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void net_stopmonitor(FAR struct tcp_conn_s *conn)
|
||||
{
|
||||
net_lock_t save;
|
||||
|
||||
DEBUGASSERT(conn);
|
||||
|
||||
/* Free any allocated device event callback structure */
|
||||
|
||||
save = net_lock();
|
||||
if (conn->connection_devcb)
|
||||
{
|
||||
tcp_monitor_callback_free(conn, conn->connection_devcb);
|
||||
}
|
||||
|
||||
/* Nullify all connection event data */
|
||||
|
||||
conn->connection_private = NULL;
|
||||
conn->connection_devcb = NULL;
|
||||
conn->connection_event = NULL;
|
||||
net_unlock(save);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -207,7 +256,7 @@ void net_stopmonitor(FAR struct tcp_conn_s *conn)
|
|||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Running at the interrupt level
|
||||
* The caller holds the network lock.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
|
|
@ -237,7 +237,8 @@ FAR struct socket *sockfd_socket(int sockfd);
|
|||
* case, -ENOTCONN is returned.
|
||||
*
|
||||
* Assumptions:
|
||||
* The caller holds the network lock.
|
||||
* The caller holds the network lock (if not, it will be locked momentarily
|
||||
* by this function).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
@ -257,6 +258,10 @@ int net_startmonitor(FAR struct socket *psock);
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* The caller holds the network lock (if not, it will be locked momentarily
|
||||
* by this function).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_TCP
|
||||
|
@ -277,7 +282,7 @@ void net_stopmonitor(FAR struct tcp_conn_s *conn);
|
|||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Running at the interrupt level
|
||||
* The caller holds the network lock.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
|
|
@ -63,15 +63,42 @@
|
|||
/* Allocate a new TCP data callback */
|
||||
|
||||
#ifdef CONFIG_NETDEV_MULTINIC
|
||||
/* These macros allocate and free callback structures used for receiving
|
||||
* notifications of TCP data-related events.
|
||||
*/
|
||||
|
||||
# define tcp_callback_alloc(conn) \
|
||||
devif_callback_alloc(conn->dev, &conn->list)
|
||||
# define tcp_callback_free(conn,cb) \
|
||||
devif_callback_free(conn->dev, cb, &conn->list)
|
||||
|
||||
/* These macros allocate and free callback structures used for receiving
|
||||
* notifications of device-related events.
|
||||
*/
|
||||
|
||||
# define tcp_monitor_callback_alloc(conn) \
|
||||
devif_callback_alloc(conn->dev, NULL)
|
||||
# define tcp_monitor_callback_free(conn,cb) \
|
||||
devif_callback_free(conn->dev, cb, NULL)
|
||||
|
||||
#else
|
||||
/* These macros allocate and free callback structures used for receiving
|
||||
* notifications of TCP data-related events.
|
||||
*/
|
||||
|
||||
# define tcp_callback_alloc(conn) \
|
||||
devif_callback_alloc(g_netdevices, &conn->list)
|
||||
# define tcp_callback_free(conn,cb) \
|
||||
devif_callback_free(g_netdevices, cb, &conn->list)
|
||||
|
||||
/* These macros allocate and free callback structures used for receiving
|
||||
* notifications of device-related events.
|
||||
*/
|
||||
|
||||
# define tcp_monitor_callback_alloc(conn) \
|
||||
devif_callback_alloc(g_netdevices, NULL)
|
||||
# define tcp_monitor_callback_free(conn,cb) \
|
||||
devif_callback_free(g_netdevices, cb, NULL)
|
||||
#endif
|
||||
|
||||
/* Get the current maximum segment size that can be sent on the current
|
||||
|
@ -227,17 +254,34 @@ struct tcp_conn_s
|
|||
|
||||
FAR struct devif_callback_s *list;
|
||||
|
||||
/* accept() is called when the TCP logic has created a connection */
|
||||
/* accept() is called when the TCP logic has created a connection
|
||||
*
|
||||
* accept_private: This is private data that will be available to the
|
||||
* accept() handler when it is invoked with a point to this structure
|
||||
* as an argument.
|
||||
* accept: This is the the pointer to the accept handler.
|
||||
*/
|
||||
|
||||
FAR void *accept_private;
|
||||
int (*accept)(FAR struct tcp_conn_s *listener, FAR struct tcp_conn_s *conn);
|
||||
|
||||
/* connection_event() is called on any of the subset of connection-related
|
||||
* events.
|
||||
*
|
||||
* connection_private: This is private data that will be available to
|
||||
* the connection_event() handler when it is invoked with a point to
|
||||
* this structure as an argument.
|
||||
* connection_devcb: this is the allocated callback structure that is
|
||||
* used to
|
||||
* connection_event: This is the the pointer to the connection event
|
||||
* handler.
|
||||
*/
|
||||
|
||||
FAR void *connection_private;
|
||||
void (*connection_event)(FAR struct tcp_conn_s *conn, uint16_t flags);
|
||||
FAR struct devif_callback_s *connection_devcb;
|
||||
uint16_t (*connection_event)(FAR struct net_driver_s *dev,
|
||||
FAR void *pvconn, FAR void *pvpriv,
|
||||
uint16_t flags);
|
||||
};
|
||||
|
||||
/* This structure supports TCP write buffering */
|
||||
|
|
|
@ -201,7 +201,8 @@ uint16_t tcp_callback(FAR struct net_driver_s *dev,
|
|||
{
|
||||
/* Perform the callback */
|
||||
|
||||
conn->connection_event(conn, flags);
|
||||
flags = conn->connection_event(dev, conn, conn->connection_private,
|
||||
flags);
|
||||
}
|
||||
|
||||
return flags;
|
||||
|
|
Loading…
Reference in a new issue