* [PATCH 1/4] monitor: add include <stdint.h> @ 2012-05-22 5:40 Gustavo Padovan 2012-05-22 5:40 ` [PATCH 2/4] monitor: add config_file parser Gustavo Padovan 0 siblings, 1 reply; 7+ messages in thread From: Gustavo Padovan @ 2012-05-22 5:40 UTC (permalink / raw) To: linux-bluetooth; +Cc: Gustavo Padovan From: Gustavo Padovan <gustavo.padovan@collabora.co.uk> --- monitor/packet.h | 1 + 1 file changed, 1 insertion(+) diff --git a/monitor/packet.h b/monitor/packet.h index 90fc7ec..4c8b698 100644 --- a/monitor/packet.h +++ b/monitor/packet.h @@ -23,6 +23,7 @@ */ #include <stdbool.h> +#include <stdint.h> #include <sys/time.h> #define PACKET_FILTER_SHOW_INDEX (1 << 0) -- 1.7.10.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/4] monitor: add config_file parser 2012-05-22 5:40 [PATCH 1/4] monitor: add include <stdint.h> Gustavo Padovan @ 2012-05-22 5:40 ` Gustavo Padovan 2012-05-22 5:40 ` [PATCH 3/4] monitor: add filter support Gustavo Padovan 0 siblings, 1 reply; 7+ messages in thread From: Gustavo Padovan @ 2012-05-22 5:40 UTC (permalink / raw) To: linux-bluetooth; +Cc: Gustavo Padovan From: Gustavo Padovan <gustavo.padovan@collabora.co.uk> parse_config() returns a list with the filter data for each controller entry. --- Makefile.tools | 5 +- monitor/config_file.c | 325 +++++++++++++++++++++++++++++++++++++++++++++++++ monitor/config_file.h | 30 +++++ monitor/list.c | 44 +++++++ monitor/list.h | 32 +++++ monitor/main.c | 9 +- monitor/packet.h | 7 +- 7 files changed, 448 insertions(+), 4 deletions(-) create mode 100644 monitor/config_file.c create mode 100644 monitor/config_file.h create mode 100644 monitor/list.c create mode 100644 monitor/list.h diff --git a/Makefile.tools b/Makefile.tools index 4df7453..b82d4bc 100644 --- a/Makefile.tools +++ b/Makefile.tools @@ -60,7 +60,10 @@ monitor_btmon_SOURCES = monitor/main.c monitor/bt.h \ monitor/hcidump.h monitor/hcidump.c \ monitor/btsnoop.h monitor/btsnoop.c \ monitor/control.h monitor/control.c \ - monitor/packet.h monitor/packet.c + monitor/packet.h monitor/packet.c \ + monitor/config_file.h \ + monitor/config_file.c \ + monitor/list.h monitor/list.c monitor_btmon_LDADD = lib/libbluetooth-private.la emulator_btvirt_SOURCES = emulator/main.c monitor/bt.h \ diff --git a/monitor/config_file.c b/monitor/config_file.c new file mode 100644 index 0000000..6fb50f9 --- /dev/null +++ b/monitor/config_file.c @@ -0,0 +1,325 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Collabora Ltd. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> + +#include <ctype.h> +#include <unistd.h> +#include <stdlib.h> +#include <time.h> +#include <sys/time.h> + +#include "config_file.h" +#include "packet.h" + +#define PROTO_FILT (PACKET_FILTER_SHOW_HCI | PACKET_FILTER_SHOW_ACL \ + | PACKET_FILTER_SHOW_SCO) +#define TS_MASK (PACKET_FILTER_SHOW_DATE | PACKET_FILTER_SHOW_TIME) + +#define error(fmt ,l, arg...) \ + fprintf(stderr, "line %d: error: " fmt "\n",l, ## arg) + +#define SPACE " \n\t\r," + +enum keyword_code { + OP_CONTROLLER, + OP_IGNORE, + OP_SHOW, + OP_HIDE, + OP_TIMESTAMPS, + OP_ERROR, +}; + +static struct keyword { + const char *string; + int code; +} kw[] = { + { "Controller", OP_CONTROLLER }, + { "Ignore", OP_IGNORE }, + { "Show", OP_SHOW }, + { "Hide", OP_HIDE }, + { "Timestamps", OP_TIMESTAMPS }, + { NULL, OP_ERROR } +}; + +static struct filter_options { + const char *string; + int bit; +} filters[] = { + { "HCI", PACKET_FILTER_SHOW_HCI }, + { "L2CAP", PACKET_FILTER_SHOW_ACL }, + { "SCO", PACKET_FILTER_SHOW_SCO }, + { NULL, 0 } +}; + +struct controller *controller; + +static void free_controllers_list(struct list *controllers_l) +{ + struct list *l, *tmp; + + for (l = controllers_l->next ; l != controllers_l ; ) { + tmp = l; + + list_del(l); + l = l->next; + + free(tmp->controller->value); + free(tmp->controller); + free(tmp); + } + + free(controllers_l); +} + +static char *find_token(char *line) +{ + int n; + + if (line == NULL) + return NULL; + + line += strspn(line, SPACE); + if (line[0] == '\0' || line[0] == '\n' || line[0] == '\r') + return NULL; + + n = strcspn(line, SPACE); + if (n == 0) + return NULL; + + line[n] = '\0'; + + return line; +} + +static int create_controller(struct list *controllers_l, char *c) +{ + struct list *l; + + l = calloc(1, sizeof(*l)); + if (!l) + return -ENOMEM; + + l->controller = calloc(1, sizeof(*l->controller)); + if (!l->controller) { + free(l); + return -ENOMEM; + } + + l->controller->value = strdup(c); + + l->controller->filter = ~0UL; + + list_append(controllers_l, l); + + controller = l->controller; + + return 0; +} + +static int get_filter(char *s, unsigned long *f, int line) +{ + int i, found; + + *f = 0L; + + s = find_token(s + strlen(s) + 1); + if (!s) + error("no options specified", line); + + do { + found = 0; + for (i = 0 ; filters[i].string ; i++) { + if (!strcasecmp(s, filters[i].string)) { + found = 1; + break; + } + } + + if (!found) { + error("invalid filter parameter: %s", line, s); + return -EINVAL; + } + + *f |= filters[i].bit; + s = find_token(s + strlen(s) + 1); + } while(s); + + return 0; +} + +static int parse_on_off(char *c, int line) +{ + char *state; + int ret; + + state = find_token(c + strlen(c) + 1); + if (!strcasecmp(state, "on")) { + ret = 1; + } else if (!strcasecmp(state, "off")) { + ret = 0; + } else { + error("parameter should be 'on' or 'off'", line); + return -EINVAL; + } + + return ret; +} + +static int process_keyword(struct list *controllers_l, char *key, int line) +{ + char *value; + unsigned long filter; + int i, v, err; + + for (i = 0 ; kw[i].string ; i++) { + if (!strcasecmp(key, kw[i].string)) + break; + } + + if ((kw[i].code != OP_CONTROLLER) && !controller) { + error("no controller specified", line); + return -EINVAL; + } + + err = 0; + switch (kw[i].code) { + case OP_CONTROLLER: + value = find_token(key + strlen(key) + 1); + if (!value) { + error("missing expected paramenter for 'Controller'", + line); + return -EINVAL; + } + + err = create_controller(controllers_l, value); + break; + case OP_IGNORE: + controller->ignore = 1; + break; + case OP_SHOW: + if ((controller->filter | TS_MASK) != ~0UL) { + error("'Hide' option was specified, can't set 'Show'", + line); + return -EINVAL; + } + + err = get_filter(key, &filter, line); + if (err) + return err; + + controller->filter &= (0L | TS_MASK); + + controller->filter |= filter; + + break; + + case OP_HIDE: + if ((controller->filter | TS_MASK) != ~0UL) { + error("'Show' option was specified, can't set 'Hide'", + line); + return -EINVAL; + } + + err = get_filter(key, &filter, line); + if (err) + return err; + + controller->filter &= ~filter; + + break; + case OP_TIMESTAMPS: + v = parse_on_off(key, line); + if (v < 0) + return v; + + if (v == 0) + controller->filter &= ~(PACKET_FILTER_SHOW_DATE | + PACKET_FILTER_SHOW_TIME); + + break; + case OP_ERROR: + error("string not recognized: '%s'", line, key); + return -EINVAL; + } + + return err; +} + +struct list *parse_config(char *file) +{ + FILE *f; + struct stat s; + int line; + char buf[1024]; + struct list *controllers_l; + + if (stat(file, &s) < 0) { + fprintf(stderr, "failed to get file status '%s' (%d)\n", file, + errno); + return NULL; + + } + + f = fopen(file, "r"); + if (!f) { + fprintf(stderr, "failed to open filter file '%s' (%d)\n", file, + errno); + return NULL; + } + + /*Allocate list head */ + controllers_l = calloc(1, sizeof(*controllers_l)); + if (!controllers_l) + goto error; + + list_init(controllers_l); + + line = 1; + memset(buf, 0, sizeof(buf)); + while (fgets(buf, sizeof(buf), f)) { + char *key = find_token(buf); + + if (key && key[0] != '#') { + if (process_keyword(controllers_l, key, line) < 0) + goto error; + } + + line++; + memset(buf, 0, sizeof(buf)); + } + + fclose(f); + return controllers_l; + +error: + free_controllers_list(controllers_l); + fclose(f); + return NULL; +} + diff --git a/monitor/config_file.h b/monitor/config_file.h new file mode 100644 index 0000000..9190e01 --- /dev/null +++ b/monitor/config_file.h @@ -0,0 +1,30 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Collabora Ltd. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +struct controller { + char *value; + unsigned long filter; + int ignore:1; +}; + +struct list *parse_config(char *file); diff --git a/monitor/list.c b/monitor/list.c new file mode 100644 index 0000000..8ac4647 --- /dev/null +++ b/monitor/list.c @@ -0,0 +1,44 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Collabora Ltd. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "list.h" + +void list_init(struct list *l) +{ + l->next = l; + l->prev = l; +} + +void list_append(struct list *head, struct list *l) +{ + l->next = head; + l->prev = head->prev; + head->prev->next = l; + head->prev = l; +} + +void list_del(struct list *l) +{ + l->next->prev = l->prev; + l->prev->next = l->next; +} diff --git a/monitor/list.h b/monitor/list.h new file mode 100644 index 0000000..046811c --- /dev/null +++ b/monitor/list.h @@ -0,0 +1,32 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2012 Collabora Ltd. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +struct list { + struct list *next; + struct list *prev; + struct controller *controller; +}; + +void list_init(struct list *l); +void list_append(struct list *head, struct list *l); +void list_del(struct list *l); diff --git a/monitor/main.c b/monitor/main.c index 90e32c5..1379839 100644 --- a/monitor/main.c +++ b/monitor/main.c @@ -35,6 +35,7 @@ #include "control.h" #include "hcidump.h" #include "btsnoop.h" +#include "config_file.h" static void signal_callback(int signum, void *user_data) { @@ -52,11 +53,13 @@ static void usage(void) "Usage:\n"); printf("\tbtmon [options]\n"); printf("options:\n" + "\t-f, --filter <file> Filter file\n" "\t-b, --btsnoop <file> Save dump in btsnoop format\n" "\t-h, --help Show help options\n"); } static const struct option main_options[] = { + { "filter", required_argument, NULL, 'f' }, { "btsnoop", required_argument, NULL, 'b' }, { "version", no_argument, NULL, 'v' }, { "help", no_argument, NULL, 'h' }, @@ -73,11 +76,15 @@ int main(int argc, char *argv[]) for (;;) { int opt; - opt = getopt_long(argc, argv, "bvh", main_options, NULL); + opt = getopt_long(argc, argv, "f:bvh", main_options, NULL); if (opt < 0) break; switch (opt) { + case 'f': + if (!parse_config(optarg)) + return EXIT_FAILURE; + break; case 'b': btsnoop_open(optarg); break; diff --git a/monitor/packet.h b/monitor/packet.h index 4c8b698..c8d011d 100644 --- a/monitor/packet.h +++ b/monitor/packet.h @@ -29,8 +29,11 @@ #define PACKET_FILTER_SHOW_INDEX (1 << 0) #define PACKET_FILTER_SHOW_DATE (1 << 1) #define PACKET_FILTER_SHOW_TIME (1 << 2) -#define PACKET_FILTER_SHOW_ACL_DATA (1 << 3) -#define PACKET_FILTER_SHOW_SCO_DATA (1 << 4) +#define PACKET_FILTER_SHOW_HCI (1 << 3) +#define PACKET_FILTER_SHOW_ACL (1 << 4) +#define PACKET_FILTER_SHOW_SCO (1 << 5) +#define PACKET_FILTER_SHOW_ACL_DATA (1 << 6) +#define PACKET_FILTER_SHOW_SCO_DATA (1 << 7) void packet_set_filter(unsigned long filter); -- 1.7.10.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/4] monitor: add filter support 2012-05-22 5:40 ` [PATCH 2/4] monitor: add config_file parser Gustavo Padovan @ 2012-05-22 5:40 ` Gustavo Padovan 2012-05-22 5:40 ` [PATCH 4/4] monitor: add example filter file Gustavo Padovan 2012-05-22 15:02 ` [PATCH 3/4] monitor: add filter support Vinicius Costa Gomes 0 siblings, 2 replies; 7+ messages in thread From: Gustavo Padovan @ 2012-05-22 5:40 UTC (permalink / raw) To: linux-bluetooth; +Cc: Gustavo Padovan From: Gustavo Padovan <gustavo.padovan@collabora.co.uk> the packet code receives the data parsed from the filter file and apply the proper filters to the devices. --- monitor/config_file.c | 4 +- monitor/config_file.h | 1 + monitor/main.c | 21 +++++----- monitor/packet.c | 108 ++++++++++++++++++++++++++++++++++++++++--------- monitor/packet.h | 4 +- 5 files changed, 106 insertions(+), 32 deletions(-) diff --git a/monitor/config_file.c b/monitor/config_file.c index 6fb50f9..464fe4f 100644 --- a/monitor/config_file.c +++ b/monitor/config_file.c @@ -79,7 +79,7 @@ static struct filter_options { struct controller *controller; -static void free_controllers_list(struct list *controllers_l) +void controllers_list_free(struct list *controllers_l) { struct list *l, *tmp; @@ -318,7 +318,7 @@ struct list *parse_config(char *file) return controllers_l; error: - free_controllers_list(controllers_l); + controllers_list_free(controllers_l); fclose(f); return NULL; } diff --git a/monitor/config_file.h b/monitor/config_file.h index 9190e01..dd5fe79 100644 --- a/monitor/config_file.h +++ b/monitor/config_file.h @@ -28,3 +28,4 @@ struct controller { }; struct list *parse_config(char *file); +void controllers_list_free(struct list *controllers_l); diff --git a/monitor/main.c b/monitor/main.c index 1379839..c429333 100644 --- a/monitor/main.c +++ b/monitor/main.c @@ -68,8 +68,9 @@ static const struct option main_options[] = { int main(int argc, char *argv[]) { - unsigned long filter_mask = 0; + struct list *filter_l = NULL; sigset_t mask; + int err; mainloop_init(); @@ -82,7 +83,8 @@ int main(int argc, char *argv[]) switch (opt) { case 'f': - if (!parse_config(optarg)) + filter_l = parse_config(optarg); + if (!filter_l) return EXIT_FAILURE; break; case 'b': @@ -105,18 +107,19 @@ int main(int argc, char *argv[]) mainloop_set_signal(&mask, signal_callback, NULL, NULL); - filter_mask |= PACKET_FILTER_SHOW_INDEX; - filter_mask |= PACKET_FILTER_SHOW_TIME; - filter_mask |= PACKET_FILTER_SHOW_ACL_DATA; - - packet_set_filter(filter_mask); + packet_set_filter(filter_l); printf("Bluetooth monitor ver %s\n", VERSION); if (control_tracing() < 0) { - if (hcidump_tracing() < 0) + if (hcidump_tracing() < 0) { + controllers_list_free(filter_l); return EXIT_FAILURE; + } } - return mainloop_run(); + err = mainloop_run(); + + controllers_list_free(filter_l); + return err; } diff --git a/monitor/packet.c b/monitor/packet.c index 0f14ea6..bdc9705 100644 --- a/monitor/packet.c +++ b/monitor/packet.c @@ -43,18 +43,74 @@ #include "control.h" #include "btsnoop.h" #include "packet.h" +#include "config_file.h" -static unsigned long filter_mask = 0; +#define MAX_INDEX 16 + +struct monitor_new_index { + uint8_t type; + uint8_t bus; + bdaddr_t bdaddr; + char name[8]; +} __attribute__((packed)); -void packet_set_filter(unsigned long filter) +struct index_filter { + unsigned long filter; + uint8_t ignore; +}; + +static struct monitor_new_index index_list[MAX_INDEX]; +static struct index_filter index_filter[MAX_INDEX]; +static struct list *filter_l; + +void packet_set_filter(struct list *filter) { - filter_mask = filter; + filter_l = filter; +} + +static int filter_bacmp(char *str1, char *str2) +{ + int i, max; + + max = strlen(str1) < 18 ? strlen(str1) : 18; + + for (i = 0 ; i < max ; i++) { + if (str1[i] == '*') + return 1; + if (str1[i] != str2[i]) + return 0; + } + + return 1; +} + +static void packet_set_index_filter(int index) +{ + char str[18]; + struct list *l; + + index_filter[index].ignore = 0; + index_filter[index].filter = ~0UL; + + ba2str(&index_list[index].bdaddr, str); + + for (l = filter_l->next ; l != filter_l ; l = l->next) { + if (filter_bacmp(l->controller->value, str)) { + index_filter[index].ignore = l->controller->ignore; + index_filter[index].filter = l->controller->filter; + } + } +} + +static int filter_check_flag(uint16_t index, int flag) +{ + return (index_filter[index].filter & flag); } static void print_channel_header(struct timeval *tv, uint16_t index, uint16_t channel) { - if (filter_mask & PACKET_FILTER_SHOW_INDEX) { + if (filter_check_flag(index, PACKET_FILTER_SHOW_INDEX)) { switch (channel) { case HCI_CHANNEL_CONTROL: printf("{hci%d} ", index); @@ -71,11 +127,11 @@ static void print_channel_header(struct timeval *tv, uint16_t index, localtime_r(&t, &tm); - if (filter_mask & PACKET_FILTER_SHOW_DATE) + if (filter_check_flag(index, PACKET_FILTER_SHOW_DATE)) printf("%04d-%02d-%02d ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); - if (filter_mask & PACKET_FILTER_SHOW_TIME) + if (filter_check_flag(index, PACKET_FILTER_SHOW_TIME)) printf("%02d:%02d:%02d.%06lu ", tm.tm_hour, tm.tm_min, tm.tm_sec, tv->tv_usec); } @@ -128,6 +184,9 @@ void packet_hexdump(const unsigned char *buf, uint16_t len) void packet_control(struct timeval *tv, uint16_t index, uint16_t opcode, const void *data, uint16_t size) { + if (index_filter[index].ignore) + return + print_channel_header(tv, index, HCI_CHANNEL_CONTROL); control_message(opcode, data, size); @@ -142,33 +201,30 @@ void packet_control(struct timeval *tv, uint16_t index, uint16_t opcode, #define MONITOR_SCO_TX_PKT 6 #define MONITOR_SCO_RX_PKT 7 -struct monitor_new_index { - uint8_t type; - uint8_t bus; - bdaddr_t bdaddr; - char name[8]; -} __attribute__((packed)); - #define MONITOR_NEW_INDEX_SIZE 16 #define MONITOR_DEL_INDEX_SIZE 0 -#define MAX_INDEX 16 - -static struct monitor_new_index index_list[MAX_INDEX]; - void packet_monitor(struct timeval *tv, uint16_t index, uint16_t opcode, const void *data, uint16_t size) { const struct monitor_new_index *ni; char str[18]; + if (index_filter[index].ignore) + return; + switch (opcode) { case MONITOR_NEW_INDEX: ni = data; - if (index < MAX_INDEX) + if (index < MAX_INDEX) { memcpy(&index_list[index], ni, MONITOR_NEW_INDEX_SIZE); + packet_set_index_filter(index); + } + + if (index_filter[index].ignore) + break; ba2str(&ni->bdaddr, str); packet_new_index(tv, index, str, ni->type, ni->bus, ni->name); @@ -573,6 +629,9 @@ void packet_hci_command(struct timeval *tv, uint16_t index, btsnoop_write(tv, index, 0x02, data, size); + if (!filter_check_flag(index, PACKET_FILTER_SHOW_HCI)) + return; + print_header(tv, index); if (size < HCI_COMMAND_HDR_SIZE) { @@ -596,6 +655,9 @@ void packet_hci_event(struct timeval *tv, uint16_t index, btsnoop_write(tv, index, 0x03, data, size); + if (!filter_check_flag(index, PACKET_FILTER_SHOW_HCI)) + return; + print_header(tv, index); if (size < HCI_EVENT_HDR_SIZE) { @@ -622,6 +684,9 @@ void packet_hci_acldata(struct timeval *tv, uint16_t index, bool in, btsnoop_write(tv, index, in ? 0x01 : 0x00, data, size); + if (!filter_check_flag(index, PACKET_FILTER_SHOW_ACL)) + return; + print_header(tv, index); if (size < HCI_ACL_HDR_SIZE) { @@ -635,7 +700,7 @@ void packet_hci_acldata(struct timeval *tv, uint16_t index, bool in, data += HCI_ACL_HDR_SIZE; size -= HCI_ACL_HDR_SIZE; - if (filter_mask & PACKET_FILTER_SHOW_ACL_DATA) + if (filter_check_flag(index, PACKET_FILTER_SHOW_ACL_DATA)) packet_hexdump(data, size); } @@ -646,6 +711,9 @@ void packet_hci_scodata(struct timeval *tv, uint16_t index, bool in, uint16_t handle = btohs(hdr->handle); uint8_t flags = acl_flags(handle); + if (!filter_check_flag(index, PACKET_FILTER_SHOW_SCO)) + return; + print_header(tv, index); if (size < HCI_SCO_HDR_SIZE) { @@ -659,6 +727,6 @@ void packet_hci_scodata(struct timeval *tv, uint16_t index, bool in, data += HCI_SCO_HDR_SIZE; size -= HCI_SCO_HDR_SIZE; - if (filter_mask & PACKET_FILTER_SHOW_SCO_DATA) + if (filter_check_flag(index, PACKET_FILTER_SHOW_SCO_DATA)) packet_hexdump(data, size); } diff --git a/monitor/packet.h b/monitor/packet.h index c8d011d..aa113df 100644 --- a/monitor/packet.h +++ b/monitor/packet.h @@ -26,6 +26,8 @@ #include <stdint.h> #include <sys/time.h> +#include "list.h" + #define PACKET_FILTER_SHOW_INDEX (1 << 0) #define PACKET_FILTER_SHOW_DATE (1 << 1) #define PACKET_FILTER_SHOW_TIME (1 << 2) @@ -35,7 +37,7 @@ #define PACKET_FILTER_SHOW_ACL_DATA (1 << 6) #define PACKET_FILTER_SHOW_SCO_DATA (1 << 7) -void packet_set_filter(unsigned long filter); +void packet_set_filter(struct list *filter); void packet_hexdump(const unsigned char *buf, uint16_t len); -- 1.7.10.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 4/4] monitor: add example filter file 2012-05-22 5:40 ` [PATCH 3/4] monitor: add filter support Gustavo Padovan @ 2012-05-22 5:40 ` Gustavo Padovan 2012-05-22 15:02 ` [PATCH 3/4] monitor: add filter support Vinicius Costa Gomes 1 sibling, 0 replies; 7+ messages in thread From: Gustavo Padovan @ 2012-05-22 5:40 UTC (permalink / raw) To: linux-bluetooth; +Cc: Gustavo Padovan From: Gustavo Padovan <gustavo.padovan@collabora.co.uk> --- monitor/filter.example | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 monitor/filter.example diff --git a/monitor/filter.example b/monitor/filter.example new file mode 100644 index 0000000..e84b07f --- /dev/null +++ b/monitor/filter.example @@ -0,0 +1,31 @@ +# +# Example filter file for btmon. +# +# It should be used with the -f option of btmon: +# +# $ btmon -f <filter file> +# +# +# The basic structure of the file is show below, we always need a 'Controller' +# keyword followed by a Bluetooth pattern, wild card is accepted. +# +# Then there is 4 possible configurations you can specify: +# - 'Timestamps' to show timestamps or not +# - 'Show' to selects which protocols to show, any protocol not listed here is +# hided. +# - 'Hide' to hide specific protocols. All the others are shown. 'Show' and +# 'Hide' can't be used together. +# - 'Ignore' to ignore this device in btmon. +# +# The available options for 'Show' and 'Hide' are l2cap, sco and hci. + +Controller * + Timestamps on + Show l2cap + +Controller 00:11:22:33:44:55 + Timestamps off + Hide sco,hci + +Controller CA:FE:CA:FE:* + Ignore -- 1.7.10.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 3/4] monitor: add filter support 2012-05-22 5:40 ` [PATCH 3/4] monitor: add filter support Gustavo Padovan 2012-05-22 5:40 ` [PATCH 4/4] monitor: add example filter file Gustavo Padovan @ 2012-05-22 15:02 ` Vinicius Costa Gomes 2012-05-22 15:30 ` Gustavo Padovan 1 sibling, 1 reply; 7+ messages in thread From: Vinicius Costa Gomes @ 2012-05-22 15:02 UTC (permalink / raw) To: Gustavo Padovan; +Cc: linux-bluetooth, Gustavo Padovan Hi Gustavo, Here are some nitpicks, feel free to ignore them. On 02:40 Tue 22 May, Gustavo Padovan wrote: > From: Gustavo Padovan <gustavo.padovan@collabora.co.uk> The title "add filter support" is not totally correct, there was some support for filters, but it was quite basic, right? > > the packet code receives the data parsed from the filter file and apply > the proper filters to the devices. > --- > monitor/config_file.c | 4 +- > monitor/config_file.h | 1 + > monitor/main.c | 21 +++++----- > monitor/packet.c | 108 ++++++++++++++++++++++++++++++++++++++++--------- > monitor/packet.h | 4 +- > 5 files changed, 106 insertions(+), 32 deletions(-) > > diff --git a/monitor/config_file.c b/monitor/config_file.c > index 6fb50f9..464fe4f 100644 > --- a/monitor/config_file.c > +++ b/monitor/config_file.c > @@ -79,7 +79,7 @@ static struct filter_options { > > struct controller *controller; > > -static void free_controllers_list(struct list *controllers_l) > +void controllers_list_free(struct list *controllers_l) This change is somewhat unrelated. > { > struct list *l, *tmp; > > @@ -318,7 +318,7 @@ struct list *parse_config(char *file) > return controllers_l; > > error: [snip] > > void packet_hexdump(const unsigned char *buf, uint16_t len); > > -- > 1.7.10.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html Cheers, -- Vinicius ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 3/4] monitor: add filter support 2012-05-22 15:02 ` [PATCH 3/4] monitor: add filter support Vinicius Costa Gomes @ 2012-05-22 15:30 ` Gustavo Padovan 0 siblings, 0 replies; 7+ messages in thread From: Gustavo Padovan @ 2012-05-22 15:30 UTC (permalink / raw) To: Vinicius Costa Gomes; +Cc: linux-bluetooth, Gustavo Padovan Hi Vinicius, * Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2012-05-22 12:02:39 -0300]: > Hi Gustavo, > > Here are some nitpicks, feel free to ignore them. > > On 02:40 Tue 22 May, Gustavo Padovan wrote: > > From: Gustavo Padovan <gustavo.padovan@collabora.co.uk> > > The title "add filter support" is not totally correct, there was some > support for filters, but it was quite basic, right? Quite basic, and there wasn't any option to set it from command line so I decided to call this "add filter support" > > > > > the packet code receives the data parsed from the filter file and apply > > the proper filters to the devices. > > --- > > monitor/config_file.c | 4 +- > > monitor/config_file.h | 1 + > > monitor/main.c | 21 +++++----- > > monitor/packet.c | 108 ++++++++++++++++++++++++++++++++++++++++--------- > > monitor/packet.h | 4 +- > > 5 files changed, 106 insertions(+), 32 deletions(-) > > > > diff --git a/monitor/config_file.c b/monitor/config_file.c > > index 6fb50f9..464fe4f 100644 > > --- a/monitor/config_file.c > > +++ b/monitor/config_file.c > > @@ -79,7 +79,7 @@ static struct filter_options { > > > > struct controller *controller; > > > > -static void free_controllers_list(struct list *controllers_l) > > +void controllers_list_free(struct list *controllers_l) > > This change is somewhat unrelated. Kind of, I had to export this function for this patch and I changed the name to some that makes more sense. Gustavo ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/4] monitor: add include <stdint.h> @ 2012-06-13 2:59 Gustavo Padovan 2012-06-13 2:59 ` [PATCH 3/4] monitor: add filter support Gustavo Padovan 0 siblings, 1 reply; 7+ messages in thread From: Gustavo Padovan @ 2012-06-13 2:59 UTC (permalink / raw) To: linux-bluetooth; +Cc: Gustavo Padovan From: Gustavo Padovan <gustavo.padovan@collabora.co.uk> --- monitor/packet.h | 1 + 1 file changed, 1 insertion(+) diff --git a/monitor/packet.h b/monitor/packet.h index 90fc7ec..4c8b698 100644 --- a/monitor/packet.h +++ b/monitor/packet.h @@ -23,6 +23,7 @@ */ #include <stdbool.h> +#include <stdint.h> #include <sys/time.h> #define PACKET_FILTER_SHOW_INDEX (1 << 0) -- 1.7.10.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/4] monitor: add filter support 2012-06-13 2:59 [PATCH 1/4] monitor: add include <stdint.h> Gustavo Padovan @ 2012-06-13 2:59 ` Gustavo Padovan 0 siblings, 0 replies; 7+ messages in thread From: Gustavo Padovan @ 2012-06-13 2:59 UTC (permalink / raw) To: linux-bluetooth; +Cc: Gustavo Padovan From: Gustavo Padovan <gustavo.padovan@collabora.co.uk> The packet code receives the data parsed from the filter file and apply the proper filters to the devices. --- monitor/config_file.c | 2 +- monitor/config_file.h | 1 + monitor/main.c | 21 +++++---- monitor/packet.c | 116 ++++++++++++++++++++++++++++++++++++++++--------- monitor/packet.h | 4 +- 5 files changed, 113 insertions(+), 31 deletions(-) diff --git a/monitor/config_file.c b/monitor/config_file.c index 5ebbeae..aed9d94 100644 --- a/monitor/config_file.c +++ b/monitor/config_file.c @@ -77,7 +77,7 @@ static struct filter_options { struct controller *controller; -static void controllers_list_free(struct list *controllers_l) +void controllers_list_free(struct list *controllers_l) { struct list *l, *tmp; diff --git a/monitor/config_file.h b/monitor/config_file.h index 9190e01..dd5fe79 100644 --- a/monitor/config_file.h +++ b/monitor/config_file.h @@ -28,3 +28,4 @@ struct controller { }; struct list *parse_config(char *file); +void controllers_list_free(struct list *controllers_l); diff --git a/monitor/main.c b/monitor/main.c index 1379839..c429333 100644 --- a/monitor/main.c +++ b/monitor/main.c @@ -68,8 +68,9 @@ static const struct option main_options[] = { int main(int argc, char *argv[]) { - unsigned long filter_mask = 0; + struct list *filter_l = NULL; sigset_t mask; + int err; mainloop_init(); @@ -82,7 +83,8 @@ int main(int argc, char *argv[]) switch (opt) { case 'f': - if (!parse_config(optarg)) + filter_l = parse_config(optarg); + if (!filter_l) return EXIT_FAILURE; break; case 'b': @@ -105,18 +107,19 @@ int main(int argc, char *argv[]) mainloop_set_signal(&mask, signal_callback, NULL, NULL); - filter_mask |= PACKET_FILTER_SHOW_INDEX; - filter_mask |= PACKET_FILTER_SHOW_TIME; - filter_mask |= PACKET_FILTER_SHOW_ACL_DATA; - - packet_set_filter(filter_mask); + packet_set_filter(filter_l); printf("Bluetooth monitor ver %s\n", VERSION); if (control_tracing() < 0) { - if (hcidump_tracing() < 0) + if (hcidump_tracing() < 0) { + controllers_list_free(filter_l); return EXIT_FAILURE; + } } - return mainloop_run(); + err = mainloop_run(); + + controllers_list_free(filter_l); + return err; } diff --git a/monitor/packet.c b/monitor/packet.c index 0f14ea6..0d62b51 100644 --- a/monitor/packet.c +++ b/monitor/packet.c @@ -43,18 +43,82 @@ #include "control.h" #include "btsnoop.h" #include "packet.h" +#include "config_file.h" -static unsigned long filter_mask = 0; +#define MAX_INDEX 16 + +struct monitor_new_index { + uint8_t type; + uint8_t bus; + bdaddr_t bdaddr; + char name[8]; +} __attribute__((packed)); + +struct index_filter { + unsigned long filter; + uint8_t ignore; +}; + +static struct monitor_new_index index_list[MAX_INDEX]; +static struct index_filter index_filter[MAX_INDEX]; +static struct list *filter_l; + +void packet_set_filter(struct list *filter) +{ + filter_l = filter; +} + +static int filter_bacmp(char *str1, char *str2) +{ + int i, max; + + max = strlen(str1) < 18 ? strlen(str1) : 18; + + for (i = 0 ; i < max ; i++) { + if (str1[i] == '*') + return 1; + if (str1[i] != str2[i]) + return 0; + } + + return 1; +} + +static void packet_set_index_filter(int index) +{ + char str[18]; + struct list *l; + + index_filter[index].ignore = 0; + index_filter[index].filter = ~0UL; + + if (!filter_l) + return; + + ba2str(&index_list[index].bdaddr, str); + + for (l = filter_l->next ; l != filter_l ; l = l->next) { + if (filter_bacmp(l->controller->value, str)) { + index_filter[index].ignore = l->controller->ignore; + index_filter[index].filter = l->controller->filter; + } + } +} + +static int filter_check_flag(uint16_t index, int flag) +{ + return index_filter[index].filter & flag; +} -void packet_set_filter(unsigned long filter) +static int filter_check_ignore(uint16_t index) { - filter_mask = filter; + return index_filter[index].ignore; } static void print_channel_header(struct timeval *tv, uint16_t index, uint16_t channel) { - if (filter_mask & PACKET_FILTER_SHOW_INDEX) { + if (filter_check_flag(index, PACKET_FILTER_SHOW_INDEX)) { switch (channel) { case HCI_CHANNEL_CONTROL: printf("{hci%d} ", index); @@ -71,11 +135,11 @@ static void print_channel_header(struct timeval *tv, uint16_t index, localtime_r(&t, &tm); - if (filter_mask & PACKET_FILTER_SHOW_DATE) + if (filter_check_flag(index, PACKET_FILTER_SHOW_DATE)) printf("%04d-%02d-%02d ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); - if (filter_mask & PACKET_FILTER_SHOW_TIME) + if (filter_check_flag(index, PACKET_FILTER_SHOW_TIME)) printf("%02d:%02d:%02d.%06lu ", tm.tm_hour, tm.tm_min, tm.tm_sec, tv->tv_usec); } @@ -128,6 +192,9 @@ void packet_hexdump(const unsigned char *buf, uint16_t len) void packet_control(struct timeval *tv, uint16_t index, uint16_t opcode, const void *data, uint16_t size) { + if (filter_check_ignore(index)) + return; + print_channel_header(tv, index, HCI_CHANNEL_CONTROL); control_message(opcode, data, size); @@ -142,33 +209,30 @@ void packet_control(struct timeval *tv, uint16_t index, uint16_t opcode, #define MONITOR_SCO_TX_PKT 6 #define MONITOR_SCO_RX_PKT 7 -struct monitor_new_index { - uint8_t type; - uint8_t bus; - bdaddr_t bdaddr; - char name[8]; -} __attribute__((packed)); - #define MONITOR_NEW_INDEX_SIZE 16 #define MONITOR_DEL_INDEX_SIZE 0 -#define MAX_INDEX 16 - -static struct monitor_new_index index_list[MAX_INDEX]; - void packet_monitor(struct timeval *tv, uint16_t index, uint16_t opcode, const void *data, uint16_t size) { const struct monitor_new_index *ni; char str[18]; + if (filter_check_ignore(index)) + return; + switch (opcode) { case MONITOR_NEW_INDEX: ni = data; - if (index < MAX_INDEX) + if (index < MAX_INDEX) { memcpy(&index_list[index], ni, MONITOR_NEW_INDEX_SIZE); + packet_set_index_filter(index); + } + + if (filter_check_ignore(index)) + return; ba2str(&ni->bdaddr, str); packet_new_index(tv, index, str, ni->type, ni->bus, ni->name); @@ -573,6 +637,9 @@ void packet_hci_command(struct timeval *tv, uint16_t index, btsnoop_write(tv, index, 0x02, data, size); + if (!filter_check_flag(index, PACKET_FILTER_SHOW_HCI)) + return; + print_header(tv, index); if (size < HCI_COMMAND_HDR_SIZE) { @@ -596,6 +663,9 @@ void packet_hci_event(struct timeval *tv, uint16_t index, btsnoop_write(tv, index, 0x03, data, size); + if (!filter_check_flag(index, PACKET_FILTER_SHOW_HCI)) + return; + print_header(tv, index); if (size < HCI_EVENT_HDR_SIZE) { @@ -622,6 +692,9 @@ void packet_hci_acldata(struct timeval *tv, uint16_t index, bool in, btsnoop_write(tv, index, in ? 0x01 : 0x00, data, size); + if (!filter_check_flag(index, PACKET_FILTER_SHOW_ACL)) + return; + print_header(tv, index); if (size < HCI_ACL_HDR_SIZE) { @@ -635,7 +708,7 @@ void packet_hci_acldata(struct timeval *tv, uint16_t index, bool in, data += HCI_ACL_HDR_SIZE; size -= HCI_ACL_HDR_SIZE; - if (filter_mask & PACKET_FILTER_SHOW_ACL_DATA) + if (filter_check_flag(index, PACKET_FILTER_SHOW_ACL_DATA)) packet_hexdump(data, size); } @@ -646,6 +719,9 @@ void packet_hci_scodata(struct timeval *tv, uint16_t index, bool in, uint16_t handle = btohs(hdr->handle); uint8_t flags = acl_flags(handle); + if (!filter_check_flag(index, PACKET_FILTER_SHOW_SCO)) + return; + print_header(tv, index); if (size < HCI_SCO_HDR_SIZE) { @@ -659,6 +735,6 @@ void packet_hci_scodata(struct timeval *tv, uint16_t index, bool in, data += HCI_SCO_HDR_SIZE; size -= HCI_SCO_HDR_SIZE; - if (filter_mask & PACKET_FILTER_SHOW_SCO_DATA) + if (filter_check_flag(index, PACKET_FILTER_SHOW_SCO_DATA)) packet_hexdump(data, size); } diff --git a/monitor/packet.h b/monitor/packet.h index c8d011d..aa113df 100644 --- a/monitor/packet.h +++ b/monitor/packet.h @@ -26,6 +26,8 @@ #include <stdint.h> #include <sys/time.h> +#include "list.h" + #define PACKET_FILTER_SHOW_INDEX (1 << 0) #define PACKET_FILTER_SHOW_DATE (1 << 1) #define PACKET_FILTER_SHOW_TIME (1 << 2) @@ -35,7 +37,7 @@ #define PACKET_FILTER_SHOW_ACL_DATA (1 << 6) #define PACKET_FILTER_SHOW_SCO_DATA (1 << 7) -void packet_set_filter(unsigned long filter); +void packet_set_filter(struct list *filter); void packet_hexdump(const unsigned char *buf, uint16_t len); -- 1.7.10.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-06-13 2:59 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-05-22 5:40 [PATCH 1/4] monitor: add include <stdint.h> Gustavo Padovan 2012-05-22 5:40 ` [PATCH 2/4] monitor: add config_file parser Gustavo Padovan 2012-05-22 5:40 ` [PATCH 3/4] monitor: add filter support Gustavo Padovan 2012-05-22 5:40 ` [PATCH 4/4] monitor: add example filter file Gustavo Padovan 2012-05-22 15:02 ` [PATCH 3/4] monitor: add filter support Vinicius Costa Gomes 2012-05-22 15:30 ` Gustavo Padovan -- strict thread matches above, loose matches on Subject: below -- 2012-06-13 2:59 [PATCH 1/4] monitor: add include <stdint.h> Gustavo Padovan 2012-06-13 2:59 ` [PATCH 3/4] monitor: add filter support Gustavo Padovan
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).