diff options
author | Andrei Emeltchenko <andrei.emeltchenko@intel.com> | 2012-11-01 09:37:02 -0400 |
---|---|---|
committer | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2012-11-01 18:27:10 -0400 |
commit | 6e1df6a60372b6ea00c480c1cd8c8c8134357d89 (patch) | |
tree | 3079849a319ec7a13f370a998179773f35b94b2b /net/bluetooth | |
parent | cf70ff220a918b25d383510f913de52308d04bb2 (diff) |
Bluetooth: Process Create Chan Request
Add processing L2CAP Create Chan Request. When channel is created
save associated high speed link hs_hcon.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/l2cap_core.c | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index bdffc4c207b5..2f0e165eef4d 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -4237,7 +4237,9 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn, | |||
4237 | u16 cmd_len, void *data) | 4237 | u16 cmd_len, void *data) |
4238 | { | 4238 | { |
4239 | struct l2cap_create_chan_req *req = data; | 4239 | struct l2cap_create_chan_req *req = data; |
4240 | struct l2cap_create_chan_rsp rsp; | ||
4240 | struct l2cap_chan *chan; | 4241 | struct l2cap_chan *chan; |
4242 | struct hci_dev *hdev; | ||
4241 | u16 psm, scid; | 4243 | u16 psm, scid; |
4242 | 4244 | ||
4243 | if (cmd_len != sizeof(*req)) | 4245 | if (cmd_len != sizeof(*req)) |
@@ -4251,36 +4253,57 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn, | |||
4251 | 4253 | ||
4252 | BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id); | 4254 | BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id); |
4253 | 4255 | ||
4254 | if (req->amp_id) { | 4256 | /* For controller id 0 make BR/EDR connection */ |
4255 | struct hci_dev *hdev; | 4257 | if (req->amp_id == HCI_BREDR_ID) { |
4256 | 4258 | l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP, | |
4257 | /* Validate AMP controller id */ | 4259 | req->amp_id); |
4258 | hdev = hci_dev_get(req->amp_id); | 4260 | return 0; |
4259 | if (!hdev || hdev->dev_type != HCI_AMP || | 4261 | } |
4260 | !test_bit(HCI_UP, &hdev->flags)) { | ||
4261 | struct l2cap_create_chan_rsp rsp; | ||
4262 | 4262 | ||
4263 | rsp.dcid = 0; | 4263 | /* Validate AMP controller id */ |
4264 | rsp.scid = cpu_to_le16(scid); | 4264 | hdev = hci_dev_get(req->amp_id); |
4265 | rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP); | 4265 | if (!hdev) |
4266 | rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); | 4266 | goto error; |
4267 | 4267 | ||
4268 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP, | 4268 | if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) { |
4269 | sizeof(rsp), &rsp); | 4269 | hci_dev_put(hdev); |
4270 | goto error; | ||
4271 | } | ||
4270 | 4272 | ||
4271 | if (hdev) | 4273 | chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP, |
4272 | hci_dev_put(hdev); | 4274 | req->amp_id); |
4275 | if (chan) { | ||
4276 | struct amp_mgr *mgr = conn->hcon->amp_mgr; | ||
4277 | struct hci_conn *hs_hcon; | ||
4273 | 4278 | ||
4274 | return 0; | 4279 | hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst); |
4280 | if (!hs_hcon) { | ||
4281 | hci_dev_put(hdev); | ||
4282 | return -EFAULT; | ||
4275 | } | 4283 | } |
4276 | 4284 | ||
4277 | hci_dev_put(hdev); | 4285 | BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon); |
4286 | |||
4287 | chan->local_amp_id = req->amp_id; | ||
4288 | mgr->bredr_chan = chan; | ||
4289 | chan->hs_hcon = hs_hcon; | ||
4290 | conn->mtu = hdev->block_mtu; | ||
4278 | } | 4291 | } |
4279 | 4292 | ||
4280 | chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP, | 4293 | hci_dev_put(hdev); |
4281 | req->amp_id); | ||
4282 | 4294 | ||
4283 | return 0; | 4295 | return 0; |
4296 | |||
4297 | error: | ||
4298 | rsp.dcid = 0; | ||
4299 | rsp.scid = cpu_to_le16(scid); | ||
4300 | rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP); | ||
4301 | rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); | ||
4302 | |||
4303 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP, | ||
4304 | sizeof(rsp), &rsp); | ||
4305 | |||
4306 | return -EFAULT; | ||
4284 | } | 4307 | } |
4285 | 4308 | ||
4286 | static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id) | 4309 | static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id) |