msft.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. *
  3. * BlueZ - Bluetooth protocol stack for Linux
  4. *
  5. * Copyright (C) 2011-2014 Intel Corporation
  6. * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
  7. *
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 2.1 of the License, or (at your option) any later version.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. */
  24. #ifdef HAVE_CONFIG_H
  25. #include <config.h>
  26. #endif
  27. #define _GNU_SOURCE
  28. #include <stdio.h>
  29. #include <inttypes.h>
  30. #include "src/shared/util.h"
  31. #include "display.h"
  32. #include "packet.h"
  33. #include "vendor.h"
  34. #include "msft.h"
  35. #define COLOR_COMMAND COLOR_BLUE
  36. #define COLOR_COMMAND_UNKNOWN COLOR_WHITE_BG
  37. static void null_cmd(const void *data, uint16_t size)
  38. {
  39. }
  40. static void null_rsp(const void *data, uint16_t size)
  41. {
  42. }
  43. static void read_supported_features_rsp(const void *data, uint16_t size)
  44. {
  45. uint8_t evt_prefix_len = get_u8(data + 8);
  46. packet_print_features_msft(data);
  47. print_field("Event prefix length: %u", evt_prefix_len);
  48. packet_hexdump(data + 9, size - 9);
  49. packet_set_msft_evt_prefix(data + 9, evt_prefix_len);
  50. }
  51. static void le_monitor_advertisement_cmd(const void *data, uint16_t size)
  52. {
  53. int8_t threshold_high = get_s8(data);
  54. int8_t threshold_low = get_s8(data + 1);
  55. uint8_t threshold_low_time_interval = get_u8(data + 2);
  56. uint8_t sampling_period = get_u8(data + 3);
  57. packet_print_rssi("RSSI threshold high", threshold_high);
  58. packet_print_rssi("RSSI threshold low", threshold_low);
  59. print_field("RSSI threshold low time interval: %u sec (0x%2.2x)",
  60. threshold_low_time_interval,
  61. threshold_low_time_interval);
  62. print_field("RSSI sampling period: %u msec (0x%2.2x)",
  63. sampling_period * 100,
  64. sampling_period);
  65. packet_hexdump(data + 4, size - 4);
  66. }
  67. static void le_monitor_advertisement_rsp(const void *data, uint16_t size)
  68. {
  69. uint8_t handle = get_u8(data);
  70. print_field("Monitor handle: %u", handle);
  71. }
  72. static void set_adv_filter_enable_cmd(const void *data, uint16_t size)
  73. {
  74. uint8_t enable = get_u8(data);
  75. const char *str;
  76. switch (enable) {
  77. case 0x00:
  78. str = "Current allow list";
  79. break;
  80. case 0x01:
  81. str = "All filter conditions";
  82. break;
  83. default:
  84. str = "Reserved";
  85. break;
  86. }
  87. print_field("Enable: %s (0x%2.2x)", str, enable);
  88. }
  89. typedef void (*func_t) (const void *data, uint16_t size);
  90. static const struct {
  91. uint8_t code;
  92. const char *str;
  93. func_t cmd_func;
  94. func_t rsp_func;
  95. } cmd_table[] = {
  96. { 0x00, "Read Supported Features",
  97. null_cmd,
  98. read_supported_features_rsp },
  99. { 0x01, "Monitor RSSI" },
  100. { 0x02, "Cancel Monitor RSSI" },
  101. { 0x03, "LE Monitor Advertisement",
  102. le_monitor_advertisement_cmd,
  103. le_monitor_advertisement_rsp },
  104. { 0x04, "LE Cancel Monitor Advertisement" },
  105. { 0x05, "LE Set Advertisement Filter Enable",
  106. set_adv_filter_enable_cmd,
  107. null_rsp },
  108. { 0x06, "Read Absolute RSSI" },
  109. { }
  110. };
  111. static void msft_cmd(const void *data, uint8_t size)
  112. {
  113. uint8_t code = get_u8(data);
  114. const char *code_color, *code_str = NULL;
  115. func_t code_func = NULL;
  116. int i;
  117. for (i = 0; cmd_table[i].str; i++) {
  118. if (cmd_table[i].code == code) {
  119. code_str = cmd_table[i].str;
  120. code_func = cmd_table[i].cmd_func;
  121. break;
  122. }
  123. }
  124. if (code_str) {
  125. if (code_func)
  126. code_color = COLOR_COMMAND;
  127. else
  128. code_color = COLOR_COMMAND_UNKNOWN;
  129. } else {
  130. code_color = COLOR_COMMAND_UNKNOWN;
  131. code_str = "Unknown";
  132. }
  133. print_indent(6, code_color, "", code_str, COLOR_OFF,
  134. " (0x%2.2x)", code);
  135. if (code_func)
  136. code_func(data + 1, size - 1);
  137. else
  138. packet_hexdump(data + 1, size - 1);
  139. }
  140. static void msft_rsp(const void *data, uint8_t size)
  141. {
  142. uint8_t status = get_u8(data);
  143. uint8_t code = get_u8(data + 1);
  144. const char *code_color, *code_str = NULL;
  145. func_t code_func = NULL;
  146. int i;
  147. for (i = 0; cmd_table[i].str; i++) {
  148. if (cmd_table[i].code == code) {
  149. code_str = cmd_table[i].str;
  150. code_func = cmd_table[i].rsp_func;
  151. break;
  152. }
  153. }
  154. if (code_str) {
  155. if (code_func)
  156. code_color = COLOR_COMMAND;
  157. else
  158. code_color = COLOR_COMMAND_UNKNOWN;
  159. } else {
  160. code_color = COLOR_COMMAND_UNKNOWN;
  161. code_str = "Unknown";
  162. }
  163. print_indent(6, code_color, "", code_str, COLOR_OFF,
  164. " (0x%2.2x)", code);
  165. packet_print_error("Status", status);
  166. if (code_func)
  167. code_func(data + 2, size - 2);
  168. else
  169. packet_hexdump(data + 2, size - 2);
  170. }
  171. static const struct vendor_ocf vendor_ocf_entry = {
  172. 0x000, "Extension", msft_cmd, 1, false, msft_rsp, 2, false
  173. };
  174. const struct vendor_ocf *msft_vendor_ocf(void)
  175. {
  176. return &vendor_ocf_entry;
  177. }
  178. static void msft_evt(const void *data, uint8_t size)
  179. {
  180. packet_hexdump(data, size);
  181. }
  182. static const struct vendor_evt vendor_evt_entry = {
  183. 0x00, "Extension", msft_evt, 1, false
  184. };
  185. const struct vendor_evt *msft_vendor_evt(void)
  186. {
  187. return &vendor_evt_entry;
  188. }