[PATCH BlueZ] vhci: Check whether vhci open setup succeeded

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Due to race condition in the vhci kernel driver, we might read not a
vendor response packet, but a HCI reset command. This extra check will
ensure that kernel driver behaves correctly. Otherwise, the HCI setup
process will fail, because our controller will not respond to "missing"
HCI reset command. In result the virtual HCI will be DOWN and without
initialized Bluetooth address, e.g:

> hciconfig
hci2:   Type: Primary  Bus: Virtual
        BD Address: 00:AA:01:01:00:02  ACL MTU: 192:1  SCO MTU: 0:0
        UP RUNNING
        RX bytes:0 acl:0 sco:0 events:66 errors:0
        TX bytes:3086 acl:0 sco:0 commands:66 errors:0

hci1:   Type: Primary  Bus: Virtual
        BD Address: 00:00:00:00:00:00  ACL MTU: 0:0  SCO MTU: 0:0
        DOWN
        RX bytes:0 acl:0 sco:0 events:0 errors:0
        TX bytes:8 acl:0 sco:0 commands:1 errors:0

> dmesg
[1754256.640122] Bluetooth: MGMT ver 1.22
[1754263.023806] Bluetooth: MGMT ver 1.22
[1754265.043775] Bluetooth: hci1: Opcode 0x c03 failed: -110
---
 emulator/hciemu.c | 2 +-
 emulator/vhci.c   | 5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/emulator/hciemu.c b/emulator/hciemu.c
index 25874ded5..e53fec0a2 100644
--- a/emulator/hciemu.c
+++ b/emulator/hciemu.c
@@ -313,7 +313,7 @@ static struct hciemu_client *hciemu_client_new(struct hciemu *hciemu,
 	if (!client)
 		return NULL;
 
-	client->dev = btdev_create(hciemu->btdev_type, id++);
+	client->dev = btdev_create(hciemu->btdev_type, id);
 	if (!client->dev) {
 		free(client);
 		return NULL;
diff --git a/emulator/vhci.c b/emulator/vhci.c
index 7b363009a..80e1825f3 100644
--- a/emulator/vhci.c
+++ b/emulator/vhci.c
@@ -122,14 +122,15 @@ struct vhci *vhci_open(uint8_t type)
 		break;
 	}
 
-	if (write(fd, &req, sizeof(req)) < 0) {
+	if (write(fd, &req, sizeof(req)) != sizeof(req)) {
 		close(fd);
 		return NULL;
 	}
 
 	memset(&rsp, 0, sizeof(rsp));
 
-	if (read(fd, &rsp, sizeof(rsp)) < 0) {
+	if (read(fd, &rsp, sizeof(rsp)) != sizeof(rsp) ||
+			!(rsp.pkt_type == HCI_VENDOR_PKT && rsp.opcode == req.opcode)) {
 		close(fd);
 		return NULL;
 	}
-- 
2.39.2




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux