Module Name:    src
Committed By:   plunky
Date:           Thu Sep 24 18:30:37 UTC 2009

Modified Files:
        src/usr.bin/rfcomm_sppd: rfcomm_sppd.1 rfcomm_sppd.c

Log Message:
Add a new feature, allow to specify an alternative PSM value for the
RFCOMM protocol to use in client or server mode. Also, handle the case
where service search of the remote device returns non-standard PSM.


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/usr.bin/rfcomm_sppd/rfcomm_sppd.1
cvs rdiff -u -r1.11 -r1.12 src/usr.bin/rfcomm_sppd/rfcomm_sppd.c

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

Modified files:

Index: src/usr.bin/rfcomm_sppd/rfcomm_sppd.1
diff -u src/usr.bin/rfcomm_sppd/rfcomm_sppd.1:1.6 src/usr.bin/rfcomm_sppd/rfcomm_sppd.1:1.7
--- src/usr.bin/rfcomm_sppd/rfcomm_sppd.1:1.6	Sun Dec  2 20:41:40 2007
+++ src/usr.bin/rfcomm_sppd/rfcomm_sppd.1	Thu Sep 24 18:30:37 2009
@@ -1,4 +1,4 @@
-.\" $NetBSD: rfcomm_sppd.1,v 1.6 2007/12/02 20:41:40 wiz Exp $
+.\" $NetBSD: rfcomm_sppd.1,v 1.7 2009/09/24 18:30:37 plunky Exp $
 .\"
 .\" Copyright (c) 2006 Itronix Inc.
 .\" All rights reserved.
@@ -52,7 +52,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd April 10, 2007
+.Dd September 24, 2009
 .Dt RFCOMM_SPPD 1
 .Os
 .Sh NAME
@@ -62,6 +62,7 @@
 .Nm
 .Op Fl d Ar device
 .Op Fl m Ar mode
+.Op Fl p Ar psm
 .Op Fl s Ar service
 .Op Fl t Ar tty
 .Brq Fl a Ar address | Fl c Ar channel
@@ -129,6 +130,12 @@
 .It secure
 encryption, plus change of link key.
 .El
+.It Fl p Ar psm
+Specify the
+.Qq Protocol/Service Multiplexer
+value to be used for the RFCOMM protocol.
+In client mode where Service Discovery is being used, this value
+will be ignored.
 .It Fl s Ar service
 This is the service class that will be searched for on the remote device.
 If no

Index: src/usr.bin/rfcomm_sppd/rfcomm_sppd.c
diff -u src/usr.bin/rfcomm_sppd/rfcomm_sppd.c:1.11 src/usr.bin/rfcomm_sppd/rfcomm_sppd.c:1.12
--- src/usr.bin/rfcomm_sppd/rfcomm_sppd.c:1.11	Thu May 21 14:44:01 2009
+++ src/usr.bin/rfcomm_sppd/rfcomm_sppd.c	Thu Sep 24 18:30:37 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: rfcomm_sppd.c,v 1.11 2009/05/21 14:44:01 plunky Exp $	*/
+/*	$NetBSD: rfcomm_sppd.c,v 1.12 2009/09/24 18:30:37 plunky Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -62,7 +62,7 @@
   Copyright (c) 2006 Itronix, Inc.\
   Copyright (c) 2003 Maksim Yevmenkin m_evmen...@yahoo.com.\
   All rights reserved.");
-__RCSID("$NetBSD: rfcomm_sppd.c,v 1.11 2009/05/21 14:44:01 plunky Exp $");
+__RCSID("$NetBSD: rfcomm_sppd.c,v 1.12 2009/09/24 18:30:37 plunky Exp $");
 
 #include <sys/param.h>
 
@@ -87,10 +87,10 @@
 #include <netbt/rfcomm.h>
 
 int open_tty(const char *);
-int open_client(bdaddr_t *, bdaddr_t *, int, const char *);
-int open_server(bdaddr_t *, uint8_t, int, const char *);
+int open_client(bdaddr_t *, bdaddr_t *, int, uintmax_t, const char *);
+int open_server(bdaddr_t *, uint16_t, uint8_t, int, const char *);
 void copy_data(int, int);
-int channel_lookup(const bdaddr_t *, const bdaddr_t *, uint16_t, uintmax_t *);
+int service_search(const bdaddr_t *, const bdaddr_t *, uint16_t, uintmax_t *, uintmax_t *);
 void sighandler(int);
 void usage(void);
 void reset_tio(void);
@@ -121,6 +121,7 @@
 	const char		*service;
 	char			*ep, *tty;
 	int			lm, n, rfcomm, tty_in, tty_out;
+	uint16_t		psm;
 	uint8_t			channel;
 
 	bdaddr_copy(&laddr, BDADDR_ANY);
@@ -128,10 +129,11 @@
 	service = "SP";
 	tty = NULL;
 	channel = 0;
+	psm = L2CAP_PSM_RFCOMM;
 	lm = 0;
 
 	/* Parse command line options */
-	while ((n = getopt(argc, argv, "a:c:d:hm:s:t:")) != -1) {
+	while ((n = getopt(argc, argv, "a:c:d:hm:p:s:t:")) != -1) {
 		switch (n) {
 		case 'a': /* remote device address */
 			if (!bt_aton(optarg, &raddr)) {
@@ -170,6 +172,13 @@
 
 			break;
 
+		case 'p': /* PSM */
+			psm = strtoul(optarg, &ep, 0);
+			if (*ep != '\0' || L2CAP_PSM_INVALID(psm))
+				errx(EXIT_FAILURE, "Invalid PSM: %s", optarg);
+
+			break;
+
 		case 's': /* service class */
 			service = optarg;
 			break;
@@ -210,9 +219,9 @@
 
 	/* open RFCOMM */
 	if (channel == 0)
-		rfcomm = open_client(&laddr, &raddr, lm, service);
+		rfcomm = open_client(&laddr, &raddr, lm, psm, service);
 	else
-		rfcomm = open_server(&laddr, channel, lm, service);
+		rfcomm = open_server(&laddr, psm, channel, lm, service);
 
 	/*
 	 * now we are ready to go, so either detach or maybe turn
@@ -318,7 +327,7 @@
 }
 
 int
-open_client(bdaddr_t *laddr, bdaddr_t *raddr, int lm, const char *service)
+open_client(bdaddr_t *laddr, bdaddr_t *raddr, int lm, uintmax_t psm, const char *service)
 {
 	struct sockaddr_bt sa;
 	struct service *s;
@@ -337,7 +346,7 @@
 		}
 
 		if (strcasecmp(s->name, service) == 0) {
-			error = channel_lookup(laddr, raddr, s->class, &channel);
+			error = service_search(laddr, raddr, s->class, &psm, &channel);
 			if (error != 0)
 				errx(EXIT_FAILURE, "%s: %s", s->name, strerror(error));
 
@@ -348,6 +357,9 @@
 	if (channel < RFCOMM_CHANNEL_MIN || channel > RFCOMM_CHANNEL_MAX)
 		errx(EXIT_FAILURE, "Invalid channel %"PRIuMAX, channel);
 
+	if (L2CAP_PSM_INVALID(psm))
+		errx(EXIT_FAILURE, "Invalid PSM 0x%04"PRIxMAX, psm);
+
 	memset(&sa, 0, sizeof(sa));
 	sa.bt_len = sizeof(sa);
 	sa.bt_family = AF_BLUETOOTH;
@@ -369,18 +381,19 @@
 	if (setsockopt(fd, BTPROTO_RFCOMM, SO_RFCOMM_LM, &lm, sizeof(lm)) < 0)
 		err(EXIT_FAILURE, "link mode");
 
+	sa.bt_psm = psm;
 	sa.bt_channel = channel;
 	bdaddr_copy(&sa.bt_bdaddr, raddr);
 
 	if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0)
-		err(EXIT_FAILURE, "connect(%s, %"PRIuMAX")", bt_ntoa(raddr, NULL),
-						     channel);
+		err(EXIT_FAILURE, "connect(%s, 0x%04"PRIxMAX", %"PRIuMAX")",
+		    bt_ntoa(raddr, NULL), psm, channel);
 
 	return fd;
 }
 
 int
-open_server(bdaddr_t *laddr, uint8_t channel, int lm, const char *service)
+open_server(bdaddr_t *laddr, uint16_t psm, uint8_t channel, int lm, const char *service)
 {
 	uint8_t	buffer[256];
 	struct sockaddr_bt sa;
@@ -407,11 +420,12 @@
 	memset(&sa, 0, sizeof(sa));
 	sa.bt_len = sizeof(sa);
 	sa.bt_family = AF_BLUETOOTH;
+	sa.bt_psm = psm;
 	sa.bt_channel = channel;
 	bdaddr_copy(&sa.bt_bdaddr, laddr);
 	if (bind(sv, (struct sockaddr *)&sa, sizeof(sa)) < 0)
-		err(EXIT_FAILURE, "bind(%s, %d)", bt_ntoa(laddr, NULL),
-						  channel);
+		err(EXIT_FAILURE, "bind(%s, 0x%04x, %d)",
+		    bt_ntoa(laddr, NULL), psm, channel);
 
 	if (setsockopt(sv, BTPROTO_RFCOMM, SO_RFCOMM_LM, &lm, sizeof(lm)) < 0)
 		err(EXIT_FAILURE, "link mode");
@@ -430,10 +444,14 @@
 	sdp_put_seq(&rec, 3);
 	sdp_put_uuid16(&rec, s->class);
 
+	len = (psm == L2CAP_PSM_RFCOMM ? 0 : 3);
+
 	sdp_put_uint16(&rec, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
-	sdp_put_seq(&rec, 12);
-	sdp_put_seq(&rec, 3);
+	sdp_put_seq(&rec, 12 + len);
+	sdp_put_seq(&rec, 3 + len);
 	sdp_put_uuid16(&rec, SDP_UUID_PROTOCOL_L2CAP);
+	if (len > 0)
+		sdp_put_uint16(&rec, psm);
 	sdp_put_seq(&rec, 5);
 	sdp_put_uuid16(&rec, SDP_UUID_PROTOCOL_RFCOMM);
 	sdp_put_uint8(&rec, channel);
@@ -527,8 +545,8 @@
 }
 
 int
-channel_lookup(bdaddr_t const *laddr, bdaddr_t const *raddr,
-    uint16_t class, uintmax_t *channel)
+service_search(bdaddr_t const *laddr, bdaddr_t const *raddr,
+    uint16_t class, uintmax_t *psm, uintmax_t *channel)
 {
 	uint8_t		buffer[6];	/* SSP (3 bytes) + AIL (3 bytes) */
 	sdp_session_t	ss;
@@ -598,7 +616,8 @@
 	 * Each protocol stack description contains a sequence for each
 	 * protocol, where each sequence contains the protocol UUID as
 	 * the first element, and any ProtocolSpecificParameters. We are
-	 * interested in the RFCOMM channel number, stored as parameter#1.
+	 * interested in the L2CAP psm if provided, and the RFCOMM channel
+	 * number, stored as parameter#1 in each case.
 	 *
 	 *	seq
 	 *	  uuid		L2CAP
@@ -616,8 +635,10 @@
 
 		sdp_get_alt(&value, &value);	/* strip any alt container */
 		while (!rv && sdp_get_seq(&value, &pdl)) {
+			*psm = L2CAP_PSM_RFCOMM;
 			if (sdp_get_seq(&pdl, &seq)
 			    && sdp_match_uuid16(&seq, SDP_UUID_PROTOCOL_L2CAP)
+			    && (sdp_get_uint(&seq, psm) || true)
 			    && sdp_get_seq(&pdl, &seq)
 			    && sdp_match_uuid16(&seq, SDP_UUID_PROTOCOL_RFCOMM)
 			    && sdp_get_uint(&seq, channel))
@@ -649,7 +670,7 @@
 	const char *cmd = getprogname();
 	struct service *s;
 
-	fprintf(stderr, "Usage: %s [-d device] [-m mode] [-s service] [-t tty]\n"
+	fprintf(stderr, "Usage: %s [-d device] [-m mode] [-p psm] [-s service] [-t tty]\n"
 			"       %*s {-a bdaddr | -c channel}\n"
 			"\n"
 			"Where:\n"
@@ -657,6 +678,7 @@
 			"\t-c channel   local RFCOMM channel\n"
 			"\t-d device    local device address\n"
 			"\t-m mode      link mode\n"
+			"\t-p psm       protocol/service multiplexer\n"
 			"\t-s service   service class\n"
 			"\t-t tty       run in background using pty\n"
 			"\n", cmd, (int)strlen(cmd), "");

Reply via email to