1 // SPDX-License-Identifier: LGPL-2.1-or-later
4 * BlueZ - Bluetooth protocol stack for Linux
6 * Copyright (C) 2011-2014 Intel Corporation
7 * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
19 #include "src/shared/util.h"
27 #define COLOR_UNKNOWN_FEATURE_BIT COLOR_WHITE_BG
29 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
33 static void print_status(uint8_t status)
35 packet_print_error("Status", status);
38 static void print_handle(uint16_t handle)
40 packet_print_handle(handle);
43 static void print_rssi(int8_t rssi)
45 packet_print_rssi("RSSI", rssi);
48 static void print_sco_routing(uint8_t routing)
70 print_field("SCO routing: %s (0x%2.2x)", str, routing);
73 static void print_pcm_interface_rate(uint8_t rate)
98 print_field("PCM interface rate: %s (0x%2.2x)", str, rate);
101 static void print_frame_type(uint8_t type)
117 print_field("Frame type: %s (0x%2.2x)", str, type);
120 static void print_sync_mode(uint8_t mode)
136 print_field("Sync mode: %s (0x%2.2x)", str, mode);
139 static void print_clock_mode(uint8_t mode)
155 print_field("Clock mode: %s (0x%2.2x)", str, mode);
158 static void print_sleep_mode(uint8_t mode)
164 str = "No sleep mode";
170 str = "UART with messaging";
179 str = "USB with Host wake";
197 str = "UART with BREAK";
204 print_field("Sleep mode: %s (0x%2.2x)", str, mode);
207 static void print_clock_setting(uint8_t clock)
223 print_field("UART clock: %s (0x%2.2x)", str, clock);
226 static void null_cmd(uint16_t index, const void *data, uint8_t size)
230 static void null_cmd_without_index(const void *data, uint8_t size)
234 static void status_rsp(uint16_t index, const void *data, uint8_t size)
236 uint8_t status = get_u8(data);
238 print_status(status);
241 static void write_bd_addr_cmd(uint16_t index, const void *data, uint8_t size)
243 packet_print_addr("Address", data, 0x00);
246 static void update_uart_baud_rate_cmd(uint16_t index, const void *data,
249 uint16_t enc_rate = get_le16(data);
250 uint32_t exp_rate = get_le32(data + 2);
252 if (enc_rate == 0x0000)
253 print_field("Encoded baud rate: Not used (0x0000)");
255 print_field("Encoded baud rate: 0x%4.4x", enc_rate);
257 print_field("Explicit baud rate: %u Mbps", exp_rate);
260 static void write_sco_pcm_int_param_cmd(uint16_t index, const void *data,
263 uint8_t routing = get_u8(data);
264 uint8_t rate = get_u8(data + 1);
265 uint8_t frame_type = get_u8(data + 2);
266 uint8_t sync_mode = get_u8(data + 3);
267 uint8_t clock_mode = get_u8(data + 4);
269 print_sco_routing(routing);
270 print_pcm_interface_rate(rate);
271 print_frame_type(frame_type);
272 print_sync_mode(sync_mode);
273 print_clock_mode(clock_mode);
276 static void read_sco_pcm_int_param_rsp(uint16_t index, const void *data,
279 uint8_t status = get_u8(data);
280 uint8_t routing = get_u8(data + 1);
281 uint8_t rate = get_u8(data + 2);
282 uint8_t frame_type = get_u8(data + 3);
283 uint8_t sync_mode = get_u8(data + 4);
284 uint8_t clock_mode = get_u8(data + 5);
286 print_status(status);
287 print_sco_routing(routing);
288 print_pcm_interface_rate(rate);
289 print_frame_type(frame_type);
290 print_sync_mode(sync_mode);
291 print_clock_mode(clock_mode);
294 static void set_sleepmode_param_cmd(uint16_t index, const void *data,
297 uint8_t mode = get_u8(data);
299 print_sleep_mode(mode);
301 packet_hexdump(data + 1, size - 1);
304 static void read_sleepmode_param_rsp(uint16_t index, const void *data,
307 uint8_t status = get_u8(data);
308 uint8_t mode = get_u8(data + 1);
310 print_status(status);
311 print_sleep_mode(mode);
313 packet_hexdump(data + 2, size - 2);
316 static void enable_radio_cmd(uint16_t index, const void *data,
319 uint8_t mode = get_u8(data);
324 str = "Disable the radio";
327 str = "Enable the radio";
334 print_field("Mode: %s (0x%2.2x)", str, mode);
337 static void enable_usb_hid_emulation_cmd(uint16_t index, const void *data,
340 uint8_t enable = get_u8(data);
345 str = "Bluetooth mode";
355 print_field("Enable: %s (0x%2.2x)", str, enable);
358 static void read_uart_clock_setting_rsp(uint16_t index, const void *data,
361 uint8_t status = get_u8(data);
362 uint8_t clock = get_u8(data + 1);
364 print_status(status);
365 print_clock_setting(clock);
368 static void write_uart_clock_setting_cmd(uint16_t index, const void *data,
371 uint8_t clock = get_u8(data);
373 print_clock_setting(clock);
376 static void read_raw_rssi_cmd(uint16_t index, const void *data, uint8_t size)
378 uint16_t handle = get_le16(data);
380 print_handle(handle);
383 static void read_raw_rssi_rsp(uint16_t index, const void *data, uint8_t size)
385 uint8_t status = get_u8(data);
386 uint16_t handle = get_le16(data + 1);
387 int8_t rssi = get_s8(data + 3);
389 print_status(status);
390 print_handle(handle);
394 static void write_ram_cmd(uint16_t index, const void *data, uint8_t size)
396 uint32_t addr = get_le32(data);
398 print_field("Address: 0x%8.8x", addr);
400 packet_hexdump(data + 4, size - 4);
403 static void read_ram_cmd(uint16_t index, const void *data, uint8_t size)
405 uint32_t addr = get_le32(data);
406 uint8_t length = get_u8(data + 4);
408 print_field("Address: 0x%8.8x", addr);
409 print_field("Length: %u", length);
412 static void read_ram_rsp(uint16_t index, const void *data, uint8_t size)
414 uint8_t status = get_u8(data);
416 print_status(status);
418 packet_hexdump(data + 1, size - 1);
421 static void launch_ram_cmd(uint16_t index, const void *data, uint8_t size)
423 uint32_t addr = get_le32(data);
425 print_field("Address: 0x%8.8x", addr);
428 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
429 static void set_advt_param_multi_subcmd(const void *data, uint8_t size)
431 uint8_t adv_instance = get_u8(data + size - 2);
432 int8_t tx_power = *((int8_t *)(data + size - 1));
434 print_le_set_adv_parameters_cmd(data, size - 2);
436 print_field("Advertising Instance: %u", adv_instance);
437 print_field("TX Power: %d", tx_power);
440 static void set_advt_data_subcmd(const void *data, uint8_t size)
442 uint8_t adv_instance = get_u8(data + size - 1);
444 print_le_set_adv_data_cmd(data, size - 1);
446 print_field("Advertising Instance: %u", adv_instance);
449 static void set_scan_rsp_data_multi_subcmd(const void *data, uint8_t size)
451 uint8_t adv_instance = get_u8(data + size - 1);
453 print_le_set_scan_rsp_data_cmd(data, size - 1);
455 print_field("Advertising Instance: %u", adv_instance);
458 static void set_random_addr_multi_subcmd(const void *data, uint8_t size)
460 uint8_t adv_instance = get_u8(data + size - 1);
462 print_le_set_random_address_cmd(data, size - 1);
464 print_field("Advertising Instance: %u", adv_instance);
467 static void set_adv_enable_multi_subcmd(const void *data, uint8_t size)
469 uint8_t adv_instance = get_u8(data + size - 1);
471 print_le_set_adv_enable_cmd(data, size - 1);
473 print_field("Advertising Instance: %u", adv_instance);
476 static void enable_custom_feature_subcmd(const void *data, uint8_t size)
478 uint8_t enable = get_u8(data);
493 print_field("%s offloaded RPA feature (0x%2.2x)", str, enable);
496 static void add_irk_to_list_subcmd(const void *data, uint8_t size)
498 uint8_t addr_type = get_u8(data + 16);
499 const uint8_t *addr = data + 17;
502 print_field("LE IRK (1st byte LSB)");
503 packet_hexdump(data, 16);
507 str = "Public Address";
510 str = "Random Address";
517 print_field("Address type : %s (0x%2.2x)", str, addr_type);
518 print_field("Address : %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
519 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
522 static void remove_irk_from_list_subcmd(const void *data, uint8_t size)
524 uint8_t addr_type = get_u8(data);
525 const uint8_t *addr = data + 1;
530 str = "Public Address";
533 str = "Random Address";
540 print_field("Address type : %s (0x%2.2x)", str, addr_type);
541 print_field("Address : %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
542 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
545 static void read_irk_list_entry_subcmd(const void *data, uint8_t size)
547 uint8_t index = get_u8(data);
549 print_field("LE Read IRK List entry index : %u", index);
552 static void apcf_enable_subcmd(const void *data, uint8_t size)
554 uint8_t enable = get_u8(data);
569 print_field("%s APCF feature (0x%2.2x)", str, enable);
572 static const struct {
575 } apcf_feature_table[] = {
576 { 0, "Broadcast Address filter" },
577 { 1, "Service Data Change filter" },
578 { 2, "Service UUID check" },
579 { 3, "Service Solicitation UUID check" },
580 { 4, "Local Name check" },
581 { 5, "Manufacturer Data check" },
582 { 6, "Service Data check" },
586 static void print_apcf_feature(const char *label, uint16_t feature)
593 print_field("%s", label);
595 for (i = 0; apcf_feature_table[i].str; i++) {
596 if (feature & (1 << apcf_feature_table[i].bit)) {
597 print_field(" %s", apcf_feature_table[i].str);
598 mask &= ~(1 << apcf_feature_table[i].bit);
603 print_field(" Unknown features (0x%4.4x)", mask);
606 static void apcf_set_filtering_param_subcmd(const void *data, uint8_t size)
608 uint8_t add = get_u8(data);
609 uint8_t index = get_u8(data + 1);
610 uint16_t feature_selection = get_le16(data + 2);
611 uint16_t list_logic = get_le16(data + 4);
612 uint16_t filter_logic = get_u8(data + 6);
613 uint8_t rssi_high = get_u8(data + 8);
614 uint8_t delivery_mode = get_u8(data + 9);
615 uint16_t onfound_timeout = get_le16(data + 10);
616 uint8_t onfound_timeout_cnt = get_u8(data + 12);
617 uint8_t rssi_low = get_u8(data + 13);
618 uint16_t onlost_timeout = get_le16(data + 14);
619 uint16_t no_of_tracking_entries;
637 print_field("Action : %s for filter [%d]", str, index);
639 print_apcf_feature("Feature Selection", feature_selection);
640 print_apcf_feature("List Logic Type (OR)", ~list_logic);
641 print_apcf_feature("List Logic Type (AND)", list_logic);
642 print_apcf_feature("Filter Logic Type (OR)", ~(filter_logic << 3));
643 print_apcf_feature("Filter Logic Type (AND)", filter_logic << 3);
644 print_field("RSSI High Threshold : %d dBm", rssi_high);
646 switch (delivery_mode) {
661 print_field("Delivery_mode : %s", str);
662 print_field("On Found Timeout : %d miliseconds", onfound_timeout);
663 print_field("On Found Timeout Count : %d", onfound_timeout_cnt);
664 print_field("RSSI Low Threshold : %d dBm", rssi_low);
665 print_field("On Lost Timeout : %d miliseconds", onlost_timeout);
668 no_of_tracking_entries = get_le16(data + 16);
669 print_field("Number of Tracking Entries : %d",
670 no_of_tracking_entries);
674 static void apcf_broadcaster_addr_subcmd(const void *data, uint8_t size)
676 uint8_t add = get_u8(data);
677 uint8_t index = get_u8(data + 1);
678 uint8_t type = get_u8(data + 7);
696 print_field("Action : %s for filter [%d]", str, index);
697 packet_print_addr("Address", data + 2, type == 0x00 ? false : true);
700 static void apcf_service_uuid_subcmd(const void *data, uint8_t size)
702 uint8_t add = get_u8(data);
703 uint8_t index = get_u8(data + 1);
725 print_field("Action : %s for filter [%d]", str, index);
727 switch ((size - 2) / 2) {
729 uuid16 = get_le16(data + 2);
730 print_field(" UUID : %s (0x%4.4x)",
731 uuid16_to_str(uuid16), uuid16);
733 uuid16 = get_le16(data + 4);
734 print_field(" UUID Mask: %s (0x%4.4x)",
735 uuid16_to_str(uuid16), uuid16);
738 uuid32 = get_le32(data + 2);
739 print_field(" UUID :%s (0x%8.8x)",
740 uuid32_to_str(uuid32), uuid32);
742 uuid32 = get_le32(data + 6);
743 print_field(" UUID Mask:%s (0x%8.8x)",
744 uuid32_to_str(uuid32), uuid32);
748 print_field(" UUID :%8.8x-%4.4x-%4.4x-%4.4x-%8.8x%4.4x",
749 get_le32(&uuid[12]), get_le16(&uuid[10]),
750 get_le16(&uuid[8]), get_le16(&uuid[6]),
751 get_le32(&uuid[2]), get_le16(&uuid[0]));
753 print_field(" UUID :%8.8x-%4.4x-%4.4x-%4.4x-%8.8x%4.4x",
754 get_le32(&uuid[12]), get_le16(&uuid[10]),
755 get_le16(&uuid[8]), get_le16(&uuid[6]),
756 get_le32(&uuid[2]), get_le16(&uuid[0]));
759 print_field("Invalid UUIDs");
760 packet_hexdump(data + 2, size - 2);
767 static void apcf_service_solicitation_uuid_subcmd(const void *data, uint8_t size)
769 apcf_service_uuid_subcmd(data, size);
772 static void apcf_local_name_subcmd(const void *data, uint8_t size)
774 uint8_t add = get_u8(data);
775 uint8_t index = get_u8(data + 1);
777 char name[30] = { 0 };
794 print_field("Action : %s for filter [%d]", str, index);
796 memcpy(name, data + 2, size - 2 < 29 ? size - 2 : 29);
797 print_field("Local Name : %s", name);
800 static void apcf_manufacturer_data_subcmd(const void *data, uint8_t size)
802 uint8_t add = get_u8(data);
803 uint8_t index = get_u8(data + 1);
821 print_field("Action : %s for filter [%d]", str, index);
823 print_field("Manufacturer data");
824 packet_hexdump(data + 2, (size - 2 ) / 2);
826 print_field("Manufacturer data Mask");
827 packet_hexdump(data + 2 + (size - 2) / 2, (size - 2 ) / 2);
830 static void apcf_service_data_subcmd(const void *data, uint8_t size)
832 uint8_t add = get_u8(data);
833 uint8_t index = get_u8(data + 1);
851 print_field("Action : %s for filter [%d]", str, index);
853 print_field("Service data");
854 packet_hexdump(data + 2, (size - 2 ) / 2);
856 print_field("Service data Mask");
857 packet_hexdump(data + 2 + (size - 2) / 2, (size - 2 ) / 2);
863 void (*cmd_func) (const void *data, uint8_t size);
868 static void print_subcmd(const struct subcmd_data *subcmd_data,
869 const void *data, uint8_t size)
871 const char *subcmd_color;
873 if (subcmd_data->cmd_func)
874 subcmd_color = COLOR_BLUE;
876 subcmd_color = COLOR_WHITE_BG;
878 print_indent(6, subcmd_color, "", subcmd_data->str, COLOR_OFF,
879 " (0x%2.2x)", subcmd_data->subcmd);
881 if (!subcmd_data->cmd_func) {
882 packet_hexdump(data, size);
886 if (subcmd_data->cmd_fixed) {
887 if (size != subcmd_data->cmd_size) {
888 print_text(COLOR_ERROR, "invalid packet size");
889 packet_hexdump(data, size);
893 if (size < subcmd_data->cmd_size) {
894 print_text(COLOR_ERROR, "too short packet");
895 packet_hexdump(data, size);
900 subcmd_data->cmd_func(data, size);
903 static const struct subcmd_data le_multi_advt_table[] = {
904 { 0x01, "LE Set Advertising Parameters Multi Sub Command",
905 set_advt_param_multi_subcmd, 23, true },
906 { 0x02, "LE Set Advertising Data Multi Sub Command",
907 set_advt_data_subcmd, 33, false },
908 { 0x03, "LE Set Scan Response Data Multi Sub Command",
909 set_scan_rsp_data_multi_subcmd, 33, false },
910 { 0x04, "LE Set Random Address Multi Sub Command",
911 set_random_addr_multi_subcmd, 7, true },
912 { 0x05, "LE Set Advertise Enable Multi Sub Command",
913 set_adv_enable_multi_subcmd, 2, true },
917 static void le_multi_advt_cmd(uint16_t index, const void *data, uint8_t size)
919 uint8_t subcmd = *((const uint8_t *)data);
920 struct subcmd_data unknown;
921 const struct subcmd_data *subcmd_data = &unknown;
924 unknown.subcmd = subcmd;
925 unknown.str = "Unknown Sub Command";
926 unknown.cmd_func = NULL;
927 unknown.cmd_size = 0;
928 unknown.cmd_fixed = true;
930 for (i = 0; le_multi_advt_table[i].str; i++) {
931 if (le_multi_advt_table[i].subcmd == subcmd) {
932 subcmd_data = &le_multi_advt_table[i];
937 print_subcmd(subcmd_data, data + 1, size - 1);
940 static const struct subcmd_data le_rpa_offload_table[] = {
941 { 0x01, "Enable customer specific feature",
942 enable_custom_feature_subcmd, 1, true },
943 { 0x02, "Add IRK to the list",
944 add_irk_to_list_subcmd, 23, true },
945 { 0x03, "Remove IRK from the list",
946 remove_irk_from_list_subcmd, 7, true },
947 { 0x04, "Clear IRK list",
948 null_cmd_without_index, 0, true },
949 { 0x05, "Read IRK list entry",
950 read_irk_list_entry_subcmd, 1, true },
954 static void le_rpa_offload_cmd(uint16_t index, const void *data, uint8_t size)
956 uint8_t subcmd = *((const uint8_t *)data);
957 struct subcmd_data unknown;
958 const struct subcmd_data *subcmd_data = &unknown;
961 unknown.subcmd = subcmd;
962 unknown.str = "Unknown Sub Command";
963 unknown.cmd_func = NULL;
964 unknown.cmd_size = 0;
965 unknown.cmd_fixed = true;
967 for (i = 0; le_rpa_offload_table[i].str; i++) {
968 if (le_rpa_offload_table[i].subcmd == subcmd) {
969 subcmd_data = &le_rpa_offload_table[i];
974 print_subcmd(subcmd_data, data + 1, size - 1);
977 static const struct subcmd_data le_apcf_table[] = {
978 { 0x00, "APCF Enable",
979 apcf_enable_subcmd, 1, true },
980 { 0x01, "APCF Set Filtering Parameters",
981 apcf_set_filtering_param_subcmd, 15, false },
982 { 0x02, "APCF Broadcaster Address",
983 apcf_broadcaster_addr_subcmd, 9, true },
984 { 0x03, "APCF Service UUID",
985 apcf_service_uuid_subcmd, 2, false },
986 { 0x04, "APCF Service Solicitation UUID",
987 apcf_service_solicitation_uuid_subcmd, 2, false },
988 { 0x05, "APCF Local Name",
989 apcf_local_name_subcmd, 2, false },
990 { 0x06, "APCF Manufacturer Data",
991 apcf_manufacturer_data_subcmd, 2, false },
992 { 0x07, "APCF Service Data",
993 apcf_service_data_subcmd, 2, false },
997 static void le_apcf_cmd(uint16_t index, const void *data, uint8_t size)
999 uint8_t subcmd = *((const uint8_t *)data);
1000 struct subcmd_data unknown;
1001 const struct subcmd_data *subcmd_data = &unknown;
1004 unknown.subcmd = subcmd;
1005 unknown.str = "Unknown Sub Command";
1006 unknown.cmd_func = NULL;
1007 unknown.cmd_size = 0;
1008 unknown.cmd_fixed = true;
1010 for (i = 0; le_apcf_table[i].str; i++) {
1011 if (le_apcf_table[i].subcmd == subcmd) {
1012 subcmd_data = &le_apcf_table[i];
1017 print_subcmd(subcmd_data, data + 1, size - 1);
1021 static void read_vid_pid_rsp(uint16_t index, const void *data, uint8_t size)
1023 uint8_t status = get_u8(data);
1024 uint16_t vid = get_le16(data + 1);
1025 uint16_t pid = get_le16(data + 3);
1027 print_status(status);
1028 print_field("Product: %4.4x:%4.4x", vid, pid);
1031 static void write_high_priority_connection_cmd(uint16_t index, const void *data,
1034 uint16_t handle = get_le16(data);
1035 uint8_t priority = get_u8(data + 2);
1038 print_handle(handle);
1052 print_field("Priority: %s (0x%2.2x)", str, priority);
1055 static const struct {
1058 } features_table[] = {
1059 { 0, "Multi-AV transport bandwidth reducer" },
1062 { 3, "FM SBC internal stack" },
1066 static void print_features(const uint8_t *features_array)
1068 uint64_t mask, features = 0;
1072 for (i = 0; i < 8; i++) {
1073 sprintf(str + (i * 5), " 0x%2.2x", features_array[i]);
1074 features |= ((uint64_t) features_array[i]) << (i * 8);
1077 print_field("Features:%s", str);
1081 for (i = 0; features_table[i].str; i++) {
1082 if (features & (((uint64_t) 1) << features_table[i].bit)) {
1083 print_field(" %s", features_table[i].str);
1084 mask &= ~(((uint64_t) 1) << features_table[i].bit);
1089 print_text(COLOR_UNKNOWN_FEATURE_BIT, " Unknown features "
1090 "(0x%16.16" PRIx64 ")", mask);
1093 static void read_controller_features_rsp(uint16_t index, const void *data,
1096 uint8_t status = get_u8(data);
1098 print_status(status);
1099 print_features(data + 1);
1102 static void read_verbose_version_info_rsp(uint16_t index, const void *data,
1105 uint8_t status = get_u8(data);
1106 uint8_t chip_id = get_u8(data + 1);
1107 uint8_t target_id = get_u8(data + 2);
1108 uint16_t build_base = get_le16(data + 3);
1109 uint16_t build_num = get_le16(data + 5);
1112 print_status(status);
1113 print_field("Chip ID: %u (0x%2.2x)", chip_id, chip_id);
1115 switch (target_id) {
1127 print_field("Build target: %s (%u)", str, target_id);
1128 print_field("Build baseline: %u (0x%4.4x)", build_base, build_base);
1129 print_field("Build number: %u (0x%4.4x)", build_num, build_num);
1132 static void enable_wbs_cmd(uint16_t index, const void *data, uint8_t size)
1134 uint8_t mode = get_u8(data);
1135 uint16_t codec = get_le16(data + 1);
1140 str = "Disable WBS";
1150 print_field("Mode: %s (0x%2.2x)", str, mode);
1167 print_field("Codec: %s (0x%4.4x)", str, codec);
1170 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1171 static void get_vendor_capabilities_rsp(uint16_t index, const void *data, uint8_t size)
1173 uint8_t status = get_u8(data);
1174 uint8_t max_advt_instances = get_u8(data + 1);
1175 uint8_t offloaded_resolution_of_private_address = get_u8(data + 2);
1176 uint16_t total_scan_results_storage = get_le16(data + 3);
1177 uint8_t max_irk_list_sz = get_u8(data + 5);
1178 uint8_t filtering_support = get_u8(data + 6);
1179 uint8_t max_filter = get_u8(data + 7);
1180 uint8_t activity_energy_info_support = get_u8(data + 8);
1181 uint8_t onlost_follow_per_filter = get_u8(data + 9);
1183 print_status(status);
1184 print_field("The Number of advertisement instances supported: %u",
1185 max_advt_instances);
1186 print_field("BT chip capability of RPA: %s",
1187 offloaded_resolution_of_private_address ?
1188 "Capable" : "Not Capable");
1189 print_field("Storage for scan results: %u bytes",
1190 total_scan_results_storage);
1191 print_field("The Number of IRK entries supported: %u", max_irk_list_sz);
1192 print_field("Support Filtering in BT chip: %s",
1193 filtering_support ? "Supported" : "Not Supported");
1194 print_field("The Number of filters supported: %u", max_filter);
1195 print_field("Supports reporting of activity and energy info: %s",
1196 activity_energy_info_support ?
1197 "Capable" : "Not Capable");
1198 print_field("The Number of advertisers that can be analysed for "
1199 "onlost per filter: %u", onlost_follow_per_filter);
1202 static void le_multi_advt_rsp(uint16_t index, const void *data, uint8_t size)
1204 uint8_t status = get_u8(data);
1205 uint8_t subcmd = get_u8(data + 1);
1207 const char *str = "Unknown Sub Command";
1209 print_status(status);
1211 for (i = 0; le_multi_advt_table[i].str; i++) {
1212 if (le_multi_advt_table[i].subcmd == subcmd) {
1213 str = le_multi_advt_table[i].str;
1218 print_field("Multi Advertise OPcode: %s (%u)", str, subcmd);
1221 static void le_rpa_offload_rsp(uint16_t index, const void *data, uint8_t size)
1223 uint8_t status = get_u8(data);
1224 uint8_t subcmd = get_u8(data + 1);
1226 const char *str = "Unknown Sub Command";
1228 print_status(status);
1230 for (i = 0; le_rpa_offload_table[i].str; i++) {
1231 if (le_rpa_offload_table[i].subcmd == subcmd) {
1232 str = le_rpa_offload_table[i].str;
1237 print_field("RPA Offload OPcode: %s (%u)", str, subcmd);
1240 static void le_apcf_rsp(uint16_t index, const void *data, uint8_t size)
1242 uint8_t status = get_u8(data);
1243 uint8_t subcmd = get_u8(data + 1);
1245 const char *str = "Unknown Sub Command";
1247 print_status(status);
1249 for (i = 0; le_apcf_table[i].str; i++) {
1250 if (le_apcf_table[i].subcmd == subcmd) {
1251 str = le_apcf_table[i].str;
1256 print_field("Advertising Packet Content Filter OPcode: %s (%u)",
1261 static const struct vendor_ocf vendor_ocf_table[] = {
1262 { 0x001, "Write BD ADDR",
1263 write_bd_addr_cmd, 6, true,
1264 status_rsp, 1, true },
1265 { 0x018, "Update UART Baud Rate",
1266 update_uart_baud_rate_cmd, 6, true,
1267 status_rsp, 1, true },
1268 { 0x01c, "Write SCO PCM Int Param",
1269 write_sco_pcm_int_param_cmd, 5, true,
1270 status_rsp, 1, true },
1271 { 0x01d, "Read SCO PCM Int Param",
1273 read_sco_pcm_int_param_rsp, 6, true },
1274 { 0x027, "Set Sleepmode Param",
1275 set_sleepmode_param_cmd, 12, true,
1276 status_rsp, 1, true },
1277 { 0x028, "Read Sleepmode Param",
1279 read_sleepmode_param_rsp, 13, true },
1280 { 0x02e, "Download Minidriver",
1282 status_rsp, 1, true },
1283 { 0x034, "Enable Radio",
1284 enable_radio_cmd, 1, true,
1285 status_rsp, 1, true },
1286 { 0x03b, "Enable USB HID Emulation",
1287 enable_usb_hid_emulation_cmd, 1, true,
1288 status_rsp, 1, true },
1289 { 0x044, "Read UART Clock Setting",
1291 read_uart_clock_setting_rsp, 1, true },
1292 { 0x045, "Write UART Clock Setting",
1293 write_uart_clock_setting_cmd, 1, true,
1294 status_rsp, 1, true },
1295 { 0x048, "Read Raw RSSI",
1296 read_raw_rssi_cmd, 2, true,
1297 read_raw_rssi_rsp, 4, true },
1298 { 0x04c, "Write RAM",
1299 write_ram_cmd, 4, false,
1300 status_rsp, 1, true },
1301 { 0x04d, "Read RAM",
1302 read_ram_cmd, 5, true,
1303 read_ram_rsp, 1, false },
1304 { 0x04e, "Launch RAM",
1305 launch_ram_cmd, 4, true,
1306 status_rsp, 1, true },
1307 { 0x05a, "Read VID PID",
1309 read_vid_pid_rsp, 5, true },
1310 { 0x057, "Write High Priority Connection",
1311 write_high_priority_connection_cmd, 3, true,
1312 status_rsp, 1, true },
1313 { 0x06d, "Write I2SPCM Interface Param" },
1314 { 0x06e, "Read Controller Features",
1316 read_controller_features_rsp, 9, true },
1317 { 0x079, "Read Verbose Config Version Info",
1319 read_verbose_version_info_rsp, 7, true },
1320 { 0x07e, "Enable WBS",
1321 enable_wbs_cmd, 3, true,
1322 status_rsp, 1, true },
1323 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1324 { 0x0153, "LE Get Vendor Capabilities",
1326 get_vendor_capabilities_rsp, 10, false },
1327 { 0x0154, "LE Multi Advertise",
1328 le_multi_advt_cmd, 1, false,
1329 le_multi_advt_rsp, 2, true },
1330 { 0x0155, "LE RPA Offload",
1331 le_rpa_offload_cmd, 1, false,
1332 le_rpa_offload_rsp, 2, false },
1334 { 0x0156, "LE Batch Scan",
1335 le_batch_scan_cmd, 1, false,
1336 le_batch_scan_rsp, 2, true },
1338 { 0x0157, "LE APCF",
1339 le_apcf_cmd, 1, false,
1340 le_apcf_rsp, 2, false },
1345 const struct vendor_ocf *broadcom_vendor_ocf(uint16_t ocf)
1349 for (i = 0; vendor_ocf_table[i].str; i++) {
1350 if (vendor_ocf_table[i].ocf == ocf)
1351 return &vendor_ocf_table[i];
1357 void broadcom_lm_diag(const void *data, uint8_t size)
1361 const uint8_t *addr;
1365 packet_hexdump(data, size);
1369 type = *((uint8_t *) data);
1370 clock = get_be32(data + 1);
1377 str = "LMP receive";
1390 print_field("Type: %s (%u)", str, type);
1391 print_field("Clock: 0x%8.8x", clock);
1396 print_field("Address: --:--:%2.2X:%2.2X:%2.2X:%2.2X",
1397 addr[0], addr[1], addr[2], addr[3]);
1398 packet_hexdump(data + 9, 1);
1399 lmp_packet(data + 10, size - 10, true);
1403 print_field("Address: --:--:%2.2X:%2.2X:%2.2X:%2.2X",
1404 addr[0], addr[1], addr[2], addr[3]);
1405 packet_hexdump(data + 9, 4);
1406 lmp_packet(data + 13, size - 13, true);
1410 packet_hexdump(data + 5, 7);
1411 llcp_packet(data + 12, size - 12, true);
1414 packet_hexdump(data + 9, size - 9);
1419 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1420 struct hci_vse_sec_brcm_link_loss_dbg_info{
1421 unsigned char linklost_status;
1422 unsigned char conn_handle;
1425 unsigned char ch_map[10];
1426 unsigned char lmp_cmd[4];
1429 static void linkloss_evt(struct timeval *tv, uint16_t index,
1430 const void *data, uint8_t size)
1433 struct hci_vse_sec_brcm_link_loss_dbg_info *ev = (void *) data;
1434 char *status = NULL;
1435 switch (ev->linklost_status) {
1437 status = "BT_Link_Supervision_Timeout";
1440 status = "LE_Link_Supervision_Timeout";
1443 status = "BT_LMP_Timeout_Local";
1446 status = "BT_LMP_Timeout_Remote";
1449 status = "LE_LMP_Timeout";
1452 status = "Page_Timeout";
1458 print_field("Status:%s,Handle:%02x,Trans_Pwr:%d,RSSI:%d"
1459 " Ch_map:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
1460 " LMP_cmd:0x%x%x%x%x",
1461 status, ev->conn_handle, ev->trans_pwr, ev->rssi,
1462 ev->ch_map[0], ev->ch_map[1], ev->ch_map[2], ev->ch_map[3],
1463 ev->ch_map[4], ev->ch_map[5], ev->ch_map[6], ev->ch_map[7],
1464 ev->ch_map[8], ev->ch_map[9], ev->lmp_cmd[0], ev->lmp_cmd[1],
1465 ev->lmp_cmd[2], ev->lmp_cmd[3]);
1469 static void lm_diag_evt(struct timeval *tv, uint16_t index,
1470 const void *data, uint8_t size)
1472 broadcom_lm_diag(data, 63);
1475 static const struct vendor_evt vendor_evt_table[] = {
1476 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1477 { 0x76, "SEC Link Loss", linkloss_evt, 18, true },
1479 { 0xb4, "LM Diag", lm_diag_evt, 64, true },
1483 const struct vendor_evt *broadcom_vendor_evt(uint8_t evt)
1487 for (i = 0; vendor_evt_table[i].str; i++) {
1488 if (vendor_evt_table[i].evt == evt)
1489 return &vendor_evt_table[i];