Bluetooth: Fix updating advertising state flags and data
authorJohan Hedberg <johan.hedberg@intel.com>
Thu, 8 Nov 2012 00:23:01 +0000 (01:23 +0100)
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>
Mon, 19 Nov 2012 01:03:01 +0000 (23:03 -0200)
This patch adds a callback for the HCI_LE_Set_Advertise_Enable command.
The callback is responsible for updating the HCI_LE_PERIPHERAL flag
updating as well as updating the advertising data flags field to
indicate undirected connectable advertising.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
include/net/bluetooth/hci.h
net/bluetooth/hci_event.c

index 7306078e547cccbc852523ec62f539fb65220a76..4bbabd85f5e5973a4d4c09582c2b317a492a5403 100644 (file)
@@ -957,6 +957,8 @@ struct hci_cp_le_set_adv_data {
        __u8    data[HCI_MAX_AD_LENGTH];
 } __packed;
 
+#define HCI_OP_LE_SET_ADV_ENABLE       0x200a
+
 #define HCI_OP_LE_SET_SCAN_PARAM       0x200b
 struct hci_cp_le_set_scan_param {
        __u8    type;
index 7caea1af557b4a602ee41fb04f288312fbfac03b..9f5c5f244502ef3cad289c8477fb05ad3990f37e 100644 (file)
@@ -1190,6 +1190,33 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
        hci_dev_unlock(hdev);
 }
 
+static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       __u8 *sent, status = *((__u8 *) skb->data);
+
+       BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+       sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
+       if (!sent)
+               return;
+
+       hci_dev_lock(hdev);
+
+       if (!status) {
+               if (*sent)
+                       set_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
+               else
+                       clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
+       }
+
+       hci_dev_unlock(hdev);
+
+       if (!test_bit(HCI_INIT, &hdev->flags))
+               hci_update_ad(hdev);
+
+       hci_req_complete(hdev, HCI_OP_LE_SET_ADV_ENABLE, status);
+}
+
 static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
 {
        __u8 status = *((__u8 *) skb->data);
@@ -2585,6 +2612,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
                hci_cc_le_set_scan_param(hdev, skb);
                break;
 
+       case HCI_OP_LE_SET_ADV_ENABLE:
+               hci_cc_le_set_adv_enable(hdev, skb);
+               break;
+
        case HCI_OP_LE_SET_SCAN_ENABLE:
                hci_cc_le_set_scan_enable(hdev, skb);
                break;