aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2013-10-06 07:08:14 -0400
committerJohan Hedberg <johan.hedberg@intel.com>2013-10-06 09:00:07 -0400
commit5976e60811723220678ebdb2ea06fbb52fe900bd (patch)
tree847ee9b60a023863d4315ad94f8246e3a6230c4f
parentb4faf30096c3deb618392a88feaa7674cd55c257 (diff)
Bluetooth: Use helper function for re-enabling advertising
When the all LE connections have been disconneted, then it is up to the host to re-enable advertising at that point. To ensure that the correct advertising parameters are used, force the usage of the common helper to enable advertising. The change just moves the manual enabling of advertising from the event handler into the management core so that the helper can be actually shared. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
-rw-r--r--include/net/bluetooth/hci_core.h1
-rw-r--r--net/bluetooth/hci_event.c36
-rw-r--r--net/bluetooth/mgmt.c33
3 files changed, 35 insertions, 35 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 82c397451261..869f6ad602d1 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1151,6 +1151,7 @@ int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
1151int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); 1151int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
1152bool mgmt_valid_hdev(struct hci_dev *hdev); 1152bool mgmt_valid_hdev(struct hci_dev *hdev);
1153int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent); 1153int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent);
1154void mgmt_reenable_advertising(struct hci_dev *hdev);
1154 1155
1155/* HCI info for socket */ 1156/* HCI info for socket */
1156#define hci_pi(sk) ((struct hci_pinfo *) sk) 1157#define hci_pi(sk) ((struct hci_pinfo *) sk)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 6eaef6ed9522..224210ce82fc 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1796,40 +1796,6 @@ static u8 hci_to_mgmt_reason(u8 err)
1796 } 1796 }
1797} 1797}
1798 1798
1799static void adv_enable_complete(struct hci_dev *hdev, u8 status)
1800{
1801 BT_DBG("%s status %u", hdev->name, status);
1802
1803 /* Clear the advertising mgmt setting if we failed to re-enable it */
1804 if (status) {
1805 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
1806 mgmt_new_settings(hdev);
1807 }
1808}
1809
1810static void reenable_advertising(struct hci_dev *hdev)
1811{
1812 struct hci_request req;
1813 u8 enable = 0x01;
1814
1815 if (hdev->conn_hash.le_num)
1816 return;
1817
1818 if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
1819 return;
1820
1821 hci_req_init(&req, hdev);
1822 hci_req_add(&req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
1823
1824 /* If this fails we have no option but to let user space know
1825 * that we've disabled advertising.
1826 */
1827 if (hci_req_run(&req, adv_enable_complete) < 0) {
1828 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
1829 mgmt_new_settings(hdev);
1830 }
1831}
1832
1833static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 1799static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1834{ 1800{
1835 struct hci_ev_disconn_complete *ev = (void *) skb->data; 1801 struct hci_ev_disconn_complete *ev = (void *) skb->data;
@@ -1878,7 +1844,7 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1878 * is timed out due to Directed Advertising." 1844 * is timed out due to Directed Advertising."
1879 */ 1845 */
1880 if (type == LE_LINK) 1846 if (type == LE_LINK)
1881 reenable_advertising(hdev); 1847 mgmt_reenable_advertising(hdev);
1882 } 1848 }
1883 1849
1884unlock: 1850unlock:
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index b78a0eefe03e..381faf600195 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -4660,3 +4660,36 @@ int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
4660 return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &ev, sizeof(ev), 4660 return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &ev, sizeof(ev),
4661 cmd ? cmd->sk : NULL); 4661 cmd ? cmd->sk : NULL);
4662} 4662}
4663
4664static void adv_enable_complete(struct hci_dev *hdev, u8 status)
4665{
4666 BT_DBG("%s status %u", hdev->name, status);
4667
4668 /* Clear the advertising mgmt setting if we failed to re-enable it */
4669 if (status) {
4670 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
4671 mgmt_new_settings(hdev);
4672 }
4673}
4674
4675void mgmt_reenable_advertising(struct hci_dev *hdev)
4676{
4677 struct hci_request req;
4678
4679 if (hdev->conn_hash.le_num)
4680 return;
4681
4682 if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
4683 return;
4684
4685 hci_req_init(&req, hdev);
4686 enable_advertising(&req);
4687
4688 /* If this fails we have no option but to let user space know
4689 * that we've disabled advertising.
4690 */
4691 if (hci_req_run(&req, adv_enable_complete) < 0) {
4692 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
4693 mgmt_new_settings(hdev);
4694 }
4695}