bluetooth:support read imcompleted hci data from blueooth socket

hci data from bluetooth socket maybe imcompleted hci data.

Signed-off-by: chengkai <chengkai@xiaomi.com>
This commit is contained in:
chengkai 2023-12-15 20:48:00 +08:00 committed by Xiang Xiao
parent fee8b443dd
commit 933841d985

View file

@ -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)
dev->rxlen += ret;
while (dev->rxlen)
{
type = BT_EVT;
}
else if (data[0] == H4_ACL)
{
type = BT_ACL_IN;
}
else if (data[0] == H4_ISO)
{
type = BT_ISO_IN;
}
else
{
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)