Module Name:    src
Committed By:   plunky
Date:           Tue May 12 21:50:38 UTC 2009

Modified Files:
        src/usr.sbin/btpand: Makefile btpand.c btpand.h client.c server.c
Removed Files:
        src/usr.sbin/btpand: sdp.c sdp.h

Log Message:
update to use the new Service Discovery API


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/usr.sbin/btpand/Makefile
cvs rdiff -u -r1.3 -r1.4 src/usr.sbin/btpand/btpand.c \
    src/usr.sbin/btpand/client.c src/usr.sbin/btpand/server.c
cvs rdiff -u -r1.2 -r1.3 src/usr.sbin/btpand/btpand.h
cvs rdiff -u -r1.2 -r0 src/usr.sbin/btpand/sdp.c src/usr.sbin/btpand/sdp.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.sbin/btpand/Makefile
diff -u src/usr.sbin/btpand/Makefile:1.4 src/usr.sbin/btpand/Makefile:1.5
--- src/usr.sbin/btpand/Makefile:1.4	Tue May 12 13:11:18 2009
+++ src/usr.sbin/btpand/Makefile	Tue May 12 21:50:38 2009
@@ -1,13 +1,11 @@
-# $NetBSD: Makefile,v 1.4 2009/05/12 13:11:18 plunky Exp $
+# $NetBSD: Makefile,v 1.5 2009/05/12 21:50:38 plunky Exp $
 #
 
 PROG=	btpand
 MAN=	btpand.8
-SRCS=	btpand.c bnep.c channel.c client.c packet.c server.c sdp.c tap.c
+SRCS=	btpand.c bnep.c channel.c client.c packet.c server.c tap.c
 
 DPADD+=	${LIBBLUETOOTH} ${LIBEVENT} ${LIBUTIL}
 LDADD+=	-lbluetooth -levent -lutil
 
-CPPFLAGS+=	-DSDP_COMPAT
-
 .include <bsd.prog.mk>

Index: src/usr.sbin/btpand/btpand.c
diff -u src/usr.sbin/btpand/btpand.c:1.3 src/usr.sbin/btpand/btpand.c:1.4
--- src/usr.sbin/btpand/btpand.c:1.3	Tue May 12 21:08:30 2009
+++ src/usr.sbin/btpand/btpand.c	Tue May 12 21:50:38 2009
@@ -1,7 +1,7 @@
-/*	$NetBSD: btpand.c,v 1.3 2009/05/12 21:08:30 plunky Exp $	*/
+/*	$NetBSD: btpand.c,v 1.4 2009/05/12 21:50:38 plunky Exp $	*/
 
 /*-
- * Copyright (c) 2008 Iain Hibbert
+ * Copyright (c) 2008-2009 Iain Hibbert
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,8 +26,8 @@
  */
 
 #include <sys/cdefs.h>
-__COPYRIGHT("@(#) Copyright (c) 2008 Iain Hibbert. All rights reserved.");
-__RCSID("$NetBSD: btpand.c,v 1.3 2009/05/12 21:08:30 plunky Exp $");
+__COPYRIGHT("@(#) Copyright (c) 2008-2009 Iain Hibbert. All rights reserved.");
+__RCSID("$NetBSD: btpand.c,v 1.4 2009/05/12 21:50:38 plunky Exp $");
 
 #include <sys/wait.h>
 
@@ -47,24 +47,35 @@
 /* global variables */
 const char *	control_path;		/* -c <path> */
 const char *	interface_name;		/* -i <ifname> */
-const char *	service_name;		/* -s <service> */
+const char *	service_type;		/* -s <service> */
 uint16_t	service_class;
+const char *	service_name;
+const char *	service_desc;
 
 bdaddr_t	local_bdaddr;		/* -d <addr> */
 bdaddr_t	remote_bdaddr;		/* -a <addr> */
 uint16_t	l2cap_psm;		/* -p <psm> */
 int		l2cap_mode;		/* -m <mode> */
-
 int		server_limit;		/* -n <limit> */
 
 static const struct {
-	const char *	name;
+	const char *	type;
 	uint16_t	class;
+	const char *	name;
 	const char *	desc;
 } services[] = {
-	{ "PANU", SDP_SERVICE_CLASS_PANU, "Personal Area Networking User" },
-	{ "NAP",  SDP_SERVICE_CLASS_NAP,  "Network Acess Point"		  },
-	{ "GN",	  SDP_SERVICE_CLASS_GN,   "Group Network"		  },
+	{ "PANU", SDP_SERVICE_CLASS_PANU,
+	  "Personal Ad-hoc User Service",
+	  "Personal Ad-hoc User Service"
+	},
+	{ "NAP",  SDP_SERVICE_CLASS_NAP,
+	  "Network Acess Point",
+	  "Personal Ad-hoc Network Service"
+	},
+	{ "GN",	  SDP_SERVICE_CLASS_GN,
+	  "Group Ad-hoc Network",
+	  "Personal Group Ad-hoc Network Service"
+	},
 };
 
 static void main_exit(int);
@@ -139,18 +150,21 @@
 			    || ul > 0xffff || L2CAP_PSM_INVALID(ul))
 				errx(EXIT_FAILURE, "%s: invalid PSM", optarg);
 
-			l2cap_psm = ul;
+			l2cap_psm = (uint16_t)ul;
 			break;
 
 		case 's': /* service */
 		case 'S': /* service (no SDP) */
-			for (ul = 0; strcasecmp(optarg, services[ul].name); ul++) {
+			for (ul = 0; strcasecmp(optarg, services[ul].type); ul++) {
 				if (ul == __arraycount(services))
 					errx(EXIT_FAILURE, "%s: unknown service", optarg);
 			}
 
-			if (ch == 's')
+			if (ch == 's') {
+				service_type = services[ul].type;
 				service_name = services[ul].name;
+				service_desc = services[ul].desc;
+			}
 
 			service_class = services[ul].class;
 			break;
@@ -169,7 +183,7 @@
 		usage();
 
 	if (!bdaddr_any(&remote_bdaddr) && (server_limit != 0 ||
-	    control_path != 0 || (service_name != NULL && l2cap_psm != 0)))
+	    control_path != 0 || (service_type != NULL && l2cap_psm != 0)))
 		usage();
 
 	/* default options */
@@ -261,7 +275,7 @@
 usage(void)
 {
 	const char *p = getprogname();
-	int n = strlen(p);
+	size_t n = strlen(p);
 
 	fprintf(stderr,
 	    "usage: %s [-i ifname] [-m mode] -a address -d device\n"
@@ -283,8 +297,8 @@
 	    "Known services:\n"
 	    "", p, n, "", p, n, "");
 
-	for (n = 0; n < (int)__arraycount(services); n++)
-		fprintf(stderr, "\t%s\t%s\n", services[n].name, services[n].desc);
+	for (n = 0; n < __arraycount(services); n++)
+		fprintf(stderr, "\t%s\t%s\n", services[n].type, services[n].name);
 
 	exit(EXIT_FAILURE);
 }
Index: src/usr.sbin/btpand/client.c
diff -u src/usr.sbin/btpand/client.c:1.3 src/usr.sbin/btpand/client.c:1.4
--- src/usr.sbin/btpand/client.c:1.3	Tue May 12 21:08:30 2009
+++ src/usr.sbin/btpand/client.c	Tue May 12 21:50:38 2009
@@ -1,7 +1,7 @@
-/*	$NetBSD: client.c,v 1.3 2009/05/12 21:08:30 plunky Exp $	*/
+/*	$NetBSD: client.c,v 1.4 2009/05/12 21:50:38 plunky Exp $	*/
 
 /*-
- * Copyright (c) 2008 Iain Hibbert
+ * Copyright (c) 2008-2009 Iain Hibbert
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: client.c,v 1.3 2009/05/12 21:08:30 plunky Exp $");
+__RCSID("$NetBSD: client.c,v 1.4 2009/05/12 21:50:38 plunky Exp $");
 
 #include <bluetooth.h>
 #include <errno.h>
@@ -35,7 +35,6 @@
 
 #include "btpand.h"
 #include "bnep.h"
-#include "sdp.h"
 
 static void client_down(channel_t *);
 static void client_query(void);
@@ -52,7 +51,7 @@
 	if (bdaddr_any(&remote_bdaddr))
 		return;
 
-	if (service_name)
+	if (service_type)
 		client_query();
 
 	fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
@@ -144,64 +143,83 @@
 static void
 client_query(void)
 {
-	uint8_t buffer[512];
-	sdp_attr_t attr;
-	uint32_t range;
-	void *ss;
-	int rv;
-	uint8_t *seq0, *seq1;
-
-	attr.flags = SDP_ATTR_INVALID;
-	attr.attr = 0;
-	attr.vlen = sizeof(buffer);
-	attr.value = buffer;
-
-	range = SDP_ATTR_RANGE(SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST,
-			       SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
+	uint8_t buf[12];	/* enough for SSP and AIL both */
+	sdp_session_t ss;
+	sdp_data_t ssp, ail, rsp, rec, value, pdl, seq;
+	uintmax_t psm;
+	uint16_t attr;
+	bool rv;
 
 	ss = sdp_open(&local_bdaddr, &remote_bdaddr);
-	if (ss == NULL || (errno = sdp_error(ss)) != 0) {
-		log_err("%s: %m", service_name);
+	if (ss == NULL) {
+		log_err("%s: %m", service_type);
 		exit(EXIT_FAILURE);
 	}
 
 	log_info("Searching for %s service at %s",
-	    service_name, bt_ntoa(&remote_bdaddr, NULL));
+	    service_type, bt_ntoa(&remote_bdaddr, NULL));
 
-	rv = sdp_search(ss, 1, &service_class, 1, &range, 1, &attr);
-	if (rv != 0) {
-		log_err("%s: %s", service_name, strerror(sdp_error(ss)));
-		exit(EXIT_FAILURE);
-	}
+	seq.next = buf;
+	seq.end = buf + sizeof(buf);
 
-	sdp_close(ss);
+	/*
+	 * build ServiceSearchPattern (9 bytes)
+	 *
+	 *	uuid16	"service_class"
+	 *	uuid16	L2CAP
+	 *	uuid16	BNEP
+	 */
+	ssp.next = seq.next;
+	sdp_put_uuid16(&seq, service_class);
+	sdp_put_uuid16(&seq, SDP_UUID_PROTOCOL_L2CAP);
+	sdp_put_uuid16(&seq, SDP_UUID_PROTOCOL_BNEP);
+	ssp.end = seq.next;
 
-	if (attr.flags != SDP_ATTR_OK
-	    || attr.attr != SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST) {
-		log_err("%s service not found", service_name);
+	/*
+	 * build AttributeIDList (3 bytes)
+	 *
+	 *	uint16	ProtocolDescriptorList
+	 */
+	ail.next = seq.next;
+	sdp_put_uint16(&seq, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
+	ail.end = seq.next;
+
+	rv = sdp_service_search_attribute(ss, &ssp, &ail, &rsp);
+	if (!rv) {
+		log_err("%s: %m", service_type);
 		exit(EXIT_FAILURE);
 	}
 
 	/*
-	 * we expect the following protocol descriptor list
-	 *
-	 *	seq len
-	 *	  seq len
-	 *	    uuid value == L2CAP
-	 *	    uint16 value16 => PSM
-	 *	  seq len
-	 *	    uuid value == BNEP
+	 * we expect the response to contain a list of records
+	 * containing a ProtocolDescriptorList. Find the first
+	 * one containing L2CAP and BNEP protocols and extract
+	 * the PSM.
 	 */
-	if (_sdp_get_seq(&attr.value, attr.value + attr.vlen, &seq0)
-	    && _sdp_get_seq(&seq0, attr.value, &seq1)
-	    && _sdp_match_uuid16(&seq1, seq0, SDP_UUID_PROTOCOL_L2CAP)
-	    && _sdp_get_uint16(&seq1, seq0, &l2cap_psm)
-	    && _sdp_get_seq(&seq0, attr.value, &seq1)
-	    && _sdp_match_uuid16(&seq1, seq0, SDP_UUID_PROTOCOL_BNEP)) {
-		log_info("Found PSM %d for service %s", l2cap_psm, service_name);
-		return;
+	rv = false;
+	while (!rv && sdp_get_seq(&rsp, &rec)) {
+		if (!sdp_get_attr(&rec, &attr, &value)
+		    || attr != SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST)
+			continue;
+
+		sdp_get_alt(&value, &value);	/* drop any alt header */
+		while (!rv && sdp_get_seq(&value, &pdl)) {
+			if (sdp_get_seq(&pdl, &seq)
+			    && sdp_match_uuid16(&seq, SDP_UUID_PROTOCOL_L2CAP)
+			    && sdp_get_uint(&seq, &psm)
+			    && sdp_get_seq(&pdl, &seq)
+			    && sdp_match_uuid16(&seq, SDP_UUID_PROTOCOL_BNEP))
+				rv = true;
+		}
 	}
 
-	log_err("%s query failed", service_name);
-	exit(EXIT_FAILURE);
+	sdp_close(ss);
+
+	if (!rv) {
+		log_err("%s query failed", service_type);
+		exit(EXIT_FAILURE);
+	}
+
+	l2cap_psm = (uint16_t)psm;
+	log_info("Found PSM %u for service %s", l2cap_psm, service_type);
 }
Index: src/usr.sbin/btpand/server.c
diff -u src/usr.sbin/btpand/server.c:1.3 src/usr.sbin/btpand/server.c:1.4
--- src/usr.sbin/btpand/server.c:1.3	Tue May 12 21:08:30 2009
+++ src/usr.sbin/btpand/server.c	Tue May 12 21:50:38 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: server.c,v 1.3 2009/05/12 21:08:30 plunky Exp $	*/
+/*	$NetBSD: server.c,v 1.4 2009/05/12 21:50:38 plunky Exp $	*/
 
 /*-
  * Copyright (c) 2008-2009 Iain Hibbert
@@ -26,10 +26,12 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: server.c,v 1.3 2009/05/12 21:08:30 plunky Exp $");
+__RCSID("$NetBSD: server.c,v 1.4 2009/05/12 21:50:38 plunky Exp $");
 
 #include <sys/ioctl.h>
 
+#include <net/ethertypes.h>
+
 #include <bluetooth.h>
 #include <errno.h>
 #include <sdp.h>
@@ -41,13 +43,20 @@
 static struct event	server_ev;
 static int		server_count;
 
-static void *		server_ss;
+static sdp_session_t	server_ss;
 static uint32_t		server_handle;
+static sdp_data_t	server_record;
+
+static char *		server_ipv4_subnet;
+static char *		server_ipv6_subnet;
+static uint16_t		server_proto[] = { ETHERTYPE_IP, ETHERTYPE_ARP, ETHERTYPE_IPV6 };
+static size_t		server_nproto = __arraycount(server_proto);
 
 static void server_open(void);
 static void server_read(int, short, void *);
 static void server_down(channel_t *);
 static void server_update(void);
+static void server_mkrecord(void);
 
 void
 server_init(void)
@@ -247,35 +256,114 @@
 static void
 server_update(void)
 {
-	sdp_nap_profile_t p;
-	int rv;
+	bool rv;
 
-	if (service_name == NULL)
+	if (service_type == NULL)
 		return;
 
 	if (server_ss == NULL) {
 		server_ss = sdp_open_local(control_path);
-		if (server_ss == NULL || sdp_error(server_ss) != 0) {
+		if (server_ss == NULL) {
 			log_err("failed to contact SDP server");
 			return;
 		}
 	}
 
-	memset(&p, 0, sizeof(p));
-	p.psm = l2cap_psm;
-	p.load_factor = (UINT8_MAX - server_count * UINT8_MAX / server_limit);
-	p.security_description = (l2cap_mode == 0 ? 0x0000 : 0x0001);
-
-	if (server_handle)
-		rv = sdp_change_service(server_ss, server_handle,
-		    (uint8_t *)&p, sizeof(p));
+	server_mkrecord();
+
+	if (server_handle == 0)
+		rv = sdp_record_insert(server_ss, &local_bdaddr,
+		    &server_handle, &server_record);
 	else
-		rv = sdp_register_service(server_ss, service_class,
-		    &local_bdaddr, (uint8_t *)&p, sizeof(p), &server_handle);
+		rv = sdp_record_update(server_ss, server_handle,
+		    &server_record);
 
-	if (rv != 0) {
-		errno = sdp_error(server_ss);
-		log_err("%s: %m", service_name);
+	if (!rv) {
+		log_err("%s: %m", service_type);
 		exit(EXIT_FAILURE);
 	}
 }
+
+static void
+server_mkrecord(void)
+{
+	static uint8_t data[256];	/* tis enough */
+	sdp_data_t buf;
+	size_t i;
+
+	buf.next = data;
+	buf.end = data + sizeof(data);
+
+	sdp_put_uint16(&buf, SDP_ATTR_SERVICE_RECORD_HANDLE);
+	sdp_put_uint32(&buf, 0x00000000);
+
+	sdp_put_uint16(&buf, SDP_ATTR_SERVICE_CLASS_ID_LIST);
+	sdp_put_seq(&buf, 3);
+	sdp_put_uuid16(&buf, service_class);
+
+	sdp_put_uint16(&buf, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
+	sdp_put_seq(&buf, 8 + 10 + 3 * server_nproto);
+	sdp_put_seq(&buf, 6);
+	sdp_put_uuid16(&buf, SDP_UUID_PROTOCOL_L2CAP);
+	sdp_put_uint16(&buf, l2cap_psm);
+	sdp_put_seq(&buf, 8 + 3 * server_nproto);
+	sdp_put_uuid16(&buf, SDP_UUID_PROTOCOL_BNEP);
+	sdp_put_uint16(&buf, 0x0100);	/* v1.0 */
+	sdp_put_seq(&buf, 3 * server_nproto);
+	for (i = 0; i < server_nproto; i++)
+		sdp_put_uint16(&buf, server_proto[i]);
+
+	sdp_put_uint16(&buf, SDP_ATTR_BROWSE_GROUP_LIST);
+	sdp_put_seq(&buf, 3);
+	sdp_put_uuid16(&buf, SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP);
+
+	sdp_put_uint16(&buf, SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
+	sdp_put_seq(&buf, 9);
+	sdp_put_uint16(&buf, 0x656e);	/* "en" */
+	sdp_put_uint16(&buf, 106);	/* UTF-8 */
+	sdp_put_uint16(&buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID);
+
+	sdp_put_uint16(&buf, SDP_ATTR_SERVICE_AVAILABILITY);
+	sdp_put_uint8(&buf, (UINT8_MAX - server_count * UINT8_MAX / server_limit));
+
+	sdp_put_uint16(&buf, SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
+	sdp_put_seq(&buf, 8);
+	sdp_put_seq(&buf, 6);
+	sdp_put_uuid16(&buf, service_class);
+	sdp_put_uint16(&buf, 0x0100);	/* v1.0 */
+
+	sdp_put_uint16(&buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID
+	    + SDP_ATTR_SERVICE_NAME_OFFSET);
+	sdp_put_str(&buf, service_name, -1);
+
+	sdp_put_uint16(&buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID
+	    + SDP_ATTR_SERVICE_DESCRIPTION_OFFSET);
+	sdp_put_str(&buf, service_desc, -1);
+
+	sdp_put_uint16(&buf, SDP_ATTR_SECURITY_DESCRIPTION);
+	sdp_put_uint16(&buf, (l2cap_mode == 0) ? 0x0000 : 0x0001);
+
+	if (service_class == SDP_SERVICE_CLASS_NAP) {
+		sdp_put_uint16(&buf, SDP_ATTR_NET_ACCESS_TYPE);
+		sdp_put_uint16(&buf, 0x0004);	/* 10Mb Ethernet */
+
+		sdp_put_uint16(&buf, SDP_ATTR_MAX_NET_ACCESS_RATE);
+		sdp_put_uint32(&buf, 10000);	/* 10Mb/s (?) */
+	}
+
+	if (service_class == SDP_SERVICE_CLASS_NAP
+	    || service_class == SDP_SERVICE_CLASS_GN) {
+		if (server_ipv4_subnet) {
+			sdp_put_uint16(&buf, SDP_ATTR_IPV4_SUBNET);
+			sdp_put_str(&buf, server_ipv4_subnet, -1);
+		}
+
+		if (server_ipv6_subnet) {
+			sdp_put_uint16(&buf, SDP_ATTR_IPV6_SUBNET);
+			sdp_put_str(&buf, server_ipv6_subnet, -1);
+		}
+	}
+
+	server_record.next = data;
+	server_record.end = buf.next;
+}

Index: src/usr.sbin/btpand/btpand.h
diff -u src/usr.sbin/btpand/btpand.h:1.2 src/usr.sbin/btpand/btpand.h:1.3
--- src/usr.sbin/btpand/btpand.h:1.2	Tue May 12 21:08:30 2009
+++ src/usr.sbin/btpand/btpand.h	Tue May 12 21:50:38 2009
@@ -1,7 +1,7 @@
-/*	$NetBSD: btpand.h,v 1.2 2009/05/12 21:08:30 plunky Exp $	*/
+/*	$NetBSD: btpand.h,v 1.3 2009/05/12 21:50:38 plunky Exp $	*/
 
 /*-
- * Copyright (c) 2008 Iain Hibbert
+ * Copyright (c) 2008-2009 Iain Hibbert
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -135,7 +135,9 @@
 
 /* global variables */
 extern const char *	control_path;
+extern const char *	service_type;
 extern const char *	service_name;
+extern const char *	service_desc;
 extern const char *	interface_name;
 extern bdaddr_t		local_bdaddr;
 extern bdaddr_t		remote_bdaddr;

Reply via email to