aboutsummaryrefslogtreecommitdiffstats
path: root/executor
diff options
context:
space:
mode:
Diffstat (limited to 'executor')
-rw-r--r--executor/common_linux.h48
1 files changed, 37 insertions, 11 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h
index 39a687e36..10f693815 100644
--- a/executor/common_linux.h
+++ b/executor/common_linux.h
@@ -2586,11 +2586,21 @@ struct hci_dev_req {
uint32 dev_opt;
};
-struct vhci_vendor_pkt {
+struct vhci_vendor_pkt_request {
uint8 type;
uint8 opcode;
- uint16 id;
-};
+} __attribute__((packed));
+
+struct vhci_pkt {
+ uint8 type;
+ union {
+ struct {
+ uint8 opcode;
+ uint16 id;
+ } __attribute__((packed)) vendor_pkt;
+ struct hci_command_hdr command_hdr;
+ };
+} __attribute__((packed));
#define HCIDEVUP _IOW('H', 201, int)
#define HCISETSCAN _IOW('H', 221, int)
@@ -2718,6 +2728,9 @@ static void* event_thread(void* arg)
#define HCI_HANDLE_1 200
#define HCI_HANDLE_2 201
+#define HCI_PRIMARY 0
+#define HCI_OP_RESET 0x0c03
+
static void initialize_vhci()
{
#if SYZ_EXECUTOR
@@ -2741,25 +2754,38 @@ static void initialize_vhci()
close(vhci_fd);
vhci_fd = kVhciFd;
- struct vhci_vendor_pkt vendor_pkt;
- if (read(vhci_fd, &vendor_pkt, sizeof(vendor_pkt)) != sizeof(vendor_pkt))
- fail("read failed");
+ struct vhci_vendor_pkt_request vendor_pkt_req = {HCI_VENDOR_PKT, HCI_PRIMARY};
+ if (write(vhci_fd, &vendor_pkt_req, sizeof(vendor_pkt_req)) != sizeof(vendor_pkt_req))
+ fail("vendor_pkt_req write failed");
+
+ struct vhci_pkt vhci_pkt;
+ if (read(vhci_fd, &vhci_pkt, sizeof(vhci_pkt)) != sizeof(vhci_pkt))
+ fail("vhci_pkt read failed");
+
+ if (vhci_pkt.type == HCI_COMMAND_PKT && vhci_pkt.command_hdr.opcode == HCI_OP_RESET) {
+ char response[1] = {0};
+ hci_send_event_cmd_complete(vhci_fd, HCI_OP_RESET, response, sizeof(response));
+
+ if (read(vhci_fd, &vhci_pkt, sizeof(vhci_pkt)) != sizeof(vhci_pkt))
+ fail("vhci_pkt read failed");
+ }
- if (vendor_pkt.type != HCI_VENDOR_PKT)
+ if (vhci_pkt.type != HCI_VENDOR_PKT)
fail("wrong response packet");
- debug("hci dev id: %x\n", vendor_pkt.id);
+ int dev_id = vhci_pkt.vendor_pkt.id;
+ debug("hci dev id: %x\n", dev_id);
pthread_t th;
if (pthread_create(&th, NULL, event_thread, NULL))
fail("pthread_create failed");
// Bring hci device up
- int ret = ioctl(hci_sock, HCIDEVUP, vendor_pkt.id);
+ int ret = ioctl(hci_sock, HCIDEVUP, dev_id);
if (ret) {
if (errno == ERFKILL) {
rfkill_unblock_all();
- ret = ioctl(hci_sock, HCIDEVUP, vendor_pkt.id);
+ ret = ioctl(hci_sock, HCIDEVUP, dev_id);
}
if (ret && errno != EALREADY)
@@ -2768,7 +2794,7 @@ static void initialize_vhci()
// Activate page scanning mode which is required to fake a connection.
struct hci_dev_req dr = {0};
- dr.dev_id = vendor_pkt.id;
+ dr.dev_id = dev_id;
dr.dev_opt = SCAN_PAGE;
if (ioctl(hci_sock, HCISETSCAN, &dr))
fail("ioctl(HCISETSCAN) failed");