2 Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved.
3 Copyright (c) 2011,2012 Intel Corp.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 and
7 only version 2 as published by the Free Software Foundation.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
15 #include <net/bluetooth/bluetooth.h>
16 #include <net/bluetooth/hci_core.h>
17 #include <net/bluetooth/l2cap.h>
18 #include <net/bluetooth/a2mp.h>
20 /* A2MP build & send command helper functions */
21 static struct a2mp_cmd *__a2mp_build(u8 code, u8 ident, u16 len, void *data)
26 plen = sizeof(*cmd) + len;
27 cmd = kzalloc(plen, GFP_KERNEL);
33 cmd->len = cpu_to_le16(len);
35 memcpy(cmd->data, data, len);
40 static void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len,
43 struct l2cap_chan *chan = mgr->a2mp_chan;
45 u16 total_len = len + sizeof(*cmd);
49 cmd = __a2mp_build(code, ident, len, data);
54 iv.iov_len = total_len;
56 memset(&msg, 0, sizeof(msg));
58 msg.msg_iov = (struct iovec *) &iv;
61 l2cap_chan_send(chan, &msg, total_len, 0);
66 static struct l2cap_ops a2mp_chan_ops = {
67 .name = "L2CAP A2MP channel",
70 static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn)
72 struct l2cap_chan *chan;
75 chan = l2cap_chan_create();
79 BT_DBG("chan %p", chan);
81 hci_conn_hold(conn->hcon);
83 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
84 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
85 chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
87 chan->ops = &a2mp_chan_ops;
89 l2cap_chan_set_defaults(chan);
90 chan->remote_max_tx = chan->max_tx;
91 chan->remote_tx_win = chan->tx_win;
93 chan->retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
94 chan->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
96 skb_queue_head_init(&chan->tx_q);
98 chan->mode = L2CAP_MODE_ERTM;
100 err = l2cap_ertm_init(chan);
102 l2cap_chan_del(chan, 0);
106 chan->conf_state = 0;
108 l2cap_chan_add(conn, chan);
110 chan->remote_mps = chan->omtu;
111 chan->mps = chan->omtu;
113 chan->state = BT_CONNECTED;
118 /* AMP Manager functions */
119 void amp_mgr_get(struct amp_mgr *mgr)
121 BT_DBG("mgr %p", mgr);
123 kref_get(&mgr->kref);
126 static void amp_mgr_destroy(struct kref *kref)
128 struct amp_mgr *mgr = container_of(kref, struct amp_mgr, kref);
130 BT_DBG("mgr %p", mgr);
135 int amp_mgr_put(struct amp_mgr *mgr)
137 BT_DBG("mgr %p", mgr);
139 return kref_put(&mgr->kref, &_mgr_destroy);
142 static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn)
145 struct l2cap_chan *chan;
147 mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
151 BT_DBG("conn %p mgr %p", conn, mgr);
153 mgr->l2cap_conn = conn;
155 chan = a2mp_chan_open(conn);
161 mgr->a2mp_chan = chan;
164 conn->hcon->amp_mgr = mgr;
166 kref_init(&mgr->kref);