linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Add discover characteristics by uuid to gattool
@ 2011-03-16 17:40 Sheldon Demario
  2011-03-16 21:51 ` [PATCH] Add discover characteristics by uuid to gatttool Sheldon Demario
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Sheldon Demario @ 2011-03-16 17:40 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

---
 attrib/client.c      |    2 +-
 attrib/gatt.c        |   16 +++++++++++-----
 attrib/gatt.h        |    3 ++-
 attrib/gatttool.c    |    3 ++-
 attrib/interactive.c |   18 ++++++++++++++++--
 5 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/attrib/client.c b/attrib/client.c
index 3237a6b..54bdc79 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -960,7 +960,7 @@ static DBusMessage *discover_char(DBusConnection *conn, DBusMessage *msg,
 	qchr->prim = prim;
 	qchr->msg = dbus_message_ref(msg);
 
-	gatt_discover_char(gatt->attrib, att->start, att->end,
+	gatt_discover_char(gatt->attrib, att->start, att->end, NULL,
 						char_discovered_cb, qchr);
 
 	return NULL;
diff --git a/attrib/gatt.c b/attrib/gatt.c
index 32bd4a0..b328c72 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -40,7 +40,7 @@ struct discover_primary {
 
 struct discover_char {
 	GAttrib *attrib;
-	bt_uuid_t uuid;
+	bt_uuid_t *uuid;
 	uint16_t end;
 	GSList *characteristics;
 	gatt_cb_t cb;
@@ -59,6 +59,7 @@ static void discover_char_free(struct discover_char *dc)
 	g_slist_foreach(dc->characteristics, (GFunc) g_free, NULL);
 	g_slist_free(dc->characteristics);
 	g_attrib_unref(dc->attrib);
+	g_free(dc->uuid);
 	g_free(dc);
 }
 
@@ -281,6 +282,9 @@ static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 			goto done;
 		}
 
+		if (dc->uuid && bt_uuid_cmp(dc->uuid, &uuid))
+			break;
+
 		chars->handle = last;
 		chars->properties = value[2];
 		chars->value_handle = att_get_u16(&value[3]);
@@ -313,16 +317,17 @@ done:
 }
 
 guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
-					gatt_cb_t func, gpointer user_data)
+						bt_uuid_t *uuid, gatt_cb_t func,
+						gpointer user_data)
 {
 	uint8_t pdu[ATT_DEFAULT_LE_MTU];
 	struct discover_char *dc;
+	bt_uuid_t type_uuid;
 	guint16 plen;
-	bt_uuid_t uuid;
 
-	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
+	bt_uuid16_create(&type_uuid, GATT_CHARAC_UUID);
 
-	plen = enc_read_by_type_req(start, end, &uuid, pdu, sizeof(pdu));
+	plen = enc_read_by_type_req(start, end, &type_uuid, pdu, sizeof(pdu));
 	if (plen == 0)
 		return 0;
 
@@ -334,6 +339,7 @@ guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
 	dc->cb = func;
 	dc->user_data = user_data;
 	dc->end = end;
+	dc->uuid = uuid;
 
 	return g_attrib_send(attrib, 0, pdu[0], pdu, plen, char_discovered_cb,
 								dc, NULL);
diff --git a/attrib/gatt.h b/attrib/gatt.h
index 730de7e..c6d3843 100644
--- a/attrib/gatt.h
+++ b/attrib/gatt.h
@@ -30,7 +30,8 @@ guint gatt_discover_primary(GAttrib *attrib, bt_uuid_t *uuid, gatt_cb_t func,
 							gpointer user_data);
 
 guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
-					gatt_cb_t func, gpointer user_data);
+					bt_uuid_t *uuid, gatt_cb_t func,
+					gpointer user_data);
 
 guint gatt_read_char(GAttrib *attrib, uint16_t handle, uint16_t offset,
 				GAttribResultFunc func, gpointer user_data);
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 729e18d..0dfbc04 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -206,7 +206,8 @@ static gboolean characteristics(gpointer user_data)
 {
 	GAttrib *attrib = user_data;
 
-	gatt_discover_char(attrib, opt_start, opt_end, char_discovered_cb, NULL);
+	gatt_discover_char(attrib, opt_start, opt_end, opt_uuid,
+						char_discovered_cb, NULL);
 
 	return FALSE;
 }
diff --git a/attrib/interactive.c b/attrib/interactive.c
index b32e9e7..7e5aa4c 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -431,7 +431,21 @@ static void cmd_char(int argcp, char **argvp)
 		}
 	}
 
-	gatt_discover_char(attrib, start, end, char_cb, NULL);
+	if (argcp > 3) {
+		bt_uuid_t *uuid;
+
+		uuid = g_try_new(bt_uuid_t, 1);
+		if (bt_string_to_uuid(uuid, argvp[3]) < 0) {
+			g_free(uuid);
+			printf("Invalid UUID\n");
+			return;
+		}
+
+		gatt_discover_char(attrib, start, end, uuid, char_cb, NULL);
+		return;
+	}
+
+	gatt_discover_char(attrib, start, end, NULL, char_cb, NULL);
 }
 
 static void cmd_char_desc(int argcp, char **argvp)
@@ -658,7 +672,7 @@ static struct {
 		"Disconnect from a remote device" },
 	{ "primary",		cmd_primary,	"[UUID]",
 		"Primary Service Discovery" },
-	{ "characteristics",	cmd_char,	"[start hnd] [end hnd]",
+	{ "characteristics",	cmd_char,	"[start hnd [end hnd [UUID]]]",
 		"Characteristics Discovery" },
 	{ "char-desc",		cmd_char_desc,	"[start hnd] [end hnd]",
 		"Characteristics Descriptor Discovery" },
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH] Add discover characteristics by uuid to gatttool
  2011-03-16 17:40 [PATCH] Add discover characteristics by uuid to gattool Sheldon Demario
@ 2011-03-16 21:51 ` Sheldon Demario
  2011-03-16 22:00 ` [PATCH v2] " Sheldon Demario
  2011-03-17 12:47 ` [PATCH] Add discover characteristics by uuid to gattool Johan Hedberg
  2 siblings, 0 replies; 6+ messages in thread
From: Sheldon Demario @ 2011-03-16 21:51 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

According to the spec the characteristics discover and characteristics discover
by uuid use the same opcode and the result should be filtered by callback.
---
 attrib/client.c      |    2 +-
 attrib/gatt.c        |   16 +++++++++++-----
 attrib/gatt.h        |    3 ++-
 attrib/gatttool.c    |    3 ++-
 attrib/interactive.c |   16 ++++++++++++++--
 5 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/attrib/client.c b/attrib/client.c
index 3237a6b..54bdc79 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -960,7 +960,7 @@ static DBusMessage *discover_char(DBusConnection *conn, DBusMessage *msg,
 	qchr->prim = prim;
 	qchr->msg = dbus_message_ref(msg);
 
-	gatt_discover_char(gatt->attrib, att->start, att->end,
+	gatt_discover_char(gatt->attrib, att->start, att->end, NULL,
 						char_discovered_cb, qchr);
 
 	return NULL;
diff --git a/attrib/gatt.c b/attrib/gatt.c
index 32bd4a0..1cd651c 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -40,7 +40,7 @@ struct discover_primary {
 
 struct discover_char {
 	GAttrib *attrib;
-	bt_uuid_t uuid;
+	bt_uuid_t *uuid;
 	uint16_t end;
 	GSList *characteristics;
 	gatt_cb_t cb;
@@ -59,6 +59,7 @@ static void discover_char_free(struct discover_char *dc)
 	g_slist_foreach(dc->characteristics, (GFunc) g_free, NULL);
 	g_slist_free(dc->characteristics);
 	g_attrib_unref(dc->attrib);
+	g_free(dc->uuid);
 	g_free(dc);
 }
 
@@ -281,6 +282,9 @@ static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 			goto done;
 		}
 
+		if (dc->uuid && bt_uuid_cmp(dc->uuid, &uuid))
+			break;
+
 		chars->handle = last;
 		chars->properties = value[2];
 		chars->value_handle = att_get_u16(&value[3]);
@@ -313,16 +317,17 @@ done:
 }
 
 guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
-					gatt_cb_t func, gpointer user_data)
+						bt_uuid_t *uuid, gatt_cb_t func,
+						gpointer user_data)
 {
 	uint8_t pdu[ATT_DEFAULT_LE_MTU];
 	struct discover_char *dc;
+	bt_uuid_t type_uuid;
 	guint16 plen;
-	bt_uuid_t uuid;
 
-	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
+	bt_uuid16_create(&type_uuid, GATT_CHARAC_UUID);
 
-	plen = enc_read_by_type_req(start, end, &uuid, pdu, sizeof(pdu));
+	plen = enc_read_by_type_req(start, end, &type_uuid, pdu, sizeof(pdu));
 	if (plen == 0)
 		return 0;
 
@@ -334,6 +339,7 @@ guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
 	dc->cb = func;
 	dc->user_data = user_data;
 	dc->end = end;
+	dc->uuid = g_memdup(uuid, sizeof(bt_uuid_t));
 
 	return g_attrib_send(attrib, 0, pdu[0], pdu, plen, char_discovered_cb,
 								dc, NULL);
diff --git a/attrib/gatt.h b/attrib/gatt.h
index 730de7e..c6d3843 100644
--- a/attrib/gatt.h
+++ b/attrib/gatt.h
@@ -30,7 +30,8 @@ guint gatt_discover_primary(GAttrib *attrib, bt_uuid_t *uuid, gatt_cb_t func,
 							gpointer user_data);
 
 guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
-					gatt_cb_t func, gpointer user_data);
+					bt_uuid_t *uuid, gatt_cb_t func,
+					gpointer user_data);
 
 guint gatt_read_char(GAttrib *attrib, uint16_t handle, uint16_t offset,
 				GAttribResultFunc func, gpointer user_data);
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 729e18d..0dfbc04 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -206,7 +206,8 @@ static gboolean characteristics(gpointer user_data)
 {
 	GAttrib *attrib = user_data;
 
-	gatt_discover_char(attrib, opt_start, opt_end, char_discovered_cb, NULL);
+	gatt_discover_char(attrib, opt_start, opt_end, opt_uuid,
+						char_discovered_cb, NULL);
 
 	return FALSE;
 }
diff --git a/attrib/interactive.c b/attrib/interactive.c
index b32e9e7..a9157e7 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -431,7 +431,19 @@ static void cmd_char(int argcp, char **argvp)
 		}
 	}
 
-	gatt_discover_char(attrib, start, end, char_cb, NULL);
+	if (argcp > 3) {
+		bt_uuid_t uuid;
+
+		if (bt_string_to_uuid(&uuid, argvp[3]) < 0) {
+			printf("Invalid UUID\n");
+			return;
+		}
+
+		gatt_discover_char(attrib, start, end, &uuid, char_cb, NULL);
+		return;
+	}
+
+	gatt_discover_char(attrib, start, end, NULL, char_cb, NULL);
 }
 
 static void cmd_char_desc(int argcp, char **argvp)
@@ -658,7 +670,7 @@ static struct {
 		"Disconnect from a remote device" },
 	{ "primary",		cmd_primary,	"[UUID]",
 		"Primary Service Discovery" },
-	{ "characteristics",	cmd_char,	"[start hnd] [end hnd]",
+	{ "characteristics",	cmd_char,	"[start hnd [end hnd [UUID]]]",
 		"Characteristics Discovery" },
 	{ "char-desc",		cmd_char_desc,	"[start hnd] [end hnd]",
 		"Characteristics Descriptor Discovery" },
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2] Add discover characteristics by uuid to gatttool
  2011-03-16 17:40 [PATCH] Add discover characteristics by uuid to gattool Sheldon Demario
  2011-03-16 21:51 ` [PATCH] Add discover characteristics by uuid to gatttool Sheldon Demario
@ 2011-03-16 22:00 ` Sheldon Demario
  2011-03-17 12:52   ` Johan Hedberg
  2011-03-17 12:47 ` [PATCH] Add discover characteristics by uuid to gattool Johan Hedberg
  2 siblings, 1 reply; 6+ messages in thread
From: Sheldon Demario @ 2011-03-16 22:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

According to the spec the characteristics discover and characteristics discover
by uuid use the same opcode and the result should be filtered by callback.
---
 attrib/client.c      |    2 +-
 attrib/gatt.c        |   16 +++++++++++-----
 attrib/gatt.h        |    3 ++-
 attrib/gatttool.c    |    3 ++-
 attrib/interactive.c |   16 ++++++++++++++--
 5 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/attrib/client.c b/attrib/client.c
index 3237a6b..54bdc79 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -960,7 +960,7 @@ static DBusMessage *discover_char(DBusConnection *conn, DBusMessage *msg,
 	qchr->prim = prim;
 	qchr->msg = dbus_message_ref(msg);
 
-	gatt_discover_char(gatt->attrib, att->start, att->end,
+	gatt_discover_char(gatt->attrib, att->start, att->end, NULL,
 						char_discovered_cb, qchr);
 
 	return NULL;
diff --git a/attrib/gatt.c b/attrib/gatt.c
index 32bd4a0..1cd651c 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -40,7 +40,7 @@ struct discover_primary {
 
 struct discover_char {
 	GAttrib *attrib;
-	bt_uuid_t uuid;
+	bt_uuid_t *uuid;
 	uint16_t end;
 	GSList *characteristics;
 	gatt_cb_t cb;
@@ -59,6 +59,7 @@ static void discover_char_free(struct discover_char *dc)
 	g_slist_foreach(dc->characteristics, (GFunc) g_free, NULL);
 	g_slist_free(dc->characteristics);
 	g_attrib_unref(dc->attrib);
+	g_free(dc->uuid);
 	g_free(dc);
 }
 
@@ -281,6 +282,9 @@ static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 			goto done;
 		}
 
+		if (dc->uuid && bt_uuid_cmp(dc->uuid, &uuid))
+			break;
+
 		chars->handle = last;
 		chars->properties = value[2];
 		chars->value_handle = att_get_u16(&value[3]);
@@ -313,16 +317,17 @@ done:
 }
 
 guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
-					gatt_cb_t func, gpointer user_data)
+						bt_uuid_t *uuid, gatt_cb_t func,
+						gpointer user_data)
 {
 	uint8_t pdu[ATT_DEFAULT_LE_MTU];
 	struct discover_char *dc;
+	bt_uuid_t type_uuid;
 	guint16 plen;
-	bt_uuid_t uuid;
 
-	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
+	bt_uuid16_create(&type_uuid, GATT_CHARAC_UUID);
 
-	plen = enc_read_by_type_req(start, end, &uuid, pdu, sizeof(pdu));
+	plen = enc_read_by_type_req(start, end, &type_uuid, pdu, sizeof(pdu));
 	if (plen == 0)
 		return 0;
 
@@ -334,6 +339,7 @@ guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
 	dc->cb = func;
 	dc->user_data = user_data;
 	dc->end = end;
+	dc->uuid = g_memdup(uuid, sizeof(bt_uuid_t));
 
 	return g_attrib_send(attrib, 0, pdu[0], pdu, plen, char_discovered_cb,
 								dc, NULL);
diff --git a/attrib/gatt.h b/attrib/gatt.h
index 730de7e..c6d3843 100644
--- a/attrib/gatt.h
+++ b/attrib/gatt.h
@@ -30,7 +30,8 @@ guint gatt_discover_primary(GAttrib *attrib, bt_uuid_t *uuid, gatt_cb_t func,
 							gpointer user_data);
 
 guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
-					gatt_cb_t func, gpointer user_data);
+					bt_uuid_t *uuid, gatt_cb_t func,
+					gpointer user_data);
 
 guint gatt_read_char(GAttrib *attrib, uint16_t handle, uint16_t offset,
 				GAttribResultFunc func, gpointer user_data);
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 729e18d..0dfbc04 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -206,7 +206,8 @@ static gboolean characteristics(gpointer user_data)
 {
 	GAttrib *attrib = user_data;
 
-	gatt_discover_char(attrib, opt_start, opt_end, char_discovered_cb, NULL);
+	gatt_discover_char(attrib, opt_start, opt_end, opt_uuid,
+						char_discovered_cb, NULL);
 
 	return FALSE;
 }
diff --git a/attrib/interactive.c b/attrib/interactive.c
index b32e9e7..a9157e7 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -431,7 +431,19 @@ static void cmd_char(int argcp, char **argvp)
 		}
 	}
 
-	gatt_discover_char(attrib, start, end, char_cb, NULL);
+	if (argcp > 3) {
+		bt_uuid_t uuid;
+
+		if (bt_string_to_uuid(&uuid, argvp[3]) < 0) {
+			printf("Invalid UUID\n");
+			return;
+		}
+
+		gatt_discover_char(attrib, start, end, &uuid, char_cb, NULL);
+		return;
+	}
+
+	gatt_discover_char(attrib, start, end, NULL, char_cb, NULL);
 }
 
 static void cmd_char_desc(int argcp, char **argvp)
@@ -658,7 +670,7 @@ static struct {
 		"Disconnect from a remote device" },
 	{ "primary",		cmd_primary,	"[UUID]",
 		"Primary Service Discovery" },
-	{ "characteristics",	cmd_char,	"[start hnd] [end hnd]",
+	{ "characteristics",	cmd_char,	"[start hnd [end hnd [UUID]]]",
 		"Characteristics Discovery" },
 	{ "char-desc",		cmd_char_desc,	"[start hnd] [end hnd]",
 		"Characteristics Descriptor Discovery" },
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] Add discover characteristics by uuid to gattool
  2011-03-16 17:40 [PATCH] Add discover characteristics by uuid to gattool Sheldon Demario
  2011-03-16 21:51 ` [PATCH] Add discover characteristics by uuid to gatttool Sheldon Demario
  2011-03-16 22:00 ` [PATCH v2] " Sheldon Demario
@ 2011-03-17 12:47 ` Johan Hedberg
  2011-03-17 12:49   ` Johan Hedberg
  2 siblings, 1 reply; 6+ messages in thread
From: Johan Hedberg @ 2011-03-17 12:47 UTC (permalink / raw)
  To: Sheldon Demario; +Cc: linux-bluetooth

Hi Sheldon,

On Wed, Mar 16, 2011, Sheldon Demario wrote:
> +		uuid = g_try_new(bt_uuid_t, 1);
> +		if (bt_string_to_uuid(uuid, argvp[3]) < 0) {
> +			g_free(uuid);
> +			printf("Invalid UUID\n");
> +			return;
> +		}

If you're gonna use the _try version of GLib memory allocators you need
to check for the return value. However in this case I'd just use the
non-try version (since the amount of memory is small).

Johan

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Add discover characteristics by uuid to gattool
  2011-03-17 12:47 ` [PATCH] Add discover characteristics by uuid to gattool Johan Hedberg
@ 2011-03-17 12:49   ` Johan Hedberg
  0 siblings, 0 replies; 6+ messages in thread
From: Johan Hedberg @ 2011-03-17 12:49 UTC (permalink / raw)
  To: Sheldon Demario, linux-bluetooth

Hi,

On Thu, Mar 17, 2011, Johan Hedberg wrote:
> On Wed, Mar 16, 2011, Sheldon Demario wrote:
> > +		uuid = g_try_new(bt_uuid_t, 1);
> > +		if (bt_string_to_uuid(uuid, argvp[3]) < 0) {
> > +			g_free(uuid);
> > +			printf("Invalid UUID\n");
> > +			return;
> > +		}
> 
> If you're gonna use the _try version of GLib memory allocators you need
> to check for the return value. However in this case I'd just use the
> non-try version (since the amount of memory is small).

Never mind, I just saw that you've sent an updated version which gets
rid of the memory allocation need completely (by using a stack
variable).

Johan

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] Add discover characteristics by uuid to gatttool
  2011-03-16 22:00 ` [PATCH v2] " Sheldon Demario
@ 2011-03-17 12:52   ` Johan Hedberg
  0 siblings, 0 replies; 6+ messages in thread
From: Johan Hedberg @ 2011-03-17 12:52 UTC (permalink / raw)
  To: Sheldon Demario; +Cc: linux-bluetooth

Hi Sheldon,

On Wed, Mar 16, 2011, Sheldon Demario wrote:
> According to the spec the characteristics discover and characteristics discover
> by uuid use the same opcode and the result should be filtered by callback.
> ---
>  attrib/client.c      |    2 +-
>  attrib/gatt.c        |   16 +++++++++++-----
>  attrib/gatt.h        |    3 ++-
>  attrib/gatttool.c    |    3 ++-
>  attrib/interactive.c |   16 ++++++++++++++--
>  5 files changed, 30 insertions(+), 10 deletions(-)

Pushed upstream after manually fixing your commit message: please limit
line lengths to 74 characters.

Johan

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-03-17 12:52 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-16 17:40 [PATCH] Add discover characteristics by uuid to gattool Sheldon Demario
2011-03-16 21:51 ` [PATCH] Add discover characteristics by uuid to gatttool Sheldon Demario
2011-03-16 22:00 ` [PATCH v2] " Sheldon Demario
2011-03-17 12:52   ` Johan Hedberg
2011-03-17 12:47 ` [PATCH] Add discover characteristics by uuid to gattool Johan Hedberg
2011-03-17 12:49   ` Johan Hedberg

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).