Skip to contentSkip to conversation

Support for getting rfcomm connection information before setting up the connection

RFC New Ville Tervo 1 participant 1 message Dec 4, 2008

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

RFC 1/1 Support for getting rfcomm connection information before setting up the connection

Hi,

In order to implement HFP profile correctly the gateway needs to know address off the the HF device before accepting the connection. Currently there is no way to check the address without calling accept(). This patch creates a socket option which can be used change the behavior of the socket. Server still calls accept() but the actual connection setup will be done only after calling recv() for the first time. In between the server can use other getsockopts to get the needed information.

I also attached patch against rctest.c as an example how test this feature.

Waiting for comments :)

Signature · 1 line
Ville
Quoted 1 line

From 746b1179efe09bf4ba5ec0d2b954e2b2c8ab80c5 Mon Sep 17 00:00:00 2001

From: Ville Tervo <[email protected]>
Date: Wed, 3 Dec 2008 14:20:55 +0200
Subject: [PATCH] [BLUETOOTH] Support for deferring rfcomm connection

In order to decide if listening rfcomm socket should be accept()ed the bd_addr of remote device needs to be known. This patch add a socket option which defines timeout for deferring connection setup.

The connection is actually allowed after reading from socket first time. Until reading first time writing to socket returns -ENOTCONN.

---
 include/net/bluetooth/bluetooth.h |    4 +
 include/net/bluetooth/rfcomm.h    |    6 ++-
 net/bluetooth/rfcomm/core.c       |   48 ++++++++++++++--
 net/bluetooth/rfcomm/sock.c       |  112 ++++++++++++++++++++++++++-----------
 4 files changed, 131 insertions(+), 39 deletions(-)
include/net/bluetooth/bluetooth.h +4 -0
index 6f8418b..1a0fa21 100644
@@ -53,6 +53,10 @@
 #define SOL_SCO		17
 #define SOL_RFCOMM	18
 
+#define BT_INFORMATION	0x01
+
+#define BT_DEFER_SETUP	0x02
+
 #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
 #define BT_DBG(fmt, arg...)  printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , ## arg)
 #define BT_ERR(fmt, arg...)  printk(KERN_ERR  "%s: " fmt "\n" , __FUNCTION__ , ## arg)
include/net/bluetooth/rfcomm.h +5 -1
index 4dc8d92..eaa1365 100644
@@ -184,6 +184,7 @@ struct rfcomm_dlc {
 	u8            mscex;
 	u8            out;
 
+	u32           defer_setup;
 	u32           link_mode;
 
 	uint          mtu;
@@ -202,10 +203,11 @@ struct rfcomm_dlc {
 #define RFCOMM_RX_THROTTLED 0
 #define RFCOMM_TX_THROTTLED 1
 #define RFCOMM_TIMED_OUT    2
-#define RFCOMM_MSC_PENDING  3 
+#define RFCOMM_MSC_PENDING  3
 #define RFCOMM_AUTH_PENDING 4
 #define RFCOMM_AUTH_ACCEPT  5
 #define RFCOMM_AUTH_REJECT  6
+#define RFCOMM_DEFER_SETUP  7
 
 /* Scheduling flags and events */
 #define RFCOMM_SCHED_STATE  0
@@ -239,6 +241,7 @@ int  rfcomm_dlc_close(struct rfcomm_dlc *d, int reason);
 int  rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb);
 int  rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig);
 int  rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig);
+int  rfcomm_dlc_accept_conn(struct rfcomm_dlc *d);
 
 #define rfcomm_dlc_lock(d)     spin_lock(&d->lock)
 #define rfcomm_dlc_unlock(d)   spin_unlock(&d->lock)
@@ -305,6 +308,7 @@ struct rfcomm_pinfo {
 	struct rfcomm_dlc   *dlc;
 	u8     channel;
 	u32    link_mode;
+	u32    defer_setup;
 };
 
 int  rfcomm_init_sockets(void);
net/bluetooth/rfcomm/core.c +42 -6

96 lines not on this page · raw message

net/bluetooth/rfcomm/sock.c +80 -32

191 lines not on this page · raw message

Signature · 1 line
1.6.0.4
Quoted 1 line

From d6510a66b1df0ff6da1049b8d3a8ba61ccc2cd6f Mon Sep 17 00:00:00 2001

From: Ville Tervo <[email protected]>
Date: Wed, 3 Dec 2008 14:00:56 +0200
Subject: [PATCH] hack to test connection defer feature

---
 test/rctest.c |   32 +++++++++++++++++++++++++++++---
 1 files changed, 29 insertions(+), 3 deletions(-)
test/rctest.c +29 -3
index 08620d4..11bc97f 100644
@@ -81,6 +81,9 @@ static int secure = 0;
 static int socktype = SOCK_STREAM;
 static int linger = 0;
 static int timestamp = 0;
+static int defer_setup = 0;
+
+#define BT_DEFER_SETUP 0x02
 
 static float tv2fl(struct timeval tv)
 {
@@ -231,6 +234,16 @@ static void do_listen(void (*handler)(int sk))
 		goto error;
 	}
 
+	/* Enable deferred connection setup */
+	if (defer_setup > 0) {
+		if (setsockopt(sk, SOL_BLUETOOTH, BT_DEFER_SETUP, &defer_setup,
+			       sizeof(defer_setup))) {
+			syslog(LOG_ERR, "Can't enable BT_DEFER_SETUP: %s (%d)",
+							strerror(errno), errno);
+			goto error;
+		}
+	}
+
 	/* Listen for connections */
 	if (listen(sk, 10)) {
 		syslog(LOG_ERR,"Can not listen on the socket: %s (%d)",
@@ -286,6 +299,14 @@ static void do_listen(void (*handler)(int sk))
 			ba, conn.hci_handle,
 			conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]);
 
+		if (defer_setup > 0) {
+			syslog(LOG_INFO, "Waiting for %d msecs before making connection active",
+					  defer_setup - 1000);
+			usleep((defer_setup - 1000) * 1000);
+			close(nsk);
+			goto error;
+		}
+
 #if 0
 		/* Enable SO_TIMESTAMP */
 		if (timestamp) {
@@ -353,7 +374,7 @@ static void recv_mode(int sk)
 			//uint16_t l;
 			int r;
 
-			if ((r = recv(sk, buf, data_size, 0)) <= 0) {
+			if ((r = recv(sk, buf, data_size, 0)) < 0) {
 				if (r < 0)
 					syslog(LOG_ERR, "Read failed: %s (%d)",
 							strerror(errno), errno);
@@ -510,7 +531,8 @@ static void usage(void)
 		"\t[-E] request encryption\n"
 		"\t[-S] secure connection\n"
 		"\t[-M] become master\n"
-		"\t[-T] enable timestamps\n");
+		"\t[-T] enable timestamps\n"
+		"\t[-F] deFerrred setup\n");
 }
 
 int main(int argc, char *argv[])
@@ -520,7 +542,7 @@ int main(int argc, char *argv[])
 
 	bacpy(&bdaddr, BDADDR_ANY);
 
-	while ((opt=getopt(argc,argv,"rdscuwmnb:i:P:B:N:MAESL:C:D:T")) != EOF) {
+	while ((opt=getopt(argc,argv,"rdscuwmnb:i:P:B:N:MAESL:C:D:TF:")) != EOF) {
 		switch (opt) {
 		case 'r':
 			mode = RECV;
@@ -614,6 +636,10 @@ int main(int argc, char *argv[])
 			timestamp = 1;
 			break;
 
+		case 'F':
+			defer_setup = atoi(optarg);
+			break;
+
 		default:
 			usage();
 			exit(1);
Signature · 1 line
1.6.0.4