cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

aosp.c (5049B)


      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(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
    101length_error:
    102	bt_dev_err(hdev, "AOSP capabilities length %d too short", skb->len);
    103
    104done:
    105	kfree_skb(skb);
    106}
    107
    108void 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
    138struct aosp_bqr_cp {
    139	__u8	report_action;
    140	__u32	event_mask;
    141	__u16	min_report_interval;
    142} __packed;
    143
    144static 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
    165static 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
    184bool aosp_has_quality_report(struct hci_dev *hdev)
    185{
    186	return hdev->aosp_quality_report;
    187}
    188
    189int 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}