diff --git a/Makefile.tools b/Makefile.tools
index d4ed087..dc9dde9 100644
--- a/Makefile.tools
+++ b/Makefile.tools
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
#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) {
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);
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)
{
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);
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"
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;
case 'A':
amp_path = optarg;
break;
+ case 'R':
+ raw_device = true;
+ break;
case 'v':
printf("%s\n", VERSION);
return EXIT_SUCCESS;
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;
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) {
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) {
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;
}