Bluetooth: Simplify usage of the enable_advertising function
[pandora-kernel.git] / net / bluetooth / mgmt.c
index be91d55..68c0698 100644 (file)
@@ -1039,6 +1039,13 @@ static bool get_connectable(struct hci_dev *hdev)
        return test_bit(HCI_CONNECTABLE, &hdev->dev_flags);
 }
 
+static void disable_advertising(struct hci_request *req)
+{
+       u8 enable = 0x00;
+
+       hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
+}
+
 static void enable_advertising(struct hci_request *req)
 {
        struct hci_dev *hdev = req->hdev;
@@ -1046,12 +1053,18 @@ static void enable_advertising(struct hci_request *req)
        u8 own_addr_type, enable = 0x01;
        bool connectable;
 
-       /* Clear the HCI_ADVERTISING bit temporarily so that the
+       if (hci_conn_num(hdev, LE_LINK) > 0)
+               return;
+
+       if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
+               disable_advertising(req);
+
+       /* Clear the HCI_LE_ADV bit temporarily so that the
         * hci_update_random_address knows that it's safe to go ahead
         * and write a new random address. The flag will be set back on
         * as soon as the SET_ADV_ENABLE HCI command completes.
         */
-       clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
+       clear_bit(HCI_LE_ADV, &hdev->dev_flags);
 
        connectable = get_connectable(hdev);
 
@@ -1074,13 +1087,6 @@ static void enable_advertising(struct hci_request *req)
        hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
 }
 
-static void disable_advertising(struct hci_request *req)
-{
-       u8 enable = 0x00;
-
-       hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
-}
-
 static void service_cache_off(struct work_struct *work)
 {
        struct hci_dev *hdev = container_of(work, struct hci_dev,
@@ -1112,19 +1118,14 @@ static void rpa_expired(struct work_struct *work)
 
        set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
 
-       if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags) ||
-           hci_conn_num(hdev, LE_LINK) > 0)
+       if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
                return;
 
        /* The generation of a new RPA and programming it into the
         * controller happens in the enable_advertising() function.
         */
-
        hci_req_init(&req, hdev);
-
-       disable_advertising(&req);
        enable_advertising(&req);
-
        hci_req_run(&req, NULL);
 }
 
@@ -1750,8 +1751,10 @@ static void set_connectable_complete(struct hci_dev *hdev, u8 status)
 
        send_settings_rsp(cmd->sk, MGMT_OP_SET_CONNECTABLE, hdev);
 
-       if (changed)
+       if (changed) {
                new_settings(hdev, cmd->sk);
+               hci_update_background_scan(hdev);
+       }
 
 remove_cmd:
        mgmt_pending_remove(cmd);
@@ -1862,10 +1865,8 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
                write_fast_connectable(&req, false);
 
        if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) &&
-           hci_conn_num(hdev, LE_LINK) == 0) {
-               disable_advertising(&req);
+           !test_bit(HCI_LE_ADV, &hdev->dev_flags))
                enable_advertising(&req);
-       }
 
        err = hci_req_run(&req, set_connectable_complete);
        if (err < 0) {
@@ -2150,6 +2151,8 @@ static void le_enable_complete(struct hci_dev *hdev, u8 status)
                update_scan_rsp_data(&req);
                hci_req_run(&req, NULL);
 
+               hci_update_background_scan(hdev);
+
                hci_dev_unlock(hdev);
        }
 }
@@ -3115,9 +3118,9 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
                 */
                hci_conn_params_add(hdev, &cp->addr.bdaddr, addr_type);
 
+               /* Request a connection with master = true role */
                conn = hci_connect_le(hdev, &cp->addr.bdaddr, addr_type,
-                                     sec_level, auth_type,
-                                     HCI_LE_CONN_TIMEOUT);
+                                     sec_level, HCI_LE_CONN_TIMEOUT, true);
        }
 
        if (IS_ERR(conn)) {
@@ -4030,6 +4033,11 @@ static void set_advertising_complete(struct hci_dev *hdev, u8 status)
                return;
        }
 
+       if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
+               set_bit(HCI_ADVERTISING, &hdev->dev_flags);
+       else
+               clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
+
        mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, settings_rsp,
                             &match);
 
@@ -5974,18 +5982,6 @@ void mgmt_connectable(struct hci_dev *hdev, u8 connectable)
                new_settings(hdev, NULL);
 }
 
-void mgmt_advertising(struct hci_dev *hdev, u8 advertising)
-{
-       /* Powering off may stop advertising - don't let that interfere */
-       if (!advertising && mgmt_pending_find(MGMT_OP_SET_POWERED, hdev))
-               return;
-
-       if (advertising)
-               set_bit(HCI_ADVERTISING, &hdev->dev_flags);
-       else
-               clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
-}
-
 void mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status)
 {
        u8 mgmt_err = mgmt_status(status);
@@ -6717,7 +6713,6 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 {
        char buf[512];
        struct mgmt_ev_device_found *ev = (void *) buf;
-       struct smp_irk *irk;
        size_t ev_size;
 
        /* Don't send events for a non-kernel initiated discovery. With
@@ -6739,15 +6734,8 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 
        memset(buf, 0, sizeof(buf));
 
-       irk = hci_get_irk(hdev, bdaddr, addr_type);
-       if (irk) {
-               bacpy(&ev->addr.bdaddr, &irk->bdaddr);
-               ev->addr.type = link_to_bdaddr(link_type, irk->addr_type);
-       } else {
-               bacpy(&ev->addr.bdaddr, bdaddr);
-               ev->addr.type = link_to_bdaddr(link_type, addr_type);
-       }
-
+       bacpy(&ev->addr.bdaddr, bdaddr);
+       ev->addr.type = link_to_bdaddr(link_type, addr_type);
        ev->rssi = rssi;
        ev->flags = cpu_to_le32(flags);
 
@@ -6820,32 +6808,16 @@ void mgmt_discovering(struct hci_dev *hdev, u8 discovering)
 static void adv_enable_complete(struct hci_dev *hdev, u8 status)
 {
        BT_DBG("%s status %u", hdev->name, status);
-
-       /* Clear the advertising mgmt setting if we failed to re-enable it */
-       if (status) {
-               clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
-               new_settings(hdev, NULL);
-       }
 }
 
 void mgmt_reenable_advertising(struct hci_dev *hdev)
 {
        struct hci_request req;
 
-       if (hci_conn_num(hdev, LE_LINK) > 0)
-               return;
-
        if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
                return;
 
        hci_req_init(&req, hdev);
        enable_advertising(&req);
-
-       /* If this fails we have no option but to let user space know
-        * that we've disabled advertising.
-        */
-       if (hci_req_run(&req, adv_enable_complete) < 0) {
-               clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
-               new_settings(hdev, NULL);
-       }
+       hci_req_run(&req, adv_enable_complete);
 }