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/nuttx.git

commit 933841d9859ff1ebb7c6bf1063be1a6a1c554101
Author: chengkai <[email protected]>
AuthorDate: Fri Dec 15 20:48:00 2023 +0800

    bluetooth:support read imcompleted hci data from blueooth socket
    
    hci data from bluetooth socket maybe imcompleted hci data.
    
    Signed-off-by: chengkai <[email protected]>
---
 arch/sim/src/sim/sim_hcisocket.c | 94 +++++++++++++++++++++++++++++++---------
 1 file changed, 74 insertions(+), 20 deletions(-)

diff --git a/arch/sim/src/sim/sim_hcisocket.c b/arch/sim/src/sim/sim_hcisocket.c
index da05efb83f..0d36ef98b6 100644
--- a/arch/sim/src/sim/sim_hcisocket.c
+++ b/arch/sim/src/sim/sim_hcisocket.c
@@ -50,19 +50,29 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define SIM_BTHCI_RX_FRAMELEN 1024
+#define SIM_BTHCI_RX_FRAMELEN 2048
 #define SIM_BTHCI_WORK_DELAY  USEC2TICK(1000)
 
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
+union bt_hdr_u
+{
+  struct bt_hci_cmd_hdr_s cmd;
+  struct bt_hci_acl_hdr_s acl;
+  struct bt_hci_evt_hdr_s evt;
+  struct bt_hci_iso_hdr_s iso;
+};
 struct bthcisock_s
 {
   struct bt_driver_s drv;
   int                id;
   int                fd;
 
+  uint16_t           rxlen;
+  uint8_t            rxbuf[SIM_BTHCI_RX_FRAMELEN];
+
   /* Work queue for transmit */
 
   struct work_s      worker;
@@ -124,36 +134,80 @@ static void bthcisock_close(struct bt_driver_s *drv)
 static int bthcisock_receive(struct bt_driver_s *drv)
 {
   struct bthcisock_s *dev = (struct bthcisock_s *)drv;
-  char data[SIM_BTHCI_RX_FRAMELEN];
   enum bt_buf_type_e type;
+  union bt_hdr_u *hdr;
+  uint16_t pktlen;
   int ret;
 
-  ret = host_bthcisock_receive(dev->fd, data, sizeof(data));
+  ret = host_bthcisock_receive(dev->fd, &dev->rxbuf[dev->rxlen],
+                               sizeof(dev->rxbuf) - dev->rxlen);
   if (ret <= 0)
     {
       return ret;
     }
 
-  if (data[0] == H4_EVT)
-    {
-      type = BT_EVT;
-    }
-  else if (data[0] == H4_ACL)
-    {
-      type = BT_ACL_IN;
-    }
-  else if (data[0] == H4_ISO)
-    {
-      type = BT_ISO_IN;
-    }
-  else
+  dev->rxlen += ret;
+
+  while (dev->rxlen)
     {
-      return -EINVAL;
+      hdr = (union bt_hdr_u *)&dev->rxbuf[H4_HEADER_SIZE];
+      switch (dev->rxbuf[0])
+        {
+        case H4_EVT:
+          {
+            if (dev->rxlen < H4_HEADER_SIZE
+                + sizeof (struct bt_hci_evt_hdr_s))
+              {
+                return ret;
+              }
+
+            type = BT_EVT;
+            pktlen = H4_HEADER_SIZE + sizeof(struct bt_hci_evt_hdr_s)
+                     + hdr->evt.len;
+          }
+          break;
+        case H4_ACL:
+          {
+            if (dev->rxlen < H4_HEADER_SIZE
+                + sizeof(struct bt_hci_acl_hdr_s))
+              {
+                return ret;
+              }
+
+            type = BT_ACL_IN;
+            pktlen = H4_HEADER_SIZE + sizeof(struct bt_hci_acl_hdr_s)
+                     + hdr->acl.len;
+          }
+          break;
+        case H4_ISO:
+          {
+            if (dev->rxlen < H4_HEADER_SIZE
+                + sizeof(struct bt_hci_iso_hdr_s))
+              {
+                return ret;
+              }
+
+            type = BT_ISO_IN;
+            pktlen = H4_HEADER_SIZE + sizeof(struct bt_hci_iso_hdr_s)
+                     + hdr->iso.len;
+          }
+          break;
+        default:
+          return -EINVAL;
+        }
+
+      if (dev->rxlen < pktlen)
+        {
+          return ret;
+        }
+
+      bt_netdev_receive(&dev->drv, type, dev->rxbuf + H4_HEADER_SIZE,
+                        pktlen - H4_HEADER_SIZE);
+      dev->rxlen -= pktlen;
+      memmove(dev->rxbuf, dev->rxbuf + pktlen, dev->rxlen);
     }
 
-  return bt_netdev_receive(&dev->drv, type,
-                           data + H4_HEADER_SIZE,
-                           ret - H4_HEADER_SIZE);
+  return ret;
 }
 
 static int bthcisock_open(struct bt_driver_s *drv)

Reply via email to