Linux Audio

Check our new training course

Loading...
v6.8
  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 */
 17struct 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
 43void 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
104length_error:
105	bt_dev_err(hdev, "AOSP capabilities length %d too short", skb->len);
106
107done:
108	kfree_skb(skb);
109}
110
111void 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
141struct aosp_bqr_cp {
142	__u8	report_action;
143	__u32	event_mask;
144	__u16	min_report_interval;
145} __packed;
146
147static 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
171static 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
193bool aosp_has_quality_report(struct hci_dev *hdev)
194{
195	return hdev->aosp_quality_report;
196}
197
198int 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}
v6.13.7
  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 */
 17struct 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
 43void 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
104length_error:
105	bt_dev_err(hdev, "AOSP capabilities length %d too short", skb->len);
106
107done:
108	kfree_skb(skb);
109}
110
111void 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
141struct aosp_bqr_cp {
142	__u8	report_action;
143	__u32	event_mask;
144	__u16	min_report_interval;
145} __packed;
146
147static 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
171static 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
193bool aosp_has_quality_report(struct hci_dev *hdev)
194{
195	return hdev->aosp_quality_report;
196}
197
198int 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}