Diff between b76f55ce125e884a16dac5eb317b6a037f913a08 and af2c5941ccc708695ce4270c35164f1e636ac1c6

Changed Files

File Additions Deletions Status
emulator/bthost.c +25 -0 modified
emulator/bthost.h +9 -0 modified
src/shared/hciemu.c +36 -0 modified
src/shared/hciemu.h +5 -0 modified

Full Patch

diff --git a/emulator/bthost.c b/emulator/bthost.c
index cfa507b..0f6e224 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 84e5b7a..5901464 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 463ef52..ac54890 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 0b2da35..3919436 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,