Skip to content

Commit

Permalink
Send sco handle to btusb sco driver
Browse files Browse the repository at this point in the history
SCO handle is needed in btusb sco driver for proper Tx/Rx voice
data exchange between btusb_soc_snd_card driver and btusb.

Send them using ioctl from BT HAL as soon as SCO connection
established.

Tests done:
1. Flash binary
2. #>adb shell cat proc/asound/cards
3. btaudiosource listed
4. Connect BT headset
5. Verify sco handle sent from bt-hal

Tracked-On: OAM-126126
Signed-off-by: Aiswarya Cyriac <[email protected]>
Signed-off-by: Gowtham Anandha Babu <[email protected]>
  • Loading branch information
gowthambabu92 committed Oct 18, 2024
1 parent 2dbb88c commit cd05a3c
Showing 1 changed file with 235 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
From 865018e7f864c178985a0136e42d7a7bf9f4ecf5 Mon Sep 17 00:00:00 2001
From: Gowtham Anandha Babu <[email protected]>
Date: Wed, 16 Oct 2024 13:05:27 +0000
Subject: [PATCH] Send sco handle to btusb sco driver

SCO handle is needed in btusb sco driver for proper Tx/Rx voice
data exchange between btusb_soc_snd_card driver and btusb.

Send them using ioctl from BT HAL as soon as SCO connection
established.

Tests done:
1. Flash binary
2. #>adb shell cat proc/asound/cards
3. btaudiosource listed
4. Connect BT headset
5. Verify sco handle sent from bt-hal

Tracked-On: OAM-126126
Signed-off-by: Aiswarya Cyriac <[email protected]>
Signed-off-by: Gowtham Anandha Babu <[email protected]>
---
bluetooth/aidl/default/Android.bp | 1 +
bluetooth/hci/Android.bp | 1 +
bluetooth/hci/h4_protocol.cc | 123 ++++++++++++++++++++++++++++++
bluetooth/hci/h4_protocol.h | 8 ++
4 files changed, 133 insertions(+)

diff --git a/bluetooth/aidl/default/Android.bp b/bluetooth/aidl/default/Android.bp
index 9f0f5b4..a7463ae 100644
--- a/bluetooth/aidl/default/Android.bp
+++ b/bluetooth/aidl/default/Android.bp
@@ -51,6 +51,7 @@ cc_binary {
"libhidlbase",
"libutils",
"liblog",
+ "libusb",
],
static_libs: [
"libbluetoothhcihalimplvbt",
diff --git a/bluetooth/hci/Android.bp b/bluetooth/hci/Android.bp
index 72c2dd4..1dd5f0b 100644
--- a/bluetooth/hci/Android.bp
+++ b/bluetooth/hci/Android.bp
@@ -17,6 +17,7 @@ cc_library_static {
"libhidlbase",
"liblog",
"libutils",
+ "libusb",
],
}

diff --git a/bluetooth/hci/h4_protocol.cc b/bluetooth/hci/h4_protocol.cc
index 5f6d86e..e18e552 100644
--- a/bluetooth/hci/h4_protocol.cc
+++ b/bluetooth/hci/h4_protocol.cc
@@ -18,11 +18,36 @@

#define LOG_TAG "android.hardware.bluetooth.hci-h4"

+#include <sys/ioctl.h>
+#include <linux/usbdevice_fs.h>
+#include <asm/byteorder.h>
+#include <linux/usb/ch9.h>
+#include <libusb/libusb.h>
+
+#define HCI_COMMAND_COMPLETE_EVT 0x0E
+#define HCI_COMMAND_STATUS_EVT 0x0F
+#define HCI_ESCO_CONNECTION_COMP_EVT 0x2C
+#define HCI_RESET_SUPPORTED(x) ((x)[5] & 0x80)
+#define HCI_GRP_INFORMATIONAL_PARAMS (0x04 << 10) /* 0x1000 */
+#define HCI_READ_LOCAL_SUPPORTED_CMDS (0x0002 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10) /* 0x0C00 */
+#define HCI_RESET (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+
+#define INTEL_VID 0x8087
+#define INTEL_PID_8265 0x0a2b // Windstorm peak
+#define INTEL_PID_3168 0x0aa7 //SandyPeak (SdP)
+#define INTEL_PID_9260 0x0025 // 9160/9260 (also known as ThunderPeak)
+#define INTEL_PID_9560 0x0aaa // 9460/9560 also know as Jefferson Peak (JfP)
+#define INTEL_PID_AX201 0x0026 // AX201 also know as Harrison Peak (HrP)
+#define INTEL_PID_AX211 0x0033 // AX211 also know as GarfieldPeak (Gfp)
+#define INTEL_PID_AX210 0x0032 // AX210 also know as TyphoonPeak (TyP2)
+
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/uio.h>
+#include <string.h>

#include "log/log.h"

@@ -70,7 +95,82 @@ size_t H4Protocol::Send(PacketType type, const uint8_t* data, size_t length) {
return ret;
}

+bool H4Protocol::IsIntelController(uint16_t vid, uint16_t pid) {
+ if ((vid == INTEL_VID) && ((pid == INTEL_PID_8265) ||
+ (pid == INTEL_PID_3168)||
+ (pid == INTEL_PID_9260)||
+ (pid == INTEL_PID_9560)||
+ (pid == INTEL_PID_AX201)||
+ (pid == INTEL_PID_AX211)||
+ (pid == INTEL_PID_AX210)))
+ return true;
+ else
+ return false;
+}
+
+int H4Protocol::GetUsbpath(void) {
+ size_t count, i;
+ int ret = 0, busnum, devnum;
+ struct libusb_device **dev_list = NULL;
+ struct libusb_context *ctx;
+ uint16_t vid = 0, pid = 0;
+ ALOGD(" Initializing GenericUSB (libusb-1.0)...\n");
+ ret = libusb_init(&ctx);
+ if (ret < 0) {
+ ALOGE("libusb failed to initialize: %d\n", ret);
+ return ret;
+ }
+ count = libusb_get_device_list(ctx, &dev_list);
+ if (count <= 0) {
+ ALOGE("Error getting USB device list: %s\n", strerror(count));
+ goto exit;
+ }
+ for (i = 0; i < count; ++i) {
+ struct libusb_device* dev = dev_list[i];
+ busnum = libusb_get_bus_number(dev);
+ devnum = libusb_get_device_address(dev);
+ struct libusb_device_descriptor descriptor;
+ ret = libusb_get_device_descriptor(dev, &descriptor);
+ if (ret < 0) {
+ ALOGE("Error getting device descriptor %d ", ret);
+ goto exit;
+ }
+ vid = descriptor.idVendor;
+ pid = descriptor.idProduct;
+ if (H4Protocol::IsIntelController(vid, pid)) {
+ snprintf(dev_address, sizeof(dev_address), "/dev/bus/usb/%03d/%03d",
+ busnum, devnum);
+ ALOGD("Value of BT device address = %s", dev_address);
+ goto exit;
+ }
+ }
+exit:
+ libusb_free_device_list(dev_list, count);
+ libusb_exit(ctx);
+ return ret;
+}
+
+int H4Protocol::SendHandle(void) {
+ int fd, ret = 0;
+ fd = open(dev_address,O_WRONLY|O_NONBLOCK);
+ if (fd < 0) {
+ ALOGE("Fail to open USB device %s, value of fd= %d", dev_address, fd);
+ return -1;
+ } else {
+ struct usbdevfs_ioctl wrapper;
+ wrapper.ifno = 1;
+ wrapper.ioctl_code = USBDEVFS_IOCTL;
+ wrapper.data = sco_handle;
+ ret = ioctl(fd, USBDEVFS_IOCTL, &wrapper);
+ if (ret < 0)
+ ALOGE("Failed to send SCO handle err = %d", ret);
+ close(fd);
+ return ret;
+ }
+}
+
size_t H4Protocol::OnPacketReady(const std::vector<uint8_t>& packet) {
+ int ret = 0;
switch (hci_packet_type_) {
case PacketType::COMMAND:
cmd_cb_(packet);
@@ -82,6 +182,29 @@ size_t H4Protocol::OnPacketReady(const std::vector<uint8_t>& packet) {
sco_cb_(packet);
break;
case PacketType::EVENT:
+ if (!packet.empty()) {
+ if (packet[0] == HCI_COMMAND_COMPLETE_EVT) {
+ unsigned int cmd, lsb, msb;
+ msb = packet[4];
+ lsb = packet[3];
+ cmd = msb << 8 | lsb ;
+ if (cmd == HCI_RESET) {
+ event_cb_(packet);
+ hci_packet_type_ = PacketType::UNKNOWN;
+ ret = H4Protocol::GetUsbpath();
+ if (ret < 0)
+ ALOGE("Failed to get the USB path for btusb-sound-card");
+ break;
+ }
+ } else if (packet[0] == HCI_ESCO_CONNECTION_COMP_EVT) {
+ const unsigned char *handle = packet.data() + 3;
+ memcpy(sco_handle, handle, 2);
+ ALOGD("Value of SCO handle = %x, %x", handle[0], handle[1]);
+ ret = H4Protocol::SendHandle();
+ if (ret < 0)
+ ALOGE("Failed to send SCO handle to btusb-sound-card driver");
+ }
+ }
event_cb_(packet);
break;
case PacketType::ISO_DATA:
diff --git a/bluetooth/hci/h4_protocol.h b/bluetooth/hci/h4_protocol.h
index 5daee83..83e76f7 100644
--- a/bluetooth/hci/h4_protocol.h
+++ b/bluetooth/hci/h4_protocol.h
@@ -38,6 +38,12 @@ class H4Protocol {

void OnDataReady();

+ bool IsIntelController(uint16_t vid, uint16_t pid);
+
+ int GetUsbpath(void);
+
+ int SendHandle(void);
+
protected:
size_t OnPacketReady(const std::vector<uint8_t>& packet);
void SendDataToPacketizer(uint8_t* buffer, size_t length);
@@ -45,6 +51,8 @@ class H4Protocol {
private:
int uart_fd_;
bool disconnected_{false};
+ uint8_t sco_handle[2];
+ char dev_address[32];

PacketReadCallback cmd_cb_;
PacketReadCallback acl_cb_;
--
2.34.1

0 comments on commit cd05a3c

Please sign in to comment.