From 75efcfcbb409f028c3579dd8483fd6398e8b925d Mon Sep 17 00:00:00 2001 From: Konsta Date: Sat, 16 Nov 2024 22:23:55 +0200 Subject: [PATCH] bluetooth: adjust rfkill * Switch to android.hardware.bluetooth@1.1-service.btlinux rfkill implementation that uses /sys/class/rfkill/rfkill*/state. --- bluetooth/net_bluetooth_mgmt.cpp | 116 ++++++++++++------------------- bluetooth/net_bluetooth_mgmt.h | 10 +-- 2 files changed, 46 insertions(+), 80 deletions(-) diff --git a/bluetooth/net_bluetooth_mgmt.cpp b/bluetooth/net_bluetooth_mgmt.cpp index a26ef0c..02e74b2 100644 --- a/bluetooth/net_bluetooth_mgmt.cpp +++ b/bluetooth/net_bluetooth_mgmt.cpp @@ -50,6 +50,9 @@ struct sockaddr_hci { #define MGMT_EV_CMD_COMPLETE 0x0001 #define MGMT_PKT_SIZE_MAX 1024 #define MGMT_INDEX_NONE 0xFFFF +#define WRITE_NO_INTR(fn) \ + do { \ + } while ((fn) == -1 && errno == EINTR) struct mgmt_pkt { uint16_t opcode; @@ -65,24 +68,6 @@ struct mgmt_ev_read_index_list { uint16_t index[]; } __attribute__((packed)); -// Definitions imported from -#define RFKILL_STATE_SOFT_BLOCKED 0 -#define RFKILL_STATE_UNBLOCKED 1 -#define RFKILL_STATE_HARD_BLOCKED 2 - -#define RFKILL_TYPE_BLUETOOTH 2 - -#define RFKILL_OP_ADD 0 -#define RFKILL_OP_CHANGE 2 - -struct rfkill_event { - uint32_t idx; - uint8_t type; - uint8_t op; - uint8_t soft; - uint8_t hard; -} __attribute__((packed)); - namespace aidl::android::hardware::bluetooth::impl { // Wait indefinitely for the selected HCI interface to be enabled in the @@ -194,66 +179,49 @@ end: return ret; } -int NetBluetoothMgmt::openRfkill() { - int fd = open("/dev/rfkill", O_RDWR); +int NetBluetoothMgmt::findRfKill() { + char rfkill_type[64]; + char type[16]; + int fd, size, i; + for(i = 0; rfkill_state_ == NULL; i++) + { + snprintf(rfkill_type, sizeof(rfkill_type), "/sys/class/rfkill/rfkill%d/type", i); + if ((fd = open(rfkill_type, O_RDONLY)) < 0) + { + ALOGE("open(%s) failed: %s (%d)\n", rfkill_type, strerror(errno), errno); + return -1; + } + + size = read(fd, &type, sizeof(type)); + ::close(fd); + + if ((size >= 9) && !memcmp(type, "bluetooth", 9)) + { + ::asprintf(&rfkill_state_, "/sys/class/rfkill/rfkill%d/state", i); + break; + } + } + return 0; +} + +int NetBluetoothMgmt::rfKill(int block) { + int fd; + char on = (block)?'1':'0'; + if (findRfKill() != 0) return 0; + + fd = open(rfkill_state_, O_WRONLY); if (fd < 0) { - ALOGE("unable to open /dev/rfkill: %s", strerror(errno)); + ALOGE( "Unable to open /dev/rfkill"); return -1; } - - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { - ALOGE("unable to set rfkill control device to non-blocking: %s", - strerror(errno)); + ssize_t len; + WRITE_NO_INTR(len = write(fd, &on, 1)); + if (len < 0) { + ALOGE( "Failed to change rfkill state"); ::close(fd); return -1; } - - for (;;) { - struct rfkill_event event {}; - ssize_t res = read(fd, &event, sizeof(event)); - if (res < 0) { - ALOGE("error reading rfkill events: %s", strerror(errno)); - break; - } - - ALOGI("index:%d type:%d op:%d", event.idx, event.type, event.op); - - if (event.op == RFKILL_OP_ADD && event.type == RFKILL_TYPE_BLUETOOTH) { - rfkill_bt_index_ = event.idx; - rfkill_fd_ = fd; - return 0; - } - } - ::close(fd); - return -1; -} - -// Block or unblock Bluetooth. -int NetBluetoothMgmt::rfkill(int block) { - if (rfkill_fd_ == -1) { - openRfkill(); - } - - if (rfkill_fd_ == -1) { - ALOGE("rfkill unavailable"); - return -1; - } - - struct rfkill_event event = { - .idx = static_cast(rfkill_bt_index_), - .type = RFKILL_TYPE_BLUETOOTH, - .op = RFKILL_OP_CHANGE, - .soft = static_cast(block), - .hard = 0, - }; - - int res = write(rfkill_fd_, &event, sizeof(event)); - if (res < 0) { - ALOGE("error writing rfkill command: %s", strerror(errno)); - return -1; - } - return 0; } @@ -261,7 +229,8 @@ int NetBluetoothMgmt::openHci(int hci_interface) { ALOGI("opening hci interface %d", hci_interface); // Block Bluetooth. - rfkill(1); + rfkill_state_ = NULL; + rfKill(1); // Wait for the HCI interface to complete initialization or to come online. int hci = waitHciDev(hci_interface); @@ -302,7 +271,8 @@ void NetBluetoothMgmt::closeHci() { } // Unblock Bluetooth. - rfkill(0); + rfKill(0); + free(rfkill_state_); } } // namespace aidl::android::hardware::bluetooth::impl diff --git a/bluetooth/net_bluetooth_mgmt.h b/bluetooth/net_bluetooth_mgmt.h index 23fb57a..b67510f 100644 --- a/bluetooth/net_bluetooth_mgmt.h +++ b/bluetooth/net_bluetooth_mgmt.h @@ -25,7 +25,6 @@ class NetBluetoothMgmt { public: NetBluetoothMgmt() {} ~NetBluetoothMgmt() { - ::close(rfkill_fd_); ::close(bt_fd_); } @@ -34,13 +33,10 @@ class NetBluetoothMgmt { private: int waitHciDev(int hci_interface); - int openRfkill(); - int rfkill(int block); + int findRfKill(); + int rfKill(int block); + char *rfkill_state_; - // Index of the first rfkill device of type bluetooth. - int rfkill_bt_index_{-1}; - // File descriptor opened to /dev/rfkill. - int rfkill_fd_{-1}; // File descriptor opened to the bluetooth user channel. int bt_fd_{-1}; };