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
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;
}