aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2013-10-15 09:33:52 -0400
committerJohan Hedberg <johan.hedberg@intel.com>2013-10-15 10:20:00 -0400
commit441ad2d04123eecb06d7c14948a0e7b07bf75aa5 (patch)
tree643ba2a1e2f4ae441f392cc7a9a916b74c79840c /net/bluetooth/mgmt.c
parentb1e73124104d0c4c6c9a073afea07ff0b73d5787 (diff)
Bluetooth: Update advertising data based on management commands
Magically updating the advertising data when some random command enables advertising in the controller is not really a good idea. It also caused a bit of complicated code with the exported hci_udpate_ad function that is shared from many places. This patch consolidates the advertising data update into the management core. It also makes sure that when powering on with LE enabled or later on enabling LE the controller has a good default for advertising data. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r--net/bluetooth/mgmt.c126
1 files changed, 115 insertions, 11 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index c071708aac24..285d571eee6b 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -536,6 +536,89 @@ static u8 *create_uuid128_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
536 return ptr; 536 return ptr;
537} 537}
538 538
539static u8 create_ad(struct hci_dev *hdev, u8 *ptr)
540{
541 u8 ad_len = 0, flags = 0;
542 size_t name_len;
543
544 if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
545 flags |= LE_AD_GENERAL;
546
547 if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
548 if (lmp_le_br_capable(hdev))
549 flags |= LE_AD_SIM_LE_BREDR_CTRL;
550 if (lmp_host_le_br_capable(hdev))
551 flags |= LE_AD_SIM_LE_BREDR_HOST;
552 } else {
553 flags |= LE_AD_NO_BREDR;
554 }
555
556 if (flags) {
557 BT_DBG("adv flags 0x%02x", flags);
558
559 ptr[0] = 2;
560 ptr[1] = EIR_FLAGS;
561 ptr[2] = flags;
562
563 ad_len += 3;
564 ptr += 3;
565 }
566
567 if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) {
568 ptr[0] = 2;
569 ptr[1] = EIR_TX_POWER;
570 ptr[2] = (u8) hdev->adv_tx_power;
571
572 ad_len += 3;
573 ptr += 3;
574 }
575
576 name_len = strlen(hdev->dev_name);
577 if (name_len > 0) {
578 size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
579
580 if (name_len > max_len) {
581 name_len = max_len;
582 ptr[1] = EIR_NAME_SHORT;
583 } else
584 ptr[1] = EIR_NAME_COMPLETE;
585
586 ptr[0] = name_len + 1;
587
588 memcpy(ptr + 2, hdev->dev_name, name_len);
589
590 ad_len += (name_len + 2);
591 ptr += (name_len + 2);
592 }
593
594 return ad_len;
595}
596
597static void update_ad(struct hci_request *req)
598{
599 struct hci_dev *hdev = req->hdev;
600 struct hci_cp_le_set_adv_data cp;
601 u8 len;
602
603 if (!lmp_le_capable(hdev))
604 return;
605
606 memset(&cp, 0, sizeof(cp));
607
608 len = create_ad(hdev, cp.data);
609
610 if (hdev->adv_data_len == len &&
611 memcmp(cp.data, hdev->adv_data, len) == 0)
612 return;
613
614 memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
615 hdev->adv_data_len = len;
616
617 cp.length = len;
618
619 hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
620}
621
539static void create_eir(struct hci_dev *hdev, u8 *data) 622static void create_eir(struct hci_dev *hdev, u8 *data)
540{ 623{
541 u8 *ptr = data; 624 u8 *ptr = data;
@@ -1555,6 +1638,23 @@ static void le_enable_complete(struct hci_dev *hdev, u8 status)
1555 1638
1556 if (match.sk) 1639 if (match.sk)
1557 sock_put(match.sk); 1640 sock_put(match.sk);
1641
1642 /* Make sure the controller has a good default for
1643 * advertising data. Restrict the update to when LE
1644 * has actually been enabled. During power on, the
1645 * update in powered_update_hci will take care of it.
1646 */
1647 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
1648 struct hci_request req;
1649
1650 hci_dev_lock(hdev);
1651
1652 hci_req_init(&req, hdev);
1653 update_ad(&req);
1654 hci_req_run(&req, NULL);
1655
1656 hci_dev_unlock(hdev);
1657 }
1558} 1658}
1559 1659
1560static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) 1660static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
@@ -1622,18 +1722,18 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1622 goto unlock; 1722 goto unlock;
1623 } 1723 }
1624 1724
1725 hci_req_init(&req, hdev);
1726
1625 memset(&hci_cp, 0, sizeof(hci_cp)); 1727 memset(&hci_cp, 0, sizeof(hci_cp));
1626 1728
1627 if (val) { 1729 if (val) {
1628 hci_cp.le = val; 1730 hci_cp.le = val;
1629 hci_cp.simul = lmp_le_br_capable(hdev); 1731 hci_cp.simul = lmp_le_br_capable(hdev);
1732 } else {
1733 if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
1734 disable_advertising(&req);
1630 } 1735 }
1631 1736
1632 hci_req_init(&req, hdev);
1633
1634 if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) && !val)
1635 disable_advertising(&req);
1636
1637 hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp), 1737 hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp),
1638 &hci_cp); 1738 &hci_cp);
1639 1739
@@ -2772,7 +2872,7 @@ static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data,
2772 } 2872 }
2773 2873
2774 if (lmp_le_capable(hdev)) 2874 if (lmp_le_capable(hdev))
2775 hci_update_ad(&req); 2875 update_ad(&req);
2776 2876
2777 err = hci_req_run(&req, set_name_complete); 2877 err = hci_req_run(&req, set_name_complete);
2778 if (err < 0) 2878 if (err < 0)
@@ -3724,7 +3824,7 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
3724 goto unlock; 3824 goto unlock;
3725 } 3825 }
3726 3826
3727 /* We need to flip the bit already here so that hci_update_ad 3827 /* We need to flip the bit already here so that update_ad
3728 * generates the correct flags. 3828 * generates the correct flags.
3729 */ 3829 */
3730 set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 3830 set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
@@ -3734,7 +3834,7 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
3734 if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) 3834 if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
3735 set_bredr_scan(&req); 3835 set_bredr_scan(&req);
3736 3836
3737 hci_update_ad(&req); 3837 update_ad(&req);
3738 3838
3739 err = hci_req_run(&req, set_bredr_complete); 3839 err = hci_req_run(&req, set_bredr_complete);
3740 if (err < 0) 3840 if (err < 0)
@@ -4035,9 +4135,6 @@ static int powered_update_hci(struct hci_dev *hdev)
4035 cp.simul != lmp_host_le_br_capable(hdev)) 4135 cp.simul != lmp_host_le_br_capable(hdev))
4036 hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED, 4136 hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED,
4037 sizeof(cp), &cp); 4137 sizeof(cp), &cp);
4038
4039 /* In case BR/EDR was toggled during the AUTO_OFF phase */
4040 hci_update_ad(&req);
4041 } 4138 }
4042 4139
4043 if (lmp_le_capable(hdev)) { 4140 if (lmp_le_capable(hdev)) {
@@ -4046,6 +4143,13 @@ static int powered_update_hci(struct hci_dev *hdev)
4046 hci_req_add(&req, HCI_OP_LE_SET_RANDOM_ADDR, 6, 4143 hci_req_add(&req, HCI_OP_LE_SET_RANDOM_ADDR, 6,
4047 &hdev->static_addr); 4144 &hdev->static_addr);
4048 4145
4146 /* Make sure the controller has a good default for
4147 * advertising data. This also applies to the case
4148 * where BR/EDR was toggled during the AUTO_OFF phase.
4149 */
4150 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
4151 update_ad(&req);
4152
4049 if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) 4153 if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
4050 enable_advertising(&req); 4154 enable_advertising(&req);
4051 } 4155 }