else
dyn_end = L2CAP_CID_DYN_END;
- for (cid = L2CAP_CID_DYN_START; cid < dyn_end; cid++) {
+ for (cid = L2CAP_CID_DYN_START; cid <= dyn_end; cid++) {
if (!__l2cap_get_chan_by_scid(conn, cid))
return cid;
}
hci_dev_lock(hdev);
- if (user->list.next || user->list.prev) {
+ if (!list_empty(&user->list)) {
ret = -EINVAL;
goto out_unlock;
}
hci_dev_lock(hdev);
- if (!user->list.next || !user->list.prev)
+ if (list_empty(&user->list))
goto out_unlock;
- list_del(&user->list);
- user->list.next = NULL;
- user->list.prev = NULL;
+ list_del_init(&user->list);
user->remove(conn, user);
out_unlock:
while (!list_empty(&conn->users)) {
user = list_first_entry(&conn->users, struct l2cap_user, list);
- list_del(&user->list);
- user->list.next = NULL;
- user->list.prev = NULL;
+ list_del_init(&user->list);
user->remove(conn, user);
}
}
credits = __le16_to_cpu(rsp->credits);
result = __le16_to_cpu(rsp->result);
- if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23))
+ if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23 ||
+ dcid < L2CAP_CID_DYN_START ||
+ dcid > L2CAP_CID_LE_DYN_END))
return -EPROTO;
BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x",
switch (result) {
case L2CAP_CR_SUCCESS:
+ if (__l2cap_get_chan_by_dcid(conn, dcid)) {
+ err = -EBADSLT;
+ break;
+ }
+
chan->ident = 0;
chan->dcid = dcid;
chan->omtu = mtu;
goto response_unlock;
}
+ /* Check for valid dynamic CID range */
+ if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) {
+ result = L2CAP_CR_INVALID_SCID;
+ chan = NULL;
+ goto response_unlock;
+ }
+
/* Check if we already have channel with that dcid */
if (__l2cap_get_chan_by_dcid(conn, scid)) {
- result = L2CAP_CR_NO_MEM;
+ result = L2CAP_CR_SCID_IN_USE;
chan = NULL;
goto response_unlock;
}
else
role = HCI_ROLE_MASTER;
- hcon = hci_connect_le(hdev, dst, dst_type, chan->sec_level,
- HCI_LE_CONN_TIMEOUT, role);
+ hcon = hci_connect_le_scan(hdev, dst, dst_type,
+ chan->sec_level,
+ HCI_LE_CONN_TIMEOUT,
+ role);
} else {
u8 auth_type = l2cap_get_auth_type(chan);
hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type);
mutex_unlock(&conn->chan_lock);
}
-int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
+void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
{
struct l2cap_conn *conn = hcon->l2cap_data;
struct l2cap_hdr *hdr;
if (len == skb->len) {
/* Complete frame received */
l2cap_recv_frame(conn, skb);
- return 0;
+ return;
}
BT_DBG("Start: total len %d, frag len %d", len, skb->len);
drop:
kfree_skb(skb);
- return 0;
}
static struct hci_cb l2cap_cb = {