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

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit cc89076de7c23f44497d348dfbca7cc256b3b83e
Author: mazhuang <[email protected]>
AuthorDate: Tue Nov 3 21:19:59 2026 +0800

    net/rpmsg: add SO_PRIORITY support for rpmsg sockets
    
    Rpmsg messages can carry a priority, but a socket had no way to select
    one, so every endpoint used the default.
    
    Add conn->priority, expose it through SO_PRIORITY get/setsockopt, and
    apply it with rpmsg_set_priority() on both the client endpoint created in
    rpmsg_socket_device_created() and the accepted-connection endpoint created
    in rpmsg_socket_ns_bind().  An accepted connection inherits the listening
    socket's priority, so that getsockopt() on it reports the value in use.
    rpmsg_socket_setsockopt() is restructured from a single if into a switch
    so further options can be added.
    
    SO_PRIORITY takes an int (socket(7)), but read the value according to the
    length the caller supplied, as ipv4_setsockopt() already does for IP_TTL,
    so that an int, a char or a uint8_t argument all work without reading past
    the caller's buffer.  getsockopt() likewise writes back only as many bytes
    as the caller provided and reports the length used.
    
    Signed-off-by: mazhuang <[email protected]>
    Signed-off-by: zhanghongyu <[email protected]>
---
 net/rpmsg/rpmsg_sockif.c | 100 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 90 insertions(+), 10 deletions(-)

diff --git a/net/rpmsg/rpmsg_sockif.c b/net/rpmsg/rpmsg_sockif.c
index 82498ca68e1..b23422fdc92 100644
--- a/net/rpmsg/rpmsg_sockif.c
+++ b/net/rpmsg/rpmsg_sockif.c
@@ -144,6 +144,8 @@ struct rpmsg_socket_conn_s
 
   uint32_t                       recvpos;
   uint32_t                       lastpos;
+
+  uint8_t                        priority;
 };
 
 /****************************************************************************
@@ -276,6 +278,7 @@ static FAR struct rpmsg_socket_conn_s 
*rpmsg_socket_alloc(void)
 
   conn->recvsize = CONFIG_NET_RPMSG_RXBUF_SIZE;
   conn->crefs = 1;
+  conn->priority = RPMSG_PRIO_DEFAULT;
   return conn;
 }
 
@@ -539,6 +542,7 @@ static void rpmsg_socket_device_created(FAR struct 
rpmsg_device *rdev,
       rpmsg_create_ept(&conn->ept, rdev, namebuf,
                        RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
                        rpmsg_socket_ept_cb, rpmsg_socket_ns_unbind);
+      rpmsg_set_priority(&conn->ept, conn->priority);
     }
 }
 
@@ -600,6 +604,19 @@ static void rpmsg_socket_ns_bind(FAR struct rpmsg_device 
*rdev,
       return;
     }
 
+  /* The accepted connection inherits the listener's priority, so that
+   * getsockopt(SO_PRIORITY) on it reports the priority actually in use.
+   */
+
+  new->priority = server->priority;
+
+  ret = rpmsg_set_priority(&new->ept, new->priority);
+  if (ret < 0)
+    {
+      rpmsg_socket_free(new);
+      return;
+    }
+
   new->rpaddr.rp_family = AF_RPMSG;
   strlcpy(new->rpaddr.rp_cpu, rpmsg_get_cpuname(rdev),
           sizeof(new->rpaddr.rp_cpu));
@@ -1547,6 +1564,31 @@ static int rpmsg_socket_getsockopt(FAR struct socket 
*psock, int level,
               *(FAR int *)value = conn->sendsize;
               return OK;
             }
+
+          case SO_PRIORITY:
+            {
+              if (value == NULL || *value_len == 0)
+                {
+                  return -EINVAL;
+                }
+
+              /* Write back only as many bytes as the caller provided, so
+               * that both an int and a char argument work.
+               */
+
+              if (*value_len >= sizeof(int))
+                {
+                  *(FAR int *)value = conn->priority;
+                  *value_len = sizeof(int);
+                }
+              else
+                {
+                  *(FAR unsigned char *)value = conn->priority;
+                  *value_len = sizeof(unsigned char);
+                }
+
+              return OK;
+            }
         }
     }
 
@@ -1559,20 +1601,58 @@ static int rpmsg_socket_setsockopt(FAR struct socket 
*psock, int level,
 {
   FAR struct rpmsg_socket_conn_s *conn = psock->s_conn;
 
-  if (level == SOL_SOCKET && option == SO_RCVBUF)
+  if (level == SOL_SOCKET)
     {
-      if (value_len < sizeof(int))
+      switch (option)
         {
-          return -EINVAL;
-        }
+          case SO_RCVBUF:
+            {
+              if (value_len < sizeof(int))
+                {
+                  return -EINVAL;
+                }
 
-      if (_SS_ISCONNECTED(conn->sconn.s_flags))
-        {
-          return -EISCONN;
-        }
+              if (_SS_ISCONNECTED(conn->sconn.s_flags))
+                {
+                  return -EISCONN;
+                }
 
-      conn->recvsize = *(FAR const int *)value;
-      return OK;
+              conn->recvsize = *(FAR const int *)value;
+              return OK;
+            }
+
+          case SO_PRIORITY:
+            {
+              int priority;
+
+              if (value == NULL || value_len == 0)
+                {
+                  return -EINVAL;
+                }
+
+              if (_SS_ISCONNECTED(conn->sconn.s_flags))
+                {
+                  return -EISCONN;
+                }
+
+              /* SO_PRIORITY is an int in socket(7), but accept a smaller
+               * value as well so that a char or uint8_t argument also
+               * works.  Read only as many bytes as the caller supplied.
+               */
+
+              priority = (value_len >= sizeof(int)) ?
+                *(FAR const int *)value :
+                (int)*(FAR const unsigned char *)value;
+
+              if (priority < RPMSG_PRIO_MIN || priority > RPMSG_PRIO_MAX)
+                {
+                  return -EINVAL;
+                }
+
+              conn->priority = (uint8_t)priority;
+              return OK;
+            }
+        }
     }
 
   return -ENOPROTOOPT;

Reply via email to