From f6fd16e5d540cbffb78d17bc1b313485e5884705 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Thu, 20 Dec 2018 08:28:26 +0800 Subject: [PATCH 1/2] disable BLE advertisment --- drivers/bluetooth/btusb.c | 13 +++++++++ include/net/bluetooth/hci_core.h | 3 ++ net/bluetooth/hci_core.c | 48 ++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 10c8f9872ee5..74f1553767da 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -490,6 +490,7 @@ struct btusb_data { int (*setup_on_usb)(struct hci_dev *hdev); int oob_wake_irq; /* irq for out-of-band wake-on-bt */ + bool suspended; }; static inline void btusb_free_frags(struct btusb_data *data) @@ -3316,12 +3317,18 @@ static void btusb_disconnect(struct usb_interface *intf) static int btusb_suspend(struct usb_interface *intf, pm_message_t message) { struct btusb_data *data = usb_get_intfdata(intf); + struct hci_dev *hdev = data->hdev; BT_DBG("intf %p", intf); if (data->suspend_count++) return 0; + if (!PMSG_IS_AUTO(message)) { + hci_disable_le_advertising(hdev); + data->suspended = true; + } + spin_lock_irq(&data->txlock); if (!(PMSG_IS_AUTO(message) && data->tx_in_flight)) { set_bit(BTUSB_SUSPENDING, &data->flags); @@ -3343,6 +3350,7 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) enable_irq(data->oob_wake_irq); } + return 0; } @@ -3427,6 +3435,11 @@ static int btusb_resume(struct usb_interface *intf) spin_unlock_irq(&data->txlock); schedule_work(&data->work); + if (data->suspended) { + hci_enable_le_advertising(hdev); + data->suspended = false; + } + return 0; failed: diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index e5ea633ea368..ef92dd12f816 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -269,6 +269,7 @@ struct hci_dev { __u16 le_max_rx_time; __u8 le_max_key_size; __u8 le_min_key_size; + __u8 le_events[8]; __u16 discov_interleaved_timeout; __u16 conn_info_min_age; __u16 conn_info_max_age; @@ -1141,6 +1142,8 @@ void hci_init_sysfs(struct hci_dev *hdev); void hci_conn_init_sysfs(struct hci_conn *conn); void hci_conn_add_sysfs(struct hci_conn *conn); void hci_conn_del_sysfs(struct hci_conn *conn); +int hci_enable_le_advertising(struct hci_dev *hdev); +int hci_disable_le_advertising(struct hci_dev *hdev); #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev)) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 7352fe85674b..4c64788b5418 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -411,6 +411,52 @@ static void hci_setup_event_mask(struct hci_request *req) hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events); } +static int hci_enable_le_advertising_req(struct hci_request *req, unsigned long opt) +{ + struct hci_dev *hdev = req->hdev; + u8 events[8]; + memcpy(events, hdev->le_events, sizeof(events)); + + hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events), + events); + + return 0; +} + +static int hci_disable_le_advertising_req(struct hci_request *req, unsigned long opt) +{ + struct hci_dev *hdev = req->hdev; + + u8 events[8]; + memcpy(events, hdev->le_events, sizeof(events)); + + events[0] &= ~(u8)0x02; /* LE Advertising Report */ + //events[2] &= ~(u8)0x02; /* LE Advertising Set Terminated */ + + hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events), + events); + + return 0; +} + +int hci_enable_le_advertising(struct hci_dev *hdev) +{ + if (!lmp_le_capable(hdev)) + return 0; + + return __hci_req_sync(hdev, hci_enable_le_advertising_req, 0, HCI_CMD_TIMEOUT, NULL); +} +EXPORT_SYMBOL(hci_enable_le_advertising); + +int hci_disable_le_advertising(struct hci_dev *hdev) +{ + if (!lmp_le_capable(hdev)) + return 0; + + return __hci_req_sync(hdev, hci_disable_le_advertising_req, 0, HCI_CMD_TIMEOUT, NULL); +} +EXPORT_SYMBOL(hci_disable_le_advertising); + static int hci_init2_req(struct hci_request *req, unsigned long opt) { struct hci_dev *hdev = req->hdev; @@ -771,6 +817,8 @@ static int hci_init3_req(struct hci_request *req, unsigned long opt) } hci_set_le_support(req); + + memcpy(hdev->le_events, events, sizeof(events)); } /* Read features beyond page 1 if available */ -- 2.17.1