Diff between 096799fd522f388de4501d0bfafda468a8297e2b and a18440c23b23704dba92c49fd60cae9032015233

Changed Files

File Additions Deletions Status
Makefile.tools +10 -0 modified
tools/btattach.c +98 -22 modified

Full Patch

diff --git a/Makefile.tools b/Makefile.tools
index d4ed087..dc9dde9 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -314,6 +314,16 @@ tools_btinfo_SOURCES = tools/btinfo.c monitor/bt.h \
 				src/shared/queue.h src/shared/queue.c \
 				src/shared/ringbuf.h src/shared/ringbuf.c
 
+tools_btattach_SOURCES = tools/btattach.c monitor/bt.h \
+				monitor/mainloop.h monitor/mainloop.c \
+				src/shared/io.h src/shared/io-mainloop.c \
+				src/shared/timeout.h \
+				src/shared/timeout-mainloop.c \
+				src/shared/hci.h src/shared/hci.c \
+				src/shared/util.h src/shared/util.c \
+				src/shared/queue.h src/shared/queue.c \
+				src/shared/ringbuf.h src/shared/ringbuf.c
+
 tools_btsnoop_SOURCES = tools/btsnoop.c \
 				src/shared/pcap.h src/shared/pcap.c \
 				src/shared/btsnoop.h src/shared/btsnoop.c
diff --git a/tools/btattach.c b/tools/btattach.c
index 87ea784..9458fd7 100644
--- a/tools/btattach.c
+++ b/tools/btattach.c
@@ -42,11 +42,16 @@
 #include <bluetooth/hci_lib.h>
 
 #include "hciattach.h"
+#include "monitor/mainloop.h"
+#include "monitor/bt.h"
+#include "src/shared/timeout.h"
+#include "src/shared/util.h"
+#include "src/shared/hci.h"
 
 static int open_serial(const char *path)
 {
 	struct termios ti;
-	int fd, ldisc = N_HCI;
+	int fd, saved_ldisc, ldisc = N_HCI;
 
 	fd = open(path, O_RDWR | O_NOCTTY);
 	if (fd < 0) {
@@ -60,12 +65,21 @@ static int open_serial(const char *path)
 		return -1;
 	}
 
+	if (ioctl(fd, TIOCGETD, &saved_ldisc) < 0) {
+		perror("Failed get serial line discipline");
+		close(fd);
+		return -1;
+	}
+
 	/* Switch TTY to raw mode */
 	memset(&ti, 0, sizeof(ti));
 	cfmakeraw(&ti);
 
 	ti.c_cflag |= (B115200 | CLOCAL | CREAD);
 
+	/* Set flow control */
+	ti.c_cflag |= CRTSCTS;
+
 	if (tcsetattr(fd, TCSANOW, &ti) < 0) {
 		perror("Failed to set serial port settings");
 		close(fd);
@@ -78,9 +92,19 @@ static int open_serial(const char *path)
 		return -1;
 	}
 
+	printf("Switched line discipline from %d to %d\n", saved_ldisc, ldisc);
+
 	return fd;
 }
 
+static void local_version_callback(const void *data, uint8_t size,
+							void *user_data)
+{
+	const struct bt_hci_rsp_read_local_version *rsp = data;
+
+	printf("Manufacturer: %u\n", le16_to_cpu(rsp->manufacturer));
+}
+
 static int attach_proto(const char *path, unsigned int proto,
 						unsigned int flags)
 {
@@ -102,7 +126,7 @@ static int attach_proto(const char *path, unsigned int proto,
 		return -1;
 	}
 
-	dev_id = ioctl(fd, HCIUARTGETDEVICE, NULL);
+	dev_id = ioctl(fd, HCIUARTGETDEVICE);
 	if (dev_id < 0) {
 		perror("Failed to get device id");
 		close(fd);
@@ -111,9 +135,50 @@ static int attach_proto(const char *path, unsigned int proto,
 
 	printf("Device index %d attached\n", dev_id);
 
+	if (flags & (1 << HCI_UART_RAW_DEVICE)) {
+		unsigned int attempts = 6;
+		struct bt_hci *hci;
+
+		while (attempts-- > 0) {
+			hci = bt_hci_new_user_channel(dev_id);
+			if (hci)
+				break;
+
+			usleep(250 * 1000);
+		}
+
+		if (!hci) {
+			fprintf(stderr, "Failed to open HCI user channel\n");
+			close(fd);
+			return -1;
+		}
+
+		bt_hci_send(hci, BT_HCI_CMD_READ_LOCAL_VERSION, NULL, 0,
+					local_version_callback, NULL, NULL);
+	}
+
 	return fd;
 }
 
+static void uart_callback(int fd, uint32_t events, void *user_data)
+{
+	printf("UART callback handling\n");
+}
+
+static void signal_callback(int signum, void *user_data)
+{
+	static bool terminated = false;
+
+	switch (signum) {
+	case SIGINT:
+	case SIGTERM:
+		if (!terminated) {
+			mainloop_quit();
+			terminated = true;
+		}
+		break;
+	}
+}
 static void usage(void)
 {
 	printf("btattach - Bluetooth serial utility\n"
@@ -136,13 +201,14 @@ static const struct option main_options[] = {
 int main(int argc, char *argv[])
 {
 	const char *bredr_path = NULL, *amp_path = NULL;
-	struct pollfd p[5];
-	int i, count = 0;
+	bool raw_device = false;
+	sigset_t mask;
+	int exit_status, count = 0;
 
 	for (;;) {
 		int opt;
 
-		opt = getopt_long(argc, argv, "B:A:vh",
+		opt = getopt_long(argc, argv, "B:A:Rvh",
 						main_options, NULL);
 		if (opt < 0)
 			break;
@@ -154,6 +220,9 @@ int main(int argc, char *argv[])
 		case 'A':
 			amp_path = optarg;
 			break;
+		case 'R':
+			raw_device = true;
+			break;
 		case 'v':
 			printf("%s\n", VERSION);
 			return EXIT_SUCCESS;
@@ -170,6 +239,14 @@ int main(int argc, char *argv[])
 		return EXIT_FAILURE;
 	}
 
+	mainloop_init();
+
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGINT);
+	sigaddset(&mask, SIGTERM);
+
+	mainloop_set_signal(&mask, signal_callback, NULL, NULL);
+
 	if (bredr_path) {
 		unsigned long flags;
 		int fd;
@@ -178,9 +255,14 @@ int main(int argc, char *argv[])
 
 		flags = (1 << HCI_UART_RESET_ON_INIT);
 
+		if (raw_device)
+			flags = (1 << HCI_UART_RAW_DEVICE);
+
 		fd = attach_proto(bredr_path, HCI_UART_H4, flags);
-		if (fd >= 0)
-			p[count++].fd = fd;
+		if (fd >= 0) {
+			mainloop_add_fd(fd, 0, uart_callback, NULL, NULL);
+			count++;
+		}
 	}
 
 	if (amp_path) {
@@ -192,9 +274,14 @@ int main(int argc, char *argv[])
 		flags = (1 << HCI_UART_RESET_ON_INIT) |
 			(1 << HCI_UART_CREATE_AMP);
 
+		if (raw_device)
+			flags = (1 << HCI_UART_RAW_DEVICE);
+
 		fd = attach_proto(amp_path, HCI_UART_H4, flags);
-		if (fd >= 0)
-			p[count++].fd = fd;
+		if (fd >= 0) {
+			mainloop_add_fd(fd, 0, uart_callback, NULL, NULL);
+			count++;
+		}
 	}
 
 	if (count < 1) {
@@ -202,18 +289,7 @@ int main(int argc, char *argv[])
 		return EXIT_FAILURE;
 	}
 
-	for (i = 0; i < count; i++) {
-		p[i].events = POLLERR | POLLHUP;
-		p[i].revents = 0;
-	}
-
-	while (1) {
-		if (poll(p, count, -1) < 0)
-			break;
-        }
-
-	for (i = 0; i < count; i++)
-		close(p[i].fd);
+	exit_status = mainloop_run();
 
-	return EXIT_SUCCESS;
+	return exit_status;
 }