attach.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // SPDX-License-Identifier: LGPL-2.1-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2015 Intel Corporation. All rights reserved.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #define _GNU_SOURCE
  14. #include <fcntl.h>
  15. #include <unistd.h>
  16. #include <sys/ioctl.h>
  17. #include "lib/bluetooth.h"
  18. #include "lib/hci.h"
  19. #include "lib/hci_lib.h"
  20. #include "tools/hciattach.h"
  21. #include "peripheral/attach.h"
  22. static const char *serial_dev = "/dev/ttyS1";
  23. static int serial_fd = -1;
  24. static int open_serial(const char *path)
  25. {
  26. struct termios ti;
  27. int fd, saved_ldisc, ldisc = N_HCI;
  28. fd = open(path, O_RDWR | O_NOCTTY);
  29. if (fd < 0) {
  30. perror("Failed to open serial port");
  31. return -1;
  32. }
  33. if (tcflush(fd, TCIOFLUSH) < 0) {
  34. perror("Failed to flush serial port");
  35. close(fd);
  36. return -1;
  37. }
  38. if (ioctl(fd, TIOCGETD, &saved_ldisc) < 0) {
  39. perror("Failed get serial line discipline");
  40. close(fd);
  41. return -1;
  42. }
  43. /* Switch TTY to raw mode */
  44. memset(&ti, 0, sizeof(ti));
  45. cfmakeraw(&ti);
  46. ti.c_cflag |= (B115200 | CLOCAL | CREAD);
  47. /* Set flow control */
  48. ti.c_cflag |= CRTSCTS;
  49. if (tcsetattr(fd, TCSANOW, &ti) < 0) {
  50. perror("Failed to set serial port settings");
  51. close(fd);
  52. return -1;
  53. }
  54. if (ioctl(fd, TIOCSETD, &ldisc) < 0) {
  55. perror("Failed set serial line discipline");
  56. close(fd);
  57. return -1;
  58. }
  59. printf("Switched line discipline from %d to %d\n", saved_ldisc, ldisc);
  60. return fd;
  61. }
  62. static int attach_proto(const char *path, unsigned int proto,
  63. unsigned int flags)
  64. {
  65. int fd, dev_id;
  66. fd = open_serial(path);
  67. if (fd < 0)
  68. return -1;
  69. if (ioctl(fd, HCIUARTSETFLAGS, flags) < 0) {
  70. perror("Failed to set flags");
  71. close(fd);
  72. return -1;
  73. }
  74. if (ioctl(fd, HCIUARTSETPROTO, proto) < 0) {
  75. perror("Failed to set protocol");
  76. close(fd);
  77. return -1;
  78. }
  79. dev_id = ioctl(fd, HCIUARTGETDEVICE);
  80. if (dev_id < 0) {
  81. perror("Failed to get device id");
  82. close(fd);
  83. return -1;
  84. }
  85. printf("Device index %d attached\n", dev_id);
  86. return fd;
  87. }
  88. void attach_start(void)
  89. {
  90. unsigned long flags;
  91. if (serial_fd >= 0)
  92. return;
  93. printf("Attaching BR/EDR controller to %s\n", serial_dev);
  94. flags = (1 << HCI_UART_RESET_ON_INIT);
  95. serial_fd = attach_proto(serial_dev, HCI_UART_H4, flags);
  96. }
  97. void attach_stop(void)
  98. {
  99. if (serial_fd < 0)
  100. return;
  101. close(serial_fd);
  102. serial_fd = -1;
  103. }