From a18440c23b23704dba92c49fd60cae9032015233 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 12 Jul 2014 16:42:11 +0200 Subject: [PATCH] tools: Use mainloop handling for btattach utility --- Makefile.tools | 10 ++++ tools/btattach.c | 120 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 108 insertions(+), 22 deletions(-) diff --git a/Makefile.tools b/Makefile.tools index d4ed0870f..dc9dde98f 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 87ea78474..9458fd7d0 100644 --- a/tools/btattach.c +++ b/tools/btattach.c @@ -42,11 +42,16 @@ #include #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; } -- 2.47.3