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 244ec920f7a7c77834f74569cfcb3204898ea47c
Author: p-szafonimateusz <[email protected]>
AuthorDate: Mon Nov 9 11:51:11 2026 +0100

    net/can: Move can_sendmsg.c into can_raw.c.
    
    Move the code of can_sendmsg.c into can_raw.c without changes and remove
    can_sendmsg.c.  Only the include lists and the file guards are merged; the
    functions are copied as they are.
    
    Assisted-by: Claude:claude-opus-5-5
    Signed-off-by: p-szafonimateusz <[email protected]>
---
 .github/CODEOWNERS                        |   1 -
 Documentation/os/networking/socketcan.rst |   3 +-
 net/can/CMakeLists.txt                    |   2 -
 net/can/Make.defs                         |   2 -
 net/can/can_raw.c                         | 341 +++++++++++++++++++++++++
 net/can/can_sendmsg.c                     | 402 ------------------------------
 6 files changed, 342 insertions(+), 409 deletions(-)

diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 84e158695d4..56b7e93266d 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -15894,7 +15894,6 @@ net/can/can.c [email protected] 
[email protected] [email protected] anchao
 net/can/can.h [email protected] [email protected] 
[email protected] [email protected] [email protected]
 net/can/can_getsockopt.c [email protected] [email protected] 
[email protected] [email protected] [email protected]
 net/can/can_raw.c [email protected] [email protected] 
[email protected] [email protected] [email protected]
-net/can/can_sendmsg.c [email protected] [email protected] 
[email protected] [email protected] [email protected]
 net/can/can_setsockopt.c [email protected] [email protected] 
[email protected] [email protected] [email protected]
 net/devif/devif.h [email protected] [email protected] 
[email protected] [email protected]
 net/devif/devif_callback.c [email protected] [email protected] 
[email protected] [email protected]
diff --git a/Documentation/os/networking/socketcan.rst 
b/Documentation/os/networking/socketcan.rst
index 9cf1e0008ea..fadfdbd1a93 100644
--- a/Documentation/os/networking/socketcan.rst
+++ b/Documentation/os/networking/socketcan.rst
@@ -93,8 +93,7 @@ Files supporting SocketCAN can be found in the following 
locations:
 -  **Main Modules**:
 
    - ``can.c`` - Connection management, input, callbacks and polling
-   - ``can_raw.c`` - Socket interface and message reception
-   - ``can_sendmsg.c`` - Message transmission
+   - ``can_raw.c`` - Socket interface, message transmission and reception
    - ``can_sendmsg_buffered.c`` - Message transmission with buffering
 
 Configuration Options
diff --git a/net/can/CMakeLists.txt b/net/can/CMakeLists.txt
index e89495f1eb6..0344d890b3c 100644
--- a/net/can/CMakeLists.txt
+++ b/net/can/CMakeLists.txt
@@ -27,8 +27,6 @@ if(CONFIG_NET_CAN)
 
   if(CONFIG_NET_CAN_WRITE_BUFFERS)
     list(APPEND SRCS can_sendmsg_buffered.c)
-  else()
-    list(APPEND SRCS can_sendmsg.c)
   endif()
 
   if(CONFIG_NET_CANPROTO_OPTIONS)
diff --git a/net/can/Make.defs b/net/can/Make.defs
index fa55c9bb002..9dfdd90bf17 100644
--- a/net/can/Make.defs
+++ b/net/can/Make.defs
@@ -29,8 +29,6 @@ ifeq ($(CONFIG_NET_CAN),y)
 SOCK_CSRCS += can_raw.c
 ifeq ($(CONFIG_NET_CAN_WRITE_BUFFERS),y)
 SOCK_CSRCS += can_sendmsg_buffered.c
-else
-SOCK_CSRCS += can_sendmsg.c
 endif
 
 ifeq ($(CONFIG_NET_CANPROTO_OPTIONS),y)
diff --git a/net/can/can_raw.c b/net/can/can_raw.c
index e852dbdf820..e92b09c4f70 100644
--- a/net/can/can_raw.c
+++ b/net/can/can_raw.c
@@ -45,6 +45,7 @@
 #include <netpacket/packet.h>
 #include <nuttx/debug.h>
 #include <nuttx/kmalloc.h>
+#include <nuttx/net/ip.h>
 #include <nuttx/net/net.h>
 #include <nuttx/net/netdev.h>
 #include <nuttx/net/netstats.h>
@@ -62,6 +63,24 @@
  * Private Types
  ****************************************************************************/
 
+#ifndef CONFIG_NET_CAN_WRITE_BUFFERS
+/* This structure holds the state of the send operation until it can be
+ * operated upon by the event handler.
+ */
+
+struct send_s
+{
+  FAR struct devif_callback_s *snd_cb; /* Reference to callback instance */
+  FAR struct can_conn_s  *snd_conn;    /* Reference to the CAN connection */
+  sem_t                   snd_sem;     /* Used to wake up the waiting thread */
+  FAR const uint8_t      *snd_buffer;  /* Points to the buffer of data to send 
*/
+  size_t                  snd_buflen;  /* Number of bytes in the buffer to 
send */
+  size_t                  pr_msglen;   /* Length of msg buffer */
+  FAR uint8_t            *pr_msgbuf;   /* Pointer to msg buffer */
+  ssize_t                 snd_sent;    /* The number of bytes sent */
+};
+#endif
+
 struct can_recvfrom_s
 {
   FAR struct can_conn_s *pr_conn;      /* Connection associated with the 
socket */
@@ -590,6 +609,328 @@ errout_with_state:
   return ret;
 }
 
+#ifndef CONFIG_NET_CAN_WRITE_BUFFERS
+/****************************************************************************
+ * Name: psock_send_eventhandler
+ ****************************************************************************/
+
+static uint32_t psock_send_eventhandler(FAR struct net_driver_s *dev,
+                                        FAR void *pvpriv, uint32_t flags)
+{
+  FAR struct send_s *pstate = pvpriv;
+
+  if (pstate)
+    {
+      /* Check if the outgoing packet is available. It may have been claimed
+       * by a send event handler serving a different thread -OR- if the
+       * output buffer currently contains unprocessed incoming data. In
+       * these cases we will just have to wait for the next polling cycle.
+       */
+
+      if (dev->d_sndlen > 0 || (flags & CAN_NEWDATA) != 0)
+        {
+          /* Another thread has beat us sending data or the buffer is busy,
+           * Check for a timeout. If not timed out, wait for the next
+           * polling cycle and check again.
+           */
+
+          /* No timeout. Just wait for the next polling cycle */
+
+          return flags;
+        }
+
+      /* It looks like we are good to send the data */
+
+      else
+        {
+          /* Copy the packet data into the device packet buffer and send it */
+
+          int ret;
+
+          ret = devif_send(dev, pstate->snd_buffer,
+                           pstate->snd_buflen + pstate->pr_msglen, 0);
+          dev->d_len = dev->d_sndlen - pstate->pr_msglen;
+          if (ret <= 0)
+            {
+              pstate->snd_sent = ret;
+              goto end_wait;
+            }
+
+          dev->d_iob->io_conn = &pstate->snd_conn->sconn;
+
+          pstate->snd_sent = pstate->snd_buflen;
+          if (pstate->pr_msglen > 0) /* concat cmsg data after packet */
+            {
+              memcpy(dev->d_buf + pstate->snd_buflen, pstate->pr_msgbuf,
+                     pstate->pr_msglen);
+            }
+        }
+
+end_wait:
+
+      /* Don't allow any further call backs. */
+
+      pstate->snd_cb->flags = 0;
+      pstate->snd_cb->priv  = NULL;
+      pstate->snd_cb->event = NULL;
+
+      /* Wake up the waiting thread */
+
+      nxsem_post(&pstate->snd_sem);
+    }
+
+  return flags;
+}
+
+/****************************************************************************
+ * Name: can_sendmsg
+ *
+ * Description:
+ *   The can_sendmsg() call may be used only when the packet socket is
+ *   in a connected state (so that the intended recipient is known).
+ *
+ * Input Parameters:
+ *   psock    An instance of the internal socket structure.
+ *   msg      CAN frame and optional CMSG
+ *   flags    Send flags (ignored)
+ *
+ * Returned Value:
+ *   On success, returns the number of characters sent.  On  error,
+ *   a negated errno value is retruend.  See sendmsg() for the complete list
+ *   of return values.
+ *
+ ****************************************************************************/
+
+ssize_t can_sendmsg(FAR struct socket *psock, FAR const struct msghdr *msg,
+                    int flags)
+{
+  FAR struct net_driver_s *dev;
+  FAR struct can_conn_s *conn;
+  struct send_s state;
+  size_t total_len = 0;
+  size_t i;
+  int ret = OK;
+#if defined(CONFIG_NET_CANPROTO_OPTIONS) && defined(CONFIG_NET_CAN_CANFD)
+  uint8_t buf[CANFD_MTU];
+#else
+  uint8_t buf[CAN_MTU];
+#endif
+
+  /* Verify that the sockfd corresponds to valid, allocated socket */
+
+  if (psock == NULL || psock->s_conn == NULL)
+    {
+      return -EBADF;
+    }
+
+  /* Only SOCK_RAW is supported */
+
+  if (psock->s_type != SOCK_RAW)
+    {
+      /* EDESTADDRREQ.  Signifies that the socket is not connection-mode and
+       * no peer address is set.
+       */
+
+      return -EDESTADDRREQ;
+    }
+
+  conn = psock->s_conn;
+
+  /* Get the device driver that will service this transfer */
+
+  dev = conn->dev;
+  if (dev == NULL)
+    {
+      return -ENODEV;
+    }
+
+  if (msg->msg_iovlen == 0)
+    {
+      return -EMSGSIZE;
+    }
+
+  for (i = 0; i < msg->msg_iovlen; i++)
+    {
+      if (msg->msg_iov[i].iov_len > sizeof(buf) - total_len)
+        {
+          return -EINVAL;
+        }
+
+      if (msg->msg_iov[i].iov_len > 0 && msg->msg_iov[i].iov_base == NULL)
+        {
+          return -EINVAL;
+        }
+
+      total_len += msg->msg_iov[i].iov_len;
+    }
+
+#if defined(CONFIG_NET_CANPROTO_OPTIONS) && defined(CONFIG_NET_CAN_CANFD)
+  if (_SO_GETOPT(conn->sconn.s_options, CAN_RAW_FD_FRAMES))
+    {
+      if (total_len != CANFD_MTU && total_len != CAN_MTU)
+        {
+          return -EINVAL;
+        }
+    }
+  else
+#endif
+    {
+      if (total_len != CAN_MTU)
+        {
+          return -EINVAL;
+        }
+    }
+
+  if (msg->msg_iovlen > 1)
+    {
+      size_t offset = 0;
+
+      for (i = 0; i < msg->msg_iovlen; i++)
+        {
+          if (msg->msg_iov[i].iov_len > 0)
+            {
+              memcpy(buf + offset, msg->msg_iov[i].iov_base,
+                     msg->msg_iov[i].iov_len);
+              offset += msg->msg_iov[i].iov_len;
+            }
+        }
+    }
+
+  /* Perform the send operation */
+
+  /* Initialize the state structure. This is done with the network locked
+   * because we don't want anything to happen until we are ready.
+   */
+
+  conn_dev_lock(&conn->sconn, dev);
+  memset(&state, 0, sizeof(struct send_s));
+  nxsem_init(&state.snd_sem, 0, 0); /* Doesn't really fail */
+
+  state.snd_buflen = total_len;
+  state.snd_buffer = (msg->msg_iovlen == 1) ? msg->msg_iov[0].iov_base : buf;
+  state.snd_conn   = conn;
+
+#ifdef CONFIG_NET_CAN_RAW_TX_DEADLINE
+  if (msg->msg_controllen > sizeof(struct cmsghdr))
+    {
+      FAR struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);
+
+      if (_SO_GETOPT(conn->sconn.s_options, CAN_RAW_TX_DEADLINE) &&
+          cmsg->cmsg_level == SOL_CAN_RAW &&
+          cmsg->cmsg_type == CAN_RAW_TX_DEADLINE &&
+          cmsg->cmsg_len == sizeof(struct timeval))
+        {
+          state.pr_msgbuf = CMSG_DATA(cmsg); /* Buffer to cmsg data */
+          state.pr_msglen = cmsg->cmsg_len;  /* len of cmsg data */
+        }
+    }
+#endif
+
+  /* Allocate resource to receive a callback */
+
+  state.snd_cb = can_callback_alloc(dev, conn);
+  if (state.snd_cb)
+    {
+      /* Set up the callback in the connection */
+
+      state.snd_cb->flags = CAN_POLL;
+      state.snd_cb->priv  = (FAR void *)&state;
+      state.snd_cb->event = psock_send_eventhandler;
+
+      /* Notify the device driver that new TX data is available. */
+
+      netdev_txnotify_dev(dev, CAN_POLL);
+
+      /* Wait for the send to complete or an error to occur.
+       * conn_dev_sem_timedwait will also terminate if a signal is received.
+       */
+
+      if (_SS_ISNONBLOCK(conn->sconn.s_flags) || (flags & MSG_DONTWAIT) != 0)
+        {
+          ret = conn_dev_sem_timedwait(&state.snd_sem, true, 0,
+                                       &conn->sconn, dev);
+        }
+      else
+        {
+          ret = conn_dev_sem_timedwait(&state.snd_sem, true, UINT_MAX,
+                                       &conn->sconn, dev);
+        }
+
+      /* Make sure that no further events are processed */
+
+      can_callback_free(dev, conn, state.snd_cb);
+    }
+
+  nxsem_destroy(&state.snd_sem);
+  conn_dev_unlock(&conn->sconn, dev);
+
+  /* Check for a errors, Errors are signalled by negative errno values
+   * for the send length
+   */
+
+  if (state.snd_sent < 0)
+    {
+      return state.snd_sent;
+    }
+
+  /* If conn_dev_sem_timedwait failed, then we were probably reawakened by
+   * a signal. In this case, conn_dev_sem_timedwait will have returned
+   * negated errno appropriately.
+   */
+
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+#ifdef CONFIG_NET_STATISTICS
+  g_netstats.can.sent++;
+#endif
+
+  /* Return the number of bytes actually sent */
+
+  return state.snd_sent;
+}
+
+/****************************************************************************
+ * Name: psock_can_cansend
+ *
+ * Description:
+ *   psock_can_cansend() returns a value indicating if a write to the socket
+ *   would block.  No space in the buffer is actually reserved, so it is
+ *   possible that the write may still block if the buffer is filled by
+ *   another means.
+ *
+ * Input Parameters:
+ *   psock    An instance of the internal socket structure.
+ *
+ * Returned Value:
+ *   OK
+ *     At least one byte of data could be successfully written.
+ *   -EWOULDBLOCK
+ *     There is no room in the output buffer.
+ *   -EBADF
+ *     An invalid descriptor was specified.
+ *
+ ****************************************************************************/
+
+int psock_can_cansend(FAR struct socket *psock)
+{
+  /* Verify that we received a valid socket */
+
+  if (psock == NULL || psock->s_conn == NULL)
+    {
+      nerr("ERROR: Invalid socket\n");
+      return -EBADF;
+    }
+
+  /* TODO Query CAN driver mailboxes to see if there's mailbox available */
+
+  return OK;
+}
+
+#endif
+
 /****************************************************************************
  * Name: can_poll_eventhandler
  *
diff --git a/net/can/can_sendmsg.c b/net/can/can_sendmsg.c
deleted file mode 100644
index 58008fefcf0..00000000000
--- a/net/can/can_sendmsg.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/****************************************************************************
- * net/can/can_sendmsg.c
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.  The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-#if defined(CONFIG_NET) && defined(CONFIG_NET_CAN)
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include <errno.h>
-#include <nuttx/debug.h>
-
-#include <arch/irq.h>
-
-#include <nuttx/semaphore.h>
-#include <nuttx/net/netdev.h>
-#include <nuttx/net/net.h>
-#include <nuttx/net/ip.h>
-#include <nuttx/net/netstats.h>
-
-#include "netdev/netdev.h"
-#include "devif/devif.h"
-#include "socket/socket.h"
-#include "utils/utils.h"
-#include "can/can.h"
-
-#include <sys/time.h>
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* This structure holds the state of the send operation until it can be
- * operated upon by the event handler.
- */
-
-struct send_s
-{
-  FAR struct devif_callback_s *snd_cb; /* Reference to callback instance */
-  FAR struct can_conn_s  *snd_conn;    /* Reference to the CAN connection */
-  sem_t                   snd_sem;     /* Used to wake up the waiting thread */
-  FAR const uint8_t      *snd_buffer;  /* Points to the buffer of data to send 
*/
-  size_t                  snd_buflen;  /* Number of bytes in the buffer to 
send */
-  size_t                  pr_msglen;   /* Length of msg buffer */
-  FAR uint8_t            *pr_msgbuf;   /* Pointer to msg buffer */
-  ssize_t                 snd_sent;    /* The number of bytes sent */
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: psock_send_eventhandler
- ****************************************************************************/
-
-static uint32_t psock_send_eventhandler(FAR struct net_driver_s *dev,
-                                        FAR void *pvpriv, uint32_t flags)
-{
-  FAR struct send_s *pstate = pvpriv;
-
-  if (pstate)
-    {
-      /* Check if the outgoing packet is available. It may have been claimed
-       * by a send event handler serving a different thread -OR- if the
-       * output buffer currently contains unprocessed incoming data. In
-       * these cases we will just have to wait for the next polling cycle.
-       */
-
-      if (dev->d_sndlen > 0 || (flags & CAN_NEWDATA) != 0)
-        {
-          /* Another thread has beat us sending data or the buffer is busy,
-           * Check for a timeout. If not timed out, wait for the next
-           * polling cycle and check again.
-           */
-
-          /* No timeout. Just wait for the next polling cycle */
-
-          return flags;
-        }
-
-      /* It looks like we are good to send the data */
-
-      else
-        {
-          /* Copy the packet data into the device packet buffer and send it */
-
-          int ret;
-
-          ret = devif_send(dev, pstate->snd_buffer,
-                           pstate->snd_buflen + pstate->pr_msglen, 0);
-          dev->d_len = dev->d_sndlen - pstate->pr_msglen;
-          if (ret <= 0)
-            {
-              pstate->snd_sent = ret;
-              goto end_wait;
-            }
-
-          dev->d_iob->io_conn = &pstate->snd_conn->sconn;
-
-          pstate->snd_sent = pstate->snd_buflen;
-          if (pstate->pr_msglen > 0) /* concat cmsg data after packet */
-            {
-              memcpy(dev->d_buf + pstate->snd_buflen, pstate->pr_msgbuf,
-                     pstate->pr_msglen);
-            }
-        }
-
-end_wait:
-
-      /* Don't allow any further call backs. */
-
-      pstate->snd_cb->flags = 0;
-      pstate->snd_cb->priv  = NULL;
-      pstate->snd_cb->event = NULL;
-
-      /* Wake up the waiting thread */
-
-      nxsem_post(&pstate->snd_sem);
-    }
-
-  return flags;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: can_sendmsg
- *
- * Description:
- *   The can_sendmsg() call may be used only when the packet socket is
- *   in a connected state (so that the intended recipient is known).
- *
- * Input Parameters:
- *   psock    An instance of the internal socket structure.
- *   msg      CAN frame and optional CMSG
- *   flags    Send flags (ignored)
- *
- * Returned Value:
- *   On success, returns the number of characters sent.  On  error,
- *   a negated errno value is retruend.  See sendmsg() for the complete list
- *   of return values.
- *
- ****************************************************************************/
-
-ssize_t can_sendmsg(FAR struct socket *psock, FAR const struct msghdr *msg,
-                    int flags)
-{
-  FAR struct net_driver_s *dev;
-  FAR struct can_conn_s *conn;
-  struct send_s state;
-  size_t total_len = 0;
-  size_t i;
-  int ret = OK;
-#if defined(CONFIG_NET_CANPROTO_OPTIONS) && defined(CONFIG_NET_CAN_CANFD)
-  uint8_t buf[CANFD_MTU];
-#else
-  uint8_t buf[CAN_MTU];
-#endif
-
-  /* Verify that the sockfd corresponds to valid, allocated socket */
-
-  if (psock == NULL || psock->s_conn == NULL)
-    {
-      return -EBADF;
-    }
-
-  /* Only SOCK_RAW is supported */
-
-  if (psock->s_type != SOCK_RAW)
-    {
-      /* EDESTADDRREQ.  Signifies that the socket is not connection-mode and
-       * no peer address is set.
-       */
-
-      return -EDESTADDRREQ;
-    }
-
-  conn = psock->s_conn;
-
-  /* Get the device driver that will service this transfer */
-
-  dev = conn->dev;
-  if (dev == NULL)
-    {
-      return -ENODEV;
-    }
-
-  if (msg->msg_iovlen == 0)
-    {
-      return -EMSGSIZE;
-    }
-
-  for (i = 0; i < msg->msg_iovlen; i++)
-    {
-      if (msg->msg_iov[i].iov_len > sizeof(buf) - total_len)
-        {
-          return -EINVAL;
-        }
-
-      if (msg->msg_iov[i].iov_len > 0 && msg->msg_iov[i].iov_base == NULL)
-        {
-          return -EINVAL;
-        }
-
-      total_len += msg->msg_iov[i].iov_len;
-    }
-
-#if defined(CONFIG_NET_CANPROTO_OPTIONS) && defined(CONFIG_NET_CAN_CANFD)
-  if (_SO_GETOPT(conn->sconn.s_options, CAN_RAW_FD_FRAMES))
-    {
-      if (total_len != CANFD_MTU && total_len != CAN_MTU)
-        {
-          return -EINVAL;
-        }
-    }
-  else
-#endif
-    {
-      if (total_len != CAN_MTU)
-        {
-          return -EINVAL;
-        }
-    }
-
-  if (msg->msg_iovlen > 1)
-    {
-      size_t offset = 0;
-
-      for (i = 0; i < msg->msg_iovlen; i++)
-        {
-          if (msg->msg_iov[i].iov_len > 0)
-            {
-              memcpy(buf + offset, msg->msg_iov[i].iov_base,
-                     msg->msg_iov[i].iov_len);
-              offset += msg->msg_iov[i].iov_len;
-            }
-        }
-    }
-
-  /* Perform the send operation */
-
-  /* Initialize the state structure. This is done with the network locked
-   * because we don't want anything to happen until we are ready.
-   */
-
-  conn_dev_lock(&conn->sconn, dev);
-  memset(&state, 0, sizeof(struct send_s));
-  nxsem_init(&state.snd_sem, 0, 0); /* Doesn't really fail */
-
-  state.snd_buflen = total_len;
-  state.snd_buffer = (msg->msg_iovlen == 1) ? msg->msg_iov[0].iov_base : buf;
-  state.snd_conn   = conn;
-
-#ifdef CONFIG_NET_CAN_RAW_TX_DEADLINE
-  if (msg->msg_controllen > sizeof(struct cmsghdr))
-    {
-      FAR struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);
-
-      if (_SO_GETOPT(conn->sconn.s_options, CAN_RAW_TX_DEADLINE) &&
-          cmsg->cmsg_level == SOL_CAN_RAW &&
-          cmsg->cmsg_type == CAN_RAW_TX_DEADLINE &&
-          cmsg->cmsg_len == sizeof(struct timeval))
-        {
-          state.pr_msgbuf = CMSG_DATA(cmsg); /* Buffer to cmsg data */
-          state.pr_msglen = cmsg->cmsg_len;  /* len of cmsg data */
-        }
-    }
-#endif
-
-  /* Allocate resource to receive a callback */
-
-  state.snd_cb = can_callback_alloc(dev, conn);
-  if (state.snd_cb)
-    {
-      /* Set up the callback in the connection */
-
-      state.snd_cb->flags = CAN_POLL;
-      state.snd_cb->priv  = (FAR void *)&state;
-      state.snd_cb->event = psock_send_eventhandler;
-
-      /* Notify the device driver that new TX data is available. */
-
-      netdev_txnotify_dev(dev, CAN_POLL);
-
-      /* Wait for the send to complete or an error to occur.
-       * conn_dev_sem_timedwait will also terminate if a signal is received.
-       */
-
-      if (_SS_ISNONBLOCK(conn->sconn.s_flags) || (flags & MSG_DONTWAIT) != 0)
-        {
-          ret = conn_dev_sem_timedwait(&state.snd_sem, true, 0,
-                                       &conn->sconn, dev);
-        }
-      else
-        {
-          ret = conn_dev_sem_timedwait(&state.snd_sem, true, UINT_MAX,
-                                       &conn->sconn, dev);
-        }
-
-      /* Make sure that no further events are processed */
-
-      can_callback_free(dev, conn, state.snd_cb);
-    }
-
-  nxsem_destroy(&state.snd_sem);
-  conn_dev_unlock(&conn->sconn, dev);
-
-  /* Check for a errors, Errors are signalled by negative errno values
-   * for the send length
-   */
-
-  if (state.snd_sent < 0)
-    {
-      return state.snd_sent;
-    }
-
-  /* If conn_dev_sem_timedwait failed, then we were probably reawakened by
-   * a signal. In this case, conn_dev_sem_timedwait will have returned
-   * negated errno appropriately.
-   */
-
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-#ifdef CONFIG_NET_STATISTICS
-  g_netstats.can.sent++;
-#endif
-
-  /* Return the number of bytes actually sent */
-
-  return state.snd_sent;
-}
-
-/****************************************************************************
- * Name: psock_can_cansend
- *
- * Description:
- *   psock_can_cansend() returns a value indicating if a write to the socket
- *   would block.  No space in the buffer is actually reserved, so it is
- *   possible that the write may still block if the buffer is filled by
- *   another means.
- *
- * Input Parameters:
- *   psock    An instance of the internal socket structure.
- *
- * Returned Value:
- *   OK
- *     At least one byte of data could be successfully written.
- *   -EWOULDBLOCK
- *     There is no room in the output buffer.
- *   -EBADF
- *     An invalid descriptor was specified.
- *
- ****************************************************************************/
-
-int psock_can_cansend(FAR struct socket *psock)
-{
-  /* Verify that we received a valid socket */
-
-  if (psock == NULL || psock->s_conn == NULL)
-    {
-      nerr("ERROR: Invalid socket\n");
-      return -EBADF;
-    }
-
-  /* TODO Query CAN driver mailboxes to see if there's mailbox available */
-
-  return OK;
-}
-
-#endif /* CONFIG_NET && CONFIG_NET_CAN */

Reply via email to