Module Name:    src
Committed By:   plunky
Date:           Fri Sep 25 19:44:57 UTC 2009

Modified Files:
        src/sys/netbt: l2cap_signal.c l2cap_upper.c

Log Message:
When the special L2CAP_PSM_ANY value is used for listening sockets,
select the next unused PSM from the dynamic range (0x1001->)


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/netbt/l2cap_signal.c \
    src/sys/netbt/l2cap_upper.c

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

Modified files:

Index: src/sys/netbt/l2cap_signal.c
diff -u src/sys/netbt/l2cap_signal.c:1.9 src/sys/netbt/l2cap_signal.c:1.10
--- src/sys/netbt/l2cap_signal.c:1.9	Sat Nov 10 23:12:23 2007
+++ src/sys/netbt/l2cap_signal.c	Fri Sep 25 19:44:57 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: l2cap_signal.c,v 1.9 2007/11/10 23:12:23 plunky Exp $	*/
+/*	$NetBSD: l2cap_signal.c,v 1.10 2009/09/25 19:44:57 plunky Exp $	*/
 
 /*-
  * Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: l2cap_signal.c,v 1.9 2007/11/10 23:12:23 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: l2cap_signal.c,v 1.10 2009/09/25 19:44:57 plunky Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -266,8 +266,7 @@
 	bdaddr_copy(&raddr.bt_bdaddr, &link->hl_bdaddr);
 
 	LIST_FOREACH(chan, &l2cap_listen_list, lc_ncid) {
-		if (chan->lc_laddr.bt_psm != laddr.bt_psm
-		    && chan->lc_laddr.bt_psm != L2CAP_PSM_ANY)
+		if (chan->lc_laddr.bt_psm != laddr.bt_psm)
 			continue;
 
 		if (!bdaddr_same(&laddr.bt_bdaddr, &chan->lc_laddr.bt_bdaddr)
Index: src/sys/netbt/l2cap_upper.c
diff -u src/sys/netbt/l2cap_upper.c:1.9 src/sys/netbt/l2cap_upper.c:1.10
--- src/sys/netbt/l2cap_upper.c:1.9	Wed Aug  6 15:01:24 2008
+++ src/sys/netbt/l2cap_upper.c	Fri Sep 25 19:44:57 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: l2cap_upper.c,v 1.9 2008/08/06 15:01:24 plunky Exp $	*/
+/*	$NetBSD: l2cap_upper.c,v 1.10 2009/09/25 19:44:57 plunky Exp $	*/
 
 /*-
  * Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: l2cap_upper.c,v 1.9 2008/08/06 15:01:24 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: l2cap_upper.c,v 1.10 2009/09/25 19:44:57 plunky Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -296,8 +296,10 @@
  *
  *		proto->newconn(upper, laddr, raddr)
  *
- *	for incoming connections matching the psm and local address of the
- *	channel (NULL psm/address are permitted and match any protocol/device).
+ *	for incoming connections matching the psm and local address of
+ *	the channel. NULL address is permitted and matches any device.
+ *	If L2CAP_PSM_ANY is bound the next higher unused value from the
+ *	dynamic range (above 0x1001) will be selected.
  *
  *	The upper layer should create and return a new channel.
  *
@@ -307,13 +309,31 @@
 l2cap_listen(struct l2cap_channel *chan)
 {
 	struct l2cap_channel *used, *prev = NULL;
+	uint32_t psm;
 
 	if (chan->lc_lcid != L2CAP_NULL_CID)
 		return EINVAL;
 
-	if (chan->lc_laddr.bt_psm != L2CAP_PSM_ANY
-	    && L2CAP_PSM_INVALID(chan->lc_laddr.bt_psm))
-		return EADDRNOTAVAIL;
+	/*
+	 * This is simplistic but its not really worth spending a
+	 * lot of time looking for an unused PSM..
+	 */
+	if (chan->lc_laddr.bt_psm == L2CAP_PSM_ANY) {
+		psm = 0x1001;
+		used = LIST_FIRST(&l2cap_listen_list);
+
+		if (used != NULL && used->lc_laddr.bt_psm >= psm) {
+			psm = used->lc_laddr.bt_psm + 0x0002;
+			if ((psm & 0x0100) != 0)
+				psm += 0x0100;
+
+			if (psm > UINT16_MAX)
+				return EADDRNOTAVAIL;
+		}
+
+		chan->lc_laddr.bt_psm = psm;
+	} else if (L2CAP_PSM_INVALID(chan->lc_laddr.bt_psm))
+		return EINVAL;
 
 	/*
 	 * This CID is irrelevant, as the channel is not stored on the active

Reply via email to