* [PATCH 2/5] Bluetooth: Add read_version management command
From: johan.hedberg @ 2010-12-13 19:07 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1292267227-22028-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
This patch implements the initial read_version command that userspace
will use before any other management interface operations.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
include/net/bluetooth/mgmt.h | 6 ++++++
net/bluetooth/mgmt.c | 36 ++++++++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 95974da..d353d64 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -27,6 +27,12 @@ struct mgmt_hdr {
} __packed;
#define MGMT_HDR_SIZE 4
+#define MGMT_OP_READ_VERSION 0x0001
+struct mgmt_rp_read_version {
+ __u8 version;
+ __le16 revision;
+} __packed;
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 7ea5489..3e24c0b 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -29,6 +29,39 @@
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/mgmt.h>
+#define MGMT_VERSION 0
+#define MGMT_REVISION 1
+
+static int read_version(struct sock *sk)
+{
+ struct sk_buff *skb;
+ struct mgmt_hdr *hdr;
+ struct mgmt_ev_cmd_complete *ev;
+ struct mgmt_rp_read_version *rp;
+
+ BT_DBG("sock %p", sk);
+
+ skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ hdr = (void *) skb_put(skb, sizeof(*hdr));
+ hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
+ hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp));
+
+ ev = (void *) skb_put(skb, sizeof(*ev));
+ put_unaligned_le16(MGMT_OP_READ_VERSION, &ev->opcode);
+
+ rp = (void *) skb_put(skb, sizeof(*rp));
+ rp->version = MGMT_VERSION;
+ put_unaligned_le16(MGMT_REVISION, &rp->revision);
+
+ if (sock_queue_rcv_skb(sk, skb) < 0)
+ kfree_skb(skb);
+
+ return 0;
+}
+
static int cmd_status(struct sock *sk, u16 cmd, u8 status)
{
struct sk_buff *skb;
@@ -87,6 +120,9 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
}
switch (opcode) {
+ case MGMT_OP_READ_VERSION:
+ err = read_version(sk);
+ break;
default:
BT_DBG("Unknown op %u", opcode);
err = cmd_status(sk, opcode, 0x01);
--
1.7.2.3
^ permalink raw reply related
* [PATCH 1/5] Bluetooth: Add error handling for managment command handlers
From: johan.hedberg @ 2010-12-13 19:07 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1292267227-22028-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
The command handlers for bluetooth management messaging should be able
to report errors (such as memory allocation failures) to the higher
levels in the call stack.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/mgmt.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index d15bf67..7ea5489 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -29,7 +29,7 @@
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/mgmt.h>
-static void cmd_status(struct sock *sk, u16 cmd, u8 status)
+static int cmd_status(struct sock *sk, u16 cmd, u8 status)
{
struct sk_buff *skb;
struct mgmt_hdr *hdr;
@@ -39,7 +39,7 @@ static void cmd_status(struct sock *sk, u16 cmd, u8 status)
skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC);
if (!skb)
- return;
+ return -ENOMEM;
hdr = (void *) skb_put(skb, sizeof(*hdr));
@@ -52,6 +52,8 @@ static void cmd_status(struct sock *sk, u16 cmd, u8 status)
if (sock_queue_rcv_skb(sk, skb) < 0)
kfree_skb(skb);
+
+ return 0;
}
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
@@ -87,10 +89,13 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
switch (opcode) {
default:
BT_DBG("Unknown op %u", opcode);
- cmd_status(sk, opcode, 0x01);
+ err = cmd_status(sk, opcode, 0x01);
break;
}
+ if (err < 0)
+ goto done;
+
err = msglen;
done:
--
1.7.2.3
^ permalink raw reply related
* Basic Management interface command handling
From: johan.hedberg @ 2010-12-13 19:07 UTC (permalink / raw)
To: linux-bluetooth
Hi,
Here's a set of patches for dealing with basic commands needed for local
adapter enumeration and information featching.
I'm not completely sure about the parameter list of read_info (maybe
something is missing or too much) but we can fine tune that later as
long as the interface is experimental. The basic idea is to avoid too
many messages to get the initial set of info about an adapter and then
have separate "value X changed" events from the kernel to userspace when
individual values change. For the values that can be changed by the user
there'll also be individual "set value" commands.
With this set of patches you should be able to get the enumeration (at
least somewhat) working with current bluez.git:
echo 1 > /sys/module/bluetooth/parameters/enable_mgmt
bluetoothd -n -d -p mgmtops
There's no power control (HCI_UP/HCI_DOWN) available yet, so you'll get
more meaningful values in read_info if you do "hciconfig hci0 up" before
running bluetoothd.
Johan
^ permalink raw reply
* Re: [PATCH 1/1] Support for reading long Characteristic Values.
From: Vinicius Costa Gomes @ 2010-12-13 18:39 UTC (permalink / raw)
To: Brian Gix; +Cc: linux-bluetooth, padovan, rshaffer
In-Reply-To: <1292261066-28100-3-git-send-email-bgix@codeaurora.org>
On 09:24 Mon 13 Dec, Brian Gix wrote:
> Modify existing gatt_read_char() function support the reading of
> attributes (specifically Characteristic Values) that are longer than
> the MTU would otherwise allow. When a result to an ATT_OP_READ_REQ
> is received, it will be passed to the requester as always if the total
> result was shorter than the Default MTU (23). Any results equal to or
> longer will cause a series of READ_BLOB requests to be made, with the
> additional results built up until the end of the Attribute is detected.
> The full result will then be passed to the original requester.
>
> The end of the Attribute is detected by either a successful result to
> the READ_BLOB request that is shorter than the Default MTU, or by an
> error result that indicates that a read is being attempted beyond the
> length of the attribute, or that the Attribute wasn't "Long".
>
> This patch is dependant on the earlier patch:
> 0001-Implempent-READ_BLOB-encoding-for-ATT.patch
>
> The packet composed conforms to the Bluetooth Core v4.0 specification.
>
> Brian Gix
> bgix@codeaurora.org
> Employee of Qualcomm Innovation Center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
>
> ---
> attrib/gatt.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 files changed, 112 insertions(+), 2 deletions(-)
>
> diff --git a/attrib/gatt.c b/attrib/gatt.c
> index bca8b49..d888f1d 100644
> --- a/attrib/gatt.c
> +++ b/attrib/gatt.c
> @@ -97,15 +97,125 @@ guint gatt_read_char_by_uuid(GAttrib *attrib, uint16_t start, uint16_t end,
> pdu, plen, func, user_data, NULL);
> }
>
> +struct read_long_data {
> + GAttrib *attrib;
> + GAttribResultFunc func;
> + gpointer user_data;
> + guint8 *result_data;
> + guint16 result_len;
I would call result_data "buffer" (or something like it) and result_len "size"
(or total). What do you think?
> + guint16 handle;
> +};
> +
> +static void read_blob_helper(guint8 status, const guint8 *res_pdu,
> + guint16 res_len, gpointer user_data)
> +{
> + struct read_long_data *long_read = user_data;
> + uint8_t pdu[ATT_DEFAULT_MTU];
> + guint8 *tmp;
> + guint16 plen;
> + guint ret_val;
> +
> + if (status == ATT_ECODE_ATTR_NOT_LONG ||
> + status == ATT_ECODE_INVALID_OFFSET) {
> + status = 0;
> + goto done;
> + }
> +
> + if (status != 0 || res_len == 1)
> + goto done;
> +
> + tmp = g_try_realloc(long_read->result_data,
> + long_read->result_len + res_len - 1);
> +
> + if (tmp == NULL) {
> + status = ATT_ECODE_INSUFF_RESOURCES;
> + goto done;
> + }
> +
> + memcpy(&tmp[long_read->result_len], &res_pdu[1], res_len-1);
It should be "res - 1".
> + long_read->result_data = tmp;
> + long_read->result_len += res_len-1;
Same here.
> +
> + if (res_len < ATT_DEFAULT_MTU)
> + goto done;
> +
> + plen = enc_read_blob_req(long_read->handle, long_read->result_len-1,
And here.
> + pdu, sizeof(pdu));
> + ret_val = g_attrib_send(long_read->attrib, ATT_OP_READ_BLOB_REQ, pdu,
> + plen, read_blob_helper, long_read, NULL);
> +
> + if (ret_val != 0)
> + return;
> +
> + status = ATT_ECODE_INSUFF_RESOURCES;
> +
> +done:
> + long_read->func(status, long_read->result_data, long_read->result_len,
> + long_read->user_data);
> + g_free(long_read->result_data);
> + g_free(long_read);
> +}
> +
> +static void read_char_helper(guint8 status, const guint8 *res_pdu,
> + guint16 res_len, gpointer user_data)
> +{
> + struct read_long_data *long_read = user_data;
> + uint8_t pdu[ATT_DEFAULT_MTU];
> + guint16 plen;
> + guint ret_val;
> +
> + if (status != 0 || res_len < ATT_DEFAULT_MTU)
> + goto done;
> +
> + long_read->result_data = g_malloc(res_len);
> +
> + if (long_read->result_data == NULL)
> + goto done;
> +
> + memcpy(long_read->result_data, res_pdu, res_len);
> + long_read->result_len = res_len;
> +
> + plen = enc_read_blob_req(long_read->handle, res_len-1, pdu,
> + sizeof(pdu));
> + ret_val = g_attrib_send(long_read->attrib, ATT_OP_READ_BLOB_REQ,
> + pdu, plen, read_blob_helper, long_read, NULL);
g_attrib_send() returns an command id (something that could be used to cancel
the command later, if needed), so I think it would make more sense to call
ret_val "id" or just "ret". And thinking about it, I guess that the "res_"
prefix doesn't add much meaning to "res_pdu" and "res_len". Do you agree?
> +
> + if (ret_val != 0)
> + return;
> +
> + status = ATT_ECODE_INSUFF_RESOURCES;
> +
> +done:
> + long_read->func(status, res_pdu, res_len, long_read->user_data);
If g_attrib_send() fails, load_read->result_data may be leaking here.
> + g_free(long_read);
> +}
> +
> guint gatt_read_char(GAttrib *attrib, uint16_t handle, GAttribResultFunc func,
> gpointer user_data)
> {
> uint8_t pdu[ATT_DEFAULT_MTU];
> guint16 plen;
> + guint ret_val;
> + struct read_long_data *long_read;
> +
> + long_read = g_try_new0(struct read_long_data, 1);
> +
> + if (long_read == NULL)
> + return 0;
> +
> + long_read->attrib = attrib;
> + long_read->func = func;
> + long_read->user_data = user_data;
> + long_read->handle = handle;
>
> plen = enc_read_req(handle, pdu, sizeof(pdu));
> - return g_attrib_send(attrib, ATT_OP_READ_REQ, pdu, plen, func,
> - user_data, NULL);
> + ret_val = g_attrib_send(attrib, ATT_OP_READ_REQ, pdu, plen,
> + read_char_helper, long_read, NULL);
> +
> + if (ret_val == 0)
> + g_free(long_read);
> +
> + return ret_val;
> }
>
> guint gatt_write_char(GAttrib *attrib, uint16_t handle, uint8_t *value,
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Cheers,
--
Vinicius
^ permalink raw reply
* Re: [PATCH 1/1] Implempent READ_BLOB encoding for ATT.
From: Vinicius Costa Gomes @ 2010-12-13 18:15 UTC (permalink / raw)
To: Brian Gix; +Cc: linux-bluetooth, padovan, rshaffer
In-Reply-To: <1292261066-28100-2-git-send-email-bgix@codeaurora.org>
Hi Brian,
On 09:24 Mon 13 Dec, Brian Gix wrote:
> Added enc_read_blob_req() API to ATT transport, to enable
> the reading of attributes that exceed the length of the
> MTU.
>
> The packet composed conforms to the Bluetooth Core v4.0 specification.
>
> Brian Gix
> bgix@codeaurora.org
> Employee of Qualcomm Innovation Center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
Not sure if this signature belongs in the patch comment.
>
> ---
> attrib/att.c | 18 ++++++++++++++++++
> attrib/att.h | 2 ++
> 2 files changed, 20 insertions(+), 0 deletions(-)
>
> diff --git a/attrib/att.c b/attrib/att.c
> index 445b192..d0879f8 100644
> --- a/attrib/att.c
> +++ b/attrib/att.c
> @@ -542,6 +542,24 @@ uint16_t enc_read_req(uint16_t handle, uint8_t *pdu, int len)
> return min_len;
> }
>
> +uint16_t enc_read_blob_req(uint16_t handle, uint16_t offset, uint8_t *pdu,
> + int len)
I couldn't apply the patches because there were a mix between tabs and spaces,
please use only tabs for indentation.
> +{
> + const uint16_t min_len = sizeof(pdu[0]) + sizeof(handle) + sizeof(offset);
> +
> + if (pdu == NULL)
> + return 0;
> +
> + if (len < min_len)
> + return 0;
> +
> + pdu[0] = ATT_OP_READ_BLOB_REQ;
> + att_put_u16(handle, &pdu[1]);
> + att_put_u16(offset, &pdu[3]);
> +
> + return min_len;
> +}
> +
> uint16_t dec_read_req(const uint8_t *pdu, int len, uint16_t *handle)
> {
> const uint16_t min_len = sizeof(pdu[0]) + sizeof(*handle);
> diff --git a/attrib/att.h b/attrib/att.h
> index 2c8c724..46bdad4 100644
> --- a/attrib/att.h
> +++ b/attrib/att.h
> @@ -202,6 +202,8 @@ uint16_t enc_write_req(uint16_t handle, const uint8_t *value, int vlen,
> uint16_t dec_write_req(const uint8_t *pdu, int len, uint16_t *handle,
> uint8_t *value, int *vlen);
> uint16_t enc_read_req(uint16_t handle, uint8_t *pdu, int len);
> +uint16_t enc_read_blob_req(uint16_t handle, uint16_t offset, uint8_t *pdu,
> + int len);
> uint16_t dec_read_req(const uint8_t *pdu, int len, uint16_t *handle);
> uint16_t enc_read_resp(uint8_t *value, int vlen, uint8_t *pdu, int len);
> uint16_t dec_read_resp(const uint8_t *pdu, int len, uint8_t *value, int *vlen);
> --
> 1.7.1
>
> --
> 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
--
Vinicius
^ permalink raw reply
* Re: [PATCH] btusb: Fix log spamming due to autosuspend
From: Gustavo F. Padovan @ 2010-12-13 17:46 UTC (permalink / raw)
To: Stefan Seyfried
Cc: linux-bluetooth, Marcel Holtmann, gregkh, Stefan Seyfried,
Oliver Neukum
In-Reply-To: <20101209201657.0b7964fc@susi>
Hi Stefan,
* Stefan Seyfried <stefan.seyfried@googlemail.com> [2010-12-09 20:16:57 +0100]:
> Hi all,
>
> On Wed, 1 Dec 2010 15:49:10 -0200
> "Gustavo F. Padovan" <padovan@profusion.mobi> wrote:
>
> > Hi Stefan,
> >
> > * Stefan Seyfried <stefan.seyfried@googlemail.com> [2010-12-01 15:47:14 +0100]:
>
> > > > > If a device is autosuspended an inability to resubmit URBs is
> > > > > to be expected. Check the error code and only log real errors.
> > > > > (Now that autosuspend is default enabled for btusb, those log
> > > > > messages were happening all the time e.g. with a BT mouse)
> > > > >
> > > > > Signed-off-by: Stefan Seyfried <seife+kernel@b1-systems.com>
> > > > > Signed-off-by: Oliver Neukum <oneukum@suse.de>
> > > >
> > > > we had a similar one some time ago, but I am fine with this one as well.
> > > > Actually this one might be a bit better since it still keeps some
> > > > errors.
> > > >
> > > > Acked-by: Marcel Holtmann <marcel@holtmann.org>
> > >
> > > Could you (or Gustavo) send it to Linus? It's pretty trivial, but the
> > > messages are annoying and users will complain if they are still in 2.6.37
> > > final.
> >
> > I'll send it, applied to bluetooth-2.6 tree. Thanks.
>
> unfortunately, it does not seem to make it into 2.6.37?
Patch is in net-2.6 right now. Should go to mainline soon.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* pull request: bluetooth-2.6 2010-12-13
From: Gustavo F. Padovan @ 2010-12-13 17:43 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, linux-bluetooth
Hi John,
The latest Bluetooth patches to linux 2.6.37. First is very critical fix a
break in the DUN profile connection setup. Second patch is also critical and
adds a NULL pointer protection in HCI code.
Please pull or let me know any problems! Thanks.
The following changes since commit 0a54917c3fc295cb61f3fb52373c173fd3b69f48:
orinoco: fix TKIP countermeasure behaviour (2010-12-08 15:24:06 -0500)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git master
Johan Hedberg (1):
Bluetooth: Fix initial RFCOMM DLC security level
Jun Nie (1):
Bluetooth: add NULL pointer check in HCI
drivers/bluetooth/hci_ldisc.c | 6 ++++--
net/bluetooth/rfcomm/core.c | 1 +
2 files changed, 5 insertions(+), 2 deletions(-)
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: Start dropping PCMCIA from compat-wireless for 2.6.38+
From: Luis R. Rodriguez @ 2010-12-13 17:26 UTC (permalink / raw)
To: Holger Schurig; +Cc: linux-wireless, linux-kernel, linux-bluetooth
In-Reply-To: <201012130846.16522.holgerschurig@gmail.com>
On Sun, Dec 12, 2010 at 11:46 PM, Holger Schurig
<holgerschurig@gmail.com> wrote:
> Please, if the burden is not too much, keep it for the benefit of
> embedded people.
>
> If you have some embedded device (e.g. ARM based), it's usually not so
> easy to hieve this device to newest 2.6.3[5-7] kernel. However, it's
> easy to use your adapted kernel, and compile compat-wireless against it.
>
> I'm in such a situation with libertas_cs.
You use libertas_cs on an embedded device with compat-wireless, OK,
thanks for the feedback. If you can help with patches when PCMCIA crap
is advanced that would help too.
Luis
^ permalink raw reply
* [PATCH 1/1] Support for reading long Characteristic Values.
From: Brian Gix @ 2010-12-13 17:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: padovan, rshaffer, Brian Gix
In-Reply-To: <1292261066-28100-1-git-send-email-bgix@codeaurora.org>
Modify existing gatt_read_char() function support the reading of
attributes (specifically Characteristic Values) that are longer than
the MTU would otherwise allow. When a result to an ATT_OP_READ_REQ
is received, it will be passed to the requester as always if the total
result was shorter than the Default MTU (23). Any results equal to or
longer will cause a series of READ_BLOB requests to be made, with the
additional results built up until the end of the Attribute is detected.
The full result will then be passed to the original requester.
The end of the Attribute is detected by either a successful result to
the READ_BLOB request that is shorter than the Default MTU, or by an
error result that indicates that a read is being attempted beyond the
length of the attribute, or that the Attribute wasn't "Long".
This patch is dependant on the earlier patch:
0001-Implempent-READ_BLOB-encoding-for-ATT.patch
The packet composed conforms to the Bluetooth Core v4.0 specification.
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
---
attrib/gatt.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 112 insertions(+), 2 deletions(-)
diff --git a/attrib/gatt.c b/attrib/gatt.c
index bca8b49..d888f1d 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -97,15 +97,125 @@ guint gatt_read_char_by_uuid(GAttrib *attrib, uint16_t start, uint16_t end,
pdu, plen, func, user_data, NULL);
}
+struct read_long_data {
+ GAttrib *attrib;
+ GAttribResultFunc func;
+ gpointer user_data;
+ guint8 *result_data;
+ guint16 result_len;
+ guint16 handle;
+};
+
+static void read_blob_helper(guint8 status, const guint8 *res_pdu,
+ guint16 res_len, gpointer user_data)
+{
+ struct read_long_data *long_read = user_data;
+ uint8_t pdu[ATT_DEFAULT_MTU];
+ guint8 *tmp;
+ guint16 plen;
+ guint ret_val;
+
+ if (status == ATT_ECODE_ATTR_NOT_LONG ||
+ status == ATT_ECODE_INVALID_OFFSET) {
+ status = 0;
+ goto done;
+ }
+
+ if (status != 0 || res_len == 1)
+ goto done;
+
+ tmp = g_try_realloc(long_read->result_data,
+ long_read->result_len + res_len - 1);
+
+ if (tmp == NULL) {
+ status = ATT_ECODE_INSUFF_RESOURCES;
+ goto done;
+ }
+
+ memcpy(&tmp[long_read->result_len], &res_pdu[1], res_len-1);
+ long_read->result_data = tmp;
+ long_read->result_len += res_len-1;
+
+ if (res_len < ATT_DEFAULT_MTU)
+ goto done;
+
+ plen = enc_read_blob_req(long_read->handle, long_read->result_len-1,
+ pdu, sizeof(pdu));
+ ret_val = g_attrib_send(long_read->attrib, ATT_OP_READ_BLOB_REQ, pdu,
+ plen, read_blob_helper, long_read, NULL);
+
+ if (ret_val != 0)
+ return;
+
+ status = ATT_ECODE_INSUFF_RESOURCES;
+
+done:
+ long_read->func(status, long_read->result_data, long_read->result_len,
+ long_read->user_data);
+ g_free(long_read->result_data);
+ g_free(long_read);
+}
+
+static void read_char_helper(guint8 status, const guint8 *res_pdu,
+ guint16 res_len, gpointer user_data)
+{
+ struct read_long_data *long_read = user_data;
+ uint8_t pdu[ATT_DEFAULT_MTU];
+ guint16 plen;
+ guint ret_val;
+
+ if (status != 0 || res_len < ATT_DEFAULT_MTU)
+ goto done;
+
+ long_read->result_data = g_malloc(res_len);
+
+ if (long_read->result_data == NULL)
+ goto done;
+
+ memcpy(long_read->result_data, res_pdu, res_len);
+ long_read->result_len = res_len;
+
+ plen = enc_read_blob_req(long_read->handle, res_len-1, pdu,
+ sizeof(pdu));
+ ret_val = g_attrib_send(long_read->attrib, ATT_OP_READ_BLOB_REQ,
+ pdu, plen, read_blob_helper, long_read, NULL);
+
+ if (ret_val != 0)
+ return;
+
+ status = ATT_ECODE_INSUFF_RESOURCES;
+
+done:
+ long_read->func(status, res_pdu, res_len, long_read->user_data);
+ g_free(long_read);
+}
+
guint gatt_read_char(GAttrib *attrib, uint16_t handle, GAttribResultFunc func,
gpointer user_data)
{
uint8_t pdu[ATT_DEFAULT_MTU];
guint16 plen;
+ guint ret_val;
+ struct read_long_data *long_read;
+
+ long_read = g_try_new0(struct read_long_data, 1);
+
+ if (long_read == NULL)
+ return 0;
+
+ long_read->attrib = attrib;
+ long_read->func = func;
+ long_read->user_data = user_data;
+ long_read->handle = handle;
plen = enc_read_req(handle, pdu, sizeof(pdu));
- return g_attrib_send(attrib, ATT_OP_READ_REQ, pdu, plen, func,
- user_data, NULL);
+ ret_val = g_attrib_send(attrib, ATT_OP_READ_REQ, pdu, plen,
+ read_char_helper, long_read, NULL);
+
+ if (ret_val == 0)
+ g_free(long_read);
+
+ return ret_val;
}
guint gatt_write_char(GAttrib *attrib, uint16_t handle, uint8_t *value,
--
1.7.1
^ permalink raw reply related
* [PATCH 1/1] Implempent READ_BLOB encoding for ATT.
From: Brian Gix @ 2010-12-13 17:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: padovan, rshaffer, Brian Gix
In-Reply-To: <1292261066-28100-1-git-send-email-bgix@codeaurora.org>
Added enc_read_blob_req() API to ATT transport, to enable
the reading of attributes that exceed the length of the
MTU.
The packet composed conforms to the Bluetooth Core v4.0 specification.
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
---
attrib/att.c | 18 ++++++++++++++++++
attrib/att.h | 2 ++
2 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/attrib/att.c b/attrib/att.c
index 445b192..d0879f8 100644
--- a/attrib/att.c
+++ b/attrib/att.c
@@ -542,6 +542,24 @@ uint16_t enc_read_req(uint16_t handle, uint8_t *pdu, int len)
return min_len;
}
+uint16_t enc_read_blob_req(uint16_t handle, uint16_t offset, uint8_t *pdu,
+ int len)
+{
+ const uint16_t min_len = sizeof(pdu[0]) + sizeof(handle) + sizeof(offset);
+
+ if (pdu == NULL)
+ return 0;
+
+ if (len < min_len)
+ return 0;
+
+ pdu[0] = ATT_OP_READ_BLOB_REQ;
+ att_put_u16(handle, &pdu[1]);
+ att_put_u16(offset, &pdu[3]);
+
+ return min_len;
+}
+
uint16_t dec_read_req(const uint8_t *pdu, int len, uint16_t *handle)
{
const uint16_t min_len = sizeof(pdu[0]) + sizeof(*handle);
diff --git a/attrib/att.h b/attrib/att.h
index 2c8c724..46bdad4 100644
--- a/attrib/att.h
+++ b/attrib/att.h
@@ -202,6 +202,8 @@ uint16_t enc_write_req(uint16_t handle, const uint8_t *value, int vlen,
uint16_t dec_write_req(const uint8_t *pdu, int len, uint16_t *handle,
uint8_t *value, int *vlen);
uint16_t enc_read_req(uint16_t handle, uint8_t *pdu, int len);
+uint16_t enc_read_blob_req(uint16_t handle, uint16_t offset, uint8_t *pdu,
+ int len);
uint16_t dec_read_req(const uint8_t *pdu, int len, uint16_t *handle);
uint16_t enc_read_resp(uint8_t *value, int vlen, uint8_t *pdu, int len);
uint16_t dec_read_resp(const uint8_t *pdu, int len, uint8_t *value, int *vlen);
--
1.7.1
^ permalink raw reply related
* [PATCH 0/2] Implement Long reads for GATT/ATT
From: Brian Gix @ 2010-12-13 17:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: padovan, rshaffer
These patches implement long attribute reads for GATT clients.
The first patch implements the ATT_OP_READ_BLOB_REQ opcode pkt in ATT.
The second patch modifies the gatt_read_char() API to recognize long
attributes, and build up the result over multiple ATT calls to both
ATT_OP_READ_REQ and ATT_OP_READ_BLOB_REQ, until the entire attribute
has been retrieved. It then forwards to the original requester.
The public GATT API is unchanged, and the input parameters, and returned
results are the same.
Over-the-air, the request-result sequence is unchanged unless a long
attribute is detected.
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply
* [RFC] Bluetooth: Use non-flushable pb flag by default for ACL data on capable chipsets.
From: Emeltchenko Andrei @ 2010-12-13 14:38 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1292251105-31130-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
Modification of Nick Pelly <npelly@google.com> patch.
With Bluetooth 2.1 ACL packets can be flushable or non-flushable. This commit
makes ACL data packets non-flushable by default on compatible chipsets, and
adds the BT_FLUSHABLE socket option to explicitly request flushable ACL
data packets for a given L2CAP socket. This is useful for A2DP data which can
be safely discarded if it can not be delivered within a short time (while
other ACL data should not be discarded).
Note that making ACL data flushable has no effect unless the automatic flush
timeout for that ACL link is changed from its default of 0 (infinite).
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
---
include/net/bluetooth/bluetooth.h | 5 +++++
include/net/bluetooth/hci.h | 2 ++
include/net/bluetooth/hci_core.h | 1 +
include/net/bluetooth/l2cap.h | 2 ++
net/bluetooth/hci_core.c | 6 ++++--
net/bluetooth/l2cap.c | 33 +++++++++++++++++++++++++++++++--
6 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 0c5e725..ed7d775 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -64,6 +64,11 @@ struct bt_security {
#define BT_DEFER_SETUP 7
+#define BT_FLUSHABLE 8
+
+#define BT_FLUSHABLE_OFF 0
+#define BT_FLUSHABLE_ON 1
+
#define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
#define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 29a7a8c..333d5cb 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -150,6 +150,7 @@ enum {
#define EDR_ESCO_MASK (ESCO_2EV3 | ESCO_3EV3 | ESCO_2EV5 | ESCO_3EV5)
/* ACL flags */
+#define ACL_START_NO_FLUSH 0x00
#define ACL_CONT 0x01
#define ACL_START 0x02
#define ACL_ACTIVE_BCAST 0x04
@@ -193,6 +194,7 @@ enum {
#define LMP_EDR_ESCO_3M 0x40
#define LMP_EDR_3S_ESCO 0x80
+#define LMP_NO_FLUSH 0x01
#define LMP_SIMPLE_PAIR 0x08
/* Connection modes */
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 1992fac..9778bc8 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -456,6 +456,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO)
#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
+#define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH)
/* ----- HCI protocols ----- */
struct hci_proto {
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 7ad25ca..af35711 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -75,6 +75,7 @@ struct l2cap_conninfo {
#define L2CAP_LM_TRUSTED 0x0008
#define L2CAP_LM_RELIABLE 0x0010
#define L2CAP_LM_SECURE 0x0020
+#define L2CAP_LM_FLUSHABLE 0x0040
/* L2CAP command codes */
#define L2CAP_COMMAND_REJ 0x01
@@ -327,6 +328,7 @@ struct l2cap_pinfo {
__u8 sec_level;
__u8 role_switch;
__u8 force_reliable;
+ __u8 flushable;
__u8 conf_req[64];
__u8 conf_len;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 51c61f7..c0d776b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1380,7 +1380,7 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
skb->dev = (void *) hdev;
bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
- hci_add_acl_hdr(skb, conn->handle, flags | ACL_START);
+ hci_add_acl_hdr(skb, conn->handle, flags);
list = skb_shinfo(skb)->frag_list;
if (!list) {
@@ -1398,12 +1398,14 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
spin_lock_bh(&conn->data_q.lock);
__skb_queue_tail(&conn->data_q, skb);
+ flags &= ~ACL_START;
+ flags |= ACL_CONT;
do {
skb = list; list = list->next;
skb->dev = (void *) hdev;
bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
- hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT);
+ hci_add_acl_hdr(skb, conn->handle, flags);
BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index c791fcd..c7f25c2 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -362,13 +362,19 @@ static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
{
struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
+ u8 flags;
BT_DBG("code 0x%2.2x", code);
if (!skb)
return;
- hci_send_acl(conn->hcon, skb, 0);
+ if (lmp_no_flush_capable(conn->hcon->hdev))
+ flags = ACL_START_NO_FLUSH;
+ else
+ flags = ACL_START;
+
+ hci_send_acl(conn->hcon, skb, flags);
}
static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
@@ -900,6 +906,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
pi->sec_level = l2cap_pi(parent)->sec_level;
pi->role_switch = l2cap_pi(parent)->role_switch;
pi->force_reliable = l2cap_pi(parent)->force_reliable;
+ pi->flushable = l2cap_pi(parent)->flushable;
} else {
pi->imtu = L2CAP_DEFAULT_MTU;
pi->omtu = 0;
@@ -915,6 +922,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
pi->sec_level = BT_SECURITY_LOW;
pi->role_switch = 0;
pi->force_reliable = 0;
+ pi->flushable = BT_FLUSHABLE_OFF;
}
/* Default config options */
@@ -2098,6 +2106,20 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
bt_sk(sk)->defer_setup = opt;
break;
+ case BT_FLUSHABLE:
+ if (get_user(opt, (u32 __user *) optval)) {
+ err = -EFAULT;
+ break;
+ }
+
+ if (opt > BT_FLUSHABLE_ON) {
+ err = -EINVAL;
+ break;
+ }
+
+ l2cap_pi(sk)->flushable = opt;
+ break;
+
default:
err = -ENOPROTOOPT;
break;
@@ -2237,6 +2259,13 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
break;
+ case BT_FLUSHABLE:
+
+ if (put_user(l2cap_pi(sk)->flushable, (u32 __user *) optval))
+ err = -EFAULT;
+
+ break;
+
default:
err = -ENOPROTOOPT;
break;
@@ -4697,7 +4726,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
- if (flags & ACL_START) {
+ if (!(flags & ACL_CONT)) {
struct l2cap_hdr *hdr;
struct sock *sk;
u16 cid;
--
1.7.1
^ permalink raw reply related
* [RFC] Allow Bluez to select flushable or non-flushable ACL packets
From: Emeltchenko Andrei @ 2010-12-13 14:38 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
Slight modification of original patch from Nick Pelly <npelly@google.com>
Changes: rebasing, simplifying logic, using SOL_BLUETOOTH instead of SOL_L2CAP.
No changes done for RFCOMM sockets since no use case exist so far but can be
added later
Andrei Emeltchenko (1):
Bluetooth: Use non-flushable pb flag by default for ACL data on
capable chipsets.
include/net/bluetooth/bluetooth.h | 5 +++++
include/net/bluetooth/hci.h | 2 ++
include/net/bluetooth/hci_core.h | 1 +
include/net/bluetooth/l2cap.h | 2 ++
net/bluetooth/hci_core.c | 6 ++++--
net/bluetooth/l2cap.c | 33 +++++++++++++++++++++++++++++++--
6 files changed, 45 insertions(+), 4 deletions(-)
^ permalink raw reply
* Re: [PATCH] Setting default Link Policy according to the chip supported features
From: Johan Hedberg @ 2010-12-13 14:27 UTC (permalink / raw)
To: Pawel Wieczorkiewicz; +Cc: linux-bluetooth
In-Reply-To: <1292249954-8544-1-git-send-email-pawel.wieczorkiewicz@tieto.com>
Hi Pawel,
On Mon, Dec 13, 2010, Pawel Wieczorkiewicz wrote:
> By default all features are enabled (RSWITCH, HOLD, PARK, SNIFF).
> When "read local supported features" complete event occurs, not supported
> features are disabled and then "Write default link policy" command with
> supported features is sent.
>
> On behalf of ST-Ericsson SA
> ---
> plugins/hciops.c | 35 +++++++++++++++--------------------
> 1 files changed, 15 insertions(+), 20 deletions(-)
Thanks! The patch has been pushed upstream.
Johan
^ permalink raw reply
* [PATCH] Setting default Link Policy according to the chip supported features
From: Pawel Wieczorkiewicz @ 2010-12-13 14:19 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Pawel Wieczorkiewicz
By default all features are enabled (RSWITCH, HOLD, PARK, SNIFF).
When "read local supported features" complete event occurs, not supported
features are disabled and then "Write default link policy" command with
supported features is sent.
On behalf of ST-Ericsson SA
---
plugins/hciops.c | 35 +++++++++++++++--------------------
1 files changed, 15 insertions(+), 20 deletions(-)
diff --git a/plugins/hciops.c b/plugins/hciops.c
index 4af137c..44039ba 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -297,6 +297,7 @@ static void start_adapter(int index)
{
uint8_t events[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00 };
uint8_t inqmode;
+ uint16_t policy;
if (VER(index).lmp_ver > 1) {
if (FEATURES(index)[5] & LMP_SNIFF_SUBR)
@@ -345,6 +346,20 @@ static void start_adapter(int index)
hci_send_cmd(SK(index), OGF_HOST_CTL,
OCF_READ_INQ_RESPONSE_TX_POWER_LEVEL, 0, NULL);
+ /* Set default link policy */
+ if (!(FEATURES(index)[0] & LMP_RSWITCH))
+ main_opts.link_policy &= ~HCI_LP_RSWITCH;
+ if (!(FEATURES(index)[0] & LMP_HOLD))
+ main_opts.link_policy &= ~HCI_LP_HOLD;
+ if (!(FEATURES(index)[0] & LMP_SNIFF))
+ main_opts.link_policy &= ~HCI_LP_SNIFF;
+ if (!(FEATURES(index)[1] & LMP_PARK))
+ main_opts.link_policy &= ~HCI_LP_PARK;
+
+ policy = htobs(main_opts.link_policy);
+ hci_send_cmd(SK(index), OGF_LINK_POLICY,
+ OCF_WRITE_DEFAULT_LINK_POLICY, 2, &policy);
+
CURRENT_COD(index) = 0;
memset(EIR(index), 0, sizeof(EIR(index)));
@@ -1949,7 +1964,6 @@ static void at_child_exit(void)
static void device_devup_setup(int index)
{
struct hci_dev_info di;
- uint16_t policy;
read_stored_link_key_cp cp;
DBG("hci%d", index);
@@ -1972,11 +1986,6 @@ static void device_devup_setup(int index)
WRITE_PAGE_TIMEOUT_CP_SIZE, &cp);
}
- /* Set default link policy */
- policy = htobs(main_opts.link_policy);
- hci_send_cmd(SK(index), OGF_LINK_POLICY,
- OCF_WRITE_DEFAULT_LINK_POLICY, 2, &policy);
-
bacpy(&cp.bdaddr, BDADDR_ANY);
cp.read_all = 1;
hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_READ_STORED_LINK_KEY,
@@ -1997,7 +2006,6 @@ static void init_pending(int index)
static void init_device(int index)
{
struct hci_dev_req dr;
- struct hci_dev_info di;
int dd;
pid_t pid;
@@ -2042,19 +2050,6 @@ static void init_device(int index)
error("Can't set link mode on hci%d: %s (%d)",
index, strerror(errno), errno);
- /* Set link policy for BR/EDR HCI devices */
- if (hci_devinfo(index, &di) < 0)
- goto fail;
-
- if (!ignore_device(&di)) {
- dr.dev_opt = main_opts.link_policy;
- if (ioctl(dd, HCISETLINKPOL, (unsigned long) &dr) < 0 &&
- errno != ENETDOWN) {
- error("Can't set link policy on hci%d: %s (%d)",
- index, strerror(errno), errno);
- }
- }
-
/* Start HCI device */
if (ioctl(dd, HCIDEVUP, index) < 0 && errno != EALREADY) {
error("Can't init device hci%d: %s (%d)",
--
1.7.0.4
^ permalink raw reply related
* Re: How to implement multiple instances of obexd service?
From: Slawomir Bochenski @ 2010-12-13 13:56 UTC (permalink / raw)
To: Slawomir Bochenski, linux-bluetooth
In-Reply-To: <20101213132145.GA13767@jh-x301>
On Mon, Dec 13, 2010 at 2:21 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Slawek,
>
> On Mon, Dec 13, 2010, Slawomir Bochenski wrote:
>> On Mon, Dec 13, 2010 at 1:00 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
>> >> And what about assigned bitmask values for services in src/obex.h?
>> >
>> > Do we need to change something there?
>>
>> In that case src/obex.h is the only place that will need simple
>> modification for now -- MAP service value for services bitmask. This
>> may be OBEX_MAP (or OBEX_MAS) and I supppose its value should be the
>> next one available -- (1 << 8).
>
> Right, we'll need that. I thought you were talking about something
> related to multiple MAS instances (which I don't think affect this
> bitmask in any way).
>
> Johan
>
Yes, if we were to implement multiple instances using multiple
obex_service_driver structures (which would be needed in order to
support additional sdp records and additional channels), then we would
again have to add one define for each planned instance as obexd allows
adding only one service driver per service.
--
Slawomir Bochenski
^ permalink raw reply
* Re: How to implement multiple instances of obexd service?
From: Johan Hedberg @ 2010-12-13 13:21 UTC (permalink / raw)
To: Slawomir Bochenski; +Cc: linux-bluetooth
In-Reply-To: <AANLkTim2Q9dgj0t+AAcww33O=pdOHJp=sfQ_F7s8N08i@mail.gmail.com>
Hi Slawek,
On Mon, Dec 13, 2010, Slawomir Bochenski wrote:
> On Mon, Dec 13, 2010 at 1:00 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> >> And what about assigned bitmask values for services in src/obex.h?
> >
> > Do we need to change something there?
>
> In that case src/obex.h is the only place that will need simple
> modification for now -- MAP service value for services bitmask. This
> may be OBEX_MAP (or OBEX_MAS) and I supppose its value should be the
> next one available -- (1 << 8).
Right, we'll need that. I thought you were talking about something
related to multiple MAS instances (which I don't think affect this
bitmask in any way).
Johan
^ permalink raw reply
* Re: [PATCH] Setting default Link Policy according to the chip supported features
From: Johan Hedberg @ 2010-12-13 13:04 UTC (permalink / raw)
To: Pawel Wieczorkiewicz; +Cc: linux-bluetooth
In-Reply-To: <1292243202-6821-1-git-send-email-pawel.wieczorkiewicz@tieto.com>
Hi Pawel,
On Mon, Dec 13, 2010, Pawel Wieczorkiewicz wrote:
> By default all features are enabled (RSWITCH, HOLD, PARK, SNIFF).
> When "read local supported features" complete event occurs, not supported
> features are disabled and then "Write default link policy" command with
> supported features is sent.
>
> On behalf of ST-Ericsson SA
> ---
> plugins/hciops.c | 31 ++++++++++++++++---------------
> 1 files changed, 16 insertions(+), 15 deletions(-)
In general the patch seems fine and is actually a big improvement to the
hard coded link policy. In the long run I think it'd make sense for the
kernel to do this intialization, and I think I'll do that for mgmtops.
However for this hciops change I do have a few comments:
> static void read_local_features_complete(int index,
> const read_local_features_rp *rp)
> {
> + uint16_t policy;
> +
> if (rp->status)
> return;
>
> + /* Set default link policy */
> + if (!(rp->features[0] & LMP_RSWITCH))
> + main_opts.link_policy &= ~HCI_LP_RSWITCH;
> + if (!(rp->features[0] & LMP_HOLD))
> + main_opts.link_policy &= ~HCI_LP_HOLD;
> + if (!(rp->features[0] & LMP_SNIFF))
> + main_opts.link_policy &= ~HCI_LP_SNIFF;
> + if (!(rp->features[1] & LMP_PARK))
> + main_opts.link_policy &= ~HCI_LP_PARK;
> +
> + policy = htobs(main_opts.link_policy);
> + hci_send_cmd(SK(index), OGF_LINK_POLICY,
> + OCF_WRITE_DEFAULT_LINK_POLICY, 2, &policy);
> +
> memcpy(FEATURES(index), rp->features, 8);
read_local_features is the first command that the kernel sends (after
HCI_Reset) when bringing up a device. Therefore, I think it's a bit
early for userspace to send its own commands at this point. So I'd do
this in through the start_adapter function instead.
> @@ -2046,15 +2056,6 @@ static void init_device(int index)
> if (hci_devinfo(index, &di) < 0)
> goto fail;
>
> - if (!ignore_device(&di)) {
> - dr.dev_opt = main_opts.link_policy;
> - if (ioctl(dd, HCISETLINKPOL, (unsigned long) &dr) < 0 &&
> - errno != ENETDOWN) {
> - error("Can't set link policy on hci%d: %s (%d)",
> - index, strerror(errno), errno);
> - }
> - }
> -
> /* Start HCI device */
> if (ioctl(dd, HCIDEVUP, index) < 0 && errno != EALREADY) {
> error("Can't init device hci%d: %s (%d)",
It looks like the hci_devinfo call above isn't needed anymore after you
remove the ignore_device call. So please remove that too (as well as the
di variable from the function).
Johan
^ permalink raw reply
* Re: How to implement multiple instances of obexd service?
From: Slawomir Bochenski @ 2010-12-13 12:31 UTC (permalink / raw)
To: Slawomir Bochenski, linux-bluetooth
In-Reply-To: <20101213120003.GA12104@jh-x301>
Hello Johan,
On Mon, Dec 13, 2010 at 1:00 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
>> And what about assigned bitmask values for services in src/obex.h?
>
> Do we need to change something there?
In that case src/obex.h is the only place that will need simple
modification for now -- MAP service value for services bitmask. This
may be OBEX_MAP (or OBEX_MAS) and I supppose its value should be the
next one available -- (1 << 8).
--
Slawomir Bochenski
^ permalink raw reply
* [PATCH] Setting default Link Policy according to the chip supported features
From: Pawel Wieczorkiewicz @ 2010-12-13 12:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Pawel Wieczorkiewicz
By default all features are enabled (RSWITCH, HOLD, PARK, SNIFF).
When "read local supported features" complete event occurs, not supported
features are disabled and then "Write default link policy" command with
supported features is sent.
On behalf of ST-Ericsson SA
---
plugins/hciops.c | 31 ++++++++++++++++---------------
1 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/plugins/hciops.c b/plugins/hciops.c
index 4af137c..404422e 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -896,9 +896,25 @@ static void read_local_version_complete(int index,
static void read_local_features_complete(int index,
const read_local_features_rp *rp)
{
+ uint16_t policy;
+
if (rp->status)
return;
+ /* Set default link policy */
+ if (!(rp->features[0] & LMP_RSWITCH))
+ main_opts.link_policy &= ~HCI_LP_RSWITCH;
+ if (!(rp->features[0] & LMP_HOLD))
+ main_opts.link_policy &= ~HCI_LP_HOLD;
+ if (!(rp->features[0] & LMP_SNIFF))
+ main_opts.link_policy &= ~HCI_LP_SNIFF;
+ if (!(rp->features[1] & LMP_PARK))
+ main_opts.link_policy &= ~HCI_LP_PARK;
+
+ policy = htobs(main_opts.link_policy);
+ hci_send_cmd(SK(index), OGF_LINK_POLICY,
+ OCF_WRITE_DEFAULT_LINK_POLICY, 2, &policy);
+
memcpy(FEATURES(index), rp->features, 8);
if (!PENDING(index))
@@ -1949,7 +1965,6 @@ static void at_child_exit(void)
static void device_devup_setup(int index)
{
struct hci_dev_info di;
- uint16_t policy;
read_stored_link_key_cp cp;
DBG("hci%d", index);
@@ -1972,11 +1987,6 @@ static void device_devup_setup(int index)
WRITE_PAGE_TIMEOUT_CP_SIZE, &cp);
}
- /* Set default link policy */
- policy = htobs(main_opts.link_policy);
- hci_send_cmd(SK(index), OGF_LINK_POLICY,
- OCF_WRITE_DEFAULT_LINK_POLICY, 2, &policy);
-
bacpy(&cp.bdaddr, BDADDR_ANY);
cp.read_all = 1;
hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_READ_STORED_LINK_KEY,
@@ -2046,15 +2056,6 @@ static void init_device(int index)
if (hci_devinfo(index, &di) < 0)
goto fail;
- if (!ignore_device(&di)) {
- dr.dev_opt = main_opts.link_policy;
- if (ioctl(dd, HCISETLINKPOL, (unsigned long) &dr) < 0 &&
- errno != ENETDOWN) {
- error("Can't set link policy on hci%d: %s (%d)",
- index, strerror(errno), errno);
- }
- }
-
/* Start HCI device */
if (ioctl(dd, HCIDEVUP, index) < 0 && errno != EALREADY) {
error("Can't init device hci%d: %s (%d)",
--
1.7.0.4
^ permalink raw reply related
* Re: How to implement multiple instances of obexd service?
From: Johan Hedberg @ 2010-12-13 12:00 UTC (permalink / raw)
To: Slawomir Bochenski; +Cc: linux-bluetooth
In-Reply-To: <AANLkTin4xG5KUEpn6QaZA0V6y3cDvxpWhwRJhMrE_8QO@mail.gmail.com>
Hi Slawek,
On Mon, Dec 13, 2010, Slawomir Bochenski wrote:
> In order to fully implement Message Access Profile, support for more
> than one so-called instance is needed (MAP specification, chapter
> 3.1.8). According to specs, separate e-mail accounts on MSE should be
> represented by separate MAS instances. This requires one SDP record
> per instance and those differ by MASInstanceID and ServiceName.
>
> As I understand this also implies that each and every instance needs
> its own separate RFCOMM channel?
Yep, I think that's implied, since othewise we can't detect which MAS
instance the client is trying to connect to (if I read the spec
correctly).
> What would be the preffered way to deal with this ugliness in obexd
> code?
Since we're primarly conserned with supporting only SMS for now, I think
it's too early to start adding complexity to the code due to this
feature. I.e. let's get working MAP with SMS support integrated upstream
and only after that start looking into these more advanced features.
> If separate channels are needed how to keep this in compliance
> with bluez doc/assigned-numbers.txt?
We'll need to reserve some channels for additional MAS instances.
> And what about assigned bitmask values for services in src/obex.h?
Do we need to change something there?
Johan
^ permalink raw reply
* How to implement multiple instances of obexd service?
From: Slawomir Bochenski @ 2010-12-13 11:10 UTC (permalink / raw)
To: linux-bluetooth
In order to fully implement Message Access Profile, support for more
than one so-called instance is needed (MAP specification, chapter
3.1.8). According to specs, separate e-mail accounts on MSE should be
represented by separate MAS instances. This requires one SDP record
per instance and those differ by MASInstanceID and ServiceName.
As I understand this also implies that each and every instance needs
its own separate RFCOMM channel?
What would be the preffered way to deal with this ugliness in obexd
code? If separate channels are needed how to keep this in compliance
with bluez doc/assigned-numbers.txt? And what about assigned bitmask values for
services in src/obex.h?
--
Slawomir Bochenski
^ permalink raw reply
* Re: Start dropping PCMCIA from compat-wireless for 2.6.38+
From: Holger Schurig @ 2010-12-13 7:46 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: linux-wireless, linux-kernel, linux-bluetooth
In-Reply-To: <AANLkTik4W+UxgyPjVyHDeEFTRCkXdDBQ9obgPkpnhzGW@mail.gmail.com>
Please, if the burden is not too much, keep it for the benefit of
embedded people.
If you have some embedded device (e.g. ARM based), it's usually not so
easy to hieve this device to newest 2.6.3[5-7] kernel. However, it's
easy to use your adapted kernel, and compile compat-wireless against it.
I'm in such a situation with libertas_cs.
Greetings,
Holger
--
Homepage: http://www.holgerschurig.de
^ permalink raw reply
* EDR support
From: Manuel Naranjo @ 2010-12-11 20:18 UTC (permalink / raw)
To: BlueZ
Hi guys,
I was checking the latest BlueZ source code and the kernel source code,
and I noticed that by default EDR is disabled, when a dongle is detected
net/bluetooth/hci_core.c initializes the packet types with DM1, DH1 and
HV1, and then net/bluetooth/hci_event.c does it for DM3-5 DH3-5 and
HV3-5, but it never initializes the 2DHx or 3DHx. Was it made on purpose
or is it a bug in the code?
I just figured out how to help and try fixing it, but kernel hacking
isn't an easy to do task, and would prefer to get professional advice first.
Manuel
^ permalink raw reply
* Re: [PATCH] Initial draft of Application registration API
From: Claudio Takahasi @ 2010-12-11 19:27 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <AANLkTik8pqd0uaV2kVaeenBOfTPrVeO0YuW2mfQzJy1J@mail.gmail.com>
Hi Luiz,
On Fri, Dec 10, 2010 at 8:31 AM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi,
>
> On Fri, Dec 10, 2010 at 6:13 AM, Claudio Takahasi
> <claudio.takahasi@openbossa.org> wrote:
>> doc/attribute-api.txt | 44 +++++++++++++++++++++++++++++++++++++++++++-
>> 1 files changed, 43 insertions(+), 1 deletions(-)
>>
>> diff --git a/doc/attribute-api.txt b/doc/attribute-api.txt
>> index 23808e6..ab62313 100644
>> --- a/doc/attribute-api.txt
>> +++ b/doc/attribute-api.txt
>> @@ -23,7 +23,6 @@ fully transparent and a differentiation becomes unimportant in the future.
>> A service consists of some generic service information and a set of
>> characteristics. All characteristic are presented as object path as well.
>>
>> -
>> Local Service hierarchy
>> =======================
>>
>> @@ -37,6 +36,35 @@ Methods
>> Properties
>>
>>
>> +Adapter Application Attribute hierarchy
>> +=======================================
>> +
>> +Service org.bluez
>> +Interface org.bluez.Attrib
>> +Object path [variable prefix]/{hci0,hci1,...}
>> +
>> +Methods void RegisterApplication(array{string} uuids, dict settings)
>> +
>> + Method to allow applications to control automatic
>> + connections to known devices.
>> +
>> + "settings" dictionary defines the wanted application
>> + connection parameters. Defined values:
>> + - Latency: low, medium and high
>> + - BandWidth: TBD
>> + - AutoConnect: boolean
>> +
>> + Latency parameter controls the scan and connect
>> + interval. AutoConnect parameter controls automatic
>> + connections if a bonded device emits a connectable
>> + advertising report.
>> +
>> + void UnregisterApplication(array{string} uuids)
>> +
>> + Unregister a previously registered application.
>> + Remotes are automatically disconnected if no more
>> + applications are interested in the given services.
>> +
>> Device Service hierarchy
>> ========================
>>
>> @@ -154,3 +182,17 @@ Object path freely definable
>> Methods void ValueChanged(object characteristic, array{byte})
>>
>> New raw value of the Characteristic Value attribute.
>> +
>> +Adapter Application Agent hierarchy
>> +====================================
>> +
>> +Service unique name
>> +Interface org.bluez.Application
>> +Object path freely definable
>> +
>> +Methods void Connected(object device, array{object} services)
>> +
>> + Indication that a given remote device was found
>> + and the connection has been established. service
>> + object represents an instance of a primary service
>> + that the application is interested in.
>
> It seems it is missing the object path on RegisterAplication to be
> used to call Connected, also I could see some use of this Application
> Agent for regular (non-LE) profiles, but of course the settings would
> have a bit different purpose for those.
>
> --
> Luiz Augusto von Dentz
> Computer Engineer
>
I discussed this issue with Vinicius before send the initial proposal,
but it is unclear to me if we need to support multiple calls/registers
for the same application or change the parameters. Returning an object
path will be easier to manage the unregister procedure, but once we
export an object path we need to export some methods and properties
for this object. For instance, allow the caller/owner change the UUIDs
and connection parameters.
Is it necessary to pass the application object path in the Connected
method? In my opinion only the object path for the primary services
are enough.
Implement the support for non-LE profiles will be trick, I am not sure
at the moment if we will be able to support BR/EDR and LE profiles
using the same API, but this is something that we already discussed
previously.
Claudio.
^ 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