aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/amp.c8
-rw-r--r--net/bluetooth/hci_core.c98
-rw-r--r--net/bluetooth/hci_event.c44
-rw-r--r--net/bluetooth/l2cap_core.c52
-rw-r--r--net/bluetooth/mgmt.c2
5 files changed, 177 insertions, 27 deletions
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index 4b2fea6c1c2a..1b0d92c0643a 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -386,13 +386,17 @@ void amp_physical_cfm(struct hci_conn *bredr_hcon, struct hci_conn *hs_hcon)
386 386
387 bredr_chan = mgr->bredr_chan; 387 bredr_chan = mgr->bredr_chan;
388 388
389 l2cap_chan_lock(bredr_chan);
390
389 set_bit(FLAG_EFS_ENABLE, &bredr_chan->flags); 391 set_bit(FLAG_EFS_ENABLE, &bredr_chan->flags);
390 bredr_chan->remote_amp_id = hs_hcon->remote_id; 392 bredr_chan->remote_amp_id = hs_hcon->remote_id;
393 bredr_chan->local_amp_id = hs_hcon->hdev->id;
391 bredr_chan->hs_hcon = hs_hcon; 394 bredr_chan->hs_hcon = hs_hcon;
392 bredr_chan->conn->mtu = hs_hcon->hdev->block_mtu; 395 bredr_chan->conn->mtu = hs_hcon->hdev->block_mtu;
393 bredr_chan->fcs = L2CAP_FCS_NONE;
394 396
395 l2cap_physical_cfm(bredr_chan, 0); 397 __l2cap_physical_cfm(bredr_chan, 0);
398
399 l2cap_chan_unlock(bredr_chan);
396 400
397 hci_dev_put(bredr_hdev); 401 hci_dev_put(bredr_hdev);
398} 402}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index c68c4098da98..7140f83328a2 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -434,6 +434,8 @@ bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
434 434
435 BT_DBG("cache %p, %pMR", cache, &data->bdaddr); 435 BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
436 436
437 hci_remove_remote_oob_data(hdev, &data->bdaddr);
438
437 if (ssp) 439 if (ssp)
438 *ssp = data->ssp_mode; 440 *ssp = data->ssp_mode;
439 441
@@ -594,6 +596,99 @@ done:
594 return err; 596 return err;
595} 597}
596 598
599static u8 create_ad(struct hci_dev *hdev, u8 *ptr)
600{
601 u8 ad_len = 0, flags = 0;
602 size_t name_len;
603
604 if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
605 flags |= LE_AD_GENERAL;
606
607 if (!lmp_bredr_capable(hdev))
608 flags |= LE_AD_NO_BREDR;
609
610 if (lmp_le_br_capable(hdev))
611 flags |= LE_AD_SIM_LE_BREDR_CTRL;
612
613 if (lmp_host_le_br_capable(hdev))
614 flags |= LE_AD_SIM_LE_BREDR_HOST;
615
616 if (flags) {
617 BT_DBG("adv flags 0x%02x", flags);
618
619 ptr[0] = 2;
620 ptr[1] = EIR_FLAGS;
621 ptr[2] = flags;
622
623 ad_len += 3;
624 ptr += 3;
625 }
626
627 if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) {
628 ptr[0] = 2;
629 ptr[1] = EIR_TX_POWER;
630 ptr[2] = (u8) hdev->adv_tx_power;
631
632 ad_len += 3;
633 ptr += 3;
634 }
635
636 name_len = strlen(hdev->dev_name);
637 if (name_len > 0) {
638 size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
639
640 if (name_len > max_len) {
641 name_len = max_len;
642 ptr[1] = EIR_NAME_SHORT;
643 } else
644 ptr[1] = EIR_NAME_COMPLETE;
645
646 ptr[0] = name_len + 1;
647
648 memcpy(ptr + 2, hdev->dev_name, name_len);
649
650 ad_len += (name_len + 2);
651 ptr += (name_len + 2);
652 }
653
654 return ad_len;
655}
656
657int hci_update_ad(struct hci_dev *hdev)
658{
659 struct hci_cp_le_set_adv_data cp;
660 u8 len;
661 int err;
662
663 hci_dev_lock(hdev);
664
665 if (!lmp_le_capable(hdev)) {
666 err = -EINVAL;
667 goto unlock;
668 }
669
670 memset(&cp, 0, sizeof(cp));
671
672 len = create_ad(hdev, cp.data);
673
674 if (hdev->adv_data_len == len &&
675 memcmp(cp.data, hdev->adv_data, len) == 0) {
676 err = 0;
677 goto unlock;
678 }
679
680 memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
681 hdev->adv_data_len = len;
682
683 cp.length = len;
684 err = hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
685
686unlock:
687 hci_dev_unlock(hdev);
688
689 return err;
690}
691
597/* ---- HCI ioctl helpers ---- */ 692/* ---- HCI ioctl helpers ---- */
598 693
599int hci_dev_open(__u16 dev) 694int hci_dev_open(__u16 dev)
@@ -651,6 +746,7 @@ int hci_dev_open(__u16 dev)
651 hci_dev_hold(hdev); 746 hci_dev_hold(hdev);
652 set_bit(HCI_UP, &hdev->flags); 747 set_bit(HCI_UP, &hdev->flags);
653 hci_notify(hdev, HCI_DEV_UP); 748 hci_notify(hdev, HCI_DEV_UP);
749 hci_update_ad(hdev);
654 if (!test_bit(HCI_SETUP, &hdev->dev_flags) && 750 if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
655 mgmt_valid_hdev(hdev)) { 751 mgmt_valid_hdev(hdev)) {
656 hci_dev_lock(hdev); 752 hci_dev_lock(hdev);
@@ -1606,6 +1702,8 @@ struct hci_dev *hci_alloc_dev(void)
1606 hdev->esco_type = (ESCO_HV1); 1702 hdev->esco_type = (ESCO_HV1);
1607 hdev->link_mode = (HCI_LM_ACCEPT); 1703 hdev->link_mode = (HCI_LM_ACCEPT);
1608 hdev->io_capability = 0x03; /* No Input No Output */ 1704 hdev->io_capability = 0x03; /* No Input No Output */
1705 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
1706 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
1609 1707
1610 hdev->sniff_max_interval = 800; 1708 hdev->sniff_max_interval = 800;
1611 hdev->sniff_min_interval = 80; 1709 hdev->sniff_min_interval = 80;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index c08ac7c03711..9f5c5f244502 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -202,6 +202,11 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
202 BIT(HCI_PERIODIC_INQ)); 202 BIT(HCI_PERIODIC_INQ));
203 203
204 hdev->discovery.state = DISCOVERY_STOPPED; 204 hdev->discovery.state = DISCOVERY_STOPPED;
205 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
206 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
207
208 memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
209 hdev->adv_data_len = 0;
205} 210}
206 211
207static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) 212static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
@@ -224,6 +229,9 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
224 229
225 hci_dev_unlock(hdev); 230 hci_dev_unlock(hdev);
226 231
232 if (!status && !test_bit(HCI_INIT, &hdev->flags))
233 hci_update_ad(hdev);
234
227 hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status); 235 hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status);
228} 236}
229 237
@@ -1089,8 +1097,11 @@ static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
1089 1097
1090 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 1098 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1091 1099
1092 if (!rp->status) 1100 if (!rp->status) {
1093 hdev->adv_tx_power = rp->tx_power; 1101 hdev->adv_tx_power = rp->tx_power;
1102 if (!test_bit(HCI_INIT, &hdev->flags))
1103 hci_update_ad(hdev);
1104 }
1094 1105
1095 hci_req_complete(hdev, HCI_OP_LE_READ_ADV_TX_POWER, rp->status); 1106 hci_req_complete(hdev, HCI_OP_LE_READ_ADV_TX_POWER, rp->status);
1096} 1107}
@@ -1179,6 +1190,33 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1179 hci_dev_unlock(hdev); 1190 hci_dev_unlock(hdev);
1180} 1191}
1181 1192
1193static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
1194{
1195 __u8 *sent, status = *((__u8 *) skb->data);
1196
1197 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1198
1199 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
1200 if (!sent)
1201 return;
1202
1203 hci_dev_lock(hdev);
1204
1205 if (!status) {
1206 if (*sent)
1207 set_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
1208 else
1209 clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
1210 }
1211
1212 hci_dev_unlock(hdev);
1213
1214 if (!test_bit(HCI_INIT, &hdev->flags))
1215 hci_update_ad(hdev);
1216
1217 hci_req_complete(hdev, HCI_OP_LE_SET_ADV_ENABLE, status);
1218}
1219
1182static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) 1220static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1183{ 1221{
1184 __u8 status = *((__u8 *) skb->data); 1222 __u8 status = *((__u8 *) skb->data);
@@ -2574,6 +2612,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2574 hci_cc_le_set_scan_param(hdev, skb); 2612 hci_cc_le_set_scan_param(hdev, skb);
2575 break; 2613 break;
2576 2614
2615 case HCI_OP_LE_SET_ADV_ENABLE:
2616 hci_cc_le_set_adv_enable(hdev, skb);
2617 break;
2618
2577 case HCI_OP_LE_SET_SCAN_ENABLE: 2619 case HCI_OP_LE_SET_SCAN_ENABLE:
2578 hci_cc_le_set_scan_enable(hdev, skb); 2620 hci_cc_le_set_scan_enable(hdev, skb);
2579 break; 2621 break;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index a1faaab41839..b52f66d22437 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4284,9 +4284,9 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn,
4284 4284
4285 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon); 4285 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4286 4286
4287 chan->local_amp_id = req->amp_id;
4288 mgr->bredr_chan = chan; 4287 mgr->bredr_chan = chan;
4289 chan->hs_hcon = hs_hcon; 4288 chan->hs_hcon = hs_hcon;
4289 chan->fcs = L2CAP_FCS_NONE;
4290 conn->mtu = hdev->block_mtu; 4290 conn->mtu = hdev->block_mtu;
4291 } 4291 }
4292 4292
@@ -4518,21 +4518,39 @@ void l2cap_move_start(struct l2cap_chan *chan)
4518static void l2cap_do_create(struct l2cap_chan *chan, int result, 4518static void l2cap_do_create(struct l2cap_chan *chan, int result,
4519 u8 local_amp_id, u8 remote_amp_id) 4519 u8 local_amp_id, u8 remote_amp_id)
4520{ 4520{
4521 if (!test_bit(CONF_CONNECT_PEND, &chan->conf_state)) { 4521 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4522 local_amp_id, remote_amp_id);
4523
4524 chan->fcs = L2CAP_FCS_NONE;
4525
4526 /* Outgoing channel on AMP */
4527 if (chan->state == BT_CONNECT) {
4528 if (result == L2CAP_CR_SUCCESS) {
4529 chan->local_amp_id = local_amp_id;
4530 l2cap_send_create_chan_req(chan, remote_amp_id);
4531 } else {
4532 /* Revert to BR/EDR connect */
4533 l2cap_send_conn_req(chan);
4534 }
4535
4536 return;
4537 }
4538
4539 /* Incoming channel on AMP */
4540 if (__l2cap_no_conn_pending(chan)) {
4522 struct l2cap_conn_rsp rsp; 4541 struct l2cap_conn_rsp rsp;
4523 char buf[128]; 4542 char buf[128];
4524 rsp.scid = cpu_to_le16(chan->dcid); 4543 rsp.scid = cpu_to_le16(chan->dcid);
4525 rsp.dcid = cpu_to_le16(chan->scid); 4544 rsp.dcid = cpu_to_le16(chan->scid);
4526 4545
4527 /* Incoming channel on AMP */
4528 if (result == L2CAP_CR_SUCCESS) { 4546 if (result == L2CAP_CR_SUCCESS) {
4529 /* Send successful response */ 4547 /* Send successful response */
4530 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); 4548 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4531 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); 4549 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4532 } else { 4550 } else {
4533 /* Send negative response */ 4551 /* Send negative response */
4534 rsp.result = cpu_to_le16(L2CAP_CR_NO_MEM); 4552 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4535 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); 4553 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4536 } 4554 }
4537 4555
4538 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP, 4556 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
@@ -4546,15 +4564,6 @@ static void l2cap_do_create(struct l2cap_chan *chan, int result,
4546 l2cap_build_conf_req(chan, buf), buf); 4564 l2cap_build_conf_req(chan, buf), buf);
4547 chan->num_conf_req++; 4565 chan->num_conf_req++;
4548 } 4566 }
4549 } else {
4550 /* Outgoing channel on AMP */
4551 if (result == L2CAP_CR_SUCCESS) {
4552 chan->local_amp_id = local_amp_id;
4553 l2cap_send_create_chan_req(chan, remote_amp_id);
4554 } else {
4555 /* Revert to BR/EDR connect */
4556 l2cap_send_conn_req(chan);
4557 }
4558 } 4567 }
4559} 4568}
4560 4569
@@ -4612,7 +4621,8 @@ static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4612 l2cap_ertm_send(chan); 4621 l2cap_ertm_send(chan);
4613} 4622}
4614 4623
4615void l2cap_physical_cfm(struct l2cap_chan *chan, int result) 4624/* Invoke with locked chan */
4625void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
4616{ 4626{
4617 u8 local_amp_id = chan->local_amp_id; 4627 u8 local_amp_id = chan->local_amp_id;
4618 u8 remote_amp_id = chan->remote_amp_id; 4628 u8 remote_amp_id = chan->remote_amp_id;
@@ -4620,8 +4630,6 @@ void l2cap_physical_cfm(struct l2cap_chan *chan, int result)
4620 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d", 4630 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4621 chan, result, local_amp_id, remote_amp_id); 4631 chan, result, local_amp_id, remote_amp_id);
4622 4632
4623 l2cap_chan_lock(chan);
4624
4625 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) { 4633 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4626 l2cap_chan_unlock(chan); 4634 l2cap_chan_unlock(chan);
4627 return; 4635 return;
@@ -4645,8 +4653,6 @@ void l2cap_physical_cfm(struct l2cap_chan *chan, int result)
4645 break; 4653 break;
4646 } 4654 }
4647 } 4655 }
4648
4649 l2cap_chan_unlock(chan);
4650} 4656}
4651 4657
4652static inline int l2cap_move_channel_req(struct l2cap_conn *conn, 4658static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
@@ -6086,7 +6092,7 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6086 control->super); 6092 control->super);
6087 6093
6088 if (len != 0) { 6094 if (len != 0) {
6089 BT_ERR("%d", len); 6095 BT_ERR("Trailing bytes: %d in sframe", len);
6090 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); 6096 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
6091 goto drop; 6097 goto drop;
6092 } 6098 }
@@ -6380,7 +6386,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
6380 continue; 6386 continue;
6381 } 6387 }
6382 6388
6383 if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) { 6389 if (!__l2cap_no_conn_pending(chan)) {
6384 l2cap_chan_unlock(chan); 6390 l2cap_chan_unlock(chan);
6385 continue; 6391 continue;
6386 } 6392 }
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a97948b96b49..142764aec2af 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -485,7 +485,7 @@ static void create_eir(struct hci_dev *hdev, u8 *data)
485 ptr += (name_len + 2); 485 ptr += (name_len + 2);
486 } 486 }
487 487
488 if (hdev->inq_tx_power) { 488 if (hdev->inq_tx_power != HCI_TX_POWER_INVALID) {
489 ptr[0] = 2; 489 ptr[0] = 2;
490 ptr[1] = EIR_TX_POWER; 490 ptr[1] = EIR_TX_POWER;
491 ptr[2] = (u8) hdev->inq_tx_power; 491 ptr[2] = (u8) hdev->inq_tx_power;