aosp.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2021 Intel Corporation
  4. */
  5. #include <net/bluetooth/bluetooth.h>
  6. #include <net/bluetooth/hci_core.h>
  7. #include "aosp.h"
  8. /* Command complete parameters of LE_Get_Vendor_Capabilities_Command
  9. * The parameters grow over time. The base version that declares the
  10. * version_supported field is v0.95. Refer to
  11. * https://cs.android.com/android/platform/superproject/+/master:system/
  12. * bt/gd/hci/controller.cc;l=452?q=le_get_vendor_capabilities_handler
  13. */
  14. struct aosp_rp_le_get_vendor_capa {
  15. /* v0.95: 15 octets */
  16. __u8 status;
  17. __u8 max_advt_instances;
  18. __u8 offloaded_resolution_of_private_address;
  19. __le16 total_scan_results_storage;
  20. __u8 max_irk_list_sz;
  21. __u8 filtering_support;
  22. __u8 max_filter;
  23. __u8 activity_energy_info_support;
  24. __le16 version_supported;
  25. __le16 total_num_of_advt_tracked;
  26. __u8 extended_scan_support;
  27. __u8 debug_logging_supported;
  28. /* v0.96: 16 octets */
  29. __u8 le_address_generation_offloading_support;
  30. /* v0.98: 21 octets */
  31. __le32 a2dp_source_offload_capability_mask;
  32. __u8 bluetooth_quality_report_support;
  33. /* v1.00: 25 octets */
  34. __le32 dynamic_audio_buffer_support;
  35. } __packed;
  36. #define VENDOR_CAPA_BASE_SIZE 15
  37. #define VENDOR_CAPA_0_98_SIZE 21
  38. void aosp_do_open(struct hci_dev *hdev)
  39. {
  40. struct sk_buff *skb;
  41. struct aosp_rp_le_get_vendor_capa *rp;
  42. u16 version_supported;
  43. if (!hdev->aosp_capable)
  44. return;
  45. bt_dev_dbg(hdev, "Initialize AOSP extension");
  46. /* LE Get Vendor Capabilities Command */
  47. skb = __hci_cmd_sync(hdev, hci_opcode_pack(0x3f, 0x153), 0, NULL,
  48. HCI_CMD_TIMEOUT);
  49. if (IS_ERR_OR_NULL(skb)) {
  50. if (!skb)
  51. skb = ERR_PTR(-EIO);
  52. bt_dev_err(hdev, "AOSP get vendor capabilities (%ld)",
  53. PTR_ERR(skb));
  54. return;
  55. }
  56. /* A basic length check */
  57. if (skb->len < VENDOR_CAPA_BASE_SIZE)
  58. goto length_error;
  59. rp = (struct aosp_rp_le_get_vendor_capa *)skb->data;
  60. version_supported = le16_to_cpu(rp->version_supported);
  61. /* AOSP displays the verion number like v0.98, v1.00, etc. */
  62. bt_dev_info(hdev, "AOSP extensions version v%u.%02u",
  63. version_supported >> 8, version_supported & 0xff);
  64. /* Do not support very old versions. */
  65. if (version_supported < 95) {
  66. bt_dev_warn(hdev, "AOSP capabilities version %u too old",
  67. version_supported);
  68. goto done;
  69. }
  70. if (version_supported < 98) {
  71. bt_dev_warn(hdev, "AOSP quality report is not supported");
  72. goto done;
  73. }
  74. if (skb->len < VENDOR_CAPA_0_98_SIZE)
  75. goto length_error;
  76. /* The bluetooth_quality_report_support is defined at version
  77. * v0.98. Refer to
  78. * https://cs.android.com/android/platform/superproject/+/
  79. * master:system/bt/gd/hci/controller.cc;l=477
  80. */
  81. if (rp->bluetooth_quality_report_support) {
  82. hdev->aosp_quality_report = true;
  83. bt_dev_info(hdev, "AOSP quality report is supported");
  84. }
  85. goto done;
  86. length_error:
  87. bt_dev_err(hdev, "AOSP capabilities length %d too short", skb->len);
  88. done:
  89. kfree_skb(skb);
  90. }
  91. void aosp_do_close(struct hci_dev *hdev)
  92. {
  93. if (!hdev->aosp_capable)
  94. return;
  95. bt_dev_dbg(hdev, "Cleanup of AOSP extension");
  96. }
  97. /* BQR command */
  98. #define BQR_OPCODE hci_opcode_pack(0x3f, 0x015e)
  99. /* BQR report action */
  100. #define REPORT_ACTION_ADD 0x00
  101. #define REPORT_ACTION_DELETE 0x01
  102. #define REPORT_ACTION_CLEAR 0x02
  103. /* BQR event masks */
  104. #define QUALITY_MONITORING BIT(0)
  105. #define APPRAOCHING_LSTO BIT(1)
  106. #define A2DP_AUDIO_CHOPPY BIT(2)
  107. #define SCO_VOICE_CHOPPY BIT(3)
  108. #define DEFAULT_BQR_EVENT_MASK (QUALITY_MONITORING | APPRAOCHING_LSTO | \
  109. A2DP_AUDIO_CHOPPY | SCO_VOICE_CHOPPY)
  110. /* Reporting at milliseconds so as not to stress the controller too much.
  111. * Range: 0 ~ 65535 ms
  112. */
  113. #define DEFALUT_REPORT_INTERVAL_MS 5000
  114. struct aosp_bqr_cp {
  115. __u8 report_action;
  116. __u32 event_mask;
  117. __u16 min_report_interval;
  118. } __packed;
  119. static int enable_quality_report(struct hci_dev *hdev)
  120. {
  121. struct sk_buff *skb;
  122. struct aosp_bqr_cp cp;
  123. cp.report_action = REPORT_ACTION_ADD;
  124. cp.event_mask = DEFAULT_BQR_EVENT_MASK;
  125. cp.min_report_interval = DEFALUT_REPORT_INTERVAL_MS;
  126. skb = __hci_cmd_sync(hdev, BQR_OPCODE, sizeof(cp), &cp,
  127. HCI_CMD_TIMEOUT);
  128. if (IS_ERR_OR_NULL(skb)) {
  129. if (!skb)
  130. skb = ERR_PTR(-EIO);
  131. bt_dev_err(hdev, "Enabling Android BQR failed (%ld)",
  132. PTR_ERR(skb));
  133. return PTR_ERR(skb);
  134. }
  135. kfree_skb(skb);
  136. return 0;
  137. }
  138. static int disable_quality_report(struct hci_dev *hdev)
  139. {
  140. struct sk_buff *skb;
  141. struct aosp_bqr_cp cp = { 0 };
  142. cp.report_action = REPORT_ACTION_CLEAR;
  143. skb = __hci_cmd_sync(hdev, BQR_OPCODE, sizeof(cp), &cp,
  144. HCI_CMD_TIMEOUT);
  145. if (IS_ERR_OR_NULL(skb)) {
  146. if (!skb)
  147. skb = ERR_PTR(-EIO);
  148. bt_dev_err(hdev, "Disabling Android BQR failed (%ld)",
  149. PTR_ERR(skb));
  150. return PTR_ERR(skb);
  151. }
  152. kfree_skb(skb);
  153. return 0;
  154. }
  155. bool aosp_has_quality_report(struct hci_dev *hdev)
  156. {
  157. return hdev->aosp_quality_report;
  158. }
  159. int aosp_set_quality_report(struct hci_dev *hdev, bool enable)
  160. {
  161. if (!aosp_has_quality_report(hdev))
  162. return -EOPNOTSUPP;
  163. bt_dev_dbg(hdev, "quality report enable %d", enable);
  164. /* Enable or disable the quality report feature. */
  165. if (enable)
  166. return enable_quality_report(hdev);
  167. else
  168. return disable_quality_report(hdev);
  169. }