* Re: [PATCH 7/7] Add service UUIDs from EIR to device properties in "Device Found" signal.
From: Johan Hedberg @ 2010-08-06 7:55 UTC (permalink / raw)
To: Inga Stotland; +Cc: linux-bluetooth, marcel, rshaffer
In-Reply-To: <1281047801-4044-1-git-send-email-ingas@codeaurora.org>
Hi Inga,
On Thu, Aug 05, 2010, Inga Stotland wrote:
> + while (len < EIR_DATA_LENGTH - 1) {
> + uint8_t type = eir_data[1];
> + uint8_t field_len = eir_data[0];
> +
> + /* Check for the end of EIR */
> + if (field_len == 0)
> + break;
Shouldn't there also be another check here:
/* Bail out if field_len claims to reach beyond the EIR
* data end */
if (len + field_len + 1 >= EIR_DATA_LENGTH)
break;
Johan
^ permalink raw reply
* [PATCH 9/9] Bluetooth: Use 3-DH5 payload size for default ERTM max PDU size.
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>
The previous value of 672 for L2CAP_DEFAULT_MAX_PDU_SIZE is based on
the default L2CAP MTU. That default MTU is calculated from the size
of two DH5 packets, minus ACL and L2CAP b-frame header overhead.
ERTM is used with newer basebands that typically support larger 3-DH5
packets, and i-frames and s-frames have more header overhead. With
clean RF conditions, basebands will typically attempt to use 1021-byte
3-DH5 packets for maximum throughput. Adjusting for 2 bytes of ACL
headers plus 10 bytes of worst-case L2CAP headers yields 1009 bytes
of payload.
This PDU size imposes less overhead for header bytes and gives the
baseband the option to choose 3-DH5 packets, but is small enough for
ERTM traffic to interleave well with other L2CAP or SCO data.
672-byte payloads do not allow the most efficient over-the-air
packet choice, and cannot achieve maximum throughput over BR/EDR.
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
include/net/bluetooth/l2cap.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 16e412f..6c24144 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -35,7 +35,7 @@
#define L2CAP_DEFAULT_MAX_TX 3
#define L2CAP_DEFAULT_RETRANS_TO 2000 /* 2 seconds */
#define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */
-#define L2CAP_DEFAULT_MAX_PDU_SIZE 672
+#define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */
#define L2CAP_DEFAULT_ACK_TO 200
#define L2CAP_LOCAL_BUSY_TRIES 12
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH 8/9] Bluetooth: Use a stream-oriented recvmsg with SOCK_STREAM L2CAP sockets.
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>
L2CAP ERTM sockets can be opened with the SOCK_STREAM socket type,
which is a mandatory request for ERTM mode.
However, these sockets still have SOCK_SEQPACKET read semantics when
bt_sock_recvmsg() is used to pull data from the receive queue. If the
application is only reading part of a frame, then the unread portion
of the frame is discarded. If the application requests more bytes
than are in the current frame, only the current frame's data is
returned.
This patch utilizes common code derived from RFCOMM's recvmsg()
function to make L2CAP SOCK_STREAM reads behave like RFCOMM reads (and
other SOCK_STREAM sockets in general). The application may read one
byte at a time from the input stream and not lose any data, and may
also read across L2CAP frame boundaries.
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
net/bluetooth/l2cap.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 43e0eae..cd0e150 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1956,7 +1956,10 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms
release_sock(sk);
- return bt_sock_recvmsg(iocb, sock, msg, len, flags);
+ if (sock->type == SOCK_STREAM)
+ return bt_sock_stream_recvmsg(iocb, sock, msg, len, flags);
+ else
+ return bt_sock_recvmsg(iocb, sock, msg, len, flags);
}
static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH 7/9] Bluetooth: Use common SOCK_STREAM receive code in RFCOMM.
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>
To reduce code duplication, have rfcomm_sock_recvmsg() call
bt_sock_stream_recvmsg(). The common bt_sock_stream_recvmsg()
code is nearly identical, with the RFCOMM-specific functionality
for deferred setup and connection unthrottling left in
rfcomm_sock_recvmsg().
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
net/bluetooth/rfcomm/sock.c | 104 +++----------------------------------------
1 files changed, 6 insertions(+), 98 deletions(-)
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 44a6232..4396f47 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -617,121 +617,29 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
return sent;
}
-static long rfcomm_sock_data_wait(struct sock *sk, long timeo)
-{
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue(sk_sleep(sk), &wait);
- for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
-
- if (!skb_queue_empty(&sk->sk_receive_queue) ||
- sk->sk_err ||
- (sk->sk_shutdown & RCV_SHUTDOWN) ||
- signal_pending(current) ||
- !timeo)
- break;
-
- set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
- release_sock(sk);
- timeo = schedule_timeout(timeo);
- lock_sock(sk);
- clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
- }
-
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(sk_sleep(sk), &wait);
- return timeo;
-}
-
static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags)
{
struct sock *sk = sock->sk;
struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
- int err = 0;
- size_t target, copied = 0;
- long timeo;
+ int len;
if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
rfcomm_dlc_accept(d);
return 0;
}
- if (flags & MSG_OOB)
- return -EOPNOTSUPP;
-
- msg->msg_namelen = 0;
-
- BT_DBG("sk %p size %zu", sk, size);
+ len = bt_sock_stream_recvmsg(iocb, sock, msg, size, flags);
lock_sock(sk);
+ if (!(flags & MSG_PEEK) && len > 0)
+ atomic_sub(len, &sk->sk_rmem_alloc);
- target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
- timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
-
- do {
- struct sk_buff *skb;
- int chunk;
-
- skb = skb_dequeue(&sk->sk_receive_queue);
- if (!skb) {
- if (copied >= target)
- break;
-
- if ((err = sock_error(sk)) != 0)
- break;
- if (sk->sk_shutdown & RCV_SHUTDOWN)
- break;
-
- err = -EAGAIN;
- if (!timeo)
- break;
-
- timeo = rfcomm_sock_data_wait(sk, timeo);
-
- if (signal_pending(current)) {
- err = sock_intr_errno(timeo);
- goto out;
- }
- continue;
- }
-
- chunk = min_t(unsigned int, skb->len, size);
- if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
- skb_queue_head(&sk->sk_receive_queue, skb);
- if (!copied)
- copied = -EFAULT;
- break;
- }
- copied += chunk;
- size -= chunk;
-
- sock_recv_ts_and_drops(msg, sk, skb);
-
- if (!(flags & MSG_PEEK)) {
- atomic_sub(chunk, &sk->sk_rmem_alloc);
-
- skb_pull(skb, chunk);
- if (skb->len) {
- skb_queue_head(&sk->sk_receive_queue, skb);
- break;
- }
- kfree_skb(skb);
-
- } else {
- /* put message back and return */
- skb_queue_head(&sk->sk_receive_queue, skb);
- break;
- }
- } while (size);
-
-out:
if (atomic_read(&sk->sk_rmem_alloc) <= (sk->sk_rcvbuf >> 2))
rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc);
-
release_sock(sk);
- return copied ? : err;
+
+ return len;
}
static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH 6/9] Bluetooth: Add common code for stream-oriented recvmsg()
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>
This commit adds a bt_sock_stream_recvmsg() function for use by any
Bluetooth code that uses SOCK_STREAM sockets. This code is copied
from rfcomm_sock_recvmsg() with minimal modifications to remove
RFCOMM-specific functionality and improve readability.
L2CAP (with the SOCK_STREAM socket type) and RFCOMM have common needs
when it comes to reading data. Proper stream read semantics require
that applications can read from a stream one byte at a time and not
lose any data. The RFCOMM code already operated on and pulled data
from the underlying L2CAP socket, so very few changes were required to
make the code more generic for use with non-RFCOMM data over L2CAP.
Applications that need more awareness of L2CAP frame boundaries are
still free to use SOCK_SEQPACKET sockets, and may verify that they
connection did not fall back to basic mode by calling getsockopt().
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
include/net/bluetooth/bluetooth.h | 2 +
net/bluetooth/af_bluetooth.c | 109 +++++++++++++++++++++++++++++++++++++
2 files changed, 111 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 27a902d..08b6c2a 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -126,6 +126,8 @@ int bt_sock_unregister(int proto);
void bt_sock_link(struct bt_sock_list *l, struct sock *s);
void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags);
+int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+ struct msghdr *msg, size_t len, int flags);
uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 421c45b..77a26fe 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -265,6 +265,115 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
}
EXPORT_SYMBOL(bt_sock_recvmsg);
+static long bt_sock_data_wait(struct sock *sk, long timeo)
+{
+ DECLARE_WAITQUEUE(wait, current);
+
+ add_wait_queue(sk_sleep(sk), &wait);
+ for (;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ if (!skb_queue_empty(&sk->sk_receive_queue))
+ break;
+
+ if (sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN))
+ break;
+
+ if (signal_pending(current) || !timeo)
+ break;
+
+ set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+ release_sock(sk);
+ timeo = schedule_timeout(timeo);
+ lock_sock(sk);
+ clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+ }
+
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(sk_sleep(sk), &wait);
+ return timeo;
+}
+
+int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+ struct msghdr *msg, size_t size, int flags)
+{
+ struct sock *sk = sock->sk;
+ int err = 0;
+ size_t target, copied = 0;
+ long timeo;
+
+ if (flags & MSG_OOB)
+ return -EOPNOTSUPP;
+
+ msg->msg_namelen = 0;
+
+ BT_DBG("sk %p size %zu", sk, size);
+
+ lock_sock(sk);
+
+ target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
+ timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
+
+ do {
+ struct sk_buff *skb;
+ int chunk;
+
+ skb = skb_dequeue(&sk->sk_receive_queue);
+ if (!skb) {
+ if (copied >= target)
+ break;
+
+ if ((err = sock_error(sk)) != 0)
+ break;
+ if (sk->sk_shutdown & RCV_SHUTDOWN)
+ break;
+
+ err = -EAGAIN;
+ if (!timeo)
+ break;
+
+ timeo = bt_sock_data_wait(sk, timeo);
+
+ if (signal_pending(current)) {
+ err = sock_intr_errno(timeo);
+ goto out;
+ }
+ continue;
+ }
+
+ chunk = min_t(unsigned int, skb->len, size);
+ if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ if (!copied)
+ copied = -EFAULT;
+ break;
+ }
+ copied += chunk;
+ size -= chunk;
+
+ sock_recv_ts_and_drops(msg, sk, skb);
+
+ if (!(flags & MSG_PEEK)) {
+ skb_pull(skb, chunk);
+ if (skb->len) {
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ break;
+ }
+ kfree_skb(skb);
+
+ } else {
+ /* put message back and return */
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ break;
+ }
+ } while (size);
+
+out:
+ release_sock(sk);
+ return copied ? : err;
+}
+EXPORT_SYMBOL(bt_sock_stream_recvmsg);
+
static inline unsigned int bt_accept_poll(struct sock *parent)
{
struct list_head *p, *n;
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH 5/9] Bluetooth: Fix incorrect setting of remote_tx_win for L2CAP ERTM.
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>
remote_tx_win is intended to be set on receipt of an L2CAP
configuration request. The value is used to determine the size of the
transmit window on the remote side of an ERTM connection, so L2CAP
can stop sending frames when that remote window is full.
An incorrect remote_tx_win value will cause the stack to not fully
utilize the tx window (performance impact), or to overfill the remote
tx window (causing dropped frames or a disconnect).
This patch removes an extra setting of remote_tx_win when a
configuration response is received. The transmit window has a
different meaning in a response - it is an informational value
less than or equal to the local tx_win.
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
net/bluetooth/l2cap.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 5541b56..43e0eae 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2819,7 +2819,6 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
if (*result == L2CAP_CONF_SUCCESS) {
switch (rfc.mode) {
case L2CAP_MODE_ERTM:
- pi->remote_tx_win = rfc.txwin_size;
pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
pi->mps = le16_to_cpu(rfc.max_pdu_size);
@@ -2875,7 +2874,6 @@ static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
done:
switch (rfc.mode) {
case L2CAP_MODE_ERTM:
- pi->remote_tx_win = rfc.txwin_size;
pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
pi->mps = le16_to_cpu(rfc.max_pdu_size);
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH 4/9] Bluetooth: Fix endianness issue with L2CAP MPS configuration.
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>
Incoming configuration values must be converted to native CPU order
before use. This fixes a bug where a little-endian MPS value is
compared to a native CPU value. On big-endian processors, this
can cause ERTM and streaming mode segmentation to produce PDUs
that are larger than the remote stack is expecting, or that would
produce fragmented skbs that the current FCS code cannot handle.
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
net/bluetooth/l2cap.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 77ba106..5541b56 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2717,8 +2717,9 @@ done:
case L2CAP_MODE_ERTM:
pi->remote_tx_win = rfc.txwin_size;
pi->remote_max_tx = rfc.max_transmit;
- if (rfc.max_pdu_size > pi->conn->mtu - 10)
- rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
+
+ if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
+ rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
@@ -2735,8 +2736,8 @@ done:
break;
case L2CAP_MODE_STREAMING:
- if (rfc.max_pdu_size > pi->conn->mtu - 10)
- rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
+ if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
+ rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH 3/9] Bluetooth: Validate PSM values in calls to connect() and bind().
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>
Valid L2CAP PSMs are odd numbers, and the least significant bit of the
most significant byte must be 0.
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
net/bluetooth/l2cap.c | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index bc10be8..77ba106 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1008,6 +1008,12 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
goto done;
}
+ /* If specified, PSM must be odd and lsb of upper byte must be 0 */
+ if (la.l2_psm && (__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001) {
+ err = -EINVAL;
+ goto done;
+ }
+
if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
!capable(CAP_NET_BIND_SERVICE)) {
err = -EACCES;
@@ -1190,6 +1196,12 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
goto done;
}
+ /* PSM must be odd and lsb of upper byte must be 0 */
+ if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001) {
+ err = -EINVAL;
+ goto done;
+ }
+
/* Set destination address and psm */
bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
l2cap_pi(sk)->psm = la.l2_psm;
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH 2/9] Bluetooth: Change default ERTM retransmit timeout.
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>
The L2CAP spec requires that the ERTM retransmit timeout be at least 2
seconds for BR/EDR connections.
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
include/net/bluetooth/l2cap.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 636724b..16e412f 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -33,7 +33,7 @@
#define L2CAP_DEFAULT_FLUSH_TO 0xffff
#define L2CAP_DEFAULT_TX_WINDOW 63
#define L2CAP_DEFAULT_MAX_TX 3
-#define L2CAP_DEFAULT_RETRANS_TO 1000 /* 1 second */
+#define L2CAP_DEFAULT_RETRANS_TO 2000 /* 2 seconds */
#define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */
#define L2CAP_DEFAULT_MAX_PDU_SIZE 672
#define L2CAP_DEFAULT_ACK_TO 200
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH 1/9] Bluetooth: Only enable for L2CAP FCS for ERTM or streaming.
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>
This fixes a bug which caused the FCS setting to show L2CAP_FCS_CRC16
with L2CAP modes other than ERTM or streaming. At present, this only
affects the FCS value shown with getsockopt() for basic mode.
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
net/bluetooth/l2cap.c | 16 ++++++++++++----
1 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 3e3cd9d..bc10be8 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3072,6 +3072,16 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
return 0;
}
+static inline int l2cap_fcs_needed(struct l2cap_pinfo *pi)
+{
+ if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
+ return 0;
+
+ /* FCS is enabled if one or both sides request it. */
+ return !(pi->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
+ pi->fcs == L2CAP_FCS_CRC16;
+}
+
static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
{
struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
@@ -3136,8 +3146,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
goto unlock;
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
- if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
- l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
+ if (l2cap_fcs_needed(l2cap_pi(sk)))
l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
sk->sk_state = BT_CONNECTED;
@@ -3226,8 +3235,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
- if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
- l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
+ if (l2cap_fcs_needed(l2cap_pi(sk)))
l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
sk->sk_state = BT_CONNECTED;
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH v3 0/9] Bluetooth: L2CAP updates for PSM validation and ERTM
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm
This is a collection of ERTM-related patches, including some L2CAP
configuration fixes and allowing partial-frame reads from L2CAP
SOCK_STREAM sockets. PSM validation is also included, although that
is not restricted to ERTM.
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply
* [PATCH 7/7] Add service UUIDs from EIR to device properties in "Device Found" signal.
From: Inga Stotland @ 2010-08-05 22:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: johan.hedberg, marcel, rshaffer, Inga Stotland
In-Reply-To: <20100805102513.GA7221@jh-x301>
---
src/adapter.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
src/adapter.h | 4 +-
src/dbus-hci.c | 6 ++--
3 files changed, 110 insertions(+), 8 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index c142a4a..b2b5be8 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2749,8 +2749,102 @@ static void emit_device_found(const char *path, const char *address,
g_dbus_send_message(connection, signal);
}
+static char **get_eir_uuids(uint8_t *eir_data, size_t *uuid_count)
+{
+ uint16_t len = 0;
+ char **uuids;
+ size_t total;
+ size_t uuid16_count = 0;
+ size_t uuid32_count = 0;
+ size_t uuid128_count = 0;
+ uint8_t *uuid16;
+ uint8_t *uuid32;
+ uint8_t *uuid128;
+ uuid_t service;
+ int i;
+
+ while (len < EIR_DATA_LENGTH - 1) {
+ uint8_t type = eir_data[1];
+ uint8_t field_len = eir_data[0];
+
+ /* Check for the end of EIR */
+ if (field_len == 0)
+ break;
+
+ switch (type) {
+ case EIR_UUID16_SOME:
+ case EIR_UUID16_ALL:
+ uuid16_count = field_len / 2;
+ uuid16 = &eir_data[2];
+ break;
+ case EIR_UUID32_SOME:
+ case EIR_UUID32_ALL:
+ uuid32_count = field_len / 4;
+ uuid32 = &eir_data[2];
+ break;
+ case EIR_UUID128_SOME:
+ case EIR_UUID128_ALL:
+ uuid128_count = field_len / 16;
+ uuid128 = &eir_data[2];
+ break;
+ }
+
+ len += field_len + 1;
+ eir_data += field_len + 1;
+ }
+
+ /* Bail out if got incorrect length */
+ if (len > EIR_DATA_LENGTH)
+ return NULL;
+
+ total = uuid16_count + uuid32_count + uuid128_count;
+ *uuid_count = total;
+
+ if (!total)
+ return NULL;
+
+ uuids = g_new0(char *, total + 1);
+
+ /* Generate uuids in SDP format (EIR data is Little Endian) */
+ service.type = SDP_UUID16;
+ for (i = 0; i < uuid16_count; i++) {
+ uint16_t val16 = uuid16[1];
+
+ val16 = (val16 << 8) + uuid16[0];
+ service.value.uuid16 = val16;
+ uuids[i] = bt_uuid2string(&service);
+ uuid16 += 2;
+ }
+
+ service.type = SDP_UUID32;
+ for (i = uuid16_count; i < uuid32_count + uuid16_count; i++) {
+ uint32_t val32 = uuid32[3];
+ int k;
+
+ for (k = 2; k >= 0; k--)
+ val32 = (val32 << 8) + uuid32[k];
+
+ service.value.uuid32 = val32;
+ uuids[i] = bt_uuid2string(&service);
+ uuid32 += 4;
+ }
+
+ service.type = SDP_UUID128;
+ for (i = uuid32_count + uuid16_count; i < total; i++) {
+ int k;
+
+ for (k = 0; k < 16; k++)
+ service.value.uuid128.data[k] = uuid128[16 - k - 1];
+
+ uuids[i] = bt_uuid2string(&service);
+ uuid128 += 16;
+ }
+
+ return uuids;
+}
+
void adapter_emit_device_found(struct btd_adapter *adapter,
- struct remote_dev_info *dev)
+ struct remote_dev_info *dev, uint8_t *eir_data)
{
struct btd_device *device;
char peer_addr[18], local_addr[18];
@@ -2758,6 +2852,8 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
dbus_bool_t paired = FALSE;
dbus_int16_t rssi = dev->rssi;
char *alias;
+ char **uuids = NULL;
+ size_t uuid_count = 0;
ba2str(&dev->bdaddr, peer_addr);
ba2str(&adapter->bdaddr, local_addr);
@@ -2777,6 +2873,10 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
} else
alias = g_strdup(dev->alias);
+ /* Extract UUIDs from extended inquiry response if any*/
+ if (eir_data != NULL)
+ uuids = get_eir_uuids(eir_data, &uuid_count);
+
emit_device_found(adapter->path, paddr,
"Address", DBUS_TYPE_STRING, &paddr,
"Class", DBUS_TYPE_UINT32, &dev->class,
@@ -2786,15 +2886,17 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
"Alias", DBUS_TYPE_STRING, &alias,
"LegacyPairing", DBUS_TYPE_BOOLEAN, &dev->legacy,
"Paired", DBUS_TYPE_BOOLEAN, &paired,
+ "UUIDs", DBUS_TYPE_ARRAY, &uuids, uuid_count,
NULL);
g_free(alias);
+ g_strfreev(uuids);
}
void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
int8_t rssi, uint32_t class, const char *name,
const char *alias, gboolean legacy,
- name_status_t name_status)
+ name_status_t name_status, uint8_t *eir_data)
{
struct remote_dev_info *dev, match;
@@ -2833,7 +2935,7 @@ done:
adapter->found_devices = g_slist_sort(adapter->found_devices,
(GCompareFunc) dev_rssi_cmp);
- adapter_emit_device_found(adapter, dev);
+ adapter_emit_device_found(adapter, dev, eir_data);
}
int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr)
diff --git a/src/adapter.h b/src/adapter.h
index 8226514..a7eca0e 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -113,10 +113,10 @@ struct remote_dev_info *adapter_search_found_devices(struct btd_adapter *adapter
void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
int8_t rssi, uint32_t class, const char *name,
const char *alias, gboolean legacy,
- name_status_t name_status);
+ name_status_t name_status, uint8_t *eir_data);
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);
+ struct remote_dev_info *dev, uint8_t *eir_data);
void adapter_update_oor_devices(struct btd_adapter *adapter);
void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode);
void adapter_setname_complete(bdaddr_t *local, uint8_t status);
diff --git a/src/dbus-hci.c b/src/dbus-hci.c
index b83506f..6d27caa 100644
--- a/src/dbus-hci.c
+++ b/src/dbus-hci.c
@@ -515,7 +515,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
if (dev) {
adapter_update_found_devices(adapter, peer, rssi, class,
NULL, NULL, dev->legacy,
- NAME_NOT_REQUIRED);
+ NAME_NOT_REQUIRED, data);
return;
}
@@ -566,7 +566,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
/* add in the list to track name sent/pending */
adapter_update_found_devices(adapter, peer, rssi, class, name, alias,
- legacy, name_status);
+ legacy, name_status, data);
g_free(name);
g_free(alias);
@@ -642,7 +642,7 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status,
if (dev_info) {
g_free(dev_info->name);
dev_info->name = g_strdup(name);
- adapter_emit_device_found(adapter, dev_info);
+ adapter_emit_device_found(adapter, dev_info, NULL);
}
if (device)
--
1.7.2
--
Inga Stotland
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
* Handling HID Connections for certain devices externally
From: Carl Önnheim @ 2010-08-05 22:15 UTC (permalink / raw)
To: linux-bluetooth
Hi,
I am working on a project to integrate the Sony PS3 Remote to LIRC.
BlueZ supports the use of this device by translating key presses to
keyboard events. It is possible for me to read these translated keyboard
events to figure out what happens on the remote, but the application is
more stable if I can get hold of the raw data stream from the remote
directly. This ability would also allow for separate development for
other special devices that communicate as HID devices (e.g. the
WII-remotes).
I have not been able to get a hold of that datastream (except by
stopping bluez and then listening directly on the relevant PSM's, but
since bluez need to run for all other purposes that is not really an
option). So my question is:
1. Is there a possibility that I have missed for a separate user-space
program to "steal" the interrupt and control channels from BlueZ for a
specific HID Device?
2. If not, will you consider adding this possibility? I have
experimented with one option; the fake_hid functionality is extended so
that when a HID device connects it tries to connect to a unix socket
with a predefined name
(e.g. /var/run/bluez/fakehid_<vendor_id>_<product_id>). If a program
listens on that socket, the data channels will be passed over. If not,
bluez will continue as usual.
I have a patch that does this more or less ready to go, and I would be
happy to contribute further if I can. Other options can of course be
considered (e.g. exposing new DBus methods). But I wanted to check your
initial views before going into more details. You can see all details
about the project I am working on at
http://sourceforge.net/projects/sonyps3remote/.
The patch can be found in the svn tree there as well:
http://sonyps3remote.svn.sourceforge.net/viewvc/sonyps3remote/bluez/patches/bluez-4.69-sonyps3.diff.gz?view=log
Thanks in advance
//Carl
^ permalink raw reply
* Re: [PATCH 7/7] Add service UUIDs from EIR to device properties in "Device Found" signal.
From: ingas @ 2010-08-05 21:26 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth
In-Reply-To: <20100805102513.GA7221@jh-x301>
Hi Johan,
> I've pushed the six other patches upstream, but I'm still a bit
> concerned with this one.
>
Thanks :)
>
> Then, a more general concern about this function. It will receive data
> as input that any nearby device that's discoverable has declared in
> their EIR data. I.e. we need to be super strict about checking the
> validity of the data and not make any assumptions about the correctness
> of encoded field lengths etc. in order not to do buffer overflows. Have
> you taken this into account when designing the function? Looking at it
> it seems it might be possible to give it data that will cause some
> buffer overflows (by e.g. placing a uuid list at the very end of the EIR
> data with an invalid field length value).
>
I agree. Adding few more checks there. Will send a new patch today.
Inga
^ permalink raw reply
* Re: NoInputNoOutput and legacy pairing?
From: Manuel Naranjo @ 2010-08-05 20:58 UTC (permalink / raw)
To: BlueZ
In-Reply-To: <20100805195314.GA13190@jh-x301>
>> > I have a question regarding the NoInputNoOutput mode for registering
>> > agents for BlueZ. What happens when there's a legacy pin request and
>> > the mode is NoInputNoOutput? Will it fallback to standard pin code
>> > pairing?
>>
Great thanks. I know how to go on now.
BTW what happened to the wiki? This are the kind of things that would be
easy to address by just looking at it.
^ permalink raw reply
* Re: NoInputNoOutput and legacy pairing?
From: Johan Hedberg @ 2010-08-05 19:53 UTC (permalink / raw)
To: Manuel Naranjo; +Cc: BlueZ
In-Reply-To: <4C5B0884.2040805@aircable.net>
Hi Manuel,
On Thu, Aug 05, 2010, Manuel Naranjo wrote:
> I have a question regarding the NoInputNoOutput mode for registering
> agents for BlueZ. What happens when there's a legacy pin request and
> the mode is NoInputNoOutput? Will it fallback to standard pin code
> pairing?
Yes. The IO capability is only relevant for Secure Simple Pairing. It
doesn't matter what capability you give for legacy pairing since you'll
always get a pin request then.
Johan
^ permalink raw reply
* NoInputNoOutput and legacy pairing?
From: Manuel Naranjo @ 2010-08-05 18:52 UTC (permalink / raw)
To: BlueZ
Hi guys,
I have a question regarding the NoInputNoOutput mode for registering
agents for BlueZ. What happens when there's a legacy pin request and the
mode is NoInputNoOutput? Will it fallback to standard pin code pairing?
My system is working in an environment where no screen or no keyboard is
available so I can't pair with a random number. Thing is in some cases I
still need to fallback to a hardcoded pin because some cellphones
require it.
Manuel
^ permalink raw reply
* Re: [PATCH 5/9] Bluetooth: Fix incorrect setting of remote_tx_win for L2CAP ERTM.
From: Mat Martineau @ 2010-08-05 16:54 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: linux-bluetooth, marcel, rshaffer, linux-arm-msm
In-Reply-To: <20100805042013.GH7870@vigoh>
Gustavo -
On Thu, 5 Aug 2010, Gustavo F. Padovan wrote:
> Hi Mat,
>
> * Mat Martineau <mathewm@codeaurora.org> [2010-08-04 15:49:02 -0700]:
>
>> remote_tx_win is intended to be set on receipt of an L2CAP
>> configuration request. The value is used to determine the size of the
>> transmit window on the remote side of an ERTM connection, so L2CAP
>> can stop sending frames when that remote window is full.
>>
>> An incorrect remote_tx_win value will cause the stack to not fully
>> utilize the tx window (performance impact), or to overfill the remote
>> tx window (causing dropped frames or a disconnect).
>>
>> This patch removes an extra setting of remote_tx_win when a
>> configuration response is received. The transmit window has a
>> different meaning in a response - it is an informational value
>> less than or equal to the local tx_win.
>>
>> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
>> ---
>> net/bluetooth/l2cap.c | 1 -
>> 1 files changed, 0 insertions(+), 1 deletions(-)
>>
>> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
>> index 8cf9569..f0f3c7c 100644
>> --- a/net/bluetooth/l2cap.c
>> +++ b/net/bluetooth/l2cap.c
>> @@ -2808,7 +2808,6 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
>> if (*result == L2CAP_CONF_SUCCESS) {
>> switch (rfc.mode) {
>> case L2CAP_MODE_ERTM:
>> - pi->remote_tx_win = rfc.txwin_size;
>> pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
>> pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
>> pi->mps = le16_to_cpu(rfc.max_pdu_size);
>
> I agree. But you may also want to remove the same check inside
> l2cap_conf_rfc_get()
I'll do that.
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply
* Re: [PATCH 4/9] Bluetooth: Fix endianness issue with L2CAP MPS configuration.
From: Mat Martineau @ 2010-08-05 16:50 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: linux-bluetooth, marcel, rshaffer, linux-arm-msm
In-Reply-To: <20100805040018.GG7870@vigoh>
Gustavo -
On Thu, 5 Aug 2010, Gustavo F. Padovan wrote:
> Hi Mat,
>
> * Mat Martineau <mathewm@codeaurora.org> [2010-08-04 15:49:01 -0700]:
>
>> Incoming configuration values must be converted to native CPU order
>> before use. This fixes a bug where a little-endian MPS value is
>> compared to a native CPU value. On big-endian processors, this
>> can cause ERTM and streaming mode segmentation to produce PDUs
>> that are larger than the remote stack is expecting, or that would
>> produce fragmented skbs that the current FCS code cannot handle.
>>
>> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
>> ---
>> net/bluetooth/l2cap.c | 9 ++++-----
>> 1 files changed, 4 insertions(+), 5 deletions(-)
>>
>> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
>> index 920a53f..8cf9569 100644
>> --- a/net/bluetooth/l2cap.c
>> +++ b/net/bluetooth/l2cap.c
>> @@ -2708,10 +2708,10 @@ done:
>> case L2CAP_MODE_ERTM:
>> pi->remote_tx_win = rfc.txwin_size;
>> pi->remote_max_tx = rfc.max_transmit;
>> - if (rfc.max_pdu_size > pi->conn->mtu - 10)
>> - rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
>>
>> pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
>> + if (pi->remote_mps > pi->conn->mtu - 10)
>> + pi->remote_mps = pi->conn->mtu - 10;
>
>
> What happened with thte "rfc.max_pdu_size =" attribution. We have the
> send the value to through the RFC option.
You're right - I didn't see that the rfc struct was used for both the
response and reply.
> So what I do propose here is:
>
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index 0f34e12..11d4405 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -2705,7 +2705,7 @@ done:
> case L2CAP_MODE_ERTM:
> pi->remote_tx_win = rfc.txwin_size;
> pi->remote_max_tx = rfc.max_transmit;
> - if (rfc.max_pdu_size > pi->conn->mtu - 10)
> + if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
> rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
>
> pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
Sure. I'll change it to "cpu_to_le16(pi->conn->mtu - 10)" (even
though they're functionally equivalent, it is definitely a conversion
to le16).
> @@ -2723,7 +2723,7 @@ done:
> break;
>
> case L2CAP_MODE_STREAMING:
> - if (rfc.max_pdu_size > pi->conn->mtu - 10)
> + if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
> rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
Same thing - cpu_to_le16() instead.
> pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
>
>
>
>>
>> rfc.retrans_timeout =
>> le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
>> @@ -2726,10 +2726,9 @@ done:
>> break;
>>
>> case L2CAP_MODE_STREAMING:
>> - if (rfc.max_pdu_size > pi->conn->mtu - 10)
>> - rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
>> -
>> pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
>> + if (pi->remote_mps > pi->conn->mtu - 10)
>> + pi->remote_mps = pi->conn->mtu - 10;
>>
>> pi->conf_state |= L2CAP_CONF_MODE_DONE;
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply
* Re: [PATCH 1/9] Bluetooth: Only enable for L2CAP FCS for ERTM or streaming.
From: Mat Martineau @ 2010-08-05 16:27 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: linux-bluetooth, marcel, rshaffer, linux-arm-msm
In-Reply-To: <20100805033218.GE7870@vigoh>
Gustavo -
On Thu, 5 Aug 2010, Gustavo F. Padovan wrote:
> Hi Mat,
>
> * Mat Martineau <mathewm@codeaurora.org> [2010-08-04 15:48:58 -0700]:
>
>> This fixes a bug which caused the FCS setting to show L2CAP_FCS_CRC16
>> with L2CAP modes other than ERTM or streaming. At present, this only
>> affects the FCS value shown with getsockopt() for basic mode.
>>
>> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
>> ---
>> net/bluetooth/l2cap.c | 17 +++++++++++++----
>> 1 files changed, 13 insertions(+), 4 deletions(-)
>>
>> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
>> index 9ba1e8e..a2706d9 100644
>> --- a/net/bluetooth/l2cap.c
>> +++ b/net/bluetooth/l2cap.c
>> @@ -3063,6 +3063,17 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
>> return 0;
>> }
>>
>> +static inline int l2cap_fcs_needed(struct l2cap_pinfo *pi)
>> +{
>> + if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
>> + return 0;
>> + else {
>> + /* FCS is enabled if one or both sides request it. */
>> + return !(pi->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
>> + pi->fcs == L2CAP_FCS_CRC16;
>> + }
>
> Get ride of the else, just put the return !(pi->....
Ok.
> Also I would like to see the use case for the check for the ERTM and
> Streaming before merge this patch. ;)
I have a patch modifying l2cap_skbuff_fromiovec() that allows ERTM
PDUs to be longer than the HCI MTU (some USB BT dongles only have a
310 byte HCI MTU). That function has to allocate space for the FCS in
the final HCI continuation fragment, and therefore checks to see if
FCS is enabled. When I first did this, it was not obvious that
pi->fcs could be L2CAP_FCS_CRC16 even when the FCS is not in use.
I hope you can agree that this patch makes the meaning of pi->fcs more
intuitive, and eliminates the need to check both pi->fcs and pi->mode
to really determine if the FCS is in use. Depending on using pi->fcs
only in ERTM code paths makes the code more fragile.
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply
* Re: [PATCH 2/9] Bluetooth: Change default ERTM retransmit timeout.
From: Mat Martineau @ 2010-08-05 15:53 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: linux-bluetooth, marcel, rshaffer, linux-arm-msm
In-Reply-To: <20100805032903.GD7870@vigoh>
Hi Gustavo -
On Thu, 5 Aug 2010, Gustavo F. Padovan wrote:
> Hi Mat,
>
> * Mat Martineau <mathewm@codeaurora.org> [2010-08-04 15:48:59 -0700]:
>
>> The L2CAP spec requires that the ERTM retransmit timeout be at least 2
>> seconds for BR/EDR connections.
>>
>> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
>> ---
>> include/net/bluetooth/l2cap.h | 2 +-
>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
>> index 636724b..16e412f 100644
>> --- a/include/net/bluetooth/l2cap.h
>> +++ b/include/net/bluetooth/l2cap.h
>> @@ -33,7 +33,7 @@
>> #define L2CAP_DEFAULT_FLUSH_TO 0xffff
>> #define L2CAP_DEFAULT_TX_WINDOW 63
>> #define L2CAP_DEFAULT_MAX_TX 3
>> -#define L2CAP_DEFAULT_RETRANS_TO 1000 /* 1 second */
>> +#define L2CAP_DEFAULT_RETRANS_TO 2000 /* 2 seconds */
>> #define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */
>> #define L2CAP_DEFAULT_MAX_PDU_SIZE 672
>> #define L2CAP_DEFAULT_ACK_TO 200
>
> The spec says that a 2 seconds retransmission timeout shall be used
> after a move channel operation in a BR/EDR radio. (section 8.6.2.3)
> For a normal ACL connection the default value is 1 second(section
> 8.6.2.1), so I prefer to keep L2CAP_DEFAULT_RETRANS_TO set to 1000.
Section 8.6.2.1 reads:
"If a flush timeout does not exist on the BR/EDR link for the channel
using Enhanced Retransmission mode, then the value for the
Retransmission timeout shall be at least two seconds..."
That is followed by the rule for channels with a flush timeout, which
requires the retrans timeout to be the larger of flushTO * 3 or 1
second. Since BlueZ does not configure the flush timeout for BR/EDR
links, the 2 second rule applies.
I experienced interoperability problems with ERTM on the BM3 Bluetooth
stack and the 1-second timeout - the one second timeout was not long
enough to allow for all the transmit buffering in BlueZ (all frames to
fill the TX window are immediately pushed to the HCI TX queue). I'd
like to discuss changing the way ERTM queues data to HCI, but that's a
separate topic - maybe something to chat about in Boston.
Regards,
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply
* Re: [PATCH][RFC] Fix SDP resolving segfault
From: Manuel Naranjo @ 2010-08-05 14:48 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: Johan Hedberg, BlueZ
In-Reply-To: <4C587AFF.7060402@aircable.net>
Luiz,
>> This looks like a different issue, at least it doesn't seems to crash
>> in the same point, so I assume the patch does fix something but
>> uncover another problem. But we have to find out where exactly is this
>> other problem because btd_device_unref doesn't seems to be the place,
>> can't you get any core dumps from the tests you did?
>>
>
> I agree it looks like it triggered another issue, I will try to get logs
> tomorrow.
>
Here's the call trace, unfortunately I don't have bluetoothd debug
messages, just this
+ 0 0x804e4ea (from 0x7e0dab) watch_func():
/home/manuel/bluez/gdbus/mainloop.c:94
+ 1 0x804ea3b (from 0x7140dd) dispatch_status():
/home/manuel/bluez/gdbus/mainloop.c:244
+ 2 0x804e49b (from 0x804ea7d) queue_dispatch():
/home/manuel/bluez/gdbus/mainloop.c:87
+ 0 0x804e436 (from 0x7aa53c) message_dispatch():
/home/manuel/bluez/gdbus/mainloop.c:73
+ 1 0x8050fa1 (from 0x716c8d) message_filter():
/home/manuel/bluez/gdbus/watch.c:408
+ 1 0x804f506 (from 0x723f13) generic_message():
/home/manuel/bluez/gdbus/object.c:236
+ 2 0x804f483 (from 0x804f549) find_interface():
/home/manuel/bluez/gdbus/object.c:219
+ 2 0x80a4d46 (from 0x804f5cb) adapter_start_discovery():
/home/manuel/bluez/src/adapter.c:1215
+ 3 0x80a354c (from 0x80a4da5) find_session():
/home/manuel/bluez/src/adapter.c:621
+ 3 0x80a4cce (from 0x80a4dfa) adapter_start_inquiry():
/home/manuel/bluez/src/adapter.c:1203
+ 4 0x80a2744 (from 0x80a4d0c) pending_remote_name_cancel():
/home/manuel/bluez/src/adapter.c:263
+ 5 0x80a208d (from 0x80a27aa) bacpy():
/home/manuel/bluez/./lib/bluetooth/bluetooth.h:132
+ 5 0x80a8b8e (from 0x80a27c3) adapter_search_found_devices():
/home/manuel/bluez/src/adapter.c:2667
+ 4 0x808831a (from 0x80a4d29) hciops_start_discovery():
/home/manuel/bluez/plugins/hciops.c:570
+ 3 0x80a2de5 (from 0x80a4e45) create_session():
/home/manuel/bluez/src/adapter.c:425
+ 4 0x80514c7 (from 0x80a2ea9) g_dbus_add_disconnect_watch():
/home/manuel/bluez/gdbus/watch.c:572
+ 5 0x80513cc (from 0x8051510) g_dbus_add_service_watch():
/home/manuel/bluez/gdbus/watch.c:544
+ 6 0x8050753 (from 0x8051430) filter_data_get():
/home/manuel/bluez/gdbus/watch.c:177
+ 7 0x80502a8 (from 0x80507a0) filter_data_find():
/home/manuel/bluez/gdbus/watch.c:69
+ 7 0x80502a8 (from 0x8050803) filter_data_find():
/home/manuel/bluez/gdbus/watch.c:69
+ 7 0x8050572 (from 0x80508a4) add_match():
/home/manuel/bluez/gdbus/watch.c:134
+ 8 0x8050402 (from 0x80505cc) format_rule():
/home/manuel/bluez/gdbus/watch.c:111
+ 8 0x804e8bd (from 0x729783) add_timeout():
/home/manuel/bluez/gdbus/mainloop.c:207
+ 8 0x804ea3b (from 0x7140dd) dispatch_status():
/home/manuel/bluez/gdbus/mainloop.c:244
+ 9 0x804e49b (from 0x804ea7d) queue_dispatch():
/home/manuel/bluez/gdbus/mainloop.c:87
+ 8 0x804e96c (from 0x7296ff) remove_timeout():
/home/manuel/bluez/gdbus/mainloop.c:227
+ 8 0x804e85f (from 0x729469) timeout_handler_free():
/home/manuel/bluez/gdbus/mainloop.c:195
+ 6 0x8050af5 (from 0x8051470) filter_data_add_callback():
/home/manuel/bluez/gdbus/watch.c:272
+ 4 0x8089ea8 (from 0x80a2ee4) info(): /home/manuel/bluez/src/log.c:36
+ 4 0x80a2d65 (from 0x80a2eef) session_ref():
/home/manuel/bluez/src/adapter.c:416
+ 5 0x8089f44 (from 0x80a2dc7) btd_debug():
/home/manuel/bluez/src/log.c:58
+ 0 0x808c945 (from 0x7e0dab) io_security_event():
/home/manuel/bluez/src/security.c:967
+ 1 0x808a32d (from 0x808caa9) hci_test_bit():
/home/manuel/bluez/./lib/bluetooth/hci_lib.h:167
+ 1 0x808bc97 (from 0x808cb24) cmd_complete():
/home/manuel/bluez/src/security.c:690
+ 2 0x808b951 (from 0x808bd70) start_inquiry():
/home/manuel/bluez/src/security.c:570
+ 3 0x80a1a5d (from 0x808b9a0) manager_find_adapter():
/home/manuel/bluez/src/manager.c:343
+ 4 0x80a1955 (from 0x7c947e) adapter_cmp():
/home/manuel/bluez/src/manager.c:319
+ 5 0x80a89ca (from 0x80a198d) adapter_get_address():
/home/manuel/bluez/src/adapter.c:2625
+ 6 0x80a208d (from 0x80a89f8) bacpy():
/home/manuel/bluez/./lib/bluetooth/bluetooth.h:132
+ 5 0x80a1000 (from 0x80a199f) bacmp():
/home/manuel/bluez/./lib/bluetooth/bluetooth.h:128
+ 3 0x80a8b15 (from 0x808b9ca) adapter_get_state():
/home/manuel/bluez/src/adapter.c:2657
+ 3 0x80a995b (from 0x808b9d8) adapter_has_discov_sessions():
/home/manuel/bluez/src/adapter.c:3021
+ 3 0x80a8a0d (from 0x808b9fc) adapter_set_state():
/home/manuel/bluez/src/adapter.c:2630
+ 4 0x80b0b44 (from 0x80a8aeb) emit_property_changed():
/home/manuel/bluez/src/dbus-common.c:266
+ 5 0x80b086d (from 0x80b0be0) append_variant():
/home/manuel/bluez/src/dbus-common.c:195
+ 5 0x805005d (from 0x80b0bf2) g_dbus_send_message():
/home/manuel/bluez/gdbus/object.c:615
+ 1 0x808a82f (from 0x808cdb4) check_pending_hci_req():
/home/manuel/bluez/src/security.c:186
+ 0 0x808c945 (from 0x7e0dab) io_security_event():
/home/manuel/bluez/src/security.c:967
+ 1 0x808a32d (from 0x808caa9) hci_test_bit():
/home/manuel/bluez/./lib/bluetooth/hci_lib.h:167
+ 1 0x808bc30 (from 0x808cafa) cmd_status():
/home/manuel/bluez/src/security.c:681
+ 1 0x808a82f (from 0x808cdb4) check_pending_hci_req():
/home/manuel/bluez/src/security.c:186
+ 0 0x808c945 (from 0x7e0dab) io_security_event():
/home/manuel/bluez/src/security.c:967
+ 1 0x808a32d (from 0x808caa9) hci_test_bit():
/home/manuel/bluez/./lib/bluetooth/hci_lib.h:167
+ 1 0x808c6e1 (from 0x808cd1b) disconn_complete():
/home/manuel/bluez/src/security.c:916
+ 2 0x80b2947 (from 0x808c734) hcid_dbus_disconn_complete():
/home/manuel/bluez/src/dbus-hci.c:779
+ 3 0x80a1a5d (from 0x80b29a3) manager_find_adapter():
/home/manuel/bluez/src/manager.c:343
+ 4 0x80a1955 (from 0x7c947e) adapter_cmp():
/home/manuel/bluez/src/manager.c:319
+ 5 0x80a89ca (from 0x80a198d) adapter_get_address():
/home/manuel/bluez/src/adapter.c:2625
+ 6 0x80a208d (from 0x80a89f8) bacpy():
/home/manuel/bluez/./lib/bluetooth/bluetooth.h:132
+ 5 0x80a1000 (from 0x80a199f) bacmp():
/home/manuel/bluez/./lib/bluetooth/bluetooth.h:128
+ 3 0x80a45fd (from 0x80b29d2) adapter_find_connection():
/home/manuel/bluez/src/adapter.c:1025
+ 4 0x80ac5b0 (from 0x80a4644) device_has_connection():
/home/manuel/bluez/src/device.c:934
+ 3 0x80a97f0 (from 0x80b2a2c) adapter_remove_connection():
/home/manuel/bluez/src/adapter.c:2992
+ 4 0x80ac472 (from 0x80a9864) device_remove_connection():
/home/manuel/bluez/src/device.c:908
+ 5 0x80ac306 (from 0x80ac58f) device_set_connected():
/home/manuel/bluez/src/device.c:875
+ 6 0x80b0b44 (from 0x80ac353) emit_property_changed():
/home/manuel/bluez/src/dbus-common.c:266
+ 7 0x80b086d (from 0x80b0be0) append_variant():
/home/manuel/bluez/src/dbus-common.c:195
+ 7 0x805005d (from 0x80b0bf2) g_dbus_send_message():
/home/manuel/bluez/gdbus/object.c:615
+ 4 0x80ae44a (from 0x80a9891) device_get_address():
/home/manuel/bluez/src/device.c:1654
+ 5 0x80aa3e0 (from 0x80ae475) bacpy():
/home/manuel/bluez/./lib/bluetooth/bluetooth.h:132
+ 4 0x808a77f (from 0x80a98a9) hci_req_queue_remove():
/home/manuel/bluez/src/security.c:169
+ 4 0x80afe26 (from 0x80a98b4) device_is_authenticating():
/home/manuel/bluez/src/device.c:2339
+ 4 0x80ae585 (from 0x80a98d6) device_is_temporary():
/home/manuel/bluez/src/device.c:1683
+ 1 0x808a82f (from 0x808cdb4) check_pending_hci_req():
/home/manuel/bluez/src/security.c:186
+ 0 0x8099459 (from 0x7e0dab) connect_watch():
/home/manuel/bluez/src/glib-helper.c:257
+ 1 0x80ae001 (from 0x809963a) browse_cb():
/home/manuel/bluez/src/device.c:1540
I think it keeps crashing the same way, when browse_cb gets called
user_data points to non valid data.
Manuel
^ permalink raw reply
* [PATCH] Fix not deleting stored keys when a new one is created
From: Luiz Augusto von Dentz @ 2010-08-05 13:58 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
When a new link key is created but it doesn't match any criteria to be
stored any previouly one should be removed from filesystem.
This can be reproduced by the following steps:
1. Pair devices normally so that a valid link key is stored
2. Remove link key on remote device
3. Attempt to do a rfcomm connection with security level higher than low
This can be triggered in some other ways but right now this is the
easiest since kernel will switch the authentication requirements in this
case, here is the hcidump output:
< HCI Command: IO Capability Request Reply (0x01|0x002b) plen 9
bdaddr xx:xx:xx:xx:xx:xx capability 0x01 oob 0x00 auth 0x00
Capability: DisplayYesNo (OOB data not present)
Authentication: No Bonding (No MITM Protection)
...
> HCI Event: Link Key Notification (0x18) plen 23
bdaddr xx:xx:xx:xx:xx:xx key 26D32FBEF7B7CBD7923CA391A2DE600F type 4
Type: Unauthenticated Combination Key
...
< HCI Command: Link Key Request Reply (0x01|0x000b) plen 22
bdaddr xx:xx:xx:xx:xx:xx key 38E2BC10B26148FBC264E0DBA2535F1B
> HCI Event: Auth Complete (0x06) plen 3
status 0x05 handle 1
Error: Authentication Failure
Note that the reason this is reproducible with a single rfcomm connection
might be a bug in kernel, but there is clearly a problem in the daemon
too since link keys doesn't match.
So link keys information should be available while connected even in
cases where bonding is not required, to fix this everytime there is a new
link key the old one is clear, to make sure this actually work with those
keys that are not stored persistently all keys are cached in memory so
they are always accessible via device object as long the object exists,
this changes should also enable the code path bellow:
/* Don't use unauthenticated combination keys if MITM is
* required */
if (type == 0x04 && req.type != 0xff && (req.type & 0x01))
and follow the recommendation of the simple pairing white paper which
says:
"Bonding is defined as the connection process where the link key
and connection information are stored in non-volatile memory.
Thus bonding implies that the device’s link information is
available after the current connection ceases. If the link key
and current connection information are not stored, then the
connection process uses “Pairing”"
Devices which link key is not permanently stored are currently being
marked as temporary so their information will be lost once the connection
ceases.
---
src/dbus-hci.c | 23 +++++++++++------------
src/device.c | 31 ++++++++++++++++---------------
src/device.h | 5 +++--
src/security.c | 5 ++---
4 files changed, 32 insertions(+), 32 deletions(-)
diff --git a/src/dbus-hci.c b/src/dbus-hci.c
index b83506f..c8b2ad6 100644
--- a/src/dbus-hci.c
+++ b/src/dbus-hci.c
@@ -674,11 +674,12 @@ int hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer,
if (!get_adapter_and_device(local, peer, &adapter, &device, TRUE))
return -ENODEV;
+ /* Check if there is a key cached in memory */
+ device_get_key(device, NULL, &old_key_type);
+
new_key_type = key_type;
if (key_type == 0x06) {
- if (device_get_debug_key(device, NULL))
- old_key_type = 0x03;
if (old_key_type != 0xff)
new_key_type = old_key_type;
else
@@ -697,12 +698,11 @@ int hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer,
DBG("local auth 0x%02x and remote auth 0x%02x",
local_auth, remote_auth);
- /* Clear any previous debug key */
- device_set_debug_key(device, NULL);
+ /* Cache new link key */
+ device_set_key(device, key, new_key_type);
- /* Store the link key only in runtime memory if it's a debug
- * key, else store the link key persistently if one of the
- * following is true:
+ /* Link key are ALWAYS stored in runtime memory, they are also stored
+ * in filesystem persistently if one of the following is true:
* 1. this is a legacy link key
* 2. this is a changed combination key and there was a previously
* stored one
@@ -710,13 +710,12 @@ int hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer,
* 4. the local side had dedicated bonding as a requirement
* 5. the remote side is using dedicated bonding since in that case
* also the local requirements are set to dedicated bonding
- * If none of the above match only keep the link key around for
+ * If none of the above match and only keep the link key around for
* this connection and set the temporary flag for the device.
*/
- if (new_key_type == 0x03) {
- DBG("Storing debug key in runtime memory");
- device_set_debug_key(device, key);
- } else if (key_type < 0x03 ||
+ if (new_key_type == 0x03)
+ temporary = FALSE;
+ else if (key_type < 0x03 ||
(key_type == 0x06 && old_key_type != 0xff) ||
(local_auth > 0x01 && remote_auth > 0x01) ||
(local_auth == 0x02 || local_auth == 0x03) ||
diff --git a/src/device.c b/src/device.c
index 6af76d1..059aec3 100644
--- a/src/device.c
+++ b/src/device.c
@@ -143,8 +143,8 @@ struct btd_device {
gboolean authorizing;
gint ref;
- gboolean has_debug_key;
- uint8_t debug_key[16];
+ uint8_t key[16];
+ uint8_t key_type;
};
static uint16_t uuid_list[] = {
@@ -1024,7 +1024,8 @@ struct btd_device *device_create(DBusConnection *conn,
device->auth = 0xff;
- if (read_link_key(&src, &device->bdaddr, NULL, NULL) == 0)
+ if (read_link_key(&src, &device->bdaddr, device->key,
+ &device->key_type) == 0)
device->paired = TRUE;
return btd_device_ref(device);
@@ -2399,26 +2400,26 @@ const sdp_record_t *btd_device_get_record(struct btd_device *device,
return find_record_in_list(device->tmp_records, uuid);
}
-gboolean device_set_debug_key(struct btd_device *device, uint8_t *key)
+void device_set_key(struct btd_device *device, uint8_t *key, uint8_t type)
{
- if (key == NULL) {
- device->has_debug_key = FALSE;
- return TRUE;
- }
-
- memcpy(device->debug_key, key, 16);
- device->has_debug_key = TRUE;
+ /* Clear any previous key */
+ if (device->paired)
+ device_remove_bonding(device);
- return TRUE;
+ memcpy(device->key, key, 16);
+ device->key_type = type;
}
-gboolean device_get_debug_key(struct btd_device *device, uint8_t *key)
+gboolean device_get_key(struct btd_device *device, uint8_t *key, uint8_t *type)
{
- if (!device->has_debug_key)
+ if (!device->paired)
return FALSE;
if (key != NULL)
- memcpy(key, device->debug_key, 16);
+ memcpy(key, device->key, 16);
+
+ if (type != NULL)
+ *type = device->key_type;
return TRUE;
}
diff --git a/src/device.h b/src/device.h
index 5f75e61..229bc9e 100644
--- a/src/device.h
+++ b/src/device.h
@@ -79,8 +79,9 @@ gboolean device_is_authenticating(struct btd_device *device);
gboolean device_is_authorizing(struct btd_device *device);
void device_set_authorizing(struct btd_device *device, gboolean auth);
void device_set_renewed_key(struct btd_device *device, gboolean renewed);
-gboolean device_set_debug_key(struct btd_device *device, uint8_t *key);
-gboolean device_get_debug_key(struct btd_device *device, uint8_t *key);
+void device_set_key(struct btd_device *device, uint8_t *key, uint8_t type);
+gboolean device_get_key(struct btd_device *device, uint8_t *key,
+ uint8_t *type);
void device_add_connection(struct btd_device *device, DBusConnection *conn,
uint16_t handle);
void device_remove_connection(struct btd_device *device, DBusConnection *conn,
diff --git a/src/security.c b/src/security.c
index ca394e1..9d9e26f 100644
--- a/src/security.c
+++ b/src/security.c
@@ -329,9 +329,8 @@ static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba)
DBG("kernel auth requirements = 0x%02x", req.type);
- if (main_opts.debug_keys && device && device_get_debug_key(device, key))
- type = 0x03;
- else if (read_link_key(sba, dba, key, &type) < 0 || type == 0x03) {
+ if (device_get_key(device, key, &type) == FALSE ||
+ (type == 0x03 && main_opts.debug_keys == FALSE)) {
/* Link key not found */
hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 6, dba);
return;
--
1.7.0.4
^ permalink raw reply related
* [PATCH] Changes in HDP API.
From: Jose Antonio Santos Cadenas @ 2010-08-05 13:49 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <201008051129.38119.santoscadenas@gmail.com>
Now the connection is made directly to a device and bluetoothd daemon
guess the PSM connection and the MDEPID based on the data get from the
SDP record.
---
doc/health-api.txt | 105 ++++++++++++++++++++--------------------------------
1 files changed, 40 insertions(+), 65 deletions(-)
diff --git a/doc/health-api.txt b/doc/health-api.txt
index f469df3..89df8bd 100644
--- a/doc/health-api.txt
+++ b/doc/health-api.txt
@@ -14,12 +14,9 @@ Object path /org/bluez/
Methods:
- object CreateApplication(dict config, object agent)
+ object CreateApplication(dict config)
- Returns the path of the new registered application. The agent
- parameter is the path of the object with the callbacks to
- notify events (see org.bluez.HealthAgent at the end
- of this document).
+ Returns the path of the new registered application.
Dict is defined as bellow:
{
@@ -39,32 +36,33 @@ Methods:
Closes the HDP application identified by the object path. Also
application will be closed if the process that started it leaves
- the bus.
+ the bus. Only the creator of the application will be able to
+ destroy it.
Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.NotFound
+ org.bluez.Error.NotAllowed
--------------------------------------------------------------------------------
Service org.bluez
-Interface org.bluez.HealthApplication
-Object path [variable prefix]/health_app_ZZZZ
+Interface org.bluez.HealthDevice
+Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX
Methods:
- void Echo(object service)
+ Boolean Echo()
Sends an echo petition to the remote service. Returns True if
response matches with the buffer sent. If some error is detected
- False value is returned and the associated MCL is closed.
+ False value is returned.
Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.OutOfRange
- object CreateChannel(object service, string type)
+ object CreateChannel(object application, string configuration)
- Creates a new data channel with the indicated config to the
- remote Service.
+ Creates a new data channel.
The configuration should indicate the channel quality of
service using one of this values "Reliable", "Streaming", "Any".
@@ -76,16 +74,27 @@ Methods:
void DestroyChannel(object channel)
- Destroys the data channel object.
+ Destroys the data channel object. Only the creator of the
+ channel or the creator of the HealtApplication that received the
+ data channel will be able to destroy it
Possible errors: org.bluez.Error.InvalidArguments
- orb.bluez.Error.NotFound
+ org.bluez.Error.NotFound
+ org.bluez.Error.NotAllowed
---------------------------------------------------------------------------------
+Signals:
-Service org.bluez
-Interface org.bluez.HealthService
-Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY
+ void ChannelConnected(object channel)
+
+ This signal is launched when a new data channel is created or
+ when a known data channel is reconnected.
+
+ void ChannelDeleted(object channel)
+
+ This signal is launched when a data channel is deleted.
+
+ After this signal the data channel path will not be valid and
+ its path can be reused for future data channels.
--------------------------------------------------------------------------------
@@ -94,6 +103,9 @@ Interface org.bluez.HealthChannel
Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/
hdp_YYYY/channel_ZZ
+Only the process that created the data channel or the creator of the
+HealthApplication that received it will be able to call this methods.
+
Methods:
dict GetProperties()
@@ -101,17 +113,23 @@ Methods:
Returns all properties for the interface. See the properties
section for available properties.
+ Posible errors: org.bluez.Error.NotAllowed
+
fd Acquire()
Returns the file descriptor for this data channel. If the data
channel is not connected it will also reconnect.
Possible errors: org.bluez.Error.NotConnected
+ org.bluez.Error.NotAllowed
void Release()
Releases the fd. Application should also need to close() it.
+ Possible errors: org.bluez.Error.NotAcquired
+ org.bluez.Error.NotAllowed
+
Properties:
string Type (read only)
@@ -119,50 +137,7 @@ Properties:
The quality of service of the data channel. ("Reliable" or
"Streaming")
- object Service (read only)
-
- Identifies the Remote Service that is connected with. Maps with
- a HealthService object.
-
-HealthAgent hierarchy
-=====================
-
-(this object is implemented by the HDP user in order to receive notifications)
-
-Service unique name
-Interface org.bluez.HealthAgent
-Object path freely definable
-
-Methods:
-
- void Release()
-
- This method gets called when the service daemon unregisters the
- agent. An agent can use it to do cleanup tasks. There is no need
- to unregister the agent, because when this method gets called it
- has already been unregistered.
-
- void ServiceDiscovered(object service)
-
- This method is called when a device containing an HDP
- application is paired or when the method Update of the
- HealthManager is called and new HealthServices are discovered.
- The method will be called once for each HealthService.
-
- void ServiceRemoved(object service)
-
- This is called if during an Update some HealthServices
- have disappeared. The method is called once for each removed
- HealthService.
-
- void ChannelConnected(object channel)
-
- This method is called when a new data channel is created or when
- a known data channel is reconnected.
-
- void ChannelDeleted(object channel)
-
- This method is called when a data channel is deleted.
+ object Device (read only)
- After this call the data channel path will not be valid and can
- be reused for future creation of data channels.
+ Identifies the Remote Device that is connected with. Maps with
+ a HealthDevice object.
--
1.7.0.4
^ permalink raw reply related
* RE: L2cap Security And Role Switch
From: Waldemar.Rymarkiewicz @ 2010-08-05 12:54 UTC (permalink / raw)
To: mcprabhakaran; +Cc: linux-bluetooth
In-Reply-To: <AANLkTikQMqvPQ8-Gv6CqSGgL0fv7ZV3ji4TQUvgkQFGe@mail.gmail.com>
Hi
>-----Original Message-----
>From: Prabhakaran M.C [mailto:mcprabhakaran@gmail.com]
>Sent: Thursday, August 05, 2010 2:44 PM
>To: Rymarkiewicz Waldemar
>Cc: linux-bluetooth@vger.kernel.org
>Subject: Re: L2cap Security And Role Switch
>
>Hi ,
>
>2010/8/5 <Waldemar.Rymarkiewicz@tieto.com>:
>> Hi,
>>
>>>-----Original Message-----
>>>From: Prabhakaran M.C [mailto:mcprabhakaran@gmail.com]
>>>Sent: Thursday, August 05, 2010 12:38 PM
>>>To: Rymarkiewicz Waldemar
>>>Cc: linux-bluetooth@vger.kernel.org
>>>Subject: Re: L2cap Security And Role Switch
>>>
>>>Hi Waldek,
>>>
>>>On Thu, Aug 5, 2010 at 3:37 PM,
>>><Waldemar.Rymarkiewicz@tieto.com> wrote:
>>>> Hi,
>>>>
>>>>>-----Original Message-----
>>>>>From: linux-bluetooth-owner@vger.kernel.org
>>>>>[mailto:linux-bluetooth-owner@vger.kernel.org] On Behalf Of
>>>>>Prabhakaran M.C
>>>>>Sent: Wednesday, August 04, 2010 4:09 PM
>>>>>To: linux-bluetooth@vger.kernel.org
>>>>>Subject: Reg: L2cap Security And Role Switch
>>>>>
>>>>>Hello All,
>>>>>
>>>>> Whenever L2cap security is HIGH and remote device does
>role switch,
>>>>>Bluez accepts the Role switch and L2cap disconnects the channel
>>>>>because of HIGH security.
>>>>>
>>>>> For PAN profile, I would like to keep the L2cap security to HIGH
>>>>>since it involves internet browsing but the Widcomm stack
>>>always does
>>>>>a role switch in PAN connection and Bluez disconnects
>l2cap channel.
>>>>>
>>>>> Can someone please point in specification about the l2cap
>security
>>>>>level and Role switch relation. I tried to find out this
>but I could
>>>>>not get this behavior described in specification. Please
>>>provide your
>>>>>comments and inputs. Thanks in Advance.
>>>>>
>>>>>Thanks,
>>>>>Prabhakaran.
>>>>>--
>>>>
>>>> Note that HIGH sec level requires encription on the link.
>>>Role switch procedure turn off the encription before it starts
>>>switching roles and turn on it again after all. In 2.1 spec the
>>>controller handles switching off/on encription (pause/resume).
>>>>
>>>> Thanks,
>>>> /Waldek
>>>
>>> From the logs, the link was authenticated and encrypted.
>>>Then Widcomm stack disables the encryption, does a role switch,
>>>enables the encryption.
>>>After role switch bluez kernel disconnects l2cap channel due to HIGH
>>>security. I just want to know where this disconnection part
>is defined
>>>in spec. Or Bluez has to just reject the role switch
>operation instead
>>>of disconnection?
>>>
>>>--
>>>Thanks,
>>>Prabhakaran.
>>
>> As far as I know it's not defined in the spec. It's simply
>Bluez design. What I would like to see, the bluez should block
>outgoing data flow in l2cap for the period of role switch.
>> It's done in rfcomm this way, I guess (?).
>>
>> I agree, in my view the current desing in this use case is
>not perfect.
>>
>> Thanks,
>> /Waldek
>>
>>
>>
>>
>>
>>
>>
>
>Thanks for your response.
>One small correction here (My Bad). The l2cap channel is
>getting closed because encryption of the link goes down during
>role switch.
>"l2cap_check_encryption" function validates the encryption, if
>it is disabled and security is high then channel is getting
>closed by this function. Please let me know your comments about this.
>
>--
>Thanks,
>Prabhakaran.
As I said, if the encryption is disabled due to role switch, l2cap should block data flow and wait some time when the encription is switched on again. If this will not occur l2cap shoudl close the channel otherwise should continue as before the role switch.
Thanks,
/Waldek
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox