From e9e62c0f086b7eb9a2750979ad419342afc1d729 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 22 Nov 2012 10:43:42 +0100 Subject: [PATCH] monitor: Decode LMP features pages --- monitor/packet.c | 125 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 115 insertions(+), 10 deletions(-) diff --git a/monitor/packet.c b/monitor/packet.c index d41d7c10e..6bbdb43a5 100644 --- a/monitor/packet.c +++ b/monitor/packet.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -1116,15 +1117,119 @@ static void print_commands(const uint8_t *commands) print_field("Commands: 0x%s", str); } -static void print_features(const uint8_t *features) +struct features_data { + uint8_t bit; + const char *str; +}; + +static const struct features_data features_page0[] = { + { 0, "3 slot packets" }, + { 1, "5 slot packets" }, + { 2, "Encryption" }, + { 3, "Slot offset" }, + { 4, "Timing accuracy" }, + { 5, "Role switch" }, + { 6, "Hold mode" }, + { 7, "Sniff mode" }, + { 8, "Park state" }, + { 9, "Power control requests" }, + { 10, "Channel quality driven data rate (CQDDR)"}, + { 11, "SCO link" }, + { 12, "HV2 packets" }, + { 13, "HV3 packets" }, + { 14, "u-law log synchronous data" }, + { 15, "A-law log synchronous data" }, + { 16, "CVSD synchronous data" }, + { 17, "Paging parameter negotiation" }, + { 18, "Power control" }, + { 19, "Transparent synchronous data" }, + { 23, "Broadcast Encryption" }, + { 25, "Enhanced Data Rate ACL 2 Mbps mode" }, + { 26, "Enhanced Data Rate ACL 3 Mbps mode" }, + { 27, "Enhanced inquiry scan" }, + { 28, "Interlaced inquiry scan" }, + { 29, "Interlaced page scan" }, + { 30, "RSSI with inquiry results" }, + { 31, "Extended SCO link (EV3 packets)" }, + { 32, "EV4 packets" }, + { 33, "EV5 packets" }, + { 35, "AFH capable slave" }, + { 36, "AFH classification slave" }, + { 37, "BR/EDR Not Supported" }, + { 38, "LE Supported (Controller)" }, + { 39, "3-slot Enhanced Data Rate ACL packets" }, + { 40, "5-slot Enhanced Data Rate ACL packets" }, + { 41, "Sniff subrating" }, + { 42, "Pause encryption" }, + { 43, "AFH capable master" }, + { 44, "AFH classification master" }, + { 45, "Enhanced Data Rate eSCO 2 Mbps mode" }, + { 46, "Enhanced Data Rate eSCO 3 Mbps mode" }, + { 47, "3-slot Enhanced Data Rate eSCO packets" }, + { 48, "Extended Inquiry Response" }, + { 49, "Simultaneous LE and BR/EDR (Controller)" }, + { 51, "Secure Simple Pairing" }, + { 52, "Encapsulated PDU" }, + { 53, "Erroneous Data Reporting" }, + { 54, "Non-flushable Packet Boundary Flag" }, + { 56, "Link Supervision Timeout Changed Event" }, + { 57, "Inquiry TX Power Level" }, + { 58, "Enhanced Power Control" }, + { 63, "Extended features" }, + { } +}; + +static const struct features_data features_page1[] = { + { 0, "Secure Simple Pairing (Host Support)" }, + { 1, "LE Supported (Host)" }, + { 2, "Simultaneous LE and BR/EDR (Host)" }, + { } +}; + +static const struct features_data features_page2[] = { + { } +}; + +static void print_features(uint8_t page, const uint8_t *features_array) { + const struct features_data *features_table = NULL; + uint64_t mask, features = 0; char str[41]; int i; - for (i = 0; i < 8; i++) - sprintf(str + (i * 5), " 0x%2.2x", features[i]); + for (i = 0; i < 8; i++) { + sprintf(str + (i * 5), " 0x%2.2x", features_array[i]); + features |= ((uint64_t ) features_array[i]) << (i * 8); + } print_field("Features:%s", str); + + switch (page) { + case 0: + features_table = features_page0; + break; + case 1: + features_table = features_page1; + break; + case 2: + features_table = features_page2; + break; + } + + if (!features_table) + return; + + mask = features; + + for (i = 0; features_table[i].str; i++) { + if (features & (1 << features_table[i].bit)) { + print_field(" %s", features_table[i].str); + mask &= ~(1 << features_table[i].bit); + } + } + + if (mask) + print_field(" Unknown features (0x%16.16" PRIx64 ")", mask); } static void print_le_states(const uint8_t *states) @@ -2521,7 +2626,7 @@ static void read_local_features_rsp(const void *data, uint8_t size) const struct bt_hci_rsp_read_local_features *rsp = data; print_status(rsp->status); - print_features(rsp->features); + print_features(0, rsp->features); } static void read_local_ext_features_cmd(const void *data, uint8_t size) @@ -2537,7 +2642,7 @@ static void read_local_ext_features_rsp(const void *data, uint8_t size) print_status(rsp->status); print_field("Page: %d/%d", rsp->page, rsp->max_page); - print_features(rsp->features); + print_features(rsp->page, rsp->features); } static void read_buffer_size_rsp(const void *data, uint8_t size) @@ -2700,7 +2805,7 @@ static void le_read_local_features_rsp(const void *data, uint8_t size) const struct bt_hci_rsp_le_read_local_features *rsp = data; print_status(rsp->status); - print_features(rsp->features); + print_features(0, rsp->features); } static void le_set_random_address_cmd(const void *data, uint8_t size) @@ -3511,7 +3616,7 @@ static void remote_features_complete_evt(const void *data, uint8_t size) print_status(evt->status); print_handle(evt->handle); - print_features(evt->features); + print_features(0, evt->features); } static void remote_version_complete_evt(const void *data, uint8_t size) @@ -3795,7 +3900,7 @@ static void remote_ext_features_complete_evt(const void *data, uint8_t size) print_status(evt->status); print_handle(evt->handle); print_field("Page: %d/%d", evt->page, evt->max_page); - print_features(evt->features); + print_features(evt->page, evt->features); } static void sync_conn_complete_evt(const void *data, uint8_t size) @@ -3965,7 +4070,7 @@ static void remote_host_features_notify_evt(const void *data, uint8_t size) const struct bt_hci_evt_remote_host_features_notify *evt = data; print_bdaddr(evt->bdaddr); - print_features(evt->features); + print_features(1, evt->features); } static void phy_link_complete_evt(const void *data, uint8_t size) @@ -4167,7 +4272,7 @@ static void le_remote_features_complete_evt(const void *data, uint8_t size) print_status(evt->status); print_handle(evt->handle); - print_features(evt->features); + print_features(0, evt->features); } static void le_long_term_key_request_evt(const void *data, uint8_t size) -- 2.47.3