[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-bluetooth
Subject: [PATCH 3/4] android/snoop: Add support for TCP clients
From: Andrzej Kaczmarek <andrzej.kaczmarek () tieto ! com>
Date: 2014-05-30 16:15:55
Message-ID: 1401466556-9040-3-git-send-email-andrzej.kaczmarek () tieto ! com
[Download RAW message or body]
This patch adds support to write snoop file to client connected via
TCP. Default listen port is 4330 which is used by Bluedroid for similar
purpose.
---
android/bluetoothd-snoop.c | 123 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 122 insertions(+), 1 deletion(-)
diff --git a/android/bluetoothd-snoop.c b/android/bluetoothd-snoop.c
index 57f97f4..25b9c97 100644
--- a/android/bluetoothd-snoop.c
+++ b/android/bluetoothd-snoop.c
@@ -32,6 +32,9 @@
#if defined(ANDROID)
#include <sys/capability.h>
#endif
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include "lib/bluetooth.h"
#include "lib/hci.h"
@@ -41,12 +44,15 @@
#include "src/shared/btsnoop.h"
#define DEFAULT_SNOOP_FILE "/sdcard/btsnoop_hci.log"
+#define DEFAULT_TCP_PORT 4330
#define MAX_PACKET_SIZE (1486 + 4)
static struct btsnoop *snoop = NULL;
+static struct btsnoop *tcp_snoop = NULL;
static uint8_t monitor_buf[MAX_PACKET_SIZE];
static int monitor_fd = -1;
+static int server_fd = -1;
static void signal_callback(int signum, void *user_data)
{
@@ -137,8 +143,10 @@ static void data_callback(int fd, uint32_t events, void *user_data)
continue;
flags = get_flags_from_opcode(opcode);
- if (flags != 0xff)
+ if (flags != 0xff) {
btsnoop_write(snoop, tv, flags, monitor_buf, pktlen);
+ btsnoop_write(tcp_snoop, tv, flags, monitor_buf, pktlen);
+ }
}
}
@@ -215,6 +223,115 @@ static void set_capabilities(void)
#endif
}
+static void tcp_callback(int fd, uint32_t events, void *user_data)
+{
+ if (events & (EPOLLERR | EPOLLHUP | EPOLLRDHUP)) {
+ mainloop_remove_fd(fd);
+
+ free(tcp_snoop);
+ tcp_snoop = NULL;
+
+ printf("TCP client disconnected\n");
+ }
+}
+
+static void accept_tcp(int fd, uint32_t events, void *user_data)
+{
+ struct sockaddr_un addr;
+ socklen_t len;
+ int nfd;
+
+ memset(&addr, 0, sizeof(addr));
+ len = sizeof(addr);
+
+ if (events & (EPOLLERR | EPOLLHUP)) {
+ mainloop_remove_fd(server_fd);
+ return;
+ }
+
+ nfd = accept(server_fd, (struct sockaddr *) &addr, &len);
+ if (nfd < 0) {
+ perror("Failed to accept incoming connection\n");
+ return;
+ }
+
+ /* We only support one client connected */
+ if (tcp_snoop) {
+ fprintf(stderr, "TCP client already connected\n");
+ close(nfd);
+ return;
+ }
+
+ if (mainloop_add_fd(nfd, EPOLLIN | EPOLLRDHUP, tcp_callback,
+ NULL, NULL) < 0) {
+ fprintf(stderr, "Failed to setup watch on client\n");
+ close(nfd);
+ return;
+ }
+
+ tcp_snoop = btsnoop_create_fd(nfd, BTSNOOP_TYPE_HCI);
+ if (!tcp_snoop) {
+ fprintf(stderr, "Failed to create snoop\n");
+ close(nfd);
+ return;
+ }
+
+ printf("TCP client connected\n");
+}
+
+static int open_tcp(void)
+{
+ struct sockaddr_in addr;
+ int fd, opt = 1;
+
+ fd = socket(PF_INET, SOCK_STREAM, 0);
+ if (fd < 0) {
+ perror("Failed to open server socket\n");
+ return -1;
+ }
+
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = INADDR_ANY;
+ addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+ addr.sin_port = htons(DEFAULT_TCP_PORT);
+
+ if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ perror("Failed to bind server socket\n");
+ close(fd);
+ return -1;
+ }
+
+ if (listen(fd, 5) < 0) {
+ perror("Failed to listen server socket\n");
+ close(fd);
+ return -1;
+ }
+
+ if (mainloop_add_fd(fd, EPOLLIN, accept_tcp, NULL, NULL) < 0) {
+ fprintf(stderr, "Failed to setup watch on server socket\n");
+ close(fd);
+ return -1;
+ }
+
+ server_fd = fd;
+
+ printf("TCP server ready\n");
+
+ return 0;
+}
+
+static void close_tcp(void)
+{
+ close(server_fd);
+
+ mainloop_remove_fd(server_fd);
+
+ server_fd = -1;
+}
+
int main(int argc, char *argv[])
{
const char *path;
@@ -243,8 +360,12 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
+ open_tcp();
+
mainloop_run();
+ close_tcp();
+
close_monitor();
return EXIT_SUCCESS;
--
1.9.3
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic