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