monitor/display.h monitor/display.c \
monitor/hcidump.h monitor/hcidump.c \
monitor/btsnoop.h monitor/btsnoop.c \
+ monitor/ellisys.h monitor/ellisys.c \
monitor/control.h monitor/control.c \
monitor/packet.h monitor/packet.c \
monitor/vendor.h monitor/vendor.c \
../monitor/ll.c \
../monitor/hwdb.h \
../monitor/hwdb.c \
+ ../monitor/ellisys.h \
+ ../monitor/ellisys.c \
../lib/hci.c \
../lib/bluetooth.c \
#include "packet.h"
#include "btsnoop.h"
#include "hcidump.h"
+#include "ellisys.h"
#include "control.h"
static bool hcidump_fallback = false;
case HCI_CHANNEL_MONITOR:
packet_monitor(tv, index, opcode, data->buf, pktlen);
btsnoop_write_hci(tv, index, opcode, data->buf, pktlen);
+ ellisys_inject_hci(tv, index, opcode,
+ data->buf, pktlen);
break;
}
}
break;
packet_monitor(&tv, index, opcode, buf, pktlen);
+ ellisys_inject_hci(&tv, index, opcode, buf, pktlen);
}
break;
--- /dev/null
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2011-2012 Intel Corporation
+ * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#include "btsnoop.h"
+#include "ellisys.h"
+
+static int ellisys_fd = -1;
+static uint16_t ellisys_index = 0xffff;
+
+void ellisys_enable(const char *server, uint16_t port)
+{
+ struct sockaddr_in addr;
+ int fd;
+
+ if (ellisys_fd >= 0) {
+ fprintf(stderr, "Ellisys injection already enabled\n");
+ return;
+ }
+
+ fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+ if (fd < 0) {
+ perror("Failed to open UDP injection socket");
+ return;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = inet_addr(server);
+ addr.sin_port = htons(port);
+
+ if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ perror("Failed to connect UDP injection socket");
+ close(fd);
+ return;
+ }
+
+ ellisys_fd = fd;
+}
+
+void ellisys_inject_hci(struct timeval *tv, uint16_t index, uint16_t opcode,
+ const void *data, uint16_t size)
+{
+ uint8_t msg[] = {
+ /* HCI Injection Service, Version 1 */
+ 0x02, 0x00, 0x01,
+ /* DateTimeNs Object */
+ 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* Bitrate Object, 12000000 bps */
+ 0x80, 0x00, 0x1b, 0x37, 0x4b,
+ /* HCI Packet Type Object */
+ 0x81, 0x00,
+ /* HCI Packet Data Object */
+ 0x82
+ };
+ long nsec;
+ time_t t;
+ struct tm tm;
+ struct iovec iov[2];
+ int iovcnt;
+
+ if (!tv)
+ return;
+
+ if (ellisys_fd < 0)
+ return;
+
+ if (ellisys_index == 0xffff)
+ ellisys_index = index;
+
+ if (index != ellisys_index)
+ return;
+
+ t = tv->tv_sec;
+ localtime_r(&t, &tm);
+
+ nsec = ((tm.tm_sec + (tm.tm_min * 60) +
+ (tm.tm_hour * 3600)) * 1000000l + tv->tv_usec) * 1000l;
+
+ msg[4] = (1900 + tm.tm_year) & 0xff;
+ msg[5] = (1900 + tm.tm_year) >> 8;
+ msg[6] = (tm.tm_mon + 1) & 0xff;
+ msg[7] = tm.tm_mday & 0xff;
+ msg[8] = (nsec & 0x0000000000ffl);
+ msg[9] = (nsec & 0x00000000ff00l) >> 8;
+ msg[10] = (nsec & 0x000000ff0000l) >> 16;
+ msg[11] = (nsec & 0x0000ff000000l) >> 24;
+ msg[12] = (nsec & 0x00ff00000000l) >> 32;
+ msg[13] = (nsec & 0xff0000000000l) >> 40;
+
+ switch (opcode) {
+ case BTSNOOP_OPCODE_COMMAND_PKT:
+ msg[20] = 0x01;
+ break;
+ case BTSNOOP_OPCODE_EVENT_PKT:
+ msg[20] = 0x84;
+ break;
+ case BTSNOOP_OPCODE_ACL_TX_PKT:
+ msg[20] = 0x02;
+ break;
+ case BTSNOOP_OPCODE_ACL_RX_PKT:
+ msg[20] = 0x82;
+ break;
+ case BTSNOOP_OPCODE_SCO_TX_PKT:
+ msg[20] = 0x03;
+ break;
+ case BTSNOOP_OPCODE_SCO_RX_PKT:
+ msg[20] = 0x83;
+ break;
+ default:
+ return;
+ }
+
+ iov[0].iov_base = msg;
+ iov[0].iov_len = sizeof(msg);
+
+ if (size > 0) {
+ iov[1].iov_base = (void *) data;
+ iov[1].iov_len = size;
+ iovcnt = 2;
+ } else
+ iovcnt = 1;
+
+ if (writev(ellisys_fd, iov, iovcnt) < 0)
+ perror("Failed to send Ellisys injection packet");
+}
--- /dev/null
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2011-2012 Intel Corporation
+ * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdint.h>
+
+void ellisys_enable(const char *server, uint16_t port);
+
+void ellisys_inject_hci(struct timeval *tv, uint16_t index, uint16_t opcode,
+ const void *data, uint16_t size);
#include "mainloop.h"
#include "packet.h"
+#include "ellisys.h"
#include "control.h"
static void signal_callback(int signum, void *user_data)
"\t-t, --time Show time instead of time offset\n"
"\t-T, --date Show time and date information\n"
"\t-S, --sco Dump SCO traffic\n"
+ "\t-E, --ellisys [ip] Send Ellisys HCI Injection\n"
"\t-h, --help Show help options\n");
}
{ "time", no_argument, NULL, 't' },
{ "date", no_argument, NULL, 'T' },
{ "sco", no_argument, NULL, 'S' },
+ { "ellisys", required_argument, NULL, 'E' },
{ "todo", no_argument, NULL, '#' },
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
int main(int argc, char *argv[])
{
unsigned long filter_mask = 0;
- const char *str, *reader_path = NULL, *writer_path = NULL;
+ const char *reader_path = NULL, *writer_path = NULL;
+ const char *ellisys_server = NULL;
+ unsigned short ellisys_port = 0;
+ const char *str;
sigset_t mask;
mainloop_init();
for (;;) {
int opt;
- opt = getopt_long(argc, argv, "r:w:s:i:tTSvh",
+ opt = getopt_long(argc, argv, "r:w:s:i:tTSE:vh",
main_options, NULL);
if (opt < 0)
break;
case 'S':
filter_mask |= PACKET_FILTER_SHOW_SCO_DATA;
break;
+ case 'E':
+ ellisys_server = optarg;
+ ellisys_port = 24352;
+ break;
case '#':
packet_todo();
return EXIT_SUCCESS;
packet_set_filter(filter_mask);
if (reader_path) {
+ if (ellisys_server)
+ ellisys_enable(ellisys_server, ellisys_port);
+
control_reader(reader_path);
return EXIT_SUCCESS;
}
if (writer_path)
control_writer(writer_path);
+ if (ellisys_server)
+ ellisys_enable(ellisys_server, ellisys_port);
+
if (control_tracing() < 0)
return EXIT_FAILURE;