xref: /openbmc/linux/net/bluetooth/aosp.c (revision 0a94608f)
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(skb)) {
58 		bt_dev_err(hdev, "AOSP get vendor capabilities (%ld)",
59 			   PTR_ERR(skb));
60 		return;
61 	}
62 
63 	/* A basic length check */
64 	if (skb->len < VENDOR_CAPA_BASE_SIZE)
65 		goto length_error;
66 
67 	rp = (struct aosp_rp_le_get_vendor_capa *)skb->data;
68 
69 	version_supported = le16_to_cpu(rp->version_supported);
70 	/* AOSP displays the verion number like v0.98, v1.00, etc. */
71 	bt_dev_info(hdev, "AOSP extensions version v%u.%02u",
72 		    version_supported >> 8, version_supported & 0xff);
73 
74 	/* Do not support very old versions. */
75 	if (version_supported < 95) {
76 		bt_dev_warn(hdev, "AOSP capabilities version %u too old",
77 			    version_supported);
78 		goto done;
79 	}
80 
81 	if (version_supported < 98) {
82 		bt_dev_warn(hdev, "AOSP quality report is not supported");
83 		goto done;
84 	}
85 
86 	if (skb->len < VENDOR_CAPA_0_98_SIZE)
87 		goto length_error;
88 
89 	/* The bluetooth_quality_report_support is defined at version
90 	 * v0.98. Refer to
91 	 * https://cs.android.com/android/platform/superproject/+/
92 	 *         master:system/bt/gd/hci/controller.cc;l=477
93 	 */
94 	if (rp->bluetooth_quality_report_support) {
95 		hdev->aosp_quality_report = true;
96 		bt_dev_info(hdev, "AOSP quality report is supported");
97 	}
98 
99 	goto done;
100 
101 length_error:
102 	bt_dev_err(hdev, "AOSP capabilities length %d too short", skb->len);
103 
104 done:
105 	kfree_skb(skb);
106 }
107 
108 void aosp_do_close(struct hci_dev *hdev)
109 {
110 	if (!hdev->aosp_capable)
111 		return;
112 
113 	bt_dev_dbg(hdev, "Cleanup of AOSP extension");
114 }
115 
116 /* BQR command */
117 #define BQR_OPCODE			hci_opcode_pack(0x3f, 0x015e)
118 
119 /* BQR report action */
120 #define REPORT_ACTION_ADD		0x00
121 #define REPORT_ACTION_DELETE		0x01
122 #define REPORT_ACTION_CLEAR		0x02
123 
124 /* BQR event masks */
125 #define QUALITY_MONITORING		BIT(0)
126 #define APPRAOCHING_LSTO		BIT(1)
127 #define A2DP_AUDIO_CHOPPY		BIT(2)
128 #define SCO_VOICE_CHOPPY		BIT(3)
129 
130 #define DEFAULT_BQR_EVENT_MASK	(QUALITY_MONITORING | APPRAOCHING_LSTO | \
131 				 A2DP_AUDIO_CHOPPY | SCO_VOICE_CHOPPY)
132 
133 /* Reporting at milliseconds so as not to stress the controller too much.
134  * Range: 0 ~ 65535 ms
135  */
136 #define DEFALUT_REPORT_INTERVAL_MS	5000
137 
138 struct aosp_bqr_cp {
139 	__u8	report_action;
140 	__u32	event_mask;
141 	__u16	min_report_interval;
142 } __packed;
143 
144 static int enable_quality_report(struct hci_dev *hdev)
145 {
146 	struct sk_buff *skb;
147 	struct aosp_bqr_cp cp;
148 
149 	cp.report_action = REPORT_ACTION_ADD;
150 	cp.event_mask = DEFAULT_BQR_EVENT_MASK;
151 	cp.min_report_interval = DEFALUT_REPORT_INTERVAL_MS;
152 
153 	skb = __hci_cmd_sync(hdev, BQR_OPCODE, sizeof(cp), &cp,
154 			     HCI_CMD_TIMEOUT);
155 	if (IS_ERR(skb)) {
156 		bt_dev_err(hdev, "Enabling Android BQR failed (%ld)",
157 			   PTR_ERR(skb));
158 		return PTR_ERR(skb);
159 	}
160 
161 	kfree_skb(skb);
162 	return 0;
163 }
164 
165 static int disable_quality_report(struct hci_dev *hdev)
166 {
167 	struct sk_buff *skb;
168 	struct aosp_bqr_cp cp = { 0 };
169 
170 	cp.report_action = REPORT_ACTION_CLEAR;
171 
172 	skb = __hci_cmd_sync(hdev, BQR_OPCODE, sizeof(cp), &cp,
173 			     HCI_CMD_TIMEOUT);
174 	if (IS_ERR(skb)) {
175 		bt_dev_err(hdev, "Disabling Android BQR failed (%ld)",
176 			   PTR_ERR(skb));
177 		return PTR_ERR(skb);
178 	}
179 
180 	kfree_skb(skb);
181 	return 0;
182 }
183 
184 bool aosp_has_quality_report(struct hci_dev *hdev)
185 {
186 	return hdev->aosp_quality_report;
187 }
188 
189 int aosp_set_quality_report(struct hci_dev *hdev, bool enable)
190 {
191 	if (!aosp_has_quality_report(hdev))
192 		return -EOPNOTSUPP;
193 
194 	bt_dev_dbg(hdev, "quality report enable %d", enable);
195 
196 	/* Enable or disable the quality report feature. */
197 	if (enable)
198 		return enable_quality_report(hdev);
199 	else
200 		return disable_quality_report(hdev);
201 }
202