mgmt.c (5a750137466400276560458db040c143cbc254ed) | mgmt.c (d81a494c43df66f053f7d1ec612e057eb99f34d4) |
---|---|
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 --- 1888 unchanged lines hidden (view full) --- 1897 if (changed) 1898 err = new_settings(hdev, sk); 1899 1900unlock: 1901 hci_dev_unlock(hdev); 1902 return err; 1903} 1904 | 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 --- 1888 unchanged lines hidden (view full) --- 1897 if (changed) 1898 err = new_settings(hdev, sk); 1899 1900unlock: 1901 hci_dev_unlock(hdev); 1902 return err; 1903} 1904 |
1905static void le_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode) | 1905static void set_le_complete(struct hci_dev *hdev, void *data, int err) |
1906{ 1907 struct cmd_lookup match = { NULL, hdev }; | 1906{ 1907 struct cmd_lookup match = { NULL, hdev }; |
1908 u8 status = mgmt_status(err); |
|
1908 | 1909 |
1909 hci_dev_lock(hdev); | 1910 bt_dev_dbg(hdev, "err %d", err); |
1910 1911 if (status) { | 1911 1912 if (status) { |
1912 u8 mgmt_err = mgmt_status(status); 1913 | |
1914 mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, cmd_status_rsp, | 1913 mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, cmd_status_rsp, |
1915 &mgmt_err); 1916 goto unlock; | 1914 &status); 1915 return; |
1917 } 1918 1919 mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, settings_rsp, &match); 1920 1921 new_settings(hdev, match.sk); 1922 1923 if (match.sk) 1924 sock_put(match.sk); | 1916 } 1917 1918 mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, settings_rsp, &match); 1919 1920 new_settings(hdev, match.sk); 1921 1922 if (match.sk) 1923 sock_put(match.sk); |
1924} |
|
1925 | 1925 |
1926static int set_le_sync(struct hci_dev *hdev, void *data) 1927{ 1928 struct mgmt_pending_cmd *cmd = data; 1929 struct mgmt_mode *cp = cmd->param; 1930 u8 val = !!cp->val; 1931 int err; 1932 1933 if (!val) { 1934 if (hci_dev_test_flag(hdev, HCI_LE_ADV)) 1935 hci_disable_advertising_sync(hdev); 1936 1937 if (ext_adv_capable(hdev)) 1938 hci_remove_ext_adv_instance_sync(hdev, 0, cmd->sk); 1939 } else { 1940 hci_dev_set_flag(hdev, HCI_LE_ENABLED); 1941 } 1942 1943 err = hci_write_le_host_supported_sync(hdev, val, 0); 1944 |
|
1926 /* Make sure the controller has a good default for 1927 * advertising data. Restrict the update to when LE 1928 * has actually been enabled. During power on, the 1929 * update in powered_update_hci will take care of it. 1930 */ | 1945 /* Make sure the controller has a good default for 1946 * advertising data. Restrict the update to when LE 1947 * has actually been enabled. During power on, the 1948 * update in powered_update_hci will take care of it. 1949 */ |
1931 if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) { 1932 struct hci_request req; 1933 hci_req_init(&req, hdev); | 1950 if (!err && hci_dev_test_flag(hdev, HCI_LE_ENABLED)) { |
1934 if (ext_adv_capable(hdev)) { | 1951 if (ext_adv_capable(hdev)) { |
1935 int err; | 1952 int status; |
1936 | 1953 |
1937 err = __hci_req_setup_ext_adv_instance(&req, 0x00); 1938 if (!err) 1939 __hci_req_update_scan_rsp_data(&req, 0x00); | 1954 status = hci_setup_ext_adv_instance_sync(hdev, 0x00); 1955 if (!status) 1956 hci_update_scan_rsp_data_sync(hdev, 0x00); |
1940 } else { | 1957 } else { |
1941 __hci_req_update_adv_data(&req, 0x00); 1942 __hci_req_update_scan_rsp_data(&req, 0x00); | 1958 hci_update_adv_data_sync(hdev, 0x00); 1959 hci_update_scan_rsp_data_sync(hdev, 0x00); |
1943 } | 1960 } |
1944 hci_req_run(&req, NULL); | 1961 |
1945 hci_update_passive_scan(hdev); 1946 } 1947 | 1962 hci_update_passive_scan(hdev); 1963 } 1964 |
1948unlock: 1949 hci_dev_unlock(hdev); | 1965 return err; |
1950} 1951 1952static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) 1953{ 1954 struct mgmt_mode *cp = data; | 1966} 1967 1968static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) 1969{ 1970 struct mgmt_mode *cp = data; |
1955 struct hci_cp_write_le_host_supported hci_cp; | |
1956 struct mgmt_pending_cmd *cmd; | 1971 struct mgmt_pending_cmd *cmd; |
1957 struct hci_request req; | |
1958 int err; 1959 u8 val, enabled; 1960 1961 bt_dev_dbg(hdev, "sock %p", sk); 1962 1963 if (!lmp_le_capable(hdev)) 1964 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LE, 1965 MGMT_STATUS_NOT_SUPPORTED); --- 53 unchanged lines hidden (view full) --- 2019 if (pending_find(MGMT_OP_SET_LE, hdev) || 2020 pending_find(MGMT_OP_SET_ADVERTISING, hdev)) { 2021 err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LE, 2022 MGMT_STATUS_BUSY); 2023 goto unlock; 2024 } 2025 2026 cmd = mgmt_pending_add(sk, MGMT_OP_SET_LE, hdev, data, len); | 1972 int err; 1973 u8 val, enabled; 1974 1975 bt_dev_dbg(hdev, "sock %p", sk); 1976 1977 if (!lmp_le_capable(hdev)) 1978 return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LE, 1979 MGMT_STATUS_NOT_SUPPORTED); --- 53 unchanged lines hidden (view full) --- 2033 if (pending_find(MGMT_OP_SET_LE, hdev) || 2034 pending_find(MGMT_OP_SET_ADVERTISING, hdev)) { 2035 err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LE, 2036 MGMT_STATUS_BUSY); 2037 goto unlock; 2038 } 2039 2040 cmd = mgmt_pending_add(sk, MGMT_OP_SET_LE, hdev, data, len); |
2027 if (!cmd) { | 2041 if (!cmd) |
2028 err = -ENOMEM; | 2042 err = -ENOMEM; |
2029 goto unlock; 2030 } | 2043 else 2044 err = hci_cmd_sync_queue(hdev, set_le_sync, cmd, 2045 set_le_complete); |
2031 | 2046 |
2032 hci_req_init(&req, hdev); | 2047 if (err < 0) { 2048 err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LE, 2049 MGMT_STATUS_FAILED); |
2033 | 2050 |
2034 memset(&hci_cp, 0, sizeof(hci_cp)); 2035 2036 if (val) { 2037 hci_cp.le = val; 2038 hci_cp.simul = 0x00; 2039 } else { 2040 if (hci_dev_test_flag(hdev, HCI_LE_ADV)) 2041 __hci_req_disable_advertising(&req); 2042 2043 if (ext_adv_capable(hdev)) 2044 __hci_req_clear_ext_adv_sets(&req); | 2051 if (cmd) 2052 mgmt_pending_remove(cmd); |
2045 } 2046 | 2053 } 2054 |
2047 hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp), 2048 &hci_cp); 2049 2050 err = hci_req_run(&req, le_enable_complete); 2051 if (err < 0) 2052 mgmt_pending_remove(cmd); 2053 | |
2054unlock: 2055 hci_dev_unlock(hdev); 2056 return err; 2057} 2058 2059/* This is a helper function to test for pending mgmt commands that can 2060 * cause CoD or EIR HCI commands. We can only allow one such pending 2061 * mgmt command at a time since otherwise we cannot easily track what --- 7626 unchanged lines hidden --- | 2055unlock: 2056 hci_dev_unlock(hdev); 2057 return err; 2058} 2059 2060/* This is a helper function to test for pending mgmt commands that can 2061 * cause CoD or EIR HCI commands. We can only allow one such pending 2062 * mgmt command at a time since otherwise we cannot easily track what --- 7626 unchanged lines hidden --- |