0001
0002
0003
0004
0005
0006 #include <net/bluetooth/bluetooth.h>
0007 #include <net/bluetooth/hci_core.h>
0008
0009 #include "aosp.h"
0010
0011
0012
0013
0014
0015
0016
0017 struct aosp_rp_le_get_vendor_capa {
0018
0019 __u8 status;
0020 __u8 max_advt_instances;
0021 __u8 offloaded_resolution_of_private_address;
0022 __le16 total_scan_results_storage;
0023 __u8 max_irk_list_sz;
0024 __u8 filtering_support;
0025 __u8 max_filter;
0026 __u8 activity_energy_info_support;
0027 __le16 version_supported;
0028 __le16 total_num_of_advt_tracked;
0029 __u8 extended_scan_support;
0030 __u8 debug_logging_supported;
0031
0032 __u8 le_address_generation_offloading_support;
0033
0034 __le32 a2dp_source_offload_capability_mask;
0035 __u8 bluetooth_quality_report_support;
0036
0037 __le32 dynamic_audio_buffer_support;
0038 } __packed;
0039
0040 #define VENDOR_CAPA_BASE_SIZE 15
0041 #define VENDOR_CAPA_0_98_SIZE 21
0042
0043 void aosp_do_open(struct hci_dev *hdev)
0044 {
0045 struct sk_buff *skb;
0046 struct aosp_rp_le_get_vendor_capa *rp;
0047 u16 version_supported;
0048
0049 if (!hdev->aosp_capable)
0050 return;
0051
0052 bt_dev_dbg(hdev, "Initialize AOSP extension");
0053
0054
0055 skb = __hci_cmd_sync(hdev, hci_opcode_pack(0x3f, 0x153), 0, NULL,
0056 HCI_CMD_TIMEOUT);
0057 if (IS_ERR_OR_NULL(skb)) {
0058 if (!skb)
0059 skb = ERR_PTR(-EIO);
0060
0061 bt_dev_err(hdev, "AOSP get vendor capabilities (%ld)",
0062 PTR_ERR(skb));
0063 return;
0064 }
0065
0066
0067 if (skb->len < VENDOR_CAPA_BASE_SIZE)
0068 goto length_error;
0069
0070 rp = (struct aosp_rp_le_get_vendor_capa *)skb->data;
0071
0072 version_supported = le16_to_cpu(rp->version_supported);
0073
0074 bt_dev_info(hdev, "AOSP extensions version v%u.%02u",
0075 version_supported >> 8, version_supported & 0xff);
0076
0077
0078 if (version_supported < 95) {
0079 bt_dev_warn(hdev, "AOSP capabilities version %u too old",
0080 version_supported);
0081 goto done;
0082 }
0083
0084 if (version_supported < 98) {
0085 bt_dev_warn(hdev, "AOSP quality report is not supported");
0086 goto done;
0087 }
0088
0089 if (skb->len < VENDOR_CAPA_0_98_SIZE)
0090 goto length_error;
0091
0092
0093
0094
0095
0096
0097 if (rp->bluetooth_quality_report_support) {
0098 hdev->aosp_quality_report = true;
0099 bt_dev_info(hdev, "AOSP quality report is supported");
0100 }
0101
0102 goto done;
0103
0104 length_error:
0105 bt_dev_err(hdev, "AOSP capabilities length %d too short", skb->len);
0106
0107 done:
0108 kfree_skb(skb);
0109 }
0110
0111 void aosp_do_close(struct hci_dev *hdev)
0112 {
0113 if (!hdev->aosp_capable)
0114 return;
0115
0116 bt_dev_dbg(hdev, "Cleanup of AOSP extension");
0117 }
0118
0119
0120 #define BQR_OPCODE hci_opcode_pack(0x3f, 0x015e)
0121
0122
0123 #define REPORT_ACTION_ADD 0x00
0124 #define REPORT_ACTION_DELETE 0x01
0125 #define REPORT_ACTION_CLEAR 0x02
0126
0127
0128 #define QUALITY_MONITORING BIT(0)
0129 #define APPRAOCHING_LSTO BIT(1)
0130 #define A2DP_AUDIO_CHOPPY BIT(2)
0131 #define SCO_VOICE_CHOPPY BIT(3)
0132
0133 #define DEFAULT_BQR_EVENT_MASK (QUALITY_MONITORING | APPRAOCHING_LSTO | \
0134 A2DP_AUDIO_CHOPPY | SCO_VOICE_CHOPPY)
0135
0136
0137
0138
0139 #define DEFALUT_REPORT_INTERVAL_MS 5000
0140
0141 struct aosp_bqr_cp {
0142 __u8 report_action;
0143 __u32 event_mask;
0144 __u16 min_report_interval;
0145 } __packed;
0146
0147 static int enable_quality_report(struct hci_dev *hdev)
0148 {
0149 struct sk_buff *skb;
0150 struct aosp_bqr_cp cp;
0151
0152 cp.report_action = REPORT_ACTION_ADD;
0153 cp.event_mask = DEFAULT_BQR_EVENT_MASK;
0154 cp.min_report_interval = DEFALUT_REPORT_INTERVAL_MS;
0155
0156 skb = __hci_cmd_sync(hdev, BQR_OPCODE, sizeof(cp), &cp,
0157 HCI_CMD_TIMEOUT);
0158 if (IS_ERR_OR_NULL(skb)) {
0159 if (!skb)
0160 skb = ERR_PTR(-EIO);
0161
0162 bt_dev_err(hdev, "Enabling Android BQR failed (%ld)",
0163 PTR_ERR(skb));
0164 return PTR_ERR(skb);
0165 }
0166
0167 kfree_skb(skb);
0168 return 0;
0169 }
0170
0171 static int disable_quality_report(struct hci_dev *hdev)
0172 {
0173 struct sk_buff *skb;
0174 struct aosp_bqr_cp cp = { 0 };
0175
0176 cp.report_action = REPORT_ACTION_CLEAR;
0177
0178 skb = __hci_cmd_sync(hdev, BQR_OPCODE, sizeof(cp), &cp,
0179 HCI_CMD_TIMEOUT);
0180 if (IS_ERR_OR_NULL(skb)) {
0181 if (!skb)
0182 skb = ERR_PTR(-EIO);
0183
0184 bt_dev_err(hdev, "Disabling Android BQR failed (%ld)",
0185 PTR_ERR(skb));
0186 return PTR_ERR(skb);
0187 }
0188
0189 kfree_skb(skb);
0190 return 0;
0191 }
0192
0193 bool aosp_has_quality_report(struct hci_dev *hdev)
0194 {
0195 return hdev->aosp_quality_report;
0196 }
0197
0198 int aosp_set_quality_report(struct hci_dev *hdev, bool enable)
0199 {
0200 if (!aosp_has_quality_report(hdev))
0201 return -EOPNOTSUPP;
0202
0203 bt_dev_dbg(hdev, "quality report enable %d", enable);
0204
0205
0206 if (enable)
0207 return enable_quality_report(hdev);
0208 else
0209 return disable_quality_report(hdev);
0210 }