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/vhci.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/emulator/vhci.c b/emulator/vhci.c index 7b363009a..355ab6389 100644 --- a/emulator/vhci.c +++ b/emulator/vhci.c @@ -122,14 +122,16 @@ 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