mgmt.c (47db6b42991e6d5645d0938e43085aaf88cdfba4) mgmt.c (2f2eb0c9de2eb69969aaf04feffb69310d3804b2)
1/*
2 BlueZ - Bluetooth protocol stack for Linux
3
4 Copyright (C) 2010 Nokia Corporation
5 Copyright (C) 2011-2012 Intel Corporation
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as

--- 6080 unchanged lines hidden (view full) ---

6089 */
6090 hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
6091
6092unlock:
6093 hci_dev_unlock(hdev);
6094 return err;
6095}
6096
1/*
2 BlueZ - Bluetooth protocol stack for Linux
3
4 Copyright (C) 2010 Nokia Corporation
5 Copyright (C) 2011-2012 Intel Corporation
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as

--- 6080 unchanged lines hidden (view full) ---

6089 */
6090 hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
6091
6092unlock:
6093 hci_dev_unlock(hdev);
6094 return err;
6095}
6096
6097static void sc_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode)
6097static void set_secure_conn_complete(struct hci_dev *hdev, void *data, int err)
6098{
6098{
6099 struct mgmt_pending_cmd *cmd;
6099 struct mgmt_pending_cmd *cmd = data;
6100 struct mgmt_mode *cp;
6101
6100 struct mgmt_mode *cp;
6101
6102 bt_dev_dbg(hdev, "status %u", status);
6102 bt_dev_dbg(hdev, "err %d", err);
6103
6103
6104 hci_dev_lock(hdev);
6104 if (err) {
6105 u8 mgmt_err = mgmt_status(err);
6105
6106
6106 cmd = pending_find(MGMT_OP_SET_SECURE_CONN, hdev);
6107 if (!cmd)
6108 goto unlock;
6109
6110 if (status) {
6111 mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
6112 mgmt_status(status));
6113 goto remove;
6107 mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
6108 goto done;
6114 }
6115
6116 cp = cmd->param;
6117
6118 switch (cp->val) {
6119 case 0x00:
6120 hci_dev_clear_flag(hdev, HCI_SC_ENABLED);
6121 hci_dev_clear_flag(hdev, HCI_SC_ONLY);
6122 break;
6123 case 0x01:
6124 hci_dev_set_flag(hdev, HCI_SC_ENABLED);
6125 hci_dev_clear_flag(hdev, HCI_SC_ONLY);
6126 break;
6127 case 0x02:
6128 hci_dev_set_flag(hdev, HCI_SC_ENABLED);
6129 hci_dev_set_flag(hdev, HCI_SC_ONLY);
6130 break;
6131 }
6132
6109 }
6110
6111 cp = cmd->param;
6112
6113 switch (cp->val) {
6114 case 0x00:
6115 hci_dev_clear_flag(hdev, HCI_SC_ENABLED);
6116 hci_dev_clear_flag(hdev, HCI_SC_ONLY);
6117 break;
6118 case 0x01:
6119 hci_dev_set_flag(hdev, HCI_SC_ENABLED);
6120 hci_dev_clear_flag(hdev, HCI_SC_ONLY);
6121 break;
6122 case 0x02:
6123 hci_dev_set_flag(hdev, HCI_SC_ENABLED);
6124 hci_dev_set_flag(hdev, HCI_SC_ONLY);
6125 break;
6126 }
6127
6133 send_settings_rsp(cmd->sk, MGMT_OP_SET_SECURE_CONN, hdev);
6128 send_settings_rsp(cmd->sk, cmd->opcode, hdev);
6134 new_settings(hdev, cmd->sk);
6135
6129 new_settings(hdev, cmd->sk);
6130
6136remove:
6137 mgmt_pending_remove(cmd);
6138unlock:
6139 hci_dev_unlock(hdev);
6131done:
6132 mgmt_pending_free(cmd);
6140}
6141
6133}
6134
6135static int set_secure_conn_sync(struct hci_dev *hdev, void *data)
6136{
6137 struct mgmt_pending_cmd *cmd = data;
6138 struct mgmt_mode *cp = cmd->param;
6139 u8 val = !!cp->val;
6140
6141 /* Force write of val */
6142 hci_dev_set_flag(hdev, HCI_SC_ENABLED);
6143
6144 return hci_write_sc_support_sync(hdev, val);
6145}
6146
6142static int set_secure_conn(struct sock *sk, struct hci_dev *hdev,
6143 void *data, u16 len)
6144{
6145 struct mgmt_mode *cp = data;
6146 struct mgmt_pending_cmd *cmd;
6147static int set_secure_conn(struct sock *sk, struct hci_dev *hdev,
6148 void *data, u16 len)
6149{
6150 struct mgmt_mode *cp = data;
6151 struct mgmt_pending_cmd *cmd;
6147 struct hci_request req;
6148 u8 val;
6149 int err;
6150
6151 bt_dev_dbg(hdev, "sock %p", sk);
6152
6153 if (!lmp_sc_capable(hdev) &&
6154 !hci_dev_test_flag(hdev, HCI_LE_ENABLED))
6155 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
6156 MGMT_STATUS_NOT_SUPPORTED);
6157
6158 if (hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
6159 lmp_sc_capable(hdev) &&
6160 !hci_dev_test_flag(hdev, HCI_SSP_ENABLED))
6161 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
6162 MGMT_STATUS_REJECTED);
6163
6164 if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02)
6165 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
6152 u8 val;
6153 int err;
6154
6155 bt_dev_dbg(hdev, "sock %p", sk);
6156
6157 if (!lmp_sc_capable(hdev) &&
6158 !hci_dev_test_flag(hdev, HCI_LE_ENABLED))
6159 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
6160 MGMT_STATUS_NOT_SUPPORTED);
6161
6162 if (hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
6163 lmp_sc_capable(hdev) &&
6164 !hci_dev_test_flag(hdev, HCI_SSP_ENABLED))
6165 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
6166 MGMT_STATUS_REJECTED);
6167
6168 if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02)
6169 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
6166 MGMT_STATUS_INVALID_PARAMS);
6170 MGMT_STATUS_INVALID_PARAMS);
6167
6168 hci_dev_lock(hdev);
6169
6170 if (!hdev_is_powered(hdev) || !lmp_sc_capable(hdev) ||
6171 !hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
6172 bool changed;
6173
6174 if (cp->val) {

--- 14 unchanged lines hidden (view full) ---

6189 goto failed;
6190
6191 if (changed)
6192 err = new_settings(hdev, sk);
6193
6194 goto failed;
6195 }
6196
6171
6172 hci_dev_lock(hdev);
6173
6174 if (!hdev_is_powered(hdev) || !lmp_sc_capable(hdev) ||
6175 !hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
6176 bool changed;
6177
6178 if (cp->val) {

--- 14 unchanged lines hidden (view full) ---

6193 goto failed;
6194
6195 if (changed)
6196 err = new_settings(hdev, sk);
6197
6198 goto failed;
6199 }
6200
6197 if (pending_find(MGMT_OP_SET_SECURE_CONN, hdev)) {
6198 err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
6199 MGMT_STATUS_BUSY);
6200 goto failed;
6201 }
6202
6203 val = !!cp->val;
6204
6205 if (val == hci_dev_test_flag(hdev, HCI_SC_ENABLED) &&
6206 (cp->val == 0x02) == hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
6207 err = send_settings_rsp(sk, MGMT_OP_SET_SECURE_CONN, hdev);
6208 goto failed;
6209 }
6210
6201 val = !!cp->val;
6202
6203 if (val == hci_dev_test_flag(hdev, HCI_SC_ENABLED) &&
6204 (cp->val == 0x02) == hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
6205 err = send_settings_rsp(sk, MGMT_OP_SET_SECURE_CONN, hdev);
6206 goto failed;
6207 }
6208
6211 cmd = mgmt_pending_add(sk, MGMT_OP_SET_SECURE_CONN, hdev, data, len);
6212 if (!cmd) {
6209 cmd = mgmt_pending_new(sk, MGMT_OP_SET_SECURE_CONN, hdev, data, len);
6210 if (!cmd)
6213 err = -ENOMEM;
6211 err = -ENOMEM;
6214 goto failed;
6215 }
6212 else
6213 err = hci_cmd_sync_queue(hdev, set_secure_conn_sync, cmd,
6214 set_secure_conn_complete);
6216
6215
6217 hci_req_init(&req, hdev);
6218 hci_req_add(&req, HCI_OP_WRITE_SC_SUPPORT, 1, &val);
6219 err = hci_req_run(&req, sc_enable_complete);
6220 if (err < 0) {
6216 if (err < 0) {
6221 mgmt_pending_remove(cmd);
6222 goto failed;
6217 mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
6218 MGMT_STATUS_FAILED);
6219 if (cmd)
6220 mgmt_pending_free(cmd);
6223 }
6224
6225failed:
6226 hci_dev_unlock(hdev);
6227 return err;
6228}
6229
6230static int set_debug_keys(struct sock *sk, struct hci_dev *hdev,

--- 3478 unchanged lines hidden ---
6221 }
6222
6223failed:
6224 hci_dev_unlock(hdev);
6225 return err;
6226}
6227
6228static int set_debug_keys(struct sock *sk, struct hci_dev *hdev,

--- 3478 unchanged lines hidden ---