From b54ddecd9cf1a4b83e13d27889d533dcf87a4390 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 18 May 2023 16:14:49 -0700 Subject: [PATCH] monitor: Add latency when decoding BT_HCI_EVT_NUM_COMPLETED_PACKETS This adds latency, min-max, and median information when decoding BT_HCI_EVT_NUM_COMPLETED_PACKETS so it works similarly to --analyze: > HCI Event: Number of Completed Packets (0x13) plen 5 Num handles: 1 Handle: 256 Address: XX:XX:XX:XX:XX:XX Count: 1 Latency: 23 msec (2-66 msec ~19 msec) --- monitor/broadcom.c | 6 +- monitor/intel.c | 51 +++--- monitor/msft.c | 3 +- monitor/packet.c | 488 +++++++++++++++++++++++++++++++++-------------------- monitor/packet.h | 4 + monitor/vendor.h | 3 +- 6 files changed, 346 insertions(+), 209 deletions(-) diff --git a/monitor/broadcom.c b/monitor/broadcom.c index aaae6f9..7876b7b 100644 --- a/monitor/broadcom.c +++ b/monitor/broadcom.c @@ -1426,7 +1426,8 @@ struct hci_vse_sec_brcm_link_loss_dbg_info{ unsigned char lmp_cmd[4]; } __packed; -static void linkloss_evt(uint16_t index, const void *data, uint8_t size) +static void linkloss_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { struct hci_vse_sec_brcm_link_loss_dbg_info *ev = (void *) data; @@ -1465,7 +1466,8 @@ static void linkloss_evt(uint16_t index, const void *data, uint8_t size) } #endif -static void lm_diag_evt(uint16_t index, const void *data, uint8_t size) +static void lm_diag_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { broadcom_lm_diag(data, 63); } diff --git a/monitor/intel.c b/monitor/intel.c index 8f8eff2..2b321ec 100755 --- a/monitor/intel.c +++ b/monitor/intel.c @@ -792,11 +792,13 @@ const struct vendor_ocf *intel_vendor_ocf(uint16_t ocf) return NULL; } -static void startup_evt(uint16_t index, const void *data, uint8_t size) +static void startup_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { } -static void fatal_exception_evt(uint16_t index, const void *data, uint8_t size) +static void fatal_exception_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { uint16_t line = get_le16(data); uint8_t module = get_u8(data + 2); @@ -807,7 +809,8 @@ static void fatal_exception_evt(uint16_t index, const void *data, uint8_t size) print_field("Reason: 0x%2.2x", reason); } -static void bootup_evt(uint16_t index, const void *data, uint8_t size) +static void bootup_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { uint8_t zero = get_u8(data); uint8_t num_packets = get_u8(data + 1); @@ -910,7 +913,8 @@ static void bootup_evt(uint16_t index, const void *data, uint8_t size) print_field("DDC status: %s (0x%2.2x)", str, ddc_status); } -static void default_bd_data_evt(uint16_t index, const void *data, uint8_t size) +static void default_bd_data_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { uint8_t mem_status = get_u8(data); const char *str; @@ -927,8 +931,8 @@ static void default_bd_data_evt(uint16_t index, const void *data, uint8_t size) print_field("Memory status: %s (0x%2.2x)", str, mem_status); } -static void secure_send_commands_result_evt(uint16_t index, const void *data, - uint8_t size) +static void secure_send_commands_result_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { uint8_t result = get_u8(data); uint16_t opcode = get_le16(data + 1); @@ -972,7 +976,8 @@ static void secure_send_commands_result_evt(uint16_t index, const void *data, print_status(status); } -static void debug_exception_evt(uint16_t index, const void *data, uint8_t size) +static void debug_exception_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { uint16_t line = get_le16(data); uint8_t module = get_u8(data + 2); @@ -983,8 +988,8 @@ static void debug_exception_evt(uint16_t index, const void *data, uint8_t size) print_field("Reason: 0x%2.2x", reason); } -static void le_link_established_evt(uint16_t index, const void *data, - uint8_t size) +static void le_link_established_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { uint16_t handle = get_le16(data); uint32_t access_addr = get_le32(data + 10); @@ -998,7 +1003,8 @@ static void le_link_established_evt(uint16_t index, const void *data, packet_hexdump(data + 14, size - 14); } -static void scan_status_evt(uint16_t index, const void *data, uint8_t size) +static void scan_status_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { uint8_t enable = get_u8(data); @@ -1013,15 +1019,16 @@ static void scan_status_evt(uint16_t index, const void *data, uint8_t size) } -static void act_deact_traces_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void act_deact_traces_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { uint8_t status = get_u8(data); print_status(status); } -static void lmp_pdu_trace_evt(uint16_t index, const void *data, uint8_t size) +static void lmp_pdu_trace_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { uint8_t type, len, id; uint16_t handle, count; @@ -1115,16 +1122,16 @@ static void lmp_pdu_trace_evt(uint16_t index, const void *data, uint8_t size) } } -static void write_bd_data_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void write_bd_data_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { uint8_t status = get_u8(data); print_status(status); } -static void sco_rejected_via_lmp_evt(uint16_t index, const void *data, - uint8_t size) +static void sco_rejected_via_lmp_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { uint8_t reason = get_u8(data + 6); @@ -1132,8 +1139,8 @@ static void sco_rejected_via_lmp_evt(uint16_t index, const void *data, packet_print_error("Reason", reason); } -static void ptt_switch_notification_evt(uint16_t index, const void *data, - uint8_t size) +static void ptt_switch_notification_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { uint16_t handle = get_le16(data); uint8_t table = get_u8(data + 2); @@ -1156,7 +1163,8 @@ static void ptt_switch_notification_evt(uint16_t index, const void *data, print_field("Packet type table: %s (0x%2.2x)", str, table); } -static void system_exception_evt(uint16_t index, const void *data, uint8_t size) +static void system_exception_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { uint8_t type = get_u8(data); const char *str; @@ -1740,7 +1748,8 @@ static const struct intel_tlv *process_ext_subevent(const struct intel_tlv *tlv, return next_tlv; } -static void intel_vendor_ext_evt(uint16_t index, const void *data, uint8_t size) +static void intel_vendor_ext_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { /* The data pointer points to a number of tlv.*/ const struct intel_tlv *tlv = data; diff --git a/monitor/msft.c b/monitor/msft.c index 9418350..1137dac 100644 --- a/monitor/msft.c +++ b/monitor/msft.c @@ -301,7 +301,8 @@ const struct vendor_ocf *msft_vendor_ocf(void) return &vendor_ocf_entry; } -static void msft_evt(uint16_t index, const void *data, uint8_t size) +static void msft_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { packet_hexdump(data, size); } diff --git a/monitor/packet.c b/monitor/packet.c index b9420d8..a4daf98 100755 --- a/monitor/packet.c +++ b/monitor/packet.c @@ -33,6 +33,7 @@ #include "src/shared/util.h" #include "src/shared/btsnoop.h" +#include "src/shared/queue.h" #include "display.h" #include "bt.h" #include "ll.h" @@ -201,11 +202,14 @@ static void release_handle(uint16_t handle) int i; for (i = 0; i < MAX_CONN; i++) { - if (conn_list[i].handle == handle) { - if (conn_list[i].destroy) - conn_list[i].destroy(conn_list[i].data); + struct packet_conn_data *conn = &conn_list[i]; - memset(&conn_list[i], 0, sizeof(conn_list[i])); + if (conn->handle == handle) { + if (conn->destroy) + conn->destroy(conn->data); + + queue_destroy(conn->tx_q, free); + memset(conn, 0, sizeof(*conn)); break; } } @@ -9975,14 +9979,16 @@ static const char *current_vendor_evt_str(void) return NULL; } -static void inquiry_complete_evt(uint16_t index, const void *data, uint8_t size) +static void inquiry_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_inquiry_complete *evt = data; print_status(evt->status); } -static void inquiry_result_evt(uint16_t index, const void *data, uint8_t size) +static void inquiry_result_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_inquiry_result *evt = data; @@ -9998,7 +10004,8 @@ static void inquiry_result_evt(uint16_t index, const void *data, uint8_t size) packet_hexdump(data + sizeof(*evt), size - sizeof(*evt)); } -static void conn_complete_evt(uint16_t index, const void *data, uint8_t size) +static void conn_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_conn_complete *evt = data; @@ -10013,7 +10020,8 @@ static void conn_complete_evt(uint16_t index, const void *data, uint8_t size) (void *)evt->bdaddr, BDADDR_BREDR); } -static void conn_request_evt(uint16_t index, const void *data, uint8_t size) +static void conn_request_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_conn_request *evt = data; @@ -10022,8 +10030,8 @@ static void conn_request_evt(uint16_t index, const void *data, uint8_t size) print_link_type(evt->link_type); } -static void disconnect_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void disconnect_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_disconnect_complete *evt = data; @@ -10035,7 +10043,8 @@ static void disconnect_complete_evt(uint16_t index, const void *data, release_handle(le16_to_cpu(evt->handle)); } -static void auth_complete_evt(uint16_t index, const void *data, uint8_t size) +static void auth_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_auth_complete *evt = data; @@ -10043,8 +10052,8 @@ static void auth_complete_evt(uint16_t index, const void *data, uint8_t size) print_handle(evt->handle); } -static void remote_name_request_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void remote_name_request_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_remote_name_request_complete *evt = data; @@ -10053,7 +10062,8 @@ static void remote_name_request_complete_evt(uint16_t index, const void *data, print_name(evt->name); } -static void encrypt_change_evt(uint16_t index, const void *data, uint8_t size) +static void encrypt_change_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_encrypt_change *evt = data; @@ -10062,8 +10072,9 @@ static void encrypt_change_evt(uint16_t index, const void *data, uint8_t size) print_encr_mode_change(evt->encr_mode, evt->handle); } -static void change_conn_link_key_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void change_conn_link_key_complete_evt(struct timeval *tv, + uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_change_conn_link_key_complete *evt = data; @@ -10071,8 +10082,8 @@ static void change_conn_link_key_complete_evt(uint16_t index, const void *data, print_handle(evt->handle); } -static void link_key_type_changed_evt(uint16_t index, const void *data, - uint8_t size) +static void link_key_type_changed_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_link_key_type_changed *evt = data; @@ -10081,8 +10092,8 @@ static void link_key_type_changed_evt(uint16_t index, const void *data, print_key_flag(evt->key_flag); } -static void remote_features_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void remote_features_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_remote_features_complete *evt = data; @@ -10091,8 +10102,8 @@ static void remote_features_complete_evt(uint16_t index, const void *data, print_features(0, evt->features, 0x00); } -static void remote_version_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void remote_version_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_remote_version_complete *evt = data; @@ -10108,8 +10119,8 @@ static void remote_version_complete_evt(uint16_t index, const void *data, } } -static void qos_setup_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void qos_setup_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_qos_setup_complete *evt = data; @@ -10125,7 +10136,8 @@ static void qos_setup_complete_evt(uint16_t index, const void *data, print_field("Delay variation: %d", le32_to_cpu(evt->delay_variation)); } -static void cmd_complete_evt(uint16_t index, const void *data, uint8_t size) +static void cmd_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_cmd_complete *evt = data; uint16_t opcode = le16_to_cpu(evt->opcode); @@ -10221,7 +10233,8 @@ static void cmd_complete_evt(uint16_t index, const void *data, uint8_t size) opcode_data->rsp_func(index, data + 3, size - 3); } -static void cmd_status_evt(uint16_t index, const void *data, uint8_t size) +static void cmd_status_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_cmd_status *evt = data; uint16_t opcode = le16_to_cpu(evt->opcode); @@ -10273,21 +10286,24 @@ static void cmd_status_evt(uint16_t index, const void *data, uint8_t size) print_status(evt->status); } -static void hardware_error_evt(uint16_t index, const void *data, uint8_t size) +static void hardware_error_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_hardware_error *evt = data; print_field("Code: 0x%2.2x", evt->code); } -static void flush_occurred_evt(uint16_t index, const void *data, uint8_t size) +static void flush_occurred_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_flush_occurred *evt = data; print_handle(evt->handle); } -static void role_change_evt(uint16_t index, const void *data, uint8_t size) +static void role_change_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_role_change *evt = data; @@ -10296,8 +10312,57 @@ static void role_change_evt(uint16_t index, const void *data, uint8_t size) print_role(evt->role); } -static void num_completed_packets_evt(uint16_t index, const void *data, - uint8_t size) +#define TV_MSEC(_tv) (long long)(_tv.tv_sec * 1000 + _tv.tv_usec / 1000) + +static void packet_dequeue_tx(struct timeval *tv, uint16_t handle) +{ + struct packet_conn_data *conn; + struct timeval *tx; + struct timeval delta; + + conn = packet_get_conn_data(handle); + if (!conn) + return; + + tx = queue_pop_head(conn->tx_q); + if (!tx) + return; + + timersub(tv, tx, &delta); + + if ((!timerisset(&conn->tx_min) || timercmp(&delta, &conn->tx_min, <)) + && delta.tv_sec >= 0 && delta.tv_usec >= 0) + conn->tx_min = delta; + + if (!timerisset(&conn->tx_max) || timercmp(&delta, &conn->tx_max, >)) + conn->tx_max = delta; + + if (timerisset(&conn->tx_med)) { + struct timeval tmp; + + timeradd(&conn->tx_med, &delta, &tmp); + + tmp.tv_sec /= 2; + tmp.tv_usec /= 2; + if (tmp.tv_sec % 2) { + tmp.tv_usec += 500000; + if (tmp.tv_usec >= 1000000) { + tmp.tv_sec++; + tmp.tv_usec -= 1000000; + } + } + + conn->tx_med = tmp; + } else + conn->tx_med = delta; + + print_field("Latency: %lld msec (%lld-%lld msec ~%lld msec)", + TV_MSEC(delta), TV_MSEC(conn->tx_min), + TV_MSEC(conn->tx_max), TV_MSEC(conn->tx_med)); +} + +static void num_completed_packets_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { struct iovec iov = { (void *)data, size}; const struct bt_hci_evt_num_completed_packets *evt = data; @@ -10320,13 +10385,16 @@ static void num_completed_packets_evt(uint16_t index, const void *data, break; print_field("Count: %d", le16_to_cpu(evt->count)); + + packet_dequeue_tx(tv, handle); } if (iov.iov_len) packet_hexdump(iov.iov_base, iov.iov_len); } -static void mode_change_evt(uint16_t index, const void *data, uint8_t size) +static void mode_change_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_mode_change *evt = data; @@ -10336,7 +10404,8 @@ static void mode_change_evt(uint16_t index, const void *data, uint8_t size) print_interval(evt->interval); } -static void return_link_keys_evt(uint16_t index, const void *data, uint8_t size) +static void return_link_keys_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_return_link_keys *evt = data; uint8_t i; @@ -10349,21 +10418,24 @@ static void return_link_keys_evt(uint16_t index, const void *data, uint8_t size) } } -static void pin_code_request_evt(uint16_t index, const void *data, uint8_t size) +static void pin_code_request_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_pin_code_request *evt = data; print_bdaddr(evt->bdaddr); } -static void link_key_request_evt(uint16_t index, const void *data, uint8_t size) +static void link_key_request_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_link_key_request *evt = data; print_bdaddr(evt->bdaddr); } -static void link_key_notify_evt(uint16_t index, const void *data, uint8_t size) +static void link_key_notify_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_link_key_notify *evt = data; @@ -10372,20 +10444,22 @@ static void link_key_notify_evt(uint16_t index, const void *data, uint8_t size) print_key_type(evt->key_type); } -static void loopback_command_evt(uint16_t index, const void *data, uint8_t size) +static void loopback_command_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { packet_hexdump(data, size); } -static void data_buffer_overflow_evt(uint16_t index, const void *data, - uint8_t size) +static void data_buffer_overflow_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_data_buffer_overflow *evt = data; print_link_type(evt->link_type); } -static void max_slots_change_evt(uint16_t index, const void *data, uint8_t size) +static void max_slots_change_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_max_slots_change *evt = data; @@ -10393,8 +10467,8 @@ static void max_slots_change_evt(uint16_t index, const void *data, uint8_t size) print_field("Max slots: %d", evt->max_slots); } -static void clock_offset_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void clock_offset_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_clock_offset_complete *evt = data; @@ -10403,8 +10477,8 @@ static void clock_offset_complete_evt(uint16_t index, const void *data, print_clock_offset(evt->clock_offset); } -static void conn_pkt_type_changed_evt(uint16_t index, const void *data, - uint8_t size) +static void conn_pkt_type_changed_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_conn_pkt_type_changed *evt = data; @@ -10413,15 +10487,16 @@ static void conn_pkt_type_changed_evt(uint16_t index, const void *data, print_pkt_type(evt->pkt_type); } -static void qos_violation_evt(uint16_t index, const void *data, uint8_t size) +static void qos_violation_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_qos_violation *evt = data; print_handle(evt->handle); } -static void pscan_mode_change_evt(uint16_t index, const void *data, - uint8_t size) +static void pscan_mode_change_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_pscan_mode_change *evt = data; @@ -10429,8 +10504,8 @@ static void pscan_mode_change_evt(uint16_t index, const void *data, print_pscan_mode(evt->pscan_mode); } -static void pscan_rep_mode_change_evt(uint16_t index, const void *data, - uint8_t size) +static void pscan_rep_mode_change_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_pscan_rep_mode_change *evt = data; @@ -10438,8 +10513,8 @@ static void pscan_rep_mode_change_evt(uint16_t index, const void *data, print_pscan_rep_mode(evt->pscan_rep_mode); } -static void flow_spec_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void flow_spec_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_flow_spec_complete *evt = data; @@ -10457,8 +10532,8 @@ static void flow_spec_complete_evt(uint16_t index, const void *data, print_field("Access latency: %d", le32_to_cpu(evt->access_latency)); } -static void inquiry_result_with_rssi_evt(uint16_t index, const void *data, - uint8_t size) +static void inquiry_result_with_rssi_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_inquiry_result_with_rssi *evt = data; @@ -10474,8 +10549,8 @@ static void inquiry_result_with_rssi_evt(uint16_t index, const void *data, packet_hexdump(data + sizeof(*evt), size - sizeof(*evt)); } -static void remote_ext_features_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void remote_ext_features_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_remote_ext_features_complete *evt = data; @@ -10485,8 +10560,8 @@ static void remote_ext_features_complete_evt(uint16_t index, const void *data, print_features(evt->page, evt->features, 0x00); } -static void sync_conn_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void sync_conn_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_sync_conn_complete *evt = data; @@ -10501,8 +10576,8 @@ static void sync_conn_complete_evt(uint16_t index, const void *data, print_air_mode(evt->air_mode); } -static void sync_conn_changed_evt(uint16_t index, const void *data, - uint8_t size) +static void sync_conn_changed_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_sync_conn_changed *evt = data; @@ -10514,7 +10589,8 @@ static void sync_conn_changed_evt(uint16_t index, const void *data, print_field("TX packet length: %d", le16_to_cpu(evt->tx_pkt_len)); } -static void sniff_subrating_evt(uint16_t index, const void *data, uint8_t size) +static void sniff_subrating_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_sniff_subrating *evt = data; @@ -10526,8 +10602,8 @@ static void sniff_subrating_evt(uint16_t index, const void *data, uint8_t size) print_slot_625("Min local timeout", evt->min_local_timeout); } -static void ext_inquiry_result_evt(uint16_t index, const void *data, - uint8_t size) +static void ext_inquiry_result_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_ext_inquiry_result *evt = data; @@ -10541,8 +10617,8 @@ static void ext_inquiry_result_evt(uint16_t index, const void *data, print_eir(evt->data, sizeof(evt->data), false); } -static void encrypt_key_refresh_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void encrypt_key_refresh_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_encrypt_key_refresh_complete *evt = data; @@ -10550,16 +10626,16 @@ static void encrypt_key_refresh_complete_evt(uint16_t index, const void *data, print_handle(evt->handle); } -static void io_capability_request_evt(uint16_t index, const void *data, - uint8_t size) +static void io_capability_request_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_io_capability_request *evt = data; print_bdaddr(evt->bdaddr); } -static void io_capability_response_evt(uint16_t index, const void *data, - uint8_t size) +static void io_capability_response_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_io_capability_response *evt = data; @@ -10569,8 +10645,8 @@ static void io_capability_response_evt(uint16_t index, const void *data, print_authentication(evt->authentication); } -static void user_confirm_request_evt(uint16_t index, const void *data, - uint8_t size) +static void user_confirm_request_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_user_confirm_request *evt = data; @@ -10578,24 +10654,24 @@ static void user_confirm_request_evt(uint16_t index, const void *data, print_passkey(evt->passkey); } -static void user_passkey_request_evt(uint16_t index, const void *data, - uint8_t size) +static void user_passkey_request_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_user_passkey_request *evt = data; print_bdaddr(evt->bdaddr); } -static void remote_oob_data_request_evt(uint16_t index, const void *data, - uint8_t size) +static void remote_oob_data_request_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_remote_oob_data_request *evt = data; print_bdaddr(evt->bdaddr); } -static void simple_pairing_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void simple_pairing_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_simple_pairing_complete *evt = data; @@ -10603,8 +10679,8 @@ static void simple_pairing_complete_evt(uint16_t index, const void *data, print_bdaddr(evt->bdaddr); } -static void link_supv_timeout_changed_evt(uint16_t index, const void *data, - uint8_t size) +static void link_supv_timeout_changed_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_link_supv_timeout_changed *evt = data; @@ -10612,16 +10688,16 @@ static void link_supv_timeout_changed_evt(uint16_t index, const void *data, print_timeout(evt->timeout); } -static void enhanced_flush_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void enhanced_flush_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_enhanced_flush_complete *evt = data; print_handle(evt->handle); } -static void user_passkey_notify_evt(uint16_t index, const void *data, - uint8_t size) +static void user_passkey_notify_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_user_passkey_notify *evt = data; @@ -10629,7 +10705,8 @@ static void user_passkey_notify_evt(uint16_t index, const void *data, print_passkey(evt->passkey); } -static void keypress_notify_evt(uint16_t index, const void *data, uint8_t size) +static void keypress_notify_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_keypress_notify *evt = data; const char *str; @@ -10660,8 +10737,8 @@ static void keypress_notify_evt(uint16_t index, const void *data, uint8_t size) print_field("Notification type: %s (0x%2.2x)", str, evt->type); } -static void remote_host_features_notify_evt(uint16_t index, const void *data, - uint8_t size) +static void remote_host_features_notify_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_remote_host_features_notify *evt = data; @@ -10669,8 +10746,8 @@ static void remote_host_features_notify_evt(uint16_t index, const void *data, print_features(1, evt->features, 0x00); } -static void phy_link_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void phy_link_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_phy_link_complete *evt = data; @@ -10678,15 +10755,16 @@ static void phy_link_complete_evt(uint16_t index, const void *data, print_phy_handle(evt->phy_handle); } -static void channel_selected_evt(uint16_t index, const void *data, uint8_t size) +static void channel_selected_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_channel_selected *evt = data; print_phy_handle(evt->phy_handle); } -static void disconn_phy_link_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void disconn_phy_link_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_disconn_phy_link_complete *evt = data; @@ -10695,8 +10773,8 @@ static void disconn_phy_link_complete_evt(uint16_t index, const void *data, print_reason(evt->reason); } -static void phy_link_loss_early_warning_evt(uint16_t index, const void *data, - uint8_t size) +static void phy_link_loss_early_warning_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_phy_link_loss_early_warning *evt = data; const char *str; @@ -10727,16 +10805,16 @@ static void phy_link_loss_early_warning_evt(uint16_t index, const void *data, print_field("Reason: %s (0x%2.2x)", str, evt->reason); } -static void phy_link_recovery_evt(uint16_t index, const void *data, - uint8_t size) +static void phy_link_recovery_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_phy_link_recovery *evt = data; print_phy_handle(evt->phy_handle); } -static void logic_link_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void logic_link_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_logic_link_complete *evt = data; @@ -10746,8 +10824,8 @@ static void logic_link_complete_evt(uint16_t index, const void *data, print_field("TX flow spec: 0x%2.2x", evt->flow_spec); } -static void disconn_logic_link_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void disconn_logic_link_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_disconn_logic_link_complete *evt = data; @@ -10756,8 +10834,8 @@ static void disconn_logic_link_complete_evt(uint16_t index, const void *data, print_reason(evt->reason); } -static void flow_spec_modify_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void flow_spec_modify_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_flow_spec_modify_complete *evt = data; @@ -10765,8 +10843,8 @@ static void flow_spec_modify_complete_evt(uint16_t index, const void *data, print_handle(evt->handle); } -static void num_completed_data_blocks_evt(uint16_t index, const void *data, - uint8_t size) +static void num_completed_data_blocks_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_num_completed_data_blocks *evt = data; @@ -10781,8 +10859,8 @@ static void num_completed_data_blocks_evt(uint16_t index, const void *data, packet_hexdump(data + sizeof(*evt), size - sizeof(*evt)); } -static void short_range_mode_change_evt(uint16_t index, const void *data, - uint8_t size) +static void short_range_mode_change_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_short_range_mode_change *evt = data; @@ -10791,8 +10869,8 @@ static void short_range_mode_change_evt(uint16_t index, const void *data, print_enable("Short range mode", evt->mode); } -static void amp_status_change_evt(uint16_t index, const void *data, - uint8_t size) +static void amp_status_change_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_amp_status_change *evt = data; @@ -10800,8 +10878,8 @@ static void amp_status_change_evt(uint16_t index, const void *data, print_amp_status(evt->amp_status); } -static void triggered_clock_capture_evt(uint16_t index, const void *data, - uint8_t size) +static void triggered_clock_capture_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_triggered_clock_capture *evt = data; @@ -10811,16 +10889,16 @@ static void triggered_clock_capture_evt(uint16_t index, const void *data, print_clock_offset(evt->clock_offset); } -static void sync_train_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void sync_train_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_sync_train_complete *evt = data; print_status(evt->status); } -static void sync_train_received_evt(uint16_t index, const void *data, - uint8_t size) +static void sync_train_received_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_sync_train_received *evt = data; @@ -10835,8 +10913,8 @@ static void sync_train_received_evt(uint16_t index, const void *data, print_field("Service Data: 0x%2.2x", evt->service_data); } -static void peripheral_broadcast_receive_evt(uint16_t index, const void *data, - uint8_t size) +static void peripheral_broadcast_receive_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_peripheral_broadcast_receive *evt = data; @@ -10858,8 +10936,8 @@ static void peripheral_broadcast_receive_evt(uint16_t index, const void *data, packet_hexdump(data + 18, size - 18); } -static void peripheral_broadcast_timeout_evt(uint16_t index, const void *data, - uint8_t size) +static void peripheral_broadcast_timeout_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_peripheral_broadcast_timeout *evt = data; @@ -10867,8 +10945,8 @@ static void peripheral_broadcast_timeout_evt(uint16_t index, const void *data, print_lt_addr(evt->lt_addr); } -static void truncated_page_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void truncated_page_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_truncated_page_complete *evt = data; @@ -10876,21 +10954,22 @@ static void truncated_page_complete_evt(uint16_t index, const void *data, print_bdaddr(evt->bdaddr); } -static void peripheral_page_response_timeout_evt(uint16_t index, - const void *data, uint8_t size) +static void peripheral_page_response_timeout_evt(struct timeval *tv, + uint16_t index, const void *data, + uint8_t size) { } -static void channel_map_change_evt(uint16_t index, const void *data, - uint8_t size) +static void channel_map_change_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_channel_map_change *evt = data; print_channel_map(evt->map); } -static void inquiry_response_notify_evt(uint16_t index, const void *data, - uint8_t size) +static void inquiry_response_notify_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_inquiry_response_notify *evt = data; @@ -10898,15 +10977,16 @@ static void inquiry_response_notify_evt(uint16_t index, const void *data, print_rssi(evt->rssi); } -static void auth_payload_timeout_expired_evt(uint16_t index, const void *data, - uint8_t size) +static void auth_payload_timeout_expired_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_auth_payload_timeout_expired *evt = data; print_handle(evt->handle); } -static void le_conn_complete_evt(uint16_t index, const void *data, uint8_t size) +static void le_conn_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_conn_complete *evt = data; @@ -10927,7 +11007,8 @@ static void le_conn_complete_evt(uint16_t index, const void *data, uint8_t size) (void *)evt->peer_addr, evt->peer_addr_type); } -static void le_adv_report_evt(uint16_t index, const void *data, uint8_t size) +static void le_adv_report_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_adv_report *evt = data; uint8_t evt_len; @@ -10955,8 +11036,8 @@ report: } } -static void le_conn_update_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void le_conn_update_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_conn_update_complete *evt = data; @@ -10969,8 +11050,8 @@ static void le_conn_update_complete_evt(uint16_t index, const void *data, le16_to_cpu(evt->supv_timeout)); } -static void le_remote_features_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void le_remote_features_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_remote_features_complete *evt = data; @@ -10979,8 +11060,8 @@ static void le_remote_features_complete_evt(uint16_t index, const void *data, print_features(0, evt->features, 0x01); } -static void le_long_term_key_request_evt(uint16_t index, const void *data, - uint8_t size) +static void le_long_term_key_request_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_long_term_key_request *evt = data; @@ -10989,8 +11070,8 @@ static void le_long_term_key_request_evt(uint16_t index, const void *data, print_encrypted_diversifier(evt->ediv); } -static void le_conn_param_request_evt(uint16_t index, const void *data, - uint8_t size) +static void le_conn_param_request_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_conn_param_request *evt = data; @@ -11003,8 +11084,8 @@ static void le_conn_param_request_evt(uint16_t index, const void *data, le16_to_cpu(evt->supv_timeout)); } -static void le_data_length_change_evt(uint16_t index, const void *data, - uint8_t size) +static void le_data_length_change_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_data_length_change *evt = data; @@ -11015,8 +11096,8 @@ static void le_data_length_change_evt(uint16_t index, const void *data, print_field("Max RX time: %d", le16_to_cpu(evt->max_rx_time)); } -static void le_read_local_pk256_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void le_read_local_pk256_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_read_local_pk256_complete *evt = data; @@ -11024,8 +11105,8 @@ static void le_read_local_pk256_complete_evt(uint16_t index, const void *data, print_pk256("Local P-256 public key", evt->local_pk256); } -static void le_generate_dhkey_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void le_generate_dhkey_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_generate_dhkey_complete *evt = data; @@ -11033,8 +11114,8 @@ static void le_generate_dhkey_complete_evt(uint16_t index, const void *data, print_dhkey(evt->dhkey); } -static void le_enhanced_conn_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void le_enhanced_conn_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_enhanced_conn_complete *evt = data; @@ -11057,8 +11138,8 @@ static void le_enhanced_conn_complete_evt(uint16_t index, const void *data, (void *)evt->peer_addr, evt->peer_addr_type); } -static void le_direct_adv_report_evt(uint16_t index, const void *data, - uint8_t size) +static void le_direct_adv_report_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_direct_adv_report *evt = data; @@ -11075,8 +11156,8 @@ static void le_direct_adv_report_evt(uint16_t index, const void *data, packet_hexdump(data + sizeof(*evt), size - sizeof(*evt)); } -static void le_phy_update_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void le_phy_update_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_phy_update_complete *evt = data; @@ -11179,8 +11260,8 @@ static void print_legacy_adv_report_pdu(uint16_t flags) print_field(" Legacy PDU Type: %s (0x%4.4x)", str, flags); } -static void le_ext_adv_report_evt(uint16_t index, const void *data, - uint8_t size) +static void le_ext_adv_report_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_ext_adv_report *evt = data; const struct bt_hci_le_ext_adv_report *report; @@ -11267,7 +11348,8 @@ static void le_ext_adv_report_evt(uint16_t index, const void *data, } } -static void le_pa_sync(uint16_t index, const void *data, uint8_t size) +static void le_pa_sync_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_per_sync_established *evt = data; @@ -11285,7 +11367,8 @@ static void le_pa_sync(uint16_t index, const void *data, uint8_t size) print_field("Advertiser clock accuracy: 0x%2.2x", evt->clock_accuracy); } -static void le_pa_report_evt(uint16_t index, const void *data, uint8_t size) +static void le_pa_report_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_le_pa_report *evt = data; const char *color_on; @@ -11347,14 +11430,16 @@ static void le_pa_report_evt(uint16_t index, const void *data, uint8_t size) packet_hexdump(evt->data, evt->data_len); } -static void le_pa_sync_lost(uint16_t index, const void *data, uint8_t size) +static void le_pa_sync_lost_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_per_sync_lost *evt = data; print_field("Sync handle: %d", evt->handle); } -static void le_adv_set_term_evt(uint16_t index, const void *data, uint8_t size) +static void le_adv_set_term_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_adv_set_term *evt = data; @@ -11365,8 +11450,8 @@ static void le_adv_set_term_evt(uint16_t index, const void *data, uint8_t size) evt->num_evts); } -static void le_scan_req_received_evt(uint16_t index, const void *data, - uint8_t size) +static void le_scan_req_received_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_scan_req_received *evt = data; @@ -11376,8 +11461,8 @@ static void le_scan_req_received_evt(uint16_t index, const void *data, evt->scanner_addr_type); } -static void le_chan_select_alg_evt(uint16_t index, const void *data, - uint8_t size) +static void le_chan_select_alg_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_chan_select_alg *evt = data; const char *str; @@ -11399,8 +11484,8 @@ static void le_chan_select_alg_evt(uint16_t index, const void *data, print_field("Algorithm: %s (0x%2.2x)", str, evt->algorithm); } -static void le_cte_request_failed_evt(uint16_t index, const void *data, - uint8_t size) +static void le_cte_request_failed_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_cte_request_failed *evt = data; @@ -11408,8 +11493,8 @@ static void le_cte_request_failed_evt(uint16_t index, const void *data, print_field("Connection handle: %d", evt->handle); } -static void le_pa_sync_trans_rec_evt(uint16_t index, const void *data, - uint8_t size) +static void le_pa_sync_trans_rec_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_pa_sync_trans_rec *evt = data; @@ -11427,8 +11512,8 @@ static void le_pa_sync_trans_rec_evt(uint16_t index, const void *data, print_clock_accuracy(evt->clock_accuracy); } -static void le_cis_established_evt(uint16_t index, const void *data, - uint8_t size) +static void le_cis_established_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_cis_established *evt = data; @@ -11450,7 +11535,8 @@ static void le_cis_established_evt(uint16_t index, const void *data, print_field("ISO Interval: %u", le16_to_cpu(evt->interval)); } -static void le_req_cis_evt(uint16_t index, const void *data, uint8_t size) +static void le_req_cis_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_cis_req *evt = data; @@ -11467,7 +11553,8 @@ static void print_bis_handle(const void *data, int i) print_field("Connection Handle #%d: %d", i, handle); } -static void le_big_complete_evt(uint16_t index, const void *data, uint8_t size) +static void le_big_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_big_complete *evt = data; @@ -11486,7 +11573,8 @@ static void le_big_complete_evt(uint16_t index, const void *data, uint8_t size) sizeof(*evt->bis_handle), print_bis_handle); } -static void le_big_terminate_evt(uint16_t index, const void *data, uint8_t size) +static void le_big_terminate_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_big_terminate *evt = data; @@ -11494,8 +11582,8 @@ static void le_big_terminate_evt(uint16_t index, const void *data, uint8_t size) print_reason(evt->reason); } -static void le_big_sync_estabilished_evt(uint16_t index, const void *data, - uint8_t size) +static void le_big_sync_estabilished_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_big_sync_estabilished *evt = data; @@ -11512,7 +11600,8 @@ static void le_big_sync_estabilished_evt(uint16_t index, const void *data, print_bis_handle); } -static void le_big_sync_lost_evt(uint16_t index, const void *data, uint8_t size) +static void le_big_sync_lost_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_big_sync_lost *evt = data; @@ -11520,8 +11609,8 @@ static void le_big_sync_lost_evt(uint16_t index, const void *data, uint8_t size) print_reason(evt->reason); } -static void le_req_sca_complete_evt(uint16_t index, const void *data, - uint8_t size) +static void le_req_sca_complete_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_req_peer_sca_complete *evt = data; @@ -11530,7 +11619,8 @@ static void le_req_sca_complete_evt(uint16_t index, const void *data, print_sca(evt->sca); } -static void le_big_info_evt(uint16_t index, const void *data, uint8_t size) +static void le_big_info_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_evt_le_big_info_adv_report *evt = data; @@ -11552,12 +11642,13 @@ static void le_big_info_evt(uint16_t index, const void *data, uint8_t size) struct subevent_data { uint8_t subevent; const char *str; - void (*func) (uint16_t index, const void *data, uint8_t size); + void (*func) (struct timeval *tv, uint16_t index, const void *data, + uint8_t size); uint8_t size; bool fixed; }; -static void print_subevent(uint16_t index, +static void print_subevent(struct timeval *tv, uint16_t index, const struct subevent_data *subevent_data, const void *data, uint8_t size) { @@ -11590,7 +11681,7 @@ static void print_subevent(uint16_t index, } } - subevent_data->func(index, data, size); + subevent_data->func(tv, index, data, size); } static const struct subevent_data le_meta_event_table[] = { @@ -11621,11 +11712,11 @@ static const struct subevent_data le_meta_event_table[] = { { 0x0d, "LE Extended Advertising Report", le_ext_adv_report_evt, 1, false}, { 0x0e, "LE Periodic Advertising Sync Established", - le_pa_sync, 15, true }, + le_pa_sync_evt, 15, true }, { 0x0f, "LE Periodic Advertising Report", le_pa_report_evt, 7, false}, { 0x10, "LE Periodic Advertising Sync Lost", - le_pa_sync_lost, 2, true}, + le_pa_sync_lost_evt, 2, true}, { 0x11, "LE Scan Timeout" }, { 0x12, "LE Advertising Set Terminated", le_adv_set_term_evt, 5, true}, @@ -11675,7 +11766,8 @@ static const struct subevent_data le_meta_event_table[] = { { } }; -static void le_meta_event_evt(uint16_t index, const void *data, uint8_t size) +static void le_meta_event_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { uint8_t subevent = *((const uint8_t *) data); struct subevent_data unknown; @@ -11695,10 +11787,11 @@ static void le_meta_event_evt(uint16_t index, const void *data, uint8_t size) } } - print_subevent(index, subevent_data, data + 1, size - 1); + print_subevent(tv, index, subevent_data, data + 1, size - 1); } -static void vendor_evt(uint16_t index, const void *data, uint8_t size) +static void vendor_evt(struct timeval *tv, uint16_t index, + const void *data, uint8_t size) { struct subevent_data vendor_data; char vendor_str[150]; @@ -11719,7 +11812,7 @@ static void vendor_evt(uint16_t index, const void *data, uint8_t size) vendor_data.size = vnd->evt_size; vendor_data.fixed = vnd->evt_fixed; - print_subevent(index, &vendor_data, data + consumed_size, + print_subevent(tv, index, &vendor_data, data + consumed_size, size - consumed_size); } else { uint16_t manufacturer; @@ -11736,7 +11829,8 @@ static void vendor_evt(uint16_t index, const void *data, uint8_t size) struct event_data { uint8_t event; const char *str; - void (*func) (uint16_t index, const void *data, uint8_t size); + void (*func) (struct timeval *tv, uint16_t index, const void *data, + uint8_t size); uint8_t size; bool fixed; }; @@ -12249,7 +12343,24 @@ void packet_hci_event(struct timeval *tv, struct ucred *cred, uint16_t index, } } - event_data->func(index, data, hdr->plen); + event_data->func(tv, index, data, hdr->plen); +} + +static void packet_queue_tx(struct timeval *tv, uint16_t handle) +{ + struct packet_conn_data *conn; + struct timeval *tx; + + conn = packet_get_conn_data(handle); + if (!conn) + return; + + 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); } void packet_hci_acldata(struct timeval *tv, struct ucred *cred, uint16_t index, @@ -12289,6 +12400,9 @@ void packet_hci_acldata(struct timeval *tv, struct ucred *cred, uint16_t index, in ? "ACL Data RX" : "ACL Data TX", handle_str, extra_str); + if (!in) + packet_queue_tx(tv, acl_handle(handle)); + if (size != dlen) { print_text(COLOR_ERROR, "invalid packet size (%d != %d)", size, dlen); @@ -12333,6 +12447,9 @@ void packet_hci_scodata(struct timeval *tv, struct ucred *cred, uint16_t index, in ? "SCO Data RX" : "SCO Data TX", handle_str, extra_str); + if (!in) + packet_queue_tx(tv, acl_handle(handle)); + if (size != hdr->dlen) { print_text(COLOR_ERROR, "invalid packet size (%d != %d)", size, hdr->dlen); @@ -12380,6 +12497,9 @@ void packet_hci_isodata(struct timeval *tv, struct ucred *cred, uint16_t index, in ? "ISO Data RX" : "ISO Data TX", handle_str, extra_str); + if (!in) + packet_queue_tx(tv, acl_handle(handle)); + if (size != hdr->dlen) { print_text(COLOR_ERROR, "invalid packet size (%d != %d)", size, hdr->dlen); diff --git a/monitor/packet.h b/monitor/packet.h index 191fb86..0a6e00a 100755 --- a/monitor/packet.h +++ b/monitor/packet.h @@ -31,6 +31,10 @@ struct packet_conn_data { uint8_t type; uint8_t dst[6]; uint8_t dst_type; + struct queue *tx_q; + struct timeval tx_min; + struct timeval tx_max; + struct timeval tx_med; void *data; void (*destroy)(void *data); }; diff --git a/monitor/vendor.h b/monitor/vendor.h index 9430f37..996ed44 100755 --- a/monitor/vendor.h +++ b/monitor/vendor.h @@ -25,7 +25,8 @@ struct vendor_ocf { struct vendor_evt { uint8_t evt; const char *str; - void (*evt_func) (uint16_t index, const void *data, uint8_t size); + void (*evt_func) (struct timeval *tv, uint16_t index, + const void *data, uint8_t size); uint8_t evt_size; bool evt_fixed; }; -- 2.7.4