* [PATCH] Fix process pending request if transfer canceled
From: Daniel Örstadius @ 2010-10-18 8:36 UTC (permalink / raw)
To: linux-bluetooth
[-- Attachment #1: Type: text/plain, Size: 29 bytes --]
Hi,
Please review.
/Daniel
[-- Attachment #2: 0001-Fix-process-pending-request-if-transfer-canceled.patch --]
[-- Type: text/x-patch, Size: 1590 bytes --]
From 7a0bd706951aebf7d66bd63f14d65e5799c9ea69 Mon Sep 17 00:00:00 2001
From: Daniel Orstadius <daniel.orstadius@nokia.com>
Date: Mon, 18 Oct 2010 11:16:40 +0300
Subject: [PATCH] Fix process pending request if transfer canceled
If the call to the Request method of the obex client agent returns
with an error (for example if the transfer is rejected), call
function session_terminate_transfer instead of unregister_transfer
to both unregister the transfer and handle the pending request.
---
client/session.c | 11 ++++++++++-
1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/client/session.c b/client/session.c
index ce3432d..0e635e7 100644
--- a/client/session.c
+++ b/client/session.c
@@ -89,6 +89,9 @@ struct agent_data {
static void session_prepare_put(struct session_data *session, GError *err,
void *data);
+static void session_terminate_transfer(struct session_data *session,
+ struct transfer_data *transfer,
+ GError *gerr);
static GQuark obex_io_error_quark(void)
{
@@ -803,11 +806,17 @@ static void session_request_reply(DBusPendingCall *call, gpointer user_data)
dbus_error_init(&derr);
if (dbus_set_error_from_message(&derr, reply)) {
+ GError *gerr = NULL;
+
error("Replied with an error: %s, %s",
derr.name, derr.message);
dbus_error_free(&derr);
dbus_message_unref(reply);
- transfer_unregister(pending->transfer);
+
+ g_set_error(&gerr, OBEX_IO_ERROR, -ECANCELED, "%s", derr.message);
+ session_terminate_transfer(session, pending->transfer, gerr);
+ g_clear_error(&gerr);
+
return;
}
--
1.6.0.4
^ permalink raw reply related
* Re: [PATCH] Fix linkage failure for bluetoothd
From: Johan Hedberg @ 2010-10-18 9:22 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: linux-bluetooth
In-Reply-To: <1287171971-32246-1-git-send-email-padovan@profusion.mobi>
Hi Gustavo,
On Fri, Oct 15, 2010, Gustavo F. Padovan wrote:
> Adding -lrt fix the following errors in one of my systems:
>
> health/mcap_sync.o: In function `initialize_caps':
> /root/bluez/health/mcap_sync.c:341: undefined reference to `clock_getres'
> /root/bluez/health/mcap_sync.c:350: undefined reference to `clock_gettime'
> /root/bluez/health/mcap_sync.c:358: undefined reference to `clock_gettime'
> /root/bluez/health/mcap_sync.c:363: undefined reference to `clock_gettime'
> health/mcap_sync.o: In function `reset_tmstamp':
> /root/bluez/health/mcap_sync.c:163: undefined reference to `clock_gettime'
> health/mcap_sync.o: In function `mcap_get_timestamp':
> /root/bluez/health/mcap_sync.c:309: undefined reference to `clock_gettime'
> health/mcap_sync.o:/root/bluez/health/mcap_sync.c:514: more undefined references to `clock_gettime' follow
> collect2: ld returned 1 exit status
> make[1]: *** [src/bluetoothd] Error 1
> make: *** [all] Error 2
> ---
> Makefile.am | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
Pushed upstream. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] bluetooth: fix unaligned access to l2cap conf data
From: Marcel Holtmann @ 2010-10-18 11:51 UTC (permalink / raw)
To: Mike Frysinger
Cc: linux-bluetooth, uclinux-dist-devel, linux-kernel, Andrew Morton,
steven miao
In-Reply-To: <1287268187-9628-1-git-send-email-vapier@gentoo.org>
Hi Mike,
> In function l2cap_get_conf_opt() and l2cap_add_conf_opt() the address of
> opt->val sometimes is not at the edge of 2-bytes/4-bytes, so 2-bytes/4 bytes
> access will cause data misalignment exeception. Use get_unaligned_le16/32
> and put_unaligned_le16/32 function to avoid data misalignment execption.
>
> Signed-off-by: steven miao <realmz6@gmail.com>
> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
> ---
> was posted a month ago with no feedback ...
must have slipped through. However I don't remember it being on
linux-bluetooth at all. Maybe it was on the other mailing lists :(
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply
* Re: [PATCH 2/3] bluetooth: Remove some unnecessary error messages
From: Marcel Holtmann @ 2010-10-18 11:55 UTC (permalink / raw)
To: Matthew Garrett; +Cc: linux-bluetooth, linux-usb
In-Reply-To: <1284659895-27984-2-git-send-email-mjg@redhat.com>
Hi Matthew,
> The main reason for these urbs to error out on submission is that runtime
> pm has kicked in, which is unnecessary noise. Let's just drop them.
do we wanna remove them or just turn into BT_DBG which is under dynamic
debug control. Or do we have a set of error results that we do wanna
print and others that we wanna ignore?
Regards
Marcel
^ permalink raw reply
* [RFC] Bluetooth Low energy support
From: Ville Tervo @ 2010-10-18 13:02 UTC (permalink / raw)
To: linux-bluetooth
Hi,
Here is v2 of bluetooth low energy patch set.
Changes from previous version.
- le_state is dropped
- support for shared ACL buffer
- various fixes proposed by reviewers.
--
Ville
^ permalink raw reply
* [PATCH 1/6] Bluetooth: Add low energy commands and events
From: Ville Tervo @ 2010-10-18 13:02 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ville Tervo
In-Reply-To: <1287406976-13463-1-git-send-email-ville.tervo@nokia.com>
Add needed HCI command and event structs to
create LE connections.
Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
---
include/net/bluetooth/hci.h | 49 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index e30e008..ee5beec 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -593,6 +593,36 @@ struct hci_rp_read_bd_addr {
bdaddr_t bdaddr;
} __packed;
+#define HCI_OP_LE_SET_EVENT_MASK 0x2001
+struct hci_cp_le_set_event_mask {
+ __u8 mask[8];
+} __packed;
+
+#define HCI_OP_LE_READ_BUFFER_SIZE 0x2002
+struct hci_rp_le_read_buffer_size {
+ __u8 status;
+ __le16 le_mtu;
+ __u8 le_max_pkt;
+} __packed;
+
+#define HCI_OP_LE_CREATE_CONN 0x200d
+struct hci_cp_le_create_conn {
+ __le16 scan_interval;
+ __le16 scan_window;
+ __u8 filter_policy;
+ __u8 peer_addr_type;
+ bdaddr_t peer_addr;
+ __u8 own_address_type;
+ __le16 conn_interval_min;
+ __le16 conn_interval_max;
+ __le16 conn_latency;
+ __le16 supervision_timeout;
+ __le16 min_ce_len;
+ __le16 max_ce_len;
+} __packed;
+
+#define HCI_OP_LE_CREATE_CONN_CANCEL 0x200e
+
/* ---- HCI Events ---- */
#define HCI_EV_INQUIRY_COMPLETE 0x01
@@ -845,6 +875,25 @@ struct hci_ev_remote_host_features {
__u8 features[8];
} __packed;
+#define HCI_EV_LE_META 0x3e
+struct hci_ev_le_meta {
+ __u8 subevent;
+} __packed;
+
+/* Low energy meta events */
+#define HCI_EV_LE_CONN_COMPLETE 0x01
+struct hci_ev_le_conn_complete {
+ __u8 status;
+ __le16 handle;
+ __u8 role;
+ __u8 bdaddr_type;
+ bdaddr_t bdaddr;
+ __le16 interval;
+ __le16 latency;
+ __le16 supervision_timeout;
+ __u8 clk_accurancy;
+} __packed;
+
/* Internal events generated by Bluetooth stack */
#define HCI_EV_STACK_INTERNAL 0xfd
struct hci_ev_stack_internal {
--
1.7.1
^ permalink raw reply related
* [PATCH 2/6] Bluetooth: Add LE connect support
From: Ville Tervo @ 2010-10-18 13:02 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ville Tervo
In-Reply-To: <1287406976-13463-1-git-send-email-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>
---
include/net/bluetooth/hci.h | 2 +
include/net/bluetooth/hci_core.h | 21 +++++++--
net/bluetooth/hci_conn.c | 51 +++++++++++++++++++-
net/bluetooth/hci_event.c | 94 +++++++++++++++++++++++++++++++++++++-
4 files changed, 160 insertions(+), 8 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index ee5beec..02055b9 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -159,6 +159,8 @@ enum {
#define SCO_LINK 0x00
#define ACL_LINK 0x01
#define ESCO_LINK 0x02
+/* Low Energy links do not have defined link type. Use invented one */
+#define LE_LINK 0x80
/* LMP features */
#define LMP_3SLOT 0x01
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index ebec8c9..fc2aaee 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -60,6 +60,7 @@ struct hci_conn_hash {
spinlock_t lock;
unsigned int acl_num;
unsigned int sco_num;
+ unsigned int le_num;
};
struct bdaddr_list {
@@ -272,20 +273,32 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
{
struct hci_conn_hash *h = &hdev->conn_hash;
list_add(&c->list, &h->list);
- if (c->type == ACL_LINK)
+ switch (c->type) {
+ case ACL_LINK:
h->acl_num++;
- else
+ break;
+ case LE_LINK:
+ h->le_num++;
+ break;
+ default:
h->sco_num++;
+ }
}
static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
{
struct hci_conn_hash *h = &hdev->conn_hash;
list_del(&c->list);
- if (c->type == ACL_LINK)
+ switch (c->type) {
+ case ACL_LINK:
h->acl_num--;
- else
+ break;
+ case LE_LINK:
+ h->le_num--;
+ break;
+ default:
h->sco_num--;
+ }
}
static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 0b1e460..c1eb8e0 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -45,6 +45,32 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
+void hci_le_connect(struct hci_conn *conn)
+{
+ struct hci_dev *hdev = conn->hdev;
+ struct hci_cp_le_create_conn cp;
+
+ conn->state = BT_CONNECT;
+ conn->out = 1;
+
+ memset(&cp, 0, sizeof(cp));
+ cp.scan_interval = cpu_to_le16(0x0004);
+ cp.scan_window = cpu_to_le16(0x0004);
+ bacpy(&cp.peer_addr, &conn->dst);
+ cp.conn_interval_min = cpu_to_le16(0x0008);
+ cp.conn_interval_max = cpu_to_le16(0x0100);
+ cp.supervision_timeout = cpu_to_le16(0x0064);
+ cp.min_ce_len = cpu_to_le16(0x0001);
+ cp.max_ce_len = cpu_to_le16(0x0001);
+
+ hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
+}
+
+static void hci_le_connect_cancel(struct hci_conn *conn)
+{
+ hci_send_cmd(conn->hdev, HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL);
+}
+
void hci_acl_connect(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
@@ -192,8 +218,12 @@ static void hci_conn_timeout(unsigned long arg)
switch (conn->state) {
case BT_CONNECT:
case BT_CONNECT2:
- if (conn->type == ACL_LINK && conn->out)
- hci_acl_connect_cancel(conn);
+ if (conn->out) {
+ if (conn->type == ACL_LINK)
+ hci_acl_connect_cancel(conn);
+ else if (conn->type == LE_LINK)
+ hci_le_connect_cancel(conn);
+ }
break;
case BT_CONFIG:
case BT_CONNECTED:
@@ -359,15 +389,30 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
}
EXPORT_SYMBOL(hci_get_route);
-/* Create SCO or ACL connection.
+/* Create SCO, ACL or LE connection.
* Device _must_ be locked */
struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type)
{
struct hci_conn *acl;
struct hci_conn *sco;
+ struct hci_conn *le;
BT_DBG("%s dst %s", hdev->name, batostr(dst));
+ if (type == LE_LINK) {
+ le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
+
+ if (!le)
+ le = hci_conn_add(hdev, LE_LINK, dst);
+
+ if (!le)
+ return NULL;
+
+ hci_le_connect(le);
+
+ return le;
+ }
+
if (!(acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
return NULL;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 84093b0..4061613 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -822,6 +822,43 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
hci_dev_unlock(hdev);
}
+static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
+{
+ struct hci_cp_le_create_conn *cp;
+ struct hci_conn *conn;
+
+ BT_DBG("%s status 0x%x", hdev->name, status);
+
+ cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
+ if (!cp)
+ return;
+
+ hci_dev_lock(hdev);
+
+ conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
+
+ BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
+ conn);
+
+ if (status) {
+ if (conn && conn->state == BT_CONNECT) {
+ conn->state = BT_CLOSED;
+ hci_proto_connect_cfm(conn, status);
+ hci_conn_del(conn);
+ }
+ } else {
+ if (!conn) {
+ conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
+ if (conn)
+ conn->out = 1;
+ else
+ BT_ERR("No memory for new connection");
+ }
+ }
+
+ hci_dev_unlock(hdev);
+}
+
static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
@@ -1024,7 +1061,6 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
if (conn) {
conn->state = BT_CLOSED;
-
hci_proto_disconn_cfm(conn, ev->reason);
hci_conn_del(conn);
}
@@ -1382,6 +1418,10 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cs_exit_sniff_mode(hdev, ev->status);
break;
+ case HCI_OP_LE_CREATE_CONN:
+ hci_cs_le_create_conn(hdev, ev->status);
+ break;
+
default:
BT_DBG("%s opcode 0x%x", hdev->name, opcode);
break;
@@ -1827,6 +1867,54 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_
hci_dev_unlock(hdev);
}
+static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_ev_le_conn_complete *ev = (void *) skb->data;
+ struct hci_conn *conn;
+
+ BT_DBG("%s status %d", hdev->name, ev->status);
+
+ hci_dev_lock(hdev);
+
+ conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
+ if (!conn)
+ goto unlock;
+
+ if (ev->status) {
+ hci_proto_connect_cfm(conn, ev->status);
+ conn->state = BT_CLOSED;
+ hci_conn_del(conn);
+ goto unlock;
+ }
+
+ conn->handle = __le16_to_cpu(ev->handle);
+ conn->state = BT_CONNECTED;
+
+ hci_conn_hold_device(conn);
+ hci_conn_add_sysfs(conn);
+
+ hci_proto_connect_cfm(conn, ev->status);
+
+unlock:
+ hci_dev_unlock(hdev);
+}
+
+static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_ev_le_meta *le_ev = (void *) skb->data;
+
+ skb_pull(skb, sizeof(*le_ev));
+
+ switch (le_ev->subevent) {
+ case HCI_EV_LE_CONN_COMPLETE:
+ hci_le_conn_complete_evt(hdev, skb);
+ break;
+
+ default:
+ break;
+ }
+}
+
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_event_hdr *hdr = (void *) skb->data;
@@ -1963,6 +2051,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_remote_host_features_evt(hdev, skb);
break;
+ case HCI_EV_LE_META:
+ hci_le_meta_evt(hdev, skb);
+ break;
+
default:
BT_DBG("%s event 0x%x", hdev->name, event);
break;
--
1.7.1
^ permalink raw reply related
* [PATCH 3/6] Bluetooth: Use LE buffers for LE traffic
From: Ville Tervo @ 2010-10-18 13:02 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ville Tervo
In-Reply-To: <1287406976-13463-1-git-send-email-ville.tervo@nokia.com>
BLuetooth chips may have separate buffers for
LE traffic. This patch add support to use LE
buffers provided by the chip.
Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
---
include/net/bluetooth/hci.h | 2 +
include/net/bluetooth/hci_core.h | 5 +++
net/bluetooth/hci_conn.c | 6 +++
net/bluetooth/hci_core.c | 74 +++++++++++++++++++++++++++++++++++--
net/bluetooth/hci_event.c | 40 +++++++++++++++++++-
5 files changed, 121 insertions(+), 6 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 02055b9..b42edf0 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -189,6 +189,8 @@ enum {
#define LMP_EV4 0x01
#define LMP_EV5 0x02
+#define LMP_NO_BREDR 0x20
+#define LMP_LE 0x40
#define LMP_SNIFF_SUBR 0x02
#define LMP_EDR_ESCO_2M 0x20
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index fc2aaee..326d290 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -103,15 +103,19 @@ struct hci_dev {
atomic_t cmd_cnt;
unsigned int acl_cnt;
unsigned int sco_cnt;
+ unsigned int le_cnt;
unsigned int acl_mtu;
unsigned int sco_mtu;
+ unsigned int le_mtu;
unsigned int acl_pkts;
unsigned int sco_pkts;
+ unsigned int le_pkts;
unsigned long cmd_last_tx;
unsigned long acl_last_tx;
unsigned long sco_last_tx;
+ unsigned long le_last_tx;
struct workqueue_struct *workqueue;
@@ -469,6 +473,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_le_capable(dev) ((dev)->features[4] & LMP_LE)
/* ----- HCI protocols ----- */
struct hci_proto {
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index c1eb8e0..c7309e4 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -324,6 +324,11 @@ int hci_conn_del(struct hci_conn *conn)
/* Unacked frames */
hdev->acl_cnt += conn->sent;
+ } else if (conn->type == LE_LINK) {
+ if (hdev->le_pkts)
+ hdev->le_cnt += conn->sent;
+ else
+ hdev->acl_cnt += conn->sent;
} else {
struct hci_conn *acl = conn->link;
if (acl) {
@@ -409,6 +414,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
return NULL;
hci_le_connect(le);
+ hci_conn_hold(le);
return le;
}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index bc2a052..45c78c2 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -254,6 +254,14 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m);
}
+static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
+{
+ BT_DBG("%s", hdev->name);
+
+ /* Read LE buffer size */
+ hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
+}
+
static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
{
__u8 scan = opt;
@@ -509,6 +517,10 @@ int hci_dev_open(__u16 dev)
ret = __hci_request(hdev, hci_init_req, 0,
msecs_to_jiffies(HCI_INIT_TIMEOUT));
+ if (lmp_le_capable(hdev))
+ ret = __hci_request(hdev, hci_le_init_req, 0,
+ msecs_to_jiffies(HCI_INIT_TIMEOUT));
+
clear_bit(HCI_INIT, &hdev->flags);
}
@@ -645,7 +657,7 @@ int hci_dev_reset(__u16 dev)
hdev->flush(hdev);
atomic_set(&hdev->cmd_cnt, 1);
- hdev->acl_cnt = 0; hdev->sco_cnt = 0;
+ hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
if (!test_bit(HCI_RAW, &hdev->flags))
ret = __hci_request(hdev, hci_reset_req, 0,
@@ -1456,8 +1468,25 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
}
if (conn) {
- int cnt = (type == ACL_LINK ? hdev->acl_cnt : hdev->sco_cnt);
- int q = cnt / num;
+ int cnt, q;
+
+ switch (conn->type) {
+ case ACL_LINK:
+ cnt = hdev->acl_cnt;
+ break;
+ case SCO_LINK:
+ case ESCO_LINK:
+ cnt = hdev->sco_cnt;
+ break;
+ case LE_LINK:
+ cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
+ break;
+ default:
+ cnt = 0;
+ BT_ERR("Unknown link type");
+ }
+
+ q = cnt / num;
*quote = q ? q : 1;
} else
*quote = 0;
@@ -1556,6 +1585,40 @@ static inline void hci_sched_esco(struct hci_dev *hdev)
}
}
+static inline void hci_sched_le(struct hci_dev *hdev)
+{
+ struct hci_conn *conn;
+ struct sk_buff *skb;
+ int quote, cnt;
+
+ BT_DBG("%s", hdev->name);
+
+ if (!test_bit(HCI_RAW, &hdev->flags)) {
+ /* ACL tx timeout must be longer than maximum
+ * link supervision timeout (40.9 seconds) */
+ if (!hdev->le_cnt &&
+ time_after(jiffies, hdev->le_last_tx + HZ * 45))
+ hci_acl_tx_to(hdev);
+ }
+
+ cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
+ while (cnt && (conn = hci_low_sent(hdev, LE_LINK, "e))) {
+ while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
+ BT_DBG("skb %p len %d", skb, skb->len);
+
+ hci_send_frame(skb);
+ hdev->le_last_tx = jiffies;
+
+ cnt--;
+ conn->sent++;
+ }
+ }
+ if (hdev->le_pkts)
+ hdev->le_cnt = cnt;
+ else
+ hdev->acl_cnt = cnt;
+}
+
static void hci_tx_task(unsigned long arg)
{
struct hci_dev *hdev = (struct hci_dev *) arg;
@@ -1563,7 +1626,8 @@ static void hci_tx_task(unsigned long arg)
read_lock(&hci_task_lock);
- BT_DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
+ BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
+ hdev->sco_cnt, hdev->le_cnt);
/* Schedule queues and send stuff to HCI driver */
@@ -1573,6 +1637,8 @@ static void hci_tx_task(unsigned long arg)
hci_sched_esco(hdev);
+ hci_sched_le(hdev);
+
/* Send next queued raw (unknown type) packet */
while ((skb = skb_dequeue(&hdev->raw_q)))
hci_send_frame(skb);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 4061613..499c823 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -539,6 +539,26 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
hci_req_complete(hdev, rp->status);
}
+static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
+
+ BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+ if (rp->status)
+ return;
+
+ hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
+ hdev->le_pkts = rp->le_max_pkt;
+
+ hdev->le_cnt = hdev->le_pkts;
+
+ BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
+
+ hci_req_complete(hdev, rp->status);
+}
+
static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
{
BT_DBG("%s status 0x%x", hdev->name, status);
@@ -1352,6 +1372,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_cc_read_bd_addr(hdev, skb);
break;
+ case HCI_OP_LE_READ_BUFFER_SIZE:
+ hci_cc_le_read_buffer_size(hdev, skb);
+ break;
+
default:
BT_DBG("%s opcode 0x%x", hdev->name, opcode);
break;
@@ -1489,10 +1513,22 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
conn->sent -= count;
if (conn->type == ACL_LINK) {
- if ((hdev->acl_cnt += count) > hdev->acl_pkts)
+ hdev->acl_cnt += count;
+ if (hdev->acl_cnt > hdev->acl_pkts)
hdev->acl_cnt = hdev->acl_pkts;
+ } else if (conn->type == LE_LINK) {
+ if (hdev->le_pkts) {
+ hdev->le_cnt += count;
+ if (hdev->le_cnt > hdev->le_pkts)
+ hdev->le_cnt = hdev->le_pkts;
+ } else {
+ hdev->acl_cnt += count;
+ if (hdev->acl_cnt > hdev->acl_pkts)
+ hdev->acl_cnt = hdev->acl_pkts;
+ }
} else {
- if ((hdev->sco_cnt += count) > hdev->sco_pkts)
+ hdev->sco_cnt += count;
+ if (hdev->sco_cnt > hdev->sco_pkts)
hdev->sco_cnt = hdev->sco_pkts;
}
}
--
1.7.1
^ permalink raw reply related
* [PATCH 4/6] Bluetooth: Add LE connection support to L2CAP
From: Ville Tervo @ 2010-10-18 13:02 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ville Tervo
In-Reply-To: <1287406976-13463-1-git-send-email-ville.tervo@nokia.com>
Add basic LE connection support to L2CAP. LE
connection can be created by specifying cid
in struct sockaddr_l2
Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
---
include/net/bluetooth/l2cap.h | 3 +++
net/bluetooth/l2cap.c | 32 ++++++++++++++++++++++++--------
2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index c819c8b..cc3a140 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -160,6 +160,9 @@ struct l2cap_conn_rsp {
/* channel indentifier */
#define L2CAP_CID_SIGNALING 0x0001
#define L2CAP_CID_CONN_LESS 0x0002
+#define L2CAP_CID_LE_DATA 0x0004
+#define L2CAP_CID_LE_SIGNALING 0x0005
+#define L2CAP_CID_SMP 0x0006
#define L2CAP_CID_DYN_START 0x0040
#define L2CAP_CID_DYN_END 0xffff
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 16049de..bf5daf3 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -617,6 +617,12 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
bh_lock_sock(sk);
+ if (conn->hcon->type == LE_LINK) {
+ l2cap_sock_clear_timer(sk);
+ sk->sk_state = BT_CONNECTED;
+ sk->sk_state_change(sk);
+ }
+
if (sk->sk_type != SOCK_SEQPACKET &&
sk->sk_type != SOCK_STREAM) {
l2cap_sock_clear_timer(sk);
@@ -675,7 +681,11 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
BT_DBG("hcon %p conn %p", hcon, conn);
- conn->mtu = hcon->hdev->acl_mtu;
+ if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
+ conn->mtu = hcon->hdev->le_mtu;
+ else
+ conn->mtu = hcon->hdev->acl_mtu;
+
conn->src = &hcon->hdev->bdaddr;
conn->dst = &hcon->dst;
@@ -1102,8 +1112,13 @@ static int l2cap_do_connect(struct sock *sk)
}
}
- hcon = hci_connect(hdev, ACL_LINK, dst,
+ if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA)
+ hcon = hci_connect(hdev, LE_LINK, dst,
+ l2cap_pi(sk)->sec_level, auth_type);
+ else
+ hcon = hci_connect(hdev, ACL_LINK, dst,
l2cap_pi(sk)->sec_level, auth_type);
+
if (!hcon)
goto done;
@@ -1154,13 +1169,13 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
len = min_t(unsigned int, sizeof(la), alen);
memcpy(&la, addr, len);
- if (la.l2_cid)
+ if (la.l2_cid && la.l2_psm)
return -EINVAL;
lock_sock(sk);
if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
- && !la.l2_psm) {
+ && !(la.l2_psm || la.l2_cid)) {
err = -EINVAL;
goto done;
}
@@ -1202,14 +1217,15 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
/* PSM must be odd and lsb of upper byte must be 0 */
if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 &&
- sk->sk_type != SOCK_RAW) {
+ sk->sk_type != SOCK_RAW && !la.l2_cid) {
err = -EINVAL;
goto done;
}
- /* Set destination address and psm */
+ /* Set destination address and psm or cid */
bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
l2cap_pi(sk)->psm = la.l2_psm;
+ l2cap_pi(sk)->dcid = la.l2_cid;
err = l2cap_do_connect(sk);
if (err)
@@ -4525,7 +4541,7 @@ static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
- if (hcon->type != ACL_LINK)
+ if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK))
return -EINVAL;
if (!status) {
@@ -4554,7 +4570,7 @@ static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
{
BT_DBG("hcon %p reason %d", hcon, reason);
- if (hcon->type != ACL_LINK)
+ if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK))
return -EINVAL;
l2cap_conn_del(hcon, bt_err(reason));
--
1.7.1
^ permalink raw reply related
* [PATCH 5/6] Bluetooth: Add server socket support for LE connection
From: Ville Tervo @ 2010-10-18 13:02 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ville Tervo
In-Reply-To: <1287406976-13463-1-git-send-email-ville.tervo@nokia.com>
Add support for LE server sockets.
Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
---
include/net/bluetooth/l2cap.h | 1 +
net/bluetooth/hci_event.c | 10 +++-
net/bluetooth/l2cap.c | 101 +++++++++++++++++++++++++++++++++++++++--
3 files changed, 105 insertions(+), 7 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index cc3a140..cba4423 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -38,6 +38,7 @@
#define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */
#define L2CAP_DEFAULT_ACK_TO 200
#define L2CAP_LOCAL_BUSY_TRIES 12
+#define L2CAP_LE_DEFAULT_MTU 23
#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */
#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 499c823..1b431a7 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1913,8 +1913,14 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
- if (!conn)
- goto unlock;
+ if (!conn) {
+ conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
+ if (!conn) {
+ BT_ERR("No memory for new connection");
+ hci_dev_unlock(hdev);
+ return;
+ }
+ }
if (ev->status) {
hci_proto_connect_cfm(conn, ev->status);
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index bf5daf3..3f0f036 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -82,6 +82,8 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
+static void l2cap_le_conn_ready(struct l2cap_conn *conn);
+
/* ---- L2CAP timers ---- */
static void l2cap_sock_timeout(unsigned long arg)
{
@@ -228,8 +230,16 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so
l2cap_pi(sk)->conn = conn;
if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
- /* Alloc CID for connection-oriented socket */
- l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
+ if (conn->hcon->type == LE_LINK) {
+ /* LE connection */
+ l2cap_pi(sk)->omtu = L2CAP_LE_DEFAULT_MTU;
+ l2cap_pi(sk)->scid = L2CAP_CID_LE_DATA;
+ l2cap_pi(sk)->dcid = L2CAP_CID_LE_DATA;
+ } else {
+ /* Alloc CID for connection-oriented socket */
+ l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
+ l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
+ }
} else if (sk->sk_type == SOCK_DGRAM) {
/* Connectionless socket */
l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
@@ -612,6 +622,9 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
BT_DBG("conn %p", conn);
+ if (!conn->hcon->out && conn->hcon->type == LE_LINK)
+ l2cap_le_conn_ready(conn);
+
read_lock(&l->lock);
for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
@@ -694,7 +707,8 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
spin_lock_init(&conn->lock);
rwlock_init(&conn->chan_list.lock);
- setup_timer(&conn->info_timer, l2cap_info_timeout,
+ if (hcon->type != LE_LINK)
+ setup_timer(&conn->info_timer, l2cap_info_timeout,
(unsigned long) conn);
conn->disc_reason = 0x13;
@@ -796,6 +810,37 @@ static void l2cap_sock_destruct(struct sock *sk)
skb_queue_purge(&sk->sk_write_queue);
}
+static inline struct sock *l2cap_get_sock_by_cid(int state, __le16 cid, bdaddr_t *src)
+{
+ struct sock *s;
+ struct sock *sk = NULL, *sk1 = NULL;
+ struct hlist_node *node;
+
+ read_lock(&l2cap_sk_list.lock);
+ sk_for_each(sk, node, &l2cap_sk_list.head) {
+ if (state && sk->sk_state != state)
+ continue;
+
+ if (l2cap_pi(sk)->dcid == cid) {
+ /* Exact match. */
+ if (!bacmp(&bt_sk(sk)->src, src))
+ break;
+
+ /* Closest match */
+ if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
+ sk1 = sk;
+ }
+ }
+
+ s = node ? sk : sk1;
+
+ if (s)
+ bh_lock_sock(s);
+ read_unlock(&l2cap_sk_list.lock);
+
+ return s;
+}
+
static void l2cap_sock_cleanup_listen(struct sock *parent)
{
struct sock *sk;
@@ -1008,7 +1053,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
len = min_t(unsigned int, sizeof(la), alen);
memcpy(&la, addr, len);
- if (la.l2_cid)
+ if (la.l2_cid && la.l2_psm)
return -EINVAL;
lock_sock(sk);
@@ -1050,6 +1095,9 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
}
+ if (la.l2_cid)
+ l2cap_pi(sk)->dcid = la.l2_cid;
+
write_unlock_bh(&l2cap_sk_list.lock);
done:
@@ -1267,7 +1315,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
goto done;
}
- if (!l2cap_pi(sk)->psm) {
+ if (!l2cap_pi(sk)->psm && !l2cap_pi(sk)->dcid) {
bdaddr_t *src = &bt_sk(sk)->src;
u16 psm;
@@ -1377,6 +1425,49 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
return 0;
}
+static void l2cap_le_conn_ready(struct l2cap_conn *conn)
+{
+ struct l2cap_chan_list *list = &conn->chan_list;
+ struct sock *parent, *uninitialized_var(sk);
+
+ BT_DBG("");
+
+ /* Check if we have socket listening on cid */
+ parent = l2cap_get_sock_by_cid(BT_LISTEN, 0x04, conn->src);
+ if (!parent)
+ goto clean;
+
+ /* Check for backlog size */
+ if (sk_acceptq_is_full(parent)) {
+ BT_DBG("backlog full %d", parent->sk_ack_backlog);
+ goto clean;
+ }
+
+ sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
+ if (!sk)
+ goto clean;
+
+ write_lock_bh(&list->lock);
+
+ hci_conn_hold(conn->hcon);
+
+ l2cap_sock_init(sk, parent);
+ bacpy(&bt_sk(sk)->src, conn->src);
+ bacpy(&bt_sk(sk)->dst, conn->dst);
+
+ __l2cap_chan_add(conn, sk, parent);
+
+ l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
+
+ sk->sk_state = BT_CONNECTED;
+ parent->sk_data_ready(parent, 0);
+
+ write_unlock_bh(&list->lock);
+
+clean:
+ bh_unlock_sock(parent);
+}
+
static int __l2cap_wait_ack(struct sock *sk)
{
DECLARE_WAITQUEUE(wait, current);
--
1.7.1
^ permalink raw reply related
* [PATCH 6/6] Bluetooth: Do not send disconn comand over LE links
From: Ville Tervo @ 2010-10-18 13:02 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ville Tervo
In-Reply-To: <1287406976-13463-1-git-send-email-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 3f0f036..2bf083e 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) {
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) {
struct l2cap_conn_rsp rsp;
__u16 result;
--
1.7.1
^ permalink raw reply related
* [PATCH] Get mode option for L2CAP sockets
From: Santiago Carot-Nemesio @ 2010-10-18 13:21 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Santiago Carot-Nemesio
---
btio/btio.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/btio/btio.c b/btio/btio.c
index 2f719b1..d8439e0 100644
--- a/btio/btio.c
+++ b/btio/btio.c
@@ -839,6 +839,9 @@ static gboolean l2cap_get(int sock, GError **err, BtIOOption opt1,
}
memcpy(va_arg(args, uint8_t *), dev_class, 3);
break;
+ case BT_IO_OPT_MODE:
+ *(va_arg(args, uint8_t *)) = l2o.mode;
+ break;
default:
g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
"Unknown option %d", opt);
--
1.7.3.1
^ permalink raw reply related
* Re: [PATCH] Fix process pending request if transfer canceled
From: Luiz Augusto von Dentz @ 2010-10-18 13:28 UTC (permalink / raw)
To: Daniel Örstadius; +Cc: linux-bluetooth
In-Reply-To: <AANLkTikmpwse=s3Z5+RzgrPCSy-qVhYkLxA1kRZrECnJ@mail.gmail.com>
Hi,
On Mon, Oct 18, 2010 at 11:36 AM, Daniel Örstadius
<daniel.orstadius@gmail.com> wrote:
> Hi,
>
> Please review.
>
> /Daniel
>
Acked-by: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
--
Luiz Augusto von Dentz
Computer Engineer
^ permalink raw reply
* Re: [PATCH] Get mode option for L2CAP sockets
From: Johan Hedberg @ 2010-10-18 14:16 UTC (permalink / raw)
To: Santiago Carot-Nemesio; +Cc: linux-bluetooth
In-Reply-To: <1287408102-25344-1-git-send-email-sancane@gmail.com>
Hi,
On Mon, Oct 18, 2010, Santiago Carot-Nemesio wrote:
> ---
> btio/btio.c | 3 +++
> 1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/btio/btio.c b/btio/btio.c
> index 2f719b1..d8439e0 100644
> --- a/btio/btio.c
> +++ b/btio/btio.c
> @@ -839,6 +839,9 @@ static gboolean l2cap_get(int sock, GError **err, BtIOOption opt1,
> }
> memcpy(va_arg(args, uint8_t *), dev_class, 3);
> break;
> + case BT_IO_OPT_MODE:
> + *(va_arg(args, uint8_t *)) = l2o.mode;
> + break;
> default:
> g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
> "Unknown option %d", opt);
Pushed upstream. Thanks.
Johan
^ permalink raw reply
* [PATCH 1/3] Make use of transfer->err to store transfer errors
From: Luiz Augusto von Dentz @ 2010-10-18 14:18 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
---
client/transfer.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/client/transfer.c b/client/transfer.c
index ea98b32..6eec513 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -360,7 +360,7 @@ static void put_xfer_progress(GwObexXfer *xfer, gpointer user_data)
{
struct transfer_data *transfer = user_data;
struct transfer_callback *callback = transfer->callback;
- gint written, err = 0;
+ gint written;
if (transfer->buffer_len == 0) {
transfer->buffer_len = DEFAULT_BUFFER_SIZE;
@@ -373,20 +373,20 @@ static void put_xfer_progress(GwObexXfer *xfer, gpointer user_data)
len = read(transfer->fd, transfer->buffer + transfer->filled,
transfer->buffer_len - transfer->filled);
if (len < 0) {
- err = -errno;
+ transfer->err = -errno;
goto done;
}
transfer->filled += len;
if (transfer->filled == 0) {
- gw_obex_xfer_close(xfer, &err);
+ gw_obex_xfer_close(xfer, &transfer->err);
goto done;
}
if (gw_obex_xfer_write(xfer, transfer->buffer,
transfer->filled,
- &written, &err) == FALSE)
+ &written, &transfer->err) == FALSE)
goto done;
transfer->filled -= written;
@@ -397,7 +397,7 @@ static void put_xfer_progress(GwObexXfer *xfer, gpointer user_data)
done:
if (callback)
- callback->func(transfer, transfer->transferred, err,
+ callback->func(transfer, transfer->transferred, transfer->err,
callback->data);
}
--
1.7.1
^ permalink raw reply related
* [PATCH 2/3] Fix not setting proper errors when canceling suspended requests
From: Luiz Augusto von Dentz @ 2010-10-18 14:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1287411529-5806-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
---
src/obex.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/obex.c b/src/obex.c
index f37cd90..6d4430d 100644
--- a/src/obex.c
+++ b/src/obex.c
@@ -702,9 +702,10 @@ static gboolean handle_async_io(void *object, int flags, int err,
ret = obex_read_stream(os, os->obex, os->obj);
proceed:
- if (ret < 0)
+ if (ret < 0) {
+ os_set_response(os->obj, err);
OBEX_CancelRequest(os->obex, TRUE);
- else
+ } else
OBEX_ResumeRequest(os->obex);
return FALSE;
--
1.7.1
^ permalink raw reply related
* [PATCH 3/3] Fix possible invalid read
From: Luiz Augusto von Dentz @ 2010-10-18 14:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1287411529-5806-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
==3229== Invalid read of size 4
==3229== at 0x1D218: obex_object_set_io_flags (in /usr/lib/obex/obexd)
==3229== Address 0x4c95e9c is 4 bytes inside a block of size 8 free'd
==3229== at 0x4833E98: free (vg_replace_malloc.c:366)
==3229== by 0x4910D23: g_free (gmem.c:191)
==3229== by 0x492B8EF: g_slist_remove (gslist.c:441)
==3229== by 0x1D15B: ??? (in /usr/lib/obex/obexd)
---
src/mimetype.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/src/mimetype.c b/src/mimetype.c
index 4a30222..078d97c 100644
--- a/src/mimetype.c
+++ b/src/mimetype.c
@@ -50,9 +50,11 @@ void obex_object_set_io_flags(void *object, int flags, int err)
{
GSList *l;
- for (l = watches; l; l = l->next) {
+ for (l = watches; l;) {
struct io_watch *watch = l->data;
+ l = l->next;
+
if (watch->object != object)
continue;
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] Fix process pending request if transfer canceled
From: Johan Hedberg @ 2010-10-18 14:24 UTC (permalink / raw)
To: Daniel Örstadius; +Cc: linux-bluetooth
In-Reply-To: <AANLkTikmpwse=s3Z5+RzgrPCSy-qVhYkLxA1kRZrECnJ@mail.gmail.com>
Hi Daniel,
On Mon, Oct 18, 2010, Daniel Örstadius wrote:
> If the call to the Request method of the obex client agent returns
> with an error (for example if the transfer is rejected), call
> function session_terminate_transfer instead of unregister_transfer
> to both unregister the transfer and handle the pending request.
> ---
> client/session.c | 11 ++++++++++-
> 1 files changed, 10 insertions(+), 1 deletions(-)
Pushed upstream. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] bluetooth: fix unaligned access to l2cap conf data
From: Gustavo F. Padovan @ 2010-10-18 15:59 UTC (permalink / raw)
To: Marcel Holtmann
Cc: Mike Frysinger, linux-bluetooth, uclinux-dist-devel, linux-kernel,
Andrew Morton, steven miao
In-Reply-To: <1287402706.3316.126.camel@aeonflux>
Hi Mike,
* Marcel Holtmann <marcel@holtmann.org> [2010-10-18 13:51:46 +0200]:
> Hi Mike,
>
> > In function l2cap_get_conf_opt() and l2cap_add_conf_opt() the address of
> > opt->val sometimes is not at the edge of 2-bytes/4-bytes, so 2-bytes/4 bytes
> > access will cause data misalignment exeception. Use get_unaligned_le16/32
> > and put_unaligned_le16/32 function to avoid data misalignment execption.
> >
> > Signed-off-by: steven miao <realmz6@gmail.com>
> > Signed-off-by: Mike Frysinger <vapier@gentoo.org>
> > ---
> > was posted a month ago with no feedback ...
>
> must have slipped through. However I don't remember it being on
> linux-bluetooth at all. Maybe it was on the other mailing lists :(
Actually I remember it, but it got lost by some way. :(
>
> Acked-by: Marcel Holtmann <marcel@holtmann.org>
Applied, thanks.
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
* Re: [PATCH] bluetooth: fix unaligned access to l2cap conf data
From: Gustavo F. Padovan @ 2010-10-18 16:32 UTC (permalink / raw)
To: Harvey Harrison
Cc: Mike Frysinger, linux-bluetooth, Marcel Holtmann,
uclinux-dist-devel, linux-kernel, Andrew Morton, steven miao
In-Reply-To: <AANLkTinMSbhTkH0zQn_YO7hFF7zkuv-Gj-B0BUFWy5nP@mail.gmail.com>
Hi Harvey,
* Harvey Harrison <harvey.harrison@gmail.com> [2010-10-18 11:17:28 -0700]:
> On Sat, Oct 16, 2010 at 3:29 PM, Mike Frysinger <vapier@gentoo.org> wrote:
> > From: steven miao <realmz6@gmail.com>
> >
> >
> > =A0 =A0 =A0 =A0case 2:
> > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 *((__le16 *) opt->val) =3D cpu_to_le16(va=
l);
> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 put_unaligned_le16(cpu_to_le16(val), opt-=
>val);
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break;
> >
>=20
> I think you wanted:
> put_unaligned_le16(val, opt->val);
I fixed that in the tree. Thanks for the report.=20
--=20
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
* Setting Inquiry Transmit Power Level
From: Roel Huybrechts @ 2010-10-18 16:54 UTC (permalink / raw)
To: linux-bluetooth
[-- Attachment #1: Type: text/plain, Size: 1727 bytes --]
Dear list,
I'm facing the same problem that Natale Vinto mentioned nearly a
year ago [1] on this list. I'm trying to set the Inquiry Transmit
Power Level of a Belkin USB Bluetooth adapter, unfortunately
without much of success.
It is a Bluetooth 2.1 capable device as mentioned by hciconfig:
# hciconfig hci0 version
hci0: Type: BR/EDR Bus: USB
BD Address: 00:19:0E:08:62:EC ACL MTU: 1021:8 SCO MTU: 64:1
HCI Version: 2.1 (0x4) Revision: 0x5184
LMP Version: 2.1 (0x4) Subversion: 0x420e
Manufacturer: Broadcom Corporation (15)
# hciconfig hci0 revision
hci0: Type: BR/EDR Bus: USB
BD Address: 00:19:0E:08:62:EC ACL MTU: 1021:8 SCO MTU: 64:1
Firmware 132.66 / 14
Writing the inqtpl is supported, as shown by 'hciconfig hci0
commands'.
However:
# hciconfig hci0 inqtpl
hci0: Type: BR/EDR Bus: USB
BD Address: 00:19:0E:08:62:EC ACL MTU: 1021:8 SCO MTU: 64:1
Inquiry transmit power level: 0
# hciconfig hci0 inqtpl 4
# hciconfig hci0 inqtpl
hci0: Type: BR/EDR Bus: USB
BD Address: 00:19:0E:08:62:EC ACL MTU: 1021:8 SCO
MTU: 64:1
Inquiry transmit power level: 0
All this happens with Bluez 4.70 (the one from Debian unstable)
on a (pretty much plain upstream) 2.6.32.22 kernel.
I'd like to hear from you if this is a hardware or firmware issue
of the adapter/chip (in which case I suspect it can't be fixed
and I need to find another adapter which isn't broken), or
whether it can be a Bluez issue.
[1] http://www.spinics.net/lists/linux-bluetooth/msg03785.html
Thanks very much for your time.
Have a nice day,
Roel Huybrechts
--
GPG | 4096R/5E2DE374
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* RE: [PATCH] Bluetooth: btwilink driver
From: Savoy, Pavan @ 2010-10-18 17:32 UTC (permalink / raw)
To: Savoy, Pavan, padovan@profusion.mobi, marcel@holtmann.org
Cc: linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <1287176299-19313-1-git-send-email-pavan_savoy@ti.com>
> -----Original Message-----
> From: Savoy, Pavan
> Sent: Friday, October 15, 2010 3:58 PM
> To: padovan@profusion.mobi; marcel@holtmann.org
> Cc: linux-bluetooth@vger.kernel.org; linux-kernel@vger.kernel.org; Savoy,
> Pavan
> Subject: [PATCH] Bluetooth: btwilink driver
>
> From: Pavan Savoy <pavan_savoy@ti.com>
>
> Gustavo, Marcel,
Hope you had a nice weekend :)
Any comments on this patch?
As you might notice, I no longer register to HCI from module_init and have =
it
as a platform device driver and register to HCI inside the probe.
> Renaming the patch, since the driver is renamed to btwilink.
> Thanks for the comments,
> Please review and provide your comments on this version of patch,
>
> -- patch description --
>
> This is the bluetooth protocol driver for the TI WiLink7 chipsets.
> Texas Instrument's WiLink chipsets combine wireless technologies
> like BT, FM, GPS and WLAN onto a single chip.
>
> This Bluetooth driver works on top of the TI_ST shared transport
> line discipline driver which also allows other drivers like
> FM V4L2 and GPS character driver to make use of the same UART interface.
>
> Kconfig and Makefile modifications to enable the Bluetooth
> driver for Texas Instrument's WiLink 7 chipset.
>
> Signed-off-by: Pavan Savoy <pavan_savoy@ti.com>
> ---
> drivers/bluetooth/Kconfig | 10 +
> drivers/bluetooth/Makefile | 1 +
> drivers/bluetooth/btwilink.c | 424
> ++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 435 insertions(+), 0 deletions(-)
> create mode 100644 drivers/bluetooth/btwilink.c
>
> diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
> index 02deef4..e0d67dd 100644
> --- a/drivers/bluetooth/Kconfig
> +++ b/drivers/bluetooth/Kconfig
> @@ -219,4 +219,14 @@ config BT_ATH3K
> Say Y here to compile support for "Atheros firmware download driv=
er"
> into the kernel or say M to compile it as module (ath3k).
>
> +config BT_WILINK
> + tristate "BlueZ bluetooth driver for TI ST"
> + depends on TI_ST
> + help
> + This enables the Bluetooth driver for Texas Instrument's BT/FM/GP=
S
> + combo devices. This makes use of shared transport line discipline
> + core driver to communicate with the BT core of the combo chip.
> +
> + Say Y here to compile support for Texas Instrument's WiLink7 driv=
er
> + into the kernel or say M to compile it as module.
> endmenu
> diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
> index 71bdf13..f4460f4 100644
> --- a/drivers/bluetooth/Makefile
> +++ b/drivers/bluetooth/Makefile
> @@ -18,6 +18,7 @@ obj-$(CONFIG_BT_HCIBTSDIO) +=3D btsdio.o
> obj-$(CONFIG_BT_ATH3K) +=3D ath3k.o
> obj-$(CONFIG_BT_MRVL) +=3D btmrvl.o
> obj-$(CONFIG_BT_MRVL_SDIO) +=3D btmrvl_sdio.o
> +obj-$(CONFIG_BT_WILINK) +=3D btwilink.o
>
> btmrvl-y :=3D btmrvl_main.o
> btmrvl-$(CONFIG_DEBUG_FS) +=3D btmrvl_debugfs.o
> diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c
> new file mode 100644
> index 0000000..f67791f
> --- /dev/null
> +++ b/drivers/bluetooth/btwilink.c
> @@ -0,0 +1,424 @@
> +/*
> + * Texas Instrument's Bluetooth Driver For Shared Transport.
> + *
> + * Bluetooth Driver acts as interface between HCI CORE and
> + * TI Shared Transport Layer.
> + *
> + * Copyright (C) 2009-2010 Texas Instruments
> + * Author: Raja Mani <raja_mani@ti.com>
> + * Pavan Savoy <pavan_savoy@ti.com>
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307=
USA
> + *
> + */
> +
> +#include <linux/platform_device.h>
> +#include <net/bluetooth/bluetooth.h>
> +#include <net/bluetooth/hci_core.h>
> +
> +#include <linux/ti_wilink_st.h>
> +
> +/* Bluetooth Driver Version */
> +#define VERSION "1.0"
> +
> +/* Defines number of seconds to wait for reg completion
> + * callback getting called from ST (in case,registration
> + * with ST returns PENDING status)
> + */
> +#define BT_REGISTER_TIMEOUT 6000 /* 6 sec */
> +
> +/**
> + * struct ti_st - BT driver operation structure
> + * @hdev: hci device pointer which binds to bt driver
> + * @flags: used locally,to maintain various BT driver status
> + * @streg_cbdata: to hold ST registration callback status
> + * @st_write: write function pointer of ST driver
> + * @wait_reg_completion - completion sync between ti_st_open
> + * and ti_st_registration_completion_cb.
> + */
> +struct ti_st {
> + struct hci_dev *hdev;
> + char streg_cbdata;
> + long (*st_write) (struct sk_buff *);
> + struct completion wait_reg_completion;
> +};
> +
> +static int reset;
> +
> +/* Increments HCI counters based on pocket ID (cmd,acl,sco) */
> +static inline void ti_st_tx_complete(struct ti_st *hst, int pkt_type)
> +{
> + struct hci_dev *hdev;
> + hdev =3D hst->hdev;
> +
> + /* Update HCI stat counters */
> + switch (pkt_type) {
> + case HCI_COMMAND_PKT:
> + hdev->stat.cmd_tx++;
> + break;
> +
> + case HCI_ACLDATA_PKT:
> + hdev->stat.acl_tx++;
> + break;
> +
> + case HCI_SCODATA_PKT:
> + hdev->stat.sco_tx++;
> + break;
> + }
> +}
> +
> +/* ------- Interfaces to Shared Transport ------ */
> +
> +/* Called by ST layer to indicate protocol registration completion
> + * status.ti_st_open() function will wait for signal from this
> + * API when st_register() function returns ST_PENDING.
> + */
> +static void st_registration_completion_cb(void *priv_data, char data)
> +{
> + struct ti_st *lhst =3D (struct ti_st *)priv_data;
> + /* ti_st_open() function needs value of 'data' to know
> + * the registration status(success/fail),So have a back
> + * up of it.
> + */
> + lhst->streg_cbdata =3D data;
> +
> + /* Got a feedback from ST for BT driver registration
> + * request.Wackup ti_st_open() function to continue
> + * it's open operation.
> + */
> + complete(&lhst->wait_reg_completion);
> +}
> +
> +/* Called by Shared Transport layer when receive data is
> + * available */
> +static long st_receive(void *priv_data, struct sk_buff *skb)
> +{
> + int err;
> + struct ti_st *lhst =3D (struct ti_st *)priv_data;
> +
> + if (!skb)
> + return -EFAULT;
> +
> + if (!lhst) {
> + kfree_skb(skb);
> + return -EFAULT;
> + }
> +
> + skb->dev =3D (struct net_device *)lhst->hdev;
> +
> + /* Forward skb to HCI CORE layer */
> + err =3D hci_recv_frame(skb);
> + if (err) {
> + kfree_skb(skb);
> + BT_ERR("Unable to push skb to HCI CORE(%d)", err);
> + return err;
> + }
> +
> + lhst->hdev->stat.byte_rx +=3D skb->len;
> + return 0;
> +}
> +
> +/* ------- Interfaces to HCI layer ------ */
> +/* protocol structure registered with shared transport */
> +static struct st_proto_s ti_st_proto =3D {
> + .type =3D ST_BT,
> + .recv =3D st_receive,
> + .reg_complete_cb =3D st_registration_completion_cb,
> + .priv_data =3D NULL,
> +};
> +
> +/* Called from HCI core to initialize the device */
> +static int ti_st_open(struct hci_dev *hdev)
> +{
> + unsigned long timeleft;
> + struct ti_st *hst;
> + int err;
> +
> + BT_DBG("%s %p", hdev->name, hdev);
> +
> + /* provide contexts for callbacks from ST */
> + hst =3D hdev->driver_data;
> + ti_st_proto.priv_data =3D hst;
> +
> + err =3D st_register(&ti_st_proto);
> + if (err =3D=3D -EINPROGRESS) {
> + /* Prepare wait-for-completion handler data structures.
> + * Needed to syncronize this and st_registration_completion=
_cb()
> + * functions.
> + */
> + init_completion(&hst->wait_reg_completion);
> +
> + /* Reset ST registration callback status flag , this value
> + * will be updated in ti_st_registration_completion_cb()
> + * function whenever it called from ST driver.
> + */
> + hst->streg_cbdata =3D -EINPROGRESS;
> +
> + /* ST is busy with other protocol registration(may be busy =
with
> + * firmware download).So,Wait till the registration callbac=
k
> + * (passed as a argument to st_register() function) getting
> + * called from ST.
> + */
> + BT_DBG(" waiting for reg completion signal from ST");
> +
> + timeleft =3D wait_for_completion_timeout
> + (&hst->wait_reg_completion,
> + msecs_to_jiffies(BT_REGISTER_TIMEOUT));
> + if (!timeleft) {
> + BT_ERR("Timeout(%d sec),didn't get reg"
> + "completion signal from ST",
> + BT_REGISTER_TIMEOUT / 1000);
> + return -ETIMEDOUT;
> + }
> +
> + /* Is ST registration callback called with ERROR value? */
> + if (hst->streg_cbdata !=3D 0) {
> + BT_ERR("ST reg completion CB called with invalid"
> + "status %d", hst->streg_cbdata);
> + return -EAGAIN;
> + }
> + err =3D 0;
> + } else if (err =3D=3D -EPERM) {
> + BT_ERR("st_register failed %d", err);
> + return -EAGAIN;
> + }
> +
> + /* Do we have proper ST write function? */
> + if (ti_st_proto.write !=3D NULL) {
> + /* We need this pointer for sending any Bluetooth pkts */
> + hst->st_write =3D ti_st_proto.write;
> + } else {
> + BT_ERR("failed to get ST write func pointer");
> +
> + /* Undo registration with ST */
> + err =3D st_unregister(ST_BT);
> + if (err)
> + BT_ERR("st_unregister failed %d", err);
> +
> + hst->st_write =3D NULL;
> + return -EAGAIN;
> + }
> +
> + /* Registration with ST layer is completed successfully,
> + * now chip is ready to accept commands from HCI CORE.
> + * Mark HCI Device flag as RUNNING
> + */
> + set_bit(HCI_RUNNING, &hdev->flags);
> + return err;
> +}
> +
> +/* Close device */
> +static int ti_st_close(struct hci_dev *hdev)
> +{
> + int err =3D 0;
> + struct ti_st *hst;
> +
> + hst =3D hdev->driver_data;
> +
> + /* Clear HCI device RUNNING flag */
> + if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
> + BT_ERR("HCI not RUNNING?");
> +
> + /* continue to unregister from transport */
> + err =3D st_unregister(ST_BT);
> + if (err)
> + BT_ERR("st_unregister failed %d", err);
> +
> + hst->st_write =3D NULL;
> + return err;
> +}
> +
> +/* Called from HCI CORE , Sends frames to Shared Transport */
> +static int ti_st_send_frame(struct sk_buff *skb)
> +{
> + struct hci_dev *hdev;
> + struct ti_st *hst;
> + long len;
> +
> + if (!skb)
> + return -ENOMEM;
> +
> + hdev =3D (struct hci_dev *)skb->dev;
> + if (!hdev)
> + return -ENODEV;
> +
> + if (!test_bit(HCI_RUNNING, &hdev->flags))
> + return -EBUSY;
> +
> + hst =3D (struct ti_st *)hdev->driver_data;
> +
> + /* Prepend skb with frame type */
> + memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
> +
> + BT_DBG(" %s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type,
> + skb->len);
> +
> + /* Insert skb to shared transport layer's transmit queue.
> + * Freeing skb memory is taken care in shared transport layer,
> + * so don't free skb memory here.
> + */
> + if (!hst->st_write) {
> + kfree_skb(skb);
> + BT_ERR(" Can't write to ST, st_write null?");
> + return -EAGAIN;
> + }
> +
> + len =3D hst->st_write(skb);
> + if (len < 0) {
> + kfree_skb(skb);
> + BT_ERR(" ST write failed (%ld)", len);
> + return -EAGAIN;
> + }
> +
> + /* ST accepted our skb. So, Go ahead and do rest */
> + hdev->stat.byte_tx +=3D len;
> + ti_st_tx_complete(hst, bt_cb(skb)->pkt_type);
> +
> + return 0;
> +}
> +
> +static void ti_st_destruct(struct hci_dev *hdev)
> +{
> + if (!hdev)
> + BT_ERR("Destruct called with invalid HCI Device"
> + "(hdev=3DNULL)");
> +
> + BT_DBG("%s", hdev->name);
> +
> + /* free ti_st memory */
> + kfree(hdev->driver_data);
> + return;
> +}
> +
> +/* Creates new HCI device */
> +static int ti_st_register_dev(struct ti_st *hst)
> +{
> + struct hci_dev *hdev;
> +
> + /* Initialize and register HCI device */
> + hdev =3D hci_alloc_dev();
> + if (!hdev)
> + return -ENOMEM;
> +
> + BT_DBG(" HCI device allocated. hdev=3D %p", hdev);
> +
> + hst->hdev =3D hdev;
> + hdev->bus =3D HCI_UART;
> + hdev->driver_data =3D hst;
> + hdev->open =3D ti_st_open;
> + hdev->close =3D ti_st_close;
> + hdev->flush =3D NULL;
> + hdev->send =3D ti_st_send_frame;
> + hdev->destruct =3D ti_st_destruct;
> + hdev->owner =3D THIS_MODULE;
> +
> + if (reset)
> + set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
> +
> + if (hci_register_dev(hdev) < 0) {
> + BT_ERR("Can't register HCI device");
> + hci_free_dev(hdev);
> + return -ENODEV;
> + }
> +
> + BT_DBG(" HCI device registered. hdev=3D %p", hdev);
> + return 0;
> +}
> +
> +
> +static int bt_ti_probe(struct platform_device *pdev)
> +{
> + int err;
> + static struct ti_st *hst;
> + err =3D 0;
> +
> + BT_DBG(" Bluetooth Driver Version %s", VERSION);
> +
> + hst =3D kzalloc(sizeof(struct ti_st), GFP_KERNEL);
> + if (!hst) {
> + BT_ERR("Can't allocate control structure");
> + return -ENOMEM;
> + }
> +
> + /* Expose "hciX" device to user space */
> + err =3D ti_st_register_dev(hst);
> + if (err) {
> + kfree(hst);
> + BT_ERR("Unable to expose hciX device(%d)", err);
> + return err;
> + }
> +
> + dev_set_drvdata(&pdev->dev, hst);
> + return err;
> +}
> +
> +static int bt_ti_remove(struct platform_device *pdev)
> +{
> + struct ti_st *hst;
> +
> + hst =3D dev_get_drvdata(&pdev->dev);
> + /* Deallocate local resource's memory */
> + if (hst) {
> + struct hci_dev *hdev =3D hst->hdev;
> + if (!hdev) {
> + BT_ERR("Invalid hdev memory");
> + kfree(hst);
> + } else {
> + ti_st_close(hdev);
> + hci_unregister_dev(hdev);
> + /* Free HCI device memory */
> + hci_free_dev(hdev);
> + }
> + }
> + return 0;
> +}
> +
> +static struct platform_driver btwilink_driver =3D {
> + .probe =3D bt_ti_probe,
> + .remove =3D bt_ti_remove,
> + .driver =3D {
> + .name =3D "btwilink",
> + .owner =3D THIS_MODULE,
> + },
> +};
> +
> +/* ------- Module Init/Exit interfaces ------ */
> +static int __init bt_drv_init(void)
> +{
> + long ret;
> +
> + ret =3D platform_driver_register(&btwilink_driver);
> + if (ret !=3D 0) {
> + BT_ERR("btwilink platform drv registration failed");
> + return -EPERM;
> + }
> + return 0;
> +}
> +
> +static void __exit bt_drv_exit(void)
> +{
> + platform_driver_unregister(&btwilink_driver);
> +}
> +
> +module_init(bt_drv_init);
> +module_exit(bt_drv_exit);
> +
> +/* ------ Module Info ------ */
> +
> +module_param(reset, bool, 0644);
> +MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
> +MODULE_AUTHOR("Raja Mani <raja_mani@ti.com>");
> +MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION);
> +MODULE_VERSION(VERSION);
> +MODULE_LICENSE("GPL");
> --
> 1.6.5
^ permalink raw reply
* Re: [PATCH] bluetooth: fix unaligned access to l2cap conf data
From: Harvey Harrison @ 2010-10-18 18:17 UTC (permalink / raw)
To: Mike Frysinger
Cc: linux-bluetooth, Marcel Holtmann, uclinux-dist-devel,
linux-kernel, Andrew Morton, steven miao
In-Reply-To: <1287268187-9628-1-git-send-email-vapier@gentoo.org>
On Sat, Oct 16, 2010 at 3:29 PM, Mike Frysinger <vapier@gentoo.org> wrote:
> From: steven miao <realmz6@gmail.com>
>
>
> =C2=A0 =C2=A0 =C2=A0 =C2=A0case 2:
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *((__le16 *) opt->val)=
=3D cpu_to_le16(val);
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 put_unaligned_le16(cpu=
_to_le16(val), opt->val);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;
>
I think you wanted:
put_unaligned_le16(val, opt->val);
Cheers,
Harvey
^ permalink raw reply
* Re: >net-wireless/bluez-4.63 unable to connect audio streams due commit
From: Pacho Ramos @ 2010-10-18 18:24 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Luiz Augusto von Dentz, Johan Hedberg, linux-bluetooth
In-Reply-To: <20101004123552.GC11737@pengutronix.de>
[-- Attachment #1.1: Type: text/plain, Size: 899 bytes --]
El lun, 04-10-2010 a las 14:35 +0200, Uwe Kleine-König escribió:
> Hello Pacho,
>
> On Mon, Oct 04, 2010 at 12:25:46PM +0200, Pacho Ramos wrote:
> > > I would say this was because of double authentication request, but it
> > > seems it is not the case, actually ssp doesn't seems to be used at all
> > > here so this must be something else, maybe you should try this:
> > >
> > > http://thread.gmane.org/gmane.linux.bluez.kernel/7256
> > >
> >
> > Thanks but, how should I try to apply that patch? Looks like
> > net/bluetooth/rfcomm/core.c is not present on bluez-4.72 sources
> I guess this is a patch to apply to your kernel, not bluez.
>
> Best regards
> Uwe
>
Downstream affected reported told me it's still failing even with the
patch:
http://bugs.gentoo.org/show_bug.cgi?id=327705#c19
Attached is the new hcidump output
Thanks a lot for your help :-)
[-- Attachment #1.2: hcidump.out --]
[-- Type: text/plain, Size: 5614 bytes --]
HCI sniffer - Bluetooth packet analyzer ver 1.42
device: hci0 snap_len: 1028 filter: 0xffffffffffffffff
< HCI Command: Create Connection (0x01|0x0005) plen 13
> HCI Event: Command Status (0x0f) plen 4
> HCI Event: Link Key Request (0x17) plen 6
< HCI Command: Link Key Request Reply (0x01|0x000b) plen 22
> HCI Event: Command Complete (0x0e) plen 10
> HCI Event: Connect Complete (0x03) plen 11
< HCI Command: Read Remote Supported Features (0x01|0x001b) plen 2
> HCI Event: Command Status (0x0f) plen 4
< HCI Command: Remote Name Request (0x01|0x0019) plen 10
> HCI Event: Max Slots Change (0x1b) plen 3
> HCI Event: Read Remote Supported Features (0x0b) plen 11
< ACL data: handle 12 flags 0x02 dlen 10
L2CAP(s): Info req: type 2
> HCI Event: Command Status (0x0f) plen 4
> ACL data: handle 12 flags 0x02 dlen 16
L2CAP(s): Info rsp: type 2 result 0
Extended feature mask 0x0000
< ACL data: handle 12 flags 0x02 dlen 12
L2CAP(s): Connect req: psm 1 scid 0x0040
> ACL data: handle 12 flags 0x02 dlen 16
L2CAP(s): Connect rsp: dcid 0x005a scid 0x0040 result 1 status 2
Connection pending - Authorization pending
> ACL data: handle 12 flags 0x02 dlen 16
L2CAP(s): Connect rsp: dcid 0x005a scid 0x0040 result 0 status 0
Connection successful
< ACL data: handle 12 flags 0x02 dlen 12
L2CAP(s): Config req: dcid 0x005a flags 0x00 clen 0
> HCI Event: Remote Name Req Complete (0x07) plen 255
> ACL data: handle 12 flags 0x02 dlen 14
L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 0 clen 0
Success
> ACL data: handle 12 flags 0x02 dlen 16
L2CAP(s): Config req: dcid 0x0040 flags 0x00 clen 4
MTU 48
< ACL data: handle 12 flags 0x02 dlen 18
L2CAP(s): Config rsp: scid 0x005a flags 0x00 result 0 clen 4
MTU 48
< ACL data: handle 12 flags 0x02 dlen 24
L2CAP(d): cid 0x005a len 20 [psm 1]
SDP SSA Req: tid 0x0 len 0xf
pat uuid-16 0x111e (Handsfree)
max 65535
aid(s) 0x0000 - 0xffff
cont 00
> HCI Event: Number of Completed Packets (0x13) plen 5
> ACL data: handle 12 flags 0x02 dlen 52
L2CAP(d): cid 0x0040 len 48 [psm 1]
SDP SSA Rsp: tid 0x0 len 0x2b
count 38
cont 02 00 39
< ACL data: handle 12 flags 0x02 dlen 26
L2CAP(d): cid 0x005a len 22 [psm 1]
SDP SSA Req: tid 0x1 len 0x11
pat uuid-16 0x111e (Handsfree)
max 65535
aid(s) 0x0000 - 0xffff
cont 02 00 39
> ACL data: handle 12 flags 0x02 dlen 52
L2CAP(d): cid 0x0040 len 48 [psm 1]
SDP SSA Rsp: tid 0x1 len 0x2b
count 38
cont 02 00 13
< ACL data: handle 12 flags 0x02 dlen 26
L2CAP(d): cid 0x005a len 22 [psm 1]
SDP SSA Req: tid 0x2 len 0x11
pat uuid-16 0x111e (Handsfree)
max 65535
aid(s) 0x0000 - 0xffff
cont 02 00 13
> ACL data: handle 12 flags 0x02 dlen 31
L2CAP(d): cid 0x0040 len 27 [psm 1]
SDP SSA Rsp: tid 0x2 len 0x16
count 19
record #0
aid 0x0000 (SrvRecHndl)
uint 0x10004
aid 0x0001 (SrvClassIDList)
< uuid-16 0x111e (Handsfree) uuid-16 0x1203 (Audio) >
aid 0x0004 (ProtocolDescList)
< < uuid-16 0x0100 (L2CAP) > <
uuid-16 0x0003 (RFCOMM) uint 0x1 > >
aid 0x0006 (LangBaseAttrIDList)
< uint 0x656e uint 0x6a uint 0x100 >
aid 0x0009 (BTProfileDescList)
< < uuid-16 0x111e (Handsfree) uint 0x101 > >
aid 0x0100 (SrvName)
str "Hands-Free unit"
aid 0x0311 (SuppFeatures)
uint 0x18
cont 00
< HCI Command: Authentication Requested (0x01|0x0011) plen 2
> HCI Event: Command Status (0x0f) plen 4
> HCI Event: Auth Complete (0x06) plen 3
< HCI Command: Set Connection Encryption (0x01|0x0013) plen 3
> HCI Event: Command Status (0x0f) plen 4
> HCI Event: Number of Completed Packets (0x13) plen 5
< ACL data: handle 12 flags 0x02 dlen 12
L2CAP(s): Disconn req: dcid 0x005a scid 0x0040
> HCI Event: Number of Completed Packets (0x13) plen 5
> HCI Event: Disconn Complete (0x05) plen 4
< HCI Command: Create Connection (0x01|0x0005) plen 13
> HCI Event: Command Status (0x0f) plen 4
> HCI Event: Link Key Request (0x17) plen 6
< HCI Command: Link Key Request Reply (0x01|0x000b) plen 22
> HCI Event: Command Complete (0x0e) plen 10
> HCI Event: Connect Complete (0x03) plen 11
< HCI Command: Read Remote Supported Features (0x01|0x001b) plen 2
> HCI Event: Max Slots Change (0x1b) plen 3
> HCI Event: Command Status (0x0f) plen 4
< HCI Command: Remote Name Request (0x01|0x0019) plen 10
> HCI Event: Read Remote Supported Features (0x0b) plen 11
< ACL data: handle 11 flags 0x02 dlen 10
L2CAP(s): Info req: type 2
> HCI Event: Command Status (0x0f) plen 4
> ACL data: handle 11 flags 0x02 dlen 16
L2CAP(s): Info rsp: type 2 result 0
Extended feature mask 0x0000
< HCI Command: Authentication Requested (0x01|0x0011) plen 2
> HCI Event: Remote Name Req Complete (0x07) plen 255
> HCI Event: Command Status (0x0f) plen 4
> HCI Event: Auth Complete (0x06) plen 3
< HCI Command: Set Connection Encryption (0x01|0x0013) plen 3
> HCI Event: Command Status (0x0f) plen 4
> HCI Event: Number of Completed Packets (0x13) plen 5
> HCI Event: Disconn Complete (0x05) plen 4
< HCI Command: Reset (0x03|0x0003) plen 0
> HCI Event: Command Complete (0x0e) plen 4
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: pull request: bluetooth-2.6 2010-10-18
From: Gustavo F. Padovan @ 2010-10-18 19:02 UTC (permalink / raw)
To: John W. Linville; +Cc: marcel, linux-wireless, linux-bluetooth, davem
In-Reply-To: <20101018200830.GA2443@tuxdriver.com>
* John W. Linville <linville@tuxdriver.com> [2010-10-18 16:08:31 -0400]:
> On Mon, Oct 18, 2010 at 03:55:40AM -0200, Gustavo F. Padovan wrote:
> > Hi John,
> >
> > Not sure if we still have time for a last minute fix, but here goes a
> > fix for a NULL dereference in L2CAP layer for 2.6.36-rc8. Please also let
> > me know if this is the right way to handle such last minute fix. Maybe you
> > should want this directly through Dave.
> >
> > Thanks.
>
> The fix seems fine to me. Given the short schedule, it might be best
> to skip the middleman and have Dave pull directly from you?
>
> Dave, be forewarned that Gustavo has based his tree off 2.6.36-rc8 --
> dunno if you are ready to pull that into net-2.6 or not.
If you guys think that rebase against Linus' tree could be a problem, I
can start to base bluetooth-2.6 against net-2.6 for the next pull
requests.
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ 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