aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/a2mp.c
diff options
context:
space:
mode:
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>2012-09-27 10:26:16 -0400
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>2012-09-27 16:18:36 -0400
commit93c3e8f5c9a0e4dc6b6c93108dcf3ec54ab1191a (patch)
treeef09b88bd239bc42c6ce5b28bfca7173644c3df4 /net/bluetooth/a2mp.c
parent9a5e94dbb4aa306742a47cbbcb0a44d4fc77a9e4 (diff)
Bluetooth: Choose connection based on capabilities
Choose which L2CAP connection to establish by checking support for HS and remote side supported features. Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Diffstat (limited to 'net/bluetooth/a2mp.c')
-rw-r--r--net/bluetooth/a2mp.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index d0fde05e8b17..93adaad782ed 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -638,7 +638,7 @@ static struct l2cap_ops a2mp_chan_ops = {
638 .ready = l2cap_chan_no_ready, 638 .ready = l2cap_chan_no_ready,
639}; 639};
640 640
641static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn) 641static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked)
642{ 642{
643 struct l2cap_chan *chan; 643 struct l2cap_chan *chan;
644 int err; 644 int err;
@@ -673,7 +673,10 @@ static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn)
673 673
674 chan->conf_state = 0; 674 chan->conf_state = 0;
675 675
676 l2cap_chan_add(conn, chan); 676 if (locked)
677 __l2cap_chan_add(conn, chan);
678 else
679 l2cap_chan_add(conn, chan);
677 680
678 chan->remote_mps = chan->omtu; 681 chan->remote_mps = chan->omtu;
679 chan->mps = chan->omtu; 682 chan->mps = chan->omtu;
@@ -712,7 +715,7 @@ int amp_mgr_put(struct amp_mgr *mgr)
712 return kref_put(&mgr->kref, &amp_mgr_destroy); 715 return kref_put(&mgr->kref, &amp_mgr_destroy);
713} 716}
714 717
715static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn) 718static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn, bool locked)
716{ 719{
717 struct amp_mgr *mgr; 720 struct amp_mgr *mgr;
718 struct l2cap_chan *chan; 721 struct l2cap_chan *chan;
@@ -725,7 +728,7 @@ static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn)
725 728
726 mgr->l2cap_conn = conn; 729 mgr->l2cap_conn = conn;
727 730
728 chan = a2mp_chan_open(conn); 731 chan = a2mp_chan_open(conn, locked);
729 if (!chan) { 732 if (!chan) {
730 kfree(mgr); 733 kfree(mgr);
731 return NULL; 734 return NULL;
@@ -754,7 +757,7 @@ struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn,
754{ 757{
755 struct amp_mgr *mgr; 758 struct amp_mgr *mgr;
756 759
757 mgr = amp_mgr_create(conn); 760 mgr = amp_mgr_create(conn, false);
758 if (!mgr) { 761 if (!mgr) {
759 BT_ERR("Could not create AMP manager"); 762 BT_ERR("Could not create AMP manager");
760 return NULL; 763 return NULL;
@@ -842,3 +845,24 @@ void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status)
842 amp_mgr_put(mgr); 845 amp_mgr_put(mgr);
843 kfree(rsp); 846 kfree(rsp);
844} 847}
848
849void a2mp_discover_amp(struct l2cap_chan *chan)
850{
851 struct l2cap_conn *conn = chan->conn;
852 struct amp_mgr *mgr = conn->hcon->amp_mgr;
853 struct a2mp_discov_req req;
854
855 BT_DBG("chan %p conn %p mgr %p", chan, conn, mgr);
856
857 if (!mgr) {
858 mgr = amp_mgr_create(conn, true);
859 if (!mgr)
860 return;
861 }
862
863 mgr->bredr_chan = chan;
864
865 req.mtu = cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU);
866 req.ext_feat = 0;
867 a2mp_send(mgr, A2MP_DISCOVER_REQ, 1, sizeof(req), &req);
868}