Bluetooth: monitor: Add support for logging packet drops
The monitor protocol provides support for logging packet drops with the help of the extended monitor header. Implement support for this. Change-Id: I7ef7894816cb8d1bd876842d0253ef0980471e69 Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
1f5a809178
commit
46e649c536
2 changed files with 91 additions and 15 deletions
|
@ -37,6 +37,18 @@ enum {
|
|||
|
||||
static atomic_t flags;
|
||||
|
||||
static struct {
|
||||
atomic_t cmd;
|
||||
atomic_t evt;
|
||||
atomic_t acl_tx;
|
||||
atomic_t acl_rx;
|
||||
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||
atomic_t sco_tx;
|
||||
atomic_t sco_rx;
|
||||
#endif
|
||||
atomic_t other;
|
||||
} drops;
|
||||
|
||||
extern int _prf(int (*func)(), void *dest,
|
||||
const char *format, va_list vargs);
|
||||
|
||||
|
@ -49,20 +61,42 @@ static void monitor_send(const void *data, size_t len)
|
|||
}
|
||||
}
|
||||
|
||||
static void encode_drops(struct bt_monitor_hdr *hdr, uint8_t type,
|
||||
atomic_t *val)
|
||||
{
|
||||
atomic_val_t count;
|
||||
|
||||
count = atomic_set(val, 0);
|
||||
if (count) {
|
||||
hdr->ext[hdr->hdr_len++] = type;
|
||||
hdr->ext[hdr->hdr_len++] = min(count, 255);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void encode_hdr(struct bt_monitor_hdr *hdr, uint16_t opcode,
|
||||
uint16_t len)
|
||||
{
|
||||
uint32_t ts32;
|
||||
struct bt_monitor_ts32 *ts;
|
||||
|
||||
hdr->hdr_len = sizeof(hdr->type) + sizeof(hdr->ts32);
|
||||
hdr->data_len = sys_cpu_to_le16(4 + hdr->hdr_len + len);
|
||||
hdr->opcode = sys_cpu_to_le16(opcode);
|
||||
hdr->flags = 0;
|
||||
|
||||
/* Extended header */
|
||||
hdr->type = BT_MONITOR_TS32;
|
||||
ts32 = k_uptime_get() * 10;
|
||||
hdr->ts32 = sys_cpu_to_le32(ts32);
|
||||
ts = (void *)hdr->ext;
|
||||
ts->type = BT_MONITOR_TS32;
|
||||
ts->ts32 = sys_cpu_to_le32(k_uptime_get() * 10);
|
||||
hdr->hdr_len = sizeof(*ts);
|
||||
|
||||
encode_drops(hdr, BT_MONITOR_COMMAND_DROPS, &drops.cmd);
|
||||
encode_drops(hdr, BT_MONITOR_EVENT_DROPS, &drops.evt);
|
||||
encode_drops(hdr, BT_MONITOR_ACL_TX_DROPS, &drops.acl_tx);
|
||||
encode_drops(hdr, BT_MONITOR_ACL_RX_DROPS, &drops.acl_rx);
|
||||
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||
encode_drops(hdr, BT_MONITOR_SCO_TX_DROPS, &drops.sco_tx);
|
||||
encode_drops(hdr, BT_MONITOR_SCO_RX_DROPS, &drops.sco_rx);
|
||||
#endif
|
||||
encode_drops(hdr, BT_MONITOR_OTHER_DROPS, &drops.other);
|
||||
|
||||
hdr->data_len = sys_cpu_to_le16(4 + hdr->hdr_len + len);
|
||||
}
|
||||
|
||||
static int log_out(int c, void *unused)
|
||||
|
@ -71,6 +105,35 @@ static int log_out(int c, void *unused)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void drop_add(uint16_t opcode)
|
||||
{
|
||||
switch (opcode) {
|
||||
case BT_MONITOR_COMMAND_PKT:
|
||||
atomic_inc(&drops.cmd);
|
||||
break;
|
||||
case BT_MONITOR_EVENT_PKT:
|
||||
atomic_inc(&drops.evt);
|
||||
break;
|
||||
case BT_MONITOR_ACL_TX_PKT:
|
||||
atomic_inc(&drops.acl_tx);
|
||||
break;
|
||||
case BT_MONITOR_ACL_RX_PKT:
|
||||
atomic_inc(&drops.acl_rx);
|
||||
break;
|
||||
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||
case BT_MONITOR_SCO_TX_PKT:
|
||||
atomic_inc(&drops.sco_tx);
|
||||
break;
|
||||
case BT_MONITOR_SCO_RX_PKT:
|
||||
atomic_inc(&drops.sco_rx);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
atomic_inc(&drops.other);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void bt_log(int prio, const char *fmt, ...)
|
||||
{
|
||||
struct bt_monitor_user_logging log;
|
||||
|
@ -90,14 +153,15 @@ void bt_log(int prio, const char *fmt, ...)
|
|||
log.priority = prio;
|
||||
log.ident_len = sizeof(id);
|
||||
|
||||
encode_hdr(&hdr, BT_MONITOR_USER_LOGGING,
|
||||
sizeof(log) + sizeof(id) + len + 1);
|
||||
|
||||
if (atomic_test_and_set_bit(&flags, BT_LOG_BUSY)) {
|
||||
drop_add(BT_MONITOR_USER_LOGGING);
|
||||
return;
|
||||
}
|
||||
|
||||
monitor_send(&hdr, sizeof(hdr));
|
||||
encode_hdr(&hdr, BT_MONITOR_USER_LOGGING,
|
||||
sizeof(log) + sizeof(id) + len + 1);
|
||||
|
||||
monitor_send(&hdr, BT_MONITOR_BASE_HDR_LEN + hdr.hdr_len);
|
||||
monitor_send(&log, sizeof(log));
|
||||
monitor_send(id, sizeof(id));
|
||||
|
||||
|
@ -115,13 +179,14 @@ void bt_monitor_send(uint16_t opcode, const void *data, size_t len)
|
|||
{
|
||||
struct bt_monitor_hdr hdr;
|
||||
|
||||
encode_hdr(&hdr, opcode, len);
|
||||
|
||||
if (atomic_test_and_set_bit(&flags, BT_LOG_BUSY)) {
|
||||
drop_add(opcode);
|
||||
return;
|
||||
}
|
||||
|
||||
monitor_send(&hdr, sizeof(hdr));
|
||||
encode_hdr(&hdr, opcode, len);
|
||||
|
||||
monitor_send(&hdr, BT_MONITOR_BASE_HDR_LEN + hdr.hdr_len);
|
||||
monitor_send(data, len);
|
||||
|
||||
atomic_clear_bit(&flags, BT_LOG_BUSY);
|
||||
|
|
|
@ -39,13 +39,24 @@
|
|||
#define BT_MONITOR_OTHER_DROPS 7
|
||||
#define BT_MONITOR_TS32 8
|
||||
|
||||
#define BT_MONITOR_BASE_HDR_LEN 6
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||
#define BT_MONITOR_EXT_HDR_MAX 19
|
||||
#else
|
||||
#define BT_MONITOR_EXT_HDR_MAX 15
|
||||
#endif
|
||||
|
||||
struct bt_monitor_hdr {
|
||||
uint16_t data_len;
|
||||
uint16_t opcode;
|
||||
uint8_t flags;
|
||||
uint8_t hdr_len;
|
||||
|
||||
/* Extended header */
|
||||
uint8_t ext[BT_MONITOR_EXT_HDR_MAX];
|
||||
} __packed;
|
||||
|
||||
struct bt_monitor_ts32 {
|
||||
uint8_t type;
|
||||
uint32_t ts32;
|
||||
} __packed;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue