Skip to content

Commit

Permalink
[Bluetooth] Support concurrent connect requests
Browse files Browse the repository at this point in the history
Most Bluetooth chips don't support concurrent connect requests, because
this would involve a multiple baseband page with only one radio. In the
case an upper layer like L2CAP requests a concurrent connect these chips
return the error "Command Disallowed" for the second request. If this
happens it the responsibility of the Bluetooth core to queue the request
and try again after the previous connect attempt has been completed.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
  • Loading branch information
Marcel Holtmann authored and David S. Miller committed Oct 16, 2006
1 parent e9c4bec commit 4c67bc7
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 7 deletions.
17 changes: 17 additions & 0 deletions include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ struct hci_conn {
__u8 mode;
__u8 type;
__u8 out;
__u8 attempt;
__u8 dev_class[3];
__u8 features[8];
__u16 interval;
Expand Down Expand Up @@ -289,6 +290,22 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
return NULL;
}

static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
__u8 type, __u16 state)
{
struct hci_conn_hash *h = &hdev->conn_hash;
struct list_head *p;
struct hci_conn *c;

list_for_each(p, &h->list) {
c = list_entry(p, struct hci_conn, list);
if (c->type == type && c->state == state)
return c;
}
return NULL;
}

void hci_acl_connect(struct hci_conn *conn);
void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
void hci_add_sco(struct hci_conn *conn, __u16 handle);

Expand Down
2 changes: 1 addition & 1 deletion net/bluetooth/af_bluetooth.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
#define BT_DBG(D...)
#endif

#define VERSION "2.10"
#define VERSION "2.11"

/* Bluetooth sockets */
#define BT_MAX_PROTO 8
Expand Down
6 changes: 4 additions & 2 deletions net/bluetooth/hci_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
#define BT_DBG(D...)
#endif

static void hci_acl_connect(struct hci_conn *conn)
void hci_acl_connect(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
struct inquiry_entry *ie;
Expand All @@ -63,6 +63,8 @@ static void hci_acl_connect(struct hci_conn *conn)
conn->out = 1;
conn->link_mode = HCI_LM_MASTER;

conn->attempt++;

memset(&cp, 0, sizeof(cp));
bacpy(&cp.bdaddr, &conn->dst);
cp.pscan_rep_mode = 0x02;
Expand All @@ -80,7 +82,7 @@ static void hci_acl_connect(struct hci_conn *conn)
cp.role_switch = 0x01;
else
cp.role_switch = 0x00;

hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp);
}

Expand Down
15 changes: 11 additions & 4 deletions net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,9 +414,12 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)

if (status) {
if (conn && conn->state == BT_CONNECT) {
conn->state = BT_CLOSED;
hci_proto_connect_cfm(conn, status);
hci_conn_del(conn);
if (status != 0x0c || conn->attempt > 2) {
conn->state = BT_CLOSED;
hci_proto_connect_cfm(conn, status);
hci_conn_del(conn);
} else
conn->state = BT_CONNECT2;
}
} else {
if (!conn) {
Expand Down Expand Up @@ -728,7 +731,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data;
struct hci_conn *conn;
struct hci_conn *conn, *pend;

BT_DBG("%s", hdev->name);

Expand Down Expand Up @@ -801,6 +804,10 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
if (ev->status)
hci_conn_del(conn);

pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
if (pend)
hci_acl_connect(pend);

hci_dev_unlock(hdev);
}

Expand Down

0 comments on commit 4c67bc7

Please sign in to comment.