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 2023/01/10 10:08:28 UTC
[nuttx] branch master updated: wireless/bluetooth: add interrupt_context hander for netsnoop
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
The following commit(s) were added to refs/heads/master by this push:
new f864e5f657 wireless/bluetooth: add interrupt_context hander for netsnoop
f864e5f657 is described below
commit f864e5f6577b349396eb586a80d35e2c87a2c7ae
Author: chengkai <ch...@xiaomi.com>
AuthorDate: Sun Sep 4 18:26:59 2022 +0800
wireless/bluetooth: add interrupt_context hander for netsnoop
Signed-off-by: chengkai <ch...@xiaomi.com>
---
drivers/wireless/bluetooth/bt_bridge.c | 7 +-
include/nuttx/net/snoop.h | 55 ++++++-
net/utils/Kconfig | 4 +
net/utils/net_snoop.c | 275 +++++++++++++++++++++++++--------
4 files changed, 265 insertions(+), 76 deletions(-)
diff --git a/drivers/wireless/bluetooth/bt_bridge.c b/drivers/wireless/bluetooth/bt_bridge.c
index 9ef41c06b4..b28138ecde 100644
--- a/drivers/wireless/bluetooth/bt_bridge.c
+++ b/drivers/wireless/bluetooth/bt_bridge.c
@@ -424,17 +424,14 @@ static int bt_bridge_send(FAR struct bt_driver_s *drv,
flags = enter_critical_section();
if (bt_filter_can_send(&device->filter, type, data, len))
{
- int ret;
-
leave_critical_section(flags);
- ret = driver->send(driver, type, data, len);
-
#ifdef CONFIG_BLUETOOTH_BRIDGE_BTSNOOP
snoop_dump(bridge->snoop, data - drv->head_reserve,
len + drv->head_reserve, 0,
SNOOP_DIRECTION_FLAG_SENT);
#endif /* CONFIG_BLUETOOTH_BRIDGE_BTSNOOP */
- return ret;
+
+ return driver->send(driver, type, data, len);
}
leave_critical_section(flags);
diff --git a/include/nuttx/net/snoop.h b/include/nuttx/net/snoop.h
index b234032ffb..a8aa0165d0 100644
--- a/include/nuttx/net/snoop.h
+++ b/include/nuttx/net/snoop.h
@@ -27,6 +27,9 @@
#include <stdint.h>
+#include <nuttx/mutex.h>
+#include <nuttx/wqueue.h>
+
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@@ -81,11 +84,18 @@
#define SNOOP_DIRECTION_FLAG_SENT 0 /* Direction flag 0 = Sent */
#define SNOOP_DIRECTION_FLAG_RECV 1 /* Direction flag 1 = Received */
+#ifndef CONFIG_NET_SNOOP_BUFSIZE
+# define CONFIG_NET_SNOOP_BUFSIZE 4096
+#endif
struct snoop_s
{
- bool autosync;
- uint32_t datalink;
- struct file filep;
+ bool autosync;
+ uint32_t datalink;
+ struct file filep;
+ mutex_t mutex;
+ struct work_s work;
+ uint8_t buf[CONFIG_NET_SNOOP_BUFSIZE];
+ size_t next;
};
/****************************************************************************
@@ -106,6 +116,17 @@ extern "C"
* Description:
* This function open snoop file by datalink.
*
+ * Input Parameters:
+ * snoop The snoop driver struct
+ * filename Snoop file name
+ * datalink Snoop datalink type, such as SNOOP_DATALINK_TYPE_XX
+ * autosync whether do file_sync when snoop_dump
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
****************************************************************************/
int snoop_open(FAR struct snoop_s *snoop, FAR const char *filename,
@@ -117,6 +138,18 @@ int snoop_open(FAR struct snoop_s *snoop, FAR const char *filename,
* Description:
* This function dump nbytes buf data into snoop file.
*
+ * Input Parameters:
+ * snoop The snoop driver struct
+ * buf Snoop buffer
+ * nbytes Snoop buffer size
+ * drops cumulative number of dropped packets
+ * flags Packet Flags: 1 hci cmd , eg: btsnoop
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
****************************************************************************/
int snoop_dump(FAR struct snoop_s *snoop, FAR const void *buf,
@@ -128,6 +161,14 @@ int snoop_dump(FAR struct snoop_s *snoop, FAR const void *buf,
* Description:
* This function sync snoop buffer.
*
+ * Input Parameters:
+ * snoop The snoop driver struct
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
****************************************************************************/
int snoop_sync(FAR struct snoop_s *snoop);
@@ -138,6 +179,14 @@ int snoop_sync(FAR struct snoop_s *snoop);
* Description:
* This function close snoop file.
*
+ * Input Parameters:
+ * snoop The snoop driver struct
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
****************************************************************************/
int snoop_close(FAR struct snoop_s *snoop);
diff --git a/net/utils/Kconfig b/net/utils/Kconfig
index b8d1a0484c..6e55134dd9 100644
--- a/net/utils/Kconfig
+++ b/net/utils/Kconfig
@@ -24,3 +24,7 @@ config NET_ARCH_CHKSUM
uint16_t ipv4_chksum(FAR struct ipv4_hdr_s *ipv4)
uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto)
uint16_t ipv6_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto, unsigned int iplen)
+
+config NET_SNOOP_BUFSIZE
+ int "Snoop buffer size for interrupt"
+ default 4096
diff --git a/net/utils/net_snoop.c b/net/utils/net_snoop.c
index 75caa9c1d0..6e1541c0a4 100644
--- a/net/utils/net_snoop.c
+++ b/net/utils/net_snoop.c
@@ -161,76 +161,128 @@ begin_packed_struct struct snoop_packet_header_s
****************************************************************************/
/****************************************************************************
- * Name: snoop_dump_packet_header
+ * Name: snoop_fill_packet_header
*
* Description:
- * This function fill snoop headr info.
+ * This function fill snoop packet header info.
*
****************************************************************************/
-static int snoop_dump_packet_header(FAR struct snoop_s *snoop,
- uint32_t bytes, uint32_t drops,
- uint32_t flags)
+static void snoop_fill_packet_header(FAR struct snoop_s *snoop,
+ uint32_t bytes, uint32_t drops,
+ uint32_t flags, FAR struct
+ snoop_packet_header_s *header)
{
- struct snoop_packet_header_s header;
- int ret;
-
- if (!snoop)
- {
- return -EINVAL;
- }
+ struct timeval tv;
switch (snoop->datalink)
{
- case SNOOP_DATALINK_HCI_UNENCAP:
- case SNOOP_DATALINK_HCI_UART:
- case SNOOP_DATALINK_HCI_BSCP:
- case SNOOP_DATALINK_HCI_SERIAL:
- {
- struct timeval tv;
-
+ case SNOOP_DATALINK_HCI_UNENCAP:
+ case SNOOP_DATALINK_HCI_UART:
+ case SNOOP_DATALINK_HCI_BSCP:
+ case SNOOP_DATALINK_HCI_SERIAL:
gettimeofday(&tv, NULL);
- header.ts_usec = htobe64(SNOOP_EPOCH_USEC(tv));
- header.flags = htobe32(flags);
+ header->ts_usec = htobe64(SNOOP_EPOCH_USEC(tv));
+ header->flags = htobe32(flags);
break;
- }
-
- case SNOOP_DATALINK_TYPE_TOKENBUS:
- case SNOOP_DATALINK_TYPE_TOKERING:
- case SNOOP_DATALINK_TYPE_METRONET:
- case SNOOP_DATALINK_TYPE_ETHERNET:
- case SNOOP_DATALINK_TYPE_HDLC:
- case SNOOP_DATALINK_TYPE_CHARSYNC:
- case SNOOP_DATALINK_TYPE_IBMC2C:
- case SNOOP_DATALINK_TYPE_FDDI:
- case SNOOP_DATALINK_TYPE_OTHER:
- {
- struct timeval tv;
+ case SNOOP_DATALINK_TYPE_TOKENBUS:
+ case SNOOP_DATALINK_TYPE_TOKERING:
+ case SNOOP_DATALINK_TYPE_METRONET:
+ case SNOOP_DATALINK_TYPE_ETHERNET:
+ case SNOOP_DATALINK_TYPE_HDLC:
+ case SNOOP_DATALINK_TYPE_CHARSYNC:
+ case SNOOP_DATALINK_TYPE_IBMC2C:
+ case SNOOP_DATALINK_TYPE_FDDI:
+ case SNOOP_DATALINK_TYPE_OTHER:
gettimeofday(&tv, NULL);
- header.ts.ts_sec = htobe32(tv.tv_sec);
- header.ts.ts_usec = htobe32(tv.tv_usec);
- header.rec_len = htobe32(flags);
+ header->ts.ts_sec = htobe32(tv.tv_sec);
+ header->ts.ts_usec = htobe32(tv.tv_usec);
+ header->rec_len = htobe32(flags);
break;
- }
- default:
- {
- return -EINVAL;
- }
+ default:
+ DEBUGASSERT(false);
}
- header.orig_len = htobe32(bytes);
- header.incl_len = htobe32(bytes);
- header.cum_drops = htobe32(drops);
+ header->orig_len = htobe32(bytes);
+ header->incl_len = htobe32(bytes);
+ header->cum_drops = htobe32(drops);
+}
- ret = file_write(&snoop->filep, &header, sizeof(header));
- if (ret != sizeof(header))
+/****************************************************************************
+ * Name: snoop_flush
+ *
+ * Description:
+ * This function could flush snoop buf into file.
+ *
+ ****************************************************************************/
+
+static int snoop_flush(FAR struct snoop_s *snoop)
+{
+ ssize_t ret;
+
+ if (snoop->next == 0)
{
- return ret < 0 ? ret : -EINVAL;
+ return 0;
}
- return OK;
+ do
+ {
+ ret = file_write(&snoop->filep, snoop->buf, snoop->next);
+ if (ret < 0)
+ {
+ break;
+ }
+
+ snoop->next -= ret;
+ memmove(snoop->buf, snoop->buf + ret, snoop->next);
+ }
+ while (snoop->next > 0);
+
+#ifndef CONFIG_DISABLE_MOUNTPOINT
+ if (snoop->autosync)
+ {
+ ret = file_fsync(&snoop->filep);
+ }
+#endif
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: snoop_flush_lock
+ *
+ * Description:
+ * Snoop flush atomic
+ *
+ ****************************************************************************/
+
+static int snoop_flush_lock(FAR struct snoop_s *snoop)
+{
+ irqstate_t flags;
+ int ret;
+
+ flags = enter_critical_section();
+ nxmutex_lock(&snoop->mutex);
+ ret = snoop_flush(snoop);
+ nxmutex_unlock(&snoop->mutex);
+ leave_critical_section(flags);
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: snoop_flush_work
+ *
+ * Description:
+ * Do snoop flush work.
+ *
+ ****************************************************************************/
+
+static void snoop_flush_work(FAR void *arg)
+{
+ snoop_flush_lock((FAR struct snoop_s *)arg);
}
/****************************************************************************
@@ -243,6 +295,17 @@ static int snoop_dump_packet_header(FAR struct snoop_s *snoop,
* Description:
* This function open snoop file by datalink.
*
+ * Input Parameters:
+ * snoop The snoop driver struct
+ * filename Snoop file name
+ * datalink Snoop datalink type, such as SNOOP_DATALINK_TYPE_XX
+ * autosync whether do file_sync when snoop_dump
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
****************************************************************************/
int snoop_open(FAR struct snoop_s *snoop, FAR const char *filename,
@@ -268,7 +331,7 @@ int snoop_open(FAR struct snoop_s *snoop, FAR const char *filename,
case SNOOP_DATALINK_TYPE_FDDI:
case SNOOP_DATALINK_TYPE_OTHER:
{
- uint8_t snoop_magic[] =
+ static const uint8_t snoop_magic[] =
{
's', 'n', 'o', 'o', 'p', '\0', '\0', '\0'
};
@@ -283,7 +346,7 @@ int snoop_open(FAR struct snoop_s *snoop, FAR const char *filename,
case SNOOP_DATALINK_HCI_BSCP:
case SNOOP_DATALINK_HCI_SERIAL:
{
- uint8_t btsnoop_magic[] =
+ static const uint8_t btsnoop_magic[] =
{
'b', 't', 's', 'n', 'o', 'o', 'p', '\0'
};
@@ -307,8 +370,9 @@ int snoop_open(FAR struct snoop_s *snoop, FAR const char *filename,
snoop->datalink = datalink;
snoop->autosync = autosync;
- header.datalink = htobe32(datalink);
+ snoop->next = 0;
+ header.datalink = htobe32(datalink);
ret = file_write(&snoop->filep, &header, sizeof(header));
if (ret != sizeof(header))
{
@@ -316,10 +380,11 @@ int snoop_open(FAR struct snoop_s *snoop, FAR const char *filename,
goto error;
}
+ nxmutex_init(&snoop->mutex);
return OK;
error:
- file_close(&snoop->filep);
+ snoop_close(snoop);
return ret;
}
@@ -329,31 +394,93 @@ error:
* Description:
* This function dump nbytes buf data into snoop file.
*
+ * Input Parameters:
+ * snoop The snoop driver struct
+ * buf Snoop buffer
+ * nbytes Snoop buffer size
+ * drops cumulative number of dropped packets
+ * flags Packet Flags: 1 hci cmd , eg: btsnoop
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
****************************************************************************/
int snoop_dump(FAR struct snoop_s *snoop, FAR const void *buf,
uint32_t nbytes, uint32_t drops, uint32_t flags)
{
- int ret;
+ struct snoop_packet_header_s header;
+ irqstate_t irqflags;
+ int ret = 0;
if (!snoop)
{
return -EINVAL;
}
- ret = snoop_dump_packet_header(snoop, nbytes, drops, flags);
- if (ret != OK)
+ snoop_fill_packet_header(snoop, nbytes, drops, flags, &header);
+
+ irqflags = enter_critical_section();
+ if (up_interrupt_context())
{
- return ret;
- }
+ if (sizeof(snoop->buf) - snoop->next <
+ nbytes + sizeof(struct snoop_packet_header_s))
+ {
+ ret = -ENOMEM;
+ goto out_leave;
+ }
- ret = file_write(&snoop->filep, buf, nbytes);
- if (ret != nbytes)
+ memcpy(snoop->buf + snoop->next, &header, sizeof(header));
+ snoop->next += sizeof(header);
+ memcpy(snoop->buf + snoop->next, buf, nbytes);
+ snoop->next += nbytes;
+
+ if (work_available(&snoop->work))
+ {
+ work_queue(HPWORK, &snoop->work, snoop_flush_work, snoop, 0);
+ }
+
+ goto out_leave;
+ }
+ else
{
- return ret < 0 ? ret : -EINVAL;
+ nxmutex_lock(&snoop->mutex);
+ ret = snoop_flush(snoop);
+ if (ret < 0)
+ {
+ goto out_unlock;
+ }
+
+ ret = file_write(&snoop->filep, &header, sizeof(header));
+ if (ret < 0)
+ {
+ goto out_unlock;
+ }
+ else if (ret != sizeof(header))
+ {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ ret = file_write(&snoop->filep, buf, nbytes);
+ if (ret < 0)
+ {
+ goto out_unlock;
+ }
+ else if (ret != nbytes)
+ {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
}
- return snoop->autosync ? snoop_sync(snoop) : OK;
+out_unlock:
+ nxmutex_unlock(&snoop->mutex);
+out_leave:
+ leave_critical_section(irqflags);
+ return ret;
}
/****************************************************************************
@@ -362,21 +489,24 @@ int snoop_dump(FAR struct snoop_s *snoop, FAR const void *buf,
* Description:
* This function sync snoop buffer.
*
+ * Input Parameters:
+ * snoop The snoop driver struct
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
****************************************************************************/
int snoop_sync(FAR struct snoop_s *snoop)
{
- int ret = OK;
-
if (!snoop)
{
return -EINVAL;
}
-#ifndef CONFIG_DISABLE_MOUNTPOINT
- ret = file_fsync(&snoop->filep);
-#endif
- return ret;
+ return snoop_flush_lock(snoop);
}
/****************************************************************************
@@ -385,6 +515,14 @@ int snoop_sync(FAR struct snoop_s *snoop)
* Description:
* This function close snoop file.
*
+ * Input Parameters:
+ * snoop The snoop driver struct
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
****************************************************************************/
int snoop_close(FAR struct snoop_s *snoop)
@@ -394,5 +532,6 @@ int snoop_close(FAR struct snoop_s *snoop)
return -EINVAL;
}
+ nxmutex_destroy(&snoop->mutex);
return file_close(&snoop->filep);
}