[PATCH BlueZ v2] emulator: btvirt: support debug for -s socket server

Pauli Virtanen <[email protected]>
Newsgroups org.kernel.vger.linux-bluetooth
Message-ID <3a0785ebc5ceef448c52d25545b142659d25ce24.1786177678.git.pav@iki.fi>
Support btdev debug -d when using socket server -s.

$ btvirt -d -s
Bluetooth emulator ver 5.87
Request for /tmp/bt-server-bredrle
bredrle: host10: > 01 01 10 00                                      ....
bredrle: host10: command 0x1001
bredrle: host10: event 0x0e opcode 0x1001
...
---

Notes:
    v2:
    - Handle closing server with active clients correctly,
      in case this is used from elsewhere than main.c

 emulator/main.c   | 16 ++++++++++++++
 emulator/server.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++
 emulator/server.h |  5 +++++
 3 files changed, 77 insertions(+)

diff --git a/emulator/main.c b/emulator/main.c
index 09d6e9adb..c21640adc 100644
--- a/emulator/main.c
+++ b/emulator/main.c
@@ -80,6 +80,13 @@ static void vhci_debug(const char *str, void *user_data)
 	printf("vhci%u: %s\n", i, str);
 }
 
+static void server_debug(const char *str, void *user_data)
+{
+	const char *name = user_data;
+
+	printf("%s: %s\n", name, str);
+}
+
 int main(int argc, char *argv[])
 {
 	struct server *server1;
@@ -231,6 +238,15 @@ int main(int argc, char *argv[])
 		server5 = server_open_unix(SERVER_TYPE_MONITOR, path);
 		if (!server5)
 			fprintf(stderr, "Failed to open monitor server\n");
+
+		if (debug_enabled) {
+			server_set_debug(server1, server_debug, "bredrle",
+									NULL);
+			server_set_debug(server2, server_debug, "bredr", NULL);
+			server_set_debug(server3, server_debug, "amp", NULL);
+			server_set_debug(server4, server_debug, "le", NULL);
+			server_set_debug(server5, server_debug, "mon", NULL);
+		}
 	}
 
 	if (tcp_port) {
diff --git a/emulator/server.c b/emulator/server.c
index 7790867b7..e3eda8458 100644
--- a/emulator/server.c
+++ b/emulator/server.c
@@ -30,6 +30,7 @@
 #include "bluetooth/hci.h"
 
 #include "src/shared/mainloop.h"
+#include "src/shared/queue.h"
 #include "btdev.h"
 #include "server.h"
 
@@ -39,10 +40,15 @@ struct server {
 	enum server_type type;
 	uint16_t id;
 	int fd;
+	struct queue *clients;
+	server_debug_func_t debug_callback;
+	server_destroy_func_t debug_destroy;
+	void *debug_data;
 };
 
 struct client {
 	int fd;
+	struct server *server;
 	struct btdev *btdev;
 	uint8_t *pkt_data;
 	uint8_t pkt_type;
@@ -51,10 +57,22 @@ struct client {
 	uint16_t pkt_offset;
 };
 
+static void detach_client(void *data)
+{
+	struct client *client = data;
+
+	client->server = NULL;
+}
+
 static void server_destroy(void *user_data)
 {
 	struct server *server = user_data;
 
+	queue_destroy(server->clients, detach_client);
+
+	if (server->debug_destroy)
+		server->debug_destroy(server->debug_data);
+
 	close(server->fd);
 
 	free(server);
@@ -64,6 +82,9 @@ static void client_destroy(void *user_data)
 {
 	struct client *client = user_data;
 
+	if (client->server)
+		queue_remove(client->server->clients, client);
+
 	btdev_destroy(client->btdev);
 
 	close(client->fd);
@@ -223,6 +244,18 @@ static int accept_client(int fd)
 	return nfd;
 }
 
+static void dev_debug(const char *str, void *user_data)
+{
+	struct client *client = user_data;
+	struct server *server = client->server;
+	char buf[512];
+
+	if (server && server->debug_callback) {
+		snprintf(buf, sizeof(buf), "host%d: %s", client->fd, str);
+		server->debug_callback(buf, server->debug_data);
+	}
+}
+
 static void server_accept_callback(int fd, uint32_t events, void *user_data)
 {
 	struct server *server = user_data;
@@ -279,6 +312,11 @@ done:
 		close(client->fd);
 		free(client);
 	}
+
+	client->server = server;
+	queue_push_tail(server->clients, client);
+
+	btdev_set_debug(client->btdev, dev_debug, client, NULL);
 }
 
 static int open_unix(const char *path)
@@ -338,6 +376,8 @@ struct server *server_open_unix(enum server_type type, const char *path)
 		return NULL;
 	}
 
+	server->clients = queue_new();
+
 	return server;
 }
 
@@ -414,3 +454,19 @@ void server_close(struct server *server)
 
 	mainloop_remove_fd(server->fd);
 }
+
+bool server_set_debug(struct server *server, server_debug_func_t callback,
+			void *user_data, server_destroy_func_t destroy)
+{
+	if (!server)
+		return false;
+
+	if (server->debug_destroy)
+		server->debug_destroy(server->debug_data);
+
+	server->debug_callback = callback;
+	server->debug_destroy = destroy;
+	server->debug_data = user_data;
+
+	return true;
+}
diff --git a/emulator/server.h b/emulator/server.h
index 7d6b7be74..1844a9871 100644
--- a/emulator/server.h
+++ b/emulator/server.h
@@ -24,3 +24,8 @@ struct server;
 struct server *server_open_unix(enum server_type type, const char *path);
 struct server *server_open_tcp(enum server_type type, uint16_t port);
 void server_close(struct server *server);
+
+typedef void (*server_debug_func_t)(const char *str, void *user_data);
+typedef void (*server_destroy_func_t)(void *user_data);
+bool server_set_debug(struct server *server, server_debug_func_t callback,
+				void *user_data, server_destroy_func_t destroy);
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.