You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/09/01 06:58:18 UTC

[incubator-nuttx-apps] 04/06: examples/usrsocktest: add USRSOCK_REQUEST_IOCTL support

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx-apps.git

commit 45a21aea8e9ade6dd40b43d9e4c237b0f317dd24
Author: chao an <an...@xiaomi.com>
AuthorDate: Wed Aug 31 22:55:32 2022 +0800

    examples/usrsocktest: add USRSOCK_REQUEST_IOCTL support
    
    The test model of usrsock ioctl() has changed after file socket layer implemented from vfs,
    usrsock must implement the ioctl() hook to pass this test
    
    Signed-off-by: chao an <an...@xiaomi.com>
---
 examples/usrsocktest/usrsocktest_daemon.c | 142 +++++++++++++++++++++++++++++-
 1 file changed, 141 insertions(+), 1 deletion(-)

diff --git a/examples/usrsocktest/usrsocktest_daemon.c b/examples/usrsocktest/usrsocktest_daemon.c
index f948395e3..f9c80f84b 100644
--- a/examples/usrsocktest/usrsocktest_daemon.c
+++ b/examples/usrsocktest/usrsocktest_daemon.c
@@ -36,6 +36,7 @@
 #include <pthread.h>
 
 #include <sys/socket.h>
+#include <sys/ioctl.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <nuttx/net/usrsock.h>
@@ -74,6 +75,7 @@ struct test_socket_s
   bool connect_refused:1;
   bool disconnected:1;
   int recv_avail_bytes;
+  int flags;
   FAR void *endp;
   struct usrsock_message_req_ack_s pending_resp;
 };
@@ -1333,7 +1335,12 @@ prepare:
 
   resp.reqack.head.flags = 0;
   resp.reqack.result = ret;
-  if (ret >= 0)
+  if (req->max_addrlen == 0)
+    {
+      resp.valuelen = 0;
+      resp.valuelen_nontrunc = sizeof(addr);
+    }
+  else if (ret >= 0)
     {
       resp.valuelen = sizeof(addr);
       resp.valuelen_nontrunc = sizeof(addr);
@@ -1380,6 +1387,133 @@ prepare:
   return OK;
 }
 
+static int ioctl_request(int fd, FAR struct daemon_priv_s *priv,
+                         FAR void *hdrbuf)
+{
+  FAR struct usrsock_request_ioctl_s *req = hdrbuf;
+  struct usrsock_message_datareq_ack_s resp = {
+  };
+
+  FAR struct test_socket_s *tsock;
+  uint32_t value;
+  ssize_t wlen;
+  ssize_t rlen;
+  int ret;
+
+  /* Check if this socket exists. */
+
+  tsock = test_socket_get(priv, req->usockid);
+  if (!tsock)
+    {
+      ret = -EBADFD;
+      goto prepare;
+    }
+
+  if (req->arglen != sizeof(value))
+    {
+      ret = -EINVAL;
+      goto prepare;
+    }
+
+  /* Read value. */
+
+  rlen = read(fd, &value, sizeof(value));
+  if (rlen < 0 || rlen < sizeof(value))
+    {
+      ret = -EFAULT;
+      goto prepare;
+    }
+
+  ret = OK;
+
+prepare:
+
+  /* Prepare response. */
+
+  resp.reqack.xid = req->head.xid;
+  resp.reqack.head.msgid  = USRSOCK_MESSAGE_RESPONSE_DATA_ACK;
+  resp.reqack.head.flags  = 0;
+  resp.reqack.head.events = 0;
+
+  if (priv->conf->delay_all_responses)
+    {
+      resp.reqack.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS;
+      resp.reqack.result = -EINPROGRESS;
+      resp.valuelen = 0;
+      resp.valuelen_nontrunc = 0;
+
+      /* Send ack response. */
+
+      wlen = write(fd, &resp, sizeof(resp));
+      if (wlen < 0)
+        {
+          return -errno;
+        }
+
+      if (wlen != sizeof(resp))
+        {
+          return -ENOSPC;
+        }
+
+      pthread_mutex_unlock(&daemon_mutex);
+      usleep(50 * 1000);
+      pthread_mutex_lock(&daemon_mutex);
+
+      /* Previous write was acknowledgment to request, informing that request
+       * is still in progress. Now write actual completion response.
+       */
+
+      resp.reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK;
+      resp.reqack.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS;
+    }
+
+  resp.reqack.head.flags = 0;
+  resp.reqack.result = ret;
+  if (ret >= 0)
+    {
+      resp.valuelen = sizeof(value);
+      resp.valuelen_nontrunc = sizeof(value);
+
+      tsock->flags |= value;
+      value = tsock->flags;
+    }
+  else
+    {
+      resp.valuelen = 0;
+    }
+
+  /* Send response. */
+
+  wlen = write(fd, &resp, sizeof(resp));
+  if (wlen < 0)
+    {
+      return -errno;
+    }
+
+  if (wlen != sizeof(resp))
+    {
+      return -ENOSPC;
+    }
+
+  if (resp.valuelen > 0)
+    {
+      /* Send address (value) */
+
+      wlen = write(fd, &value, resp.valuelen);
+      if (wlen < 0)
+        {
+          return -errno;
+        }
+
+      if (wlen != resp.valuelen)
+        {
+          return -ENOSPC;
+        }
+    }
+
+  return OK;
+}
+
 static int handle_usrsock_request(int fd, FAR struct daemon_priv_s *priv)
 {
   static const struct
@@ -1437,6 +1571,12 @@ static int handle_usrsock_request(int fd, FAR struct daemon_priv_s *priv)
           sizeof(struct usrsock_request_getsockname_s),
           getsockname_request,
         },
+
+      [USRSOCK_REQUEST_IOCTL] =
+        {
+          sizeof(struct usrsock_request_ioctl_s),
+          ioctl_request,
+        },
     };
 
   uint8_t hdrbuf[16];