* [PATCH 1/6] Add phonebook_req_cancel prototype
From: Dmitriy Paliy @ 2010-11-24 15:07 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Dmitriy Paliy
In-Reply-To: <1290611236-25656-1-git-send-email-dmitriy.paliy@nokia.com>
Add phonebook_req_cancel function prototype to cancel pending request
to backend.
---
plugins/phonebook.h | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/plugins/phonebook.h b/plugins/phonebook.h
index d7cfa46..7ae5ccc 100644
--- a/plugins/phonebook.h
+++ b/plugins/phonebook.h
@@ -107,3 +107,9 @@ int phonebook_get_entry(const char *folder, const char *id,
*/
int phonebook_create_cache(const char *name, phonebook_entry_cb entry_cb,
phonebook_cache_ready_cb ready_cb, void *user_data);
+
+/*
+ * Function used to cancel pending request to backend and free resources
+ * allocated for phonebook request structure.
+ */
+void phonebook_req_cancel(void *request);
--
1.7.0.4
^ permalink raw reply related
* [PATCH 0/6 v2] Cancel pending phonebook request
From: Dmitriy Paliy @ 2010-11-24 15:07 UTC (permalink / raw)
To: linux-bluetooth
Hi,
This is optimized version of previous submission
[PATCH 0/7] Cancel pending phonebook request
In these patches only pointer to pending call is returned from
phonebook_..._open functions, while no other structure is created.
For tracker this call is DBusPendingCall and for phonebook-dummy
and phonebook-ebook it is NULL.
Also, query_tracker is modified appropriately.
BR,
Dmitriy
^ permalink raw reply
* Re: [PATCH 2/3] Bluetooth: Add initial Bluetooth Management interface callbacks
From: Andrei Emeltchenko @ 2010-11-24 14:55 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth, Johan Hedberg
In-Reply-To: <1290609575-28435-3-git-send-email-johan.hedberg@gmail.com>
Hi,
On Wed, Nov 24, 2010 at 4:39 PM, <johan.hedberg@gmail.com> wrote:
> From: Johan Hedberg <johan.hedberg@nokia.com>
>
> Add initial code for handling Bluetooth Management interface messages.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
> ---
> include/net/bluetooth/hci_core.h | 3 +
> net/bluetooth/Makefile | 2 +-
> net/bluetooth/hci_sock.c | 39 +++++++++++++--
> net/bluetooth/mgmt.c | 99 ++++++++++++++++++++++++++++++++++++++
> 4 files changed, 136 insertions(+), 7 deletions(-)
> create mode 100644 net/bluetooth/mgmt.c
>
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index b8104af..dd1573da 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -660,6 +660,9 @@ void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
> /* ----- HCI Sockets ----- */
> void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
>
> +/* Management interface */
> +int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
> +
> /* HCI info for socket */
> #define hci_pi(sk) ((struct hci_pinfo *) sk)
>
> diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
> index d1e433f..8b411d9 100644
> --- a/net/bluetooth/Makefile
> +++ b/net/bluetooth/Makefile
> @@ -10,4 +10,4 @@ obj-$(CONFIG_BT_BNEP) += bnep/
> obj-$(CONFIG_BT_CMTP) += cmtp/
> obj-$(CONFIG_BT_HIDP) += hidp/
>
> -bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o
> +bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o
> diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
> index 83acd16..730a4e8 100644
> --- a/net/bluetooth/hci_sock.c
> +++ b/net/bluetooth/hci_sock.c
> @@ -49,6 +49,8 @@
> #include <net/bluetooth/bluetooth.h>
> #include <net/bluetooth/hci_core.h>
>
> +static int enable_mgmt = 0;
> +
> /* ----- HCI socket interface ----- */
>
> static inline int hci_test_bit(int nr, void *addr)
> @@ -352,25 +354,35 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long a
>
> static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
> {
> - struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
> + struct sockaddr_hci haddr;
> struct sock *sk = sock->sk;
> struct hci_dev *hdev = NULL;
> - int err = 0;
> + int len, err = 0;
>
> BT_DBG("sock %p sk %p", sock, sk);
>
> - if (!haddr || haddr->hci_family != AF_BLUETOOTH)
> + if (!addr)
> + return -EINVAL;
> +
> + memset(&haddr, 0, sizeof(haddr));
> + len = min_t(unsigned int, sizeof(haddr), addr_len);
> + memcpy(&haddr, addr, len);
> +
> + if (haddr.hci_family != AF_BLUETOOTH)
> + return -EINVAL;
> +
> + if (haddr.hci_channel != HCI_CHANNEL_RAW && !enable_mgmt)
> return -EINVAL;
>
> lock_sock(sk);
>
> - if (hci_pi(sk)->hdev) {
> + if (sk->sk_state == BT_BOUND || hci_pi(sk)->hdev) {
> err = -EALREADY;
> goto done;
> }
>
> - if (haddr->hci_dev != HCI_DEV_NONE) {
> - if (!(hdev = hci_dev_get(haddr->hci_dev))) {
> + if (haddr.hci_dev != HCI_DEV_NONE) {
> + if (!(hdev = hci_dev_get(haddr.hci_dev))) {
doesn't checkpatch give errors here? Would be more clean like:
...
hdev = hci_dev_get(haddr.hci_dev);
if (!hdev)
...
At some point shall be fixed in the old code also
otherwise looks fine
Acked-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
> err = -ENODEV;
> goto done;
> }
> @@ -378,6 +390,7 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
> atomic_inc(&hdev->promisc);
> }
>
> + hci_pi(sk)->channel = haddr.hci_channel;
> hci_pi(sk)->hdev = hdev;
> sk->sk_state = BT_BOUND;
>
> @@ -499,6 +512,17 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
>
> lock_sock(sk);
>
> + switch (hci_pi(sk)->channel) {
> + case HCI_CHANNEL_RAW:
> + break;
> + case HCI_CHANNEL_CONTROL:
> + err = mgmt_control(sk, msg, len);
> + goto done;
> + default:
> + err = -EINVAL;
> + goto done;
> + }
> +
> if (!(hdev = hci_pi(sk)->hdev)) {
> err = -EBADFD;
> goto done;
> @@ -826,3 +850,6 @@ void __exit hci_sock_cleanup(void)
>
> proto_unregister(&hci_sk_proto);
> }
> +
> +module_param(enable_mgmt, bool, 0644);
> +MODULE_PARM_DESC(enable_mgmt, "Enable Management interface");
> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> new file mode 100644
> index 0000000..78255f1
> --- /dev/null
> +++ b/net/bluetooth/mgmt.c
> @@ -0,0 +1,99 @@
> +/*
> + BlueZ - Bluetooth protocol stack for Linux
> + Copyright (C) 2010 Nokia Corporation
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License version 2 as
> + published by the Free Software Foundation;
> +
> + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
> + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
> + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
> + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> +
> + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
> + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
> + SOFTWARE IS DISCLAIMED.
> +*/
> +
> +/* Bluetooth HCI Management interface */
> +
> +#include <asm/uaccess.h>
> +#include <asm/unaligned.h>
> +
> +#include <net/bluetooth/bluetooth.h>
> +#include <net/bluetooth/hci_core.h>
> +#include <net/bluetooth/mgmt.h>
> +
> +static void cmd_status(struct sock *sk, u16 cmd, u8 status)
> +{
> + struct sk_buff *skb;
> + struct mgmt_hdr *hdr;
> + struct mgmt_ev_cmd_status *ev;
> +
> + BT_DBG("sock %p", sk);
> +
> + skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC);
> + if (!skb)
> + return;
> +
> + hdr = (void *) skb_put(skb, sizeof(struct mgmt_hdr));
> +
> + hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS);
> + hdr->len = cpu_to_le16(3);
> +
> + ev = (void *) skb_put(skb, sizeof(*ev));
> + ev->status = status;
> + put_unaligned_le16(cmd, &ev->opcode);
> +
> + if (sock_queue_rcv_skb(sk, skb) < 0)
> + kfree_skb(skb);
> +}
> +
> +int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
> +{
> + unsigned char *buf;
> + struct mgmt_hdr *hdr;
> + u16 opcode, len;
> + int err;
> +
> + BT_DBG("got %zu bytes", msglen);
> +
> + if (msglen < sizeof(*hdr))
> + return -EINVAL;
> +
> + buf = kmalloc(msglen, GFP_ATOMIC);
> + if (!buf)
> + return -ENOMEM;
> +
> + if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
> + err = -EFAULT;
> + goto done;
> + }
> +
> + hdr = (struct mgmt_hdr *) buf;
> + opcode = get_unaligned_le16(&hdr->opcode);
> + len = get_unaligned_le16(&hdr->len);
> +
> + if (len != msglen - sizeof(struct mgmt_hdr)) {
> + err = -EINVAL;
> + goto done;
> + }
> +
> + switch (opcode) {
> + default:
> + BT_DBG("Unknown op %u", opcode);
> + cmd_status(sk, opcode, 0x01);
> + break;
> + }
> +
> + err = msglen;
> +
> +done:
> + kfree(buf);
> + return err;
> +}
> --
> 1.7.2.3
>
> --
> 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: [PATCH 3/3] Bluetooth: Make hci_send_to_sock usable for management control sockets
From: Marcel Holtmann @ 2010-11-24 14:49 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth, Johan Hedberg
In-Reply-To: <1290609575-28435-4-git-send-email-johan.hedberg@gmail.com>
Hi Johan,
> In order to send data to management control sockets the function should:
>
> - skip checks intended for raw HCI data and stack internal events
> - make sure RAW HCI data or stack internal events don't go to
> management control sockets
>
> In order to accomplish this the patch adds a new member to the bluetooth
> skb private data to flag skb's that are destined for management control
> sockets.
looks fine to me.
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply
* Re: [PATCH 2/3] Bluetooth: Add initial Bluetooth Management interface callbacks
From: Marcel Holtmann @ 2010-11-24 14:48 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth, Johan Hedberg
In-Reply-To: <1290609575-28435-3-git-send-email-johan.hedberg@gmail.com>
Hi Johan,
> Add initial code for handling Bluetooth Management interface messages.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
> ---
> include/net/bluetooth/hci_core.h | 3 +
> net/bluetooth/Makefile | 2 +-
> net/bluetooth/hci_sock.c | 39 +++++++++++++--
> net/bluetooth/mgmt.c | 99 ++++++++++++++++++++++++++++++++++++++
> 4 files changed, 136 insertions(+), 7 deletions(-)
> create mode 100644 net/bluetooth/mgmt.c
looks good.
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply
* Re: [PATCH 1/3] Bluetooth: Add Bluetooth Management interface definitions
From: Marcel Holtmann @ 2010-11-24 14:47 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth, Johan Hedberg
In-Reply-To: <1290609575-28435-2-git-send-email-johan.hedberg@gmail.com>
Hi Johan,
> Add initial definitions for the new Bluetooth Management interface to
> the bluetooth headers.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
> ---
> include/net/bluetooth/hci.h | 4 +++
> include/net/bluetooth/hci_core.h | 1 +
> include/net/bluetooth/mgmt.h | 46 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 51 insertions(+), 0 deletions(-)
> create mode 100644 include/net/bluetooth/mgmt.h
looks fine to me.
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply
* Re: [RFC 12/20] Bluetooth: fix receiving L2CAP packets over LE
From: Vinicius Costa Gomes @ 2010-11-24 14:47 UTC (permalink / raw)
To: Ville Tervo; +Cc: ext Vinicius Costa Gomes, linux-bluetooth
In-Reply-To: <20101124053202.GH874@null>
Hi Ville,
On 07:32 Wed 24 Nov, Ville Tervo wrote:
> Hi,
>
>
> On Tue, Nov 23, 2010 at 12:06:28PM -0300, ext Vinicius Costa Gomes wrote:
> > As L2CAP packets coming over LE don't have any more encapsulation,
> > other than L2CAP, we are able to process them as soon as they arrive.
> >
>
> I thought this patch was only fixing symphoms of broken controller? LE frames
> should have same continuation bits as ACL. See Vol 2 Part E 5.4.2.
You are right. Broken controller. A better behaved one has the right flags.
Will drop this patch.
>
> > Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> > ---
> > net/bluetooth/l2cap.c | 17 +++++++++++++++--
> > 1 files changed, 15 insertions(+), 2 deletions(-)
> >
> > diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> > index e481d6b..0d168aa 100644
> > --- a/net/bluetooth/l2cap.c
> > +++ b/net/bluetooth/l2cap.c
> > @@ -4798,17 +4798,30 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
> > static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
> > {
> > struct l2cap_conn *conn = hcon->l2cap_data;
> > + struct l2cap_hdr *hdr;
> > + int len;
> >
> > if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
> > goto drop;
> >
> > BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
> >
> > + if (hcon->type == LE_LINK) {
> > + hdr = (struct l2cap_hdr *) skb->data;
> > + len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
> > +
> > + if (len == skb->len) {
> > + /* Complete frame received */
> > + l2cap_recv_frame(conn, skb);
> > + return 0;
> > + }
> > +
> > + goto drop;
> > + }
> > +
> > if (flags & ACL_START) {
> > - struct l2cap_hdr *hdr;
> > struct sock *sk;
> > u16 cid;
> > - int len;
> >
> > if (conn->rx_len) {
> > BT_ERR("Unexpected start frame (len %d)", skb->len);
> > --
> > 1.7.3.2
> >
> > --
> > 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
* [PATCH 3/3] Bluetooth: Make hci_send_to_sock usable for management control sockets
From: johan.hedberg @ 2010-11-24 14:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Johan Hedberg
In-Reply-To: <1290609575-28435-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
In order to send data to management control sockets the function should:
- skip checks intended for raw HCI data and stack internal events
- make sure RAW HCI data or stack internal events don't go to
management control sockets
In order to accomplish this the patch adds a new member to the bluetooth
skb private data to flag skb's that are destined for management control
sockets.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
include/net/bluetooth/bluetooth.h | 1 +
net/bluetooth/hci_sock.c | 10 +++++++++-
2 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index d81ea79..0c5e725 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -144,6 +144,7 @@ struct bt_skb_cb {
__u8 tx_seq;
__u8 retries;
__u8 sar;
+ unsigned short channel;
};
#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 730a4e8..ab449b2 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -104,6 +104,12 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
if (skb->sk == sk)
continue;
+ if (bt_cb(skb)->channel != hci_pi(sk)->channel)
+ continue;
+
+ if (bt_cb(skb)->channel == HCI_CHANNEL_CONTROL)
+ goto clone;
+
/* Apply filter */
flt = &hci_pi(sk)->filter;
@@ -127,11 +133,13 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
continue;
}
+clone:
if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
continue;
/* Put type byte before the data */
- memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1);
+ if (bt_cb(skb)->channel == HCI_CHANNEL_RAW)
+ memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1);
if (sock_queue_rcv_skb(sk, nskb))
kfree_skb(nskb);
--
1.7.2.3
^ permalink raw reply related
* [PATCH 2/3] Bluetooth: Add initial Bluetooth Management interface callbacks
From: johan.hedberg @ 2010-11-24 14:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Johan Hedberg
In-Reply-To: <1290609575-28435-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
Add initial code for handling Bluetooth Management interface messages.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
include/net/bluetooth/hci_core.h | 3 +
net/bluetooth/Makefile | 2 +-
net/bluetooth/hci_sock.c | 39 +++++++++++++--
net/bluetooth/mgmt.c | 99 ++++++++++++++++++++++++++++++++++++++
4 files changed, 136 insertions(+), 7 deletions(-)
create mode 100644 net/bluetooth/mgmt.c
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index b8104af..dd1573da 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -660,6 +660,9 @@ void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
/* ----- HCI Sockets ----- */
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
+/* Management interface */
+int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
+
/* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *) sk)
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index d1e433f..8b411d9 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -10,4 +10,4 @@ obj-$(CONFIG_BT_BNEP) += bnep/
obj-$(CONFIG_BT_CMTP) += cmtp/
obj-$(CONFIG_BT_HIDP) += hidp/
-bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o
+bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 83acd16..730a4e8 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -49,6 +49,8 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
+static int enable_mgmt = 0;
+
/* ----- HCI socket interface ----- */
static inline int hci_test_bit(int nr, void *addr)
@@ -352,25 +354,35 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long a
static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
{
- struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
+ struct sockaddr_hci haddr;
struct sock *sk = sock->sk;
struct hci_dev *hdev = NULL;
- int err = 0;
+ int len, err = 0;
BT_DBG("sock %p sk %p", sock, sk);
- if (!haddr || haddr->hci_family != AF_BLUETOOTH)
+ if (!addr)
+ return -EINVAL;
+
+ memset(&haddr, 0, sizeof(haddr));
+ len = min_t(unsigned int, sizeof(haddr), addr_len);
+ memcpy(&haddr, addr, len);
+
+ if (haddr.hci_family != AF_BLUETOOTH)
+ return -EINVAL;
+
+ if (haddr.hci_channel != HCI_CHANNEL_RAW && !enable_mgmt)
return -EINVAL;
lock_sock(sk);
- if (hci_pi(sk)->hdev) {
+ if (sk->sk_state == BT_BOUND || hci_pi(sk)->hdev) {
err = -EALREADY;
goto done;
}
- if (haddr->hci_dev != HCI_DEV_NONE) {
- if (!(hdev = hci_dev_get(haddr->hci_dev))) {
+ if (haddr.hci_dev != HCI_DEV_NONE) {
+ if (!(hdev = hci_dev_get(haddr.hci_dev))) {
err = -ENODEV;
goto done;
}
@@ -378,6 +390,7 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
atomic_inc(&hdev->promisc);
}
+ hci_pi(sk)->channel = haddr.hci_channel;
hci_pi(sk)->hdev = hdev;
sk->sk_state = BT_BOUND;
@@ -499,6 +512,17 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
lock_sock(sk);
+ switch (hci_pi(sk)->channel) {
+ case HCI_CHANNEL_RAW:
+ break;
+ case HCI_CHANNEL_CONTROL:
+ err = mgmt_control(sk, msg, len);
+ goto done;
+ default:
+ err = -EINVAL;
+ goto done;
+ }
+
if (!(hdev = hci_pi(sk)->hdev)) {
err = -EBADFD;
goto done;
@@ -826,3 +850,6 @@ void __exit hci_sock_cleanup(void)
proto_unregister(&hci_sk_proto);
}
+
+module_param(enable_mgmt, bool, 0644);
+MODULE_PARM_DESC(enable_mgmt, "Enable Management interface");
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
new file mode 100644
index 0000000..78255f1
--- /dev/null
+++ b/net/bluetooth/mgmt.c
@@ -0,0 +1,99 @@
+/*
+ BlueZ - Bluetooth protocol stack for Linux
+ Copyright (C) 2010 Nokia Corporation
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2 as
+ published by the Free Software Foundation;
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
+ SOFTWARE IS DISCLAIMED.
+*/
+
+/* Bluetooth HCI Management interface */
+
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/mgmt.h>
+
+static void cmd_status(struct sock *sk, u16 cmd, u8 status)
+{
+ struct sk_buff *skb;
+ struct mgmt_hdr *hdr;
+ struct mgmt_ev_cmd_status *ev;
+
+ BT_DBG("sock %p", sk);
+
+ skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC);
+ if (!skb)
+ return;
+
+ hdr = (void *) skb_put(skb, sizeof(struct mgmt_hdr));
+
+ hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS);
+ hdr->len = cpu_to_le16(3);
+
+ ev = (void *) skb_put(skb, sizeof(*ev));
+ ev->status = status;
+ put_unaligned_le16(cmd, &ev->opcode);
+
+ if (sock_queue_rcv_skb(sk, skb) < 0)
+ kfree_skb(skb);
+}
+
+int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
+{
+ unsigned char *buf;
+ struct mgmt_hdr *hdr;
+ u16 opcode, len;
+ int err;
+
+ BT_DBG("got %zu bytes", msglen);
+
+ if (msglen < sizeof(*hdr))
+ return -EINVAL;
+
+ buf = kmalloc(msglen, GFP_ATOMIC);
+ if (!buf)
+ return -ENOMEM;
+
+ if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
+ err = -EFAULT;
+ goto done;
+ }
+
+ hdr = (struct mgmt_hdr *) buf;
+ opcode = get_unaligned_le16(&hdr->opcode);
+ len = get_unaligned_le16(&hdr->len);
+
+ if (len != msglen - sizeof(struct mgmt_hdr)) {
+ err = -EINVAL;
+ goto done;
+ }
+
+ switch (opcode) {
+ default:
+ BT_DBG("Unknown op %u", opcode);
+ cmd_status(sk, opcode, 0x01);
+ break;
+ }
+
+ err = msglen;
+
+done:
+ kfree(buf);
+ return err;
+}
--
1.7.2.3
^ permalink raw reply related
* [PATCH 1/3] Bluetooth: Add Bluetooth Management interface definitions
From: johan.hedberg @ 2010-11-24 14:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Johan Hedberg
In-Reply-To: <1290609575-28435-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
Add initial definitions for the new Bluetooth Management interface to
the bluetooth headers.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
include/net/bluetooth/hci.h | 4 +++
include/net/bluetooth/hci_core.h | 1 +
include/net/bluetooth/mgmt.h | 46 ++++++++++++++++++++++++++++++++++++++
3 files changed, 51 insertions(+), 0 deletions(-)
create mode 100644 include/net/bluetooth/mgmt.h
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index e30e008..bf39eef 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -934,9 +934,13 @@ static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb)
struct sockaddr_hci {
sa_family_t hci_family;
unsigned short hci_dev;
+ unsigned short hci_channel;
};
#define HCI_DEV_NONE 0xffff
+#define HCI_CHANNEL_RAW 0
+#define HCI_CHANNEL_CONTROL 1
+
struct hci_filter {
unsigned long type_mask;
unsigned long event_mask[2];
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index ebec8c9..b8104af 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -668,6 +668,7 @@ struct hci_pinfo {
struct hci_dev *hdev;
struct hci_filter filter;
__u32 cmsg_mask;
+ unsigned short channel;
};
/* HCI security filter */
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
new file mode 100644
index 0000000..95974da
--- /dev/null
+++ b/include/net/bluetooth/mgmt.h
@@ -0,0 +1,46 @@
+/*
+ BlueZ - Bluetooth protocol stack for Linux
+
+ Copyright (C) 2010 Nokia Corporation
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2 as
+ published by the Free Software Foundation;
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
+ SOFTWARE IS DISCLAIMED.
+*/
+
+struct mgmt_hdr {
+ __le16 opcode;
+ __le16 len;
+} __packed;
+#define MGMT_HDR_SIZE 4
+
+#define MGMT_EV_CMD_COMPLETE 0x0001
+struct mgmt_ev_cmd_complete {
+ __le16 opcode;
+ __u8 data[0];
+} __packed;
+
+#define MGMT_EV_CMD_STATUS 0x0002
+struct mgmt_ev_cmd_status {
+ __u8 status;
+ __le16 opcode;
+} __packed;
+
+#define MGMT_EV_CONTROLLER_ERROR 0x0003
+struct mgmt_ev_controller_error {
+ __le16 index;
+ __u8 error_code;
+} __packed;
--
1.7.2.3
^ permalink raw reply related
* Initial set of Management interface patches
From: johan.hedberg @ 2010-11-24 14:39 UTC (permalink / raw)
To: linux-bluetooth
Hi,
Here's an initial (short) set of patches for the upcoming management
interface which should hopefully be quite straght forward. Since
bluetoothd will nowdays automatically pick up and try to use this
interface it's disabled by default and can be enabled with the
enable_mgmt module parameter. I.e. it should be safe to push these
towards upstream trees. Once I've received acks on these I'll start
preparing the patches which add some real functionality (i.e. message
handling) for managment sockets.
Johan
^ permalink raw reply
* RE: Enabling SCO mode
From: Peter Hurley @ 2010-11-24 14:29 UTC (permalink / raw)
To: Greg Mercurio, linux-bluetooth@vger.kernel.org
In-Reply-To: <734620.13775.qm@web65716.mail.ac4.yahoo.com>
SGkgR3JlZywNCg0KPiBTdWJqZWN0OiBFbmFibGluZyBTQ08gbW9kZQ0KPiANCj4gSSBhbSBuZXcg
dG8gQmx1ZXogYW5kIGhhdmUgYSBxdWVzdGlvbiBhYm91dCBzY28gYXVkaW8uICBJIGFtIHVzaW5n
DQo+IEJsdWV6IHZlcnNpb24gNC40NyBpbiBhbiBBbmRyb2lkIGVudmlyb25tZW50Lg0KLi4uDQo+
IENhbiBzb21lb25lIGNvbmZpcm0gbXkgYXNzdW1wdGlvbnMgYW5kIHBvaW50IG1lIHRvIHRoZSBw
bGFjZSBpbiB0aGUNCj4gY29kZSB3aGVyZSBlbmFibGluZyB0aGUgc2NvIGNvbW1hbmRzIGFyZSBz
ZW50IHRvIHRoZSBjaGlwPw0KDQpUaGUgSENJIGNvZGUgaXMgaW4gdGhlIEFuZHJvaWQga2VybmVs
LiBUaGUgQW5kcm9pZCBrZXJuZWwgZ2l0IHRyZWUgaXMgYXQgZ2l0Oi8vYW5kcm9pZC5naXQua2Vy
bmVsLm9yZy9rZXJuZWwvY29tbW9uLmdpdC4gVGhlIEJUIGNvZGUgeW91J3JlIGludGVyZXN0ZWQg
aW4gaXMgaW4gdGhlIG5ldC9ibHVldG9vdGggc3ViZGlyIC0gc3BlY2lmaWNhbGx5IGhjaV9jb25u
LmMvaGNpX2Nvbm5lY3QoKS4NCg0KUmVnYXJkcywNClBldGVyIEh1cmxleQ0KIA0KDQo=
^ permalink raw reply
* Re: [PATCH v2] Bluetooth: Fix error handling for l2cap_init()
From: Marcel Holtmann @ 2010-11-24 12:42 UTC (permalink / raw)
To: Anderson Lizardo; +Cc: linux-bluetooth, padovan
In-Reply-To: <1290423434-2920-1-git-send-email-anderson.lizardo@openbossa.org>
Hi Anderson,
> create_singlethread_workqueue() may fail with errors such as -ENOMEM. If
> this happens, the return value is not set to a negative value and the
> module load will succeed. It will then crash on module unload because of
> a destroy_workqueue() call on a NULL pointer.
>
> Additionally, the _busy_wq workqueue is not being destroyed if any
> errors happen on l2cap_init().
>
> Signed-off-by: Anderson Lizardo <anderson.lizardo@openbossa.org>
> ---
> net/bluetooth/l2cap.c | 8 ++++++--
> 1 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index 18a802c..7980e24 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -4875,8 +4875,10 @@ static int __init l2cap_init(void)
> return err;
>
> _busy_wq = create_singlethread_workqueue("l2cap");
> - if (!_busy_wq)
> - goto error;
> + if (!_busy_wq) {
> + err = -ENOMEM;
> + goto error_busy_wq;
> + }
aren't these returning PTR_ERR etc.?
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] Bluetooth: do not use assignment in if condition
From: Marcel Holtmann @ 2010-11-24 12:40 UTC (permalink / raw)
To: Emeltchenko Andrei; +Cc: linux-bluetooth
In-Reply-To: <1290424897-32463-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
> Fix checkpatch errors like:
> "ERROR: do not use assignment in if condition"
> Simplify code and fix one long line.
>
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
> ---
> net/bluetooth/hci_event.c | 18 ++++++++++++------
> 1 files changed, 12 insertions(+), 6 deletions(-)
I am fine with these. It is just pretty old code and it is good that you
start fixing these up.
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply
* Gaining Vendor Documentation
From: Dave Keck @ 2010-11-24 7:01 UTC (permalink / raw)
To: linux-bluetooth
Hi list,
I'm in the process of debugging some Bluetooth software, and I've
discovered a bug for which all evidence implicates the firmware for my
system's Bluetooth chipset (manufactured by Broadcom.) Intending to
workaround this bug, I'm waiting to hear back from Broadcom regarding
the documentation that might exist for my chipset.
I was wondering if anyone has experience dealing with vendors and has
advice towards getting access to their non-public documentation? As an
independent developer, I'm not sure what to expect.
Thanks!
David
(I apologize that this is off-topic, but as Bluetooth stack developers
I couldn't find a better place to ask. I humbly request your
forgiveness.)
^ permalink raw reply
* Re: [RFC 00/20] Simple SMP Just Works implementation
From: Ville Tervo @ 2010-11-24 5:42 UTC (permalink / raw)
To: ext Vinicius Costa Gomes; +Cc: linux-bluetooth, padovan
In-Reply-To: <1290524796-32246-1-git-send-email-vinicius.gomes@openbossa.org>
Hi,
On Tue, Nov 23, 2010 at 12:06:16PM -0300, ext Vinicius Costa Gomes wrote:
> Hi,
>
> This is an implementation of the Just Works SMP procedure, on top of the work
> done by Ville (included in this series to give some context). The SMP stuff
> starts at 11/20.
>
> The most important thing about this series is the discussion that (I hope)
> it will cause.
>
> Some things that I would like to point (in no order):
>
> - the SMP function names follow the spec nomeclature, would it be better to
> use more meaningful names?
>
> - the crypto transform is allocated during the adapter registration, is this
> the best place to do this?
>
> - renaming l2cap.c to l2cap_core.c was the only way we could find to keep the
> SMP implementation separated from the "core" l2cap.
Gustavo do you have something against this change?
>
> I think this is enough to start a discussion.
>
> So, as the Human Torch would say: Flame on! :-)
I'll try to find time to do some testing soon.
>
> Anderson Briglia (3):
> Bluetooth: Start SMP procedure
> Bluetooth: simple SMP pairing negotiation
> Bluetooth: LE SMP Cryptoolbox functions
>
> Ville Tervo (10):
> Bluetooth: Add low energy commands and events
> Bluetooth: Add LE connect support
> Bluetooth: Use LE buffers for LE traffic
> Bluetooth: Add LE connection support to L2CAP
> Bluetooth: Add server socket support for LE connection
> Bluetooth: Do not send disconn comand over LE links
> Bluetooth: Treat LE and ACL links separately on timeout
> Bluetooth: Fix locking balance in l2cap_le_conn_ready
> Bluetooth: Add server socket support for LE connection
> Bluetooth: Add SMP command structures
>
> Vinicius Costa Gomes (7):
> Bluetooth: Fix initiated LE connections
> Bluetooth: fix receiving L2CAP packets over LE
> Bluetooth: Implement the first SMP commands
> Bluetooth: Add support for using the crypto subsystem
> Bluetooth: Add support for SMP confirmation checks
> Bluetooth: Add support for LE Start Encryption
> Bluetooth: Add support for resuming socket when SMP is finished
>
> include/net/bluetooth/hci.h | 86 ++++++
> include/net/bluetooth/hci_core.h | 37 +++-
> include/net/bluetooth/l2cap.h | 10 +
> include/net/bluetooth/smp.h | 80 ++++++
> net/bluetooth/Makefile | 1 +
> net/bluetooth/hci_conn.c | 104 +++++++-
> net/bluetooth/hci_core.c | 94 ++++++-
> net/bluetooth/hci_event.c | 206 ++++++++++++++-
> net/bluetooth/{l2cap.c => l2cap_core.c} | 237 +++++++++++++---
> net/bluetooth/smp.c | 465 +++++++++++++++++++++++++++++++
> 10 files changed, 1264 insertions(+), 56 deletions(-)
> create mode 100644 include/net/bluetooth/smp.h
> rename net/bluetooth/{l2cap.c => l2cap_core.c} (96%)
> create mode 100644 net/bluetooth/smp.c
>
> --
> 1.7.3.2
>
> --
> 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: [RFC 12/20] Bluetooth: fix receiving L2CAP packets over LE
From: Ville Tervo @ 2010-11-24 5:32 UTC (permalink / raw)
To: ext Vinicius Costa Gomes; +Cc: linux-bluetooth
In-Reply-To: <1290524796-32246-13-git-send-email-vinicius.gomes@openbossa.org>
Hi,
On Tue, Nov 23, 2010 at 12:06:28PM -0300, ext Vinicius Costa Gomes wrote:
> As L2CAP packets coming over LE don't have any more encapsulation,
> other than L2CAP, we are able to process them as soon as they arrive.
>
I thought this patch was only fixing symphoms of broken controller? LE frames
should have same continuation bits as ACL. See Vol 2 Part E 5.4.2.
> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> ---
> net/bluetooth/l2cap.c | 17 +++++++++++++++--
> 1 files changed, 15 insertions(+), 2 deletions(-)
>
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index e481d6b..0d168aa 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -4798,17 +4798,30 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
> static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
> {
> struct l2cap_conn *conn = hcon->l2cap_data;
> + struct l2cap_hdr *hdr;
> + int len;
>
> if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
> goto drop;
>
> BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
>
> + if (hcon->type == LE_LINK) {
> + hdr = (struct l2cap_hdr *) skb->data;
> + len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
> +
> + if (len == skb->len) {
> + /* Complete frame received */
> + l2cap_recv_frame(conn, skb);
> + return 0;
> + }
> +
> + goto drop;
> + }
> +
> if (flags & ACL_START) {
> - struct l2cap_hdr *hdr;
> struct sock *sk;
> u16 cid;
> - int len;
>
> if (conn->rx_len) {
> BT_ERR("Unexpected start frame (len %d)", skb->len);
> --
> 1.7.3.2
>
> --
> 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: [RFC 06/20] Bluetooth: Do not send disconn comand over LE links
From: Ville Tervo @ 2010-11-24 5:05 UTC (permalink / raw)
To: ext Gustavo F. Padovan; +Cc: Vinicius Costa Gomes, linux-bluetooth
In-Reply-To: <20101123224839.GA11860@vigoh>
On Tue, Nov 23, 2010 at 08:48:39PM -0200, ext Gustavo F. Padovan wrote:
> * Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2010-11-23 12:06:22 -0300]:
>
> > From: Ville Tervo <ville.tervo@nokia.com>
> >
> > l2cap over LE links can be disconnected without sending
> > disconnect command first.
> >
> > Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
> > ---
> > net/bluetooth/l2cap.c | 15 ++++++++++-----
> > 1 files changed, 10 insertions(+), 5 deletions(-)
> >
> > diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> > index 0b583c4..5894662 100644
> > --- a/net/bluetooth/l2cap.c
> > +++ b/net/bluetooth/l2cap.c
> > @@ -873,6 +873,8 @@ static void l2cap_sock_kill(struct sock *sk)
> >
> > static void __l2cap_sock_close(struct sock *sk, int reason)
> > {
> > + struct l2cap_conn *conn;
> > +
> > BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
> >
> > switch (sk->sk_state) {
> > @@ -882,8 +884,10 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
> >
> > case BT_CONNECTED:
> > case BT_CONFIG:
> > - if (sk->sk_type == SOCK_SEQPACKET ||
> > - sk->sk_type == SOCK_STREAM) {
> > + conn = l2cap_pi(sk)->conn;
> > + if ((sk->sk_type == SOCK_SEQPACKET ||
> > + sk->sk_type == SOCK_STREAM) &&
> > + conn->hcon->type != LE_LINK) {
>
> Makes more senses check for conn->hcon->type == ACL_LINK.
Will be changed.
>
> > struct l2cap_conn *conn = l2cap_pi(sk)->conn;
> >
> > l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
> > @@ -893,9 +897,10 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
> > break;
> >
> > case BT_CONNECT2:
> > - if (sk->sk_type == SOCK_SEQPACKET ||
> > - sk->sk_type == SOCK_STREAM) {
> > - struct l2cap_conn *conn = l2cap_pi(sk)->conn;
> > + conn = l2cap_pi(sk)->conn;
> > + if ((sk->sk_type == SOCK_SEQPACKET ||
> > + sk->sk_type == SOCK_STREAM) &&
> > + conn->hcon->type != LE_LINK) {
>
> Same here.
Ditto
--
Ville
^ permalink raw reply
* Re: [RFC 02/20] Bluetooth: Add LE connect support
From: Ville Tervo @ 2010-11-24 5:03 UTC (permalink / raw)
To: ext Gustavo F. Padovan; +Cc: Vinicius Costa Gomes, linux-bluetooth
In-Reply-To: <20101123175705.GD22502@vigoh>
On Tue, Nov 23, 2010 at 03:57:05PM -0200, ext Gustavo F. Padovan wrote:
> Hi Ville,
>
> * Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2010-11-23 12:06:18 -0300]:
>
> > From: Ville Tervo <ville.tervo@nokia.com>
> >
> > Bluetooth V4.0 adds support for Low Energy (LE)
> > connections. Specification introduses new set
> > of hci commands to control LE connection.
> > This patch adds logic to create, cancel and
> > disconnect LE connections
> >
> > Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
>
> I remember Marcel acked some of these patches. Why the ack is not here?
> It makes life easier if you tell who is acking your patch already.
There was more comments which changed the patch after acking.
--
Ville
^ permalink raw reply
* [PATCH 5/5] Don't trigger the discovering when registering the client
From: Claudio Takahasi @ 2010-11-24 2:30 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1290565847-17382-1-git-send-email-claudio.takahasi@openbossa.org>
Discover All Primary Services should not be trigged by the attribute
client when a given device is registered. Discover services is now done
by the device entity.
---
attrib/client.c | 47 +----------------------------------------------
1 files changed, 1 insertions(+), 46 deletions(-)
diff --git a/attrib/client.c b/attrib/client.c
index a851a74..a8a4051 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -1322,16 +1322,8 @@ int attrib_client_register(struct btd_device *device, int psm)
struct btd_adapter *adapter = device_get_adapter(device);
const char *path = device_get_path(device);
struct gatt_service *gatt;
- GError *gerr = NULL;
- GIOChannel *io;
bdaddr_t sba, dba;
- /*
- * Registering fake services/characteristics. The following
- * paths/interfaces shall be registered after discover primary
- * services only.
- */
-
adapter_get_address(adapter, &sba);
device_get_address(device, &dba);
@@ -1343,46 +1335,9 @@ int attrib_client_register(struct btd_device *device, int psm)
bacpy(&gatt->dba, &dba);
gatt->psm = psm;
- if (load_primary_services(gatt)) {
+ if (load_primary_services(gatt))
DBG("Primary services loaded");
- goto done;
- }
-
- if (psm < 0) {
- io = bt_io_connect(BT_IO_L2CAP, connect_cb, gatt, NULL, &gerr,
- BT_IO_OPT_SOURCE_BDADDR, &sba,
- BT_IO_OPT_DEST_BDADDR, &dba,
- BT_IO_OPT_CID, GATT_CID,
- BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
- BT_IO_OPT_INVALID);
-
- DBG("GATT over Low Energy");
- } else {
- io = bt_io_connect(BT_IO_L2CAP, connect_cb, gatt, NULL, &gerr,
- BT_IO_OPT_SOURCE_BDADDR, &sba,
- BT_IO_OPT_DEST_BDADDR, &dba,
- BT_IO_OPT_PSM, psm,
- BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
- BT_IO_OPT_INVALID);
-
- DBG("GATT over Basic Rate");
- }
-
- if (!io) {
- error("%s", gerr->message);
- g_error_free(gerr);
- gatt_service_free(gatt);
- return -1;
- }
-
- gatt->attrib = g_attrib_new(io);
- g_io_channel_unref(io);
- g_attrib_set_destroy_function(gatt->attrib, attrib_destroy, gatt);
- g_attrib_set_disconnect_function(gatt->attrib, attrib_disconnect,
- gatt);
-
-done:
gatt_services = g_slist_append(gatt_services, gatt);
return 0;
--
1.7.3.2
^ permalink raw reply related
* [PATCH 4/5] Fix memory leak of sdp list in the attribute client
From: Claudio Takahasi @ 2010-11-24 2:30 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1290565847-17382-1-git-send-email-claudio.takahasi@openbossa.org>
---
attrib/manager.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/attrib/manager.c b/attrib/manager.c
index 9b06c8c..f991f8e 100644
--- a/attrib/manager.c
+++ b/attrib/manager.c
@@ -44,15 +44,19 @@ static DBusConnection *connection;
static int client_probe(struct btd_device *device, GSList *uuids)
{
const sdp_record_t *rec;
- sdp_list_t *list;
int psm = -1;
rec = btd_device_get_record(device, GATT_UUID);
if (rec) {
+ sdp_list_t *list;
if (sdp_get_access_protos(rec, &list) < 0)
return -1;
psm = sdp_get_proto_port(list, L2CAP_UUID);
+
+ sdp_list_foreach(list, (sdp_list_func_t) sdp_list_free, NULL);
+ sdp_list_free(list, NULL);
+
if (psm < 0)
return -1;
}
--
1.7.3.2
^ permalink raw reply related
* [PATCH 3/5] Return a D-Bus error if device_browse fails
From: Claudio Takahasi @ 2010-11-24 2:30 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1290565847-17382-1-git-send-email-claudio.takahasi@openbossa.org>
If Discover All Primary Services or SDP search fails, the CreateDevice
caller will not receive a response. Error reproducible when a Discover
All Primary Services is sent over a LE link and the kernel doesn't
address properly the connections in the channel ID 4.
---
src/adapter.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 029bec8..6c3396c 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1696,6 +1696,7 @@ static DBusMessage *create_device(DBusConnection *conn,
struct remote_dev_info *dev, match;
const gchar *address;
gboolean le;
+ int err;
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
DBUS_TYPE_INVALID) == FALSE)
@@ -1722,7 +1723,9 @@ static DBusMessage *create_device(DBusConnection *conn,
if (!device)
return NULL;
- device_browse(device, conn, msg, NULL, FALSE);
+ err = device_browse(device, conn, msg, NULL, FALSE);
+ if (err < 0)
+ return failed_strerror(msg, -err);
return NULL;
}
--
1.7.3.2
^ permalink raw reply related
* [PATCH 2/5] Check the device type when creating the device
From: Claudio Takahasi @ 2010-11-24 2:30 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1290565847-17382-1-git-send-email-claudio.takahasi@openbossa.org>
For CreateDevice, if the remote device is LE capable, Discover All
Primary Services shall be issued instead of SDP queries. The logic
to define if the remote is LE capable shall be based on the result
of the interleaved discovery results. Meaning, the remote device
is classified as LE capable only if an advertising event from this
device was collected during the discovery.
Limitation: Advertising event data is not being considered yet to
infer the remote properties and CreateDevice needs to be called
during the discovery session.
---
src/adapter.c | 25 +++++++++++++++++--------
src/adapter.h | 3 ++-
src/device.c | 3 ++-
src/device.h | 5 +++--
4 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 6b4a354..029bec8 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1199,15 +1199,15 @@ sdp_list_t *adapter_get_services(struct btd_adapter *adapter)
}
struct btd_device *adapter_create_device(DBusConnection *conn,
- struct btd_adapter *adapter,
- const char *address)
+ struct btd_adapter *adapter,
+ const char *address, gboolean le)
{
struct btd_device *device;
const char *path;
DBG("%s", address);
- device = device_create(conn, adapter, address);
+ device = device_create(conn, adapter, address, le);
if (!device)
return NULL;
@@ -1266,7 +1266,7 @@ struct btd_device *adapter_get_device(DBusConnection *conn,
if (device)
return device;
- return adapter_create_device(conn, adapter, address);
+ return adapter_create_device(conn, adapter, address, FALSE);
}
static gboolean stop_scanning(gpointer user_data)
@@ -1693,7 +1693,9 @@ static DBusMessage *create_device(DBusConnection *conn,
{
struct btd_adapter *adapter = data;
struct btd_device *device;
+ struct remote_dev_info *dev, match;
const gchar *address;
+ gboolean le;
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
DBUS_TYPE_INVALID) == FALSE)
@@ -1709,7 +1711,14 @@ static DBusMessage *create_device(DBusConnection *conn,
DBG("%s", address);
- device = adapter_create_device(conn, adapter, address);
+ memset(&match, 0, sizeof(struct remote_dev_info));
+ str2ba(address, &match.bdaddr);
+ match.name_status = NAME_ANY;
+
+ dev = adapter_search_found_devices(adapter, &match);
+ le = dev ? dev->le : FALSE;
+
+ device = adapter_create_device(conn, adapter, address, le);
if (!device)
return NULL;
@@ -2003,7 +2012,7 @@ static void create_stored_device_from_profiles(char *key, char *value,
key, (GCompareFunc) device_address_cmp))
return;
- device = device_create(connection, adapter, key);
+ device = device_create(connection, adapter, key, FALSE);
if (!device)
return;
@@ -2026,7 +2035,7 @@ static void create_stored_device_from_linkkeys(char *key, char *value,
(GCompareFunc) device_address_cmp))
return;
- device = device_create(connection, adapter, key);
+ device = device_create(connection, adapter, key, FALSE);
if (device) {
device_set_temporary(device, FALSE);
adapter->devices = g_slist_append(adapter->devices, device);
@@ -2043,7 +2052,7 @@ static void create_stored_device_from_blocked(char *key, char *value,
key, (GCompareFunc) device_address_cmp))
return;
- device = device_create(connection, adapter, key);
+ device = device_create(connection, adapter, key, FALSE);
if (device) {
device_set_temporary(device, FALSE);
adapter->devices = g_slist_append(adapter->devices, device);
diff --git a/src/adapter.h b/src/adapter.h
index de6a6f5..4f5ccdb 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -109,7 +109,8 @@ void adapter_remove_device(DBusConnection *conn, struct btd_adapter *adapter,
struct btd_device *device,
gboolean remove_storage);
struct btd_device *adapter_create_device(DBusConnection *conn,
- struct btd_adapter *adapter, const char *address);
+ struct btd_adapter *adapter,
+ const char *address, gboolean le);
int adapter_resolve_names(struct btd_adapter *adapter);
diff --git a/src/device.c b/src/device.c
index f236b29..1c119d5 100644
--- a/src/device.c
+++ b/src/device.c
@@ -965,7 +965,7 @@ void device_set_secmode3_conn(struct btd_device *device, gboolean enable)
struct btd_device *device_create(DBusConnection *conn,
struct btd_adapter *adapter,
- const gchar *address)
+ const gchar *address, gboolean le)
{
gchar *address_up;
struct btd_device *device;
@@ -993,6 +993,7 @@ struct btd_device *device_create(DBusConnection *conn,
str2ba(address, &device->bdaddr);
device->adapter = adapter;
+ device->le = le;
adapter_get_address(adapter, &src);
ba2str(&src, srcaddr);
read_device_name(srcaddr, address, device->name);
diff --git a/src/device.h b/src/device.h
index b570bd1..a5b6273 100644
--- a/src/device.h
+++ b/src/device.h
@@ -34,8 +34,9 @@ typedef enum {
AUTH_TYPE_AUTO,
} auth_type_t;
-struct btd_device *device_create(DBusConnection *conn, struct btd_adapter *adapter,
- const gchar *address);
+struct btd_device *device_create(DBusConnection *conn,
+ struct btd_adapter *adapter,
+ const gchar *address, gboolean le);
void device_set_name(struct btd_device *device, const char *name);
void device_get_name(struct btd_device *device, char *name, size_t len);
void device_remove(struct btd_device *device, gboolean remove_stored);
--
1.7.3.2
^ permalink raw reply related
* [PATCH 1/5] Implements primary service search when creating a device
From: Claudio Takahasi @ 2010-11-24 2:30 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
Discover primary services implemented inside the device entity to allow
proper integration of attribute plugin. Implements a single entry point
to the attribute plugin no matter the transport(BR/EDR or LE), the device
probe callback is called for both types.
Add a new function to discover all primary services without additional
calls to fetch the remaining primary services, sub-procedure iterations
is handled inside this function.
The next action are: clean the attribute client removing implicity service
and characteristics discovery, issue the Discover Primary Service based on
the remote properties and fetch the characteristic on demand.
---
attrib/manager.c | 27 +++-------
src/device.c | 106 +++++++++++++++++++++++++++++++-------
src/glib-helper.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/glib-helper.h | 5 ++
4 files changed, 246 insertions(+), 39 deletions(-)
diff --git a/attrib/manager.c b/attrib/manager.c
index 9bd1774..9b06c8c 100644
--- a/attrib/manager.c
+++ b/attrib/manager.c
@@ -45,26 +45,17 @@ static int client_probe(struct btd_device *device, GSList *uuids)
{
const sdp_record_t *rec;
sdp_list_t *list;
- int psm;
-
- /*
- * Entry point for BR/EDR GATT probe. LE scanning and primary service
- * search will be handled temporaly inside the gatt plugin. For the
- * final solution all LE operations should be moved to the "core",
- * otherwise it will not be possible serialize/schedule BR/EDR device
- * discovery and LE scanning.
- */
+ int psm = -1;
rec = btd_device_get_record(device, GATT_UUID);
- if (!rec)
- return -1;
-
- if (sdp_get_access_protos(rec, &list) < 0)
- return -1;
-
- psm = sdp_get_proto_port(list, L2CAP_UUID);
- if (psm < 0)
- return -1;
+ if (rec) {
+ if (sdp_get_access_protos(rec, &list) < 0)
+ return -1;
+
+ psm = sdp_get_proto_port(list, L2CAP_UUID);
+ if (psm < 0)
+ return -1;
+ }
return attrib_client_register(device, psm);
}
diff --git a/src/device.c b/src/device.c
index 7c421e3..f236b29 100644
--- a/src/device.c
+++ b/src/device.c
@@ -111,6 +111,7 @@ struct browse_req {
struct btd_device {
bdaddr_t bdaddr;
+ gboolean le;
gchar *path;
char name[MAX_NAME_LENGTH + 1];
char *alias;
@@ -215,7 +216,8 @@ static void browse_request_cancel(struct browse_req *req)
adapter_get_address(adapter, &src);
- bt_cancel_discovery(&src, &device->bdaddr);
+ if (device->le == FALSE)
+ bt_cancel_discovery(&src, &device->bdaddr);
device->browse = NULL;
browse_request_free(req);
@@ -1557,29 +1559,67 @@ static void init_browse(struct browse_req *req, gboolean reverse)
l->data);
}
-int device_browse(struct btd_device *device, DBusConnection *conn,
- DBusMessage *msg, uuid_t *search, gboolean reverse)
+static void primary_cb(GSList *services, int err, gpointer user_data)
+{
+ struct browse_req *req = user_data;
+ struct btd_device *device = req->device;
+
+ if (err) {
+ error_failed_errno(req->conn, req->msg, -err);
+ goto done;
+ }
+
+ services_changed(req->device);
+ device_set_temporary(req->device, FALSE);
+ device_probe_drivers(req->device, services);
+
+ create_device_reply(req->device, req);
+
+done:
+ device->browse = NULL;
+ browse_request_free(req);
+}
+
+static struct browse_req *browse_primary(struct btd_device *device, int *err)
{
struct btd_adapter *adapter = device->adapter;
struct browse_req *req;
bdaddr_t src;
- uuid_t uuid;
- bt_callback_t cb;
- int err;
+ int ret;
- if (device->browse)
- return -EBUSY;
+ req = g_new0(struct browse_req, 1);
+ req->device = btd_device_ref(device);
adapter_get_address(adapter, &src);
- req = g_new0(struct browse_req, 1);
+ ret = bt_discover_primary(&src, &device->bdaddr, -1, primary_cb, req,
+ NULL);
- if (conn == NULL)
- conn = get_dbus_connection();
+ if (ret < 0) {
+ browse_request_free(req);
+ if (err)
+ *err = ret;
- req->conn = dbus_connection_ref(conn);
- req->device = btd_device_ref(device);
+ return NULL;
+ }
+
+ return req;
+}
+
+static struct browse_req *browse_sdp(struct btd_device *device, uuid_t *search,
+ gboolean reverse, int *err)
+{
+ struct btd_adapter *adapter = device->adapter;
+ struct browse_req *req;
+ bt_callback_t cb;
+ bdaddr_t src;
+ uuid_t uuid;
+ int ret;
+ adapter_get_address(adapter, &src);
+
+ req = g_new0(struct browse_req, 1);
+ req->device = btd_device_ref(device);
if (search) {
memcpy(&uuid, search, sizeof(uuid_t));
cb = search_cb;
@@ -1589,6 +1629,39 @@ int device_browse(struct btd_device *device, DBusConnection *conn,
cb = browse_cb;
}
+ ret = bt_search_service(&src, &device->bdaddr, &uuid, cb, req, NULL);
+ if (ret < 0) {
+ browse_request_free(req);
+ if (err)
+ *err = ret;
+
+ return NULL;
+ }
+
+ return req;
+}
+
+int device_browse(struct btd_device *device, DBusConnection *conn,
+ DBusMessage *msg, uuid_t *search, gboolean reverse)
+{
+ struct browse_req *req;
+ int err = 0;
+
+ if (device->browse)
+ return -EBUSY;
+
+ if (device->le)
+ req = browse_primary(device, &err);
+ else
+ req = browse_sdp(device, search, reverse, &err);
+
+ if (req == NULL)
+ return err;
+
+ if (conn == NULL)
+ conn = get_dbus_connection();
+
+ req->conn = dbus_connection_ref(conn);
device->browse = req;
if (msg) {
@@ -1603,13 +1676,6 @@ int device_browse(struct btd_device *device, DBusConnection *conn,
req, NULL);
}
- err = bt_search_service(&src, &device->bdaddr,
- &uuid, cb, req, NULL);
- if (err < 0) {
- device->browse = NULL;
- browse_request_free(req);
- }
-
return err;
}
diff --git a/src/glib-helper.c b/src/glib-helper.c
index 4941d99..f0689d5 100644
--- a/src/glib-helper.c
+++ b/src/glib-helper.c
@@ -42,12 +42,26 @@
#include <glib.h>
-#include "glib-helper.h"
+#include "btio.h"
+#include "gattrib.h"
+#include "att.h"
+#include "gatt.h"
#include "sdpd.h"
+#include "glib-helper.h"
/* Number of seconds to keep a sdp_session_t in the cache */
#define CACHE_TIMEOUT 2
+struct gattrib_context {
+ bdaddr_t src;
+ bdaddr_t dst;
+ GAttrib *attrib;
+ bt_primary_t cb;
+ bt_destroy_t destroy;
+ gpointer user_data;
+ GSList *uuids;
+};
+
struct cached_sdp_session {
bdaddr_t src;
bdaddr_t dst;
@@ -57,6 +71,17 @@ struct cached_sdp_session {
static GSList *cached_sdp_sessions = NULL;
+static void gattrib_context_free(struct gattrib_context *ctxt)
+{
+ if (ctxt->destroy)
+ ctxt->destroy(ctxt->user_data);
+
+ g_slist_foreach(ctxt->uuids, (GFunc) g_free, NULL);
+ g_slist_free(ctxt->uuids);
+ g_attrib_unref(ctxt->attrib);
+ g_free(ctxt);
+}
+
static gboolean cached_session_expired(gpointer user_data)
{
struct cached_sdp_session *cached = user_data;
@@ -118,6 +143,7 @@ struct search_context {
bdaddr_t dst;
sdp_session_t *session;
bt_callback_t cb;
+ bt_primary_t prim_cb;
bt_destroy_t destroy;
gpointer user_data;
uuid_t uuid;
@@ -378,6 +404,125 @@ int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst)
return 0;
}
+static void primary_cb(guint8 status, const guint8 *pdu, guint16 plen,
+ gpointer user_data)
+{
+ struct gattrib_context *ctxt = user_data;
+ struct att_data_list *list;
+ unsigned int i, err;
+ uint16_t end;
+
+ if (status == ATT_ECODE_ATTR_NOT_FOUND) {
+ err = 0;
+ goto done;
+ }
+
+ if (status != 0) {
+ err = -EIO;
+ goto done;
+ }
+
+ list = dec_read_by_grp_resp(pdu, plen);
+ if (list == NULL) {
+ err = -EPROTO;
+ goto done;
+ }
+
+ for (i = 0, end = 0; i < list->num; i++) {
+ const uint8_t *data = list->data[i];
+ char *prim;
+ uuid_t u128, u16;
+
+ end = att_get_u16(&data[2]);
+
+ if (list->len == 6) {
+ sdp_uuid16_create(&u16,
+ att_get_u16(&data[4]));
+ sdp_uuid16_to_uuid128(&u128, &u16);
+
+ } else if (list->len == 20)
+ sdp_uuid128_create(&u128, &data[4]);
+ else
+ /* Skipping invalid data */
+ continue;
+
+ prim = bt_uuid2string(&u128);
+ ctxt->uuids = g_slist_append(ctxt->uuids, prim);
+ }
+
+ att_data_list_free(list);
+ err = 0;
+
+ if (end != 0xffff) {
+ gatt_discover_primary(ctxt->attrib, end + 1, 0xffff, NULL,
+ primary_cb, ctxt);
+ return;
+ }
+
+done:
+ ctxt->cb(ctxt->uuids, err, ctxt->user_data);
+ gattrib_context_free(ctxt);
+}
+
+static void connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
+{
+ struct gattrib_context *ctxt = user_data;
+
+ if (gerr) {
+ ctxt->cb(NULL, -EIO, ctxt->user_data);
+ gattrib_context_free(ctxt);
+ return;
+ }
+
+ gatt_discover_primary(ctxt->attrib, 0x0001, 0xffff, NULL, primary_cb,
+ ctxt);
+}
+
+int bt_discover_primary(const bdaddr_t *src, const bdaddr_t *dst, int psm,
+ bt_primary_t cb, void *user_data,
+ bt_destroy_t destroy)
+{
+ struct gattrib_context *ctxt;
+ GIOChannel *io;
+ GError *gerr = NULL;
+
+ ctxt = g_try_malloc0(sizeof(struct gattrib_context));
+ if (ctxt == NULL)
+ return -ENOMEM;
+
+ bacpy(&ctxt->src, src);
+ bacpy(&ctxt->dst, dst);
+ ctxt->user_data = user_data;
+ ctxt->cb = cb;
+ ctxt->destroy = destroy;
+
+ if (psm < 0)
+ io = bt_io_connect(BT_IO_L2CAP, connect_cb, ctxt, NULL, &gerr,
+ BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_DEST_BDADDR, dst,
+ BT_IO_OPT_CID, GATT_CID,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_INVALID);
+ else
+ io = bt_io_connect(BT_IO_L2CAP, connect_cb, ctxt, NULL, &gerr,
+ BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_DEST_BDADDR, dst,
+ BT_IO_OPT_PSM, psm,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_INVALID);
+
+ if (io == NULL) {
+ gattrib_context_free(ctxt);
+ return -EIO;
+ }
+
+ ctxt->attrib = g_attrib_new(io);
+
+ g_io_channel_unref(io);
+
+ return 0;
+}
+
char *bt_uuid2string(uuid_t *uuid)
{
gchar *str;
diff --git a/src/glib-helper.h b/src/glib-helper.h
index dfe4123..018ff92 100644
--- a/src/glib-helper.h
+++ b/src/glib-helper.h
@@ -22,6 +22,7 @@
*/
typedef void (*bt_callback_t) (sdp_list_t *recs, int err, gpointer user_data);
+typedef void (*bt_primary_t) (GSList *l, int err, gpointer user_data);
typedef void (*bt_destroy_t) (gpointer user_data);
int bt_discover_services(const bdaddr_t *src, const bdaddr_t *dst,
@@ -32,6 +33,10 @@ int bt_search_service(const bdaddr_t *src, const bdaddr_t *dst,
bt_destroy_t destroy);
int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst);
+int bt_discover_primary(const bdaddr_t *src, const bdaddr_t *dst, int psm,
+ bt_primary_t cb, void *user_data,
+ bt_destroy_t destroy);
+
gchar *bt_uuid2string(uuid_t *uuid);
uint16_t bt_name2class(const char *string);
char *bt_name2string(const char *string);
--
1.7.3.2
^ permalink raw reply related
* Re: [RFC 12/20] Bluetooth: fix receiving L2CAP packets over LE
From: Vinicius Costa Gomes @ 2010-11-23 23:06 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: Vinicius Costa Gomes, linux-bluetooth
In-Reply-To: <20101123225558.GD11860@vigoh>
Hi Gustavo,
On 20:55 Tue 23 Nov , Gustavo F. Padovan wrote:
> Hi Vinicius,
>
> * Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2010-11-23 12:06:28 -0300]:
>
> > As L2CAP packets coming over LE don't have any more encapsulation,
> > other than L2CAP, we are able to process them as soon as they arrive.
> >
> > Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> > ---
> > net/bluetooth/l2cap.c | 17 +++++++++++++++--
> > 1 files changed, 15 insertions(+), 2 deletions(-)
>
> So move this patch before the SMP changes in the patchset.
Will do.
>
> --
> Gustavo F. Padovan
> http://profusion.mobi
Cheers,
--
Vinicius
^ 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