Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2021 Intel Corporation
0004  */
0005 
0006 #include <net/bluetooth/bluetooth.h>
0007 #include <net/bluetooth/hci_core.h>
0008 
0009 #include "aosp.h"
0010 
0011 /* Command complete parameters of LE_Get_Vendor_Capabilities_Command
0012  * The parameters grow over time. The base version that declares the
0013  * version_supported field is v0.95. Refer to
0014  * https://cs.android.com/android/platform/superproject/+/master:system/
0015  *         bt/gd/hci/controller.cc;l=452?q=le_get_vendor_capabilities_handler
0016  */
0017 struct aosp_rp_le_get_vendor_capa {
0018     /* v0.95: 15 octets */
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     /* v0.96: 16 octets */
0032     __u8    le_address_generation_offloading_support;
0033     /* v0.98: 21 octets */
0034     __le32  a2dp_source_offload_capability_mask;
0035     __u8    bluetooth_quality_report_support;
0036     /* v1.00: 25 octets */
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     /* LE Get Vendor Capabilities Command */
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     /* A basic length check */
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     /* AOSP displays the verion number like v0.98, v1.00, etc. */
0074     bt_dev_info(hdev, "AOSP extensions version v%u.%02u",
0075             version_supported >> 8, version_supported & 0xff);
0076 
0077     /* Do not support very old versions. */
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     /* The bluetooth_quality_report_support is defined at version
0093      * v0.98. Refer to
0094      * https://cs.android.com/android/platform/superproject/+/
0095      *         master:system/bt/gd/hci/controller.cc;l=477
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 /* BQR command */
0120 #define BQR_OPCODE          hci_opcode_pack(0x3f, 0x015e)
0121 
0122 /* BQR report action */
0123 #define REPORT_ACTION_ADD       0x00
0124 #define REPORT_ACTION_DELETE        0x01
0125 #define REPORT_ACTION_CLEAR     0x02
0126 
0127 /* BQR event masks */
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 /* Reporting at milliseconds so as not to stress the controller too much.
0137  * Range: 0 ~ 65535 ms
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     /* Enable or disable the quality report feature. */
0206     if (enable)
0207         return enable_quality_report(hdev);
0208     else
0209         return disable_quality_report(hdev);
0210 }