3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2011-2014 Intel Corporation
6 * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library 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 GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
36 #include <sys/socket.h>
39 #include "lib/bluetooth.h"
43 #include "src/shared/util.h"
44 #include "src/shared/btsnoop.h"
45 #include "src/shared/mainloop.h"
53 static struct btsnoop *btsnoop_file = NULL;
54 static bool hcidump_fallback = false;
59 unsigned char buf[BTSNOOP_MAX_PACKET_SIZE];
63 static void free_data(void *user_data)
65 struct control_data *data = user_data;
72 static void mgmt_index_added(uint16_t len, const void *buf)
74 printf("@ Index Added\n");
76 packet_hexdump(buf, len);
79 static void mgmt_index_removed(uint16_t len, const void *buf)
81 printf("@ Index Removed\n");
83 packet_hexdump(buf, len);
86 static void mgmt_unconf_index_added(uint16_t len, const void *buf)
88 printf("@ Unconfigured Index Added\n");
90 packet_hexdump(buf, len);
93 static void mgmt_unconf_index_removed(uint16_t len, const void *buf)
95 printf("@ Unconfigured Index Removed\n");
97 packet_hexdump(buf, len);
100 static void mgmt_ext_index_added(uint16_t len, const void *buf)
102 const struct mgmt_ev_ext_index_added *ev = buf;
104 if (len < sizeof(*ev)) {
105 printf("* Malformed Extended Index Added control\n");
109 printf("@ Extended Index Added: %u (%u)\n", ev->type, ev->bus);
114 packet_hexdump(buf, len);
117 static void mgmt_ext_index_removed(uint16_t len, const void *buf)
119 const struct mgmt_ev_ext_index_removed *ev = buf;
121 if (len < sizeof(*ev)) {
122 printf("* Malformed Extended Index Removed control\n");
126 printf("@ Extended Index Removed: %u (%u)\n", ev->type, ev->bus);
131 packet_hexdump(buf, len);
134 static void mgmt_controller_error(uint16_t len, const void *buf)
136 const struct mgmt_ev_controller_error *ev = buf;
138 if (len < sizeof(*ev)) {
139 printf("* Malformed Controller Error control\n");
143 printf("@ Controller Error: 0x%2.2x\n", ev->error_code);
148 packet_hexdump(buf, len);
152 #define NELEM(x) (sizeof(x) / sizeof((x)[0]))
155 static const char *config_options_str[] = {
156 "external", "public-address",
159 static void mgmt_new_config_options(uint16_t len, const void *buf)
165 printf("* Malformed New Configuration Options control\n");
169 options = get_le32(buf);
171 printf("@ New Configuration Options: 0x%4.4x\n", options);
174 printf("%-12c", ' ');
175 for (i = 0; i < NELEM(config_options_str); i++) {
176 if (options & (1 << i))
177 printf("%s ", config_options_str[i]);
185 packet_hexdump(buf, len);
188 static const char *settings_str[] = {
189 "powered", "connectable", "fast-connectable", "discoverable",
190 "bondable", "link-security", "ssp", "br/edr", "hs", "le",
191 "advertising", "secure-conn", "debug-keys", "privacy",
192 "configuration", "static-addr",
195 static void mgmt_new_settings(uint16_t len, const void *buf)
201 printf("* Malformed New Settings control\n");
205 settings = get_le32(buf);
207 printf("@ New Settings: 0x%4.4x\n", settings);
210 printf("%-12c", ' ');
211 for (i = 0; i < NELEM(settings_str); i++) {
212 if (settings & (1 << i))
213 printf("%s ", settings_str[i]);
221 packet_hexdump(buf, len);
224 static void mgmt_class_of_dev_changed(uint16_t len, const void *buf)
226 const struct mgmt_ev_class_of_dev_changed *ev = buf;
228 if (len < sizeof(*ev)) {
229 printf("* Malformed Class of Device Changed control\n");
233 printf("@ Class of Device Changed: 0x%2.2x%2.2x%2.2x\n",
241 packet_hexdump(buf, len);
244 static void mgmt_local_name_changed(uint16_t len, const void *buf)
246 const struct mgmt_ev_local_name_changed *ev = buf;
248 if (len < sizeof(*ev)) {
249 printf("* Malformed Local Name Changed control\n");
253 printf("@ Local Name Changed: %s (%s)\n", ev->name, ev->short_name);
258 packet_hexdump(buf, len);
261 static void mgmt_new_link_key(uint16_t len, const void *buf)
263 const struct mgmt_ev_new_link_key *ev = buf;
266 if (len < sizeof(*ev)) {
267 printf("* Malformed New Link Key control\n");
271 ba2str(&ev->key.addr.bdaddr, str);
273 printf("@ New Link Key: %s (%d)\n", str, ev->key.addr.type);
278 packet_hexdump(buf, len);
281 static void mgmt_new_long_term_key(uint16_t len, const void *buf)
283 const struct mgmt_ev_new_long_term_key *ev = buf;
287 if (len < sizeof(*ev)) {
288 printf("* Malformed New Long Term Key control\n");
292 /* LE SC keys are both for master and slave */
293 switch (ev->key.type) {
296 type = "Master (Unauthenticated)";
298 type = "Slave (Unauthenticated)";
302 type = "Master (Authenticated)";
304 type = "Slave (Authenticated)";
307 type = "SC (Unauthenticated)";
310 type = "SC (Authenticated)";
320 ba2str(&ev->key.addr.bdaddr, str);
322 printf("@ New Long Term Key: %s (%d) %s 0x%02x\n", str,
323 ev->key.addr.type, type, ev->key.type);
328 packet_hexdump(buf, len);
331 static void mgmt_device_connected(uint16_t len, const void *buf)
333 const struct mgmt_ev_device_connected *ev = buf;
337 if (len < sizeof(*ev)) {
338 printf("* Malformed Device Connected control\n");
342 flags = le32_to_cpu(ev->flags);
343 ba2str(&ev->addr.bdaddr, str);
345 printf("@ Device Connected: %s (%d) flags 0x%4.4x\n",
346 str, ev->addr.type, flags);
351 packet_hexdump(buf, len);
354 static void mgmt_device_disconnected(uint16_t len, const void *buf)
356 const struct mgmt_ev_device_disconnected *ev = buf;
359 uint16_t consumed_len;
361 if (len < sizeof(struct mgmt_addr_info)) {
362 printf("* Malformed Device Disconnected control\n");
366 if (len < sizeof(*ev)) {
367 reason = MGMT_DEV_DISCONN_UNKNOWN;
371 consumed_len = sizeof(*ev);
374 ba2str(&ev->addr.bdaddr, str);
376 printf("@ Device Disconnected: %s (%d) reason %u\n", str, ev->addr.type,
382 packet_hexdump(buf, len);
385 static void mgmt_connect_failed(uint16_t len, const void *buf)
387 const struct mgmt_ev_connect_failed *ev = buf;
390 if (len < sizeof(*ev)) {
391 printf("* Malformed Connect Failed control\n");
395 ba2str(&ev->addr.bdaddr, str);
397 printf("@ Connect Failed: %s (%d) status 0x%2.2x\n",
398 str, ev->addr.type, ev->status);
403 packet_hexdump(buf, len);
406 static void mgmt_pin_code_request(uint16_t len, const void *buf)
408 const struct mgmt_ev_pin_code_request *ev = buf;
411 if (len < sizeof(*ev)) {
412 printf("* Malformed PIN Code Request control\n");
416 ba2str(&ev->addr.bdaddr, str);
418 printf("@ PIN Code Request: %s (%d) secure 0x%2.2x\n",
419 str, ev->addr.type, ev->secure);
424 packet_hexdump(buf, len);
427 static void mgmt_user_confirm_request(uint16_t len, const void *buf)
429 const struct mgmt_ev_user_confirm_request *ev = buf;
432 if (len < sizeof(*ev)) {
433 printf("* Malformed User Confirmation Request control\n");
437 ba2str(&ev->addr.bdaddr, str);
439 printf("@ User Confirmation Request: %s (%d) hint %d value %d\n",
440 str, ev->addr.type, ev->confirm_hint, ev->value);
445 packet_hexdump(buf, len);
448 static void mgmt_user_passkey_request(uint16_t len, const void *buf)
450 const struct mgmt_ev_user_passkey_request *ev = buf;
453 if (len < sizeof(*ev)) {
454 printf("* Malformed User Passkey Request control\n");
458 ba2str(&ev->addr.bdaddr, str);
460 printf("@ User Passkey Request: %s (%d)\n", str, ev->addr.type);
465 packet_hexdump(buf, len);
468 static void mgmt_auth_failed(uint16_t len, const void *buf)
470 const struct mgmt_ev_auth_failed *ev = buf;
473 if (len < sizeof(*ev)) {
474 printf("* Malformed Authentication Failed control\n");
478 ba2str(&ev->addr.bdaddr, str);
480 printf("@ Authentication Failed: %s (%d) status 0x%2.2x\n",
481 str, ev->addr.type, ev->status);
486 packet_hexdump(buf, len);
489 static void mgmt_device_found(uint16_t len, const void *buf)
491 const struct mgmt_ev_device_found *ev = buf;
495 if (len < sizeof(*ev)) {
496 printf("* Malformed Device Found control\n");
500 flags = le32_to_cpu(ev->flags);
501 ba2str(&ev->addr.bdaddr, str);
503 printf("@ Device Found: %s (%d) rssi %d flags 0x%4.4x\n",
504 str, ev->addr.type, ev->rssi, flags);
509 packet_hexdump(buf, len);
512 static void mgmt_discovering(uint16_t len, const void *buf)
514 const struct mgmt_ev_discovering *ev = buf;
516 if (len < sizeof(*ev)) {
517 printf("* Malformed Discovering control\n");
521 printf("@ Discovering: 0x%2.2x (%d)\n", ev->discovering, ev->type);
526 packet_hexdump(buf, len);
529 static void mgmt_device_blocked(uint16_t len, const void *buf)
531 const struct mgmt_ev_device_blocked *ev = buf;
534 if (len < sizeof(*ev)) {
535 printf("* Malformed Device Blocked control\n");
539 ba2str(&ev->addr.bdaddr, str);
541 printf("@ Device Blocked: %s (%d)\n", str, ev->addr.type);
546 packet_hexdump(buf, len);
549 static void mgmt_device_unblocked(uint16_t len, const void *buf)
551 const struct mgmt_ev_device_unblocked *ev = buf;
554 if (len < sizeof(*ev)) {
555 printf("* Malformed Device Unblocked control\n");
559 ba2str(&ev->addr.bdaddr, str);
561 printf("@ Device Unblocked: %s (%d)\n", str, ev->addr.type);
566 packet_hexdump(buf, len);
569 static void mgmt_device_unpaired(uint16_t len, const void *buf)
571 const struct mgmt_ev_device_unpaired *ev = buf;
574 if (len < sizeof(*ev)) {
575 printf("* Malformed Device Unpaired control\n");
579 ba2str(&ev->addr.bdaddr, str);
581 printf("@ Device Unpaired: %s (%d)\n", str, ev->addr.type);
586 packet_hexdump(buf, len);
589 static void mgmt_passkey_notify(uint16_t len, const void *buf)
591 const struct mgmt_ev_passkey_notify *ev = buf;
595 if (len < sizeof(*ev)) {
596 printf("* Malformed Passkey Notify control\n");
600 ba2str(&ev->addr.bdaddr, str);
602 passkey = le32_to_cpu(ev->passkey);
604 printf("@ Passkey Notify: %s (%d) passkey %06u entered %u\n",
605 str, ev->addr.type, passkey, ev->entered);
610 packet_hexdump(buf, len);
613 static void mgmt_new_irk(uint16_t len, const void *buf)
615 const struct mgmt_ev_new_irk *ev = buf;
616 char addr[18], rpa[18];
618 if (len < sizeof(*ev)) {
619 printf("* Malformed New IRK control\n");
623 ba2str(&ev->rpa, rpa);
624 ba2str(&ev->key.addr.bdaddr, addr);
626 printf("@ New IRK: %s (%d) %s\n", addr, ev->key.addr.type, rpa);
631 packet_hexdump(buf, len);
634 static void mgmt_new_csrk(uint16_t len, const void *buf)
636 const struct mgmt_ev_new_csrk *ev = buf;
640 if (len < sizeof(*ev)) {
641 printf("* Malformed New CSRK control\n");
645 ba2str(&ev->key.addr.bdaddr, addr);
647 switch (ev->key.type) {
649 type = "Local Unauthenticated";
652 type = "Remote Unauthenticated";
655 type = "Local Authenticated";
658 type = "Remote Authenticated";
665 printf("@ New CSRK: %s (%d) %s (%u)\n", addr, ev->key.addr.type,
671 packet_hexdump(buf, len);
674 static void mgmt_device_added(uint16_t len, const void *buf)
676 const struct mgmt_ev_device_added *ev = buf;
679 if (len < sizeof(*ev)) {
680 printf("* Malformed Device Added control\n");
684 ba2str(&ev->addr.bdaddr, str);
686 printf("@ Device Added: %s (%d) %d\n", str, ev->addr.type, ev->action);
691 packet_hexdump(buf, len);
694 static void mgmt_device_removed(uint16_t len, const void *buf)
696 const struct mgmt_ev_device_removed *ev = buf;
699 if (len < sizeof(*ev)) {
700 printf("* Malformed Device Removed control\n");
704 ba2str(&ev->addr.bdaddr, str);
706 printf("@ Device Removed: %s (%d)\n", str, ev->addr.type);
711 packet_hexdump(buf, len);
714 static void mgmt_new_conn_param(uint16_t len, const void *buf)
716 const struct mgmt_ev_new_conn_param *ev = buf;
718 uint16_t min, max, latency, timeout;
720 if (len < sizeof(*ev)) {
721 printf("* Malformed New Connection Parameter control\n");
725 ba2str(&ev->addr.bdaddr, addr);
726 min = le16_to_cpu(ev->min_interval);
727 max = le16_to_cpu(ev->max_interval);
728 latency = le16_to_cpu(ev->latency);
729 timeout = le16_to_cpu(ev->timeout);
731 printf("@ New Conn Param: %s (%d) hint %d min 0x%4.4x max 0x%4.4x "
732 "latency 0x%4.4x timeout 0x%4.4x\n", addr, ev->addr.type,
733 ev->store_hint, min, max, latency, timeout);
738 packet_hexdump(buf, len);
741 static void mgmt_advertising_added(uint16_t len, const void *buf)
743 const struct mgmt_ev_advertising_added *ev = buf;
745 if (len < sizeof(*ev)) {
746 printf("* Malformed Advertising Added control\n");
750 printf("@ Advertising Added: %u\n", ev->instance);
755 packet_hexdump(buf, len);
758 static void mgmt_advertising_removed(uint16_t len, const void *buf)
760 const struct mgmt_ev_advertising_removed *ev = buf;
762 if (len < sizeof(*ev)) {
763 printf("* Malformed Advertising Removed control\n");
767 printf("@ Advertising Removed: %u\n", ev->instance);
772 packet_hexdump(buf, len);
775 void control_message(uint16_t opcode, const void *data, uint16_t size)
778 case MGMT_EV_INDEX_ADDED:
779 mgmt_index_added(size, data);
781 case MGMT_EV_INDEX_REMOVED:
782 mgmt_index_removed(size, data);
784 case MGMT_EV_CONTROLLER_ERROR:
785 mgmt_controller_error(size, data);
787 case MGMT_EV_NEW_SETTINGS:
788 mgmt_new_settings(size, data);
790 case MGMT_EV_CLASS_OF_DEV_CHANGED:
791 mgmt_class_of_dev_changed(size, data);
793 case MGMT_EV_LOCAL_NAME_CHANGED:
794 mgmt_local_name_changed(size, data);
796 case MGMT_EV_NEW_LINK_KEY:
797 mgmt_new_link_key(size, data);
799 case MGMT_EV_NEW_LONG_TERM_KEY:
800 mgmt_new_long_term_key(size, data);
802 case MGMT_EV_DEVICE_CONNECTED:
803 mgmt_device_connected(size, data);
805 case MGMT_EV_DEVICE_DISCONNECTED:
806 mgmt_device_disconnected(size, data);
808 case MGMT_EV_CONNECT_FAILED:
809 mgmt_connect_failed(size, data);
811 case MGMT_EV_PIN_CODE_REQUEST:
812 mgmt_pin_code_request(size, data);
814 case MGMT_EV_USER_CONFIRM_REQUEST:
815 mgmt_user_confirm_request(size, data);
817 case MGMT_EV_USER_PASSKEY_REQUEST:
818 mgmt_user_passkey_request(size, data);
820 case MGMT_EV_AUTH_FAILED:
821 mgmt_auth_failed(size, data);
823 case MGMT_EV_DEVICE_FOUND:
824 mgmt_device_found(size, data);
826 case MGMT_EV_DISCOVERING:
827 mgmt_discovering(size, data);
829 case MGMT_EV_DEVICE_BLOCKED:
830 mgmt_device_blocked(size, data);
832 case MGMT_EV_DEVICE_UNBLOCKED:
833 mgmt_device_unblocked(size, data);
835 case MGMT_EV_DEVICE_UNPAIRED:
836 mgmt_device_unpaired(size, data);
838 case MGMT_EV_PASSKEY_NOTIFY:
839 mgmt_passkey_notify(size, data);
841 case MGMT_EV_NEW_IRK:
842 mgmt_new_irk(size, data);
844 case MGMT_EV_NEW_CSRK:
845 mgmt_new_csrk(size, data);
847 case MGMT_EV_DEVICE_ADDED:
848 mgmt_device_added(size, data);
850 case MGMT_EV_DEVICE_REMOVED:
851 mgmt_device_removed(size, data);
853 case MGMT_EV_NEW_CONN_PARAM:
854 mgmt_new_conn_param(size, data);
856 case MGMT_EV_UNCONF_INDEX_ADDED:
857 mgmt_unconf_index_added(size, data);
859 case MGMT_EV_UNCONF_INDEX_REMOVED:
860 mgmt_unconf_index_removed(size, data);
862 case MGMT_EV_NEW_CONFIG_OPTIONS:
863 mgmt_new_config_options(size, data);
865 case MGMT_EV_EXT_INDEX_ADDED:
866 mgmt_ext_index_added(size, data);
868 case MGMT_EV_EXT_INDEX_REMOVED:
869 mgmt_ext_index_removed(size, data);
871 case MGMT_EV_ADVERTISING_ADDED:
872 mgmt_advertising_added(size, data);
874 case MGMT_EV_ADVERTISING_REMOVED:
875 mgmt_advertising_removed(size, data);
878 printf("* Unknown control (code %d len %d)\n", opcode, size);
879 packet_hexdump(data, size);
884 static void data_callback(int fd, uint32_t events, void *user_data)
886 struct control_data *data = user_data;
887 unsigned char control[32];
892 if (events & (EPOLLERR | EPOLLHUP)) {
893 mainloop_remove_fd(data->fd);
897 iov[0].iov_base = &hdr;
898 iov[0].iov_len = MGMT_HDR_SIZE;
899 iov[1].iov_base = data->buf;
900 iov[1].iov_len = sizeof(data->buf);
902 memset(&msg, 0, sizeof(msg));
905 msg.msg_control = control;
906 msg.msg_controllen = sizeof(control);
909 struct cmsghdr *cmsg;
910 struct timeval *tv = NULL;
912 uint16_t opcode, index, pktlen;
915 len = recvmsg(data->fd, &msg, MSG_DONTWAIT);
919 if (len < MGMT_HDR_SIZE)
922 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
923 cmsg = CMSG_NXTHDR(&msg, cmsg)) {
924 if (cmsg->cmsg_level != SOL_SOCKET)
927 if (cmsg->cmsg_type == SCM_TIMESTAMP) {
928 memcpy(&ctv, CMSG_DATA(cmsg), sizeof(ctv));
933 opcode = le16_to_cpu(hdr.opcode);
934 index = le16_to_cpu(hdr.index);
935 pktlen = le16_to_cpu(hdr.len);
937 switch (data->channel) {
938 case HCI_CHANNEL_CONTROL:
939 packet_control(tv, index, opcode, data->buf, pktlen);
941 case HCI_CHANNEL_MONITOR:
942 btsnoop_write_hci(btsnoop_file, tv, index, opcode,
944 ellisys_inject_hci(tv, index, opcode,
946 packet_monitor(tv, index, opcode, data->buf, pktlen);
952 static int open_socket(uint16_t channel)
954 struct sockaddr_hci addr;
957 fd = socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BTPROTO_HCI);
959 perror("Failed to open channel");
963 memset(&addr, 0, sizeof(addr));
964 addr.hci_family = AF_BLUETOOTH;
965 addr.hci_dev = HCI_DEV_NONE;
966 addr.hci_channel = channel;
968 if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
969 if (errno == EINVAL) {
970 /* Fallback to hcidump support */
971 hcidump_fallback = true;
975 perror("Failed to bind channel");
980 if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt)) < 0) {
981 perror("Failed to enable timestamps");
989 static int open_channel(uint16_t channel)
991 struct control_data *data;
993 data = malloc(sizeof(*data));
997 memset(data, 0, sizeof(*data));
998 data->channel = channel;
1000 data->fd = open_socket(channel);
1006 mainloop_add_fd(data->fd, EPOLLIN, data_callback, data, free_data);
1011 static void client_callback(int fd, uint32_t events, void *user_data)
1013 struct control_data *data = user_data;
1016 if (events & (EPOLLERR | EPOLLHUP)) {
1017 mainloop_remove_fd(data->fd);
1021 len = recv(data->fd, data->buf + data->offset,
1022 sizeof(data->buf) - data->offset, MSG_DONTWAIT);
1026 data->offset += len;
1028 if (data->offset > MGMT_HDR_SIZE) {
1029 struct mgmt_hdr *hdr = (struct mgmt_hdr *) data->buf;
1030 uint16_t pktlen = le16_to_cpu(hdr->len);
1032 if (data->offset > pktlen + MGMT_HDR_SIZE) {
1033 uint16_t opcode = le16_to_cpu(hdr->opcode);
1034 uint16_t index = le16_to_cpu(hdr->index);
1036 packet_monitor(NULL, index, opcode,
1037 data->buf + MGMT_HDR_SIZE, pktlen);
1039 data->offset -= pktlen + MGMT_HDR_SIZE;
1041 if (data->offset > 0)
1042 memmove(data->buf, data->buf +
1043 MGMT_HDR_SIZE + pktlen, data->offset);
1048 static void server_accept_callback(int fd, uint32_t events, void *user_data)
1050 struct control_data *data;
1051 struct sockaddr_un addr;
1055 if (events & (EPOLLERR | EPOLLHUP)) {
1056 mainloop_remove_fd(fd);
1060 memset(&addr, 0, sizeof(addr));
1063 nfd = accept(fd, (struct sockaddr *) &addr, &len);
1065 perror("Failed to accept client socket");
1069 printf("--- New monitor connection ---\n");
1071 data = malloc(sizeof(*data));
1077 memset(data, 0, sizeof(*data));
1078 data->channel = HCI_CHANNEL_MONITOR;
1081 mainloop_add_fd(data->fd, EPOLLIN, client_callback, data, free_data);
1084 static int server_fd = -1;
1086 void control_server(const char *path)
1088 struct sockaddr_un addr;
1096 fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
1098 perror("Failed to open server socket");
1102 memset(&addr, 0, sizeof(addr));
1103 addr.sun_family = AF_UNIX;
1104 strcpy(addr.sun_path, path);
1106 if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1107 perror("Failed to bind server socket");
1112 if (listen(fd, 5) < 0) {
1113 perror("Failed to listen server socket");
1118 if (mainloop_add_fd(fd, EPOLLIN, server_accept_callback,
1127 #ifdef __TIZEN_PATCH__
1128 bool control_writer(const char *path, int16_t rotate_count, ssize_t file_size)
1130 bool control_writer(const char *path)
1133 #ifdef __TIZEN_PATCH__
1134 btsnoop_file = btsnoop_create(path, BTSNOOP_TYPE_MONITOR,
1135 rotate_count, file_size);
1137 btsnoop_file = btsnoop_create(path, BTSNOOP_TYPE_MONITOR);
1140 return !!btsnoop_file;
1143 void control_reader(const char *path)
1145 unsigned char buf[BTSNOOP_MAX_PACKET_SIZE];
1150 btsnoop_file = btsnoop_open(path, BTSNOOP_FLAG_PKLG_SUPPORT);
1154 type = btsnoop_get_type(btsnoop_file);
1157 case BTSNOOP_TYPE_HCI:
1158 case BTSNOOP_TYPE_UART:
1159 case BTSNOOP_TYPE_SIMULATOR:
1160 packet_del_filter(PACKET_FILTER_SHOW_INDEX);
1163 case BTSNOOP_TYPE_MONITOR:
1164 packet_add_filter(PACKET_FILTER_SHOW_INDEX);
1171 case BTSNOOP_TYPE_HCI:
1172 case BTSNOOP_TYPE_UART:
1173 case BTSNOOP_TYPE_MONITOR:
1175 uint16_t index, opcode;
1177 if (!btsnoop_read_hci(btsnoop_file, &tv, &index,
1178 &opcode, buf, &pktlen))
1181 if (opcode == 0xffff)
1184 packet_monitor(&tv, index, opcode, buf, pktlen);
1185 ellisys_inject_hci(&tv, index, opcode, buf, pktlen);
1189 case BTSNOOP_TYPE_SIMULATOR:
1193 if (!btsnoop_read_phy(btsnoop_file, &tv, &frequency,
1197 packet_simulator(&tv, frequency, buf, pktlen);
1204 btsnoop_unref(btsnoop_file);
1207 int control_tracing(void)
1209 packet_add_filter(PACKET_FILTER_SHOW_INDEX);
1214 if (open_channel(HCI_CHANNEL_MONITOR) < 0) {
1215 if (!hcidump_fallback)
1217 if (hcidump_tracing() < 0)
1222 open_channel(HCI_CHANNEL_CONTROL);