linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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 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).