@@ -221,11 +221,13 @@ static void conn_destroy(void *data)
print_field("%lu RX packets", conn->rx_num);
print_field("%lu TX packets", conn->tx_num);
print_field("%lu TX completed packets", conn->tx_num_comp);
- print_field("%lld-%lld msec (~%lld msec) TX Latency",
+ print_field("%lld-%lld msec (~%lld msec/~lld Kb/s) TX Latency",
TV_MSEC(conn->tx_l.min), TV_MSEC(conn->tx_l.max),
TV_MSEC(conn->tx_l.med));
print_field("%u-%u octets (~%u octets) TX packet size",
conn->tx_pkt_min, conn->tx_pkt_max, conn->tx_pkt_med);
+ print_field("~%lld Kb/s TX transfer speed",
+ conn->tx_bytes * 8 / TV_MSEC(conn->tx_l.total));
plot_draw(conn->plot);
@@ -10397,6 +10397,8 @@ static void role_change_evt(struct timeval *tv, uint16_t index,
void packet_latency_add(struct packet_latency *latency, struct timeval *delta)
{
+ timeradd(&latency->total, delta, &latency->total);
+
if ((!timerisset(&latency->min) || timercmp(delta, &latency->min, <))
&& delta->tv_sec >= 0 && delta->tv_usec >= 0)
latency->min = *delta;
@@ -10427,28 +10429,30 @@ void packet_latency_add(struct packet_latency *latency, struct timeval *delta)
static void packet_dequeue_tx(struct timeval *tv, uint16_t handle)
{
struct packet_conn_data *conn;
- struct timeval *tx;
+ struct packet_frame *frame;
struct timeval delta;
conn = packet_get_conn_data(handle);
if (!conn)
return;
- tx = queue_pop_head(conn->tx_q);
- if (!tx)
+ frame = queue_pop_head(conn->tx_q);
+ if (!frame)
return;
- timersub(tv, tx, &delta);
+ timersub(tv, &frame->tv, &delta);
packet_latency_add(&conn->tx_l, &delta);
+ print_field("#%zu: len %zu (%lld Kb/s)", frame->num, frame->len,
+ frame->len * 8 / TV_MSEC(delta));
print_field("Latency: %lld msec (%lld-%lld msec ~%lld msec)",
TV_MSEC(delta), TV_MSEC(conn->tx_l.min),
TV_MSEC(conn->tx_l.max), TV_MSEC(conn->tx_l.med));
l2cap_dequeue_frame(&delta, conn);
- free(tx);
+ free(frame);
}
static void num_completed_packets_evt(struct timeval *tv, uint16_t index,
@@ -12442,10 +12446,11 @@ void packet_hci_event(struct timeval *tv, struct ucred *cred, uint16_t index,
event_data->func(tv, index, data, hdr->plen);
}
-static void packet_queue_tx(struct timeval *tv, uint16_t handle)
+static void packet_enqueue_tx(struct timeval *tv, uint16_t handle,
+ size_t num, uint16_t len)
{
struct packet_conn_data *conn;
- struct timeval *tx;
+ struct packet_frame *frame;
conn = packet_get_conn_data(handle);
if (!conn)
@@ -12454,9 +12459,12 @@ static void packet_queue_tx(struct timeval *tv, uint16_t handle)
if (!conn->tx_q)
conn->tx_q = queue_new();
- tx = new0(struct timeval, 1);
- memcpy(tx, tv, sizeof(*tv));
- queue_push_tail(conn->tx_q, tx);
+ frame = new0(struct packet_frame, 1);
+ if (tv)
+ memcpy(&frame->tv, tv, sizeof(*tv));
+ frame->num = num;
+ frame->len = len;
+ queue_push_tail(conn->tx_q, frame);
}
void packet_hci_acldata(struct timeval *tv, struct ucred *cred, uint16_t index,
@@ -12497,7 +12505,8 @@ void packet_hci_acldata(struct timeval *tv, struct ucred *cred, uint16_t index,
handle_str, extra_str);
if (!in)
- packet_queue_tx(tv, acl_handle(handle));
+ packet_enqueue_tx(tv, acl_handle(handle),
+ index_list[index].frame, dlen);
if (size != dlen) {
print_text(COLOR_ERROR, "invalid packet size (%d != %d)",
@@ -12549,7 +12558,8 @@ void packet_hci_scodata(struct timeval *tv, struct ucred *cred, uint16_t index,
handle_str, extra_str);
if (!in)
- packet_queue_tx(tv, acl_handle(handle));
+ packet_enqueue_tx(tv, acl_handle(handle),
+ index_list[index].frame, hdr->dlen);
if (size != hdr->dlen) {
print_text(COLOR_ERROR, "invalid packet size (%d != %d)",
@@ -12599,7 +12609,8 @@ void packet_hci_isodata(struct timeval *tv, struct ucred *cred, uint16_t index,
handle_str, extra_str);
if (!in)
- packet_queue_tx(tv, acl_handle(handle));
+ packet_enqueue_tx(tv, acl_handle(handle),
+ index_list[index].frame, hdr->dlen);
if (size != hdr->dlen) {
print_text(COLOR_ERROR, "invalid packet size (%d != %d)",
@@ -26,11 +26,18 @@
#define TV_MSEC(_tv) (long long)((_tv).tv_sec * 1000 + (_tv).tv_usec / 1000)
struct packet_latency {
+ struct timeval total;
struct timeval min;
struct timeval max;
struct timeval med;
};
+struct packet_frame {
+ struct timeval tv;
+ size_t num;
+ size_t len;
+};
+
struct packet_conn_data {
uint16_t index;
uint8_t src[6];