Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH -v2 4/7] Bluetooth: Add chan->chan_type struct member
From: Gustavo F. Padovan @ 2011-05-13 19:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1305314450-25493-4-git-send-email-padovan@profusion.mobi>

chan_type says if our chan is raw(direclty access to HCI),
connection less or connection oriented.

Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
 include/net/bluetooth/l2cap.h |    5 +++++
 net/bluetooth/l2cap_core.c    |   30 +++++++++++-------------------
 net/bluetooth/l2cap_sock.c    |   29 ++++++++++++++++++++++-------
 3 files changed, 38 insertions(+), 26 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index dc721ca..094a7ac 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -295,6 +295,7 @@ struct l2cap_chan {
 	__u16		omtu;
 	__u16		flush_to;
 	__u8		mode;
+	__u8		chan_type;
 
 	__le16		sport;
 
@@ -384,6 +385,10 @@ struct l2cap_conn {
 #define L2CAP_INFO_FEAT_MASK_REQ_SENT	0x04
 #define L2CAP_INFO_FEAT_MASK_REQ_DONE	0x08
 
+#define L2CAP_CHAN_RAW			1
+#define L2CAP_CHAN_CONN_LESS		2
+#define L2CAP_CHAN_CONN_ORIENTED	3
+
 /* ----- L2CAP socket info ----- */
 #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
 
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 1e049a7..0964854 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -245,7 +245,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
 
 	chan->conn = conn;
 
-	if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
+	if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
 		if (conn->hcon->type == LE_LINK) {
 			/* LE connection */
 			chan->omtu = L2CAP_LE_DEFAULT_MTU;
@@ -256,7 +256,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
 			chan->scid = l2cap_alloc_cid(conn);
 			chan->omtu = L2CAP_DEFAULT_MTU;
 		}
-	} else if (sk->sk_type == SOCK_DGRAM) {
+	} else if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
 		/* Connectionless socket */
 		chan->scid = L2CAP_CID_CONN_LESS;
 		chan->dcid = L2CAP_CID_CONN_LESS;
@@ -369,8 +369,7 @@ void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
 
 	case BT_CONNECTED:
 	case BT_CONFIG:
-		if ((sk->sk_type == SOCK_SEQPACKET ||
-					sk->sk_type == SOCK_STREAM) &&
+		if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
 					conn->hcon->type == ACL_LINK) {
 			l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
 			l2cap_send_disconn_req(conn, chan, reason);
@@ -379,8 +378,7 @@ void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
 		break;
 
 	case BT_CONNECT2:
-		if ((sk->sk_type == SOCK_SEQPACKET ||
-					sk->sk_type == SOCK_STREAM) &&
+		if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
 					conn->hcon->type == ACL_LINK) {
 			struct l2cap_conn_rsp rsp;
 			__u16 result;
@@ -414,9 +412,7 @@ void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
 
 static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
 {
-	struct sock *sk = chan->sk;
-
-	if (sk->sk_type == SOCK_RAW) {
+	if (chan->chan_type == L2CAP_CHAN_RAW) {
 		switch (chan->sec_level) {
 		case BT_SECURITY_HIGH:
 			return HCI_AT_DEDICATED_BONDING_MITM;
@@ -657,8 +653,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
 
 		bh_lock_sock(sk);
 
-		if (sk->sk_type != SOCK_SEQPACKET &&
-				sk->sk_type != SOCK_STREAM) {
+		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
 			bh_unlock_sock(sk);
 			continue;
 		}
@@ -852,8 +847,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
 			sk->sk_state_change(sk);
 		}
 
-		if (sk->sk_type != SOCK_SEQPACKET &&
-				sk->sk_type != SOCK_STREAM) {
+		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
 			l2cap_sock_clear_timer(sk);
 			sk->sk_state = BT_CONNECTED;
 			sk->sk_state_change(sk);
@@ -1056,8 +1050,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan)
 	l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
 
 	if (hcon->state == BT_CONNECTED) {
-		if (sk->sk_type != SOCK_SEQPACKET &&
-				sk->sk_type != SOCK_STREAM) {
+		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
 			l2cap_sock_clear_timer(sk);
 			if (l2cap_check_security(chan))
 				sk->sk_state = BT_CONNECTED;
@@ -1537,13 +1530,12 @@ int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t le
 
 int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
 {
-	struct sock *sk = chan->sk;
 	struct sk_buff *skb;
 	u16 control;
 	int err;
 
 	/* Connectionless channel */
-	if (sk->sk_type == SOCK_DGRAM) {
+	if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
 		skb = l2cap_create_connless_pdu(chan, msg, len);
 		if (IS_ERR(skb))
 			return PTR_ERR(skb);
@@ -1650,7 +1642,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
 	read_lock(&conn->chan_lock);
 	list_for_each_entry(chan, &conn->chan_l, list) {
 		struct sock *sk = chan->sk;
-		if (sk->sk_type != SOCK_RAW)
+		if (chan->chan_type != L2CAP_CHAN_RAW)
 			continue;
 
 		/* Don't send frame to the socket it came from */
@@ -4106,7 +4098,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
 {
 	struct sock *sk = chan->sk;
 
-	if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
+	if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
 		return;
 
 	if (encrypt == 0x00) {
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index f36776e..6a80a96 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -162,7 +162,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
 
 	lock_sock(sk);
 
-	if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
+	if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED
 			&& !(la.l2_psm || la.l2_cid)) {
 		err = -EINVAL;
 		goto done;
@@ -204,8 +204,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
 	}
 
 	/* PSM must be odd and lsb of upper byte must be 0 */
-	if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 &&
-				sk->sk_type != SOCK_RAW && !la.l2_cid) {
+	if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 && !la.l2_cid &&
+					chan->chan_type != L2CAP_CHAN_RAW) {
 		err = -EINVAL;
 		goto done;
 	}
@@ -453,8 +453,8 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
 
 	switch (optname) {
 	case BT_SECURITY:
-		if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
-				&& sk->sk_type != SOCK_RAW) {
+		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
+					chan->chan_type != L2CAP_CHAN_RAW) {
 			err = -EINVAL;
 			break;
 		}
@@ -599,8 +599,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
 
 	switch (optname) {
 	case BT_SECURITY:
-		if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
-				&& sk->sk_type != SOCK_RAW) {
+		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
+					chan->chan_type != L2CAP_CHAN_RAW) {
 			err = -EINVAL;
 			break;
 		}
@@ -806,6 +806,7 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent)
 		sk->sk_type = parent->sk_type;
 		bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
 
+		chan->chan_type = pchan->chan_type;
 		chan->imtu = pchan->imtu;
 		chan->omtu = pchan->omtu;
 		chan->conf_state = pchan->conf_state;
@@ -818,6 +819,20 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent)
 		chan->force_reliable = pchan->force_reliable;
 		chan->flushable = pchan->flushable;
 	} else {
+
+		switch (sk->sk_type) {
+		case SOCK_RAW:
+			chan->chan_type = L2CAP_CHAN_RAW;
+			break;
+		case SOCK_DGRAM:
+			chan->chan_type = L2CAP_CHAN_CONN_LESS;
+			break;
+		case SOCK_SEQPACKET:
+		case SOCK_STREAM:
+			chan->chan_type = L2CAP_CHAN_CONN_ORIENTED;
+			break;
+		}
+
 		chan->imtu = L2CAP_DEFAULT_MTU;
 		chan->omtu = 0;
 		if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
-- 
1.7.5.rc3


^ permalink raw reply related

* [PATCH -v2 3/7] Bluetooth: Create l2cap_chan_send()
From: Gustavo F. Padovan @ 2011-05-13 19:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1305314450-25493-3-git-send-email-padovan@profusion.mobi>

This move all the sending logic to l2cap_core.c, but we still have a
socket dependence there, struct msghdr. It will be removed in some of the
further commits.

Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
 include/net/bluetooth/l2cap.h |    9 +----
 net/bluetooth/l2cap_core.c    |   80 +++++++++++++++++++++++++++++++++++++++
 net/bluetooth/l2cap_sock.c    |   83 +---------------------------------------
 3 files changed, 84 insertions(+), 88 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index ed75e65..dc721ca 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -449,14 +449,6 @@ void l2cap_cleanup_sockets(void);
 void __l2cap_connect_rsp_defer(struct l2cap_chan *chan);
 int __l2cap_wait_ack(struct sock *sk);
 
-struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
-struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
-struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len, u16 control, u16 sdulen);
-int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
-void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb);
-void l2cap_streaming_send(struct l2cap_chan *chan);
-int l2cap_ertm_send(struct l2cap_chan *chan);
-
 int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);
 int l2cap_add_scid(struct l2cap_chan *chan,  __u16 scid);
 
@@ -470,5 +462,6 @@ struct l2cap_chan *l2cap_chan_create(struct sock *sk);
 void __l2cap_chan_close(struct l2cap_chan *chan, int reason);
 void l2cap_chan_destroy(struct l2cap_chan *chan);
 int l2cap_chan_connect(struct l2cap_chan *chan);
+int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
 
 #endif /* __L2CAP_H */
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 550585e..1e049a7 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1535,6 +1535,86 @@ int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t le
 	return size;
 }
 
+int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
+{
+	struct sock *sk = chan->sk;
+	struct sk_buff *skb;
+	u16 control;
+	int err;
+
+	/* Connectionless channel */
+	if (sk->sk_type == SOCK_DGRAM) {
+		skb = l2cap_create_connless_pdu(chan, msg, len);
+		if (IS_ERR(skb))
+			return PTR_ERR(skb);
+
+		l2cap_do_send(chan, skb);
+		return len;
+	}
+
+	switch (chan->mode) {
+	case L2CAP_MODE_BASIC:
+		/* Check outgoing MTU */
+		if (len > chan->omtu)
+			return -EMSGSIZE;
+
+		/* Create a basic PDU */
+		skb = l2cap_create_basic_pdu(chan, msg, len);
+		if (IS_ERR(skb))
+			return PTR_ERR(skb);
+
+		l2cap_do_send(chan, skb);
+		err = len;
+		break;
+
+	case L2CAP_MODE_ERTM:
+	case L2CAP_MODE_STREAMING:
+		/* Entire SDU fits into one PDU */
+		if (len <= chan->remote_mps) {
+			control = L2CAP_SDU_UNSEGMENTED;
+			skb = l2cap_create_iframe_pdu(chan, msg, len, control,
+									0);
+			if (IS_ERR(skb))
+				return PTR_ERR(skb);
+
+			__skb_queue_tail(&chan->tx_q, skb);
+
+			if (chan->tx_send_head == NULL)
+				chan->tx_send_head = skb;
+
+		} else {
+			/* Segment SDU into multiples PDUs */
+			err = l2cap_sar_segment_sdu(chan, msg, len);
+			if (err < 0)
+				return err;
+		}
+
+		if (chan->mode == L2CAP_MODE_STREAMING) {
+			l2cap_streaming_send(chan);
+			err = len;
+			break;
+		}
+
+		if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
+				(chan->conn_state & L2CAP_CONN_WAIT_F)) {
+			err = len;
+			break;
+		}
+
+		err = l2cap_ertm_send(chan);
+		if (err >= 0)
+			err = len;
+
+		break;
+
+	default:
+		BT_DBG("bad state %1.1x", chan->mode);
+		err = -EBADFD;
+	}
+
+	return err;
+}
+
 static void l2cap_chan_ready(struct sock *sk)
 {
 	struct sock *parent = bt_sk(sk)->parent;
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index f57afa5..f36776e 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -673,8 +673,6 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
 {
 	struct sock *sk = sock->sk;
 	struct l2cap_chan *chan = l2cap_pi(sk)->chan;
-	struct sk_buff *skb;
-	u16 control;
 	int err;
 
 	BT_DBG("sock %p, sk %p", sock, sk);
@@ -689,87 +687,12 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
 	lock_sock(sk);
 
 	if (sk->sk_state != BT_CONNECTED) {
-		err = -ENOTCONN;
-		goto done;
+		release_sock(sk);
+		return -ENOTCONN;
 	}
 
-	/* Connectionless channel */
-	if (sk->sk_type == SOCK_DGRAM) {
-		skb = l2cap_create_connless_pdu(chan, msg, len);
-		if (IS_ERR(skb)) {
-			err = PTR_ERR(skb);
-		} else {
-			l2cap_do_send(chan, skb);
-			err = len;
-		}
-		goto done;
-	}
+	err = l2cap_chan_send(chan, msg, len);
 
-	switch (chan->mode) {
-	case L2CAP_MODE_BASIC:
-		/* Check outgoing MTU */
-		if (len > chan->omtu) {
-			err = -EMSGSIZE;
-			goto done;
-		}
-
-		/* Create a basic PDU */
-		skb = l2cap_create_basic_pdu(chan, msg, len);
-		if (IS_ERR(skb)) {
-			err = PTR_ERR(skb);
-			goto done;
-		}
-
-		l2cap_do_send(chan, skb);
-		err = len;
-		break;
-
-	case L2CAP_MODE_ERTM:
-	case L2CAP_MODE_STREAMING:
-		/* Entire SDU fits into one PDU */
-		if (len <= chan->remote_mps) {
-			control = L2CAP_SDU_UNSEGMENTED;
-			skb = l2cap_create_iframe_pdu(chan, msg, len, control,
-									0);
-			if (IS_ERR(skb)) {
-				err = PTR_ERR(skb);
-				goto done;
-			}
-			__skb_queue_tail(&chan->tx_q, skb);
-
-			if (chan->tx_send_head == NULL)
-				chan->tx_send_head = skb;
-
-		} else {
-		/* Segment SDU into multiples PDUs */
-			err = l2cap_sar_segment_sdu(chan, msg, len);
-			if (err < 0)
-				goto done;
-		}
-
-		if (chan->mode == L2CAP_MODE_STREAMING) {
-			l2cap_streaming_send(chan);
-			err = len;
-			break;
-		}
-
-		if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
-				(chan->conn_state & L2CAP_CONN_WAIT_F)) {
-			err = len;
-			break;
-		}
-		err = l2cap_ertm_send(chan);
-
-		if (err >= 0)
-			err = len;
-		break;
-
-	default:
-		BT_DBG("bad state %1.1x", chan->mode);
-		err = -EBADFD;
-	}
-
-done:
 	release_sock(sk);
 	return err;
 }
-- 
1.7.5.rc3


^ permalink raw reply related

* [PATCH -v2 2/7] Bluetooth: Create __l2cap_chan_close()
From: Gustavo F. Padovan @ 2011-05-13 19:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1305314450-25493-2-git-send-email-padovan@profusion.mobi>

This is actually __l2cap_sock_close() renamed to __l2cap_chan_close().
At a first look it may not make sense, but with the further cleanups that
will come it will.

Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
 include/net/bluetooth/l2cap.h |    5 +--
 net/bluetooth/l2cap_core.c    |   97 ++++++++++++++++++++++++++++++++++++++---
 net/bluetooth/l2cap_sock.c    |   85 +-----------------------------------
 3 files changed, 94 insertions(+), 93 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index d09c9b1..ed75e65 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -446,7 +446,6 @@ extern int disable_ertm;
 int l2cap_init_sockets(void);
 void l2cap_cleanup_sockets(void);
 
-void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data);
 void __l2cap_connect_rsp_defer(struct l2cap_chan *chan);
 int __l2cap_wait_ack(struct sock *sk);
 
@@ -463,14 +462,12 @@ int l2cap_add_scid(struct l2cap_chan *chan,  __u16 scid);
 
 void l2cap_sock_set_timer(struct sock *sk, long timeout);
 void l2cap_sock_clear_timer(struct sock *sk);
-void __l2cap_sock_close(struct sock *sk, int reason);
 void l2cap_sock_kill(struct sock *sk);
 void l2cap_sock_init(struct sock *sk, struct sock *parent);
 struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
 							int proto, gfp_t prio);
-void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err);
 struct l2cap_chan *l2cap_chan_create(struct sock *sk);
-void l2cap_chan_del(struct l2cap_chan *chan, int err);
+void __l2cap_chan_close(struct l2cap_chan *chan, int reason);
 void l2cap_chan_destroy(struct l2cap_chan *chan);
 int l2cap_chan_connect(struct l2cap_chan *chan);
 
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index a5ab4a2..550585e 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -69,7 +69,11 @@ static void l2cap_busy_work(struct work_struct *work);
 
 static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
 				u8 code, u8 ident, u16 dlen, void *data);
+static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
+								void *data);
 static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
+static void l2cap_send_disconn_req(struct l2cap_conn *conn,
+				struct l2cap_chan *chan, int err);
 
 static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
 
@@ -271,7 +275,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
 
 /* Delete channel.
  * Must be called on the locked socket. */
-void l2cap_chan_del(struct l2cap_chan *chan, int err)
+static void l2cap_chan_del(struct l2cap_chan *chan, int err)
 {
 	struct sock *sk = chan->sk;
 	struct l2cap_conn *conn = chan->conn;
@@ -327,6 +331,87 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
 	}
 }
 
+/* Must be called on unlocked socket. */
+static void l2cap_chan_close(struct sock *sk)
+{
+	l2cap_sock_clear_timer(sk);
+	lock_sock(sk);
+	__l2cap_chan_close(l2cap_pi(sk)->chan, ECONNRESET);
+	release_sock(sk);
+	l2cap_sock_kill(sk);
+}
+
+static void l2cap_chan_cleanup_listen(struct sock *parent)
+{
+	struct sock *sk;
+
+	BT_DBG("parent %p", parent);
+
+	/* Close not yet accepted channels */
+	while ((sk = bt_accept_dequeue(parent, NULL)))
+		l2cap_chan_close(sk);
+
+	parent->sk_state = BT_CLOSED;
+	sock_set_flag(parent, SOCK_ZAPPED);
+}
+
+void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
+{
+	struct l2cap_conn *conn = chan->conn;
+	struct sock *sk = chan->sk;
+
+	BT_DBG("chan %p state %d socket %p", chan, sk->sk_state, sk->sk_socket);
+
+	switch (sk->sk_state) {
+	case BT_LISTEN:
+		l2cap_chan_cleanup_listen(sk);
+		break;
+
+	case BT_CONNECTED:
+	case BT_CONFIG:
+		if ((sk->sk_type == SOCK_SEQPACKET ||
+					sk->sk_type == SOCK_STREAM) &&
+					conn->hcon->type == ACL_LINK) {
+			l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
+			l2cap_send_disconn_req(conn, chan, reason);
+		} else
+			l2cap_chan_del(chan, reason);
+		break;
+
+	case BT_CONNECT2:
+		if ((sk->sk_type == SOCK_SEQPACKET ||
+					sk->sk_type == SOCK_STREAM) &&
+					conn->hcon->type == ACL_LINK) {
+			struct l2cap_conn_rsp rsp;
+			__u16 result;
+
+			if (bt_sk(sk)->defer_setup)
+				result = L2CAP_CR_SEC_BLOCK;
+			else
+				result = L2CAP_CR_BAD_PSM;
+
+			rsp.scid   = cpu_to_le16(chan->dcid);
+			rsp.dcid   = cpu_to_le16(chan->scid);
+			rsp.result = cpu_to_le16(result);
+			rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
+			l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
+							sizeof(rsp), &rsp);
+		}
+
+		l2cap_chan_del(chan, reason);
+		break;
+
+	case BT_CONNECT:
+	case BT_DISCONN:
+		l2cap_chan_del(chan, reason);
+		break;
+
+	default:
+		sock_set_flag(sk, SOCK_ZAPPED);
+		break;
+	}
+}
+
 static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
 {
 	struct sock *sk = chan->sk;
@@ -393,7 +478,7 @@ u8 l2cap_get_ident(struct l2cap_conn *conn)
 	return id;
 }
 
-void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
+static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
 {
 	struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
 	u8 flags;
@@ -533,7 +618,7 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
 	}
 }
 
-void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
+static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
 {
 	struct sock *sk;
 	struct l2cap_disconn_req req;
@@ -591,10 +676,10 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
 					conn->feat_mask)
 					&& chan->conf_state &
 					L2CAP_CONF_STATE2_DEVICE) {
-				/* __l2cap_sock_close() calls list_del(chan)
+				/* __l2cap_chan_close() calls list_del(chan)
 				 * so release the lock */
 				read_unlock_bh(&conn->chan_lock);
-				 __l2cap_sock_close(sk, ECONNRESET);
+				 __l2cap_chan_close(chan, ECONNRESET);
 				read_lock_bh(&conn->chan_lock);
 				bh_unlock_sock(sk);
 				continue;
@@ -3949,7 +4034,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
 			l2cap_sock_clear_timer(sk);
 			l2cap_sock_set_timer(sk, HZ * 5);
 		} else if (chan->sec_level == BT_SECURITY_HIGH)
-			__l2cap_sock_close(sk, ECONNREFUSED);
+			__l2cap_chan_close(chan, ECONNREFUSED);
 	} else {
 		if (chan->sec_level == BT_SECURITY_MEDIUM)
 			l2cap_sock_clear_timer(sk);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index c98360d..f57afa5 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -58,7 +58,7 @@ static void l2cap_sock_timeout(unsigned long arg)
 	else
 		reason = ETIMEDOUT;
 
-	__l2cap_sock_close(sk, reason);
+	__l2cap_chan_close(l2cap_pi(sk)->chan, reason);
 
 	bh_unlock_sock(sk);
 
@@ -813,87 +813,6 @@ void l2cap_sock_kill(struct sock *sk)
 	sock_put(sk);
 }
 
-/* Must be called on unlocked socket. */
-static void l2cap_sock_close(struct sock *sk)
-{
-	l2cap_sock_clear_timer(sk);
-	lock_sock(sk);
-	__l2cap_sock_close(sk, ECONNRESET);
-	release_sock(sk);
-	l2cap_sock_kill(sk);
-}
-
-static void l2cap_sock_cleanup_listen(struct sock *parent)
-{
-	struct sock *sk;
-
-	BT_DBG("parent %p", parent);
-
-	/* Close not yet accepted channels */
-	while ((sk = bt_accept_dequeue(parent, NULL)))
-		l2cap_sock_close(sk);
-
-	parent->sk_state = BT_CLOSED;
-	sock_set_flag(parent, SOCK_ZAPPED);
-}
-
-void __l2cap_sock_close(struct sock *sk, int reason)
-{
-	struct l2cap_chan *chan = l2cap_pi(sk)->chan;
-	struct l2cap_conn *conn = chan->conn;
-
-	BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
-
-	switch (sk->sk_state) {
-	case BT_LISTEN:
-		l2cap_sock_cleanup_listen(sk);
-		break;
-
-	case BT_CONNECTED:
-	case BT_CONFIG:
-		if ((sk->sk_type == SOCK_SEQPACKET ||
-					sk->sk_type == SOCK_STREAM) &&
-					conn->hcon->type == ACL_LINK) {
-			l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
-			l2cap_send_disconn_req(conn, chan, reason);
-		} else
-			l2cap_chan_del(chan, reason);
-		break;
-
-	case BT_CONNECT2:
-		if ((sk->sk_type == SOCK_SEQPACKET ||
-					sk->sk_type == SOCK_STREAM) &&
-					conn->hcon->type == ACL_LINK) {
-			struct l2cap_conn_rsp rsp;
-			__u16 result;
-
-			if (bt_sk(sk)->defer_setup)
-				result = L2CAP_CR_SEC_BLOCK;
-			else
-				result = L2CAP_CR_BAD_PSM;
-
-			rsp.scid   = cpu_to_le16(chan->dcid);
-			rsp.dcid   = cpu_to_le16(chan->scid);
-			rsp.result = cpu_to_le16(result);
-			rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
-			l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
-							sizeof(rsp), &rsp);
-		}
-
-		l2cap_chan_del(chan, reason);
-		break;
-
-	case BT_CONNECT:
-	case BT_DISCONN:
-		l2cap_chan_del(chan, reason);
-		break;
-
-	default:
-		sock_set_flag(sk, SOCK_ZAPPED);
-		break;
-	}
-}
-
 static int l2cap_sock_shutdown(struct socket *sock, int how)
 {
 	struct sock *sk = sock->sk;
@@ -912,7 +831,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
 
 		sk->sk_shutdown = SHUTDOWN_MASK;
 		l2cap_sock_clear_timer(sk);
-		__l2cap_sock_close(sk, 0);
+		__l2cap_chan_close(chan, 0);
 
 		if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
 			err = bt_sock_wait_state(sk, BT_CLOSED,
-- 
1.7.5.rc3


^ permalink raw reply related

* [PATCH -v2 1/7] Bluetooth: Remove leftover debug messages
From: Gustavo F. Padovan @ 2011-05-13 19:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1305314450-25493-1-git-send-email-padovan@profusion.mobi>

They were added by me while testing and I forgot to remove.

Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
 net/bluetooth/l2cap_core.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index d0769a8..a5ab4a2 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2095,7 +2095,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
 	u16 dcid = 0, scid = __le16_to_cpu(req->scid);
 	__le16 psm = req->psm;
 
-	BT_ERR("psm 0x%2.2x scid 0x%4.4x", psm, scid);
+	BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
 
 	/* Check if we have socket listening on psm */
 	pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src);
@@ -2104,8 +2104,6 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
 		goto sendresp;
 	}
 
-	BT_ERR("%p 0x%2.2x", pchan, pchan->psm);
-
 	parent = pchan->sk;
 
 	bh_lock_sock(parent);
-- 
1.7.5.rc3


^ permalink raw reply related

* [PATCH -v2 0/7] L2CAP rework patches
From: Gustavo F. Padovan @ 2011-05-13 19:20 UTC (permalink / raw)
  To: linux-bluetooth

This is part of the ongoing series to fix the L2CAP core and remove its socket
dependence.

Changes since v1:
- Fixed styles issues and typos reported by Lizardo
- renamed link_type to chan_type
- renamed L2CAP_LINK_RAW to L2CAP_CHAN_RAW
- renamed L2CAP_LINK_CONNLESS to L2CAP_CHAN_CONN_LESS
- renamed L2CAP_LINK_ORIENTED to L2CAP_CHAN_CONN_ORIENTED

Gustavo F. Padovan (7):
  Bluetooth: Remove leftover debug messages
  Bluetooth: Create __l2cap_chan_close()
  Bluetooth: Create l2cap_chan_send()
  Bluetooth: Add chan->chan_type struct member
  Bluetooth: create channel timer to replace sk_timer
  Bluetooth: Remove export of l2cap_chan_clear_timer()
  Bluetooth: Rename __l2cap_chan_close() to l2cap_chan_close()

 include/net/bluetooth/l2cap.h |   23 ++--
 net/bluetooth/l2cap_core.c    |  289 ++++++++++++++++++++++++++++++++++------
 net/bluetooth/l2cap_sock.c    |  244 ++++-------------------------------
 3 files changed, 280 insertions(+), 276 deletions(-)

-- 
1.7.5.rc3


^ permalink raw reply

* Re: [PATCH v3] Bluetooth: Allow unsegmented SDU retries on sock_queue_rcv_skb failure.
From: Gustavo F. Padovan @ 2011-05-13 18:23 UTC (permalink / raw)
  To: Ruiyi Zhang; +Cc: linux-bluetooth
In-Reply-To: <7f3edf43a88fbbcd8ef1797450b43eda889e2c9a.1305256769.git.Ruiyi.Zhang@Atheros.com>

Hi Ruiyi,

* Ruiyi Zhang <Ruiyi.Zhang@Atheros.com> [2011-05-13 13:07:52 +0800]:

> In L2CAP_SDU_UNSEGMENTED case, if sock_queue_rcv_skb returns error,
> l2cap_ertm_reassembly_sdu should not return 0 so as to insert the
> skb into BUSY_QUEUE for later retries.
> 
> Signed-off-by: Ruiyi Zhang <Ruiyi.Zhang@Atheros.com>
> ---
>  net/bluetooth/l2cap_core.c |    6 +-----
>  1 files changed, 1 insertions(+), 5 deletions(-)

Applied, thanks.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: RFC: First pass at pretty hostname support
From: Bastien Nocera @ 2011-05-13 17:26 UTC (permalink / raw)
  To: BlueZ development
In-Reply-To: <1305051643.2427.82.camel@novo.hadess.net>

[-- Attachment #1: Type: text/plain, Size: 932 bytes --]

On Tue, 2011-05-10 at 19:20 +0100, Bastien Nocera wrote:
<snip>
> And a patch with inotify support (easier than I remembered).
> 
> That leaves us with the problem of changing the name when the default
> adapter changes.

Tested and a few corrections added.

- Made the inotify code work (oops)
- Make adapter_update_local_name() actually update the adapter's name if
it's up
- Factor out the "SetName" method (note that we don't check whether it's
valid UTF-8 anymore, because D-Bus will kick out the client if the
string isn't UTF-8 anyway)

What's left to do is:
- initial naming (the default_adapter isn't set on startup, so the first
adapter is always named "Foo #1" instead of "Foo")
- name changes when the default adapter changes (although I could
certainly live without that one for now)

Comments appreciated. I'm more than willing to split out the
src/adapter.[ch] and src/manager.[ch] changes, just let me know.

Cheers

[-- Attachment #2: 0001-adaptername-Move-adapter-naming-into-a-plugin.patch --]
[-- Type: text/x-patch, Size: 13995 bytes --]

>From ed8540cf729b06166240faa869fdce4103c420b3 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Tue, 10 May 2011 18:02:14 +0100
Subject: [PATCH] adaptername: Move adapter naming into a plugin

Moving the adapter naming allows us to use the /etc/machine-info [1]
pretty hostname, as implemented by hostnamed [2] in systemd.

If /etc/machine-info is not present, the adapter name stored
on disk in /var/lib/bluetooth will be used. If no adapter name
has been set yet, the default from the main.conf will be used.

[1]: http://0pointer.de/public/systemd-man/machine-info.html
[2]: http://www.freedesktop.org/wiki/Software/systemd/hostnamed

TODO:
* Changing the adapter name when the default changes
---
 Makefile.am           |    3 +
 configure.ac          |    3 +
 plugins/adaptername.c |  289 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/adapter.c         |  107 +++----------------
 src/adapter.h         |    2 +-
 src/manager.c         |    5 +
 src/manager.h         |    1 +
 7 files changed, 318 insertions(+), 92 deletions(-)
 create mode 100644 plugins/adaptername.c

diff --git a/Makefile.am b/Makefile.am
index caffbe2..fe24883 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -218,6 +218,9 @@ EXTRA_DIST += plugins/hal.c plugins/formfactor.c
 builtin_modules += storage
 builtin_sources += plugins/storage.c
 
+builtin_modules += adaptername
+builtin_sources += plugins/adaptername.c
+
 if MAEMO6PLUGIN
 builtin_modules += maemo6
 builtin_sources += plugins/maemo6.c
diff --git a/configure.ac b/configure.ac
index 111ff01..4c6016a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -35,6 +35,9 @@ AC_FUNC_PPOLL
 AC_CHECK_LIB(dl, dlopen, dummy=yes,
 			AC_MSG_ERROR(dynamic linking loader is required))
 
+AC_CHECK_HEADER([sys/inotify.h],
+		[AC_DEFINE([HAVE_SYS_INOTIFY_H], 1,
+			   [Define to 1 if you have <sys/inotify.h>.])])
 AC_PATH_DBUS
 AC_PATH_GLIB
 AC_PATH_ALSA
diff --git a/plugins/adaptername.c b/plugins/adaptername.c
new file mode 100644
index 0000000..33c4933
--- /dev/null
+++ b/plugins/adaptername.c
@@ -0,0 +1,289 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <bluetooth/bluetooth.h>
+
+#include "plugin.h"
+#include "hcid.h" /* For main_opts */
+#include "adapter.h"
+#include "manager.h"
+#include "device.h" /* Needed for storage.h */
+#include "storage.h"
+#include "log.h"
+
+#ifdef HAVE_SYS_INOTIFY_H
+#include <sys/inotify.h>
+#define EVENT_SIZE  (sizeof (struct inotify_event))
+#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))
+#endif
+
+#define MACHINE_INFO_DIR "/etc/"
+#define MACHINE_INFO_FILE "machine-info"
+
+#ifdef HAVE_SYS_INOTIFY_H
+static GIOChannel *inotify = NULL;
+static int watch_fd = -1;
+#endif
+
+/* This file is part of systemd's hostnamed functionality:
+ * http://0pointer.de/public/systemd-man/machine-info.html
+ * http://www.freedesktop.org/wiki/Software/systemd/hostnamed
+ */
+static char *read_pretty_host_name (void)
+{
+	char *contents, *ret;
+	char **lines;
+	guint i;
+
+	ret = NULL;
+
+	if (g_file_get_contents(MACHINE_INFO_DIR MACHINE_INFO_FILE,
+			&contents, NULL, NULL) == FALSE) {
+		return NULL;
+	}
+	lines = g_strsplit_set(contents, "\r\n", 0);
+	g_free(contents);
+
+	if (lines == NULL)
+		return NULL;
+
+	for (i = 0; lines[i] != NULL; i++) {
+		if (g_str_has_prefix(lines[i], "PRETTY_HOSTNAME=")) {
+			ret = g_strdup(lines[i] + strlen("PRETTY_HOSTNAME="));
+			break;
+		}
+	}
+
+	g_strfreev(lines);
+	return ret;
+}
+
+/*
+ * Device name expansion
+ *   %d - device id
+ *   %h - hostname
+ */
+static char *expand_name(char *dst, int size, char *str, int dev_id)
+{
+	register int sp, np, olen;
+	char *opt, buf[10];
+
+	if (!str || !dst)
+		return NULL;
+
+	sp = np = 0;
+	while (np < size - 1 && str[sp]) {
+		switch (str[sp]) {
+		case '%':
+			opt = NULL;
+
+			switch (str[sp+1]) {
+			case 'd':
+				sprintf(buf, "%d", dev_id);
+				opt = buf;
+				break;
+
+			case 'h':
+				opt = main_opts.host_name;
+				break;
+
+			case '%':
+				dst[np++] = str[sp++];
+				/* fall through */
+			default:
+				sp++;
+				continue;
+			}
+
+			if (opt) {
+				/* substitute */
+				olen = strlen(opt);
+				if (np + olen < size - 1)
+					memcpy(dst + np, opt, olen);
+				np += olen;
+			}
+			sp += 2;
+			continue;
+
+		case '\\':
+			sp++;
+			/* fall through */
+		default:
+			dst[np++] = str[sp++];
+			break;
+		}
+	}
+	dst[np] = '\0';
+	return dst;
+}
+
+static int adaptername_probe(struct btd_adapter *adapter)
+{
+	int current_id;
+	char name[MAX_NAME_LENGTH + 1];
+	char *pretty_hostname;
+	bdaddr_t bdaddr;
+
+	current_id = adapter_get_dev_id(adapter);
+
+	pretty_hostname = read_pretty_host_name();
+	if (pretty_hostname != NULL) {
+		int default_adapter;
+
+		default_adapter = manager_get_default_adapter();
+
+		if (default_adapter != current_id) {
+			char *str;
+
+			/* +1 because we don't want an adapter called "Foobar's laptop #0" */
+			str = g_strdup_printf ("%s #%d", pretty_hostname, current_id + 1);
+			DBG("Setting name '%s' for device 'hci%d'", str, current_id);
+
+			adapter_update_local_name(adapter, str);
+			g_free(str);
+		} else {
+			DBG("Setting name '%s' for device 'hci%d'", pretty_hostname, current_id);
+			adapter_update_local_name(adapter, pretty_hostname);
+		}
+		g_free(pretty_hostname);
+
+		return 0;
+	}
+
+	adapter_get_address(adapter, &bdaddr);
+
+	if (read_local_name(&bdaddr, name) < 0) {
+		expand_name(name, MAX_NAME_LENGTH, main_opts.name,
+							current_id);
+	}
+	DBG("Setting name '%s' for device 'hci%d'", name, current_id);
+	adapter_update_local_name(adapter, name);
+
+	return 0;
+}
+
+static gboolean handle_inotify_cb(GIOChannel *channel,
+		GIOCondition condition, gpointer data)
+{
+	char buf[EVENT_BUF_LEN];
+	GIOStatus err;
+	gsize len, i;
+	gboolean changed;
+
+	changed = FALSE;
+
+	err = g_io_channel_read_chars(channel, buf, EVENT_BUF_LEN, &len, NULL);
+	if (err != G_IO_STATUS_NORMAL) {
+		error("Error reading inotify event: %d\n", err);
+		return FALSE;
+	}
+
+	i = 0;
+	while (i < len) {
+		struct inotify_event *pevent = (struct inotify_event *) & buf[i];
+
+		/* check that it's ours */
+		if (pevent->len &&
+		    pevent->name != NULL &&
+		    strcmp(pevent->name, MACHINE_INFO_FILE) == 0) {
+			changed = TRUE;
+		}
+		i += EVENT_SIZE + pevent->len;
+	}
+
+	if (changed != FALSE) {
+		DBG(MACHINE_INFO_DIR MACHINE_INFO_FILE
+				" changed, changing names for adapters");
+		manager_foreach_adapter ((adapter_cb) adaptername_probe, NULL);
+	}
+
+	return TRUE;
+}
+
+static void adaptername_remove(struct btd_adapter *adapter)
+{
+#ifdef HAVE_SYS_INOTIFY_H
+	if (watch_fd >= 0)
+		close (watch_fd);
+	if (inotify != NULL)
+		g_io_channel_shutdown(inotify, FALSE, NULL);
+#endif /* HAVE_SYS_INOTIFY_H */
+}
+
+static struct btd_adapter_driver adaptername_driver = {
+	.name	= "adaptername",
+	.probe	= adaptername_probe,
+	.remove	= adaptername_remove,
+};
+
+static int adaptername_init(void)
+{
+	int ret;
+
+	ret = btd_register_adapter_driver(&adaptername_driver);
+#ifdef HAVE_SYS_INOTIFY_H
+	if (ret == 0) {
+		int inot_fd;
+
+		inot_fd = inotify_init();
+		if (inot_fd < 0) {
+			error("Failed to setup inotify");
+			return 0;
+		}
+		watch_fd = inotify_add_watch(inot_fd,
+				MACHINE_INFO_DIR,
+				IN_CLOSE_WRITE | IN_DELETE | IN_CREATE);
+		if (watch_fd < 0) {
+			error("Failed to setup watch for '%s'",
+					MACHINE_INFO_DIR);
+			return 0;
+		}
+
+		inotify = g_io_channel_unix_new(inot_fd);
+		g_io_channel_set_close_on_unref(inotify, TRUE);
+		g_io_channel_set_encoding (inotify, NULL, NULL);
+		  g_io_channel_set_flags (inotify, G_IO_FLAG_NONBLOCK, NULL);
+		g_io_add_watch(inotify, G_IO_IN, handle_inotify_cb, NULL);
+
+		return 0;
+	}
+#endif /* HAVE_SYS_INOTIFY_H */
+	return ret;
+}
+
+static void adaptername_exit(void)
+{
+	btd_unregister_adapter_driver(&adaptername_driver);
+}
+
+BLUETOOTH_PLUGIN_DEFINE(adaptername, VERSION,
+		BLUETOOTH_PLUGIN_PRIORITY_LOW, adaptername_init, adaptername_exit)
diff --git a/src/adapter.c b/src/adapter.c
index 76fc01b..09bbf06 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -181,64 +181,6 @@ static void dev_info_free(struct remote_dev_info *dev)
 	g_free(dev);
 }
 
-/*
- * Device name expansion
- *   %d - device id
- */
-static char *expand_name(char *dst, int size, char *str, int dev_id)
-{
-	register int sp, np, olen;
-	char *opt, buf[10];
-
-	if (!str || !dst)
-		return NULL;
-
-	sp = np = 0;
-	while (np < size - 1 && str[sp]) {
-		switch (str[sp]) {
-		case '%':
-			opt = NULL;
-
-			switch (str[sp+1]) {
-			case 'd':
-				sprintf(buf, "%d", dev_id);
-				opt = buf;
-				break;
-
-			case 'h':
-				opt = main_opts.host_name;
-				break;
-
-			case '%':
-				dst[np++] = str[sp++];
-				/* fall through */
-			default:
-				sp++;
-				continue;
-			}
-
-			if (opt) {
-				/* substitute */
-				olen = strlen(opt);
-				if (np + olen < size - 1)
-					memcpy(dst + np, opt, olen);
-				np += olen;
-			}
-			sp += 2;
-			continue;
-
-		case '\\':
-			sp++;
-			/* fall through */
-		default:
-			dst[np++] = str[sp++];
-			break;
-		}
-	}
-	dst[np] = '\0';
-	return dst;
-}
-
 int btd_adapter_set_class(struct btd_adapter *adapter, uint8_t major,
 								uint8_t minor)
 {
@@ -915,10 +857,10 @@ void btd_adapter_class_changed(struct btd_adapter *adapter, uint32_t new_class)
 				DBUS_TYPE_UINT32, &new_class);
 }
 
-void adapter_update_local_name(struct btd_adapter *adapter, const char *name)
+int adapter_update_local_name(struct btd_adapter *adapter, const char *name)
 {
 	if (strncmp(name, adapter->name, MAX_NAME_LENGTH) == 0)
-		return;
+		return 0;
 
 	strncpy(adapter->name, name, MAX_NAME_LENGTH);
 
@@ -937,38 +879,29 @@ void adapter_update_local_name(struct btd_adapter *adapter, const char *name)
 						DBUS_TYPE_STRING, &name_ptr);
 	}
 
+	if (adapter->up) {
+		int err = adapter_ops->set_name(adapter->dev_id, name);
+		if (err < 0)
+			return -err;
+
+		adapter->name_stored = TRUE;
+	}
+
 	adapter->name_stored = FALSE;
+
+	return 0;
 }
 
 static DBusMessage *set_name(DBusConnection *conn, DBusMessage *msg,
 					const char *name, void *data)
 {
 	struct btd_adapter *adapter = data;
-	char *name_ptr = adapter->name;
-
-	if (!g_utf8_validate(name, -1, NULL)) {
-		error("Name change failed: supplied name isn't valid UTF-8");
-		return btd_error_invalid_args(msg);
-	}
-
-	if (strncmp(name, adapter->name, MAX_NAME_LENGTH) == 0)
-		goto done;
-
-	strncpy(adapter->name, name, MAX_NAME_LENGTH);
-	write_local_name(&adapter->bdaddr, name);
-	emit_property_changed(connection, adapter->path,
-					ADAPTER_INTERFACE, "Name",
-					DBUS_TYPE_STRING, &name_ptr);
-
-	if (adapter->up) {
-		int err = adapter_ops->set_name(adapter->dev_id, name);
-		if (err < 0)
-			return btd_error_failed(msg, strerror(-err));
+	int err;
 
-		adapter->name_stored = TRUE;
-	}
+	err = adapter_update_local_name (adapter, name);
+	if (err < 0)
+		return btd_error_failed(msg, strerror(err));
 
-done:
 	return dbus_message_new_method_return(msg);
 }
 
@@ -2580,14 +2513,6 @@ gboolean adapter_init(struct btd_adapter *adapter)
 		return FALSE;
 	}
 
-	if (read_local_name(&adapter->bdaddr, adapter->name) < 0)
-		expand_name(adapter->name, MAX_NAME_LENGTH, main_opts.name,
-							adapter->dev_id);
-
-	if (main_opts.attrib_server)
-		attrib_gap_set(GATT_CHARAC_DEVICE_NAME,
-			(const uint8_t *) adapter->name, strlen(adapter->name));
-
 	sdp_init_services_list(&adapter->bdaddr);
 	load_drivers(adapter);
 	clear_blocked(adapter);
diff --git a/src/adapter.h b/src/adapter.h
index 9406b9b..8635400 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -127,7 +127,7 @@ int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr);
 void adapter_emit_device_found(struct btd_adapter *adapter,
 						struct remote_dev_info *dev);
 void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode);
-void adapter_update_local_name(struct btd_adapter *adapter, const char *name);
+int adapter_update_local_name(struct btd_adapter *adapter, const char *name);
 void adapter_service_insert(struct btd_adapter *adapter, void *rec);
 void adapter_service_remove(struct btd_adapter *adapter, void *rec);
 void btd_adapter_class_changed(struct btd_adapter *adapter,
diff --git a/src/manager.c b/src/manager.c
index e805e0c..dedec8b 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -288,6 +288,11 @@ static void manager_remove_adapter(struct btd_adapter *adapter)
 		btd_start_exit_timer();
 }
 
+int manager_get_default_adapter (void)
+{
+	return default_adapter_id;
+}
+
 void manager_cleanup(DBusConnection *conn, const char *path)
 {
 	g_slist_foreach(adapters, (GFunc) manager_remove_adapter, NULL);
diff --git a/src/manager.h b/src/manager.h
index 05c38b3..90d3690 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -41,3 +41,4 @@ struct btd_adapter *btd_manager_register_adapter(int id);
 int btd_manager_unregister_adapter(int id);
 void manager_add_adapter(const char *path);
 void btd_manager_set_did(uint16_t vendor, uint16_t product, uint16_t version);
+int manager_get_default_adapter (void);
-- 
1.7.5.1


^ permalink raw reply related

* Fwd: HCI data payload not getting through when using BlueZ
From: Eponymous - @ 2011-05-13 12:42 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <BANLkTi=H-iEn_oAMb1bwJk6KEAueHRMVtQ@mail.gmail.com>

The following were executed in a root shell.

Receive Side (Device B):

$ ./l2test -r 00:02:5B:00:31:21
l2test[29219]: Waiting for connection on psm 4113 ...

Transmit Side (Device A):

$ ./l2test -s -b 10 00:02:5B:01:FE:DF
l2test[29234]: Can't connect: Permission denied (13)
$ ./l2test -s -b 10 00:02:5B:01:FE:DF
l2test[29311]: Can't connect: Connection refused (111)
$ ./l2test -s -b 10 00:02:5B:01:FE:DF
l2test[29326]: Can't connect: Connection refused (111)
$ ./l2test -s -b 10 00:02:5B:01:FE:DF
l2test[29401]: Can't connect: Permission denied (13)
$ ./l2test -s -b 10 00:02:5B:01:FE:DF
l2test[29478]: Can't connect: Connection refused (111)
$ ./l2test -s -b 10 00:02:5B:01:FE:DF
l2test[29493]: Can't connect: Connection refused (111)

Doesn't appear to work...

On Fri, May 13, 2011 at 9:39 AM, Eponymous - <the.epon@gmail.com> wrote:
> What format do you specify the bdaddr in ?
>
> Cheers.
>
> On Fri, May 13, 2011 at 9:26 AM, Mika Linnanoja
> <mika.linnanoja@nokia.com> wrote:
>> On 05/13/2011 11:13 AM, ext Suraj Sumangala wrote:
>>>
>>> You have to enable it in the cofigure file and change "test_enable" from
>>> "no" to "yes".
>>> Edit the file "configure", search for "test_enable"
>>> change "test_enable=no" to "test_enable=yes"
>>>
>>> That is what I do to enable l2test. I guess there could be some other
>>> cleaner way to do it.
>>
>> ./configure --help :)
>>
>> If you pull from the git repo ./bootstrap-configure already enables most of
>> them.
>>
>> Although lately configure is often *not* complaining if something is missing
>> from build dependencies, have to do a bit of trial & error to get it right.
>>
>> This is very easy to notice when trying to 'make' bluez on a clean system
>> where it hasn't ever been built before.
>>
>> Cheers,
>> Mika
>>
>

^ permalink raw reply

* Re: HCI data payload not getting through when using BlueZ
From: Mika Linnanoja @ 2011-05-13  8:26 UTC (permalink / raw)
  To: ext Suraj Sumangala; +Cc: Eponymous -, linux-bluetooth@vger.kernel.org
In-Reply-To: <44EE5C37ADC36343B0625A05DD408C48517CE84134@CHEXMB-01.global.atheros.com>

On 05/13/2011 11:13 AM, ext Suraj Sumangala wrote:
> You have to enable it in the cofigure file and change "test_enable" from "no" to "yes".
> Edit the file "configure", search for "test_enable"
> change "test_enable=no" to "test_enable=yes"
>
> That is what I do to enable l2test. I guess there could be some other cleaner way to do it.

./configure --help :)

If you pull from the git repo ./bootstrap-configure already enables most of them.

Although lately configure is often *not* complaining if something is missing 
from build dependencies, have to do a bit of trial & error to get it right.

This is very easy to notice when trying to 'make' bluez on a clean system 
where it hasn't ever been built before.

Cheers,
Mika

^ permalink raw reply

* RE: HCI data payload not getting through when using BlueZ
From: Suraj Sumangala @ 2011-05-13  8:13 UTC (permalink / raw)
  To: Eponymous -, linux-bluetooth@vger.kernel.org
In-Reply-To: <BANLkTi=t-0QPSV4ZOqCA=OMZaGRhcga+FA@mail.gmail.com>

Hi,
________________________________________
From: linux-bluetooth-owner@vger.kernel.org [linux-bluetooth-owner@vger.kernel.org] On Behalf Of Eponymous - [the.epon@gmail.com]
Sent: Friday, May 13, 2011 1:24 PM
To: Eponymous -; linux-bluetooth@vger.kernel.org
Subject: Re: HCI data payload not getting through when using BlueZ

Can someone please advise me further on this please? There is no
binary called "l2test" in the 4.91 sources. It's crucial I get this
problem remedied as I can't send data between two HCI devices. This
could be a bug in BlueZ...


On Thu, May 12, 2011 at 11:19 AM, Eponymous - <the.epon@gmail.com> wrote:
> Hi,
>
> I've just downloaded the 4.91 sources and done a make and the only
> program I can see starting "l2" is "l2ping". There is no l2test.
>
>
> On Wed, May 11, 2011 at 5:47 PM, Gustavo F. Padovan
> <padovan@profusion.mobi> wrote:
>> * Eponymous - <the.epon@gmail.com> [2011-05-11 09:52:28 +0100]:
>>
>>> Hi,
>>>
>>> I've ran into an issue where data doesn't seem to be received by a slave device.
>>>
>>> I do the following:
>>>
>>> Using Gentoo Linux (2.6.34-gentoo-r1)
>>> Using BlueZ 4.81
>>>
>>> 1. Use BlueZ to connect to two Bluetooth devices using HCI only. This
>>> is over USB.
>>>
>>> 2. I set one device as a slave and then create a connection between
>>> the two. This completes sucessfully and can be seen on both sides.
>>>
>>> 3. I then try to send an acl packet with the word "hi" in it and it is
>>> not received on the other side.
>>
>> There a utility called l2test in the bluez sources. Check if it works for you.
>> Using -r in one side to listen and -s in the other side to send data. Or
>> l2test -h and see all options.
>>
>> --
>> Gustavo F. Padovan
>> http://profusion.mobi
>>
>

You have to enable it in the cofigure file and change "test_enable" from "no" to "yes".
Edit the file "configure", search for "test_enable"
change "test_enable=no" to "test_enable=yes"

That is what I do to enable l2test. I guess there could be some other cleaner way to do it.

Regards
Suraj
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: HCI data payload not getting through when using BlueZ
From: Eponymous - @ 2011-05-13  7:54 UTC (permalink / raw)
  To: Eponymous -, linux-bluetooth
In-Reply-To: <BANLkTimFMZ+ohvJsmD9NV7WqFqtX1W4yXw@mail.gmail.com>

Can someone please advise me further on this please? There is no
binary called "l2test" in the 4.91 sources. It's crucial I get this
problem remedied as I can't send data between two HCI devices. This
could be a bug in BlueZ...


On Thu, May 12, 2011 at 11:19 AM, Eponymous - <the.epon@gmail.com> wrote:
> Hi,
>
> I've just downloaded the 4.91 sources and done a make and the only
> program I can see starting "l2" is "l2ping". There is no l2test.
>
>
> On Wed, May 11, 2011 at 5:47 PM, Gustavo F. Padovan
> <padovan@profusion.mobi> wrote:
>> * Eponymous - <the.epon@gmail.com> [2011-05-11 09:52:28 +0100]:
>>
>>> Hi,
>>>
>>> I've ran into an issue where data doesn't seem to be received by a slave device.
>>>
>>> I do the following:
>>>
>>> Using Gentoo Linux (2.6.34-gentoo-r1)
>>> Using BlueZ 4.81
>>>
>>> 1. Use BlueZ to connect to two Bluetooth devices using HCI only. This
>>> is over USB.
>>>
>>> 2. I set one device as a slave and then create a connection between
>>> the two. This completes sucessfully and can be seen on both sides.
>>>
>>> 3. I then try to send an acl packet with the word "hi" in it and it is
>>> not received on the other side.
>>
>> There a utility called l2test in the bluez sources. Check if it works for you.
>> Using -r in one side to listen and -s in the other side to send data. Or
>> l2test -h and see all options.
>>
>> --
>> Gustavo F. Padovan
>> http://profusion.mobi
>>
>

^ permalink raw reply

* [PATCH v3] Bluetooth: Allow unsegmented SDU retries on sock_queue_rcv_skb failure.
From: Ruiyi Zhang @ 2011-05-13  5:07 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo F. Padovan, Ruiyi Zhang
In-Reply-To: <20110511175555.GE22065@joana>

In L2CAP_SDU_UNSEGMENTED case, if sock_queue_rcv_skb returns error,
l2cap_ertm_reassembly_sdu should not return 0 so as to insert the
skb into BUSY_QUEUE for later retries.

Signed-off-by: Ruiyi Zhang <Ruiyi.Zhang@Atheros.com>
---
 net/bluetooth/l2cap_core.c |    6 +-----
 1 files changed, 1 insertions(+), 5 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index a5ab4a2..a99e5d7 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2928,11 +2928,7 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk
 		if (chan->conn_state & L2CAP_CONN_SAR_SDU)
 			goto drop;
 
-		err = sock_queue_rcv_skb(chan->sk, skb);
-		if (!err)
-			return err;
-
-		break;
+		return sock_queue_rcv_skb(chan->sk, skb);
 
 	case L2CAP_SDU_START:
 		if (chan->conn_state & L2CAP_CONN_SAR_SDU)
-- 
1.7.1


^ permalink raw reply related

* [PATCH 6/9] Bluetooth: Silence DEBUG_STRICT_USER_COPY_CHECKS=y warning
From: Stephen Boyd @ 2011-05-12 23:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: linux-kernel, netdev, Marcel Holtmann, Gustavo F. Padovan
In-Reply-To: <1305244212-19183-1-git-send-email-sboyd@codeaurora.org>

Enabling DEBUG_STRICT_USER_COPY_CHECKS causes the following
warning:

In function 'copy_from_user',
    inlined from 'rfcomm_sock_setsockopt' at
    net/bluetooth/rfcomm/sock.c:705:
arch/x86/include/asm/uaccess_64.h:65:
warning: call to 'copy_from_user_overflow' declared with
attribute warning: copy_from_user() buffer size is not provably
correct

presumably due to buf_size being signed causing GCC to fail to
see that buf_size can't become negative.

Cc: Marcel Holtmann <marcel@holtmann.org>
Cc: Gustavo F. Padovan <padovan@profusion.mobi>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 net/bluetooth/rfcomm/sock.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 66cc1f0..0698b37 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -679,7 +679,8 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
 {
 	struct sock *sk = sock->sk;
 	struct bt_security sec;
-	int len, err = 0;
+	int err = 0;
+	size_t len;
 	u32 opt;
 
 	BT_DBG("sk %p", sk);
-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply related

* best supported usb bluetooth module
From: Fabio Varesano @ 2011-05-12 23:07 UTC (permalink / raw)
  To: linux-bluetooth

Hi everyone,

I have the need to get a *perfectly* Linux supported USB bluetooth
module. Any suggestions?

Thank you,

Fabio Varesano

^ permalink raw reply

* Re: [PATCH v2 02/13] Add Bluetooth address type definition
From: Marcel Holtmann @ 2011-05-12 19:10 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: Johan Hedberg, linux-bluetooth
In-Reply-To: <BANLkTims0=RKEBMaSgG-Mw5RfUJKrWtR=A@mail.gmail.com>

Hi Claudio,

> >> > Values defined to LE(public and random) are defined in the Bluetooth
> >> > Core Specification. For basic rate, there isn't address type concept.
> >> > The constants introduced by this commit will be used to identify the
> >> > remote address type, basically to distinguish LE/BR devices before
> >> > to request the L2CAP connection.
> >> > ---
> >> >  lib/bluetooth.h |    4 ++++
> >> >  1 files changed, 4 insertions(+), 0 deletions(-)
> >> >
> >> > diff --git a/lib/bluetooth.h b/lib/bluetooth.h
> >> > index 738e07a..98b8f1c 100644
> >> > --- a/lib/bluetooth.h
> >> > +++ b/lib/bluetooth.h
> >> > @@ -130,6 +130,10 @@ typedef struct {
> >> >  #define BDADDR_ALL   (&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}})
> >> >  #define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
> >> >
> >> > +#define BDADDR_TYPE_LE_PUBLIC      0x00
> >> > +#define BRADDR_TYPE_LE_RANDOM      0x01
> >> > +#define BDADDR_TYPE_BR             0xff
> >>
> >> Firstly this still needs Marcel's blessing (though I don't really see
> >> any other solution than an address type with three possible values).
> >> Secondly, if this is ever going to be added to the L2CAP socket address
> >> you'd have to have 0x00 as BDADDR_TYPE_BR for backwards compatibility.
> >
> > I am still not 100% convinced, but yes, the default 0x00 then needs to
> > be BDADDR_TYPE_BREDR. Otherwise we break APIs.
>
> Use the kernel advertising cache(for address type) plus a device
> type(LE or BR) field in the mgmt_ev_device_found is another approach.
> Can we proceed with this approach?

lets go with the advertising cache for now. That way we do not have to
worry about potential kernel API/ABI breakage.

We will see how LE devices will evolve and then we know what needs to be
done once the first once hit the market.

Regards

Marcel



^ permalink raw reply

* Re: Bluetooth: l2cap and rfcomm: fix 1 byte infoleak to userspace.
From: Marcel Holtmann @ 2011-05-12 19:08 UTC (permalink / raw)
  To: Filip Palian; +Cc: Gustavo F. Padovan, David S. Miller, linux-bluetooth
In-Reply-To: <20110512173246.GC11166@backtrack>

Hi Filip,

> Structures "l2cap_conninfo" and "rfcomm_conninfo" have one padding
> byte each. This byte in "cinfo" is copied to userspace uninitialized.
> 
> Signed-off-by: Filip Palian <filip.palian@pjwstk.edu.pl>

Acked-by: Marcel Holtmann <marcel@holtmann.org>

Regards

Marcel



^ permalink raw reply

* Re: [PATCH 3/6] Bluetooth: Add chan->link_type struct member
From: Marcel Holtmann @ 2011-05-12 19:07 UTC (permalink / raw)
  To: Gustavo F. Padovan; +Cc: linux-bluetooth
In-Reply-To: <1305178350-7568-3-git-send-email-padovan@profusion.mobi>

Hi Gustavo,

> link_type says if our link is raw, connection less or connection oriented.
> 
> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
> ---
>  include/net/bluetooth/l2cap.h |    5 +++++
>  net/bluetooth/l2cap_core.c    |   30 +++++++++++-------------------
>  net/bluetooth/l2cap_sock.c    |   30 +++++++++++++++++++++++-------
>  3 files changed, 39 insertions(+), 26 deletions(-)
> 
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index dc721ca..6915c43 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -295,6 +295,7 @@ struct l2cap_chan {
>  	__u16		omtu;
>  	__u16		flush_to;
>  	__u8		mode;
> +	__u8		link_type;
>  
>  	__le16		sport;
>  
> @@ -384,6 +385,10 @@ struct l2cap_conn {
>  #define L2CAP_INFO_FEAT_MASK_REQ_SENT	0x04
>  #define L2CAP_INFO_FEAT_MASK_REQ_DONE	0x08
>  
> +#define L2CAP_LINK_RAW		1
> +#define L2CAP_LINK_CONNLESS	2
> +#define L2CAP_LINK_ORIENTED	3
> +

the name ORIENTED is a pretty bad name. Use CONN_ORIENTED and CONN_LESS
to make this more clear. And use CONN_LESS instead of CONNLESS to have
this in sync with other constants we have.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH 2/6] Bluetooth: Create l2cap_chan_send()
From: Anderson Lizardo @ 2011-05-12 18:16 UTC (permalink / raw)
  To: Gustavo F. Padovan; +Cc: linux-bluetooth
In-Reply-To: <1305178350-7568-2-git-send-email-padovan@profusion.mobi>

Hi Gustavo,

On Thu, May 12, 2011 at 1:32 AM, Gustavo F. Padovan
<padovan@profusion.mobi> wrote:
> +               } else {
> +               /* Segment SDU into multiples PDUs */

Given that you are moving code around, can you fix the indentation
error on the comment above?

> +                       err = l2cap_sar_segment_sdu(chan, msg, len);
> +                       if (err < 0)
> +                               return err;
> +               }
> +
> +               if (chan->mode == L2CAP_MODE_STREAMING) {
> +                       l2cap_streaming_send(chan);
> +                       err = len;
> +                       break;
> +               }
> +
> +               if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
> +                               (chan->conn_state & L2CAP_CONN_WAIT_F)) {
> +                       err = len;
> +                       break;
> +               }
> +               err = l2cap_ertm_send(chan);
> +
> +               if (err >= 0)
> +                       err = len;
> +               break;

Also, it makes more sense to have an empty line above
l2cap_ertm_send(), and remove the empty line below it.

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply

* Re: [PATCH 3/6] Bluetooth: Add chan->link_type struct member
From: Anderson Lizardo @ 2011-05-12 17:58 UTC (permalink / raw)
  To: Gustavo F. Padovan; +Cc: linux-bluetooth
In-Reply-To: <1305178350-7568-3-git-send-email-padovan@profusion.mobi>

Hi Gustavo,

On Thu, May 12, 2011 at 1:32 AM, Gustavo F. Padovan
<padovan@profusion.mobi> wrote:
> @@ -204,8 +204,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
>        }
>
>        /* PSM must be odd and lsb of upper byte must be 0 */
> -       if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 &&
> -                               sk->sk_type != SOCK_RAW && !la.l2_cid) {
> +       if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 && !la.l2_cid &&
> +                                       chan->link_type == L2CAP_LINK_RAW) {

There seems to be a typo here:

Original: sk->sk_type != SOCK_RAW
New: chan->link_type == L2CAP_LINK_RAW

Should it be != instead?

>                err = -EINVAL;
>                goto done;
>        }

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply

* Re: [PATCH v2 02/13] Add Bluetooth address type definition
From: Claudio Takahasi @ 2011-05-12 17:55 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Johan Hedberg, linux-bluetooth
In-Reply-To: <1305163228.15916.163.camel@aeonflux>

Hi Marcel/Johan,

On Wed, May 11, 2011 at 10:20 PM, Marcel Holtmann <marcel@holtmann.org> wro=
te:
> Hi Johan,
>
>> > Values defined to LE(public and random) are defined in the Bluetooth
>> > Core Specification. For basic rate, there isn't address type concept.
>> > The constants introduced by this commit will be used to identify the
>> > remote address type, basically to distinguish LE/BR devices before
>> > to request the L2CAP connection.
>> > ---
>> > =C2=A0lib/bluetooth.h | =C2=A0 =C2=A04 ++++
>> > =C2=A01 files changed, 4 insertions(+), 0 deletions(-)
>> >
>> > diff --git a/lib/bluetooth.h b/lib/bluetooth.h
>> > index 738e07a..98b8f1c 100644
>> > --- a/lib/bluetooth.h
>> > +++ b/lib/bluetooth.h
>> > @@ -130,6 +130,10 @@ typedef struct {
>> > =C2=A0#define BDADDR_ALL =C2=A0 (&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff,=
 0xff, 0xff}})
>> > =C2=A0#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
>> >
>> > +#define BDADDR_TYPE_LE_PUBLIC =C2=A0 =C2=A0 =C2=A00x00
>> > +#define BRADDR_TYPE_LE_RANDOM =C2=A0 =C2=A0 =C2=A00x01
>> > +#define BDADDR_TYPE_BR =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0xff
>>
>> Firstly this still needs Marcel's blessing (though I don't really see
>> any other solution than an address type with three possible values).
>> Secondly, if this is ever going to be added to the L2CAP socket address
>> you'd have to have 0x00 as BDADDR_TYPE_BR for backwards compatibility.
>
> I am still not 100% convinced, but yes, the default 0x00 then needs to
> be BDADDR_TYPE_BREDR. Otherwise we break APIs.
>
> Regards
>
> Marcel

Use the kernel advertising cache(for address type) plus a device
type(LE or BR) field in the mgmt_ev_device_found is another approach.
Can we proceed with this approach?

Claudio.

^ permalink raw reply

* Re: [PATCH 3/6] Bluetooth: Add chan->link_type struct member
From: Vinicius Costa Gomes @ 2011-05-12 17:37 UTC (permalink / raw)
  To: Gustavo F. Padovan; +Cc: linux-bluetooth
In-Reply-To: <1305178350-7568-3-git-send-email-padovan@profusion.mobi>

Hi Gustavo,

On 02:32 Thu 12 May, Gustavo F. Padovan wrote:
> link_type says if our link is raw, connection less or connection oriented.

To avoid confusion with the hci_conn "type" field (which is the actual type
of the link between those two devices), wouldn't it be better to rename this
to chan_type or something like it?

> 
> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
> ---
>  include/net/bluetooth/l2cap.h |    5 +++++
>  net/bluetooth/l2cap_core.c    |   30 +++++++++++-------------------
>  net/bluetooth/l2cap_sock.c    |   30 +++++++++++++++++++++++-------
>  3 files changed, 39 insertions(+), 26 deletions(-)
> 
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index dc721ca..6915c43 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -295,6 +295,7 @@ struct l2cap_chan {
>  	__u16		omtu;
>  	__u16		flush_to;
>  	__u8		mode;
> +	__u8		link_type;
>  
>  	__le16		sport;
>  
> @@ -384,6 +385,10 @@ struct l2cap_conn {
>  #define L2CAP_INFO_FEAT_MASK_REQ_SENT	0x04
>  #define L2CAP_INFO_FEAT_MASK_REQ_DONE	0x08
>  
> +#define L2CAP_LINK_RAW		1
> +#define L2CAP_LINK_CONNLESS	2
> +#define L2CAP_LINK_ORIENTED	3
> +
>  /* ----- L2CAP socket info ----- */
>  #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
>  
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index 5473fc9..e1731b9 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -245,7 +245,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
>  
>  	chan->conn = conn;
>  
> -	if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
> +	if (chan->link_type == L2CAP_LINK_ORIENTED) {
>  		if (conn->hcon->type == LE_LINK) {
>  			/* LE connection */
>  			chan->omtu = L2CAP_LE_DEFAULT_MTU;
> @@ -256,7 +256,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
>  			chan->scid = l2cap_alloc_cid(conn);
>  			chan->omtu = L2CAP_DEFAULT_MTU;
>  		}
> -	} else if (sk->sk_type == SOCK_DGRAM) {
> +	} else if (chan->link_type == L2CAP_LINK_CONNLESS) {
>  		/* Connectionless socket */
>  		chan->scid = L2CAP_CID_CONN_LESS;
>  		chan->dcid = L2CAP_CID_CONN_LESS;
> @@ -369,8 +369,7 @@ void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
>  
>  	case BT_CONNECTED:
>  	case BT_CONFIG:
> -		if ((sk->sk_type == SOCK_SEQPACKET ||
> -					sk->sk_type == SOCK_STREAM) &&
> +		if (chan->link_type == L2CAP_LINK_ORIENTED &&
>  					conn->hcon->type == ACL_LINK) {
>  			l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
>  			l2cap_send_disconn_req(conn, chan, reason);
> @@ -379,8 +378,7 @@ void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
>  		break;
>  
>  	case BT_CONNECT2:
> -		if ((sk->sk_type == SOCK_SEQPACKET ||
> -					sk->sk_type == SOCK_STREAM) &&
> +		if (chan->link_type == L2CAP_LINK_ORIENTED &&
>  					conn->hcon->type == ACL_LINK) {
>  			struct l2cap_conn_rsp rsp;
>  			__u16 result;
> @@ -414,9 +412,7 @@ void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
>  
>  static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
>  {
> -	struct sock *sk = chan->sk;
> -
> -	if (sk->sk_type == SOCK_RAW) {
> +	if (chan->link_type == L2CAP_LINK_RAW) {
>  		switch (chan->sec_level) {
>  		case BT_SECURITY_HIGH:
>  			return HCI_AT_DEDICATED_BONDING_MITM;
> @@ -657,8 +653,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
>  
>  		bh_lock_sock(sk);
>  
> -		if (sk->sk_type != SOCK_SEQPACKET &&
> -				sk->sk_type != SOCK_STREAM) {
> +		if (chan->link_type != L2CAP_LINK_ORIENTED) {
>  			bh_unlock_sock(sk);
>  			continue;
>  		}
> @@ -852,8 +847,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
>  			sk->sk_state_change(sk);
>  		}
>  
> -		if (sk->sk_type != SOCK_SEQPACKET &&
> -				sk->sk_type != SOCK_STREAM) {
> +		if (chan->link_type != L2CAP_LINK_ORIENTED) {
>  			l2cap_sock_clear_timer(sk);
>  			sk->sk_state = BT_CONNECTED;
>  			sk->sk_state_change(sk);
> @@ -1056,8 +1050,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan)
>  	l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
>  
>  	if (hcon->state == BT_CONNECTED) {
> -		if (sk->sk_type != SOCK_SEQPACKET &&
> -				sk->sk_type != SOCK_STREAM) {
> +		if (chan->link_type != L2CAP_LINK_ORIENTED) {
>  			l2cap_sock_clear_timer(sk);
>  			if (l2cap_check_security(chan))
>  				sk->sk_state = BT_CONNECTED;
> @@ -1537,13 +1530,12 @@ int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t le
>  
>  int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
>  {
> -	struct sock *sk = chan->sk;
>  	struct sk_buff *skb;
>  	u16 control;
>  	int err;
>  
>  	/* Connectionless channel */
> -	if (sk->sk_type == SOCK_DGRAM) {
> +	if (chan->link_type == L2CAP_LINK_CONNLESS) {
>  		skb = l2cap_create_connless_pdu(chan, msg, len);
>  		if (IS_ERR(skb))
>  			return PTR_ERR(skb);
> @@ -1649,7 +1641,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
>  	read_lock(&conn->chan_lock);
>  	list_for_each_entry(chan, &conn->chan_l, list) {
>  		struct sock *sk = chan->sk;
> -		if (sk->sk_type != SOCK_RAW)
> +		if (chan->link_type != L2CAP_LINK_RAW)
>  			continue;
>  
>  		/* Don't send frame to the socket it came from */
> @@ -4105,7 +4097,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
>  {
>  	struct sock *sk = chan->sk;
>  
> -	if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
> +	if (chan->link_type != L2CAP_LINK_ORIENTED)
>  		return;
>  
>  	if (encrypt == 0x00) {
> diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
> index f36776e..6d5ecca 100644
> --- a/net/bluetooth/l2cap_sock.c
> +++ b/net/bluetooth/l2cap_sock.c
> @@ -162,7 +162,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
>  
>  	lock_sock(sk);
>  
> -	if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
> +	if (chan->link_type == L2CAP_LINK_ORIENTED
>  			&& !(la.l2_psm || la.l2_cid)) {
>  		err = -EINVAL;
>  		goto done;
> @@ -204,8 +204,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
>  	}
>  
>  	/* PSM must be odd and lsb of upper byte must be 0 */
> -	if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 &&
> -				sk->sk_type != SOCK_RAW && !la.l2_cid) {
> +	if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 && !la.l2_cid &&
> +					chan->link_type == L2CAP_LINK_RAW) {
>  		err = -EINVAL;
>  		goto done;
>  	}
> @@ -453,8 +453,8 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
>  
>  	switch (optname) {
>  	case BT_SECURITY:
> -		if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
> -				&& sk->sk_type != SOCK_RAW) {
> +		if (chan->link_type != L2CAP_LINK_ORIENTED &&
> +					chan->link_type != L2CAP_LINK_RAW) {
>  			err = -EINVAL;
>  			break;
>  		}
> @@ -599,8 +599,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
>  
>  	switch (optname) {
>  	case BT_SECURITY:
> -		if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
> -				&& sk->sk_type != SOCK_RAW) {
> +		if (chan->link_type != L2CAP_LINK_ORIENTED &&
> +					chan->link_type != L2CAP_LINK_RAW) {
>  			err = -EINVAL;
>  			break;
>  		}
> @@ -806,6 +806,7 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent)
>  		sk->sk_type = parent->sk_type;
>  		bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
>  
> +		chan->link_type = pchan->link_type;
>  		chan->imtu = pchan->imtu;
>  		chan->omtu = pchan->omtu;
>  		chan->conf_state = pchan->conf_state;
> @@ -818,6 +819,20 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent)
>  		chan->force_reliable = pchan->force_reliable;
>  		chan->flushable = pchan->flushable;
>  	} else {
> +
> +		switch (sk->sk_type) {
> +		case SOCK_RAW:
> +			chan->link_type = L2CAP_LINK_RAW;
> +			break;
> +		case SOCK_DGRAM:
> +			chan->link_type = L2CAP_LINK_CONNLESS;
> +			break;
> +		case SOCK_SEQPACKET:
> +		case SOCK_STREAM:
> +			chan->link_type = L2CAP_LINK_ORIENTED;
> +			break;
> +		}
> +
>  		chan->imtu = L2CAP_DEFAULT_MTU;
>  		chan->omtu = 0;
>  		if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
> @@ -826,6 +841,7 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent)
>  		} else {
>  			chan->mode = L2CAP_MODE_BASIC;
>  		}
> +

Nitpick, feel free to ignore ;-)

>  		chan->max_tx = L2CAP_DEFAULT_MAX_TX;
>  		chan->fcs  = L2CAP_FCS_CRC16;
>  		chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
> -- 
> 1.7.5.rc3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Cheers,
-- 
Vinicius

^ permalink raw reply

* Re: Bluetooth: l2cap and rfcomm: fix 1 byte infoleak to userspace.
From: Filip Palian @ 2011-05-12 17:32 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Gustavo F. Padovan, David S. Miller, linux-bluetooth
In-Reply-To: <1305163800.15916.169.camel@aeonflux>

Structures "l2cap_conninfo" and "rfcomm_conninfo" have one padding
byte each. This byte in "cinfo" is copied to userspace uninitialized.

Signed-off-by: Filip Palian <filip.palian@pjwstk.edu.pl>
---
 net/bluetooth/l2cap_sock.c  |    1 +
 net/bluetooth/rfcomm/sock.c |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 299fe56..581310f 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -446,6 +446,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
 			break;
 		}
 
+		memset(&cinfo, 0, sizeof(cinfo));
 		cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
 		memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
 
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 66cc1f0..784af0f 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -787,6 +787,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
 
 		l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk;
 
+		memset(&cinfo, 0, sizeof(cinfo));
 		cinfo.hci_handle = l2cap_pi(l2cap_sk)->conn->hcon->handle;
 		memcpy(cinfo.dev_class, l2cap_pi(l2cap_sk)->conn->hcon->dev_class, 3);
 
-- 
1.5.6.3

Found by Marek Kroemeke and Filip Palian. Special thanks to Vasiliy Kulikov for advices.

Best regards.

^ permalink raw reply related

* Re: [PATCH v6] staging: Add ST-Ericsson CG2900 driver
From: Greg KH @ 2011-05-12 16:54 UTC (permalink / raw)
  To: Par-Gunnar HJALMDAHL
  Cc: Greg Kroah-Hartman, devel@driverdev.osuosl.org, Linus Walleij,
	linux-kernel@vger.kernel.org, linux-bluetooth@vger.kernel.org,
	Pavan Savoy, Vitaly Wool, Alan Cox, Arnd Bergmann,
	Marcel Holtmann, Lukasz Rymanowski, Linus WALLEIJ,
	Par-Gunnar Hjalmdahl, Lee Jones, Mathieu Poirier
In-Reply-To: <AFCDDB4A3EA003429EEF1E7B211FDBBA3395A6DC72@EXDCVYMBSTM005.EQ1STM.local>

On Thu, May 12, 2011 at 01:54:46PM +0200, Par-Gunnar HJALMDAHL wrote:
> Hi Greg,
> 
> I downloaded you staging tree and compared the logs for the core.h file.
> Compared to linux-next tag next-20110510 it is missing 2 commits:
> 4dbee6b76fffd5740e87e286f4f4c1c15901bcae
> 558aa9c0d620b91a896d5e39ce8a570bed65589b
> where the first one is the "oldest" one in the log and is the most
> important one for my patch.

What trees are these patches coming from?

> Another option would be for me to fix the patch for your tree, but
> then I would probably have to fix it back in a few days when you update
> your staging tree to Linux-next. How often is your tree updated?

linux-next pulls from my tree, I don't pull from linux-next.

As I don't see those patches in Linus's tree, I can't merge my tree
forward to include them yet.  I could take those patches also through my
tree if you want me to, or you could send this patch through the mfd
tree so that things build properly there too.

> The easiest is probably to wait a few days until you have the next-20110510
> tag in your tree and then apply the patch.

That will never happen, see above for how linux-next works.

thanks,

greg k-h

^ permalink raw reply

* Re: [PATCH 1/6] Bluetooth: Create __l2cap_chan_close()
From: Anderson Lizardo @ 2011-05-12 15:55 UTC (permalink / raw)
  To: Gustavo F. Padovan; +Cc: linux-bluetooth
In-Reply-To: <1305178350-7568-1-git-send-email-padovan@profusion.mobi>

Hi Padovan,

On Thu, May 12, 2011 at 1:32 AM, Gustavo F. Padovan
<padovan@profusion.mobi> wrote:
> +void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
> +{
> +       struct l2cap_conn *conn = chan->conn;
> +       struct sock *sk = chan->sk;
> +
> +       BT_DBG("chan %p state %d socket %p", chan, sk->sk_state, sk->sk_socket);
> +
> +       switch (sk->sk_state) {
> +       case BT_LISTEN:
> +               l2cap_chan_cleanup_listen(chan->sk);

Cosmetic: you can use just "sk" above.

> +               break;
> +

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply

* RE: [PATCH v6] staging: Add ST-Ericsson CG2900 driver
From: Par-Gunnar HJALMDAHL @ 2011-05-12 11:54 UTC (permalink / raw)
  To: Greg KH
  Cc: Greg Kroah-Hartman, devel@driverdev.osuosl.org, Linus Walleij,
	linux-kernel@vger.kernel.org, linux-bluetooth@vger.kernel.org,
	Pavan Savoy, Vitaly Wool, Alan Cox, Arnd Bergmann,
	Marcel Holtmann, Lukasz Rymanowski, Linus WALLEIJ,
	Par-Gunnar Hjalmdahl, Lee Jones, Mathieu Poirier
In-Reply-To: <20110511134859.GB12717@kroah.com>

PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9tOiBHcmVnIEtIIFttYWlsdG86Z3Jl
Z0Brcm9haC5jb21dDQo+IFNlbnQ6IGRlbiAxMSBtYWogMjAxMSAxNTo0OQ0KPg0KPiA+IEkgdXNl
ZCBuZXh0LTIwMTEwNTEwIGFuZCBpbiB0aGF0IHRhZyB0aGUgZmlsZQ0KPiBpbmNsdWRlL0xpbnV4
L21mZC9jb3JlLmgNCj4gPiBUaGUgc3RydWN0IG1mZF9jZWxsIGhhcyBhIHBhcmFtZXRlciBjYWxs
ZWQgcGxhdGZvcm1fZGF0YSwgd2hpbGUgaW4NCj4geW91cg0KPiA+IGJ1aWxkIGl0IHNlZW1zIGl0
IGRvZXNuJ3QuDQo+ID4gVGhpcyB3YXMgY2hhbmdlZCB2ZXJ5IHJlY2VudGx5IGluIHRoZSBjb3Jl
LmggZmlsZSAob24gQXByaWwgNikuDQo+ID4gU28gZm9yIGNvcmUuaCB0aGUgbGFzdCBjb21taXQg
SUQgSSBoYXZlIGluIHRoZSB0YWcgSSBidWlsdCB1cG9uIGlzDQo+ID4gNTU4YWE5YzBkNjIwYjkx
YTg5NmQ1ZTM5Y2U4YTU3MGJlZDY1NTg5Yi4NCj4gDQo+IFNvIGRvIEkgbmVlZCB0aGF0IHBhdGNo
IG9uIHRoZSBzdGFnaW5nLW5leHQgdHJlZSBhbHNvPw0KPiANCj4gT3IgaXMgaXQgYW4gaXNzdWUg
b2YgYnVpbGRpbmcgdGhpcyBvbiB4ODYtNjQuLi4NCj4gDQo+IHRoYW5rcywNCj4gDQo+IGdyZWcg
ay1oDQoNCkhpIEdyZWcsDQoNCkkgZG93bmxvYWRlZCB5b3Ugc3RhZ2luZyB0cmVlIGFuZCBjb21w
YXJlZCB0aGUgbG9ncyBmb3IgdGhlIGNvcmUuaCBmaWxlLg0KQ29tcGFyZWQgdG8gbGludXgtbmV4
dCB0YWcgbmV4dC0yMDExMDUxMCBpdCBpcyBtaXNzaW5nIDIgY29tbWl0czoNCjRkYmVlNmI3NmZm
ZmQ1NzQwZTg3ZTI4NmY0ZjRjMWMxNTkwMWJjYWUNCjU1OGFhOWMwZDYyMGI5MWE4OTZkNWUzOWNl
OGE1NzBiZWQ2NTU4OWINCndoZXJlIHRoZSBmaXJzdCBvbmUgaXMgdGhlICJvbGRlc3QiIG9uZSBp
biB0aGUgbG9nIGFuZCBpcyB0aGUgbW9zdA0KaW1wb3J0YW50IG9uZSBmb3IgbXkgcGF0Y2guDQpB
bm90aGVyIG9wdGlvbiB3b3VsZCBiZSBmb3IgbWUgdG8gZml4IHRoZSBwYXRjaCBmb3IgeW91ciB0
cmVlLCBidXQNCnRoZW4gSSB3b3VsZCBwcm9iYWJseSBoYXZlIHRvIGZpeCBpdCBiYWNrIGluIGEg
ZmV3IGRheXMgd2hlbiB5b3UgdXBkYXRlDQp5b3VyIHN0YWdpbmcgdHJlZSB0byBMaW51eC1uZXh0
LiBIb3cgb2Z0ZW4gaXMgeW91ciB0cmVlIHVwZGF0ZWQ/DQoNClRoZSBlYXNpZXN0IGlzIHByb2Jh
Ymx5IHRvIHdhaXQgYSBmZXcgZGF5cyB1bnRpbCB5b3UgaGF2ZSB0aGUgbmV4dC0yMDExMDUxMA0K
dGFnIGluIHlvdXIgdHJlZSBhbmQgdGhlbiBhcHBseSB0aGUgcGF0Y2guDQoNClRoYW5rcywNClAt
Rw0KDQo=

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox