diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2012-02-22 14:06:55 -0500 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2012-02-23 06:07:00 -0500 |
commit | 28cc7bde5978cbc58c9026123fa5f33b62ad66b3 (patch) | |
tree | b50261ffeb89292456e02c817c2af8c07a351fa9 /net/bluetooth | |
parent | db99b5fc77e6cec47d80703b471f1efe04527d2f (diff) |
Bluetooth: mgmt: Allow local name changes while powered off
This patch makes it possible to set the local name before powering on
the device. The name will be applied using the hci_write_local_name
command once the device gets powered on.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_event.c | 13 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 38 |
2 files changed, 36 insertions, 15 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 9917fe3d1d18..9b30587c0de6 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -209,11 +209,10 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) | |||
209 | 209 | ||
210 | hci_dev_lock(hdev); | 210 | hci_dev_lock(hdev); |
211 | 211 | ||
212 | if (status == 0) | ||
213 | memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); | ||
214 | |||
215 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) | 212 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) |
216 | mgmt_set_local_name_complete(hdev, sent, status); | 213 | mgmt_set_local_name_complete(hdev, sent, status); |
214 | else if (!status) | ||
215 | memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); | ||
217 | 216 | ||
218 | hci_dev_unlock(hdev); | 217 | hci_dev_unlock(hdev); |
219 | } | 218 | } |
@@ -563,6 +562,14 @@ static void hci_setup(struct hci_dev *hdev) | |||
563 | if (hdev->hci_ver > BLUETOOTH_VER_1_1) | 562 | if (hdev->hci_ver > BLUETOOTH_VER_1_1) |
564 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); | 563 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); |
565 | 564 | ||
565 | if (!test_bit(HCI_SETUP, &hdev->dev_flags) && | ||
566 | test_bit(HCI_MGMT, &hdev->dev_flags)) { | ||
567 | struct hci_cp_write_local_name cp; | ||
568 | |||
569 | memcpy(cp.name, hdev->dev_name, sizeof(cp.name)); | ||
570 | hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp); | ||
571 | } | ||
572 | |||
566 | if (hdev->features[6] & LMP_SIMPLE_PAIR) { | 573 | if (hdev->features[6] & LMP_SIMPLE_PAIR) { |
567 | if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { | 574 | if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { |
568 | u8 mode = 0x01; | 575 | u8 mode = 0x01; |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 3f6a2df9d150..9c1f7714794d 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -2260,22 +2260,29 @@ static int set_local_name(struct sock *sk, u16 index, void *data, | |||
2260 | 2260 | ||
2261 | hci_dev_lock(hdev); | 2261 | hci_dev_lock(hdev); |
2262 | 2262 | ||
2263 | memcpy(hdev->short_name, mgmt_cp->short_name, | ||
2264 | sizeof(hdev->short_name)); | ||
2265 | |||
2263 | if (!hdev_is_powered(hdev)) { | 2266 | if (!hdev_is_powered(hdev)) { |
2264 | err = cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME, | 2267 | memcpy(hdev->dev_name, mgmt_cp->name, sizeof(hdev->dev_name)); |
2265 | MGMT_STATUS_NOT_POWERED); | 2268 | |
2269 | err = cmd_complete(sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0, | ||
2270 | data, len); | ||
2271 | if (err < 0) | ||
2272 | goto failed; | ||
2273 | |||
2274 | err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, data, len, | ||
2275 | sk); | ||
2276 | |||
2266 | goto failed; | 2277 | goto failed; |
2267 | } | 2278 | } |
2268 | 2279 | ||
2269 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, hdev, data, | 2280 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, hdev, data, len); |
2270 | len); | ||
2271 | if (!cmd) { | 2281 | if (!cmd) { |
2272 | err = -ENOMEM; | 2282 | err = -ENOMEM; |
2273 | goto failed; | 2283 | goto failed; |
2274 | } | 2284 | } |
2275 | 2285 | ||
2276 | memcpy(hdev->short_name, mgmt_cp->short_name, | ||
2277 | sizeof(hdev->short_name)); | ||
2278 | |||
2279 | memcpy(hci_cp.name, mgmt_cp->name, sizeof(hci_cp.name)); | 2286 | memcpy(hci_cp.name, mgmt_cp->name, sizeof(hci_cp.name)); |
2280 | err = hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(hci_cp), | 2287 | err = hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(hci_cp), |
2281 | &hci_cp); | 2288 | &hci_cp); |
@@ -3563,10 +3570,17 @@ int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) | |||
3563 | { | 3570 | { |
3564 | struct pending_cmd *cmd; | 3571 | struct pending_cmd *cmd; |
3565 | struct mgmt_cp_set_local_name ev; | 3572 | struct mgmt_cp_set_local_name ev; |
3566 | int err; | 3573 | bool changed = false; |
3574 | int err = 0; | ||
3575 | |||
3576 | if (memcmp(name, hdev->dev_name, sizeof(hdev->dev_name)) != 0) { | ||
3577 | memcpy(hdev->dev_name, name, sizeof(hdev->dev_name)); | ||
3578 | changed = true; | ||
3579 | } | ||
3567 | 3580 | ||
3568 | memset(&ev, 0, sizeof(ev)); | 3581 | memset(&ev, 0, sizeof(ev)); |
3569 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); | 3582 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); |
3583 | memcpy(ev.short_name, hdev->short_name, HCI_MAX_SHORT_NAME_LENGTH); | ||
3570 | 3584 | ||
3571 | cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev); | 3585 | cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev); |
3572 | if (!cmd) | 3586 | if (!cmd) |
@@ -3578,16 +3592,16 @@ int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) | |||
3578 | goto failed; | 3592 | goto failed; |
3579 | } | 3593 | } |
3580 | 3594 | ||
3581 | update_eir(hdev); | ||
3582 | |||
3583 | err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0, &ev, | 3595 | err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0, &ev, |
3584 | sizeof(ev)); | 3596 | sizeof(ev)); |
3585 | if (err < 0) | 3597 | if (err < 0) |
3586 | goto failed; | 3598 | goto failed; |
3587 | 3599 | ||
3588 | send_event: | 3600 | send_event: |
3589 | err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev), | 3601 | if (changed) |
3590 | cmd ? cmd->sk : NULL); | 3602 | err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, |
3603 | sizeof(ev), cmd ? cmd->sk : NULL); | ||
3604 | |||
3591 | update_eir(hdev); | 3605 | update_eir(hdev); |
3592 | 3606 | ||
3593 | failed: | 3607 | failed: |