ellisys.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // SPDX-License-Identifier: LGPL-2.1-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2011-2014 Intel Corporation
  7. * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
  8. *
  9. *
  10. */
  11. #ifdef HAVE_CONFIG_H
  12. #include <config.h>
  13. #endif
  14. #define _GNU_SOURCE
  15. #include <stdio.h>
  16. #include <unistd.h>
  17. #include <string.h>
  18. #include <time.h>
  19. #include <sys/time.h>
  20. #include <sys/socket.h>
  21. #include <sys/uio.h>
  22. #include <netdb.h>
  23. #include <arpa/inet.h>
  24. #include "src/shared/btsnoop.h"
  25. #include "ellisys.h"
  26. static int ellisys_fd = -1;
  27. static uint16_t ellisys_index = 0xffff;
  28. void ellisys_enable(const char *server, uint16_t port)
  29. {
  30. struct sockaddr_in addr;
  31. int fd;
  32. if (ellisys_fd >= 0) {
  33. fprintf(stderr, "Ellisys injection already enabled\n");
  34. return;
  35. }
  36. fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
  37. if (fd < 0) {
  38. perror("Failed to open UDP injection socket");
  39. return;
  40. }
  41. memset(&addr, 0, sizeof(addr));
  42. addr.sin_family = AF_INET;
  43. addr.sin_addr.s_addr = inet_addr(server);
  44. addr.sin_port = htons(port);
  45. if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  46. perror("Failed to connect UDP injection socket");
  47. close(fd);
  48. return;
  49. }
  50. ellisys_fd = fd;
  51. }
  52. void ellisys_inject_hci(struct timeval *tv, uint16_t index, uint16_t opcode,
  53. const void *data, uint16_t size)
  54. {
  55. uint8_t msg[] = {
  56. /* HCI Injection Service, Version 1 */
  57. 0x02, 0x00, 0x01,
  58. /* DateTimeNs Object */
  59. 0x02, 0x00, 0x00, 0x00, 0x00,
  60. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  61. /* Bitrate Object, 12000000 bps */
  62. 0x80, 0x00, 0x1b, 0x37, 0x4b,
  63. /* HCI Packet Type Object */
  64. 0x81, 0x00,
  65. /* HCI Packet Data Object */
  66. 0x82
  67. };
  68. long nsec;
  69. time_t t;
  70. struct tm tm;
  71. struct iovec iov[2];
  72. int iovcnt;
  73. if (!tv)
  74. return;
  75. if (ellisys_fd < 0)
  76. return;
  77. if (ellisys_index == 0xffff)
  78. ellisys_index = index;
  79. if (index != ellisys_index)
  80. return;
  81. t = tv->tv_sec;
  82. localtime_r(&t, &tm);
  83. nsec = ((tm.tm_sec + (tm.tm_min * 60) +
  84. (tm.tm_hour * 3600)) * 1000000l + tv->tv_usec) * 1000l;
  85. msg[4] = (1900 + tm.tm_year) & 0xff;
  86. msg[5] = (1900 + tm.tm_year) >> 8;
  87. msg[6] = (tm.tm_mon + 1) & 0xff;
  88. msg[7] = tm.tm_mday & 0xff;
  89. msg[8] = (nsec & 0x0000000000ffl);
  90. msg[9] = (nsec & 0x00000000ff00l) >> 8;
  91. msg[10] = (nsec & 0x000000ff0000l) >> 16;
  92. msg[11] = (nsec & 0x0000ff000000l) >> 24;
  93. msg[12] = (nsec & 0x00ff00000000l) >> 32;
  94. msg[13] = (nsec & 0xff0000000000l) >> 40;
  95. switch (opcode) {
  96. case BTSNOOP_OPCODE_COMMAND_PKT:
  97. msg[20] = 0x01;
  98. break;
  99. case BTSNOOP_OPCODE_EVENT_PKT:
  100. msg[20] = 0x84;
  101. break;
  102. case BTSNOOP_OPCODE_ACL_TX_PKT:
  103. msg[20] = 0x02;
  104. break;
  105. case BTSNOOP_OPCODE_ACL_RX_PKT:
  106. msg[20] = 0x82;
  107. break;
  108. case BTSNOOP_OPCODE_SCO_TX_PKT:
  109. msg[20] = 0x03;
  110. break;
  111. case BTSNOOP_OPCODE_SCO_RX_PKT:
  112. msg[20] = 0x83;
  113. break;
  114. default:
  115. return;
  116. }
  117. iov[0].iov_base = msg;
  118. iov[0].iov_len = sizeof(msg);
  119. if (size > 0) {
  120. iov[1].iov_base = (void *) data;
  121. iov[1].iov_len = size;
  122. iovcnt = 2;
  123. } else
  124. iovcnt = 1;
  125. if (writev(ellisys_fd, iov, iovcnt) < 0)
  126. perror("Failed to send Ellisys injection packet");
  127. }