From 390cf7f898e8e93f3eb0e438e99e0cc163f38f6c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Jan 2013 12:20:38 -0800 Subject: [PATCH] tools: Add post command hook support to HCI emulation --- tools/hciemu.c | 54 +++++++++++++++++++++++++++++++++++++++++++++----- tools/hciemu.h | 8 ++++++++ 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/tools/hciemu.c b/tools/hciemu.c index dc83d40f2..0befedf35 100644 --- a/tools/hciemu.c +++ b/tools/hciemu.c @@ -47,23 +47,43 @@ struct hciemu { guint host_source; guint master_source; guint client_source; + GList *post_command_hooks; }; +struct hciemu_command_hook { + hciemu_command_func_t function; + void *user_data; +}; + +static void destroy_command_hook(gpointer data, gpointer user_data) +{ + struct hciemu_command_hook *hook = data; + + g_free(hook); +} + static void master_command_callback(uint16_t opcode, const void *data, uint8_t len, btdev_callback callback, void *user_data) { - g_print("[master] opcode 0x%04x len %d\n", opcode, len); + struct hciemu *hciemu = user_data; + GList *list; btdev_command_default(callback); + + for (list = g_list_first(hciemu->post_command_hooks); list; + list = g_list_next(list)) { + struct hciemu_command_hook *hook = list->data; + + if (hook->function) + hook->function(opcode, data, len, hook->user_data); + } } static void client_command_callback(uint16_t opcode, const void *data, uint8_t len, btdev_callback callback, void *user_data) { - g_print("[client] opcode 0x%04x len %d\n", opcode, len); - btdev_command_default(callback); } @@ -185,7 +205,7 @@ static void create_vhci(struct hciemu *hciemu) bdaddr[i] = strtol(str, NULL, 16); btdev_set_bdaddr(btdev, bdaddr); - btdev_set_command_handler(btdev, master_command_callback, NULL); + btdev_set_command_handler(btdev, master_command_callback, hciemu); fd = open("/dev/vhci", O_RDWR | O_NONBLOCK | O_CLOEXEC); if (fd < 0) { @@ -214,7 +234,7 @@ static void create_stack(struct hciemu *hciemu) return; } - btdev_set_command_handler(btdev, client_command_callback, NULL); + btdev_set_command_handler(btdev, client_command_callback, hciemu); if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0, sv) < 0) { @@ -273,6 +293,9 @@ void hciemu_unref(struct hciemu *hciemu) if (g_atomic_int_dec_and_test(&hciemu->ref_count) == FALSE) return; + g_list_foreach(hciemu->post_command_hooks, destroy_command_hook, NULL); + g_list_free(hciemu->post_command_hooks); + bthost_stop(hciemu->host_stack); g_source_remove(hciemu->host_source); @@ -293,3 +316,24 @@ const char *hciemu_get_address(struct hciemu *hciemu) return "00:FA:CE:1E:55:00"; } + +bool hciemu_add_master_post_command_hook(struct hciemu *hciemu, + hciemu_command_func_t function, void *user_data) +{ + struct hciemu_command_hook *hook; + + if (!hciemu) + return false; + + hook = g_try_new0(struct hciemu_command_hook, 1); + if (!hook) + return false; + + hook->function = function; + hook->user_data = user_data; + + hciemu->post_command_hooks = g_list_append(hciemu->post_command_hooks, + hook); + + return true; +} diff --git a/tools/hciemu.h b/tools/hciemu.h index 1a7dff94e..2592c3a7b 100644 --- a/tools/hciemu.h +++ b/tools/hciemu.h @@ -21,6 +21,8 @@ * */ +#include + struct hciemu; struct hciemu *hciemu_new(void); @@ -29,3 +31,9 @@ struct hciemu *hciemu_ref(struct hciemu *hciemu); void hciemu_unref(struct hciemu *hciemu); const char *hciemu_get_address(struct hciemu *hciemu); + +typedef void (*hciemu_command_func_t)(uint16_t opcode, const void *data, + uint8_t len, void *user_data); + +bool hciemu_add_master_post_command_hook(struct hciemu *hciemu, + hciemu_command_func_t function, void *user_data); -- 2.47.3