From af2c5941ccc708695ce4270c35164f1e636ac1c6 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 22 May 2013 12:28:51 -0700 Subject: [PATCH] emulator: implement write_scan_enable support --- emulator/bthost.c | 25 +++++++++++++++++++++++++ emulator/bthost.h | 9 +++++++++ src/shared/hciemu.c | 36 ++++++++++++++++++++++++++++++++++++ src/shared/hciemu.h | 5 +++++ 4 files changed, 75 insertions(+) diff --git a/emulator/bthost.c b/emulator/bthost.c index cfa507b7e..0f6e224a1 100644 --- a/emulator/bthost.c +++ b/emulator/bthost.c @@ -58,6 +58,8 @@ struct bthost { void *send_data; struct cmd_queue cmd_q; uint8_t ncmd; + bthost_cmd_complete_cb cmd_complete_cb; + void *cmd_complete_data; }; struct bthost *bthost_create(void) @@ -224,6 +226,10 @@ static void evt_cmd_complete(struct bthost *bthost, const void *data, break; } + if (bthost->cmd_complete_cb) + bthost->cmd_complete_cb(opcode, 0, param, len - sizeof(*ev), + bthost->cmd_complete_data); + next_cmd(bthost); } @@ -231,12 +237,19 @@ static void evt_cmd_status(struct bthost *bthost, const void *data, uint8_t len) { const struct bt_hci_evt_cmd_status *ev = data; + uint16_t opcode; if (len < sizeof(*ev)) return; bthost->ncmd = ev->ncmd; + opcode = le16toh(ev->opcode); + + if (ev->status && bthost->cmd_complete_cb) + bthost->cmd_complete_cb(opcode, ev->status, NULL, 0, + bthost->cmd_complete_data); + next_cmd(bthost); } @@ -290,6 +303,18 @@ void bthost_receive_h4(struct bthost *bthost, const void *data, uint16_t len) } } +void bthost_set_cmd_complete_cb(struct bthost *bthost, + bthost_cmd_complete_cb cb, void *user_data) +{ + bthost->cmd_complete_cb = cb; + bthost->cmd_complete_data = user_data; +} + +void bthost_write_scan_enable(struct bthost *bthost, uint8_t scan) +{ + send_command(bthost, BT_HCI_CMD_WRITE_SCAN_ENABLE, &scan, 1); +} + void bthost_start(struct bthost *bthost) { if (!bthost) diff --git a/emulator/bthost.h b/emulator/bthost.h index 84e5b7a6d..59014640e 100644 --- a/emulator/bthost.h +++ b/emulator/bthost.h @@ -37,5 +37,14 @@ void bthost_set_send_handler(struct bthost *bthost, bthost_send_func handler, void bthost_receive_h4(struct bthost *bthost, const void *data, uint16_t len); +typedef void (*bthost_cmd_complete_cb) (uint16_t opcode, uint8_t status, + const void *param, uint8_t len, + void *user_data); + +void bthost_set_cmd_complete_cb(struct bthost *bthost, + bthost_cmd_complete_cb cb, void *user_data); + +void bthost_write_scan_enable(struct bthost *bthost, uint8_t scan); + void bthost_start(struct bthost *bthost); void bthost_stop(struct bthost *bthost); diff --git a/src/shared/hciemu.c b/src/shared/hciemu.c index 463ef52a3..ac54890f8 100644 --- a/src/shared/hciemu.c +++ b/src/shared/hciemu.c @@ -51,6 +51,8 @@ struct hciemu { guint client_source; GList *post_command_hooks; char bdaddr_str[18]; + hciemu_scan_enable_cb scan_enable_cb; + void *scan_enable_data; }; struct hciemu_command_hook { @@ -215,6 +217,29 @@ static bool create_vhci(struct hciemu *hciemu) return true; } +static void client_cmd_complete(uint16_t opcode, uint8_t status, + const void *param, uint8_t len, + void *user_data) +{ + struct hciemu *hciemu = user_data; + + switch (opcode) { + case BT_HCI_CMD_WRITE_SCAN_ENABLE: + if (!hciemu->scan_enable_cb) + break; + + hciemu->scan_enable_cb(status, hciemu->scan_enable_data); + + hciemu->scan_enable_cb = NULL; + hciemu->scan_enable_data = NULL; + + break; + + default: + break; + } +} + static bool create_stack(struct hciemu *hciemu) { struct btdev *btdev; @@ -231,6 +256,8 @@ static bool create_stack(struct hciemu *hciemu) return false; } + bthost_set_cmd_complete_cb(bthost, client_cmd_complete, hciemu); + btdev_set_command_handler(btdev, client_command_callback, hciemu); if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, @@ -331,6 +358,15 @@ void hciemu_unref(struct hciemu *hciemu) g_free(hciemu); } +void hciemu_client_scan_enable(struct hciemu *hciemu, uint8_t scan, + hciemu_scan_enable_cb cb, void *user_data) +{ + hciemu->scan_enable_cb = cb; + hciemu->scan_enable_data = user_data; + + bthost_write_scan_enable(hciemu->host_stack, scan); +} + const char *hciemu_get_address(struct hciemu *hciemu) { const uint8_t *addr; diff --git a/src/shared/hciemu.h b/src/shared/hciemu.h index 0b2da359c..3919436cd 100644 --- a/src/shared/hciemu.h +++ b/src/shared/hciemu.h @@ -37,6 +37,11 @@ struct hciemu *hciemu_new(enum hciemu_type type); struct hciemu *hciemu_ref(struct hciemu *hciemu); void hciemu_unref(struct hciemu *hciemu); +typedef void (*hciemu_scan_enable_cb)(uint8_t status, void *user_data); + +void hciemu_client_scan_enable(struct hciemu *hciemu, uint8_t scan, + hciemu_scan_enable_cb cb, void *user_data); + const char *hciemu_get_address(struct hciemu *hciemu); typedef void (*hciemu_command_func_t)(uint16_t opcode, const void *data, -- 2.47.3