3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2011-2012 Intel Corporation
6 * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
37 #include <arpa/inet.h>
39 #include "lib/bluetooth.h"
42 #include "src/shared/mainloop.h"
44 #define DEFAULT_SERVER "b1ee.com"
45 #define DEFAULT_HOST_PORT "45550" /* 0xb1ee */
46 #define DEFAULT_SNIFFER_PORT "45551" /* 0xb1ef */
48 static int sniffer_fd;
52 static void sniffer_read_callback(int fd, uint32_t events, void *user_data)
54 static uint8_t buf[4096];
57 if (events & (EPOLLERR | EPOLLHUP))
61 len = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
68 printf("Sniffer received: %zi bytes\n", len);
71 static uint8_t *server_pkt_data;
72 static uint8_t server_pkt_type;
73 static uint16_t server_pkt_expect;
74 static uint16_t server_pkt_len;
75 static uint16_t server_pkt_offset;
77 static void server_read_callback(int fd, uint32_t events, void *user_data)
79 static uint8_t buf[4096];
84 if (events & (EPOLLERR | EPOLLHUP))
88 len = recv(fd, buf + server_pkt_offset,
89 sizeof(buf) - server_pkt_offset, MSG_DONTWAIT);
96 count = server_pkt_offset + len;
99 hci_event_hdr *evt_hdr;
101 if (!server_pkt_data) {
102 server_pkt_type = ptr[0];
104 switch (server_pkt_type) {
106 if (count < HCI_EVENT_HDR_SIZE + 1) {
107 server_pkt_offset += len;
110 evt_hdr = (hci_event_hdr *) (ptr + 1);
111 server_pkt_expect = HCI_EVENT_HDR_SIZE +
113 server_pkt_data = malloc(server_pkt_expect);
117 fprintf(stderr, "Unknown packet from server\n");
121 server_pkt_offset = 0;
124 if (count >= server_pkt_expect) {
127 memcpy(server_pkt_data + server_pkt_len,
128 ptr, server_pkt_expect);
129 ptr += server_pkt_expect;
130 count -= server_pkt_expect;
132 written = write(vhci_fd, server_pkt_data,
133 server_pkt_len + server_pkt_expect);
134 if (written != server_pkt_len + server_pkt_expect)
135 fprintf(stderr, "Write to /dev/vhci failed\n");
137 free(server_pkt_data);
138 server_pkt_data = NULL;
140 memcpy(server_pkt_data + server_pkt_len, ptr, count);
141 server_pkt_len += count;
142 server_pkt_expect -= count;
148 static void vhci_read_callback(int fd, uint32_t events, void *user_data)
150 unsigned char buf[4096];
151 ssize_t len, written;
153 if (events & (EPOLLERR | EPOLLHUP))
156 len = read(fd, buf, sizeof(buf));
160 written = write(server_fd, buf, len);
162 fprintf(stderr, "Write to server failed\n");
165 static void signal_callback(int signum, void *user_data)
175 static int do_connect(const char *node, const char *service)
177 struct addrinfo hints;
178 struct addrinfo *info, *res;
181 memset(&hints, 0, sizeof(hints));
182 hints.ai_family = PF_UNSPEC;
183 hints.ai_socktype = SOCK_STREAM;
185 err = getaddrinfo(DEFAULT_SERVER, DEFAULT_HOST_PORT, &hints, &res);
187 perror(gai_strerror(err));
191 for (info = res; info; info = info->ai_next) {
192 char str[INET6_ADDRSTRLEN];
194 inet_ntop(info->ai_family, info->ai_addr->sa_data,
197 fd = socket(info->ai_family, info->ai_socktype,
202 printf("Trying to connect to %s on port %s\n", str, service);
204 if (connect(fd, res->ai_addr, res->ai_addrlen) < 0) {
205 perror("Failed to connect");
210 printf("Successfully connected to %s on port %s\n",
223 int main(int argc, char *argv[])
225 const char sniff_cmd[] = { 0x01, 0x00,
226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
230 server_fd = do_connect(DEFAULT_SERVER, DEFAULT_HOST_PORT);
231 sniffer_fd = do_connect(DEFAULT_SERVER, DEFAULT_SNIFFER_PORT);
233 written = write(sniffer_fd, sniff_cmd, sizeof(sniff_cmd));
235 perror("Failed to enable sniffer");
237 vhci_fd = open("/dev/vhci", O_RDWR | O_NONBLOCK);
239 perror("Failed to /dev/vhci");
247 sigaddset(&mask, SIGINT);
248 sigaddset(&mask, SIGTERM);
250 mainloop_set_signal(&mask, signal_callback, NULL, NULL);
252 mainloop_add_fd(sniffer_fd, EPOLLIN, sniffer_read_callback, NULL, NULL);
253 mainloop_add_fd(server_fd, EPOLLIN, server_read_callback, NULL, NULL);
254 mainloop_add_fd(vhci_fd, EPOLLIN, vhci_read_callback, NULL, NULL);
256 return mainloop_run();