Commit 5ce66b59 authored by Andrei Emeltchenko's avatar Andrei Emeltchenko Committed by Gustavo Padovan

Bluetooth: AMP: Add Logical Link Create function

After physical link is created logical link needs to be created.
The process starts after L2CAP channel is created and L2CAP
Configuration Response with result PENDING is received.
Signed-off-by: default avatarAndrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
parent 770bfefa
...@@ -46,5 +46,6 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, ...@@ -46,5 +46,6 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
struct hci_conn *hcon); struct hci_conn *hcon);
void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle); void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle);
void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle); void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle);
void amp_create_logical_link(struct l2cap_chan *chan);
#endif /* __AMP_H */ #endif /* __AMP_H */
...@@ -372,3 +372,52 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, ...@@ -372,3 +372,52 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
hci_send_cmd(hdev, HCI_OP_ACCEPT_PHY_LINK, sizeof(cp), &cp); hci_send_cmd(hdev, HCI_OP_ACCEPT_PHY_LINK, sizeof(cp), &cp);
} }
void amp_create_logical_link(struct l2cap_chan *chan)
{
struct hci_cp_create_accept_logical_link cp;
struct hci_conn *hcon;
struct hci_dev *hdev;
BT_DBG("chan %p", chan);
if (!chan->hs_hcon)
return;
hdev = hci_dev_hold(chan->hs_hcon->hdev);
if (!hdev)
return;
BT_DBG("chan %p ctrl_id %d dst %pMR", chan, chan->ctrl_id,
chan->conn->dst);
hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, chan->conn->dst);
if (!hcon)
goto done;
cp.phy_handle = hcon->handle;
cp.tx_flow_spec.id = chan->local_id;
cp.tx_flow_spec.stype = chan->local_stype;
cp.tx_flow_spec.msdu = cpu_to_le16(chan->local_msdu);
cp.tx_flow_spec.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
cp.tx_flow_spec.acc_lat = cpu_to_le32(chan->local_acc_lat);
cp.tx_flow_spec.flush_to = cpu_to_le32(chan->local_flush_to);
cp.rx_flow_spec.id = chan->remote_id;
cp.rx_flow_spec.stype = chan->remote_stype;
cp.rx_flow_spec.msdu = cpu_to_le16(chan->remote_msdu);
cp.rx_flow_spec.sdu_itime = cpu_to_le32(chan->remote_sdu_itime);
cp.rx_flow_spec.acc_lat = cpu_to_le32(chan->remote_acc_lat);
cp.rx_flow_spec.flush_to = cpu_to_le32(chan->remote_flush_to);
if (hcon->out)
hci_send_cmd(hdev, HCI_OP_CREATE_LOGICAL_LINK, sizeof(cp),
&cp);
else
hci_send_cmd(hdev, HCI_OP_ACCEPT_LOGICAL_LINK, sizeof(cp),
&cp);
done:
hci_dev_put(hdev);
}
...@@ -1835,6 +1835,11 @@ static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status) ...@@ -1835,6 +1835,11 @@ static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
amp_write_remote_assoc(hdev, cp->phy_handle); amp_write_remote_assoc(hdev, cp->phy_handle);
} }
static void hci_cs_create_logical_link(struct hci_dev *hdev, u8 status)
{
BT_DBG("%s status 0x%2.2x", hdev->name, status);
}
static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{ {
__u8 status = *((__u8 *) skb->data); __u8 status = *((__u8 *) skb->data);
...@@ -2669,6 +2674,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2669,6 +2674,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cs_accept_phylink(hdev, ev->status); hci_cs_accept_phylink(hdev, ev->status);
break; break;
case HCI_OP_CREATE_LOGICAL_LINK:
hci_cs_create_logical_link(hdev, ev->status);
break;
default: default:
BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
break; break;
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <net/bluetooth/l2cap.h> #include <net/bluetooth/l2cap.h>
#include <net/bluetooth/smp.h> #include <net/bluetooth/smp.h>
#include <net/bluetooth/a2mp.h> #include <net/bluetooth/a2mp.h>
#include <net/bluetooth/amp.h>
bool disable_ertm; bool disable_ertm;
...@@ -1013,6 +1014,12 @@ static bool __amp_capable(struct l2cap_chan *chan) ...@@ -1013,6 +1014,12 @@ static bool __amp_capable(struct l2cap_chan *chan)
return false; return false;
} }
static bool l2cap_check_efs(struct l2cap_chan *chan)
{
/* Check EFS parameters */
return true;
}
void l2cap_send_conn_req(struct l2cap_chan *chan) void l2cap_send_conn_req(struct l2cap_chan *chan)
{ {
struct l2cap_conn *conn = chan->conn; struct l2cap_conn *conn = chan->conn;
...@@ -3957,13 +3964,15 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, ...@@ -3957,13 +3964,15 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
goto done; goto done;
} }
/* check compatibility */ if (!chan->ctrl_id) {
if (!chan->ctrl_id)
l2cap_send_efs_conf_rsp(chan, buf, cmd->ident, l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
0); 0);
else } else {
chan->ident = cmd->ident; if (l2cap_check_efs(chan)) {
amp_create_logical_link(chan);
chan->ident = cmd->ident;
}
}
} }
goto done; goto done;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment