Add new actions to add_device to allow it to set or unset a device as
wakeable. When the set wakeable and unset wakeable actions are used, the
autoconnect property is not updated and the device is not added to the
whitelist (if BR/EDR).
Signed-off-by: Abhishek Pandit-Subedi <[email protected]>
---
net/bluetooth/mgmt.c | 56 ++++++++++++++++++++++++++++++++++++--------
1 file changed, 46 insertions(+), 10 deletions(-)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 6552003a170e..8688673542b3 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -5775,6 +5775,7 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
void *data, u16 len)
{
struct mgmt_cp_add_device *cp = data;
+ struct hci_conn_params *params;
u8 auto_conn, addr_type;
int err;
@@ -5786,7 +5787,7 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
MGMT_STATUS_INVALID_PARAMS,
&cp->addr, sizeof(cp->addr));
- if (cp->action != 0x00 && cp->action != 0x01 && cp->action != 0x02)
+ if (cp->action > 0x04)
return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
MGMT_STATUS_INVALID_PARAMS,
&cp->addr, sizeof(cp->addr));
@@ -5794,8 +5795,35 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
hci_dev_lock(hdev);
if (cp->addr.type == BDADDR_BREDR) {
- /* Only incoming connections action is supported for now */
- if (cp->action != 0x01) {
+ switch (cp->action) {
+ case 0x3:
+ /* Set wakeable */
+ err = hci_bdaddr_list_add(&hdev->wakeable,
+ &cp->addr.bdaddr,
+ cp->addr.type);
+ if (err && err != -EEXIST)
+ goto unlock;
+ break;
+ case 0x4:
+ /* Remove wakeable */
+ err = hci_bdaddr_list_del(&hdev->wakeable,
+ &cp->addr.bdaddr,
+ cp->addr.type);
+ if (err)
+ goto unlock;
+
+ break;
+ case 0x1:
+ /* Allow incoming connection */
+ err = hci_bdaddr_list_add(&hdev->whitelist,
+ &cp->addr.bdaddr,
+ cp->addr.type);
+ if (err && err != -EEXIST)
+ goto unlock;
+
+ hci_req_update_scan(hdev);
+ break;
+ default:
err = mgmt_cmd_complete(sk, hdev->id,
MGMT_OP_ADD_DEVICE,
MGMT_STATUS_INVALID_PARAMS,
@@ -5803,13 +5831,6 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
goto unlock;
}
- err = hci_bdaddr_list_add(&hdev->whitelist, &cp->addr.bdaddr,
- cp->addr.type);
- if (err)
- goto unlock;
-
- hci_req_update_scan(hdev);
-
goto added;
}
@@ -5834,6 +5855,21 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
goto unlock;
}
+ /* Only allow wakeable property to be set/unset on existing device */
+ if (cp->action == 0x03 || cp->action == 0x04) {
+ params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
+ addr_type);
+ if (!params) {
+ err = mgmt_cmd_complete(sk, hdev->id,
+ MGMT_OP_ADD_DEVICE,
+ MGMT_STATUS_FAILED, &cp->addr,
+ sizeof(cp->addr));
+ }
+
+ params->wakeable = cp->action == 0x03;
+ goto added;
+ }
+
/* If the connection parameters don't exist for this device,
* they will be created and configured with defaults.
*/
--
2.25.1.696.g5e7596f4ac-goog