zhhyu7 commented on code in PR #20627:
URL: https://github.com/apache/nuttx/pull/20627#discussion_r4259643626


##########
net/tcp/tcp_recvfrom.c:
##########
@@ -680,6 +682,202 @@ static void tcp_notify_recvcpu(FAR struct tcp_conn_s 
*conn)
  *
  ****************************************************************************/
 
+#ifdef CONFIG_NET_TCPURGDATA
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct tcp_oob_s
+{
+  FAR struct tcp_conn_s       *conn;
+  FAR struct devif_callback_s *cb;
+  sem_t                        sem;
+  int                          result;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: tcp_oob_eventhandler
+ *
+ * Description:
+ *   Handle callback events for a thread waiting for urgent (OOB) data.
+ *
+ * Input Parameters:
+ *   dev      The network device driver
+ *   pvpriv   Private data (pointer to struct tcp_oob_s)
+ *   flags    Event flags
+ *
+ * Returned Value:
+ *   Updated event flags
+ *
+ ****************************************************************************/
+
+static uint32_t tcp_oob_eventhandler(FAR struct net_driver_s *dev,
+                                     FAR void *pvpriv, uint32_t flags)
+{
+  FAR struct tcp_oob_s *pstate = (FAR struct tcp_oob_s *)pvpriv;
+
+  ninfo("flags: %08" PRIx32 "\n", flags);
+
+  if (pstate != NULL)
+    {
+      if ((flags & TCP_URGDATA) != 0)
+        {
+          pstate->result = OK;
+          nxsem_post(&pstate->sem);
+        }
+      else if ((flags & TCP_DISCONN_EVENTS) != 0)
+        {
+          pstate->result = -ENOTCONN;
+          nxsem_post(&pstate->sem);
+        }
+      else if ((flags & TCP_RXCLOSE) != 0)
+        {
+          pstate->result = -ENOTCONN;
+          nxsem_post(&pstate->sem);
+        }
+    }
+
+  return flags;
+}
+
+/****************************************************************************
+ * Name: tcp_recv_oob
+ *
+ * Description:
+ *   Receive urgent (out-of-band) data from the connection
+ *
+ * Input Parameters:
+ *   conn    The TCP connection of interest
+ *   buf     The buffer to receive the data
+ *   len     The length of the buffer
+ *   flags   Receive flags
+ *
+ * Returned Value:
+ *   Number of bytes received or negated errno value
+ *
+ * Assumptions:
+ *   The network is locked.
+ *
+ ****************************************************************************/
+
+static ssize_t tcp_recv_oob(FAR struct tcp_conn_s *conn, FAR void *buf,
+                            size_t len, int flags)
+{
+  FAR struct iob_s *iob;
+  ssize_t recvlen;
+  int ret;
+
+#ifdef CONFIG_NET_SOCKOPTS
+  /* POSIX Rule: If SO_OOBINLINE is enabled, MSG_OOB read is not allowed */
+
+  if (_SO_GETOPT(conn->sconn.s_options, _SO_OOBINLINE))
+    {
+      return -EINVAL;
+    }
+#endif
+
+  /* Wait while urgent buffer is empty */
+
+  while (conn->urgreadahead == NULL)
+    {
+      struct tcp_oob_s state;
+      struct tcp_callback_s info;
+
+      /* Non-blocking socket or MSG_DONTWAIT check */
+
+      if ((flags & MSG_DONTWAIT) != 0 || _SS_ISNONBLOCK(conn->sconn.s_flags))
+        {
+          return -EAGAIN;
+        }
+
+      /* Check if connection is disconnected */
+
+      if (!_SS_ISCONNECTED(conn->sconn.s_flags))
+        {
+          return -ENOTCONN;
+        }
+
+      /* Set up the devif callback to wait for TCP_URGDATA or disconnect */
+
+      state.conn   = conn;
+      state.result = -EAGAIN;
+      nxsem_init(&state.sem, 0, 0);
+      nxsem_set_protocol(&state.sem, SEM_PRIO_NONE);
+
+      state.cb = tcp_callback_alloc(conn);
+      if (state.cb == NULL)
+        {
+          nxsem_destroy(&state.sem);
+          return -EBUSY;
+        }
+
+      state.cb->flags = TCP_URGDATA | TCP_DISCONN_EVENTS | TCP_RXCLOSE;
+      state.cb->priv  = &state;
+      state.cb->event = tcp_oob_eventhandler;
+
+      /* Push cancellation cleanup */
+
+      info.tc_conn = conn;
+      info.tc_cb   = &state.cb;
+      info.tc_sem  = &state.sem;
+      tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info);
+
+      /* Wait for urgent data arrival, disconnection, or timeout */
+
+#ifdef CONFIG_NET_SOCKOPTS
+      ret = conn_dev_sem_timedwait(&state.sem, true,

Review Comment:
   ```recv (MSG_OOB)``` should not block:
   no urgent data, or the urgent byte was already read: return EINVAL;
   urgent data announced but the byte has not arrived yet: return EAGAIN.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to